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