Fix ChangeLog dates
[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);
206 TAG (AT_SYSINFO, _("Special system info/entry points"), hex);
207 TAG (AT_SYSINFO_EHDR, _("System-supplied DSO's ELF header"), hex);
208 TAG (AT_SECURE, _("Boolean, was exec setuid-like?"), dec);
209 TAG (AT_SUN_UID, _("Effective user ID"), dec);
210 TAG (AT_SUN_RUID, _("Real user ID"), dec);
211 TAG (AT_SUN_GID, _("Effective group ID"), dec);
212 TAG (AT_SUN_RGID, _("Real group ID"), dec);
213 TAG (AT_SUN_LDELF, _("Dynamic linker's ELF header"), hex);
214 TAG (AT_SUN_LDSHDR, _("Dynamic linker's section headers"), hex);
215 TAG (AT_SUN_LDNAME, _("String giving name of dynamic linker"), str);
216 TAG (AT_SUN_LPAGESZ, _("Large pagesize"), dec);
217 TAG (AT_SUN_PLATFORM, _("Platform name string"), str);
218 TAG (AT_SUN_HWCAP, _("Machine-dependent CPU capability hints"), hex);
219 TAG (AT_SUN_IFLUSH, _("Should flush icache?"), dec);
220 TAG (AT_SUN_CPU, _("CPU name string"), str);
221 TAG (AT_SUN_EMUL_ENTRY, _("COFF entry point address"), hex);
222 TAG (AT_SUN_EMUL_EXECFD, _("COFF executable file descriptor"), dec);
14ed0a8b 223 TAG (AT_SUN_EXECNAME,
edefbb7c
AC
224 _("Canonicalized file name given to execve"), str);
225 TAG (AT_SUN_MMU, _("String for name of MMU module"), str);
226 TAG (AT_SUN_LDDATA, _("Dynamic linker's data segment address"), hex);
77d49ac6
MK
227 TAG (AT_SUN_AUXFLAGS,
228 _("AF_SUN_ flags passed from the kernel"), hex);
14ed0a8b
RM
229 }
230
231 fprintf_filtered (file, "%-4s %-20s %-30s ",
623d3eb1 232 plongest (type), name, description);
14ed0a8b
RM
233 switch (flavor)
234 {
235 case dec:
623d3eb1 236 fprintf_filtered (file, "%s\n", plongest (val));
14ed0a8b
RM
237 break;
238 case hex:
239 fprintf_filtered (file, "0x%s\n", paddr_nz (val));
240 break;
241 case str:
79a45b7d
TT
242 {
243 struct value_print_options opts;
244 get_user_print_options (&opts);
245 if (opts.addressprint)
246 fprintf_filtered (file, "0x%s", paddr_nz (val));
247 val_print_string (val, -1, 1, file, &opts);
248 fprintf_filtered (file, "\n");
249 }
14ed0a8b
RM
250 break;
251 }
252 ++ents;
7c6467a4
PP
253 if (type == AT_NULL)
254 break;
14ed0a8b
RM
255 }
256
257 xfree (data);
258
259 return ents;
260}
261
262static void
263info_auxv_command (char *cmd, int from_tty)
264{
14ed0a8b 265 if (! target_has_stack)
edefbb7c 266 error (_("The program has no auxiliary information now."));
14ed0a8b
RM
267 else
268 {
269 int ents = fprint_target_auxv (gdb_stdout, &current_target);
270 if (ents < 0)
edefbb7c 271 error (_("No auxiliary vector found, or failed reading it."));
14ed0a8b 272 else if (ents == 0)
edefbb7c 273 error (_("Auxiliary vector is empty."));
14ed0a8b
RM
274 }
275}
276
277
278extern initialize_file_ftype _initialize_auxv; /* -Wmissing-prototypes; */
279
280void
281_initialize_auxv (void)
282{
283 add_info ("auxv", info_auxv_command,
edefbb7c
AC
284 _("Display the inferior's auxiliary vector.\n\
285This is information provided by the operating system at program startup."));
14ed0a8b 286}
This page took 0.269802 seconds and 4 git commands to generate.