* [PATCH/RFC] auxv entries
@ 2008-09-14 21:27 Mark Kettenis
2008-09-15 0:28 ` Thiago Jung Bauermann
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Mark Kettenis @ 2008-09-14 21:27 UTC (permalink / raw)
To: gdb-patches
Many, if not all, processor-specific ELF ABI documents have the
following definition of auxv entries:
typedef struct
{
int a_type;
union {
long a_val;
void *a_ptr;
void (*a_fcn)();
} a_un;
} auxv_t;
This is not the layout that default_auxv_parse() uses though, which is
wrong for big-endian 64-bit systems. The attached diff fixes this,
making the assumption that a_val is "naturally" aligned.
I have some slight worries though about how this ever worked on
big-endian 64-bit Linux systems, hence the RFC.
Index: ChangeLog
from Mark Kettenis <kettenis@gnu.org>
* auxv.c (default_auxv_parse): Change code to reflect standard
auxv_t layout.
Index: auxv.c
===================================================================
RCS file: /cvs/src/src/gdb/auxv.c,v
retrieving revision 1.14
diff -u -p -r1.14 auxv.c
--- auxv.c 11 Sep 2008 14:29:21 -0000 1.14
+++ auxv.c 14 Sep 2008 21:20:03 -0000
@@ -82,20 +82,22 @@ int
default_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
{
- const int sizeof_auxv_field = gdbarch_ptr_bit (target_gdbarch)
- / TARGET_CHAR_BIT;
+ struct type *builtin_int = builtin_type (target_gdbarch)->builtin_int;
+ struct type *builtin_long = builtin_type (target_gdbarch)->builtin_long;
+ const int sizeof_auxv_type = TYPE_LENGTH(builtin_int);
+ const int sizeof_auxv_val = TYPE_LENGTH(builtin_long);
gdb_byte *ptr = *readptr;
if (endptr == ptr)
return 0;
- if (endptr - ptr < sizeof_auxv_field * 2)
+ if (endptr - ptr < sizeof_auxv_val * 2)
return -1;
- *typep = extract_unsigned_integer (ptr, sizeof_auxv_field);
- ptr += sizeof_auxv_field;
- *valp = extract_unsigned_integer (ptr, sizeof_auxv_field);
- ptr += sizeof_auxv_field;
+ *typep = extract_unsigned_integer (ptr, sizeof_auxv_type);
+ ptr += sizeof_auxv_val; /* Alignment. */
+ *valp = extract_unsigned_integer (ptr, sizeof_auxv_val);
+ ptr += sizeof_auxv_val;
*readptr = ptr;
return 1;
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH/RFC] auxv entries 2008-09-14 21:27 [PATCH/RFC] auxv entries Mark Kettenis @ 2008-09-15 0:28 ` Thiago Jung Bauermann 2008-09-15 0:34 ` Thiago Jung Bauermann 2008-09-15 3:21 ` Daniel Jacobowitz 2 siblings, 0 replies; 8+ messages in thread From: Thiago Jung Bauermann @ 2008-09-15 0:28 UTC (permalink / raw) To: Mark Kettenis; +Cc: gdb-patches El dom, 14-09-2008 a las 23:27 +0200, Mark Kettenis escribió: > Many, if not all, processor-specific ELF ABI documents have the > following definition of auxv entries: > > typedef struct > { > int a_type; > union { > long a_val; > void *a_ptr; > void (*a_fcn)(); > } a_un; > } auxv_t; This is what I see in <elf.h> on ppc64-linux: > > This is not the layout that default_auxv_parse() uses though, which is > wrong for big-endian 64-bit systems. The attached diff fixes this, > making the assumption that a_val is "naturally" aligned. > > I have some slight worries though about how this ever worked on > big-endian 64-bit Linux systems, hence the RFC. > > > Index: ChangeLog > from Mark Kettenis <kettenis@gnu.org> > > * auxv.c (default_auxv_parse): Change code to reflect standard > auxv_t layout. > > Index: auxv.c > =================================================================== > RCS file: /cvs/src/src/gdb/auxv.c,v > retrieving revision 1.14 > diff -u -p -r1.14 auxv.c > --- auxv.c 11 Sep 2008 14:29:21 -0000 1.14 > +++ auxv.c 14 Sep 2008 21:20:03 -0000 > @@ -82,20 +82,22 @@ int > default_auxv_parse (struct target_ops *ops, gdb_byte **readptr, > gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) > { > - const int sizeof_auxv_field = gdbarch_ptr_bit (target_gdbarch) > - / TARGET_CHAR_BIT; > + struct type *builtin_int = builtin_type (target_gdbarch)->builtin_int; > + struct type *builtin_long = builtin_type (target_gdbarch)->builtin_long; > + const int sizeof_auxv_type = TYPE_LENGTH(builtin_int); > + const int sizeof_auxv_val = TYPE_LENGTH(builtin_long); > gdb_byte *ptr = *readptr; > > if (endptr == ptr) > return 0; > > - if (endptr - ptr < sizeof_auxv_field * 2) > + if (endptr - ptr < sizeof_auxv_val * 2) > return -1; > > - *typep = extract_unsigned_integer (ptr, sizeof_auxv_field); > - ptr += sizeof_auxv_field; > - *valp = extract_unsigned_integer (ptr, sizeof_auxv_field); > - ptr += sizeof_auxv_field; > + *typep = extract_unsigned_integer (ptr, sizeof_auxv_type); > + ptr += sizeof_auxv_val; /* Alignment. */ > + *valp = extract_unsigned_integer (ptr, sizeof_auxv_val); > + ptr += sizeof_auxv_val; > > *readptr = ptr; > return 1; > -- []'s Thiago Jung Bauermann IBM Linux Technology Center ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] auxv entries 2008-09-14 21:27 [PATCH/RFC] auxv entries Mark Kettenis 2008-09-15 0:28 ` Thiago Jung Bauermann @ 2008-09-15 0:34 ` Thiago Jung Bauermann 2008-09-15 9:21 ` Mark Kettenis 2008-09-15 3:21 ` Daniel Jacobowitz 2 siblings, 1 reply; 8+ messages in thread From: Thiago Jung Bauermann @ 2008-09-15 0:34 UTC (permalink / raw) To: Mark Kettenis; +Cc: gdb-patches (I'd really, really like to talk to the person who thought it would be a good idea to make <ctrl>+<enter> a shortcut to send the message.) El dom, 14-09-2008 a las 23:27 +0200, Mark Kettenis escribió: > Many, if not all, processor-specific ELF ABI documents have the > following definition of auxv entries: > > typedef struct > { > int a_type; > union { > long a_val; > void *a_ptr; > void (*a_fcn)(); > } a_un; > } auxv_t; I have this in <elf.h> in ppc64-linux: typedef struct { uint64_t a_type; /* Entry type */ union { uint64_t a_val; /* Integer value */ /* We use to have pointer elements added here. We cannot do that, though, since it does not work when using 32-bit definitions on 64-bit platforms and vice versa. */ } a_un; } Elf64_auxv_t; So default_auxv_parse seems right to me. -- []'s Thiago Jung Bauermann IBM Linux Technology Center ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] auxv entries 2008-09-15 0:34 ` Thiago Jung Bauermann @ 2008-09-15 9:21 ` Mark Kettenis 2008-09-15 20:23 ` Mark Kettenis 0 siblings, 1 reply; 8+ messages in thread From: Mark Kettenis @ 2008-09-15 9:21 UTC (permalink / raw) To: bauerman; +Cc: gdb-patches [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 1460 bytes --] > From: Thiago Jung Bauermann <bauerman@br.ibm.com> > Date: Sun, 14 Sep 2008 21:33:04 -0300 > > (I'd really, really like to talk to the person who thought it would be a > good idea to make <ctrl>+<enter> a shortcut to send the message.) Heh > El dom, 14-09-2008 a las 23:27 +0200, Mark Kettenis escribió: > > Many, if not all, processor-specific ELF ABI documents have the > > following definition of auxv entries: > > > > typedef struct > > { > > int a_type; > > union { > > long a_val; > > void *a_ptr; > > void (*a_fcn)(); > > } a_un; > > } auxv_t; > > I have this in <elf.h> in ppc64-linux: > > typedef struct > { > uint64_t a_type; /* Entry type */ > union > { > uint64_t a_val; /* Integer value */ > /* We use to have pointer elements added here. We cannot do that, > though, since it does not work when using 32-bit definitions > on 64-bit platforms and vice versa. */ > } a_un; > } Elf64_auxv_t; > > So default_auxv_parse seems right to me. Hmm, so it looks like Linux doesn't follow the 64-bit PowerPC ABI here. At least version 1.7 of that spec has the "standard" form of the struct with a_type being an int. OpenBSD and Solaris both use the "standard" form, so I'd argue that Linux is the odd one out here. I'll see if I can come up with a diff that overrides the standard layout for 64-bit PPC linux. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] auxv entries 2008-09-15 9:21 ` Mark Kettenis @ 2008-09-15 20:23 ` Mark Kettenis 2008-09-15 21:14 ` Daniel Jacobowitz 2008-09-16 3:28 ` Thiago Jung Bauermann 0 siblings, 2 replies; 8+ messages in thread From: Mark Kettenis @ 2008-09-15 20:23 UTC (permalink / raw) To: bauerman, gdb-patches > Date: Mon, 15 Sep 2008 11:20:31 +0200 (CEST) > From: Mark Kettenis <mark.kettenis@xs4all.nl> > > > From: Thiago Jung Bauermann <bauerman@br.ibm.com> > > Date: Sun, 14 Sep 2008 21:33:04 -0300 > > > > I have this in <elf.h> in ppc64-linux: > > > > typedef struct > > { > > uint64_t a_type; /* Entry type */ > > union > > { > > uint64_t a_val; /* Integer value */ > > /* We use to have pointer elements added here. We cannot do that, > > though, since it does not work when using 32-bit definitions > > on 64-bit platforms and vice versa. */ > > } a_un; > > } Elf64_auxv_t; > > > > So default_auxv_parse seems right to me. > > Hmm, so it looks like Linux doesn't follow the 64-bit PowerPC ABI > here. At least version 1.7 of that spec has the "standard" form of > the struct with a_type being an int. > > OpenBSD and Solaris both use the "standard" form, so I'd argue that > Linux is the odd one out here. I'll see if I can come up with a diff > that overrides the standard layout for 64-bit PPC linux. > Here is the promised diff. Tested on Linux on amd64 (which doesn't say a lot since it is little-endian). ok? Index: ChangeLog from Mark Kettenis <kettenis@gnu.org> * auxv.c (default_auxv_parse): Change code to reflect standard auxv_t layout. * linux-nat.c (linux_nat_auxv_parse): New function. (linux_nat_add_target): Install linux_nat_auxv_parse. Index: auxv.c =================================================================== RCS file: /cvs/src/src/gdb/auxv.c,v retrieving revision 1.14 diff -u -p -r1.14 auxv.c --- auxv.c 11 Sep 2008 14:29:21 -0000 1.14 +++ auxv.c 15 Sep 2008 20:17:42 -0000 @@ -82,20 +82,22 @@ int default_auxv_parse (struct target_ops *ops, gdb_byte **readptr, gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) { - const int sizeof_auxv_field = gdbarch_ptr_bit (target_gdbarch) - / TARGET_CHAR_BIT; + struct type *builtin_int = builtin_type (target_gdbarch)->builtin_int; + struct type *builtin_long = builtin_type (target_gdbarch)->builtin_long; + const int sizeof_auxv_type = TYPE_LENGTH(builtin_int); + const int sizeof_auxv_val = TYPE_LENGTH(builtin_long); gdb_byte *ptr = *readptr; if (endptr == ptr) return 0; - if (endptr - ptr < sizeof_auxv_field * 2) + if (endptr - ptr < sizeof_auxv_val * 2) return -1; - *typep = extract_unsigned_integer (ptr, sizeof_auxv_field); - ptr += sizeof_auxv_field; - *valp = extract_unsigned_integer (ptr, sizeof_auxv_field); - ptr += sizeof_auxv_field; + *typep = extract_unsigned_integer (ptr, sizeof_auxv_type); + ptr += sizeof_auxv_val; /* Alignment. */ + *valp = extract_unsigned_integer (ptr, sizeof_auxv_val); + ptr += sizeof_auxv_val; *readptr = ptr; return 1; Index: linux-nat.c =================================================================== RCS file: /cvs/src/src/gdb/linux-nat.c,v retrieving revision 1.102 diff -u -p -r1.102 linux-nat.c --- linux-nat.c 8 Sep 2008 21:51:18 -0000 1.102 +++ linux-nat.c 15 Sep 2008 20:17:44 -0000 @@ -4353,6 +4353,29 @@ send_sigint_callback (struct lwp_info *l return 0; } +static int +linux_nat_auxv_parse(struct target_ops *ops, gdb_byte **readptr, + gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) +{ + struct type *builtin_long = builtin_type (target_gdbarch)->builtin_long; + const int sizeof_auxv_field = TYPE_LENGTH(builtin_long); + gdb_byte *ptr = *readptr; + + if (endptr == ptr) + return 0; + + if (endptr - ptr < sizeof_auxv_field * 2) + return -1; + + *typep = extract_unsigned_integer (ptr, sizeof_auxv_field); + ptr += sizeof_auxv_field; + *valp = extract_unsigned_integer (ptr, sizeof_auxv_field); + ptr += sizeof_auxv_field; + + *readptr = ptr; + return 1; +} + static void linux_nat_stop (ptid_t ptid) { @@ -4401,6 +4424,10 @@ linux_nat_add_target (struct target_ops t->to_terminal_inferior = linux_nat_terminal_inferior; t->to_terminal_ours = linux_nat_terminal_ours; + /* The Linux folks messed up and didn't follow the ELF ABI on + various 64-bit architectures. */ + t->to_auxv_parse = linux_nat_auxv_parse; + /* Methods for non-stop support. */ t->to_stop = linux_nat_stop; ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] auxv entries 2008-09-15 20:23 ` Mark Kettenis @ 2008-09-15 21:14 ` Daniel Jacobowitz 2008-09-16 3:28 ` Thiago Jung Bauermann 1 sibling, 0 replies; 8+ messages in thread From: Daniel Jacobowitz @ 2008-09-15 21:14 UTC (permalink / raw) To: Mark Kettenis; +Cc: bauerman, gdb-patches On Mon, Sep 15, 2008 at 10:22:37PM +0200, Mark Kettenis wrote: > Here is the promised diff. Tested on Linux on amd64 (which doesn't > say a lot since it is little-endian). > > ok? I think the layout of the aux vector is a strange combination of an architecture property and a target property. We can read it via gdbserver too; the remote protocol manual says it's just 'Access the target's "auxiliary vector"'. The comments on procfs_auxv_parse imply that it depends on the host GDB in native Solaris debugging. But on Linux it depends on the debuggee, not the debugger. Is there some way we can differentiate based on gdbarch or osabi? -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] auxv entries 2008-09-15 20:23 ` Mark Kettenis 2008-09-15 21:14 ` Daniel Jacobowitz @ 2008-09-16 3:28 ` Thiago Jung Bauermann 1 sibling, 0 replies; 8+ messages in thread From: Thiago Jung Bauermann @ 2008-09-16 3:28 UTC (permalink / raw) To: Mark Kettenis; +Cc: gdb-patches El lun, 15-09-2008 a las 22:22 +0200, Mark Kettenis escribió: > Here is the promised diff. Tested on Linux on amd64 (which doesn't > say a lot since it is little-endian). Not sure if you're still interested, but I had already fired the regression test anyway: This patch introduces the following regressions in ppc64-linux: PASS: gdb.base/auxv.exp: generate native core dump PASS: gdb.base/auxv.exp: load core file for info auxv on native core dump PASS: gdb.base/auxv.exp: info auxv on native core dump -PASS: gdb.base/auxv.exp: matching auxv data from live and core +FAIL: gdb.base/auxv.exp: matching auxv data from live and core PASS: gdb.base/auxv.exp: load core file for info auxv on gcore-created dump PASS: gdb.base/auxv.exp: info auxv on gcore-created dump -PASS: gdb.base/auxv.exp: matching auxv data from live and gcore +FAIL: gdb.base/auxv.exp: matching auxv data from live and gcore Here's the gdb.log for the failing run: info auxv^M 0 AT_NULL End of vector 0x16^M (gdb) PASS: gdb.base/auxv.exp: info auxv on native core dump FAIL: gdb.base/auxv.exp: matching auxv data from live and core Versus the gdb.log for the successful run: info auxv^M 22 AT_IGNOREPPC Entry should be ignored 22^M 22 AT_IGNOREPPC Entry should be ignored 22^M 19 AT_DCACHEBSIZE Data cache block size 128^M 20 AT_ICACHEBSIZE Instruction cache block size 128^M 21 AT_UCACHEBSIZE Unified cache block size 0^M 33 AT_SYSINFO_EHDR System-supplied DSO's ELF header 0x100000^M 16 AT_HWCAP Machine-dependent CPU capability hints 0xdc080000^M 6 AT_PAGESZ System page size 4096^M 17 AT_CLKTCK Frequency of times() 100^M 3 AT_PHDR Program headers for program 0x10000040^M 4 AT_PHENT Size of program header entry 56^M 5 AT_PHNUM Number of program headers 9^M 7 AT_BASE Base address of interpreter 0x40000000000^M 8 AT_FLAGS Flags 0x0^M 9 AT_ENTRY Entry point of program 0x10010b98^M 11 AT_UID Real user ID 1001^M 12 AT_EUID Effective user ID 1001^M 13 AT_GID Real group ID 100^M 14 AT_EGID Effective group ID 100^M 23 AT_SECURE Boolean, was exec setuid-like? 0^M 15 AT_PLATFORM String identifying platform 0xfffffa62210 "ppc970"^M 0 AT_NULL End of vector 0x0^M (gdb) PASS: gdb.base/auxv.exp: info auxv on native core dump PASS: gdb.base/auxv.exp: matching auxv data from live and core -- []'s Thiago Jung Bauermann IBM Linux Technology Center ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH/RFC] auxv entries 2008-09-14 21:27 [PATCH/RFC] auxv entries Mark Kettenis 2008-09-15 0:28 ` Thiago Jung Bauermann 2008-09-15 0:34 ` Thiago Jung Bauermann @ 2008-09-15 3:21 ` Daniel Jacobowitz 2 siblings, 0 replies; 8+ messages in thread From: Daniel Jacobowitz @ 2008-09-15 3:21 UTC (permalink / raw) To: Mark Kettenis; +Cc: gdb-patches, Vladimir Prus On Sun, Sep 14, 2008 at 11:27:09PM +0200, Mark Kettenis wrote: > Many, if not all, processor-specific ELF ABI documents have the > following definition of auxv entries: > > typedef struct > { > int a_type; > union { > long a_val; > void *a_ptr; > void (*a_fcn)(); > } a_un; > } auxv_t; > > This is not the layout that default_auxv_parse() uses though, which is > wrong for big-endian 64-bit systems. The attached diff fixes this, > making the assumption that a_val is "naturally" aligned. If I remember right, this is a difference between Linux and other systems (including Solaris). Someone here was looking at this in context of sparc-solaris2.10... Vladimir, was it you? -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2008-09-16 3:28 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2008-09-14 21:27 [PATCH/RFC] auxv entries Mark Kettenis 2008-09-15 0:28 ` Thiago Jung Bauermann 2008-09-15 0:34 ` Thiago Jung Bauermann 2008-09-15 9:21 ` Mark Kettenis 2008-09-15 20:23 ` Mark Kettenis 2008-09-15 21:14 ` Daniel Jacobowitz 2008-09-16 3:28 ` Thiago Jung Bauermann 2008-09-15 3:21 ` Daniel Jacobowitz
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox