*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / auxv.c
CommitLineData
14ed0a8b
RM
1/* Auxiliary vector support for GDB, the GNU debugger.
2
9b254dd1 3 Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
14ed0a8b
RM
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
14ed0a8b
RM
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
14ed0a8b
RM
19
20#include "defs.h"
21#include "target.h"
22#include "gdbtypes.h"
23#include "command.h"
24#include "inferior.h"
25#include "valprint.h"
26#include "gdb_assert.h"
27
28#include "auxv.h"
29#include "elf/common.h"
30
31#include <unistd.h>
32#include <fcntl.h>
33
34
35/* This function is called like a to_xfer_partial hook,
36 but must be called with TARGET_OBJECT_AUXV.
37 It handles access via /proc/PID/auxv, which is the common method.
38 This function is appropriate for doing:
39 #define NATIVE_XFER_AUXV procfs_xfer_auxv
40 for a native target that uses inftarg.c's child_xfer_partial hook. */
41
42LONGEST
43procfs_xfer_auxv (struct target_ops *ops,
44 int /* enum target_object */ object,
45 const char *annex,
36aa5e41
AC
46 gdb_byte *readbuf,
47 const gdb_byte *writebuf,
14ed0a8b
RM
48 ULONGEST offset,
49 LONGEST len)
50{
51 char *pathname;
52 int fd;
53 LONGEST n;
54
55 gdb_assert (object == TARGET_OBJECT_AUXV);
56 gdb_assert (readbuf || writebuf);
57
58 pathname = xstrprintf ("/proc/%d/auxv", PIDGET (inferior_ptid));
59 fd = open (pathname, writebuf != NULL ? O_WRONLY : O_RDONLY);
60 xfree (pathname);
61 if (fd < 0)
62 return -1;
63
64 if (offset != (ULONGEST) 0
65 && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
66 n = -1;
67 else if (readbuf != NULL)
68 n = read (fd, readbuf, len);
69 else
70 n = write (fd, writebuf, len);
71
72 (void) close (fd);
73
74 return n;
75}
76
14ed0a8b
RM
77/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
78 Return 0 if *READPTR is already at the end of the buffer.
79 Return -1 if there is insufficient buffer for a whole entry.
80 Return 1 if an entry was read into *TYPEP and *VALP. */
81int
c47ffbe3 82default_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
36aa5e41 83 gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
14ed0a8b 84{
ffe5a37e
UW
85 const int sizeof_auxv_field = gdbarch_ptr_bit (target_gdbarch)
86 / TARGET_CHAR_BIT;
36aa5e41 87 gdb_byte *ptr = *readptr;
14ed0a8b
RM
88
89 if (endptr == ptr)
90 return 0;
91
92 if (endptr - ptr < sizeof_auxv_field * 2)
93 return -1;
94
95 *typep = extract_unsigned_integer (ptr, sizeof_auxv_field);
96 ptr += sizeof_auxv_field;
97 *valp = extract_unsigned_integer (ptr, sizeof_auxv_field);
98 ptr += sizeof_auxv_field;
99
100 *readptr = ptr;
101 return 1;
102}
103
c47ffbe3
VP
104/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
105 Return 0 if *READPTR is already at the end of the buffer.
106 Return -1 if there is insufficient buffer for a whole entry.
107 Return 1 if an entry was read into *TYPEP and *VALP. */
108int
109target_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
110 gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
111{
112 struct target_ops *t;
113 for (t = ops; t != NULL; t = t->beneath)
114 if (t->to_auxv_parse != NULL)
115 return t->to_auxv_parse (t, readptr, endptr, typep, valp);
116
117 return default_auxv_parse (ops, readptr, endptr, typep, valp);
118}
119
14ed0a8b
RM
120/* Extract the auxiliary vector entry with a_type matching MATCH.
121 Return zero if no such entry was found, or -1 if there was
122 an error getting the information. On success, return 1 after
123 storing the entry's value field in *VALP. */
124int
125target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp)
126{
127 CORE_ADDR type, val;
36aa5e41 128 gdb_byte *data;
13547ab6 129 LONGEST n = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL, &data);
36aa5e41 130 gdb_byte *ptr = data;
14ed0a8b
RM
131 int ents = 0;
132
133 if (n <= 0)
134 return n;
135
136 while (1)
137 switch (target_auxv_parse (ops, &ptr, data + n, &type, &val))
138 {
139 case 1: /* Here's an entry, check it. */
140 if (type == match)
141 {
142 xfree (data);
143 *valp = val;
144 return 1;
145 }
146 break;
147 case 0: /* End of the vector. */
148 xfree (data);
149 return 0;
150 default: /* Bogosity. */
151 xfree (data);
152 return -1;
153 }
154
155 /*NOTREACHED*/
156}
157
158
159/* Print the contents of the target's AUXV on the specified file. */
160int
161fprint_target_auxv (struct ui_file *file, struct target_ops *ops)
162{
163 CORE_ADDR type, val;
36aa5e41 164 gdb_byte *data;
13547ab6
DJ
165 LONGEST len = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL,
166 &data);
36aa5e41 167 gdb_byte *ptr = data;
14ed0a8b
RM
168 int ents = 0;
169
170 if (len <= 0)
171 return len;
172
173 while (target_auxv_parse (ops, &ptr, data + len, &type, &val) > 0)
174 {
175 extern int addressprint;
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);
207 TAG (AT_SYSINFO, _("Special system info/entry points"), hex);
208 TAG (AT_SYSINFO_EHDR, _("System-supplied DSO's ELF header"), hex);
209 TAG (AT_SECURE, _("Boolean, was exec setuid-like?"), dec);
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:
240 fprintf_filtered (file, "0x%s\n", paddr_nz (val));
241 break;
242 case str:
243 if (addressprint)
244 fprintf_filtered (file, "0x%s", paddr_nz (val));
245 val_print_string (val, -1, 1, file);
246 fprintf_filtered (file, "\n");
247 break;
248 }
249 ++ents;
7c6467a4
PP
250 if (type == AT_NULL)
251 break;
14ed0a8b
RM
252 }
253
254 xfree (data);
255
256 return ents;
257}
258
259static void
260info_auxv_command (char *cmd, int from_tty)
261{
14ed0a8b 262 if (! target_has_stack)
edefbb7c 263 error (_("The program has no auxiliary information now."));
14ed0a8b
RM
264 else
265 {
266 int ents = fprint_target_auxv (gdb_stdout, &current_target);
267 if (ents < 0)
edefbb7c 268 error (_("No auxiliary vector found, or failed reading it."));
14ed0a8b 269 else if (ents == 0)
edefbb7c 270 error (_("Auxiliary vector is empty."));
14ed0a8b
RM
271 }
272}
273
274
275extern initialize_file_ftype _initialize_auxv; /* -Wmissing-prototypes; */
276
277void
278_initialize_auxv (void)
279{
280 add_info ("auxv", info_auxv_command,
edefbb7c
AC
281 _("Display the inferior's auxiliary vector.\n\
282This is information provided by the operating system at program startup."));
14ed0a8b 283}
This page took 0.437455 seconds and 4 git commands to generate.