[2/3] (patch 2/4, v2) [nto] Implement TARGET_OBJECT_AUXV.
Commit Message
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
Comments
On 10/20/2015 04:42 PM, Aleksandar Ristovski wrote:
> 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.
OK, but please clarify or drop the misleading comment until
those patches go in then. Please push with that fixed.
>
> I will add something to the commit log.
> "Fix 'info auxv' for nto."
Thanks.
>> [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.
Why wouldn't it? If the issue is that the numbers conflict with other
ports, then it can be handled with a gdbarch method.
Thanks,
Pedro Alves
From 37c288bf9c2c945c63ab89eff6da459ee274c083 Mon Sep 17 00:00:00 2001
From: Aleksandar Ristovski <aristovski@qnx.com>
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(+)
@@ -30,6 +30,8 @@
#include <sys/syspage.h>
#include <dirent.h>
#include <sys/netmgr.h>
+#include <sys/auxv.h>
+
#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,
@@ -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;
+}
@@ -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