]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/auxv.c
gdb: fix auxv cache clearing from new_objfile observer
[thirdparty/binutils-gdb.git] / gdb / auxv.c
CommitLineData
14ed0a8b
RM
1/* Auxiliary vector support for GDB, the GNU debugger.
2
213516ef 3 Copyright (C) 2004-2023 Free Software Foundation, Inc.
14ed0a8b
RM
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
14ed0a8b
RM
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
14ed0a8b
RM
19
20#include "defs.h"
4de283e4 21#include "target.h"
d55e5aa6 22#include "gdbtypes.h"
4de283e4 23#include "command.h"
d55e5aa6 24#include "inferior.h"
d55e5aa6 25#include "valprint.h"
4de283e4
TT
26#include "gdbcore.h"
27#include "observable.h"
268a13a5 28#include "gdbsupport/filestuff.h"
4de283e4
TT
29#include "objfiles.h"
30
31#include "auxv.h"
32#include "elf/common.h"
33
34#include <unistd.h>
35#include <fcntl.h>
14ed0a8b
RM
36
37
edcc890f
YQ
38/* Implement the to_xfer_partial target_ops method. This function
39 handles access via /proc/PID/auxv, which is a common method for
40 native targets. */
14ed0a8b 41
9b409511 42static enum target_xfer_status
9f2982ff 43procfs_xfer_auxv (gdb_byte *readbuf,
36aa5e41 44 const gdb_byte *writebuf,
14ed0a8b 45 ULONGEST offset,
9b409511
YQ
46 ULONGEST len,
47 ULONGEST *xfered_len)
14ed0a8b 48{
9b409511 49 ssize_t l;
14ed0a8b 50
528e1572 51 std::string pathname = string_printf ("/proc/%d/auxv", inferior_ptid.pid ());
13084383
SM
52 scoped_fd fd
53 = gdb_open_cloexec (pathname, writebuf != NULL ? O_WRONLY : O_RDONLY, 0);
54 if (fd.get () < 0)
2ed4b548 55 return TARGET_XFER_E_IO;
14ed0a8b
RM
56
57 if (offset != (ULONGEST) 0
13084383 58 && lseek (fd.get (), (off_t) offset, SEEK_SET) != (off_t) offset)
9b409511 59 l = -1;
14ed0a8b 60 else if (readbuf != NULL)
13084383 61 l = read (fd.get (), readbuf, (size_t) len);
14ed0a8b 62 else
13084383 63 l = write (fd.get (), writebuf, (size_t) len);
14ed0a8b 64
9b409511
YQ
65 if (l < 0)
66 return TARGET_XFER_E_IO;
67 else if (l == 0)
68 return TARGET_XFER_EOF;
69 else
70 {
71 *xfered_len = (ULONGEST) l;
72 return TARGET_XFER_OK;
73 }
14ed0a8b
RM
74}
75
9f2982ff
JK
76/* This function handles access via ld.so's symbol `_dl_auxv'. */
77
9b409511 78static enum target_xfer_status
9f2982ff
JK
79ld_so_xfer_auxv (gdb_byte *readbuf,
80 const gdb_byte *writebuf,
81 ULONGEST offset,
9b409511 82 ULONGEST len, ULONGEST *xfered_len)
9f2982ff 83{
3b7344d5 84 struct bound_minimal_symbol msym;
9f2982ff 85 CORE_ADDR data_address, pointer_address;
f5656ead 86 struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
df86565b 87 size_t ptr_size = ptr_type->length ();
9f2982ff 88 size_t auxv_pair_size = 2 * ptr_size;
224c3ddb 89 gdb_byte *ptr_buf = (gdb_byte *) alloca (ptr_size);
9f2982ff
JK
90 LONGEST retval;
91 size_t block;
92
93 msym = lookup_minimal_symbol ("_dl_auxv", NULL, NULL);
3b7344d5 94 if (msym.minsym == NULL)
2ed4b548 95 return TARGET_XFER_E_IO;
9f2982ff 96
5bbfd12d 97 if (msym.minsym->size () != ptr_size)
2ed4b548 98 return TARGET_XFER_E_IO;
9f2982ff 99
0e2de366
MS
100 /* POINTER_ADDRESS is a location where the `_dl_auxv' variable
101 resides. DATA_ADDRESS is the inferior value present in
102 `_dl_auxv', therefore the real inferior AUXV address. */
9f2982ff 103
4aeddc50 104 pointer_address = msym.value_address ();
9f2982ff 105
3cd07d20 106 /* The location of the _dl_auxv symbol may no longer be correct if
0e2de366
MS
107 ld.so runs at a different address than the one present in the
108 file. This is very common case - for unprelinked ld.so or with a
109 PIE executable. PIE executable forces random address even for
110 libraries already being prelinked to some address. PIE
111 executables themselves are never prelinked even on prelinked
112 systems. Prelinking of a PIE executable would block their
113 purpose of randomizing load of everything including the
114 executable.
115
116 If the memory read fails, return -1 to fallback on another
117 mechanism for retrieving the AUXV.
118
119 In most cases of a PIE running under valgrind there is no way to
120 find out the base addresses of any of ld.so, executable or AUXV
121 as everything is randomized and /proc information is not relevant
122 for the virtual executable running under valgrind. We think that
123 we might need a valgrind extension to make it work. This is PR
124 11440. */
3cd07d20
JK
125
126 if (target_read_memory (pointer_address, ptr_buf, ptr_size) != 0)
2ed4b548 127 return TARGET_XFER_E_IO;
3cd07d20
JK
128
129 data_address = extract_typed_address (ptr_buf, ptr_type);
9f2982ff 130
0e2de366
MS
131 /* Possibly still not initialized such as during an inferior
132 startup. */
9f2982ff 133 if (data_address == 0)
2ed4b548 134 return TARGET_XFER_E_IO;
9f2982ff
JK
135
136 data_address += offset;
137
138 if (writebuf != NULL)
139 {
140 if (target_write_memory (data_address, writebuf, len) == 0)
9b409511
YQ
141 {
142 *xfered_len = (ULONGEST) len;
143 return TARGET_XFER_OK;
144 }
9f2982ff 145 else
2ed4b548 146 return TARGET_XFER_E_IO;
9f2982ff
JK
147 }
148
0e2de366
MS
149 /* Stop if trying to read past the existing AUXV block. The final
150 AT_NULL was already returned before. */
9f2982ff
JK
151
152 if (offset >= auxv_pair_size)
153 {
154 if (target_read_memory (data_address - auxv_pair_size, ptr_buf,
155 ptr_size) != 0)
2ed4b548 156 return TARGET_XFER_E_IO;
9f2982ff
JK
157
158 if (extract_typed_address (ptr_buf, ptr_type) == AT_NULL)
9b409511 159 return TARGET_XFER_EOF;
9f2982ff
JK
160 }
161
162 retval = 0;
163 block = 0x400;
164 gdb_assert (block % auxv_pair_size == 0);
165
166 while (len > 0)
167 {
168 if (block > len)
169 block = len;
170
0e2de366
MS
171 /* Reading sizes smaller than AUXV_PAIR_SIZE is not supported.
172 Tails unaligned to AUXV_PAIR_SIZE will not be read during a
173 call (they should be completed during next read with
174 new/extended buffer). */
9f2982ff
JK
175
176 block &= -auxv_pair_size;
177 if (block == 0)
9b409511 178 break;
9f2982ff
JK
179
180 if (target_read_memory (data_address, readbuf, block) != 0)
181 {
182 if (block <= auxv_pair_size)
9b409511 183 break;
9f2982ff
JK
184
185 block = auxv_pair_size;
186 continue;
187 }
188
189 data_address += block;
190 len -= block;
191
0e2de366 192 /* Check terminal AT_NULL. This function is being called
dda83cd7
SM
193 indefinitely being extended its READBUF until it returns EOF
194 (0). */
9f2982ff
JK
195
196 while (block >= auxv_pair_size)
197 {
198 retval += auxv_pair_size;
199
200 if (extract_typed_address (readbuf, ptr_type) == AT_NULL)
9b409511
YQ
201 {
202 *xfered_len = (ULONGEST) retval;
203 return TARGET_XFER_OK;
204 }
9f2982ff
JK
205
206 readbuf += auxv_pair_size;
207 block -= auxv_pair_size;
208 }
209 }
210
9b409511
YQ
211 *xfered_len = (ULONGEST) retval;
212 return TARGET_XFER_OK;
9f2982ff
JK
213}
214
edcc890f
YQ
215/* Implement the to_xfer_partial target_ops method for
216 TARGET_OBJECT_AUXV. It handles access to AUXV. */
9f2982ff 217
9b409511 218enum target_xfer_status
9f2982ff
JK
219memory_xfer_auxv (struct target_ops *ops,
220 enum target_object object,
221 const char *annex,
222 gdb_byte *readbuf,
223 const gdb_byte *writebuf,
224 ULONGEST offset,
9b409511 225 ULONGEST len, ULONGEST *xfered_len)
9f2982ff
JK
226{
227 gdb_assert (object == TARGET_OBJECT_AUXV);
228 gdb_assert (readbuf || writebuf);
229
0e2de366
MS
230 /* ld_so_xfer_auxv is the only function safe for virtual
231 executables being executed by valgrind's memcheck. Using
232 ld_so_xfer_auxv during inferior startup is problematic, because
233 ld.so symbol tables have not yet been relocated. So GDB uses
234 this function only when attaching to a process.
86e4bafc 235 */
9f2982ff 236
30220b46 237 if (current_inferior ()->attach_flag)
9f2982ff 238 {
9b409511 239 enum target_xfer_status ret;
9f2982ff 240
9b409511
YQ
241 ret = ld_so_xfer_auxv (readbuf, writebuf, offset, len, xfered_len);
242 if (ret != TARGET_XFER_E_IO)
243 return ret;
9f2982ff
JK
244 }
245
9b409511 246 return procfs_xfer_auxv (readbuf, writebuf, offset, len, xfered_len);
9f2982ff
JK
247}
248
206c98a6
KR
249/* This function compared to other auxv_parse functions: it takes the size of
250 the auxv type field as a parameter. */
251
252static int
3fe639b8
SM
253generic_auxv_parse (struct gdbarch *gdbarch, const gdb_byte **readptr,
254 const gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp,
206c98a6 255 int sizeof_auxv_type)
14ed0a8b 256{
206c98a6 257 struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
df86565b 258 const int sizeof_auxv_val = ptr_type->length ();
206c98a6 259 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
3fe639b8 260 const gdb_byte *ptr = *readptr;
14ed0a8b
RM
261
262 if (endptr == ptr)
263 return 0;
264
206c98a6 265 if (endptr - ptr < 2 * sizeof_auxv_val)
14ed0a8b
RM
266 return -1;
267
206c98a6
KR
268 *typep = extract_unsigned_integer (ptr, sizeof_auxv_type, byte_order);
269 /* Even if the auxv type takes less space than an auxv value, there is
270 padding after the type such that the value is aligned on a multiple of
271 its size (and this is why we advance by `sizeof_auxv_val` and not
272 `sizeof_auxv_type`). */
273 ptr += sizeof_auxv_val;
274 *valp = extract_unsigned_integer (ptr, sizeof_auxv_val, byte_order);
275 ptr += sizeof_auxv_val;
14ed0a8b
RM
276
277 *readptr = ptr;
278 return 1;
279}
280
206c98a6
KR
281/* See auxv.h. */
282
283int
3fe639b8
SM
284default_auxv_parse (struct target_ops *ops, const gdb_byte **readptr,
285 const gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
206c98a6
KR
286{
287 struct gdbarch *gdbarch = target_gdbarch ();
288 struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
df86565b 289 const int sizeof_auxv_type = ptr_type->length ();
206c98a6
KR
290
291 return generic_auxv_parse (gdbarch, readptr, endptr, typep, valp,
292 sizeof_auxv_type);
293}
294
295/* See auxv.h. */
296
297int
3fe639b8
SM
298svr4_auxv_parse (struct gdbarch *gdbarch, const gdb_byte **readptr,
299 const gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
206c98a6
KR
300{
301 struct type *int_type = builtin_type (gdbarch)->builtin_int;
df86565b 302 const int sizeof_auxv_type = int_type->length ();
206c98a6
KR
303
304 return generic_auxv_parse (gdbarch, readptr, endptr, typep, valp,
305 sizeof_auxv_type);
306}
307
c47ffbe3 308/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
7dce7881 309
82d23ca8
SM
310 Use the auxv_parse method from GDBARCH, if defined, else use the auxv_parse
311 method of OPS.
7dce7881 312
c47ffbe3
VP
313 Return 0 if *READPTR is already at the end of the buffer.
314 Return -1 if there is insufficient buffer for a whole entry.
315 Return 1 if an entry was read into *TYPEP and *VALP. */
82d23ca8 316
7dce7881 317static int
82d23ca8
SM
318parse_auxv (target_ops *ops, gdbarch *gdbarch, const gdb_byte **readptr,
319 const gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
c47ffbe3 320{
27a48a92
MK
321 if (gdbarch_auxv_parse_p (gdbarch))
322 return gdbarch_auxv_parse (gdbarch, readptr, endptr, typep, valp);
323
82d23ca8 324 return ops->auxv_parse (readptr, endptr, typep, valp);
c47ffbe3
VP
325}
326
865ecab4 327
865ecab4
LM
328/* Auxiliary Vector information structure. This is used by GDB
329 for caching purposes for each inferior. This helps reduce the
330 overhead of transfering data from a remote target to the local host. */
331struct auxv_info
332{
9018be22 333 gdb::optional<gdb::byte_vector> data;
865ecab4
LM
334};
335
e9b89e2d 336/* Per-inferior data key for auxv. */
08b8a139 337static const registry<inferior>::key<auxv_info> auxv_inferior_data;
865ecab4
LM
338
339/* Invalidate INF's auxv cache. */
340
341static void
342invalidate_auxv_cache_inf (struct inferior *inf)
343{
e9b89e2d 344 auxv_inferior_data.clear (inf);
865ecab4
LM
345}
346
a2827364
AB
347/* Invalidate current inferior's auxv cache when all symbol table data is
348 cleared (indicated by OBJFILE being nullptr). */
865ecab4
LM
349
350static void
a2827364 351auxv_new_objfile_observer (struct objfile *objfile)
865ecab4 352{
a2827364 353 if (objfile == nullptr)
1b28c0f4
AB
354 {
355 /* When OBJFILE is nullptr, this indicates that all symbol files have
356 been unloaded from the current program space. Discard cached auxv
357 information from any inferior within the effected program space. */
358 for (inferior *inf : all_inferiors ())
359 {
360 if (inf->pspace == current_program_space)
361 invalidate_auxv_cache_inf (inf);
362 }
363 }
865ecab4
LM
364}
365
82d23ca8 366/* See auxv.h. */
865ecab4 367
9246b7bd 368const gdb::optional<gdb::byte_vector> &
82d23ca8 369target_read_auxv ()
865ecab4 370{
82d23ca8
SM
371 inferior *inf = current_inferior ();
372 auxv_info *info = auxv_inferior_data.get (inf);
865ecab4 373
82d23ca8 374 if (info == nullptr)
865ecab4 375 {
e9b89e2d 376 info = auxv_inferior_data.emplace (inf);
1639fab3 377 info->data = target_read_auxv_raw (inf->top_target ());
865ecab4
LM
378 }
379
82d23ca8 380 return info->data;
865ecab4
LM
381}
382
82d23ca8
SM
383/* See auxv.h. */
384
385gdb::optional<gdb::byte_vector>
1639fab3 386target_read_auxv_raw (target_ops *ops)
14ed0a8b 387{
82d23ca8
SM
388 return target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL);
389}
865ecab4 390
82d23ca8 391/* See auxv.h. */
14ed0a8b 392
82d23ca8
SM
393int
394target_auxv_search (const gdb::byte_vector &auxv, target_ops *ops,
395 gdbarch *gdbarch, CORE_ADDR match, CORE_ADDR *valp)
396{
397 CORE_ADDR type, val;
398 const gdb_byte *data = auxv.data ();
3fe639b8 399 const gdb_byte *ptr = data;
82d23ca8 400 size_t len = auxv.size ();
14ed0a8b
RM
401
402 while (1)
82d23ca8 403 switch (parse_auxv (ops, gdbarch, &ptr, data + len, &type, &val))
14ed0a8b
RM
404 {
405 case 1: /* Here's an entry, check it. */
406 if (type == match)
407 {
14ed0a8b
RM
408 *valp = val;
409 return 1;
410 }
411 break;
412 case 0: /* End of the vector. */
14ed0a8b
RM
413 return 0;
414 default: /* Bogosity. */
14ed0a8b
RM
415 return -1;
416 }
14ed0a8b
RM
417}
418
82d23ca8
SM
419/* See auxv.h. */
420
421int
422target_auxv_search (CORE_ADDR match, CORE_ADDR *valp)
423{
9246b7bd 424 const gdb::optional<gdb::byte_vector> &auxv = target_read_auxv ();
82d23ca8
SM
425
426 if (!auxv.has_value ())
427 return -1;
428
429 return target_auxv_search (*auxv, current_inferior ()->top_target (),
430 current_inferior ()->gdbarch, match, valp);
431}
14ed0a8b 432
2faa3447
JB
433/* Print the description of a single AUXV entry on the specified file. */
434
435void
436fprint_auxv_entry (struct ui_file *file, const char *name,
437 const char *description, enum auxv_format format,
438 CORE_ADDR type, CORE_ADDR val)
439{
6cb06a8c
TT
440 gdb_printf (file, ("%-4s %-20s %-30s "),
441 plongest (type), name, description);
2faa3447
JB
442 switch (format)
443 {
444 case AUXV_FORMAT_DEC:
6cb06a8c 445 gdb_printf (file, ("%s\n"), plongest (val));
2faa3447
JB
446 break;
447 case AUXV_FORMAT_HEX:
6cb06a8c 448 gdb_printf (file, ("%s\n"), paddress (target_gdbarch (), val));
2faa3447
JB
449 break;
450 case AUXV_FORMAT_STR:
451 {
452 struct value_print_options opts;
453
454 get_user_print_options (&opts);
455 if (opts.addressprint)
6cb06a8c 456 gdb_printf (file, ("%s "), paddress (target_gdbarch (), val));
2faa3447
JB
457 val_print_string (builtin_type (target_gdbarch ())->builtin_char,
458 NULL, val, -1, file, &opts);
6cb06a8c 459 gdb_printf (file, ("\n"));
2faa3447
JB
460 }
461 break;
462 }
463}
464
465/* The default implementation of gdbarch_print_auxv_entry. */
466
467void
468default_print_auxv_entry (struct gdbarch *gdbarch, struct ui_file *file,
469 CORE_ADDR type, CORE_ADDR val)
470{
471 const char *name = "???";
472 const char *description = "";
473 enum auxv_format format = AUXV_FORMAT_HEX;
474
475 switch (type)
476 {
477#define TAG(tag, text, kind) \
478 case tag: name = #tag; description = text; format = kind; break
479 TAG (AT_NULL, _("End of vector"), AUXV_FORMAT_HEX);
480 TAG (AT_IGNORE, _("Entry should be ignored"), AUXV_FORMAT_HEX);
481 TAG (AT_EXECFD, _("File descriptor of program"), AUXV_FORMAT_DEC);
482 TAG (AT_PHDR, _("Program headers for program"), AUXV_FORMAT_HEX);
483 TAG (AT_PHENT, _("Size of program header entry"), AUXV_FORMAT_DEC);
484 TAG (AT_PHNUM, _("Number of program headers"), AUXV_FORMAT_DEC);
485 TAG (AT_PAGESZ, _("System page size"), AUXV_FORMAT_DEC);
486 TAG (AT_BASE, _("Base address of interpreter"), AUXV_FORMAT_HEX);
487 TAG (AT_FLAGS, _("Flags"), AUXV_FORMAT_HEX);
488 TAG (AT_ENTRY, _("Entry point of program"), AUXV_FORMAT_HEX);
489 TAG (AT_NOTELF, _("Program is not ELF"), AUXV_FORMAT_DEC);
490 TAG (AT_UID, _("Real user ID"), AUXV_FORMAT_DEC);
491 TAG (AT_EUID, _("Effective user ID"), AUXV_FORMAT_DEC);
492 TAG (AT_GID, _("Real group ID"), AUXV_FORMAT_DEC);
493 TAG (AT_EGID, _("Effective group ID"), AUXV_FORMAT_DEC);
494 TAG (AT_CLKTCK, _("Frequency of times()"), AUXV_FORMAT_DEC);
495 TAG (AT_PLATFORM, _("String identifying platform"), AUXV_FORMAT_STR);
496 TAG (AT_HWCAP, _("Machine-dependent CPU capability hints"),
497 AUXV_FORMAT_HEX);
498 TAG (AT_FPUCW, _("Used FPU control word"), AUXV_FORMAT_DEC);
499 TAG (AT_DCACHEBSIZE, _("Data cache block size"), AUXV_FORMAT_DEC);
500 TAG (AT_ICACHEBSIZE, _("Instruction cache block size"), AUXV_FORMAT_DEC);
501 TAG (AT_UCACHEBSIZE, _("Unified cache block size"), AUXV_FORMAT_DEC);
502 TAG (AT_IGNOREPPC, _("Entry should be ignored"), AUXV_FORMAT_DEC);
503 TAG (AT_BASE_PLATFORM, _("String identifying base platform"),
504 AUXV_FORMAT_STR);
505 TAG (AT_RANDOM, _("Address of 16 random bytes"), AUXV_FORMAT_HEX);
506 TAG (AT_HWCAP2, _("Extension of AT_HWCAP"), AUXV_FORMAT_HEX);
507 TAG (AT_EXECFN, _("File name of executable"), AUXV_FORMAT_STR);
508 TAG (AT_SECURE, _("Boolean, was exec setuid-like?"), AUXV_FORMAT_DEC);
509 TAG (AT_SYSINFO, _("Special system info/entry points"), AUXV_FORMAT_HEX);
510 TAG (AT_SYSINFO_EHDR, _("System-supplied DSO's ELF header"),
511 AUXV_FORMAT_HEX);
512 TAG (AT_L1I_CACHESHAPE, _("L1 Instruction cache information"),
513 AUXV_FORMAT_HEX);
bb7b70ab
LM
514 TAG (AT_L1I_CACHESIZE, _("L1 Instruction cache size"), AUXV_FORMAT_HEX);
515 TAG (AT_L1I_CACHEGEOMETRY, _("L1 Instruction cache geometry"),
516 AUXV_FORMAT_HEX);
2faa3447 517 TAG (AT_L1D_CACHESHAPE, _("L1 Data cache information"), AUXV_FORMAT_HEX);
bb7b70ab
LM
518 TAG (AT_L1D_CACHESIZE, _("L1 Data cache size"), AUXV_FORMAT_HEX);
519 TAG (AT_L1D_CACHEGEOMETRY, _("L1 Data cache geometry"),
520 AUXV_FORMAT_HEX);
2faa3447 521 TAG (AT_L2_CACHESHAPE, _("L2 cache information"), AUXV_FORMAT_HEX);
bb7b70ab
LM
522 TAG (AT_L2_CACHESIZE, _("L2 cache size"), AUXV_FORMAT_HEX);
523 TAG (AT_L2_CACHEGEOMETRY, _("L2 cache geometry"), AUXV_FORMAT_HEX);
2faa3447 524 TAG (AT_L3_CACHESHAPE, _("L3 cache information"), AUXV_FORMAT_HEX);
bb7b70ab
LM
525 TAG (AT_L3_CACHESIZE, _("L3 cache size"), AUXV_FORMAT_HEX);
526 TAG (AT_L3_CACHEGEOMETRY, _("L3 cache geometry"), AUXV_FORMAT_HEX);
527 TAG (AT_MINSIGSTKSZ, _("Minimum stack size for signal delivery"),
528 AUXV_FORMAT_HEX);
2faa3447
JB
529 TAG (AT_SUN_UID, _("Effective user ID"), AUXV_FORMAT_DEC);
530 TAG (AT_SUN_RUID, _("Real user ID"), AUXV_FORMAT_DEC);
531 TAG (AT_SUN_GID, _("Effective group ID"), AUXV_FORMAT_DEC);
532 TAG (AT_SUN_RGID, _("Real group ID"), AUXV_FORMAT_DEC);
533 TAG (AT_SUN_LDELF, _("Dynamic linker's ELF header"), AUXV_FORMAT_HEX);
534 TAG (AT_SUN_LDSHDR, _("Dynamic linker's section headers"),
535 AUXV_FORMAT_HEX);
536 TAG (AT_SUN_LDNAME, _("String giving name of dynamic linker"),
537 AUXV_FORMAT_STR);
538 TAG (AT_SUN_LPAGESZ, _("Large pagesize"), AUXV_FORMAT_DEC);
539 TAG (AT_SUN_PLATFORM, _("Platform name string"), AUXV_FORMAT_STR);
3d282ac3 540 TAG (AT_SUN_CAP_HW1, _("Machine-dependent CPU capability hints"),
2faa3447
JB
541 AUXV_FORMAT_HEX);
542 TAG (AT_SUN_IFLUSH, _("Should flush icache?"), AUXV_FORMAT_DEC);
543 TAG (AT_SUN_CPU, _("CPU name string"), AUXV_FORMAT_STR);
544 TAG (AT_SUN_EMUL_ENTRY, _("COFF entry point address"), AUXV_FORMAT_HEX);
545 TAG (AT_SUN_EMUL_EXECFD, _("COFF executable file descriptor"),
546 AUXV_FORMAT_DEC);
547 TAG (AT_SUN_EXECNAME,
548 _("Canonicalized file name given to execve"), AUXV_FORMAT_STR);
549 TAG (AT_SUN_MMU, _("String for name of MMU module"), AUXV_FORMAT_STR);
550 TAG (AT_SUN_LDDATA, _("Dynamic linker's data segment address"),
551 AUXV_FORMAT_HEX);
552 TAG (AT_SUN_AUXFLAGS,
553 _("AF_SUN_ flags passed from the kernel"), AUXV_FORMAT_HEX);
3d282ac3
RO
554 TAG (AT_SUN_EMULATOR, _("Name of emulation binary for runtime linker"),
555 AUXV_FORMAT_STR);
556 TAG (AT_SUN_BRANDNAME, _("Name of brand library"), AUXV_FORMAT_STR);
557 TAG (AT_SUN_BRAND_AUX1, _("Aux vector for brand modules 1"),
558 AUXV_FORMAT_HEX);
559 TAG (AT_SUN_BRAND_AUX2, _("Aux vector for brand modules 2"),
560 AUXV_FORMAT_HEX);
561 TAG (AT_SUN_BRAND_AUX3, _("Aux vector for brand modules 3"),
562 AUXV_FORMAT_HEX);
563 TAG (AT_SUN_CAP_HW2, _("Machine-dependent CPU capability hints 2"),
564 AUXV_FORMAT_HEX);
2faa3447
JB
565 }
566
567 fprint_auxv_entry (file, name, description, format, type, val);
568}
569
0e2de366 570/* Print the contents of the target's AUXV on the specified file. */
2faa3447 571
e2df8050 572static int
82d23ca8 573fprint_target_auxv (struct ui_file *file)
14ed0a8b 574{
2faa3447 575 struct gdbarch *gdbarch = target_gdbarch ();
14ed0a8b 576 CORE_ADDR type, val;
14ed0a8b 577 int ents = 0;
9246b7bd 578 const gdb::optional<gdb::byte_vector> &auxv = target_read_auxv ();
14ed0a8b 579
82d23ca8 580 if (!auxv.has_value ())
9018be22 581 return -1;
14ed0a8b 582
82d23ca8 583 const gdb_byte *data = auxv->data ();
3fe639b8 584 const gdb_byte *ptr = data;
82d23ca8 585 size_t len = auxv->size ();
865ecab4 586
82d23ca8
SM
587 while (parse_auxv (current_inferior ()->top_target (),
588 current_inferior ()->gdbarch,
589 &ptr, data + len, &type, &val) > 0)
14ed0a8b 590 {
2faa3447 591 gdbarch_print_auxv_entry (gdbarch, file, type, val);
14ed0a8b 592 ++ents;
7c6467a4
PP
593 if (type == AT_NULL)
594 break;
14ed0a8b
RM
595 }
596
14ed0a8b
RM
597 return ents;
598}
599
600static void
1d12d88f 601info_auxv_command (const char *cmd, int from_tty)
14ed0a8b 602{
841de120 603 if (! target_has_stack ())
edefbb7c 604 error (_("The program has no auxiliary information now."));
14ed0a8b
RM
605 else
606 {
82d23ca8 607 int ents = fprint_target_auxv (gdb_stdout);
5b4ee69b 608
14ed0a8b 609 if (ents < 0)
edefbb7c 610 error (_("No auxiliary vector found, or failed reading it."));
14ed0a8b 611 else if (ents == 0)
edefbb7c 612 error (_("Auxiliary vector is empty."));
14ed0a8b
RM
613 }
614}
615
6c265988 616void _initialize_auxv ();
14ed0a8b 617void
6c265988 618_initialize_auxv ()
14ed0a8b
RM
619{
620 add_info ("auxv", info_auxv_command,
edefbb7c
AC
621 _("Display the inferior's auxiliary vector.\n\
622This is information provided by the operating system at program startup."));
865ecab4 623
865ecab4 624 /* Observers used to invalidate the auxv cache when needed. */
c90e7d63
SM
625 gdb::observers::inferior_exit.attach (invalidate_auxv_cache_inf, "auxv");
626 gdb::observers::inferior_appeared.attach (invalidate_auxv_cache_inf, "auxv");
a2827364 627 gdb::observers::new_objfile.attach (auxv_new_objfile_observer, "auxv");
14ed0a8b 628}