xref: /dflybsd-src/contrib/gdb-7/gdb/auxv.c (revision c0d274d062fd959993bf623f25f7cb6a8a676c4e)
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 }
445