Upgrade GDB from 7.0 and 7.2 on the vendor branch
[dragonfly.git] / contrib / gdb-7 / gdb / auxv.c
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, &current_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 }