summaryrefslogtreecommitdiff
path: root/gdb/inf-ptrace.c
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@gnu.org>2011-12-27 21:36:40 +0000
committerMark Kettenis <kettenis@gnu.org>2011-12-27 21:36:40 +0000
commite8ace1c0f45c940cf64378b45a41be17225588c2 (patch)
treeb5105a6dd307c5551a8ccdf4e25b7826452d9b6a /gdb/inf-ptrace.c
parent3bc96cfbb226922c2eedc9df93a6d18bf532db7f (diff)
downloadbinutils-gdb-e8ace1c0f45c940cf64378b45a41be17225588c2.tar.gz
2011-12-27 Mark Kettenis <kettenis@gnu.org>
* inf-ptrace.c [PT_IO && PIOD_READ_AUXV] (inf_ptrace_xfer_partial): Implement TARGET_OBJECT_AUXV. (inf_ptrace_auxv_parse): New function. (inf_ptrace_target): Initialize to_auxv_parse field.
Diffstat (limited to 'gdb/inf-ptrace.c')
-rw-r--r--gdb/inf-ptrace.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c
index 110e825363e..8f0d08b7a63 100644
--- a/gdb/inf-ptrace.c
+++ b/gdb/inf-ptrace.c
@@ -582,6 +582,26 @@ inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
return -1;
case TARGET_OBJECT_AUXV:
+#if defined (PT_IO) && defined (PIOD_READ_AUXV)
+ /* OpenBSD 4.5 has a new PIOD_READ_AUXV operation for the PT_IO
+ request that allows us to read the auxilliary vector. Other
+ BSD's may follow if they feel the need to support PIE. */
+ {
+ struct ptrace_io_desc piod;
+
+ if (writebuf)
+ return -1;
+ piod.piod_op = PIOD_READ_AUXV;
+ piod.piod_addr = readbuf;
+ piod.piod_offs = (void *) (long) offset;
+ piod.piod_len = len;
+
+ errno = 0;
+ if (ptrace (PT_IO, pid, (caddr_t)&piod, 0) == 0)
+ /* Return the actual number of bytes read or written. */
+ return piod.piod_len;
+ }
+#endif
return -1;
case TARGET_OBJECT_WCOOKIE:
@@ -619,6 +639,41 @@ inf_ptrace_pid_to_str (struct target_ops *ops, ptid_t ptid)
return normal_pid_to_str (ptid);
}
+#if defined (PT_IO) && defined (PIOD_READ_AUXV)
+
+/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
+ Return 0 if *READPTR is already at the end of the buffer.
+ Return -1 if there is insufficient buffer for a whole entry.
+ Return 1 if an entry was read into *TYPEP and *VALP. */
+
+static int
+inf_ptrace_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
+ gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+{
+ struct type *int_type = builtin_type (target_gdbarch)->builtin_int;
+ struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
+ const int sizeof_auxv_type = TYPE_LENGTH (int_type);
+ const int sizeof_auxv_val = TYPE_LENGTH (ptr_type);
+ enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
+ gdb_byte *ptr = *readptr;
+
+ if (endptr == ptr)
+ return 0;
+
+ if (endptr - ptr < 2 * sizeof_auxv_val)
+ return -1;
+
+ *typep = extract_unsigned_integer (ptr, sizeof_auxv_type, byte_order);
+ ptr += sizeof_auxv_val; /* Alignment. */
+ *valp = extract_unsigned_integer (ptr, sizeof_auxv_val, byte_order);
+ ptr += sizeof_auxv_val;
+
+ *readptr = ptr;
+ return 1;
+}
+
+#endif
+
/* Create a prototype ptrace target. The client can override it with
local methods. */
@@ -644,6 +699,9 @@ inf_ptrace_target (void)
t->to_pid_to_str = inf_ptrace_pid_to_str;
t->to_stop = inf_ptrace_stop;
t->to_xfer_partial = inf_ptrace_xfer_partial;
+#if defined (PT_IO) && defined (PIOD_READ_AUXV)
+ t->to_auxv_parse = inf_ptrace_auxv_parse;
+#endif
return t;
}