gdb/
[deliverable/binutils-gdb.git] / gdb / elfread.c
index f9052c1204d66b7d24fc5ed5036328701f166ebc..c59134bf8886b25a8c340ca90bf258f5c401c446 100644 (file)
@@ -1,7 +1,7 @@
 /* Read ELF (Executable and Linking Format) object files for GDB.
 
    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
    Written by Fred Fish at Cygnus Support.
 #include "gdb-stabs.h"
 #include "complaints.h"
 #include "demangle.h"
+#include "psympriv.h"
 
 extern void _initialize_elfread (void);
 
+/* Forward declaration.  */
+static const struct sym_fns elf_sym_fns_gdb_index;
+
 /* The struct elfinfo is available only during ELF symbol table and
    psymtab reading.  It is destroyed at the completion of psymtab-reading.
    It's local to elf_symfile_read.  */
@@ -148,7 +152,7 @@ elf_symfile_segments (bfd *abfd)
 
    FIXME: The section names should not be hardwired strings (what
    should they be?  I don't think most object file formats have enough
-   section flags to specify what kind of debug section it is
+   section flags to specify what kind of debug section it is.
    -kingdon).  */
 
 static void
@@ -222,7 +226,6 @@ elf_symtab_read (struct objfile *objfile, int type,
                 int copy_names)
 {
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
-  long storage_needed;
   asymbol *sym;
   long i;
   CORE_ADDR symaddr;
@@ -246,7 +249,7 @@ elf_symtab_read (struct objfile *objfile, int type,
       if (sym->name == NULL || *sym->name == '\0')
        {
          /* Skip names that don't exist (shouldn't happen), or names
-            that are null strings (may happen). */
+            that are null strings (may happen).  */
          continue;
        }
 
@@ -275,7 +278,7 @@ elf_symtab_read (struct objfile *objfile, int type,
             of the corresponding entry in the procedure linkage table,
             plus the desired section offset.
             If its value is zero then the dynamic linker has to resolve
-            the symbol. We are unable to find any meaningful address
+            the symbol.  We are unable to find any meaningful address
             for this symbol in the executable file, so we skip it.  */
          symaddr = sym->value;
          if (symaddr == 0)
@@ -336,8 +339,8 @@ elf_symtab_read (struct objfile *objfile, int type,
 
          /* Select global/local/weak symbols.  Note that bfd puts abs
             symbols in their own section, so all symbols we are
-            interested in will have a section. */
-         /* Bfd symbols are section relative. */
+            interested in will have a section.  */
+         /* Bfd symbols are section relative.  */
          symaddr = sym->value + sym->section->vma;
          /* Relocate all non-absolute and non-TLS symbols by the
             section offset.  */
@@ -348,7 +351,7 @@ elf_symtab_read (struct objfile *objfile, int type,
            }
          /* For non-absolute symbols, use the type of the section
             they are relative to, to intuit text/data.  Bfd provides
-            no way of figuring this out for absolute symbols. */
+            no way of figuring this out for absolute symbols.  */
          if (sym->section == &bfd_abs_section)
            {
              /* This is a hack to get the minimal symbol type
@@ -376,7 +379,7 @@ elf_symtab_read (struct objfile *objfile, int type,
                }
 
              /* If it is an Irix dynamic symbol, skip section name
-                symbols, relocate all others by section offset. */
+                symbols, relocate all others by section offset.  */
              if (ms_type != mst_abs)
                {
                  if (sym->name[0] == '.')
@@ -425,6 +428,7 @@ elf_symtab_read (struct objfile *objfile, int type,
                  /* Named Local variable in a Data section.
                     Check its name for stabs-in-elf.  */
                  int special_local_sect;
+
                  if (strcmp ("Bbss.bss", sym->name) == 0)
                    special_local_sect = SECT_OFF_BSS (objfile);
                  else if (strcmp ("Ddata.data", sym->name) == 0)
@@ -465,7 +469,8 @@ elf_symtab_read (struct objfile *objfile, int type,
                          if (filesym == NULL)
                            {
                              complaint (&symfile_complaints,
-                                        _("elf/stab section information %s without a preceding file symbol"),
+                                        _("elf/stab section information %s "
+                                          "without a preceding file symbol"),
                                         sym->name);
                            }
                          else
@@ -476,7 +481,8 @@ elf_symtab_read (struct objfile *objfile, int type,
                        }
                      if (sectinfo->sections[special_local_sect] != 0)
                        complaint (&symfile_complaints,
-                                  _("duplicated elf/stab section information for %s"),
+                                  _("duplicated elf/stab section "
+                                    "information for %s"),
                                   sectinfo->filename);
                      /* BFD symbols are section relative.  */
                      symaddr = sym->value + sym->section->vma;
@@ -512,7 +518,7 @@ elf_symtab_read (struct objfile *objfile, int type,
                 hob with actions like finding what function the PC
                 is in.  Ignore them if they aren't text, data, or bss.  */
              /* ms_type = mst_unknown; */
-             continue; /* Skip this symbol. */
+             continue; /* Skip this symbol.  */
            }
          msym = record_minimal_symbol
            (sym->name, strlen (sym->name), copy_names, symaddr,
@@ -568,6 +574,148 @@ elf_symtab_read (struct objfile *objfile, int type,
     }
 }
 
+struct build_id
+  {
+    size_t size;
+    gdb_byte data[1];
+  };
+
+/* Locate NT_GNU_BUILD_ID from ABFD and return its content.  */
+
+static struct build_id *
+build_id_bfd_get (bfd *abfd)
+{
+  struct build_id *retval;
+
+  if (!bfd_check_format (abfd, bfd_object)
+      || bfd_get_flavour (abfd) != bfd_target_elf_flavour
+      || elf_tdata (abfd)->build_id == NULL)
+    return NULL;
+
+  retval = xmalloc (sizeof *retval - 1 + elf_tdata (abfd)->build_id_size);
+  retval->size = elf_tdata (abfd)->build_id_size;
+  memcpy (retval->data, elf_tdata (abfd)->build_id, retval->size);
+
+  return retval;
+}
+
+/* Return if FILENAME has NT_GNU_BUILD_ID matching the CHECK value.  */
+
+static int
+build_id_verify (const char *filename, struct build_id *check)
+{
+  bfd *abfd;
+  struct build_id *found = NULL;
+  int retval = 0;
+
+  /* We expect to be silent on the non-existing files.  */
+  abfd = bfd_open_maybe_remote (filename);
+  if (abfd == NULL)
+    return 0;
+
+  found = build_id_bfd_get (abfd);
+
+  if (found == NULL)
+    warning (_("File \"%s\" has no build-id, file skipped"), filename);
+  else if (found->size != check->size
+           || memcmp (found->data, check->data, found->size) != 0)
+    warning (_("File \"%s\" has a different build-id, file skipped"),
+            filename);
+  else
+    retval = 1;
+
+  gdb_bfd_close_or_warn (abfd);
+
+  xfree (found);
+
+  return retval;
+}
+
+static char *
+build_id_to_debug_filename (struct build_id *build_id)
+{
+  char *link, *debugdir, *retval = NULL;
+
+  /* DEBUG_FILE_DIRECTORY/.build-id/ab/cdef */
+  link = alloca (strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1
+                + 2 * build_id->size + (sizeof ".debug" - 1) + 1);
+
+  /* Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
+     cause "/.build-id/..." lookups.  */
+
+  debugdir = debug_file_directory;
+  do
+    {
+      char *s, *debugdir_end;
+      gdb_byte *data = build_id->data;
+      size_t size = build_id->size;
+
+      while (*debugdir == DIRNAME_SEPARATOR)
+       debugdir++;
+
+      debugdir_end = strchr (debugdir, DIRNAME_SEPARATOR);
+      if (debugdir_end == NULL)
+       debugdir_end = &debugdir[strlen (debugdir)];
+
+      memcpy (link, debugdir, debugdir_end - debugdir);
+      s = &link[debugdir_end - debugdir];
+      s += sprintf (s, "/.build-id/");
+      if (size > 0)
+       {
+         size--;
+         s += sprintf (s, "%02x", (unsigned) *data++);
+       }
+      if (size > 0)
+       *s++ = '/';
+      while (size-- > 0)
+       s += sprintf (s, "%02x", (unsigned) *data++);
+      strcpy (s, ".debug");
+
+      /* lrealpath() is expensive even for the usually non-existent files.  */
+      if (access (link, F_OK) == 0)
+       retval = lrealpath (link);
+
+      if (retval != NULL && !build_id_verify (retval, build_id))
+       {
+         xfree (retval);
+         retval = NULL;
+       }
+
+      if (retval != NULL)
+       break;
+
+      debugdir = debugdir_end;
+    }
+  while (*debugdir != 0);
+
+  return retval;
+}
+
+static char *
+find_separate_debug_file_by_buildid (struct objfile *objfile)
+{
+  struct build_id *build_id;
+
+  build_id = build_id_bfd_get (objfile->obfd);
+  if (build_id != NULL)
+    {
+      char *build_id_name;
+
+      build_id_name = build_id_to_debug_filename (build_id);
+      xfree (build_id);
+      /* Prevent looping on a stripped .debug file.  */
+      if (build_id_name != NULL && strcmp (build_id_name, objfile->name) == 0)
+        {
+         warning (_("\"%s\": separate debug info file has no debug info"),
+                  build_id_name);
+         xfree (build_id_name);
+       }
+      else if (build_id_name != NULL)
+        return build_id_name;
+    }
+  return NULL;
+}
+
 /* Scan and build partial symbols for a symbol file.
    We have been initialized by a call to elf_symfile_init, which 
    currently does nothing.
@@ -576,9 +724,6 @@ elf_symtab_read (struct objfile *objfile, int type,
    in each section.  We simplify it down to a single offset for all
    symbols.  FIXME.
 
-   MAINLINE is true if we are reading the main symbol
-   table (as opposed to a shared lib or dynamically loaded file).
-
    This function only does the minimum work necessary for letting the
    user "name" things symbolically; it does not read the entire symtab.
    Instead, it reads the external and static symbols and puts them in partial
@@ -600,12 +745,11 @@ elf_symtab_read (struct objfile *objfile, int type,
    capability even for files compiled without -g.  */
 
 static void
-elf_symfile_read (struct objfile *objfile, int mainline)
+elf_symfile_read (struct objfile *objfile, int symfile_flags)
 {
   bfd *abfd = objfile->obfd;
   struct elfinfo ei;
   struct cleanup *back_to;
-  CORE_ADDR offset;
   long symcount = 0, dynsymcount = 0, synthcount, storage_needed;
   asymbol **symbol_table = NULL, **dyn_symbol_table = NULL;
   asymbol *synthsyms;
@@ -615,19 +759,22 @@ elf_symfile_read (struct objfile *objfile, int mainline)
 
   memset ((char *) &ei, 0, sizeof (ei));
 
-  /* Allocate struct to keep track of the symfile */
+  /* Allocate struct to keep track of the symfile */
   objfile->deprecated_sym_stab_info = (struct dbx_symfile_info *)
     xmalloc (sizeof (struct dbx_symfile_info));
-  memset ((char *) objfile->deprecated_sym_stab_info, 0, sizeof (struct dbx_symfile_info));
+  memset ((char *) objfile->deprecated_sym_stab_info,
+         0, sizeof (struct dbx_symfile_info));
   make_cleanup (free_elfinfo, (void *) objfile);
 
-  /* Process the normal ELF symbol table first.  This may write some 
-     chain of info into the dbx_symfile_info in objfile->deprecated_sym_stab_info,
-     which can later be used by elfstab_offset_sections.  */
+  /* Process the normal ELF symbol table first.  This may write some
+     chain of info into the dbx_symfile_info in
+     objfile->deprecated_sym_stab_info, which can later be used by
+     elfstab_offset_sections.  */
 
   storage_needed = bfd_get_symtab_upper_bound (objfile->obfd);
   if (storage_needed < 0)
-    error (_("Can't read symbols from %s: %s"), bfd_get_filename (objfile->obfd),
+    error (_("Can't read symbols from %s: %s"),
+          bfd_get_filename (objfile->obfd),
           bfd_errmsg (bfd_get_error ()));
 
   if (storage_needed > 0)
@@ -637,7 +784,8 @@ elf_symfile_read (struct objfile *objfile, int mainline)
       symcount = bfd_canonicalize_symtab (objfile->obfd, symbol_table);
 
       if (symcount < 0)
-       error (_("Can't read symbols from %s: %s"), bfd_get_filename (objfile->obfd),
+       error (_("Can't read symbols from %s: %s"),
+              bfd_get_filename (objfile->obfd),
               bfd_errmsg (bfd_get_error ()));
 
       elf_symtab_read (objfile, ST_REGULAR, symcount, symbol_table, 0);
@@ -649,13 +797,20 @@ elf_symfile_read (struct objfile *objfile, int mainline)
 
   if (storage_needed > 0)
     {
-      dyn_symbol_table = (asymbol **) xmalloc (storage_needed);
-      make_cleanup (xfree, dyn_symbol_table);
+      /* Memory gets permanently referenced from ABFD after
+        bfd_get_synthetic_symtab so it must not get freed before ABFD gets.
+        It happens only in the case when elf_slurp_reloc_table sees
+        asection->relocation NULL.  Determining which section is asection is
+        done by _bfd_elf_get_synthetic_symtab which is all a bfd
+        implementation detail, though.  */
+
+      dyn_symbol_table = bfd_alloc (abfd, storage_needed);
       dynsymcount = bfd_canonicalize_dynamic_symtab (objfile->obfd,
                                                     dyn_symbol_table);
 
       if (dynsymcount < 0)
-       error (_("Can't read symbols from %s: %s"), bfd_get_filename (objfile->obfd),
+       error (_("Can't read symbols from %s: %s"),
+              bfd_get_filename (objfile->obfd),
               bfd_errmsg (bfd_get_error ()));
 
       elf_symtab_read (objfile, ST_DYNAMIC, dynsymcount, dyn_symbol_table, 0);
@@ -676,7 +831,8 @@ elf_symfile_read (struct objfile *objfile, int mainline)
       for (i = 0; i < synthcount; i++)
        synth_symbol_table[i] = synthsyms + i;
       make_cleanup (xfree, synth_symbol_table);
-      elf_symtab_read (objfile, ST_SYNTHETIC, synthcount, synth_symbol_table, 1);
+      elf_symtab_read (objfile, ST_SYNTHETIC, synthcount,
+                      synth_symbol_table, 1);
     }
 
   /* Install any minimal symbols that have been collected as the current
@@ -689,9 +845,9 @@ elf_symfile_read (struct objfile *objfile, int mainline)
   do_cleanups (back_to);
 
   /* Now process debugging information, which is contained in
-     special ELF sections. */
+     special ELF sections.  */
 
-  /* We first have to find them... */
+  /* We first have to find them...  */
   bfd_map_over_sections (abfd, elf_locate_sections, (void *) & ei);
 
   /* ELF debugging information is inserted into the psymtab in the
@@ -704,7 +860,7 @@ elf_symfile_read (struct objfile *objfile, int mainline)
      and .debug_info (DWARF2) sections then .mdebug is inserted first
      (searched last) and DWARF2 is inserted last (searched first).  If
      we don't do this then the XCOFF info is found first - for code in
-     an included file XCOFF info is useless. */
+     an included file XCOFF info is useless.  */
 
   if (ei.mdebugsect)
     {
@@ -731,15 +887,31 @@ elf_symfile_read (struct objfile *objfile, int mainline)
                                str_sect->filepos,
                                bfd_section_size (abfd, str_sect));
     }
-  if (dwarf2_has_info (objfile))
+
+  if (dwarf2_has_info (objfile) && dwarf2_initialize_objfile (objfile))
+    objfile->sf = &elf_sym_fns_gdb_index;
+
+  /* If the file has its own symbol tables it has no separate debug
+     info.  `.dynsym'/`.symtab' go to MSYMBOLS, `.debug_info' goes to
+     SYMTABS/PSYMTABS.  `.gnu_debuglink' may no longer be present with
+     `.note.gnu.build-id'.  */
+  if (!objfile_has_partial_symbols (objfile))
     {
-      /* DWARF 2 sections */
-      dwarf2_build_psymtabs (objfile);
-    }
+      char *debugfile;
+
+      debugfile = find_separate_debug_file_by_buildid (objfile);
+
+      if (debugfile == NULL)
+       debugfile = find_separate_debug_file_by_debuglink (objfile);
 
-  /* FIXME: kettenis/20030504: This still needs to be integrated with
-     dwarf2read.c in a better way.  */
-  dwarf2_build_frame_info (objfile);
+      if (debugfile)
+       {
+         bfd *abfd = symfile_bfd_open (debugfile);
+
+         symbol_file_add_separate (abfd, symfile_flags, objfile);
+         xfree (debugfile);
+       }
+    }
 }
 
 /* This cleans up the objfile's deprecated_sym_stab_info pointer, and
@@ -769,7 +941,8 @@ free_elfinfo (void *objp)
    file is specified (not just adding some symbols from another file, e.g. a
    shared library).
 
-   We reinitialize buildsym, since we may be reading stabs from an ELF file.  */
+   We reinitialize buildsym, since we may be reading stabs from an ELF
+   file.  */
 
 static void
 elf_new_init (struct objfile *ignore)
@@ -781,7 +954,7 @@ elf_new_init (struct objfile *ignore)
 /* Perform any local cleanups required when we are done with a particular
    objfile.  I.E, we are in the process of discarding all symbol information
    for an objfile, freeing up all memory held for it, and unlinking the
-   objfile struct from the global list of known objfiles. */
+   objfile struct from the global list of known objfiles.  */
 
 static void
 elf_symfile_finish (struct objfile *objfile)
@@ -801,7 +974,7 @@ elf_symfile_finish (struct objfile *objfile)
    a pointer to "private data" which we can fill with goodies.
 
    For now at least, we have nothing in particular to do, so this function is
-   just a stub. */
+   just a stub.  */
 
 static void
 elf_symfile_init (struct objfile *objfile)
@@ -823,7 +996,7 @@ elf_symfile_init (struct objfile *objfile)
 void
 elfstab_offset_sections (struct objfile *objfile, struct partial_symtab *pst)
 {
-  char *filename = pst->filename;
+  const char *filename = pst->filename;
   struct dbx_symfile_info *dbx = objfile->deprecated_sym_stab_info;
   struct stab_section_info *maybe = dbx->stab_section_info;
   struct stab_section_info *questionable = 0;
@@ -837,7 +1010,7 @@ elfstab_offset_sections (struct objfile *objfile, struct partial_symtab *pst)
 
   /* FIXME:  This linear search could speed up significantly
      if it was chained in the right order to match how we search it,
-     and if we unchained when we found a match. */
+     and if we unchained when we found a match.  */
   for (; maybe; maybe = maybe->next)
     {
       if (filename[0] == maybe->filename[0]
@@ -854,7 +1027,8 @@ elfstab_offset_sections (struct objfile *objfile, struct partial_symtab *pst)
   if (maybe == 0 && questionable != 0)
     {
       complaint (&symfile_complaints,
-                _("elf/stab section information questionable for %s"), filename);
+                _("elf/stab section information questionable for %s"),
+                filename);
       maybe = questionable;
     }
 
@@ -878,18 +1052,34 @@ elfstab_offset_sections (struct objfile *objfile, struct partial_symtab *pst)
 \f
 /* Register that we are able to handle ELF object file formats.  */
 
-static struct sym_fns elf_sym_fns =
+static const struct sym_fns elf_sym_fns =
+{
+  bfd_target_elf_flavour,
+  elf_new_init,                        /* init anything gbl to entire symtab */
+  elf_symfile_init,            /* read initial info, setup for sym_read() */
+  elf_symfile_read,            /* read a symbol file into symtab */
+  elf_symfile_finish,          /* finished with file, cleanup */
+  default_symfile_offsets,     /* Translate ext. to int. relocation */
+  elf_symfile_segments,                /* Get segment information from a file.  */
+  NULL,
+  default_symfile_relocate,    /* Relocate a debug section.  */
+  &psym_functions
+};
+
+/* The same as elf_sym_fns, but not registered and uses the
+   DWARF-specific GNU index rather than psymtab.  */
+static const struct sym_fns elf_sym_fns_gdb_index =
 {
   bfd_target_elf_flavour,
-  elf_new_init,                        /* sym_new_init: init anything gbl to entire symtab */
-  elf_symfile_init,            /* sym_init: read initial info, setup for sym_read() */
-  elf_symfile_read,            /* sym_read: read a symbol file into symtab */
-  elf_symfile_finish,          /* sym_finish: finished with file, cleanup */
-  default_symfile_offsets,     /* sym_offsets:  Translate ext. to int. relocation */
-  elf_symfile_segments,                /* sym_segments: Get segment information from
-                                  a file.  */
-  NULL,                         /* sym_read_linetable */
-  NULL                         /* next: pointer to next struct sym_fns */
+  elf_new_init,                        /* init anything gbl to entire symab */
+  elf_symfile_init,            /* read initial info, setup for sym_red() */
+  elf_symfile_read,            /* read a symbol file into symtab */
+  elf_symfile_finish,          /* finished with file, cleanup */
+  default_symfile_offsets,     /* Translate ext. to int. relocatin */
+  elf_symfile_segments,                /* Get segment information from a file.  */
+  NULL,
+  default_symfile_relocate,    /* Relocate a debug section.  */
+  &dwarf2_gdb_index_functions
 };
 
 void
This page took 0.032979 seconds and 4 git commands to generate.