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