This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH] PIE support for OpenBSD
- From: Mark Kettenis <mark dot kettenis at xs4all dot nl>
- To: gdb-patches at sourceware dot org
- Date: Sat, 17 Dec 2011 22:08:29 +0100 (CET)
- Subject: [PATCH] PIE support for OpenBSD
Just a matter of getting the right info out of the auxv vector, and I
added support to the OpenBSD kernel for that a while ago. Needs its
own function to parse the values since default_auxv_parse is
Linux-specific (and therefore not standards compliant on LP64
platforms). It can be argued that the parsing routine should really
live in the architecture vector. But 32x64-bit cross-debugging
muddies the waters here.
For now this is OpenBSD-specific, but FreeBSD and NetBSD might
implement the PIOD_READ_AUXV request at some point too.
ok?
2011-12-17 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.
Index: inf-ptrace.c
===================================================================
RCS file: /cvs/src/src/gdb/inf-ptrace.c,v
retrieving revision 1.75
diff -u -p -r1.75 inf-ptrace.c
--- inf-ptrace.c 22 Sep 2011 10:22:28 -0000 1.75
+++ inf-ptrace.c 17 Dec 2011 20:58:40 -0000
@@ -582,6 +582,23 @@ inf_ptrace_xfer_partial (struct target_o
return -1;
case TARGET_OBJECT_AUXV:
+#if defined (PT_IO) && defined (PIOD_READ_AUXV)
+ {
+ 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 +636,41 @@ inf_ptrace_pid_to_str (struct target_ops
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 +696,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;
}