2009-03-20 Tom Tromey <tromey@redhat.com>
[deliverable/binutils-gdb.git] / gdb / auxv.c
CommitLineData
14ed0a8b
RM
1/* Auxiliary vector support for GDB, the GNU debugger.
2
0fb0cc75
JB
3 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
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"
28
29#include "auxv.h"
30#include "elf/common.h"
31
32#include <unistd.h>
33#include <fcntl.h>
34
35
36/* This function is called like a to_xfer_partial hook,
37 but must be called with TARGET_OBJECT_AUXV.
38 It handles access via /proc/PID/auxv, which is the common method.
39 This function is appropriate for doing:
40 #define NATIVE_XFER_AUXV procfs_xfer_auxv
41 for a native target that uses inftarg.c's child_xfer_partial hook. */
42
43LONGEST
44procfs_xfer_auxv (struct target_ops *ops,
45 int /* enum target_object */ object,
46 const char *annex,
36aa5e41
AC
47 gdb_byte *readbuf,
48 const gdb_byte *writebuf,
14ed0a8b
RM
49 ULONGEST offset,
50 LONGEST len)
51{
52 char *pathname;
53 int fd;
54 LONGEST n;
55
56 gdb_assert (object == TARGET_OBJECT_AUXV);
57 gdb_assert (readbuf || writebuf);
58
59 pathname = xstrprintf ("/proc/%d/auxv", PIDGET (inferior_ptid));
60 fd = open (pathname, writebuf != NULL ? O_WRONLY : O_RDONLY);
61 xfree (pathname);
62 if (fd < 0)
63 return -1;
64
65 if (offset != (ULONGEST) 0
66 && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
67 n = -1;
68 else if (readbuf != NULL)
69 n = read (fd, readbuf, len);
70 else
71 n = write (fd, writebuf, len);
72
73 (void) close (fd);
74
75 return n;
76}
77
14ed0a8b
RM
78/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
79 Return 0 if *READPTR is already at the end of the buffer.
80 Return -1 if there is insufficient buffer for a whole entry.
81 Return 1 if an entry was read into *TYPEP and *VALP. */
2c0b251b 82static int
c47ffbe3 83default_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
36aa5e41 84 gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
14ed0a8b 85{
ffe5a37e
UW
86 const int sizeof_auxv_field = gdbarch_ptr_bit (target_gdbarch)
87 / TARGET_CHAR_BIT;
36aa5e41 88 gdb_byte *ptr = *readptr;
14ed0a8b
RM
89
90 if (endptr == ptr)
91 return 0;
92
93 if (endptr - ptr < sizeof_auxv_field * 2)
94 return -1;
95
96 *typep = extract_unsigned_integer (ptr, sizeof_auxv_field);
97 ptr += sizeof_auxv_field;
98 *valp = extract_unsigned_integer (ptr, sizeof_auxv_field);
99 ptr += sizeof_auxv_field;
100
101 *readptr = ptr;
102 return 1;
103}
104
c47ffbe3
VP
105/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
106 Return 0 if *READPTR is already at the end of the buffer.
107 Return -1 if there is insufficient buffer for a whole entry.
108 Return 1 if an entry was read into *TYPEP and *VALP. */
109int
110target_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
111 gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
112{
113 struct target_ops *t;
114 for (t = ops; t != NULL; t = t->beneath)
115 if (t->to_auxv_parse != NULL)
116 return t->to_auxv_parse (t, readptr, endptr, typep, valp);
117
118 return default_auxv_parse (ops, readptr, endptr, typep, valp);
119}
120
14ed0a8b
RM
121/* Extract the auxiliary vector entry with a_type matching MATCH.
122 Return zero if no such entry was found, or -1 if there was
123 an error getting the information. On success, return 1 after
124 storing the entry's value field in *VALP. */
125int
126target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp)
127{
128 CORE_ADDR type, val;
36aa5e41 129 gdb_byte *data;
13547ab6 130 LONGEST n = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL, &data);
36aa5e41 131 gdb_byte *ptr = data;
14ed0a8b
RM
132 int ents = 0;
133
134 if (n <= 0)
135 return n;
136
137 while (1)
138 switch (target_auxv_parse (ops, &ptr, data + n, &type, &val))
139 {
140 case 1: /* Here's an entry, check it. */
141 if (type == match)
142 {
143 xfree (data);
144 *valp = val;
145 return 1;
146 }
147 break;
148 case 0: /* End of the vector. */
149 xfree (data);
150 return 0;
151 default: /* Bogosity. */
152 xfree (data);
153 return -1;
154 }
155
156 /*NOTREACHED*/
157}
158
159
160/* Print the contents of the target's AUXV on the specified file. */
161int
162fprint_target_auxv (struct ui_file *file, struct target_ops *ops)
163{
164 CORE_ADDR type, val;
36aa5e41 165 gdb_byte *data;
13547ab6
DJ
166 LONGEST len = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL,
167 &data);
36aa5e41 168 gdb_byte *ptr = data;
14ed0a8b
RM
169 int ents = 0;
170
171 if (len <= 0)
172 return len;
173
174 while (target_auxv_parse (ops, &ptr, data + len, &type, &val) > 0)
175 {
14ed0a8b
RM
176 const char *name = "???";
177 const char *description = "";
178 enum { dec, hex, str } flavor = hex;
179
180 switch (type)
181 {
182#define TAG(tag, text, kind) \
183 case tag: name = #tag; description = text; flavor = kind; break
edefbb7c
AC
184 TAG (AT_NULL, _("End of vector"), hex);
185 TAG (AT_IGNORE, _("Entry should be ignored"), hex);
186 TAG (AT_EXECFD, _("File descriptor of program"), dec);
187 TAG (AT_PHDR, _("Program headers for program"), hex);
188 TAG (AT_PHENT, _("Size of program header entry"), dec);
189 TAG (AT_PHNUM, _("Number of program headers"), dec);
190 TAG (AT_PAGESZ, _("System page size"), dec);
191 TAG (AT_BASE, _("Base address of interpreter"), hex);
192 TAG (AT_FLAGS, _("Flags"), hex);
193 TAG (AT_ENTRY, _("Entry point of program"), hex);
194 TAG (AT_NOTELF, _("Program is not ELF"), dec);
195 TAG (AT_UID, _("Real user ID"), dec);
196 TAG (AT_EUID, _("Effective user ID"), dec);
197 TAG (AT_GID, _("Real group ID"), dec);
198 TAG (AT_EGID, _("Effective group ID"), dec);
199 TAG (AT_CLKTCK, _("Frequency of times()"), dec);
200 TAG (AT_PLATFORM, _("String identifying platform"), str);
201 TAG (AT_HWCAP, _("Machine-dependent CPU capability hints"), hex);
202 TAG (AT_FPUCW, _("Used FPU control word"), dec);
203 TAG (AT_DCACHEBSIZE, _("Data cache block size"), dec);
204 TAG (AT_ICACHEBSIZE, _("Instruction cache block size"), dec);
205 TAG (AT_UCACHEBSIZE, _("Unified cache block size"), dec);
206 TAG (AT_IGNOREPPC, _("Entry should be ignored"), dec);
759cc328 207 TAG (AT_BASE_PLATFORM, _("String identifying base platform"), str);
ba30a4e9 208 TAG (AT_RANDOM, _("Address of 16 random bytes"), hex);
759cc328
UW
209 TAG (AT_EXECFN, _("File name of executable"), str);
210 TAG (AT_SECURE, _("Boolean, was exec setuid-like?"), dec);
edefbb7c
AC
211 TAG (AT_SYSINFO, _("Special system info/entry points"), hex);
212 TAG (AT_SYSINFO_EHDR, _("System-supplied DSO's ELF header"), hex);
edefbb7c
AC
213 TAG (AT_SUN_UID, _("Effective user ID"), dec);
214 TAG (AT_SUN_RUID, _("Real user ID"), dec);
215 TAG (AT_SUN_GID, _("Effective group ID"), dec);
216 TAG (AT_SUN_RGID, _("Real group ID"), dec);
217 TAG (AT_SUN_LDELF, _("Dynamic linker's ELF header"), hex);
218 TAG (AT_SUN_LDSHDR, _("Dynamic linker's section headers"), hex);
219 TAG (AT_SUN_LDNAME, _("String giving name of dynamic linker"), str);
220 TAG (AT_SUN_LPAGESZ, _("Large pagesize"), dec);
221 TAG (AT_SUN_PLATFORM, _("Platform name string"), str);
222 TAG (AT_SUN_HWCAP, _("Machine-dependent CPU capability hints"), hex);
223 TAG (AT_SUN_IFLUSH, _("Should flush icache?"), dec);
224 TAG (AT_SUN_CPU, _("CPU name string"), str);
225 TAG (AT_SUN_EMUL_ENTRY, _("COFF entry point address"), hex);
226 TAG (AT_SUN_EMUL_EXECFD, _("COFF executable file descriptor"), dec);
14ed0a8b 227 TAG (AT_SUN_EXECNAME,
edefbb7c
AC
228 _("Canonicalized file name given to execve"), str);
229 TAG (AT_SUN_MMU, _("String for name of MMU module"), str);
230 TAG (AT_SUN_LDDATA, _("Dynamic linker's data segment address"), hex);
77d49ac6
MK
231 TAG (AT_SUN_AUXFLAGS,
232 _("AF_SUN_ flags passed from the kernel"), hex);
14ed0a8b
RM
233 }
234
235 fprintf_filtered (file, "%-4s %-20s %-30s ",
623d3eb1 236 plongest (type), name, description);
14ed0a8b
RM
237 switch (flavor)
238 {
239 case dec:
623d3eb1 240 fprintf_filtered (file, "%s\n", plongest (val));
14ed0a8b
RM
241 break;
242 case hex:
243 fprintf_filtered (file, "0x%s\n", paddr_nz (val));
244 break;
245 case str:
79a45b7d
TT
246 {
247 struct value_print_options opts;
248 get_user_print_options (&opts);
249 if (opts.addressprint)
250 fprintf_filtered (file, "0x%s", paddr_nz (val));
251 val_print_string (val, -1, 1, file, &opts);
252 fprintf_filtered (file, "\n");
253 }
14ed0a8b
RM
254 break;
255 }
256 ++ents;
7c6467a4
PP
257 if (type == AT_NULL)
258 break;
14ed0a8b
RM
259 }
260
261 xfree (data);
262
263 return ents;
264}
265
266static void
267info_auxv_command (char *cmd, int from_tty)
268{
14ed0a8b 269 if (! target_has_stack)
edefbb7c 270 error (_("The program has no auxiliary information now."));
14ed0a8b
RM
271 else
272 {
273 int ents = fprint_target_auxv (gdb_stdout, &current_target);
274 if (ents < 0)
edefbb7c 275 error (_("No auxiliary vector found, or failed reading it."));
14ed0a8b 276 else if (ents == 0)
edefbb7c 277 error (_("Auxiliary vector is empty."));
14ed0a8b
RM
278 }
279}
280
281
282extern initialize_file_ftype _initialize_auxv; /* -Wmissing-prototypes; */
283
284void
285_initialize_auxv (void)
286{
287 add_info ("auxv", info_auxv_command,
edefbb7c
AC
288 _("Display the inferior's auxiliary vector.\n\
289This is information provided by the operating system at program startup."));
14ed0a8b 290}
This page took 0.31486 seconds and 4 git commands to generate.