GNU Binutils with patches for OS216
Revision | 8a6c0ccdd27188047da2be9c2a49544c27dcade3 (tree) |
---|---|
Time | 2015-10-21 02:02:33 |
Author | Aleksandar Ristovski <aristovski@qnx....> |
Commiter | Aleksandar Ristovski |
[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.
@@ -1,5 +1,12 @@ | ||
1 | 1 | 2015-10-20 Aleksandar Ristovski <aristovski@qnx.com> |
2 | 2 | |
3 | + * nto-procfs.c (sys/auxv.h): Include. | |
4 | + (procfs_xfer_partial): Implement TARGET_OBJECT_AUXV. | |
5 | + * nto-tdep.c (nto_read_auxv_from_initial_stack): New function. | |
6 | + * nto-tdep.h (nto_read_auxv_from_initial_stack): New declaration. | |
7 | + | |
8 | +2015-10-20 Aleksandar Ristovski <aristovski@qnx.com> | |
9 | + | |
3 | 10 | * nto-procfs.c (nto_procfs_path): Rename to... |
4 | 11 | (nodestr): ... this, and change type. |
5 | 12 | (nto_node): Use new variable and logic accordingly. |
@@ -30,6 +30,8 @@ | ||
30 | 30 | #include <sys/syspage.h> |
31 | 31 | #include <dirent.h> |
32 | 32 | #include <sys/netmgr.h> |
33 | +#include <sys/auxv.h> | |
34 | + | |
33 | 35 | #include "gdbcore.h" |
34 | 36 | #include "inferior.h" |
35 | 37 | #include "target.h" |
@@ -885,6 +887,38 @@ procfs_xfer_partial (struct target_ops *ops, enum target_object object, | ||
885 | 887 | { |
886 | 888 | case TARGET_OBJECT_MEMORY: |
887 | 889 | return procfs_xfer_memory (readbuf, writebuf, offset, len, xfered_len); |
890 | + case TARGET_OBJECT_AUXV: | |
891 | + if (readbuf != NULL) | |
892 | + { | |
893 | + int err; | |
894 | + CORE_ADDR initial_stack; | |
895 | + debug_process_t procinfo; | |
896 | + /* For 32-bit architecture, size of auxv_t is 8 bytes. */ | |
897 | + const unsigned int sizeof_auxv_t = sizeof (auxv_t); | |
898 | + const unsigned int sizeof_tempbuf = 20 * sizeof_auxv_t; | |
899 | + int tempread; | |
900 | + gdb_byte *const tempbuf = alloca (sizeof_tempbuf); | |
901 | + | |
902 | + if (tempbuf == NULL) | |
903 | + return TARGET_XFER_E_IO; | |
904 | + | |
905 | + err = devctl (ctl_fd, DCMD_PROC_INFO, &procinfo, | |
906 | + sizeof procinfo, 0); | |
907 | + if (err != EOK) | |
908 | + return TARGET_XFER_E_IO; | |
909 | + | |
910 | + initial_stack = procinfo.initial_stack; | |
911 | + | |
912 | + /* procfs is always 'self-hosted', no byte-order manipulation. */ | |
913 | + tempread = nto_read_auxv_from_initial_stack (initial_stack, tempbuf, | |
914 | + sizeof_tempbuf, | |
915 | + sizeof (auxv_t)); | |
916 | + tempread = min (tempread, len) - offset; | |
917 | + memcpy (readbuf, tempbuf + offset, tempread); | |
918 | + *xfered_len = tempread; | |
919 | + return tempread ? TARGET_XFER_OK : TARGET_XFER_EOF; | |
920 | + } | |
921 | + /* Fallthru */ | |
888 | 922 | default: |
889 | 923 | return ops->beneath->to_xfer_partial (ops->beneath, object, annex, |
890 | 924 | readbuf, writebuf, offset, len, |
@@ -394,3 +394,86 @@ nto_initialize_signals (void) | ||
394 | 394 | signal_pass_update (SIGPHOTON, 1); |
395 | 395 | #endif |
396 | 396 | } |
397 | + | |
398 | +/* Read AUXV from initial_stack. */ | |
399 | +LONGEST | |
400 | +nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack, gdb_byte *readbuf, | |
401 | + LONGEST len, size_t sizeof_auxv_t) | |
402 | +{ | |
403 | + gdb_byte targ32[4]; /* For 32 bit target values. */ | |
404 | + gdb_byte targ64[8]; /* For 64 bit target values. */ | |
405 | + CORE_ADDR data_ofs = 0; | |
406 | + ULONGEST anint; | |
407 | + LONGEST len_read = 0; | |
408 | + gdb_byte *buff; | |
409 | + enum bfd_endian byte_order; | |
410 | + int ptr_size; | |
411 | + | |
412 | + if (sizeof_auxv_t == 16) | |
413 | + ptr_size = 8; | |
414 | + else | |
415 | + ptr_size = 4; | |
416 | + | |
417 | + /* Skip over argc, argv and envp... Comment from ldd.c: | |
418 | + | |
419 | + The startup frame is set-up so that we have: | |
420 | + auxv | |
421 | + NULL | |
422 | + ... | |
423 | + envp2 | |
424 | + envp1 <----- void *frame + (argc + 2) * sizeof(char *) | |
425 | + NULL | |
426 | + ... | |
427 | + argv2 | |
428 | + argv1 | |
429 | + argc <------ void * frame | |
430 | + | |
431 | + On entry to ldd, frame gives the address of argc on the stack. */ | |
432 | + /* Read argc. 4 bytes on both 64 and 32 bit arches and luckily little | |
433 | + * endian. So we just read first 4 bytes. */ | |
434 | + if (target_read_memory (initial_stack + data_ofs, targ32, 4) != 0) | |
435 | + return 0; | |
436 | + | |
437 | + byte_order = gdbarch_byte_order (target_gdbarch ()); | |
438 | + | |
439 | + anint = extract_unsigned_integer (targ32, sizeof (targ32), byte_order); | |
440 | + | |
441 | + /* Size of pointer is assumed to be 4 bytes (32 bit arch.) */ | |
442 | + data_ofs += (anint + 2) * ptr_size; /* + 2 comes from argc itself and | |
443 | + NULL terminating pointer in | |
444 | + argv. */ | |
445 | + | |
446 | + /* Now loop over env table: */ | |
447 | + anint = 0; | |
448 | + while (target_read_memory (initial_stack + data_ofs, targ64, ptr_size) | |
449 | + == 0) | |
450 | + { | |
451 | + if (extract_unsigned_integer (targ64, ptr_size, byte_order) == 0) | |
452 | + anint = 1; /* Keep looping until non-null entry is found. */ | |
453 | + else if (anint) | |
454 | + break; | |
455 | + data_ofs += ptr_size; | |
456 | + } | |
457 | + initial_stack += data_ofs; | |
458 | + | |
459 | + memset (readbuf, 0, len); | |
460 | + buff = readbuf; | |
461 | + while (len_read <= len-sizeof_auxv_t) | |
462 | + { | |
463 | + if (target_read_memory (initial_stack + len_read, buff, sizeof_auxv_t) | |
464 | + == 0) | |
465 | + { | |
466 | + /* Both 32 and 64 bit structures have int as the first field. */ | |
467 | + const ULONGEST a_type | |
468 | + = extract_unsigned_integer (buff, sizeof (targ32), byte_order); | |
469 | + | |
470 | + if (a_type == AT_NULL) | |
471 | + break; | |
472 | + buff += sizeof_auxv_t; | |
473 | + len_read += sizeof_auxv_t; | |
474 | + } | |
475 | + else | |
476 | + break; | |
477 | + } | |
478 | + return len_read; | |
479 | +} |
@@ -168,4 +168,7 @@ int nto_in_dynsym_resolve_code (CORE_ADDR pc); | ||
168 | 168 | |
169 | 169 | char *nto_extra_thread_info (struct target_ops *self, struct thread_info *); |
170 | 170 | |
171 | +LONGEST nto_read_auxv_from_initial_stack (CORE_ADDR inital_stack, | |
172 | + gdb_byte *readbuf, | |
173 | + LONGEST len, size_t sizeof_auxv_t); | |
171 | 174 | #endif |