* cris.h (R_CRIS_32_IE): New relocation.
[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 {
14ed0a8b
RM
175 const char *name = "???";
176 const char *description = "";
177 enum { dec, hex, str } flavor = hex;
178
179 switch (type)
180 {
181#define TAG(tag, text, kind) \
182 case tag: name = #tag; description = text; flavor = kind; break
edefbb7c
AC
183 TAG (AT_NULL, _("End of vector"), hex);
184 TAG (AT_IGNORE, _("Entry should be ignored"), hex);
185 TAG (AT_EXECFD, _("File descriptor of program"), dec);
186 TAG (AT_PHDR, _("Program headers for program"), hex);
187 TAG (AT_PHENT, _("Size of program header entry"), dec);
188 TAG (AT_PHNUM, _("Number of program headers"), dec);
189 TAG (AT_PAGESZ, _("System page size"), dec);
190 TAG (AT_BASE, _("Base address of interpreter"), hex);
191 TAG (AT_FLAGS, _("Flags"), hex);
192 TAG (AT_ENTRY, _("Entry point of program"), hex);
193 TAG (AT_NOTELF, _("Program is not ELF"), dec);
194 TAG (AT_UID, _("Real user ID"), dec);
195 TAG (AT_EUID, _("Effective user ID"), dec);
196 TAG (AT_GID, _("Real group ID"), dec);
197 TAG (AT_EGID, _("Effective group ID"), dec);
198 TAG (AT_CLKTCK, _("Frequency of times()"), dec);
199 TAG (AT_PLATFORM, _("String identifying platform"), str);
200 TAG (AT_HWCAP, _("Machine-dependent CPU capability hints"), hex);
201 TAG (AT_FPUCW, _("Used FPU control word"), dec);
202 TAG (AT_DCACHEBSIZE, _("Data cache block size"), dec);
203 TAG (AT_ICACHEBSIZE, _("Instruction cache block size"), dec);
204 TAG (AT_UCACHEBSIZE, _("Unified cache block size"), dec);
205 TAG (AT_IGNOREPPC, _("Entry should be ignored"), dec);
759cc328
UW
206 TAG (AT_BASE_PLATFORM, _("String identifying base platform"), str);
207 TAG (AT_EXECFN, _("File name of executable"), str);
208 TAG (AT_SECURE, _("Boolean, was exec setuid-like?"), dec);
edefbb7c
AC
209 TAG (AT_SYSINFO, _("Special system info/entry points"), hex);
210 TAG (AT_SYSINFO_EHDR, _("System-supplied DSO's ELF header"), hex);
edefbb7c
AC
211 TAG (AT_SUN_UID, _("Effective user ID"), dec);
212 TAG (AT_SUN_RUID, _("Real user ID"), dec);
213 TAG (AT_SUN_GID, _("Effective group ID"), dec);
214 TAG (AT_SUN_RGID, _("Real group ID"), dec);
215 TAG (AT_SUN_LDELF, _("Dynamic linker's ELF header"), hex);
216 TAG (AT_SUN_LDSHDR, _("Dynamic linker's section headers"), hex);
217 TAG (AT_SUN_LDNAME, _("String giving name of dynamic linker"), str);
218 TAG (AT_SUN_LPAGESZ, _("Large pagesize"), dec);
219 TAG (AT_SUN_PLATFORM, _("Platform name string"), str);
220 TAG (AT_SUN_HWCAP, _("Machine-dependent CPU capability hints"), hex);
221 TAG (AT_SUN_IFLUSH, _("Should flush icache?"), dec);
222 TAG (AT_SUN_CPU, _("CPU name string"), str);
223 TAG (AT_SUN_EMUL_ENTRY, _("COFF entry point address"), hex);
224 TAG (AT_SUN_EMUL_EXECFD, _("COFF executable file descriptor"), dec);
14ed0a8b 225 TAG (AT_SUN_EXECNAME,
edefbb7c
AC
226 _("Canonicalized file name given to execve"), str);
227 TAG (AT_SUN_MMU, _("String for name of MMU module"), str);
228 TAG (AT_SUN_LDDATA, _("Dynamic linker's data segment address"), hex);
77d49ac6
MK
229 TAG (AT_SUN_AUXFLAGS,
230 _("AF_SUN_ flags passed from the kernel"), hex);
14ed0a8b
RM
231 }
232
233 fprintf_filtered (file, "%-4s %-20s %-30s ",
623d3eb1 234 plongest (type), name, description);
14ed0a8b
RM
235 switch (flavor)
236 {
237 case dec:
623d3eb1 238 fprintf_filtered (file, "%s\n", plongest (val));
14ed0a8b
RM
239 break;
240 case hex:
241 fprintf_filtered (file, "0x%s\n", paddr_nz (val));
242 break;
243 case str:
79a45b7d
TT
244 {
245 struct value_print_options opts;
246 get_user_print_options (&opts);
247 if (opts.addressprint)
248 fprintf_filtered (file, "0x%s", paddr_nz (val));
249 val_print_string (val, -1, 1, file, &opts);
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.275368 seconds and 4 git commands to generate.