GDB (API)
/home/stan/gdb/src/gdb/auxv.c
Go to the documentation of this file.
00001 /* Auxiliary vector support for GDB, the GNU debugger.
00002 
00003    Copyright (C) 2004-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "target.h"
00022 #include "gdbtypes.h"
00023 #include "command.h"
00024 #include "inferior.h"
00025 #include "valprint.h"
00026 #include "gdb_assert.h"
00027 #include "gdbcore.h"
00028 #include "observer.h"
00029 #include "filestuff.h"
00030 
00031 #include "auxv.h"
00032 #include "elf/common.h"
00033 
00034 #include <unistd.h>
00035 #include <fcntl.h>
00036 
00037 
00038 /* This function handles access via /proc/PID/auxv, which is a common
00039    method for native targets.  */
00040 
00041 static LONGEST
00042 procfs_xfer_auxv (gdb_byte *readbuf,
00043                   const gdb_byte *writebuf,
00044                   ULONGEST offset,
00045                   LONGEST len)
00046 {
00047   char *pathname;
00048   int fd;
00049   LONGEST n;
00050 
00051   pathname = xstrprintf ("/proc/%d/auxv", ptid_get_pid (inferior_ptid));
00052   fd = gdb_open_cloexec (pathname, writebuf != NULL ? O_WRONLY : O_RDONLY, 0);
00053   xfree (pathname);
00054   if (fd < 0)
00055     return -1;
00056 
00057   if (offset != (ULONGEST) 0
00058       && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
00059     n = -1;
00060   else if (readbuf != NULL)
00061     n = read (fd, readbuf, len);
00062   else
00063     n = write (fd, writebuf, len);
00064 
00065   (void) close (fd);
00066 
00067   return n;
00068 }
00069 
00070 /* This function handles access via ld.so's symbol `_dl_auxv'.  */
00071 
00072 static LONGEST
00073 ld_so_xfer_auxv (gdb_byte *readbuf,
00074                  const gdb_byte *writebuf,
00075                  ULONGEST offset,
00076                  LONGEST len)
00077 {
00078   struct minimal_symbol *msym;
00079   CORE_ADDR data_address, pointer_address;
00080   struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
00081   size_t ptr_size = TYPE_LENGTH (ptr_type);
00082   size_t auxv_pair_size = 2 * ptr_size;
00083   gdb_byte *ptr_buf = alloca (ptr_size);
00084   LONGEST retval;
00085   size_t block;
00086 
00087   msym = lookup_minimal_symbol ("_dl_auxv", NULL, NULL);
00088   if (msym == NULL)
00089     return -1;
00090 
00091   if (MSYMBOL_SIZE (msym) != ptr_size)
00092     return -1;
00093 
00094   /* POINTER_ADDRESS is a location where the `_dl_auxv' variable
00095      resides.  DATA_ADDRESS is the inferior value present in
00096      `_dl_auxv', therefore the real inferior AUXV address.  */
00097 
00098   pointer_address = SYMBOL_VALUE_ADDRESS (msym);
00099 
00100   /* The location of the _dl_auxv symbol may no longer be correct if
00101      ld.so runs at a different address than the one present in the
00102      file.  This is very common case - for unprelinked ld.so or with a
00103      PIE executable.  PIE executable forces random address even for
00104      libraries already being prelinked to some address.  PIE
00105      executables themselves are never prelinked even on prelinked
00106      systems.  Prelinking of a PIE executable would block their
00107      purpose of randomizing load of everything including the
00108      executable.
00109 
00110      If the memory read fails, return -1 to fallback on another
00111      mechanism for retrieving the AUXV.
00112 
00113      In most cases of a PIE running under valgrind there is no way to
00114      find out the base addresses of any of ld.so, executable or AUXV
00115      as everything is randomized and /proc information is not relevant
00116      for the virtual executable running under valgrind.  We think that
00117      we might need a valgrind extension to make it work.  This is PR
00118      11440.  */
00119 
00120   if (target_read_memory (pointer_address, ptr_buf, ptr_size) != 0)
00121     return -1;
00122 
00123   data_address = extract_typed_address (ptr_buf, ptr_type);
00124 
00125   /* Possibly still not initialized such as during an inferior
00126      startup.  */
00127   if (data_address == 0)
00128     return -1;
00129 
00130   data_address += offset;
00131 
00132   if (writebuf != NULL)
00133     {
00134       if (target_write_memory (data_address, writebuf, len) == 0)
00135         return len;
00136       else
00137         return -1;
00138     }
00139 
00140   /* Stop if trying to read past the existing AUXV block.  The final
00141      AT_NULL was already returned before.  */
00142 
00143   if (offset >= auxv_pair_size)
00144     {
00145       if (target_read_memory (data_address - auxv_pair_size, ptr_buf,
00146                               ptr_size) != 0)
00147         return -1;
00148 
00149       if (extract_typed_address (ptr_buf, ptr_type) == AT_NULL)
00150         return 0;
00151     }
00152 
00153   retval = 0;
00154   block = 0x400;
00155   gdb_assert (block % auxv_pair_size == 0);
00156 
00157   while (len > 0)
00158     {
00159       if (block > len)
00160         block = len;
00161 
00162       /* Reading sizes smaller than AUXV_PAIR_SIZE is not supported.
00163          Tails unaligned to AUXV_PAIR_SIZE will not be read during a
00164          call (they should be completed during next read with
00165          new/extended buffer).  */
00166 
00167       block &= -auxv_pair_size;
00168       if (block == 0)
00169         return retval;
00170 
00171       if (target_read_memory (data_address, readbuf, block) != 0)
00172         {
00173           if (block <= auxv_pair_size)
00174             return retval;
00175 
00176           block = auxv_pair_size;
00177           continue;
00178         }
00179 
00180       data_address += block;
00181       len -= block;
00182 
00183       /* Check terminal AT_NULL.  This function is being called
00184          indefinitely being extended its READBUF until it returns EOF
00185          (0).  */
00186 
00187       while (block >= auxv_pair_size)
00188         {
00189           retval += auxv_pair_size;
00190 
00191           if (extract_typed_address (readbuf, ptr_type) == AT_NULL)
00192             return retval;
00193 
00194           readbuf += auxv_pair_size;
00195           block -= auxv_pair_size;
00196         }
00197     }
00198 
00199   return retval;
00200 }
00201 
00202 /* This function is called like a to_xfer_partial hook, but must be
00203    called with TARGET_OBJECT_AUXV.  It handles access to AUXV.  */
00204 
00205 LONGEST
00206 memory_xfer_auxv (struct target_ops *ops,
00207                   enum target_object object,
00208                   const char *annex,
00209                   gdb_byte *readbuf,
00210                   const gdb_byte *writebuf,
00211                   ULONGEST offset,
00212                   LONGEST len)
00213 {
00214   gdb_assert (object == TARGET_OBJECT_AUXV);
00215   gdb_assert (readbuf || writebuf);
00216 
00217    /* ld_so_xfer_auxv is the only function safe for virtual
00218       executables being executed by valgrind's memcheck.  Using
00219       ld_so_xfer_auxv during inferior startup is problematic, because
00220       ld.so symbol tables have not yet been relocated.  So GDB uses
00221       this function only when attaching to a process.
00222       */
00223 
00224   if (current_inferior ()->attach_flag != 0)
00225     {
00226       LONGEST retval;
00227 
00228       retval = ld_so_xfer_auxv (readbuf, writebuf, offset, len);
00229       if (retval != -1)
00230         return retval;
00231     }
00232 
00233   return procfs_xfer_auxv (readbuf, writebuf, offset, len);
00234 }
00235 
00236 /* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
00237    Return 0 if *READPTR is already at the end of the buffer.
00238    Return -1 if there is insufficient buffer for a whole entry.
00239    Return 1 if an entry was read into *TYPEP and *VALP.  */
00240 static int
00241 default_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
00242                    gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
00243 {
00244   const int sizeof_auxv_field = gdbarch_ptr_bit (target_gdbarch ())
00245                                 / TARGET_CHAR_BIT;
00246   const enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
00247   gdb_byte *ptr = *readptr;
00248 
00249   if (endptr == ptr)
00250     return 0;
00251 
00252   if (endptr - ptr < sizeof_auxv_field * 2)
00253     return -1;
00254 
00255   *typep = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
00256   ptr += sizeof_auxv_field;
00257   *valp = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
00258   ptr += sizeof_auxv_field;
00259 
00260   *readptr = ptr;
00261   return 1;
00262 }
00263 
00264 /* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
00265    Return 0 if *READPTR is already at the end of the buffer.
00266    Return -1 if there is insufficient buffer for a whole entry.
00267    Return 1 if an entry was read into *TYPEP and *VALP.  */
00268 int
00269 target_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
00270                   gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
00271 {
00272   struct target_ops *t;
00273 
00274   for (t = ops; t != NULL; t = t->beneath)
00275     if (t->to_auxv_parse != NULL)
00276       return t->to_auxv_parse (t, readptr, endptr, typep, valp);
00277   
00278   return default_auxv_parse (ops, readptr, endptr, typep, valp);
00279 }
00280 
00281 
00282 /* Per-inferior data key for auxv.  */
00283 static const struct inferior_data *auxv_inferior_data;
00284 
00285 /*  Auxiliary Vector information structure.  This is used by GDB
00286     for caching purposes for each inferior.  This helps reduce the
00287     overhead of transfering data from a remote target to the local host.  */
00288 struct auxv_info
00289 {
00290   LONGEST length;
00291   gdb_byte *data;
00292 };
00293 
00294 /* Handles the cleanup of the auxv cache for inferior INF.  ARG is ignored.
00295    Frees whatever allocated space there is to be freed and sets INF's auxv cache
00296    data pointer to NULL.
00297 
00298    This function is called when the following events occur: inferior_appeared,
00299    inferior_exit and executable_changed.  */
00300 
00301 static void
00302 auxv_inferior_data_cleanup (struct inferior *inf, void *arg)
00303 {
00304   struct auxv_info *info;
00305 
00306   info = inferior_data (inf, auxv_inferior_data);
00307   if (info != NULL)
00308     {
00309       xfree (info->data);
00310       xfree (info);
00311       set_inferior_data (inf, auxv_inferior_data, NULL);
00312     }
00313 }
00314 
00315 /* Invalidate INF's auxv cache.  */
00316 
00317 static void
00318 invalidate_auxv_cache_inf (struct inferior *inf)
00319 {
00320   auxv_inferior_data_cleanup (inf, NULL);
00321 }
00322 
00323 /* Invalidate current inferior's auxv cache.  */
00324 
00325 static void
00326 invalidate_auxv_cache (void)
00327 {
00328   invalidate_auxv_cache_inf (current_inferior ());
00329 }
00330 
00331 /* Fetch the auxv object from inferior INF.  If auxv is cached already,
00332    return a pointer to the cache.  If not, fetch the auxv object from the
00333    target and cache it.  This function always returns a valid INFO pointer.  */
00334 
00335 static struct auxv_info *
00336 get_auxv_inferior_data (struct target_ops *ops)
00337 {
00338   struct auxv_info *info;
00339   struct inferior *inf = current_inferior ();
00340 
00341   info = inferior_data (inf, auxv_inferior_data);
00342   if (info == NULL)
00343     {
00344       info = XZALLOC (struct auxv_info);
00345       info->length = target_read_alloc (ops, TARGET_OBJECT_AUXV,
00346                                         NULL, &info->data);
00347       set_inferior_data (inf, auxv_inferior_data, info);
00348     }
00349 
00350   return info;
00351 }
00352 
00353 /* Extract the auxiliary vector entry with a_type matching MATCH.
00354    Return zero if no such entry was found, or -1 if there was
00355    an error getting the information.  On success, return 1 after
00356    storing the entry's value field in *VALP.  */
00357 int
00358 target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp)
00359 {
00360   CORE_ADDR type, val;
00361   gdb_byte *data;
00362   gdb_byte *ptr;
00363   struct auxv_info *info;
00364 
00365   info = get_auxv_inferior_data (ops);
00366 
00367   data = info->data;
00368   ptr = data;
00369 
00370   if (info->length <= 0)
00371     return info->length;
00372 
00373   while (1)
00374     switch (target_auxv_parse (ops, &ptr, data + info->length, &type, &val))
00375       {
00376       case 1:                   /* Here's an entry, check it.  */
00377         if (type == match)
00378           {
00379             *valp = val;
00380             return 1;
00381           }
00382         break;
00383       case 0:                   /* End of the vector.  */
00384         return 0;
00385       default:                  /* Bogosity.  */
00386         return -1;
00387       }
00388 
00389   /*NOTREACHED*/
00390 }
00391 
00392 
00393 /* Print the contents of the target's AUXV on the specified file.  */
00394 int
00395 fprint_target_auxv (struct ui_file *file, struct target_ops *ops)
00396 {
00397   CORE_ADDR type, val;
00398   gdb_byte *data;
00399   gdb_byte *ptr;
00400   struct auxv_info *info;
00401   int ents = 0;
00402 
00403   info = get_auxv_inferior_data (ops);
00404 
00405   data = info->data;
00406   ptr = data;
00407   if (info->length <= 0)
00408     return info->length;
00409 
00410   while (target_auxv_parse (ops, &ptr, data + info->length, &type, &val) > 0)
00411     {
00412       const char *name = "???";
00413       const char *description = "";
00414       enum { dec, hex, str } flavor = hex;
00415 
00416       switch (type)
00417         {
00418 #define TAG(tag, text, kind) \
00419         case tag: name = #tag; description = text; flavor = kind; break
00420           TAG (AT_NULL, _("End of vector"), hex);
00421           TAG (AT_IGNORE, _("Entry should be ignored"), hex);
00422           TAG (AT_EXECFD, _("File descriptor of program"), dec);
00423           TAG (AT_PHDR, _("Program headers for program"), hex);
00424           TAG (AT_PHENT, _("Size of program header entry"), dec);
00425           TAG (AT_PHNUM, _("Number of program headers"), dec);
00426           TAG (AT_PAGESZ, _("System page size"), dec);
00427           TAG (AT_BASE, _("Base address of interpreter"), hex);
00428           TAG (AT_FLAGS, _("Flags"), hex);
00429           TAG (AT_ENTRY, _("Entry point of program"), hex);
00430           TAG (AT_NOTELF, _("Program is not ELF"), dec);
00431           TAG (AT_UID, _("Real user ID"), dec);
00432           TAG (AT_EUID, _("Effective user ID"), dec);
00433           TAG (AT_GID, _("Real group ID"), dec);
00434           TAG (AT_EGID, _("Effective group ID"), dec);
00435           TAG (AT_CLKTCK, _("Frequency of times()"), dec);
00436           TAG (AT_PLATFORM, _("String identifying platform"), str);
00437           TAG (AT_HWCAP, _("Machine-dependent CPU capability hints"), hex);
00438           TAG (AT_FPUCW, _("Used FPU control word"), dec);
00439           TAG (AT_DCACHEBSIZE, _("Data cache block size"), dec);
00440           TAG (AT_ICACHEBSIZE, _("Instruction cache block size"), dec);
00441           TAG (AT_UCACHEBSIZE, _("Unified cache block size"), dec);
00442           TAG (AT_IGNOREPPC, _("Entry should be ignored"), dec);
00443           TAG (AT_BASE_PLATFORM, _("String identifying base platform"), str);
00444           TAG (AT_RANDOM, _("Address of 16 random bytes"), hex);
00445           TAG (AT_EXECFN, _("File name of executable"), str);
00446           TAG (AT_SECURE, _("Boolean, was exec setuid-like?"), dec);
00447           TAG (AT_SYSINFO, _("Special system info/entry points"), hex);
00448           TAG (AT_SYSINFO_EHDR, _("System-supplied DSO's ELF header"), hex);
00449           TAG (AT_L1I_CACHESHAPE, _("L1 Instruction cache information"), hex);
00450           TAG (AT_L1D_CACHESHAPE, _("L1 Data cache information"), hex);
00451           TAG (AT_L2_CACHESHAPE, _("L2 cache information"), hex);
00452           TAG (AT_L3_CACHESHAPE, _("L3 cache information"), hex);
00453           TAG (AT_SUN_UID, _("Effective user ID"), dec);
00454           TAG (AT_SUN_RUID, _("Real user ID"), dec);
00455           TAG (AT_SUN_GID, _("Effective group ID"), dec);
00456           TAG (AT_SUN_RGID, _("Real group ID"), dec);
00457           TAG (AT_SUN_LDELF, _("Dynamic linker's ELF header"), hex);
00458           TAG (AT_SUN_LDSHDR, _("Dynamic linker's section headers"), hex);
00459           TAG (AT_SUN_LDNAME, _("String giving name of dynamic linker"), str);
00460           TAG (AT_SUN_LPAGESZ, _("Large pagesize"), dec);
00461           TAG (AT_SUN_PLATFORM, _("Platform name string"), str);
00462           TAG (AT_SUN_HWCAP, _("Machine-dependent CPU capability hints"), hex);
00463           TAG (AT_SUN_IFLUSH, _("Should flush icache?"), dec);
00464           TAG (AT_SUN_CPU, _("CPU name string"), str);
00465           TAG (AT_SUN_EMUL_ENTRY, _("COFF entry point address"), hex);
00466           TAG (AT_SUN_EMUL_EXECFD, _("COFF executable file descriptor"), dec);
00467           TAG (AT_SUN_EXECNAME,
00468                _("Canonicalized file name given to execve"), str);
00469           TAG (AT_SUN_MMU, _("String for name of MMU module"), str);
00470           TAG (AT_SUN_LDDATA, _("Dynamic linker's data segment address"), hex);
00471           TAG (AT_SUN_AUXFLAGS,
00472                _("AF_SUN_ flags passed from the kernel"), hex);
00473         }
00474 
00475       fprintf_filtered (file, "%-4s %-20s %-30s ",
00476                         plongest (type), name, description);
00477       switch (flavor)
00478         {
00479         case dec:
00480           fprintf_filtered (file, "%s\n", plongest (val));
00481           break;
00482         case hex:
00483           fprintf_filtered (file, "%s\n", paddress (target_gdbarch (), val));
00484           break;
00485         case str:
00486           {
00487             struct value_print_options opts;
00488 
00489             get_user_print_options (&opts);
00490             if (opts.addressprint)
00491               fprintf_filtered (file, "%s ", paddress (target_gdbarch (), val));
00492             val_print_string (builtin_type (target_gdbarch ())->builtin_char,
00493                               NULL, val, -1, file, &opts);
00494             fprintf_filtered (file, "\n");
00495           }
00496           break;
00497         }
00498       ++ents;
00499       if (type == AT_NULL)
00500         break;
00501     }
00502 
00503   return ents;
00504 }
00505 
00506 static void
00507 info_auxv_command (char *cmd, int from_tty)
00508 {
00509   if (! target_has_stack)
00510     error (_("The program has no auxiliary information now."));
00511   else
00512     {
00513       int ents = fprint_target_auxv (gdb_stdout, &current_target);
00514 
00515       if (ents < 0)
00516         error (_("No auxiliary vector found, or failed reading it."));
00517       else if (ents == 0)
00518         error (_("Auxiliary vector is empty."));
00519     }
00520 }
00521 
00522 
00523 extern initialize_file_ftype _initialize_auxv; /* -Wmissing-prototypes; */
00524 
00525 void
00526 _initialize_auxv (void)
00527 {
00528   add_info ("auxv", info_auxv_command,
00529             _("Display the inferior's auxiliary vector.\n\
00530 This is information provided by the operating system at program startup."));
00531 
00532   /* Set an auxv cache per-inferior.  */
00533   auxv_inferior_data
00534     = register_inferior_data_with_cleanup (NULL, auxv_inferior_data_cleanup);
00535 
00536   /* Observers used to invalidate the auxv cache when needed.  */
00537   observer_attach_inferior_exit (invalidate_auxv_cache_inf);
00538   observer_attach_inferior_appeared (invalidate_auxv_cache_inf);
00539   observer_attach_executable_changed (invalidate_auxv_cache);
00540 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines