OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [gdb/] [auxv.c] - Blame information for rev 330

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* Auxiliary vector support for GDB, the GNU debugger.
2
 
3
   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
4
   Free Software Foundation, Inc.
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
10
   the Free Software Foundation; either version 3 of the License, or
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
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
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
#include "gdbcore.h"
29
 
30
#include "auxv.h"
31
#include "elf/common.h"
32
 
33
#include <unistd.h>
34
#include <fcntl.h>
35
 
36
 
37
/* This function handles access via /proc/PID/auxv, which is a common method
38
   for native targets.  */
39
 
40
static LONGEST
41
procfs_xfer_auxv (gdb_byte *readbuf,
42
                  const gdb_byte *writebuf,
43
                  ULONGEST offset,
44
                  LONGEST len)
45
{
46
  char *pathname;
47
  int fd;
48
  LONGEST n;
49
 
50
  pathname = xstrprintf ("/proc/%d/auxv", PIDGET (inferior_ptid));
51
  fd = open (pathname, writebuf != NULL ? O_WRONLY : O_RDONLY);
52
  xfree (pathname);
53
  if (fd < 0)
54
    return -1;
55
 
56
  if (offset != (ULONGEST) 0
57
      && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
58
    n = -1;
59
  else if (readbuf != NULL)
60
    n = read (fd, readbuf, len);
61
  else
62
    n = write (fd, writebuf, len);
63
 
64
  (void) close (fd);
65
 
66
  return n;
67
}
68
 
69
/* This function handles access via ld.so's symbol `_dl_auxv'.  */
70
 
71
static LONGEST
72
ld_so_xfer_auxv (gdb_byte *readbuf,
73
                 const gdb_byte *writebuf,
74
                 ULONGEST offset,
75
                 LONGEST len)
76
{
77
  struct minimal_symbol *msym;
78
  CORE_ADDR data_address, pointer_address;
79
  struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
80
  size_t ptr_size = TYPE_LENGTH (ptr_type);
81
  size_t auxv_pair_size = 2 * ptr_size;
82
  gdb_byte *ptr_buf = alloca (ptr_size);
83
  LONGEST retval;
84
  size_t block;
85
 
86
  msym = lookup_minimal_symbol ("_dl_auxv", NULL, NULL);
87
  if (msym == NULL)
88
    return -1;
89
 
90
  if (MSYMBOL_SIZE (msym) != ptr_size)
91
    return -1;
92
 
93
  /* POINTER_ADDRESS is a location where the `_dl_auxv' variable resides.
94
     DATA_ADDRESS is the inferior value present in `_dl_auxv', therefore the
95
     real inferior AUXV address.  */
96
 
97
  pointer_address = SYMBOL_VALUE_ADDRESS (msym);
98
 
99
  /* The location of the _dl_auxv symbol may no longer be correct if
100
     ld.so runs at a different address than the one present in the file.
101
     This is very common case - for unprelinked ld.so or with a PIE executable.
102
     PIE executable forces random address even for libraries already being
103
     prelinked to some address.  PIE executables themselves are never prelinked
104
     even on prelinked systems.  Prelinking of a PIE executable would block
105
     their purpose of randomizing load of everything including the executable.
106
 
107
     If the memory read fails, return -1 to fallback on another mechanism for
108
     retrieving the AUXV.
109
 
110
     In most cases of a PIE running under valgrind there is no way to find
111
     out the base addresses of any of ld.so, executable or AUXV as everything
112
     is randomized and /proc information is not relevant for the virtual
113
     executable running under valgrind.  We think that we might need a valgrind
114
     extension to make it work.  This is PR 11440.  */
115
 
116
  if (target_read_memory (pointer_address, ptr_buf, ptr_size) != 0)
117
    return -1;
118
 
119
  data_address = extract_typed_address (ptr_buf, ptr_type);
120
 
121
  /* Possibly still not initialized such as during an inferior startup.  */
122
  if (data_address == 0)
123
    return -1;
124
 
125
  data_address += offset;
126
 
127
  if (writebuf != NULL)
128
    {
129
      if (target_write_memory (data_address, writebuf, len) == 0)
130
        return len;
131
      else
132
        return -1;
133
    }
134
 
135
  /* Stop if trying to read past the existing AUXV block.  The final AT_NULL
136
     was already returned before.  */
137
 
138
  if (offset >= auxv_pair_size)
139
    {
140
      if (target_read_memory (data_address - auxv_pair_size, ptr_buf,
141
                              ptr_size) != 0)
142
        return -1;
143
 
144
      if (extract_typed_address (ptr_buf, ptr_type) == AT_NULL)
145
        return 0;
146
    }
147
 
148
  retval = 0;
149
  block = 0x400;
150
  gdb_assert (block % auxv_pair_size == 0);
151
 
152
  while (len > 0)
153
    {
154
      if (block > len)
155
        block = len;
156
 
157
      /* Reading sizes smaller than AUXV_PAIR_SIZE is not supported.  Tails
158
         unaligned to AUXV_PAIR_SIZE will not be read during a call (they
159
         should be completed during next read with new/extended buffer).  */
160
 
161
      block &= -auxv_pair_size;
162
      if (block == 0)
163
        return retval;
164
 
165
      if (target_read_memory (data_address, readbuf, block) != 0)
166
        {
167
          if (block <= auxv_pair_size)
168
            return retval;
169
 
170
          block = auxv_pair_size;
171
          continue;
172
        }
173
 
174
      data_address += block;
175
      len -= block;
176
 
177
      /* Check terminal AT_NULL.  This function is being called indefinitely
178
         being extended its READBUF until it returns EOF (0).  */
179
 
180
      while (block >= auxv_pair_size)
181
        {
182
          retval += auxv_pair_size;
183
 
184
          if (extract_typed_address (readbuf, ptr_type) == AT_NULL)
185
            return retval;
186
 
187
          readbuf += auxv_pair_size;
188
          block -= auxv_pair_size;
189
        }
190
    }
191
 
192
  return retval;
193
}
194
 
195
/* This function is called like a to_xfer_partial hook, but must be
196
   called with TARGET_OBJECT_AUXV.  It handles access to AUXV.  */
197
 
198
LONGEST
199
memory_xfer_auxv (struct target_ops *ops,
200
                  enum target_object object,
201
                  const char *annex,
202
                  gdb_byte *readbuf,
203
                  const gdb_byte *writebuf,
204
                  ULONGEST offset,
205
                  LONGEST len)
206
{
207
  gdb_assert (object == TARGET_OBJECT_AUXV);
208
  gdb_assert (readbuf || writebuf);
209
 
210
   /* ld_so_xfer_auxv is the only function safe for virtual executables being
211
      executed by valgrind's memcheck.  Using ld_so_xfer_auxv during inferior
212
      startup is problematic, because ld.so symbol tables have not yet been
213
      relocated.  So GDB uses this function only when attaching to a process.
214
      */
215
 
216
  if (current_inferior ()->attach_flag != 0)
217
    {
218
      LONGEST retval;
219
 
220
      retval = ld_so_xfer_auxv (readbuf, writebuf, offset, len);
221
      if (retval != -1)
222
        return retval;
223
    }
224
 
225
  return procfs_xfer_auxv (readbuf, writebuf, offset, len);
226
}
227
 
228
/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
229
   Return 0 if *READPTR is already at the end of the buffer.
230
   Return -1 if there is insufficient buffer for a whole entry.
231
   Return 1 if an entry was read into *TYPEP and *VALP.  */
232
static int
233
default_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
234
                   gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
235
{
236
  const int sizeof_auxv_field = gdbarch_ptr_bit (target_gdbarch)
237
                                / TARGET_CHAR_BIT;
238
  const enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
239
  gdb_byte *ptr = *readptr;
240
 
241
  if (endptr == ptr)
242
    return 0;
243
 
244
  if (endptr - ptr < sizeof_auxv_field * 2)
245
    return -1;
246
 
247
  *typep = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
248
  ptr += sizeof_auxv_field;
249
  *valp = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
250
  ptr += sizeof_auxv_field;
251
 
252
  *readptr = ptr;
253
  return 1;
254
}
255
 
256
/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
257
   Return 0 if *READPTR is already at the end of the buffer.
258
   Return -1 if there is insufficient buffer for a whole entry.
259
   Return 1 if an entry was read into *TYPEP and *VALP.  */
260
int
261
target_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
262
                  gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
263
{
264
  struct target_ops *t;
265
 
266
  for (t = ops; t != NULL; t = t->beneath)
267
    if (t->to_auxv_parse != NULL)
268
      return t->to_auxv_parse (t, readptr, endptr, typep, valp);
269
 
270
  return default_auxv_parse (ops, readptr, endptr, typep, valp);
271
}
272
 
273
/* Extract the auxiliary vector entry with a_type matching MATCH.
274
   Return zero if no such entry was found, or -1 if there was
275
   an error getting the information.  On success, return 1 after
276
   storing the entry's value field in *VALP.  */
277
int
278
target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp)
279
{
280
  CORE_ADDR type, val;
281
  gdb_byte *data;
282
  LONGEST n = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL, &data);
283
  gdb_byte *ptr = data;
284
 
285
  if (n <= 0)
286
    return n;
287
 
288
  while (1)
289
    switch (target_auxv_parse (ops, &ptr, data + n, &type, &val))
290
      {
291
      case 1:                   /* Here's an entry, check it.  */
292
        if (type == match)
293
          {
294
            xfree (data);
295
            *valp = val;
296
            return 1;
297
          }
298
        break;
299
      case 0:                    /* End of the vector.  */
300
        xfree (data);
301
        return 0;
302
      default:                  /* Bogosity.  */
303
        xfree (data);
304
        return -1;
305
      }
306
 
307
  /*NOTREACHED*/
308
}
309
 
310
 
311
/* Print the contents of the target's AUXV on the specified file. */
312
int
313
fprint_target_auxv (struct ui_file *file, struct target_ops *ops)
314
{
315
  CORE_ADDR type, val;
316
  gdb_byte *data;
317
  LONGEST len = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL,
318
                                   &data);
319
  gdb_byte *ptr = data;
320
  int ents = 0;
321
 
322
  if (len <= 0)
323
    return len;
324
 
325
  while (target_auxv_parse (ops, &ptr, data + len, &type, &val) > 0)
326
    {
327
      const char *name = "???";
328
      const char *description = "";
329
      enum { dec, hex, str } flavor = hex;
330
 
331
      switch (type)
332
        {
333
#define TAG(tag, text, kind) \
334
        case tag: name = #tag; description = text; flavor = kind; break
335
          TAG (AT_NULL, _("End of vector"), hex);
336
          TAG (AT_IGNORE, _("Entry should be ignored"), hex);
337
          TAG (AT_EXECFD, _("File descriptor of program"), dec);
338
          TAG (AT_PHDR, _("Program headers for program"), hex);
339
          TAG (AT_PHENT, _("Size of program header entry"), dec);
340
          TAG (AT_PHNUM, _("Number of program headers"), dec);
341
          TAG (AT_PAGESZ, _("System page size"), dec);
342
          TAG (AT_BASE, _("Base address of interpreter"), hex);
343
          TAG (AT_FLAGS, _("Flags"), hex);
344
          TAG (AT_ENTRY, _("Entry point of program"), hex);
345
          TAG (AT_NOTELF, _("Program is not ELF"), dec);
346
          TAG (AT_UID, _("Real user ID"), dec);
347
          TAG (AT_EUID, _("Effective user ID"), dec);
348
          TAG (AT_GID, _("Real group ID"), dec);
349
          TAG (AT_EGID, _("Effective group ID"), dec);
350
          TAG (AT_CLKTCK, _("Frequency of times()"), dec);
351
          TAG (AT_PLATFORM, _("String identifying platform"), str);
352
          TAG (AT_HWCAP, _("Machine-dependent CPU capability hints"), hex);
353
          TAG (AT_FPUCW, _("Used FPU control word"), dec);
354
          TAG (AT_DCACHEBSIZE, _("Data cache block size"), dec);
355
          TAG (AT_ICACHEBSIZE, _("Instruction cache block size"), dec);
356
          TAG (AT_UCACHEBSIZE, _("Unified cache block size"), dec);
357
          TAG (AT_IGNOREPPC, _("Entry should be ignored"), dec);
358
          TAG (AT_BASE_PLATFORM, _("String identifying base platform"), str);
359
          TAG (AT_RANDOM, _("Address of 16 random bytes"), hex);
360
          TAG (AT_EXECFN, _("File name of executable"), str);
361
          TAG (AT_SECURE, _("Boolean, was exec setuid-like?"), dec);
362
          TAG (AT_SYSINFO, _("Special system info/entry points"), hex);
363
          TAG (AT_SYSINFO_EHDR, _("System-supplied DSO's ELF header"), hex);
364
          TAG (AT_SUN_UID, _("Effective user ID"), dec);
365
          TAG (AT_SUN_RUID, _("Real user ID"), dec);
366
          TAG (AT_SUN_GID, _("Effective group ID"), dec);
367
          TAG (AT_SUN_RGID, _("Real group ID"), dec);
368
          TAG (AT_SUN_LDELF, _("Dynamic linker's ELF header"), hex);
369
          TAG (AT_SUN_LDSHDR, _("Dynamic linker's section headers"), hex);
370
          TAG (AT_SUN_LDNAME, _("String giving name of dynamic linker"), str);
371
          TAG (AT_SUN_LPAGESZ, _("Large pagesize"), dec);
372
          TAG (AT_SUN_PLATFORM, _("Platform name string"), str);
373
          TAG (AT_SUN_HWCAP, _("Machine-dependent CPU capability hints"), hex);
374
          TAG (AT_SUN_IFLUSH, _("Should flush icache?"), dec);
375
          TAG (AT_SUN_CPU, _("CPU name string"), str);
376
          TAG (AT_SUN_EMUL_ENTRY, _("COFF entry point address"), hex);
377
          TAG (AT_SUN_EMUL_EXECFD, _("COFF executable file descriptor"), dec);
378
          TAG (AT_SUN_EXECNAME,
379
               _("Canonicalized file name given to execve"), str);
380
          TAG (AT_SUN_MMU, _("String for name of MMU module"), str);
381
          TAG (AT_SUN_LDDATA, _("Dynamic linker's data segment address"), hex);
382
          TAG (AT_SUN_AUXFLAGS,
383
               _("AF_SUN_ flags passed from the kernel"), hex);
384
        }
385
 
386
      fprintf_filtered (file, "%-4s %-20s %-30s ",
387
                        plongest (type), name, description);
388
      switch (flavor)
389
        {
390
        case dec:
391
          fprintf_filtered (file, "%s\n", plongest (val));
392
          break;
393
        case hex:
394
          fprintf_filtered (file, "%s\n", paddress (target_gdbarch, val));
395
          break;
396
        case str:
397
          {
398
            struct value_print_options opts;
399
 
400
            get_user_print_options (&opts);
401
            if (opts.addressprint)
402
              fprintf_filtered (file, "%s", paddress (target_gdbarch, val));
403
            val_print_string (builtin_type (target_gdbarch)->builtin_char,
404
                              val, -1, file, &opts);
405
            fprintf_filtered (file, "\n");
406
          }
407
          break;
408
        }
409
      ++ents;
410
      if (type == AT_NULL)
411
        break;
412
    }
413
 
414
  xfree (data);
415
 
416
  return ents;
417
}
418
 
419
static void
420
info_auxv_command (char *cmd, int from_tty)
421
{
422
  if (! target_has_stack)
423
    error (_("The program has no auxiliary information now."));
424
  else
425
    {
426
      int ents = fprint_target_auxv (gdb_stdout, &current_target);
427
 
428
      if (ents < 0)
429
        error (_("No auxiliary vector found, or failed reading it."));
430
      else if (ents == 0)
431
        error (_("Auxiliary vector is empty."));
432
    }
433
}
434
 
435
 
436
extern initialize_file_ftype _initialize_auxv; /* -Wmissing-prototypes; */
437
 
438
void
439
_initialize_auxv (void)
440
{
441
  add_info ("auxv", info_auxv_command,
442
            _("Display the inferior's auxiliary vector.\n\
443
This is information provided by the operating system at program startup."));
444
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.