15796c8dcSSimon Schubert /* Auxiliary vector support for GDB, the GNU debugger. 25796c8dcSSimon Schubert 3*cf7f2e2dSJohn Marino Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 45796c8dcSSimon Schubert Free Software Foundation, Inc. 55796c8dcSSimon Schubert 65796c8dcSSimon Schubert This file is part of GDB. 75796c8dcSSimon Schubert 85796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify 95796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by 105796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or 115796c8dcSSimon Schubert (at your option) any later version. 125796c8dcSSimon Schubert 135796c8dcSSimon Schubert This program is distributed in the hope that it will be useful, 145796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of 155796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 165796c8dcSSimon Schubert GNU General Public License for more details. 175796c8dcSSimon Schubert 185796c8dcSSimon Schubert You should have received a copy of the GNU General Public License 195796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */ 205796c8dcSSimon Schubert 215796c8dcSSimon Schubert #include "defs.h" 225796c8dcSSimon Schubert #include "target.h" 235796c8dcSSimon Schubert #include "gdbtypes.h" 245796c8dcSSimon Schubert #include "command.h" 255796c8dcSSimon Schubert #include "inferior.h" 265796c8dcSSimon Schubert #include "valprint.h" 275796c8dcSSimon Schubert #include "gdb_assert.h" 28*cf7f2e2dSJohn Marino #include "gdbcore.h" 295796c8dcSSimon Schubert 305796c8dcSSimon Schubert #include "auxv.h" 315796c8dcSSimon Schubert #include "elf/common.h" 325796c8dcSSimon Schubert 335796c8dcSSimon Schubert #include <unistd.h> 345796c8dcSSimon Schubert #include <fcntl.h> 355796c8dcSSimon Schubert 365796c8dcSSimon Schubert 37*cf7f2e2dSJohn Marino /* This function handles access via /proc/PID/auxv, which is a common method 38*cf7f2e2dSJohn Marino for native targets. */ 395796c8dcSSimon Schubert 40*cf7f2e2dSJohn Marino static LONGEST 41*cf7f2e2dSJohn Marino procfs_xfer_auxv (gdb_byte *readbuf, 425796c8dcSSimon Schubert const gdb_byte *writebuf, 435796c8dcSSimon Schubert ULONGEST offset, 445796c8dcSSimon Schubert LONGEST len) 455796c8dcSSimon Schubert { 465796c8dcSSimon Schubert char *pathname; 475796c8dcSSimon Schubert int fd; 485796c8dcSSimon Schubert LONGEST n; 495796c8dcSSimon Schubert 505796c8dcSSimon Schubert pathname = xstrprintf ("/proc/%d/auxv", PIDGET (inferior_ptid)); 515796c8dcSSimon Schubert fd = open (pathname, writebuf != NULL ? O_WRONLY : O_RDONLY); 525796c8dcSSimon Schubert xfree (pathname); 535796c8dcSSimon Schubert if (fd < 0) 545796c8dcSSimon Schubert return -1; 555796c8dcSSimon Schubert 565796c8dcSSimon Schubert if (offset != (ULONGEST) 0 575796c8dcSSimon Schubert && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset) 585796c8dcSSimon Schubert n = -1; 595796c8dcSSimon Schubert else if (readbuf != NULL) 605796c8dcSSimon Schubert n = read (fd, readbuf, len); 615796c8dcSSimon Schubert else 625796c8dcSSimon Schubert n = write (fd, writebuf, len); 635796c8dcSSimon Schubert 645796c8dcSSimon Schubert (void) close (fd); 655796c8dcSSimon Schubert 665796c8dcSSimon Schubert return n; 675796c8dcSSimon Schubert } 685796c8dcSSimon Schubert 69*cf7f2e2dSJohn Marino /* This function handles access via ld.so's symbol `_dl_auxv'. */ 70*cf7f2e2dSJohn Marino 71*cf7f2e2dSJohn Marino static LONGEST 72*cf7f2e2dSJohn Marino ld_so_xfer_auxv (gdb_byte *readbuf, 73*cf7f2e2dSJohn Marino const gdb_byte *writebuf, 74*cf7f2e2dSJohn Marino ULONGEST offset, 75*cf7f2e2dSJohn Marino LONGEST len) 76*cf7f2e2dSJohn Marino { 77*cf7f2e2dSJohn Marino struct minimal_symbol *msym; 78*cf7f2e2dSJohn Marino CORE_ADDR data_address, pointer_address; 79*cf7f2e2dSJohn Marino struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr; 80*cf7f2e2dSJohn Marino size_t ptr_size = TYPE_LENGTH (ptr_type); 81*cf7f2e2dSJohn Marino size_t auxv_pair_size = 2 * ptr_size; 82*cf7f2e2dSJohn Marino gdb_byte *ptr_buf = alloca (ptr_size); 83*cf7f2e2dSJohn Marino LONGEST retval; 84*cf7f2e2dSJohn Marino size_t block; 85*cf7f2e2dSJohn Marino 86*cf7f2e2dSJohn Marino msym = lookup_minimal_symbol ("_dl_auxv", NULL, NULL); 87*cf7f2e2dSJohn Marino if (msym == NULL) 88*cf7f2e2dSJohn Marino return -1; 89*cf7f2e2dSJohn Marino 90*cf7f2e2dSJohn Marino if (MSYMBOL_SIZE (msym) != ptr_size) 91*cf7f2e2dSJohn Marino return -1; 92*cf7f2e2dSJohn Marino 93*cf7f2e2dSJohn Marino /* POINTER_ADDRESS is a location where the `_dl_auxv' variable resides. 94*cf7f2e2dSJohn Marino DATA_ADDRESS is the inferior value present in `_dl_auxv', therefore the 95*cf7f2e2dSJohn Marino real inferior AUXV address. */ 96*cf7f2e2dSJohn Marino 97*cf7f2e2dSJohn Marino pointer_address = SYMBOL_VALUE_ADDRESS (msym); 98*cf7f2e2dSJohn Marino 99*cf7f2e2dSJohn Marino /* The location of the _dl_auxv symbol may no longer be correct if 100*cf7f2e2dSJohn Marino ld.so runs at a different address than the one present in the file. 101*cf7f2e2dSJohn Marino This is very common case - for unprelinked ld.so or with a PIE executable. 102*cf7f2e2dSJohn Marino PIE executable forces random address even for libraries already being 103*cf7f2e2dSJohn Marino prelinked to some address. PIE executables themselves are never prelinked 104*cf7f2e2dSJohn Marino even on prelinked systems. Prelinking of a PIE executable would block 105*cf7f2e2dSJohn Marino their purpose of randomizing load of everything including the executable. 106*cf7f2e2dSJohn Marino 107*cf7f2e2dSJohn Marino If the memory read fails, return -1 to fallback on another mechanism for 108*cf7f2e2dSJohn Marino retrieving the AUXV. 109*cf7f2e2dSJohn Marino 110*cf7f2e2dSJohn Marino In most cases of a PIE running under valgrind there is no way to find 111*cf7f2e2dSJohn Marino out the base addresses of any of ld.so, executable or AUXV as everything 112*cf7f2e2dSJohn Marino is randomized and /proc information is not relevant for the virtual 113*cf7f2e2dSJohn Marino executable running under valgrind. We think that we might need a valgrind 114*cf7f2e2dSJohn Marino extension to make it work. This is PR 11440. */ 115*cf7f2e2dSJohn Marino 116*cf7f2e2dSJohn Marino if (target_read_memory (pointer_address, ptr_buf, ptr_size) != 0) 117*cf7f2e2dSJohn Marino return -1; 118*cf7f2e2dSJohn Marino 119*cf7f2e2dSJohn Marino data_address = extract_typed_address (ptr_buf, ptr_type); 120*cf7f2e2dSJohn Marino 121*cf7f2e2dSJohn Marino /* Possibly still not initialized such as during an inferior startup. */ 122*cf7f2e2dSJohn Marino if (data_address == 0) 123*cf7f2e2dSJohn Marino return -1; 124*cf7f2e2dSJohn Marino 125*cf7f2e2dSJohn Marino data_address += offset; 126*cf7f2e2dSJohn Marino 127*cf7f2e2dSJohn Marino if (writebuf != NULL) 128*cf7f2e2dSJohn Marino { 129*cf7f2e2dSJohn Marino if (target_write_memory (data_address, writebuf, len) == 0) 130*cf7f2e2dSJohn Marino return len; 131*cf7f2e2dSJohn Marino else 132*cf7f2e2dSJohn Marino return -1; 133*cf7f2e2dSJohn Marino } 134*cf7f2e2dSJohn Marino 135*cf7f2e2dSJohn Marino /* Stop if trying to read past the existing AUXV block. The final AT_NULL 136*cf7f2e2dSJohn Marino was already returned before. */ 137*cf7f2e2dSJohn Marino 138*cf7f2e2dSJohn Marino if (offset >= auxv_pair_size) 139*cf7f2e2dSJohn Marino { 140*cf7f2e2dSJohn Marino if (target_read_memory (data_address - auxv_pair_size, ptr_buf, 141*cf7f2e2dSJohn Marino ptr_size) != 0) 142*cf7f2e2dSJohn Marino return -1; 143*cf7f2e2dSJohn Marino 144*cf7f2e2dSJohn Marino if (extract_typed_address (ptr_buf, ptr_type) == AT_NULL) 145*cf7f2e2dSJohn Marino return 0; 146*cf7f2e2dSJohn Marino } 147*cf7f2e2dSJohn Marino 148*cf7f2e2dSJohn Marino retval = 0; 149*cf7f2e2dSJohn Marino block = 0x400; 150*cf7f2e2dSJohn Marino gdb_assert (block % auxv_pair_size == 0); 151*cf7f2e2dSJohn Marino 152*cf7f2e2dSJohn Marino while (len > 0) 153*cf7f2e2dSJohn Marino { 154*cf7f2e2dSJohn Marino if (block > len) 155*cf7f2e2dSJohn Marino block = len; 156*cf7f2e2dSJohn Marino 157*cf7f2e2dSJohn Marino /* Reading sizes smaller than AUXV_PAIR_SIZE is not supported. Tails 158*cf7f2e2dSJohn Marino unaligned to AUXV_PAIR_SIZE will not be read during a call (they 159*cf7f2e2dSJohn Marino should be completed during next read with new/extended buffer). */ 160*cf7f2e2dSJohn Marino 161*cf7f2e2dSJohn Marino block &= -auxv_pair_size; 162*cf7f2e2dSJohn Marino if (block == 0) 163*cf7f2e2dSJohn Marino return retval; 164*cf7f2e2dSJohn Marino 165*cf7f2e2dSJohn Marino if (target_read_memory (data_address, readbuf, block) != 0) 166*cf7f2e2dSJohn Marino { 167*cf7f2e2dSJohn Marino if (block <= auxv_pair_size) 168*cf7f2e2dSJohn Marino return retval; 169*cf7f2e2dSJohn Marino 170*cf7f2e2dSJohn Marino block = auxv_pair_size; 171*cf7f2e2dSJohn Marino continue; 172*cf7f2e2dSJohn Marino } 173*cf7f2e2dSJohn Marino 174*cf7f2e2dSJohn Marino data_address += block; 175*cf7f2e2dSJohn Marino len -= block; 176*cf7f2e2dSJohn Marino 177*cf7f2e2dSJohn Marino /* Check terminal AT_NULL. This function is being called indefinitely 178*cf7f2e2dSJohn Marino being extended its READBUF until it returns EOF (0). */ 179*cf7f2e2dSJohn Marino 180*cf7f2e2dSJohn Marino while (block >= auxv_pair_size) 181*cf7f2e2dSJohn Marino { 182*cf7f2e2dSJohn Marino retval += auxv_pair_size; 183*cf7f2e2dSJohn Marino 184*cf7f2e2dSJohn Marino if (extract_typed_address (readbuf, ptr_type) == AT_NULL) 185*cf7f2e2dSJohn Marino return retval; 186*cf7f2e2dSJohn Marino 187*cf7f2e2dSJohn Marino readbuf += auxv_pair_size; 188*cf7f2e2dSJohn Marino block -= auxv_pair_size; 189*cf7f2e2dSJohn Marino } 190*cf7f2e2dSJohn Marino } 191*cf7f2e2dSJohn Marino 192*cf7f2e2dSJohn Marino return retval; 193*cf7f2e2dSJohn Marino } 194*cf7f2e2dSJohn Marino 195*cf7f2e2dSJohn Marino /* This function is called like a to_xfer_partial hook, but must be 196*cf7f2e2dSJohn Marino called with TARGET_OBJECT_AUXV. It handles access to AUXV. */ 197*cf7f2e2dSJohn Marino 198*cf7f2e2dSJohn Marino LONGEST 199*cf7f2e2dSJohn Marino memory_xfer_auxv (struct target_ops *ops, 200*cf7f2e2dSJohn Marino enum target_object object, 201*cf7f2e2dSJohn Marino const char *annex, 202*cf7f2e2dSJohn Marino gdb_byte *readbuf, 203*cf7f2e2dSJohn Marino const gdb_byte *writebuf, 204*cf7f2e2dSJohn Marino ULONGEST offset, 205*cf7f2e2dSJohn Marino LONGEST len) 206*cf7f2e2dSJohn Marino { 207*cf7f2e2dSJohn Marino gdb_assert (object == TARGET_OBJECT_AUXV); 208*cf7f2e2dSJohn Marino gdb_assert (readbuf || writebuf); 209*cf7f2e2dSJohn Marino 210*cf7f2e2dSJohn Marino /* ld_so_xfer_auxv is the only function safe for virtual executables being 211*cf7f2e2dSJohn Marino executed by valgrind's memcheck. Using ld_so_xfer_auxv during inferior 212*cf7f2e2dSJohn Marino startup is problematic, because ld.so symbol tables have not yet been 213*cf7f2e2dSJohn Marino relocated. So GDB uses this function only when attaching to a process. 214*cf7f2e2dSJohn Marino */ 215*cf7f2e2dSJohn Marino 216*cf7f2e2dSJohn Marino if (current_inferior ()->attach_flag != 0) 217*cf7f2e2dSJohn Marino { 218*cf7f2e2dSJohn Marino LONGEST retval; 219*cf7f2e2dSJohn Marino 220*cf7f2e2dSJohn Marino retval = ld_so_xfer_auxv (readbuf, writebuf, offset, len); 221*cf7f2e2dSJohn Marino if (retval != -1) 222*cf7f2e2dSJohn Marino return retval; 223*cf7f2e2dSJohn Marino } 224*cf7f2e2dSJohn Marino 225*cf7f2e2dSJohn Marino return procfs_xfer_auxv (readbuf, writebuf, offset, len); 226*cf7f2e2dSJohn Marino } 227*cf7f2e2dSJohn Marino 2285796c8dcSSimon Schubert /* Read one auxv entry from *READPTR, not reading locations >= ENDPTR. 2295796c8dcSSimon Schubert Return 0 if *READPTR is already at the end of the buffer. 2305796c8dcSSimon Schubert Return -1 if there is insufficient buffer for a whole entry. 2315796c8dcSSimon Schubert Return 1 if an entry was read into *TYPEP and *VALP. */ 2325796c8dcSSimon Schubert static int 2335796c8dcSSimon Schubert default_auxv_parse (struct target_ops *ops, gdb_byte **readptr, 2345796c8dcSSimon Schubert gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) 2355796c8dcSSimon Schubert { 2365796c8dcSSimon Schubert const int sizeof_auxv_field = gdbarch_ptr_bit (target_gdbarch) 2375796c8dcSSimon Schubert / TARGET_CHAR_BIT; 2385796c8dcSSimon Schubert const enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); 2395796c8dcSSimon Schubert gdb_byte *ptr = *readptr; 2405796c8dcSSimon Schubert 2415796c8dcSSimon Schubert if (endptr == ptr) 2425796c8dcSSimon Schubert return 0; 2435796c8dcSSimon Schubert 2445796c8dcSSimon Schubert if (endptr - ptr < sizeof_auxv_field * 2) 2455796c8dcSSimon Schubert return -1; 2465796c8dcSSimon Schubert 2475796c8dcSSimon Schubert *typep = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order); 2485796c8dcSSimon Schubert ptr += sizeof_auxv_field; 2495796c8dcSSimon Schubert *valp = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order); 2505796c8dcSSimon Schubert ptr += sizeof_auxv_field; 2515796c8dcSSimon Schubert 2525796c8dcSSimon Schubert *readptr = ptr; 2535796c8dcSSimon Schubert return 1; 2545796c8dcSSimon Schubert } 2555796c8dcSSimon Schubert 2565796c8dcSSimon Schubert /* Read one auxv entry from *READPTR, not reading locations >= ENDPTR. 2575796c8dcSSimon Schubert Return 0 if *READPTR is already at the end of the buffer. 2585796c8dcSSimon Schubert Return -1 if there is insufficient buffer for a whole entry. 2595796c8dcSSimon Schubert Return 1 if an entry was read into *TYPEP and *VALP. */ 2605796c8dcSSimon Schubert int 2615796c8dcSSimon Schubert target_auxv_parse (struct target_ops *ops, gdb_byte **readptr, 2625796c8dcSSimon Schubert gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) 2635796c8dcSSimon Schubert { 2645796c8dcSSimon Schubert struct target_ops *t; 265*cf7f2e2dSJohn Marino 2665796c8dcSSimon Schubert for (t = ops; t != NULL; t = t->beneath) 2675796c8dcSSimon Schubert if (t->to_auxv_parse != NULL) 2685796c8dcSSimon Schubert return t->to_auxv_parse (t, readptr, endptr, typep, valp); 2695796c8dcSSimon Schubert 2705796c8dcSSimon Schubert return default_auxv_parse (ops, readptr, endptr, typep, valp); 2715796c8dcSSimon Schubert } 2725796c8dcSSimon Schubert 2735796c8dcSSimon Schubert /* Extract the auxiliary vector entry with a_type matching MATCH. 2745796c8dcSSimon Schubert Return zero if no such entry was found, or -1 if there was 2755796c8dcSSimon Schubert an error getting the information. On success, return 1 after 2765796c8dcSSimon Schubert storing the entry's value field in *VALP. */ 2775796c8dcSSimon Schubert int 2785796c8dcSSimon Schubert target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp) 2795796c8dcSSimon Schubert { 2805796c8dcSSimon Schubert CORE_ADDR type, val; 2815796c8dcSSimon Schubert gdb_byte *data; 2825796c8dcSSimon Schubert LONGEST n = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL, &data); 2835796c8dcSSimon Schubert gdb_byte *ptr = data; 2845796c8dcSSimon Schubert 2855796c8dcSSimon Schubert if (n <= 0) 2865796c8dcSSimon Schubert return n; 2875796c8dcSSimon Schubert 2885796c8dcSSimon Schubert while (1) 2895796c8dcSSimon Schubert switch (target_auxv_parse (ops, &ptr, data + n, &type, &val)) 2905796c8dcSSimon Schubert { 2915796c8dcSSimon Schubert case 1: /* Here's an entry, check it. */ 2925796c8dcSSimon Schubert if (type == match) 2935796c8dcSSimon Schubert { 2945796c8dcSSimon Schubert xfree (data); 2955796c8dcSSimon Schubert *valp = val; 2965796c8dcSSimon Schubert return 1; 2975796c8dcSSimon Schubert } 2985796c8dcSSimon Schubert break; 2995796c8dcSSimon Schubert case 0: /* End of the vector. */ 3005796c8dcSSimon Schubert xfree (data); 3015796c8dcSSimon Schubert return 0; 3025796c8dcSSimon Schubert default: /* Bogosity. */ 3035796c8dcSSimon Schubert xfree (data); 3045796c8dcSSimon Schubert return -1; 3055796c8dcSSimon Schubert } 3065796c8dcSSimon Schubert 3075796c8dcSSimon Schubert /*NOTREACHED*/ 3085796c8dcSSimon Schubert } 3095796c8dcSSimon Schubert 3105796c8dcSSimon Schubert 3115796c8dcSSimon Schubert /* Print the contents of the target's AUXV on the specified file. */ 3125796c8dcSSimon Schubert int 3135796c8dcSSimon Schubert fprint_target_auxv (struct ui_file *file, struct target_ops *ops) 3145796c8dcSSimon Schubert { 3155796c8dcSSimon Schubert CORE_ADDR type, val; 3165796c8dcSSimon Schubert gdb_byte *data; 3175796c8dcSSimon Schubert LONGEST len = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL, 3185796c8dcSSimon Schubert &data); 3195796c8dcSSimon Schubert gdb_byte *ptr = data; 3205796c8dcSSimon Schubert int ents = 0; 3215796c8dcSSimon Schubert 3225796c8dcSSimon Schubert if (len <= 0) 3235796c8dcSSimon Schubert return len; 3245796c8dcSSimon Schubert 3255796c8dcSSimon Schubert while (target_auxv_parse (ops, &ptr, data + len, &type, &val) > 0) 3265796c8dcSSimon Schubert { 3275796c8dcSSimon Schubert const char *name = "???"; 3285796c8dcSSimon Schubert const char *description = ""; 3295796c8dcSSimon Schubert enum { dec, hex, str } flavor = hex; 3305796c8dcSSimon Schubert 3315796c8dcSSimon Schubert switch (type) 3325796c8dcSSimon Schubert { 3335796c8dcSSimon Schubert #define TAG(tag, text, kind) \ 3345796c8dcSSimon Schubert case tag: name = #tag; description = text; flavor = kind; break 3355796c8dcSSimon Schubert TAG (AT_NULL, _("End of vector"), hex); 3365796c8dcSSimon Schubert TAG (AT_IGNORE, _("Entry should be ignored"), hex); 3375796c8dcSSimon Schubert TAG (AT_EXECFD, _("File descriptor of program"), dec); 3385796c8dcSSimon Schubert TAG (AT_PHDR, _("Program headers for program"), hex); 3395796c8dcSSimon Schubert TAG (AT_PHENT, _("Size of program header entry"), dec); 3405796c8dcSSimon Schubert TAG (AT_PHNUM, _("Number of program headers"), dec); 3415796c8dcSSimon Schubert TAG (AT_PAGESZ, _("System page size"), dec); 3425796c8dcSSimon Schubert TAG (AT_BASE, _("Base address of interpreter"), hex); 3435796c8dcSSimon Schubert TAG (AT_FLAGS, _("Flags"), hex); 3445796c8dcSSimon Schubert TAG (AT_ENTRY, _("Entry point of program"), hex); 3455796c8dcSSimon Schubert TAG (AT_NOTELF, _("Program is not ELF"), dec); 3465796c8dcSSimon Schubert TAG (AT_UID, _("Real user ID"), dec); 3475796c8dcSSimon Schubert TAG (AT_EUID, _("Effective user ID"), dec); 3485796c8dcSSimon Schubert TAG (AT_GID, _("Real group ID"), dec); 3495796c8dcSSimon Schubert TAG (AT_EGID, _("Effective group ID"), dec); 3505796c8dcSSimon Schubert TAG (AT_CLKTCK, _("Frequency of times()"), dec); 3515796c8dcSSimon Schubert TAG (AT_PLATFORM, _("String identifying platform"), str); 3525796c8dcSSimon Schubert TAG (AT_HWCAP, _("Machine-dependent CPU capability hints"), hex); 3535796c8dcSSimon Schubert TAG (AT_FPUCW, _("Used FPU control word"), dec); 3545796c8dcSSimon Schubert TAG (AT_DCACHEBSIZE, _("Data cache block size"), dec); 3555796c8dcSSimon Schubert TAG (AT_ICACHEBSIZE, _("Instruction cache block size"), dec); 3565796c8dcSSimon Schubert TAG (AT_UCACHEBSIZE, _("Unified cache block size"), dec); 3575796c8dcSSimon Schubert TAG (AT_IGNOREPPC, _("Entry should be ignored"), dec); 3585796c8dcSSimon Schubert TAG (AT_BASE_PLATFORM, _("String identifying base platform"), str); 3595796c8dcSSimon Schubert TAG (AT_RANDOM, _("Address of 16 random bytes"), hex); 3605796c8dcSSimon Schubert TAG (AT_EXECFN, _("File name of executable"), str); 3615796c8dcSSimon Schubert TAG (AT_SECURE, _("Boolean, was exec setuid-like?"), dec); 3625796c8dcSSimon Schubert TAG (AT_SYSINFO, _("Special system info/entry points"), hex); 3635796c8dcSSimon Schubert TAG (AT_SYSINFO_EHDR, _("System-supplied DSO's ELF header"), hex); 3645796c8dcSSimon Schubert TAG (AT_SUN_UID, _("Effective user ID"), dec); 3655796c8dcSSimon Schubert TAG (AT_SUN_RUID, _("Real user ID"), dec); 3665796c8dcSSimon Schubert TAG (AT_SUN_GID, _("Effective group ID"), dec); 3675796c8dcSSimon Schubert TAG (AT_SUN_RGID, _("Real group ID"), dec); 3685796c8dcSSimon Schubert TAG (AT_SUN_LDELF, _("Dynamic linker's ELF header"), hex); 3695796c8dcSSimon Schubert TAG (AT_SUN_LDSHDR, _("Dynamic linker's section headers"), hex); 3705796c8dcSSimon Schubert TAG (AT_SUN_LDNAME, _("String giving name of dynamic linker"), str); 3715796c8dcSSimon Schubert TAG (AT_SUN_LPAGESZ, _("Large pagesize"), dec); 3725796c8dcSSimon Schubert TAG (AT_SUN_PLATFORM, _("Platform name string"), str); 3735796c8dcSSimon Schubert TAG (AT_SUN_HWCAP, _("Machine-dependent CPU capability hints"), hex); 3745796c8dcSSimon Schubert TAG (AT_SUN_IFLUSH, _("Should flush icache?"), dec); 3755796c8dcSSimon Schubert TAG (AT_SUN_CPU, _("CPU name string"), str); 3765796c8dcSSimon Schubert TAG (AT_SUN_EMUL_ENTRY, _("COFF entry point address"), hex); 3775796c8dcSSimon Schubert TAG (AT_SUN_EMUL_EXECFD, _("COFF executable file descriptor"), dec); 3785796c8dcSSimon Schubert TAG (AT_SUN_EXECNAME, 3795796c8dcSSimon Schubert _("Canonicalized file name given to execve"), str); 3805796c8dcSSimon Schubert TAG (AT_SUN_MMU, _("String for name of MMU module"), str); 3815796c8dcSSimon Schubert TAG (AT_SUN_LDDATA, _("Dynamic linker's data segment address"), hex); 3825796c8dcSSimon Schubert TAG (AT_SUN_AUXFLAGS, 3835796c8dcSSimon Schubert _("AF_SUN_ flags passed from the kernel"), hex); 3845796c8dcSSimon Schubert } 3855796c8dcSSimon Schubert 3865796c8dcSSimon Schubert fprintf_filtered (file, "%-4s %-20s %-30s ", 3875796c8dcSSimon Schubert plongest (type), name, description); 3885796c8dcSSimon Schubert switch (flavor) 3895796c8dcSSimon Schubert { 3905796c8dcSSimon Schubert case dec: 3915796c8dcSSimon Schubert fprintf_filtered (file, "%s\n", plongest (val)); 3925796c8dcSSimon Schubert break; 3935796c8dcSSimon Schubert case hex: 3945796c8dcSSimon Schubert fprintf_filtered (file, "%s\n", paddress (target_gdbarch, val)); 3955796c8dcSSimon Schubert break; 3965796c8dcSSimon Schubert case str: 3975796c8dcSSimon Schubert { 3985796c8dcSSimon Schubert struct value_print_options opts; 399*cf7f2e2dSJohn Marino 4005796c8dcSSimon Schubert get_user_print_options (&opts); 4015796c8dcSSimon Schubert if (opts.addressprint) 4025796c8dcSSimon Schubert fprintf_filtered (file, "%s", paddress (target_gdbarch, val)); 4035796c8dcSSimon Schubert val_print_string (builtin_type (target_gdbarch)->builtin_char, 4045796c8dcSSimon Schubert val, -1, file, &opts); 4055796c8dcSSimon Schubert fprintf_filtered (file, "\n"); 4065796c8dcSSimon Schubert } 4075796c8dcSSimon Schubert break; 4085796c8dcSSimon Schubert } 4095796c8dcSSimon Schubert ++ents; 4105796c8dcSSimon Schubert if (type == AT_NULL) 4115796c8dcSSimon Schubert break; 4125796c8dcSSimon Schubert } 4135796c8dcSSimon Schubert 4145796c8dcSSimon Schubert xfree (data); 4155796c8dcSSimon Schubert 4165796c8dcSSimon Schubert return ents; 4175796c8dcSSimon Schubert } 4185796c8dcSSimon Schubert 4195796c8dcSSimon Schubert static void 4205796c8dcSSimon Schubert info_auxv_command (char *cmd, int from_tty) 4215796c8dcSSimon Schubert { 4225796c8dcSSimon Schubert if (! target_has_stack) 4235796c8dcSSimon Schubert error (_("The program has no auxiliary information now.")); 4245796c8dcSSimon Schubert else 4255796c8dcSSimon Schubert { 4265796c8dcSSimon Schubert int ents = fprint_target_auxv (gdb_stdout, ¤t_target); 427*cf7f2e2dSJohn Marino 4285796c8dcSSimon Schubert if (ents < 0) 4295796c8dcSSimon Schubert error (_("No auxiliary vector found, or failed reading it.")); 4305796c8dcSSimon Schubert else if (ents == 0) 4315796c8dcSSimon Schubert error (_("Auxiliary vector is empty.")); 4325796c8dcSSimon Schubert } 4335796c8dcSSimon Schubert } 4345796c8dcSSimon Schubert 4355796c8dcSSimon Schubert 4365796c8dcSSimon Schubert extern initialize_file_ftype _initialize_auxv; /* -Wmissing-prototypes; */ 4375796c8dcSSimon Schubert 4385796c8dcSSimon Schubert void 4395796c8dcSSimon Schubert _initialize_auxv (void) 4405796c8dcSSimon Schubert { 4415796c8dcSSimon Schubert add_info ("auxv", info_auxv_command, 4425796c8dcSSimon Schubert _("Display the inferior's auxiliary vector.\n\ 4435796c8dcSSimon Schubert This is information provided by the operating system at program startup.")); 4445796c8dcSSimon Schubert } 445