1 /* Auxiliary vector support for GDB, the GNU debugger. 2 3 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 4 Free Software Foundation, Inc. 5 6 This file is part of GDB. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 21 #include "defs.h" 22 #include "target.h" 23 #include "gdbtypes.h" 24 #include "command.h" 25 #include "inferior.h" 26 #include "valprint.h" 27 #include "gdb_assert.h" 28 #include "gdbcore.h" 29 30 #include "auxv.h" 31 #include "elf/common.h" 32 33 #include <unistd.h> 34 #include <fcntl.h> 35 36 37 /* This function handles access via /proc/PID/auxv, which is a common method 38 for native targets. */ 39 40 static LONGEST 41 procfs_xfer_auxv (gdb_byte *readbuf, 42 const gdb_byte *writebuf, 43 ULONGEST offset, 44 LONGEST len) 45 { 46 char *pathname; 47 int fd; 48 LONGEST n; 49 50 pathname = xstrprintf ("/proc/%d/auxv", PIDGET (inferior_ptid)); 51 fd = open (pathname, writebuf != NULL ? O_WRONLY : O_RDONLY); 52 xfree (pathname); 53 if (fd < 0) 54 return -1; 55 56 if (offset != (ULONGEST) 0 57 && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset) 58 n = -1; 59 else if (readbuf != NULL) 60 n = read (fd, readbuf, len); 61 else 62 n = write (fd, writebuf, len); 63 64 (void) close (fd); 65 66 return n; 67 } 68 69 /* This function handles access via ld.so's symbol `_dl_auxv'. */ 70 71 static LONGEST 72 ld_so_xfer_auxv (gdb_byte *readbuf, 73 const gdb_byte *writebuf, 74 ULONGEST offset, 75 LONGEST len) 76 { 77 struct minimal_symbol *msym; 78 CORE_ADDR data_address, pointer_address; 79 struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr; 80 size_t ptr_size = TYPE_LENGTH (ptr_type); 81 size_t auxv_pair_size = 2 * ptr_size; 82 gdb_byte *ptr_buf = alloca (ptr_size); 83 LONGEST retval; 84 size_t block; 85 86 msym = lookup_minimal_symbol ("_dl_auxv", NULL, NULL); 87 if (msym == NULL) 88 return -1; 89 90 if (MSYMBOL_SIZE (msym) != ptr_size) 91 return -1; 92 93 /* POINTER_ADDRESS is a location where the `_dl_auxv' variable resides. 94 DATA_ADDRESS is the inferior value present in `_dl_auxv', therefore the 95 real inferior AUXV address. */ 96 97 pointer_address = SYMBOL_VALUE_ADDRESS (msym); 98 99 /* The location of the _dl_auxv symbol may no longer be correct if 100 ld.so runs at a different address than the one present in the file. 101 This is very common case - for unprelinked ld.so or with a PIE executable. 102 PIE executable forces random address even for libraries already being 103 prelinked to some address. PIE executables themselves are never prelinked 104 even on prelinked systems. Prelinking of a PIE executable would block 105 their purpose of randomizing load of everything including the executable. 106 107 If the memory read fails, return -1 to fallback on another mechanism for 108 retrieving the AUXV. 109 110 In most cases of a PIE running under valgrind there is no way to find 111 out the base addresses of any of ld.so, executable or AUXV as everything 112 is randomized and /proc information is not relevant for the virtual 113 executable running under valgrind. We think that we might need a valgrind 114 extension to make it work. This is PR 11440. */ 115 116 if (target_read_memory (pointer_address, ptr_buf, ptr_size) != 0) 117 return -1; 118 119 data_address = extract_typed_address (ptr_buf, ptr_type); 120 121 /* Possibly still not initialized such as during an inferior startup. */ 122 if (data_address == 0) 123 return -1; 124 125 data_address += offset; 126 127 if (writebuf != NULL) 128 { 129 if (target_write_memory (data_address, writebuf, len) == 0) 130 return len; 131 else 132 return -1; 133 } 134 135 /* Stop if trying to read past the existing AUXV block. The final AT_NULL 136 was already returned before. */ 137 138 if (offset >= auxv_pair_size) 139 { 140 if (target_read_memory (data_address - auxv_pair_size, ptr_buf, 141 ptr_size) != 0) 142 return -1; 143 144 if (extract_typed_address (ptr_buf, ptr_type) == AT_NULL) 145 return 0; 146 } 147 148 retval = 0; 149 block = 0x400; 150 gdb_assert (block % auxv_pair_size == 0); 151 152 while (len > 0) 153 { 154 if (block > len) 155 block = len; 156 157 /* Reading sizes smaller than AUXV_PAIR_SIZE is not supported. Tails 158 unaligned to AUXV_PAIR_SIZE will not be read during a call (they 159 should be completed during next read with new/extended buffer). */ 160 161 block &= -auxv_pair_size; 162 if (block == 0) 163 return retval; 164 165 if (target_read_memory (data_address, readbuf, block) != 0) 166 { 167 if (block <= auxv_pair_size) 168 return retval; 169 170 block = auxv_pair_size; 171 continue; 172 } 173 174 data_address += block; 175 len -= block; 176 177 /* Check terminal AT_NULL. This function is being called indefinitely 178 being extended its READBUF until it returns EOF (0). */ 179 180 while (block >= auxv_pair_size) 181 { 182 retval += auxv_pair_size; 183 184 if (extract_typed_address (readbuf, ptr_type) == AT_NULL) 185 return retval; 186 187 readbuf += auxv_pair_size; 188 block -= auxv_pair_size; 189 } 190 } 191 192 return retval; 193 } 194 195 /* This function is called like a to_xfer_partial hook, but must be 196 called with TARGET_OBJECT_AUXV. It handles access to AUXV. */ 197 198 LONGEST 199 memory_xfer_auxv (struct target_ops *ops, 200 enum target_object object, 201 const char *annex, 202 gdb_byte *readbuf, 203 const gdb_byte *writebuf, 204 ULONGEST offset, 205 LONGEST len) 206 { 207 gdb_assert (object == TARGET_OBJECT_AUXV); 208 gdb_assert (readbuf || writebuf); 209 210 /* ld_so_xfer_auxv is the only function safe for virtual executables being 211 executed by valgrind's memcheck. Using ld_so_xfer_auxv during inferior 212 startup is problematic, because ld.so symbol tables have not yet been 213 relocated. So GDB uses this function only when attaching to a process. 214 */ 215 216 if (current_inferior ()->attach_flag != 0) 217 { 218 LONGEST retval; 219 220 retval = ld_so_xfer_auxv (readbuf, writebuf, offset, len); 221 if (retval != -1) 222 return retval; 223 } 224 225 return procfs_xfer_auxv (readbuf, writebuf, offset, len); 226 } 227 228 /* Read one auxv entry from *READPTR, not reading locations >= ENDPTR. 229 Return 0 if *READPTR is already at the end of the buffer. 230 Return -1 if there is insufficient buffer for a whole entry. 231 Return 1 if an entry was read into *TYPEP and *VALP. */ 232 static int 233 default_auxv_parse (struct target_ops *ops, gdb_byte **readptr, 234 gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) 235 { 236 const int sizeof_auxv_field = gdbarch_ptr_bit (target_gdbarch) 237 / TARGET_CHAR_BIT; 238 const enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); 239 gdb_byte *ptr = *readptr; 240 241 if (endptr == ptr) 242 return 0; 243 244 if (endptr - ptr < sizeof_auxv_field * 2) 245 return -1; 246 247 *typep = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order); 248 ptr += sizeof_auxv_field; 249 *valp = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order); 250 ptr += sizeof_auxv_field; 251 252 *readptr = ptr; 253 return 1; 254 } 255 256 /* Read one auxv entry from *READPTR, not reading locations >= ENDPTR. 257 Return 0 if *READPTR is already at the end of the buffer. 258 Return -1 if there is insufficient buffer for a whole entry. 259 Return 1 if an entry was read into *TYPEP and *VALP. */ 260 int 261 target_auxv_parse (struct target_ops *ops, gdb_byte **readptr, 262 gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) 263 { 264 struct target_ops *t; 265 266 for (t = ops; t != NULL; t = t->beneath) 267 if (t->to_auxv_parse != NULL) 268 return t->to_auxv_parse (t, readptr, endptr, typep, valp); 269 270 return default_auxv_parse (ops, readptr, endptr, typep, valp); 271 } 272 273 /* Extract the auxiliary vector entry with a_type matching MATCH. 274 Return zero if no such entry was found, or -1 if there was 275 an error getting the information. On success, return 1 after 276 storing the entry's value field in *VALP. */ 277 int 278 target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp) 279 { 280 CORE_ADDR type, val; 281 gdb_byte *data; 282 LONGEST n = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL, &data); 283 gdb_byte *ptr = data; 284 285 if (n <= 0) 286 return n; 287 288 while (1) 289 switch (target_auxv_parse (ops, &ptr, data + n, &type, &val)) 290 { 291 case 1: /* Here's an entry, check it. */ 292 if (type == match) 293 { 294 xfree (data); 295 *valp = val; 296 return 1; 297 } 298 break; 299 case 0: /* End of the vector. */ 300 xfree (data); 301 return 0; 302 default: /* Bogosity. */ 303 xfree (data); 304 return -1; 305 } 306 307 /*NOTREACHED*/ 308 } 309 310 311 /* Print the contents of the target's AUXV on the specified file. */ 312 int 313 fprint_target_auxv (struct ui_file *file, struct target_ops *ops) 314 { 315 CORE_ADDR type, val; 316 gdb_byte *data; 317 LONGEST len = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL, 318 &data); 319 gdb_byte *ptr = data; 320 int ents = 0; 321 322 if (len <= 0) 323 return len; 324 325 while (target_auxv_parse (ops, &ptr, data + len, &type, &val) > 0) 326 { 327 const char *name = "???"; 328 const char *description = ""; 329 enum { dec, hex, str } flavor = hex; 330 331 switch (type) 332 { 333 #define TAG(tag, text, kind) \ 334 case tag: name = #tag; description = text; flavor = kind; break 335 TAG (AT_NULL, _("End of vector"), hex); 336 TAG (AT_IGNORE, _("Entry should be ignored"), hex); 337 TAG (AT_EXECFD, _("File descriptor of program"), dec); 338 TAG (AT_PHDR, _("Program headers for program"), hex); 339 TAG (AT_PHENT, _("Size of program header entry"), dec); 340 TAG (AT_PHNUM, _("Number of program headers"), dec); 341 TAG (AT_PAGESZ, _("System page size"), dec); 342 TAG (AT_BASE, _("Base address of interpreter"), hex); 343 TAG (AT_FLAGS, _("Flags"), hex); 344 TAG (AT_ENTRY, _("Entry point of program"), hex); 345 TAG (AT_NOTELF, _("Program is not ELF"), dec); 346 TAG (AT_UID, _("Real user ID"), dec); 347 TAG (AT_EUID, _("Effective user ID"), dec); 348 TAG (AT_GID, _("Real group ID"), dec); 349 TAG (AT_EGID, _("Effective group ID"), dec); 350 TAG (AT_CLKTCK, _("Frequency of times()"), dec); 351 TAG (AT_PLATFORM, _("String identifying platform"), str); 352 TAG (AT_HWCAP, _("Machine-dependent CPU capability hints"), hex); 353 TAG (AT_FPUCW, _("Used FPU control word"), dec); 354 TAG (AT_DCACHEBSIZE, _("Data cache block size"), dec); 355 TAG (AT_ICACHEBSIZE, _("Instruction cache block size"), dec); 356 TAG (AT_UCACHEBSIZE, _("Unified cache block size"), dec); 357 TAG (AT_IGNOREPPC, _("Entry should be ignored"), dec); 358 TAG (AT_BASE_PLATFORM, _("String identifying base platform"), str); 359 TAG (AT_RANDOM, _("Address of 16 random bytes"), hex); 360 TAG (AT_EXECFN, _("File name of executable"), str); 361 TAG (AT_SECURE, _("Boolean, was exec setuid-like?"), dec); 362 TAG (AT_SYSINFO, _("Special system info/entry points"), hex); 363 TAG (AT_SYSINFO_EHDR, _("System-supplied DSO's ELF header"), hex); 364 TAG (AT_SUN_UID, _("Effective user ID"), dec); 365 TAG (AT_SUN_RUID, _("Real user ID"), dec); 366 TAG (AT_SUN_GID, _("Effective group ID"), dec); 367 TAG (AT_SUN_RGID, _("Real group ID"), dec); 368 TAG (AT_SUN_LDELF, _("Dynamic linker's ELF header"), hex); 369 TAG (AT_SUN_LDSHDR, _("Dynamic linker's section headers"), hex); 370 TAG (AT_SUN_LDNAME, _("String giving name of dynamic linker"), str); 371 TAG (AT_SUN_LPAGESZ, _("Large pagesize"), dec); 372 TAG (AT_SUN_PLATFORM, _("Platform name string"), str); 373 TAG (AT_SUN_HWCAP, _("Machine-dependent CPU capability hints"), hex); 374 TAG (AT_SUN_IFLUSH, _("Should flush icache?"), dec); 375 TAG (AT_SUN_CPU, _("CPU name string"), str); 376 TAG (AT_SUN_EMUL_ENTRY, _("COFF entry point address"), hex); 377 TAG (AT_SUN_EMUL_EXECFD, _("COFF executable file descriptor"), dec); 378 TAG (AT_SUN_EXECNAME, 379 _("Canonicalized file name given to execve"), str); 380 TAG (AT_SUN_MMU, _("String for name of MMU module"), str); 381 TAG (AT_SUN_LDDATA, _("Dynamic linker's data segment address"), hex); 382 TAG (AT_SUN_AUXFLAGS, 383 _("AF_SUN_ flags passed from the kernel"), hex); 384 } 385 386 fprintf_filtered (file, "%-4s %-20s %-30s ", 387 plongest (type), name, description); 388 switch (flavor) 389 { 390 case dec: 391 fprintf_filtered (file, "%s\n", plongest (val)); 392 break; 393 case hex: 394 fprintf_filtered (file, "%s\n", paddress (target_gdbarch, val)); 395 break; 396 case str: 397 { 398 struct value_print_options opts; 399 400 get_user_print_options (&opts); 401 if (opts.addressprint) 402 fprintf_filtered (file, "%s", paddress (target_gdbarch, val)); 403 val_print_string (builtin_type (target_gdbarch)->builtin_char, 404 val, -1, file, &opts); 405 fprintf_filtered (file, "\n"); 406 } 407 break; 408 } 409 ++ents; 410 if (type == AT_NULL) 411 break; 412 } 413 414 xfree (data); 415 416 return ents; 417 } 418 419 static void 420 info_auxv_command (char *cmd, int from_tty) 421 { 422 if (! target_has_stack) 423 error (_("The program has no auxiliary information now.")); 424 else 425 { 426 int ents = fprint_target_auxv (gdb_stdout, ¤t_target); 427 428 if (ents < 0) 429 error (_("No auxiliary vector found, or failed reading it.")); 430 else if (ents == 0) 431 error (_("Auxiliary vector is empty.")); 432 } 433 } 434 435 436 extern initialize_file_ftype _initialize_auxv; /* -Wmissing-prototypes; */ 437 438 void 439 _initialize_auxv (void) 440 { 441 add_info ("auxv", info_auxv_command, 442 _("Display the inferior's auxiliary vector.\n\ 443 This is information provided by the operating system at program startup.")); 444 } 445