Replace some xmalloc-family functions with XNEW-family ones
[deliverable/binutils-gdb.git] / gdb / elfread.c
index 84efc594dcfc1ec525bce0cce7350f2cd67ec3e1..fa900a09b76c7a2db2a154df743b8831de6a0048 100644 (file)
@@ -1,6 +1,6 @@
 /* Read ELF (Executable and Linking Format) object files for GDB.
 
-   Copyright (C) 1991-2012 Free Software Foundation, Inc.
+   Copyright (C) 1991-2015 Free Software Foundation, Inc.
 
    Written by Fred Fish at Cygnus Support.
 
@@ -21,7 +21,6 @@
 
 #include "defs.h"
 #include "bfd.h"
-#include "gdb_string.h"
 #include "elf-bfd.h"
 #include "elf/common.h"
 #include "elf/internal.h"
 #include "regcache.h"
 #include "bcache.h"
 #include "gdb_bfd.h"
+#include "build-id.h"
+#include "location.h"
 
 extern void _initialize_elfread (void);
 
 /* Forward declarations.  */
-static const struct sym_fns elf_sym_fns_gdb_index;
-static const struct sym_fns elf_sym_fns_lazy_psyms;
+extern const struct sym_fns elf_sym_fns_gdb_index;
+extern const struct sym_fns elf_sym_fns_lazy_psyms;
 
 /* The struct elfinfo is available only during ELF symbol table and
    psymtab reading.  It is destroyed at the completion of psymtab-reading.
@@ -59,15 +60,12 @@ static const struct sym_fns elf_sym_fns_lazy_psyms;
 struct elfinfo
   {
     asection *stabsect;                /* Section pointer for .stab section */
-    asection *stabindexsect;   /* Section pointer for .stab.index section */
     asection *mdebugsect;      /* Section pointer for .mdebug section */
   };
 
-/* Per-objfile data for probe info.  */
+/* Per-BFD data for probe info.  */
 
-static const struct objfile_data *probe_key = NULL;
-
-static void free_elfinfo (void *);
+static const struct bfd_data *probe_key = NULL;
 
 /* Minimal symbols located at the GOT entries for .plt - that is the real
    pointer where the given entry will jump to.  It gets updated by the real
@@ -97,7 +95,7 @@ elf_symfile_segments (bfd *abfd)
     return NULL;
 
   num_segments = 0;
-  segments = alloca (sizeof (Elf_Internal_Phdr *) * num_phdrs);
+  segments = XALLOCAVEC (Elf_Internal_Phdr *, num_phdrs);
   for (i = 0; i < num_phdrs; i++)
     if (phdrs[i].p_type == PT_LOAD)
       segments[num_segments++] = &phdrs[i];
@@ -105,10 +103,10 @@ elf_symfile_segments (bfd *abfd)
   if (num_segments == 0)
     return NULL;
 
-  data = XZALLOC (struct symfile_segment_data);
+  data = XCNEW (struct symfile_segment_data);
   data->num_segments = num_segments;
-  data->segment_bases = XCALLOC (num_segments, CORE_ADDR);
-  data->segment_sizes = XCALLOC (num_segments, CORE_ADDR);
+  data->segment_bases = XCNEWVEC (CORE_ADDR, num_segments);
+  data->segment_sizes = XCNEWVEC (CORE_ADDR, num_segments);
 
   for (i = 0; i < num_segments; i++)
     {
@@ -117,7 +115,7 @@ elf_symfile_segments (bfd *abfd)
     }
 
   num_sections = bfd_count_sections (abfd);
-  data->segment_info = XCALLOC (num_sections, int);
+  data->segment_info = XCNEWVEC (int, num_sections);
 
   for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next)
     {
@@ -185,10 +183,6 @@ elf_locate_sections (bfd *ignore_abfd, asection *sectp, void *eip)
     {
       ei->stabsect = sectp;
     }
-  else if (strcmp (sectp->name, ".stab.index") == 0)
-    {
-      ei->stabindexsect = sectp;
-    }
   else if (strcmp (sectp->name, ".mdebug") == 0)
     {
       ei->mdebugsect = sectp;
@@ -208,8 +202,10 @@ record_minimal_symbol (const char *name, int name_len, int copy_name,
     address = gdbarch_addr_bits_remove (gdbarch, address);
 
   return prim_record_minimal_symbol_full (name, name_len, copy_name, address,
-                                         ms_type, bfd_section->index,
-                                         bfd_section, objfile);
+                                         ms_type,
+                                         gdb_bfd_section_index (objfile->obfd,
+                                                                bfd_section),
+                                         objfile);
 }
 
 /* Read the symbol table of an ELF file.
@@ -239,17 +235,13 @@ elf_symtab_read (struct objfile *objfile, int type,
   CORE_ADDR symaddr;
   CORE_ADDR offset;
   enum minimal_symbol_type ms_type;
-  /* If sectinfo is nonNULL, it contains section info that should end up
-     filed in the objfile.  */
-  struct stab_section_info *sectinfo = NULL;
-  /* If filesym is nonzero, it points to a file symbol, but we haven't
-     seen any section info for it yet.  */
-  asymbol *filesym = 0;
-  /* Name of filesym.  This is either a constant string or is saved on
-     the objfile's filename cache.  */
+  /* Name of the last file symbol.  This is either a constant string or is
+     saved on the objfile's filename cache.  */
   const char *filesymname = "";
-  struct dbx_symfile_info *dbx = objfile->deprecated_sym_stab_info;
+  struct dbx_symfile_info *dbx = DBX_SYMFILE_INFO (objfile);
   int stripped = (bfd_get_symcount (objfile->obfd) == 0);
+  int elf_make_msymbol_special_p
+    = gdbarch_elf_make_msymbol_special_p (gdbarch);
 
   for (i = 0; i < number_of_symbols; i++)
     {
@@ -271,7 +263,8 @@ elf_symtab_read (struct objfile *objfile, int type,
          continue;
        }
 
-      offset = ANOFFSET (objfile->section_offsets, sym->section->index);
+      offset = ANOFFSET (objfile->section_offsets,
+                        gdb_bfd_section_index (objfile->obfd, sym->section));
       if (type == ST_DYNAMIC
          && sym->section == bfd_und_section_ptr
          && (sym->flags & BSF_FUNCTION))
@@ -322,17 +315,19 @@ elf_symtab_read (struct objfile *objfile, int type,
             for that section is ".plt".  So, if there is a ".plt"
             section, and yet the section name of our symbol does not
             start with ".plt", we ignore that symbol.  */
-         if (strncmp (sect->name, ".plt", 4) != 0
+         if (!startswith (sect->name, ".plt")
              && bfd_get_section_by_name (abfd, ".plt") != NULL)
            continue;
 
-         symaddr += ANOFFSET (objfile->section_offsets, sect->index);
-
          msym = record_minimal_symbol
            (sym->name, strlen (sym->name), copy_names,
             symaddr, mst_solib_trampoline, sect, objfile);
          if (msym != NULL)
-           msym->filename = filesymname;
+           {
+             msym->filename = filesymname;
+             if (elf_make_msymbol_special_p)
+               gdbarch_elf_make_msymbol_special (gdbarch, sym, msym);
+           }
          continue;
        }
 
@@ -343,21 +338,13 @@ elf_symtab_read (struct objfile *objfile, int type,
        continue;
       if (sym->flags & BSF_FILE)
        {
-         /* STT_FILE debugging symbol that helps stabs-in-elf debugging.
-            Chain any old one onto the objfile; remember new sym.  */
-         if (sectinfo != NULL)
-           {
-             sectinfo->next = dbx->stab_section_info;
-             dbx->stab_section_info = sectinfo;
-             sectinfo = NULL;
-           }
-         filesym = sym;
-         filesymname = bcache (filesym->name, strlen (filesym->name) + 1,
+         filesymname = bcache (sym->name, strlen (sym->name) + 1,
                                objfile->per_bfd->filename_cache);
        }
       else if (sym->flags & BSF_SECTION_SYM)
        continue;
-      else if (sym->flags & (BSF_GLOBAL | BSF_LOCAL | BSF_WEAK))
+      else if (sym->flags & (BSF_GLOBAL | BSF_LOCAL | BSF_WEAK
+                            | BSF_GNU_UNIQUE))
        {
          struct minimal_symbol *msym;
 
@@ -366,13 +353,6 @@ elf_symtab_read (struct objfile *objfile, int type,
             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.  */
-         if (sym->section != bfd_abs_section_ptr
-             && !(sym->section->flags & SEC_THREAD_LOCAL))
-           {
-             symaddr += offset;
-           }
          /* 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.  */
@@ -408,12 +388,11 @@ elf_symtab_read (struct objfile *objfile, int type,
                {
                  if (sym->name[0] == '.')
                    continue;
-                 symaddr += offset;
                }
            }
          else if (sym->section->flags & SEC_CODE)
            {
-             if (sym->flags & (BSF_GLOBAL | BSF_WEAK))
+             if (sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE))
                {
                  if (sym->flags & BSF_GNU_INDIRECT_FUNCTION)
                    ms_type = mst_text_gnu_ifunc;
@@ -443,7 +422,7 @@ elf_symtab_read (struct objfile *objfile, int type,
            }
          else if (sym->section->flags & SEC_ALLOC)
            {
-             if (sym->flags & (BSF_GLOBAL | BSF_WEAK))
+             if (sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE))
                {
                  if (sym->section->flags & SEC_LOAD)
                    {
@@ -456,77 +435,6 @@ elf_symtab_read (struct objfile *objfile, int type,
                }
              else if (sym->flags & BSF_LOCAL)
                {
-                 /* 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)
-                   special_local_sect = SECT_OFF_DATA (objfile);
-                 else if (strcmp ("Drodata.rodata", sym->name) == 0)
-                   special_local_sect = SECT_OFF_RODATA (objfile);
-                 else
-                   special_local_sect = -1;
-                 if (special_local_sect >= 0)
-                   {
-                     /* Found a special local symbol.  Allocate a
-                        sectinfo, if needed, and fill it in.  */
-                     if (sectinfo == NULL)
-                       {
-                         int max_index;
-                         size_t size;
-
-                         max_index = SECT_OFF_BSS (objfile);
-                         if (objfile->sect_index_data > max_index)
-                           max_index = objfile->sect_index_data;
-                         if (objfile->sect_index_rodata > max_index)
-                           max_index = objfile->sect_index_rodata;
-
-                         /* max_index is the largest index we'll
-                            use into this array, so we must
-                            allocate max_index+1 elements for it.
-                            However, 'struct stab_section_info'
-                            already includes one element, so we
-                            need to allocate max_index aadditional
-                            elements.  */
-                         size = (sizeof (struct stab_section_info)
-                                 + (sizeof (CORE_ADDR) * max_index));
-                         sectinfo = (struct stab_section_info *)
-                           xmalloc (size);
-                         memset (sectinfo, 0, size);
-                         sectinfo->num_sections = max_index;
-                         if (filesym == NULL)
-                           {
-                             complaint (&symfile_complaints,
-                                        _("elf/stab section information %s "
-                                          "without a preceding file symbol"),
-                                        sym->name);
-                           }
-                         else
-                           {
-                             sectinfo->filename =
-                               (char *) filesym->name;
-                           }
-                       }
-                     if (sectinfo->sections[special_local_sect] != 0)
-                       complaint (&symfile_complaints,
-                                  _("duplicated elf/stab section "
-                                    "information for %s"),
-                                  sectinfo->filename);
-                     /* BFD symbols are section relative.  */
-                     symaddr = sym->value + sym->section->vma;
-                     /* Relocate non-absolute symbols by the
-                        section offset.  */
-                     if (sym->section != bfd_abs_section_ptr)
-                       symaddr += offset;
-                     sectinfo->sections[special_local_sect] = symaddr;
-                     /* The special local symbols don't go in the
-                        minimal symbol table, so ignore this one.  */
-                     continue;
-                   }
-                 /* Not a special stabs-in-elf symbol, do regular
-                    symbol processing.  */
                  if (sym->section->flags & SEC_LOAD)
                    {
                      ms_type = mst_file_data;
@@ -556,24 +464,33 @@ elf_symtab_read (struct objfile *objfile, int type,
 
          if (msym)
            {
-             /* Pass symbol size field in via BFD.  FIXME!!!  */
-             elf_symbol_type *elf_sym;
-
              /* NOTE: uweigand-20071112: A synthetic symbol does not have an
-                ELF-private part.  However, in some cases (e.g. synthetic
-                'dot' symbols on ppc64) the udata.p entry is set to point back
-                to the original ELF symbol it was derived from.  Get the size
-                from that symbol.  */
+                ELF-private part.  */
              if (type != ST_SYNTHETIC)
-               elf_sym = (elf_symbol_type *) sym;
-             else
-               elf_sym = (elf_symbol_type *) sym->udata.p;
-
-             if (elf_sym)
-               SET_MSYMBOL_SIZE (msym, elf_sym->internal_elf_sym.st_size);
+               {
+                 /* Pass symbol size field in via BFD.  FIXME!!!  */
+                 elf_symbol_type *elf_sym = (elf_symbol_type *) sym;
+                 SET_MSYMBOL_SIZE (msym, elf_sym->internal_elf_sym.st_size);
+               }
 
              msym->filename = filesymname;
-             gdbarch_elf_make_msymbol_special (gdbarch, sym, msym);
+             if (elf_make_msymbol_special_p)
+               gdbarch_elf_make_msymbol_special (gdbarch, sym, msym);
+           }
+
+         /* If we see a default versioned symbol, install it under
+            its version-less name.  */
+         if (msym != NULL)
+           {
+             const char *atsign = strchr (sym->name, '@');
+
+             if (atsign != NULL && atsign[1] == '@' && atsign > sym->name)
+               {
+                 int len = atsign - sym->name;
+
+                 record_minimal_symbol (sym->name, len, 1, symaddr,
+                                        ms_type, sym->section, objfile);
+               }
            }
 
          /* For @plt symbols, also record a trampoline to the
@@ -597,7 +514,9 @@ elf_symtab_read (struct objfile *objfile, int type,
                      SET_MSYMBOL_SIZE (mtramp, MSYMBOL_SIZE (msym));
                      mtramp->created_by_gdb = 1;
                      mtramp->filename = filesymname;
-                     gdbarch_elf_make_msymbol_special (gdbarch, sym, mtramp);
+                     if (elf_make_msymbol_special_p)
+                       gdbarch_elf_make_msymbol_special (gdbarch,
+                                                         sym, mtramp);
                    }
                }
            }
@@ -623,7 +542,7 @@ elf_rel_plt_read (struct objfile *objfile, asymbol **dyn_symbol_table)
   char *string_buffer = NULL;
   size_t string_buffer_size = 0;
   struct cleanup *back_to;
-  struct gdbarch *gdbarch = objfile->gdbarch;
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
   size_t ptr_size = TYPE_LENGTH (ptr_type);
 
@@ -637,7 +556,12 @@ elf_rel_plt_read (struct objfile *objfile, asymbol **dyn_symbol_table)
 
   got_plt = bfd_get_section_by_name (obfd, ".got.plt");
   if (got_plt == NULL)
-    return;
+    {
+      /* For platforms where there is no separate .got.plt.  */
+      got_plt = bfd_get_section_by_name (obfd, ".got");
+      if (got_plt == NULL)
+       return;
+    }
 
   /* This search algorithm is from _bfd_elf_canonicalize_dynamic_reloc.  */
   for (relplt = obfd->sections; relplt != NULL; relplt = relplt->next)
@@ -741,7 +665,7 @@ elf_gnu_ifunc_cache_eq (const void *a_voidp, const void *b_voidp)
 static int
 elf_gnu_ifunc_record_cache (const char *name, CORE_ADDR addr)
 {
-  struct minimal_symbol *msym;
+  struct bound_minimal_symbol msym;
   asection *sect;
   struct objfile *objfile;
   htab_t htab;
@@ -749,13 +673,13 @@ elf_gnu_ifunc_record_cache (const char *name, CORE_ADDR addr)
   void **slot;
 
   msym = lookup_minimal_symbol_by_pc (addr);
-  if (msym == NULL)
+  if (msym.minsym == NULL)
     return 0;
-  if (SYMBOL_VALUE_ADDRESS (msym) != addr)
+  if (BMSYMBOL_VALUE_ADDRESS (msym) != addr)
     return 0;
   /* minimal symbols have always SYMBOL_OBJ_SECTION non-NULL.  */
-  sect = SYMBOL_OBJ_SECTION (msym)->the_bfd_section;
-  objfile = SYMBOL_OBJ_SECTION (msym)->objfile;
+  sect = MSYMBOL_OBJ_SECTION (msym.objfile, msym.minsym)->the_bfd_section;
+  objfile = msym.objfile;
 
   /* If .plt jumps back to .plt the symbol is still deferred for later
      resolution and it has no use for GDB.  Besides ".text" this symbol can
@@ -784,7 +708,7 @@ elf_gnu_ifunc_record_cache (const char *name, CORE_ADDR addr)
   if (*slot != NULL)
     {
       struct elf_gnu_ifunc_cache *entry_found_p = *slot;
-      struct gdbarch *gdbarch = objfile->gdbarch;
+      struct gdbarch *gdbarch = get_objfile_arch (objfile);
 
       if (entry_found_p->addr != addr)
        {
@@ -864,32 +788,33 @@ elf_gnu_ifunc_resolve_by_got (const char *name, CORE_ADDR *addr_p)
   ALL_PSPACE_OBJFILES (current_program_space, objfile)
     {
       bfd *obfd = objfile->obfd;
-      struct gdbarch *gdbarch = objfile->gdbarch;
+      struct gdbarch *gdbarch = get_objfile_arch (objfile);
       struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
       size_t ptr_size = TYPE_LENGTH (ptr_type);
       CORE_ADDR pointer_address, addr;
       asection *plt;
       gdb_byte *buf = alloca (ptr_size);
-      struct minimal_symbol *msym;
+      struct bound_minimal_symbol msym;
 
       msym = lookup_minimal_symbol (name_got_plt, NULL, objfile);
-      if (msym == NULL)
+      if (msym.minsym == NULL)
        continue;
-      if (MSYMBOL_TYPE (msym) != mst_slot_got_plt)
+      if (MSYMBOL_TYPE (msym.minsym) != mst_slot_got_plt)
        continue;
-      pointer_address = SYMBOL_VALUE_ADDRESS (msym);
+      pointer_address = BMSYMBOL_VALUE_ADDRESS (msym);
 
       plt = bfd_get_section_by_name (obfd, ".plt");
       if (plt == NULL)
        continue;
 
-      if (MSYMBOL_SIZE (msym) != ptr_size)
+      if (MSYMBOL_SIZE (msym.minsym) != ptr_size)
        continue;
       if (target_read_memory (pointer_address, buf, ptr_size) != 0)
        continue;
       addr = extract_typed_address (buf, ptr_type);
       addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
                                                 &current_target);
+      addr = gdbarch_addr_bits_remove (gdbarch, addr);
 
       if (addr_p)
        *addr_p = addr;
@@ -953,6 +878,7 @@ elf_gnu_ifunc_resolve_addr (struct gdbarch *gdbarch, CORE_ADDR pc)
   address = value_as_address (address_val);
   address = gdbarch_convert_from_func_ptr_addr (gdbarch, address,
                                                &current_target);
+  address = gdbarch_addr_bits_remove (gdbarch, address);
 
   if (name_at_pc)
     elf_gnu_ifunc_record_cache (name_at_pc, address);
@@ -1061,9 +987,11 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
   resolved_pc = gdbarch_convert_from_func_ptr_addr (gdbarch,
                                                    resolved_address,
                                                    &current_target);
+  resolved_pc = gdbarch_addr_bits_remove (gdbarch, resolved_pc);
 
   gdb_assert (current_program_space == b->pspace || b->pspace == NULL);
-  elf_gnu_ifunc_record_cache (b->addr_string, resolved_pc);
+  elf_gnu_ifunc_record_cache (event_location_to_string (b->location),
+                             resolved_pc);
 
   sal = find_pc_line (resolved_pc, 0);
   sals.nelts = 1;
@@ -1074,207 +1002,50 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
   update_breakpoint_locations (b, sals, sals_end);
 }
 
-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 = gdb_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_unref (abfd);
-
-  xfree (found);
-
-  return retval;
-}
-
-static char *
-build_id_to_debug_filename (struct build_id *build_id)
-{
-  char *link, *debugdir, *retval = NULL;
-  VEC (char_ptr) *debugdir_vec;
-  struct cleanup *back_to;
-  int ix;
-
-  /* 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_vec = dirnames_to_char_ptr_vec (debug_file_directory);
-  back_to = make_cleanup_free_char_ptr_vec (debugdir_vec);
-
-  for (ix = 0; VEC_iterate (char_ptr, debugdir_vec, ix, debugdir); ++ix)
-    {
-      size_t debugdir_len = strlen (debugdir);
-      gdb_byte *data = build_id->data;
-      size_t size = build_id->size;
-      char *s;
-
-      memcpy (link, debugdir, debugdir_len);
-      s = &link[debugdir_len];
-      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;
-    }
-
-  do_cleanups (back_to);
-  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
-         && filename_cmp (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.
-
-   SECTION_OFFSETS is a set of offsets to apply to relocate the symbols
-   in each section.  We simplify it down to a single offset for all
-   symbols.  FIXME.
-
-   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
-   symbol tables.  When more extensive information is requested of a
-   file, the corresponding partial symbol table is mutated into a full
-   fledged symbol table by going back and reading the symbols
-   for real.
-
-   We look for sections with specific names, to tell us what debug
-   format to look for:  FIXME!!!
-
-   elfstab_build_psymtabs() handles STABS symbols;
-   mdebug_build_psymtabs() handles ECOFF debugging information.
-
-   Note that ELF files have a "minimal" symbol table, which looks a lot
-   like a COFF symbol table, but has only the minimal information necessary
-   for linking.  We process this also, and use the information to
-   build gdb's minimal symbol table.  This gives us some minimal debugging
-   capability even for files compiled without -g.  */
+/* A helper function for elf_symfile_read that reads the minimal
+   symbols.  */
 
 static void
-elf_symfile_read (struct objfile *objfile, int symfile_flags)
+elf_read_minimal_symbols (struct objfile *objfile, int symfile_flags,
+                         const struct elfinfo *ei)
 {
   bfd *synth_abfd, *abfd = objfile->obfd;
-  struct elfinfo ei;
   struct cleanup *back_to;
   long symcount = 0, dynsymcount = 0, synthcount, storage_needed;
   asymbol **symbol_table = NULL, **dyn_symbol_table = NULL;
   asymbol *synthsyms;
+  struct dbx_symfile_info *dbx;
 
   if (symtab_create_debug)
     {
       fprintf_unfiltered (gdb_stdlog,
                          "Reading minimal symbols of objfile %s ...\n",
-                         objfile->name);
+                         objfile_name (objfile));
+    }
+
+  /* If we already have minsyms, then we can skip some work here.
+     However, if there were stabs or mdebug sections, we go ahead and
+     redo all the work anyway, because the psym readers for those
+     kinds of debuginfo need extra information found here.  This can
+     go away once all types of symbols are in the per-BFD object.  */
+  if (objfile->per_bfd->minsyms_read
+      && ei->stabsect == NULL
+      && ei->mdebugsect == NULL)
+    {
+      if (symtab_create_debug)
+       fprintf_unfiltered (gdb_stdlog,
+                           "... minimal symbols previously read\n");
+      return;
     }
 
   init_minimal_symbol_collection ();
   back_to = make_cleanup_discard_minimal_symbols ();
 
-  memset ((char *) &ei, 0, sizeof (ei));
-
   /* 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));
-  make_cleanup (free_elfinfo, (void *) objfile);
+  dbx = XCNEW (struct dbx_symfile_info);
+  set_objfile_data (objfile, dbx_objfile_data_key, dbx);
 
-  /* 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.  */
 
   storage_needed = bfd_get_symtab_upper_bound (objfile->obfd);
   if (storage_needed < 0)
@@ -1284,8 +1055,10 @@ elf_symfile_read (struct objfile *objfile, int symfile_flags)
 
   if (storage_needed > 0)
     {
-      symbol_table = (asymbol **) xmalloc (storage_needed);
-      make_cleanup (xfree, symbol_table);
+      /* Memory gets permanently referenced from ABFD after
+        bfd_canonicalize_symtab so it must not get freed before ABFD gets.  */
+
+      symbol_table = bfd_alloc (abfd, storage_needed);
       symcount = bfd_canonicalize_symtab (objfile->obfd, symbol_table);
 
       if (symcount < 0)
@@ -1351,7 +1124,7 @@ elf_symfile_read (struct objfile *objfile, int symfile_flags)
       long i;
 
       make_cleanup (xfree, synthsyms);
-      synth_symbol_table = xmalloc (sizeof (asymbol *) * synthcount);
+      synth_symbol_table = XNEWVEC (asymbol *, synthcount);
       for (i = 0; i < synthcount; i++)
        synth_symbol_table[i] = synthsyms + i;
       make_cleanup (xfree, synth_symbol_table);
@@ -1368,12 +1141,45 @@ elf_symfile_read (struct objfile *objfile, int symfile_flags)
   install_minimal_symbols (objfile);
   do_cleanups (back_to);
 
-  /* Now process debugging information, which is contained in
-     special ELF sections.  */
+  if (symtab_create_debug)
+    fprintf_unfiltered (gdb_stdlog, "Done reading minimal symbols.\n");
+}
 
-  /* We first have to find them...  */
+/* Scan and build partial symbols for a symbol file.
+   We have been initialized by a call to elf_symfile_init, which
+   currently does nothing.
+
+   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
+   symbol tables.  When more extensive information is requested of a
+   file, the corresponding partial symbol table is mutated into a full
+   fledged symbol table by going back and reading the symbols
+   for real.
+
+   We look for sections with specific names, to tell us what debug
+   format to look for:  FIXME!!!
+
+   elfstab_build_psymtabs() handles STABS symbols;
+   mdebug_build_psymtabs() handles ECOFF debugging information.
+
+   Note that ELF files have a "minimal" symbol table, which looks a lot
+   like a COFF symbol table, but has only the minimal information necessary
+   for linking.  We process this also, and use the information to
+   build gdb's minimal symbol table.  This gives us some minimal debugging
+   capability even for files compiled without -g.  */
+
+static void
+elf_symfile_read (struct objfile *objfile, int symfile_flags)
+{
+  bfd *abfd = objfile->obfd;
+  struct elfinfo ei;
+
+  memset ((char *) &ei, 0, sizeof (ei));
   bfd_map_over_sections (abfd, elf_locate_sections, (void *) & ei);
 
+  elf_read_minimal_symbols (objfile, symfile_flags, &ei);
+
   /* ELF debugging information is inserted into the psymtab in the
      order of least informative first - most informative last.  Since
      the psymtab table is searched `most recent insertion first' this
@@ -1420,21 +1226,31 @@ elf_symfile_read (struct objfile *objfile, int symfile_flags)
 
       if (!objfile_has_partial_symbols (objfile)
          && dwarf2_initialize_objfile (objfile))
-       objfile->sf = &elf_sym_fns_gdb_index;
+       objfile_set_sym_fns (objfile, &elf_sym_fns_gdb_index);
       else
        {
          /* It is ok to do this even if the stabs reader made some
             partial symbols, because OBJF_PSYMTABS_READ has not been
             set, and so our lazy reader function will still be called
             when needed.  */
-         objfile->sf = &elf_sym_fns_lazy_psyms;
+         objfile_set_sym_fns (objfile, &elf_sym_fns_lazy_psyms);
        }
     }
   /* 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'.  */
-  else if (!objfile_has_partial_symbols (objfile))
+     `.note.gnu.build-id'.
+
+     .gnu_debugdata is !objfile_has_partial_symbols because it contains only
+     .symtab, not .debug_* section.  But if we already added .gnu_debugdata as
+     an objfile via find_separate_debug_file_in_section there was no separate
+     debug info available.  Therefore do not attempt to search for another one,
+     objfile->separate_debug_objfile->separate_debug_objfile GDB guarantees to
+     be NULL and we would possibly violate it.  */
+
+  else if (!objfile_has_partial_symbols (objfile)
+          && objfile->separate_debug_objfile == NULL
+          && objfile->separate_debug_objfile_backlink == NULL)
     {
       char *debugfile;
 
@@ -1449,13 +1265,10 @@ elf_symfile_read (struct objfile *objfile, int symfile_flags)
          bfd *abfd = symfile_bfd_open (debugfile);
 
          make_cleanup_bfd_unref (abfd);
-         symbol_file_add_separate (abfd, symfile_flags, objfile);
+         symbol_file_add_separate (abfd, debugfile, symfile_flags, objfile);
          do_cleanups (cleanup);
        }
     }
-
-  if (symtab_create_debug)
-    fprintf_unfiltered (gdb_stdlog, "Done reading minimal symbols.\n");
 }
 
 /* Callback to lazily read psymtabs.  */
@@ -1467,29 +1280,6 @@ read_psyms (struct objfile *objfile)
     dwarf2_build_psymtabs (objfile);
 }
 
-/* This cleans up the objfile's deprecated_sym_stab_info pointer, and
-   the chain of stab_section_info's, that might be dangling from
-   it.  */
-
-static void
-free_elfinfo (void *objp)
-{
-  struct objfile *objfile = (struct objfile *) objp;
-  struct dbx_symfile_info *dbxinfo = objfile->deprecated_sym_stab_info;
-  struct stab_section_info *ssi, *nssi;
-
-  ssi = dbxinfo->stab_section_info;
-  while (ssi)
-    {
-      nssi = ssi->next;
-      xfree (ssi);
-      ssi = nssi;
-    }
-
-  dbxinfo->stab_section_info = 0;      /* Just say No mo info about this.  */
-}
-
-
 /* Initialize anything that needs initializing when a completely new symbol
    file is specified (not just adding some symbols from another file, e.g. a
    shared library).
@@ -1512,22 +1302,10 @@ elf_new_init (struct objfile *ignore)
 static void
 elf_symfile_finish (struct objfile *objfile)
 {
-  if (objfile->deprecated_sym_stab_info != NULL)
-    {
-      xfree (objfile->deprecated_sym_stab_info);
-    }
-
   dwarf2_free_objfile (objfile);
 }
 
-/* ELF specific initialization routine for reading symbols.
-
-   It is passed a pointer to a struct sym_fns which contains, among other
-   things, the BFD for the file whose symbols are being read, and a slot for
-   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.  */
+/* ELF specific initialization routine for reading symbols.  */
 
 static void
 elf_symfile_init (struct objfile *objfile)
@@ -1538,80 +1316,17 @@ elf_symfile_init (struct objfile *objfile)
   objfile->flags |= OBJF_REORDERED;
 }
 
-/* When handling an ELF file that contains Sun STABS debug info,
-   some of the debug info is relative to the particular chunk of the
-   section that was generated in its individual .o file.  E.g.
-   offsets to static variables are relative to the start of the data
-   segment *for that module before linking*.  This information is
-   painfully squirreled away in the ELF symbol table as local symbols
-   with wierd names.  Go get 'em when needed.  */
-
-void
-elfstab_offset_sections (struct objfile *objfile, struct partial_symtab *pst)
-{
-  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;
-  int i;
-
-  /* The ELF symbol info doesn't include path names, so strip the path
-     (if any) from the psymtab filename.  */
-  filename = lbasename (filename);
-
-  /* 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.  */
-  for (; maybe; maybe = maybe->next)
-    {
-      if (filename[0] == maybe->filename[0]
-         && filename_cmp (filename, maybe->filename) == 0)
-       {
-         /* We found a match.  But there might be several source files
-            (from different directories) with the same name.  */
-         if (0 == maybe->found)
-           break;
-         questionable = maybe; /* Might use it later.  */
-       }
-    }
-
-  if (maybe == 0 && questionable != 0)
-    {
-      complaint (&symfile_complaints,
-                _("elf/stab section information questionable for %s"),
-                filename);
-      maybe = questionable;
-    }
-
-  if (maybe)
-    {
-      /* Found it!  Allocate a new psymtab struct, and fill it in.  */
-      maybe->found++;
-      pst->section_offsets = (struct section_offsets *)
-       obstack_alloc (&objfile->objfile_obstack,
-                      SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
-      for (i = 0; i < maybe->num_sections; i++)
-       (pst->section_offsets)->offsets[i] = maybe->sections[i];
-      return;
-    }
-
-  /* We were unable to find any offsets for this file.  Complain.  */
-  if (dbx->stab_section_info)  /* If there *is* any info, */
-    complaint (&symfile_complaints,
-              _("elf/stab section information missing for %s"), filename);
-}
-
 /* Implementation of `sym_get_probes', as documented in symfile.h.  */
 
 static VEC (probe_p) *
 elf_get_probes (struct objfile *objfile)
 {
-  VEC (probe_p) *probes_per_objfile;
+  VEC (probe_p) *probes_per_bfd;
 
   /* Have we parsed this objfile's probes already?  */
-  probes_per_objfile = objfile_data (objfile, probe_key);
+  probes_per_bfd = bfd_data (objfile->obfd, probe_key);
 
-  if (!probes_per_objfile)
+  if (!probes_per_bfd)
     {
       int ix;
       const struct probe_ops *probe_ops;
@@ -1620,69 +1335,25 @@ elf_get_probes (struct objfile *objfile)
         objfile.  */
       for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, probe_ops);
           ix++)
-       probe_ops->get_probes (&probes_per_objfile, objfile);
+       probe_ops->get_probes (&probes_per_bfd, objfile);
 
-      if (probes_per_objfile == NULL)
+      if (probes_per_bfd == NULL)
        {
-         VEC_reserve (probe_p, probes_per_objfile, 1);
-         gdb_assert (probes_per_objfile != NULL);
+         VEC_reserve (probe_p, probes_per_bfd, 1);
+         gdb_assert (probes_per_bfd != NULL);
        }
 
-      set_objfile_data (objfile, probe_key, probes_per_objfile);
+      set_bfd_data (objfile->obfd, probe_key, probes_per_bfd);
     }
 
-  return probes_per_objfile;
-}
-
-/* Implementation of `sym_get_probe_argument_count', as documented in
-   symfile.h.  */
-
-static unsigned
-elf_get_probe_argument_count (struct probe *probe)
-{
-  return probe->pops->get_probe_argument_count (probe);
-}
-
-/* Implementation of `sym_evaluate_probe_argument', as documented in
-   symfile.h.  */
-
-static struct value *
-elf_evaluate_probe_argument (struct probe *probe, unsigned n)
-{
-  return probe->pops->evaluate_probe_argument (probe, n);
-}
-
-/* Implementation of `sym_compile_to_ax', as documented in symfile.h.  */
-
-static void
-elf_compile_to_ax (struct probe *probe,
-                  struct agent_expr *expr,
-                  struct axs_value *value,
-                  unsigned n)
-{
-  probe->pops->compile_to_ax (probe, expr, value, n);
-}
-
-/* Implementation of `sym_relocate_probe', as documented in symfile.h.  */
-
-static void
-elf_symfile_relocate_probe (struct objfile *objfile,
-                           struct section_offsets *new_offsets,
-                           struct section_offsets *delta)
-{
-  int ix;
-  VEC (probe_p) *probes = objfile_data (objfile, probe_key);
-  struct probe *probe;
-
-  for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
-    probe->pops->relocate (probe, ANOFFSET (delta, SECT_OFF_TEXT (objfile)));
+  return probes_per_bfd;
 }
 
 /* Helper function used to free the space allocated for storing SystemTap
    probe information.  */
 
 static void
-probe_key_free (struct objfile *objfile, void *d)
+probe_key_free (bfd *abfd, void *d)
 {
   int ix;
   VEC (probe_p) *probes = d;
@@ -1700,18 +1371,13 @@ probe_key_free (struct objfile *objfile, void *d)
 
 static const struct sym_probe_fns elf_probe_fns =
 {
-  elf_get_probes,              /* sym_get_probes */
-  elf_get_probe_argument_count,        /* sym_get_probe_argument_count */
-  elf_evaluate_probe_argument, /* sym_evaluate_probe_argument */
-  elf_compile_to_ax,           /* sym_compile_to_ax */
-  elf_symfile_relocate_probe,  /* sym_relocate_probe */
+  elf_get_probes,                  /* sym_get_probes */
 };
 
 /* Register that we are able to handle ELF object file formats.  */
 
 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 */
@@ -1728,9 +1394,8 @@ static const struct sym_fns elf_sym_fns =
 /* The same as elf_sym_fns, but not registered and lazily reads
    psymbols.  */
 
-static const struct sym_fns elf_sym_fns_lazy_psyms =
+const struct sym_fns elf_sym_fns_lazy_psyms =
 {
-  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 */
@@ -1746,9 +1411,8 @@ static const struct sym_fns elf_sym_fns_lazy_psyms =
 
 /* 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 =
+const struct sym_fns elf_sym_fns_gdb_index =
 {
-  bfd_target_elf_flavour,
   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 */
@@ -1775,8 +1439,8 @@ static const struct gnu_ifunc_fns elf_gnu_ifunc_fns =
 void
 _initialize_elfread (void)
 {
-  probe_key = register_objfile_data_with_cleanup (NULL, probe_key_free);
-  add_symtab_fns (&elf_sym_fns);
+  probe_key = register_bfd_data_with_cleanup (NULL, probe_key_free);
+  add_symtab_fns (bfd_target_elf_flavour, &elf_sym_fns);
 
   elf_objfile_gnu_ifunc_cache_data = register_objfile_data ();
   gnu_ifunc_fns_p = &elf_gnu_ifunc_fns;
This page took 0.040732 seconds and 4 git commands to generate.