* coffcode.h (coff_write_object_contents): Enclose all occurrences
[deliverable/binutils-gdb.git] / gdb / auxv.c
CommitLineData
14ed0a8b
RM
1/* Auxiliary vector support for GDB, the GNU debugger.
2
4c38e0a4 3 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
0fb0cc75 4 Free Software Foundation, Inc.
14ed0a8b
RM
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
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
14ed0a8b
RM
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
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
14ed0a8b
RM
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"
9f2982ff 28#include "gdbcore.h"
14ed0a8b
RM
29
30#include "auxv.h"
31#include "elf/common.h"
32
33#include <unistd.h>
34#include <fcntl.h>
35
36
9f2982ff
JK
37/* This function handles access via /proc/PID/auxv, which is a common method
38 for native targets. */
14ed0a8b 39
9f2982ff
JK
40static LONGEST
41procfs_xfer_auxv (gdb_byte *readbuf,
36aa5e41 42 const gdb_byte *writebuf,
14ed0a8b
RM
43 ULONGEST offset,
44 LONGEST len)
45{
46 char *pathname;
47 int fd;
48 LONGEST n;
49
14ed0a8b
RM
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
9f2982ff
JK
69/* This function handles access via ld.so's symbol `_dl_auxv'. */
70
71static LONGEST
72ld_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 data_address = read_memory_typed_address (pointer_address, ptr_type);
100
101 /* Possibly still not initialized such as during an inferior startup. */
102 if (data_address == 0)
103 return -1;
104
105 data_address += offset;
106
107 if (writebuf != NULL)
108 {
109 if (target_write_memory (data_address, writebuf, len) == 0)
110 return len;
111 else
112 return -1;
113 }
114
115 /* Stop if trying to read past the existing AUXV block. The final AT_NULL
116 was already returned before. */
117
118 if (offset >= auxv_pair_size)
119 {
120 if (target_read_memory (data_address - auxv_pair_size, ptr_buf,
121 ptr_size) != 0)
122 return -1;
123
124 if (extract_typed_address (ptr_buf, ptr_type) == AT_NULL)
125 return 0;
126 }
127
128 retval = 0;
129 block = 0x400;
130 gdb_assert (block % auxv_pair_size == 0);
131
132 while (len > 0)
133 {
134 if (block > len)
135 block = len;
136
137 /* Reading sizes smaller than AUXV_PAIR_SIZE is not supported. Tails
138 unaligned to AUXV_PAIR_SIZE will not be read during a call (they
139 should be completed during next read with new/extended buffer). */
140
141 block &= -auxv_pair_size;
142 if (block == 0)
143 return retval;
144
145 if (target_read_memory (data_address, readbuf, block) != 0)
146 {
147 if (block <= auxv_pair_size)
148 return retval;
149
150 block = auxv_pair_size;
151 continue;
152 }
153
154 data_address += block;
155 len -= block;
156
157 /* Check terminal AT_NULL. This function is being called indefinitely
158 being extended its READBUF until it returns EOF (0). */
159
160 while (block >= auxv_pair_size)
161 {
162 retval += auxv_pair_size;
163
164 if (extract_typed_address (readbuf, ptr_type) == AT_NULL)
165 return retval;
166
167 readbuf += auxv_pair_size;
168 block -= auxv_pair_size;
169 }
170 }
171
172 return retval;
173}
174
175/* This function is called like a to_xfer_partial hook, but must be
176 called with TARGET_OBJECT_AUXV. It handles access to AUXV. */
177
178LONGEST
179memory_xfer_auxv (struct target_ops *ops,
180 enum target_object object,
181 const char *annex,
182 gdb_byte *readbuf,
183 const gdb_byte *writebuf,
184 ULONGEST offset,
185 LONGEST len)
186{
187 gdb_assert (object == TARGET_OBJECT_AUXV);
188 gdb_assert (readbuf || writebuf);
189
190 /* ld_so_xfer_auxv is the only function safe for virtual executables being
191 executed by valgrind's memcheck. As using ld_so_xfer_auxv is problematic
192 during inferior startup GDB does call it only for attached processes. */
193
194 if (current_inferior ()->attach_flag != 0)
195 {
196 LONGEST retval;
197
198 retval = ld_so_xfer_auxv (readbuf, writebuf, offset, len);
199 if (retval != -1)
200 return retval;
201 }
202
203 return procfs_xfer_auxv (readbuf, writebuf, offset, len);
204}
205
14ed0a8b
RM
206/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
207 Return 0 if *READPTR is already at the end of the buffer.
208 Return -1 if there is insufficient buffer for a whole entry.
209 Return 1 if an entry was read into *TYPEP and *VALP. */
2c0b251b 210static int
c47ffbe3 211default_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
36aa5e41 212 gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
14ed0a8b 213{
ffe5a37e
UW
214 const int sizeof_auxv_field = gdbarch_ptr_bit (target_gdbarch)
215 / TARGET_CHAR_BIT;
e17a4113 216 const enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
36aa5e41 217 gdb_byte *ptr = *readptr;
14ed0a8b
RM
218
219 if (endptr == ptr)
220 return 0;
221
222 if (endptr - ptr < sizeof_auxv_field * 2)
223 return -1;
224
e17a4113 225 *typep = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
14ed0a8b 226 ptr += sizeof_auxv_field;
e17a4113 227 *valp = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
14ed0a8b
RM
228 ptr += sizeof_auxv_field;
229
230 *readptr = ptr;
231 return 1;
232}
233
c47ffbe3
VP
234/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
235 Return 0 if *READPTR is already at the end of the buffer.
236 Return -1 if there is insufficient buffer for a whole entry.
237 Return 1 if an entry was read into *TYPEP and *VALP. */
238int
239target_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
240 gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
241{
242 struct target_ops *t;
243 for (t = ops; t != NULL; t = t->beneath)
244 if (t->to_auxv_parse != NULL)
245 return t->to_auxv_parse (t, readptr, endptr, typep, valp);
246
247 return default_auxv_parse (ops, readptr, endptr, typep, valp);
248}
249
14ed0a8b
RM
250/* Extract the auxiliary vector entry with a_type matching MATCH.
251 Return zero if no such entry was found, or -1 if there was
252 an error getting the information. On success, return 1 after
253 storing the entry's value field in *VALP. */
254int
255target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp)
256{
257 CORE_ADDR type, val;
36aa5e41 258 gdb_byte *data;
13547ab6 259 LONGEST n = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL, &data);
36aa5e41 260 gdb_byte *ptr = data;
14ed0a8b
RM
261
262 if (n <= 0)
263 return n;
264
265 while (1)
266 switch (target_auxv_parse (ops, &ptr, data + n, &type, &val))
267 {
268 case 1: /* Here's an entry, check it. */
269 if (type == match)
270 {
271 xfree (data);
272 *valp = val;
273 return 1;
274 }
275 break;
276 case 0: /* End of the vector. */
277 xfree (data);
278 return 0;
279 default: /* Bogosity. */
280 xfree (data);
281 return -1;
282 }
283
284 /*NOTREACHED*/
285}
286
287
288/* Print the contents of the target's AUXV on the specified file. */
289int
290fprint_target_auxv (struct ui_file *file, struct target_ops *ops)
291{
292 CORE_ADDR type, val;
36aa5e41 293 gdb_byte *data;
13547ab6
DJ
294 LONGEST len = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL,
295 &data);
36aa5e41 296 gdb_byte *ptr = data;
14ed0a8b
RM
297 int ents = 0;
298
299 if (len <= 0)
300 return len;
301
302 while (target_auxv_parse (ops, &ptr, data + len, &type, &val) > 0)
303 {
14ed0a8b
RM
304 const char *name = "???";
305 const char *description = "";
306 enum { dec, hex, str } flavor = hex;
307
308 switch (type)
309 {
310#define TAG(tag, text, kind) \
311 case tag: name = #tag; description = text; flavor = kind; break
edefbb7c
AC
312 TAG (AT_NULL, _("End of vector"), hex);
313 TAG (AT_IGNORE, _("Entry should be ignored"), hex);
314 TAG (AT_EXECFD, _("File descriptor of program"), dec);
315 TAG (AT_PHDR, _("Program headers for program"), hex);
316 TAG (AT_PHENT, _("Size of program header entry"), dec);
317 TAG (AT_PHNUM, _("Number of program headers"), dec);
318 TAG (AT_PAGESZ, _("System page size"), dec);
319 TAG (AT_BASE, _("Base address of interpreter"), hex);
320 TAG (AT_FLAGS, _("Flags"), hex);
321 TAG (AT_ENTRY, _("Entry point of program"), hex);
322 TAG (AT_NOTELF, _("Program is not ELF"), dec);
323 TAG (AT_UID, _("Real user ID"), dec);
324 TAG (AT_EUID, _("Effective user ID"), dec);
325 TAG (AT_GID, _("Real group ID"), dec);
326 TAG (AT_EGID, _("Effective group ID"), dec);
327 TAG (AT_CLKTCK, _("Frequency of times()"), dec);
328 TAG (AT_PLATFORM, _("String identifying platform"), str);
329 TAG (AT_HWCAP, _("Machine-dependent CPU capability hints"), hex);
330 TAG (AT_FPUCW, _("Used FPU control word"), dec);
331 TAG (AT_DCACHEBSIZE, _("Data cache block size"), dec);
332 TAG (AT_ICACHEBSIZE, _("Instruction cache block size"), dec);
333 TAG (AT_UCACHEBSIZE, _("Unified cache block size"), dec);
334 TAG (AT_IGNOREPPC, _("Entry should be ignored"), dec);
759cc328 335 TAG (AT_BASE_PLATFORM, _("String identifying base platform"), str);
ba30a4e9 336 TAG (AT_RANDOM, _("Address of 16 random bytes"), hex);
759cc328
UW
337 TAG (AT_EXECFN, _("File name of executable"), str);
338 TAG (AT_SECURE, _("Boolean, was exec setuid-like?"), dec);
edefbb7c
AC
339 TAG (AT_SYSINFO, _("Special system info/entry points"), hex);
340 TAG (AT_SYSINFO_EHDR, _("System-supplied DSO's ELF header"), hex);
edefbb7c
AC
341 TAG (AT_SUN_UID, _("Effective user ID"), dec);
342 TAG (AT_SUN_RUID, _("Real user ID"), dec);
343 TAG (AT_SUN_GID, _("Effective group ID"), dec);
344 TAG (AT_SUN_RGID, _("Real group ID"), dec);
345 TAG (AT_SUN_LDELF, _("Dynamic linker's ELF header"), hex);
346 TAG (AT_SUN_LDSHDR, _("Dynamic linker's section headers"), hex);
347 TAG (AT_SUN_LDNAME, _("String giving name of dynamic linker"), str);
348 TAG (AT_SUN_LPAGESZ, _("Large pagesize"), dec);
349 TAG (AT_SUN_PLATFORM, _("Platform name string"), str);
350 TAG (AT_SUN_HWCAP, _("Machine-dependent CPU capability hints"), hex);
351 TAG (AT_SUN_IFLUSH, _("Should flush icache?"), dec);
352 TAG (AT_SUN_CPU, _("CPU name string"), str);
353 TAG (AT_SUN_EMUL_ENTRY, _("COFF entry point address"), hex);
354 TAG (AT_SUN_EMUL_EXECFD, _("COFF executable file descriptor"), dec);
14ed0a8b 355 TAG (AT_SUN_EXECNAME,
edefbb7c
AC
356 _("Canonicalized file name given to execve"), str);
357 TAG (AT_SUN_MMU, _("String for name of MMU module"), str);
358 TAG (AT_SUN_LDDATA, _("Dynamic linker's data segment address"), hex);
77d49ac6
MK
359 TAG (AT_SUN_AUXFLAGS,
360 _("AF_SUN_ flags passed from the kernel"), hex);
14ed0a8b
RM
361 }
362
363 fprintf_filtered (file, "%-4s %-20s %-30s ",
623d3eb1 364 plongest (type), name, description);
14ed0a8b
RM
365 switch (flavor)
366 {
367 case dec:
623d3eb1 368 fprintf_filtered (file, "%s\n", plongest (val));
14ed0a8b
RM
369 break;
370 case hex:
5af949e3 371 fprintf_filtered (file, "%s\n", paddress (target_gdbarch, val));
14ed0a8b
RM
372 break;
373 case str:
79a45b7d
TT
374 {
375 struct value_print_options opts;
376 get_user_print_options (&opts);
377 if (opts.addressprint)
5af949e3 378 fprintf_filtered (file, "%s", paddress (target_gdbarch, val));
6c7a06a3
TT
379 val_print_string (builtin_type (target_gdbarch)->builtin_char,
380 val, -1, file, &opts);
79a45b7d
TT
381 fprintf_filtered (file, "\n");
382 }
14ed0a8b
RM
383 break;
384 }
385 ++ents;
7c6467a4
PP
386 if (type == AT_NULL)
387 break;
14ed0a8b
RM
388 }
389
390 xfree (data);
391
392 return ents;
393}
394
395static void
396info_auxv_command (char *cmd, int from_tty)
397{
14ed0a8b 398 if (! target_has_stack)
edefbb7c 399 error (_("The program has no auxiliary information now."));
14ed0a8b
RM
400 else
401 {
402 int ents = fprint_target_auxv (gdb_stdout, &current_target);
403 if (ents < 0)
edefbb7c 404 error (_("No auxiliary vector found, or failed reading it."));
14ed0a8b 405 else if (ents == 0)
edefbb7c 406 error (_("Auxiliary vector is empty."));
14ed0a8b
RM
407 }
408}
409
410
411extern initialize_file_ftype _initialize_auxv; /* -Wmissing-prototypes; */
412
413void
414_initialize_auxv (void)
415{
416 add_info ("auxv", info_auxv_command,
edefbb7c
AC
417 _("Display the inferior's auxiliary vector.\n\
418This is information provided by the operating system at program startup."));
14ed0a8b 419}
This page took 0.381487 seconds and 4 git commands to generate.