From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16799 invoked by alias); 15 Sep 2008 20:23:31 -0000 Received: (qmail 16790 invoked by uid 22791); 15 Sep 2008 20:23:30 -0000 X-Spam-Check-By: sourceware.org Received: from sibelius.xs4all.nl (HELO sibelius.xs4all.nl) (82.92.89.47) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 15 Sep 2008 20:22:55 +0000 Received: from brahms.sibelius.xs4all.nl (kettenis@localhost.sibelius.xs4all.nl [127.0.0.1]) by brahms.sibelius.xs4all.nl (8.14.3/8.14.3) with ESMTP id m8FKMdgL011500; Mon, 15 Sep 2008 22:22:39 +0200 (CEST) Received: (from kettenis@localhost) by brahms.sibelius.xs4all.nl (8.14.3/8.14.3/Submit) id m8FKMbbt017028; Mon, 15 Sep 2008 22:22:37 +0200 (CEST) Date: Mon, 15 Sep 2008 20:23:00 -0000 Message-Id: <200809152022.m8FKMbbt017028@brahms.sibelius.xs4all.nl> From: Mark Kettenis To: bauerman@br.ibm.com, gdb-patches@sourceware.org In-reply-to: <200809150920.m8F9KVTI023217@brahms.sibelius.xs4all.nl> (message from Mark Kettenis on Mon, 15 Sep 2008 11:20:31 +0200 (CEST)) Subject: Re: [PATCH/RFC] auxv entries References: <200809142127.m8ELR9eX025288@brahms.sibelius.xs4all.nl> <1221438784.17278.18.camel@localhost.localdomain> <200809150920.m8F9KVTI023217@brahms.sibelius.xs4all.nl> Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-09/txt/msg00340.txt.bz2 > Date: Mon, 15 Sep 2008 11:20:31 +0200 (CEST) > From: Mark Kettenis > > > From: Thiago Jung Bauermann > > Date: Sun, 14 Sep 2008 21:33:04 -0300 > > > > I have this in 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 * 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;