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