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