From patchwork Tue Oct 20 15:42:33 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aleksandar Ristovski X-Patchwork-Id: 9267 Received: (qmail 82851 invoked by alias); 20 Oct 2015 15:42:39 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 82754 invoked by uid 89); 20 Oct 2015 15:42:38 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.6 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_SOFTFAIL autolearn=no version=3.3.2 X-HELO: smtp-a01.blackberry.com Received: from smtp-a01.blackberry.com (HELO smtp-a01.blackberry.com) (208.65.78.90) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 20 Oct 2015 15:42:35 +0000 Received: from mhs101cnc.rim.net ([10.65.141.79]) by mhs210cnc-app.rim.net with ESMTP; 20 Oct 2015 11:42:33 -0400 Received: from unknown (HELO [10.222.109.89]) ([10.65.140.253]) by mhs101cnc.rim.net with ESMTP; 20 Oct 2015 15:42:34 +0000 Subject: Re: [PATCH 2/3] (patch 2/4, v2) [nto] Implement TARGET_OBJECT_AUXV. To: "gdb-patches@sourceware.org" References: <56263FED.3050602@redhat.com> <1445351294-18179-1-git-send-email-aristovski@qnx.com> <1445351294-18179-3-git-send-email-aristovski@qnx.com> <56265BB2.6060204@redhat.com> From: Aleksandar Ristovski X-Enigmail-Draft-Status: N1110 Cc: Pedro Alves Message-ID: <562660E9.7000000@qnx.com> Date: Tue, 20 Oct 2015 11:42:33 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <56265BB2.6060204@redhat.com> On 15-10-20 11:20 AM, Pedro Alves wrote: > Does this result in any visible improvement? I assume that > at least, "info auxv" now works [1] [2]. It'd be really nice to have a > blurb in the commit log mentioning what motivated this. Yes, info auxv works on a live process. For the core I have other patches that need to go in first, but the mechanism of getting auxv remains the same; only determining initial stack changes. I will add something to the commit log. "Fix 'info auxv' for nto." > > [1] - BTW, if you enable gdb.base/auxv.exp on NTO, does it pass? > It fails since we have AT_* entries that are specific to nto, and get printed as ??? which causes regex to not match. I have it patched internally and print them out, but didn't think it would be acceptable upstream. (gdb) PASS: gdb.base/auxv.exp: continue info auxv^M 3 AT_PHDR Program headers for program 0x8048034^M 4 AT_PHENT Size of program header entry 32^M 5 AT_PHNUM Number of program headers 8^M 9 AT_ENTRY Entry point of program 0x8048668^M 6 AT_PAGESZ System page size 4096^M 7 AT_BASE Base address of interpreter 0xb0300000^M 12 AT_EUID Effective user ID 2050^M 13 AT_GID Real group ID 3221225482^M 47 ??? 0x8047f7d^M WARNING: Unrecognized tag value: 47 ??? 0x8047f7d^M (gdb) FAIL: gdb.base/auxv.exp: info auxv on live process > On 10/20/2015 03:28 PM, Aleksandar Ristovski wrote: >> gdb/ChangeLog: >> >> * nto-procfs.c (sys/auxv.h): Include. >> (procfs_xfer_partial): Implement TARGET_OBJECT_AUXV. >> * gdb/nto-tdep.c (nto_read_auxv_from_initial_stack): New function. >> * gdb/nto-tdep.h (nto_read_auxv_from_initial_stack): New declaration. > > Drop the "gdb/" in the file paths. > Ok, sorry. Used 'mklog' script and didn't remove gdb/. >> @@ -885,6 +887,40 @@ procfs_xfer_partial (struct target_ops *ops, enum target_object object, >> { ... >> + /* Similar as in the case of a core file, we read auxv from >> + initial_stack. */ > > Hmm, where's this "similar" you refer to? AFAICS, for cores, BFD > extracts it from the NT_AUVX note. We don't dump it in the note, we dump initial stack page containing it. > >> + initial_stack = procinfo.initial_stack; >> + >> + /* procfs is always 'self-hosted', no byte-order manipulation. */ > > Double-space after period. > Ok. > Otherwise looks OK. > Attaching the patch with double-space fix and added "what was fixed" in commit message. Thank you, Aleksandar Ristovski From 37c288bf9c2c945c63ab89eff6da459ee274c083 Mon Sep 17 00:00:00 2001 From: Aleksandar Ristovski Date: Tue, 20 Oct 2015 10:01:04 -0400 Subject: [PATCH] [nto] Implement TARGET_OBJECT_AUXV. Fix 'info auxv' for nto. gdb/ChangeLog: * nto-procfs.c (sys/auxv.h): Include. (procfs_xfer_partial): Implement TARGET_OBJECT_AUXV. * nto-tdep.c (nto_read_auxv_from_initial_stack): New function. * nto-tdep.h (nto_read_auxv_from_initial_stack): New declaration. --- gdb/nto-procfs.c | 36 ++++++++++++++++++++++++ gdb/nto-tdep.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ gdb/nto-tdep.h | 3 ++ 3 files changed, 122 insertions(+) diff --git a/gdb/nto-procfs.c b/gdb/nto-procfs.c index 264d88b..df8a344 100644 --- a/gdb/nto-procfs.c +++ b/gdb/nto-procfs.c @@ -30,6 +30,8 @@ #include #include #include +#include + #include "gdbcore.h" #include "inferior.h" #include "target.h" @@ -885,6 +887,40 @@ procfs_xfer_partial (struct target_ops *ops, enum target_object object, { case TARGET_OBJECT_MEMORY: return procfs_xfer_memory (readbuf, writebuf, offset, len, xfered_len); + case TARGET_OBJECT_AUXV: + if (readbuf != NULL) + { + int err; + CORE_ADDR initial_stack; + debug_process_t procinfo; + /* For 32-bit architecture, size of auxv_t is 8 bytes. */ + const unsigned int sizeof_auxv_t = sizeof (auxv_t); + const unsigned int sizeof_tempbuf = 20 * sizeof_auxv_t; + int tempread; + gdb_byte *const tempbuf = alloca (sizeof_tempbuf); + + if (tempbuf == NULL) + return TARGET_XFER_E_IO; + + err = devctl (ctl_fd, DCMD_PROC_INFO, &procinfo, + sizeof procinfo, 0); + if (err != EOK) + return TARGET_XFER_E_IO; + + /* Similar as in the case of a core file, we read auxv from + initial_stack. */ + initial_stack = procinfo.initial_stack; + + /* procfs is always 'self-hosted', no byte-order manipulation. */ + tempread = nto_read_auxv_from_initial_stack (initial_stack, tempbuf, + sizeof_tempbuf, + sizeof (auxv_t)); + tempread = min (tempread, len) - offset; + memcpy (readbuf, tempbuf + offset, tempread); + *xfered_len = tempread; + return tempread ? TARGET_XFER_OK : TARGET_XFER_EOF; + } + /* Fallthru */ default: return ops->beneath->to_xfer_partial (ops->beneath, object, annex, readbuf, writebuf, offset, len, diff --git a/gdb/nto-tdep.c b/gdb/nto-tdep.c index 81ee7fb..62eb88a 100644 --- a/gdb/nto-tdep.c +++ b/gdb/nto-tdep.c @@ -394,3 +394,86 @@ nto_initialize_signals (void) signal_pass_update (SIGPHOTON, 1); #endif } + +/* Read AUXV from initial_stack. */ +LONGEST +nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack, gdb_byte *readbuf, + LONGEST len, size_t sizeof_auxv_t) +{ + gdb_byte targ32[4]; /* For 32 bit target values. */ + gdb_byte targ64[8]; /* For 64 bit target values. */ + CORE_ADDR data_ofs = 0; + ULONGEST anint; + LONGEST len_read = 0; + gdb_byte *buff; + enum bfd_endian byte_order; + int ptr_size; + + if (sizeof_auxv_t == 16) + ptr_size = 8; + else + ptr_size = 4; + + /* Skip over argc, argv and envp... Comment from ldd.c: + + The startup frame is set-up so that we have: + auxv + NULL + ... + envp2 + envp1 <----- void *frame + (argc + 2) * sizeof(char *) + NULL + ... + argv2 + argv1 + argc <------ void * frame + + On entry to ldd, frame gives the address of argc on the stack. */ + /* Read argc. 4 bytes on both 64 and 32 bit arches and luckily little + * endian. So we just read first 4 bytes. */ + if (target_read_memory (initial_stack + data_ofs, targ32, 4) != 0) + return 0; + + byte_order = gdbarch_byte_order (target_gdbarch ()); + + anint = extract_unsigned_integer (targ32, sizeof (targ32), byte_order); + + /* Size of pointer is assumed to be 4 bytes (32 bit arch.) */ + data_ofs += (anint + 2) * ptr_size; /* + 2 comes from argc itself and + NULL terminating pointer in + argv. */ + + /* Now loop over env table: */ + anint = 0; + while (target_read_memory (initial_stack + data_ofs, targ64, ptr_size) + == 0) + { + if (extract_unsigned_integer (targ64, ptr_size, byte_order) == 0) + anint = 1; /* Keep looping until non-null entry is found. */ + else if (anint) + break; + data_ofs += ptr_size; + } + initial_stack += data_ofs; + + memset (readbuf, 0, len); + buff = readbuf; + while (len_read <= len-sizeof_auxv_t) + { + if (target_read_memory (initial_stack + len_read, buff, sizeof_auxv_t) + == 0) + { + /* Both 32 and 64 bit structures have int as the first field. */ + const ULONGEST a_type + = extract_unsigned_integer (buff, sizeof (targ32), byte_order); + + if (a_type == AT_NULL) + break; + buff += sizeof_auxv_t; + len_read += sizeof_auxv_t; + } + else + break; + } + return len_read; +} diff --git a/gdb/nto-tdep.h b/gdb/nto-tdep.h index bd85d2a..d029f07 100644 --- a/gdb/nto-tdep.h +++ b/gdb/nto-tdep.h @@ -168,4 +168,7 @@ int nto_in_dynsym_resolve_code (CORE_ADDR pc); char *nto_extra_thread_info (struct target_ops *self, struct thread_info *); +LONGEST nto_read_auxv_from_initial_stack (CORE_ADDR inital_stack, + gdb_byte *readbuf, + LONGEST len, size_t sizeof_auxv_t); #endif -- 1.9.1