gdb/
[deliverable/binutils-gdb.git] / gdb / machoread.c
index 3894236fc3fdce09006306046ced0db8fd5c16bc..a454cd420ab34bce594918ed28aa697f2576a6e5 100644 (file)
@@ -1,5 +1,5 @@
 /* Darwin support for GDB, the GNU debugger.
-   Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 
    Contributed by AdaCore.
 
@@ -32,6 +32,7 @@
 #include "gdb_assert.h"
 #include "aout/stab_gnu.h"
 #include "vec.h"
+#include "psympriv.h"
 
 #include <string.h>
 
@@ -43,8 +44,8 @@ static int mach_o_debug_level = 0;
    during the link.
    Each time an oso (other source) is found in the executable, the reader
    creates such a structure.  They are read after the processing of the
-   executable.
-*/
+   executable.  */
+
 typedef struct oso_el
 {
   /* Object file name.  */
@@ -188,7 +189,7 @@ macho_symtab_read (struct objfile *objfile,
       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;
        }
 
@@ -197,12 +198,12 @@ macho_symtab_read (struct objfile *objfile,
          struct minimal_symbol *msym;
          CORE_ADDR symaddr;
 
-         /* Bfd symbols are section relative. */
+         /* Bfd symbols are section relative.  */
          symaddr = sym->value + sym->section->vma;
 
          /* 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. */
+            interested in will have a section.  */
          /* Relocate all non-absolute and non-TLS symbols by the
             section offset.  */
          if (sym->section != &bfd_abs_section
@@ -240,7 +241,7 @@ macho_symtab_read (struct objfile *objfile,
                ms_type = mst_unknown;
            }
          else
-           continue;   /* Skip this symbol. */
+           continue;   /* Skip this symbol.  */
 
          gdb_assert (sym->section->index < nbr_sections);
          if (oso_file != NULL
@@ -290,6 +291,65 @@ oso_el_compare_name (const void *vl, const void *vr)
   return strcmp (l->name, r->name);
 }
 
+/* Relocate all of ABFD's common symbols immediately.
+
+   This modifies the section and address of all common symbols to become
+   absolute symbols with their address set to match the address given by
+   the main objfile's symbol table.
+
+   The reason why the common symbols have to be handled separately
+   is because relocation is performed relative to section start.
+   But there is no section in this case.  So the "relocation" of
+   these common symbols is performed by finding their address in
+   the main objfile's symbol table, where we know it's been relocated.
+
+   ABFD is an OSO's bfd.
+   MAIN_OBJFILE is the object file from which the OSO is a part.  */
+
+static void
+macho_relocate_common_syms(bfd *abfd, struct objfile *main_objfile)
+{
+  int storage;
+  int i;
+  char leading_char;
+  asymbol **symbol_table;
+
+  storage = bfd_get_symtab_upper_bound (abfd);
+  symbol_table = (asymbol **) xmalloc (storage);
+  bfd_canonicalize_symtab (abfd, symbol_table);
+
+  leading_char = bfd_get_symbol_leading_char (abfd);
+
+  for (i = 0; symbol_table[i]; i++)
+    {
+      asymbol *sym = symbol_table[i];
+
+      if (bfd_is_com_section (sym->section))
+       {
+         /* This one must be solved.  */
+         struct minimal_symbol *msym;
+         const char *name = sym->name;
+
+         if (name[0] == leading_char)
+           name++;
+
+         msym = lookup_minimal_symbol (name, NULL, main_objfile);
+         if (msym == NULL)
+           {
+             warning (_("can't find symbol '%s' in minsymtab"), name);
+             continue;
+           }
+         else
+           {
+             sym->section = &bfd_abs_section;
+             sym->value = SYMBOL_VALUE_ADDRESS (msym);
+           }
+       }
+    }
+
+  xfree (symbol_table);
+}
+
 /* Add an oso file as a symbol file.  */
 
 static void
@@ -297,8 +357,6 @@ macho_add_oso_symfile (oso_el *oso, bfd *abfd,
                        struct objfile *main_objfile, int symfile_flags)
 {
   struct objfile *objfile;
-  struct section_addr_info *addrs;
-  int len;
   int i;
   char leading_char;
 
@@ -314,58 +372,65 @@ macho_add_oso_symfile (oso_el *oso, bfd *abfd,
     }
 
   bfd_set_cacheable (abfd, 1);
-  
-  /* Compute addr length.  */
-  len = 0;
-  for (i = 0; i < oso->num_sections; i++)
-    if (oso->symbols[i] != NULL)
-      len++;
-  
-  addrs = alloc_section_addr_info (len);
+
+  /* Relocate sections.  */
 
   leading_char = bfd_get_symbol_leading_char (main_objfile->obfd);
 
-  len = 0;
   for (i = 0; i < oso->num_sections; i++)
-    if (oso->symbols[i] != NULL)
-      {
-        if (oso->offsets[i])
-          addrs->other[len].addr = oso->offsets[i];
-        else
-          {
-            struct minimal_symbol *msym;
-            const char *name = oso->symbols[i]->name;
-            
-            if (name[0] == leading_char)
-              ++name;
-
-            if (mach_o_debug_level > 3)
-              printf_unfiltered (_("resolve sect %s with %s\n"),
-                                 oso->symbols[i]->section->name,
-                                 oso->symbols[i]->name);
-            msym = lookup_minimal_symbol (name, NULL, main_objfile);
-            if (msym == NULL)
-              {
-                warning (_("can't find symbol '%s' in minsymtab"),
-                         oso->symbols[i]->name);
-                addrs->other[len].addr = 0;
-              }
-            else
-              addrs->other[len].addr = SYMBOL_VALUE_ADDRESS (msym);
-          }
-        addrs->other[len].name = (char *)oso->symbols[i]->section->name;
-        len++;
-      }
-      
-  if (mach_o_debug_level > 1)
     {
-      int j;
-      for (j = 0; j < addrs->num_sections; j++)
+      asection *sect;
+      const char *sectname;
+      bfd_vma vma;
+
+      /* Empty slot.  */
+      if (oso->symbols[i] == NULL)
+        continue;
+
+      if (oso->offsets[i])
+        vma = oso->offsets[i];
+      else
+        {
+          struct minimal_symbol *msym;
+          const char *name = oso->symbols[i]->name;
+
+          if (name[0] == leading_char)
+            ++name;
+
+          if (mach_o_debug_level > 3)
+            printf_unfiltered (_("resolve sect %s with %s\n"),
+                               oso->symbols[i]->section->name,
+                               oso->symbols[i]->name);
+          msym = lookup_minimal_symbol (name, NULL, main_objfile);
+          if (msym == NULL)
+            {
+              warning (_("can't find symbol '%s' in minsymtab"), name);
+              continue;
+            }
+          else
+            vma = SYMBOL_VALUE_ADDRESS (msym);
+        }
+      sectname = (char *)oso->symbols[i]->section->name;
+
+      sect = bfd_get_section_by_name (abfd, sectname);
+      if (sect == NULL)
+        {
+          warning (_("can't find section '%s' in OSO file %s"),
+                   sectname, oso->name);
+          continue;
+        }
+      bfd_set_section_vma (abfd, sect, vma);
+
+      if (mach_o_debug_level > 1)
         printf_unfiltered (_("  %s: %s\n"),
-                           core_addr_to_string (addrs->other[j].addr),
-                           addrs->other[j].name);
+                           core_addr_to_string (vma), sectname);
     }
 
+  /* Deal with the common symbols now, as they need special handing.
+     Doing it now sets them up so that we don't accidently try to
+     relocate them during the normal relocation phase.  */
+  macho_relocate_common_syms (abfd, main_objfile);
+
   /* Make sure that the filename was malloc'ed.  The current filename comes
      either from an OSO symbol name or from an archive name.  Memory for both
      is not managed by gdb.  */
@@ -374,10 +439,10 @@ macho_add_oso_symfile (oso_el *oso, bfd *abfd,
   /* We need to clear SYMFILE_MAINLINE to avoid interractive question
      from symfile.c:symbol_file_add_with_addrs_or_offsets.  */
   objfile = symbol_file_add_from_bfd
-    (abfd, symfile_flags & ~SYMFILE_MAINLINE, addrs,
+    (abfd, symfile_flags & ~(SYMFILE_MAINLINE | SYMFILE_VERBOSE), NULL,
      main_objfile->flags & (OBJF_REORDERED | OBJF_SHARED
-                            | OBJF_READNOW | OBJF_USERLOADED));
-  add_separate_debug_objfile (objfile, main_objfile);
+                           | OBJF_READNOW | OBJF_USERLOADED),
+     main_objfile);
 }
 
 /* Read symbols from the vector of oso files.  */
@@ -632,7 +697,7 @@ macho_symfile_read (struct objfile *objfile, int symfile_flags)
       /* Try to read .eh_frame / .debug_frame.  */
       /* First, locate these sections.  We ignore the result status
         as it only checks for debug info.  */
-      dwarf2_has_info (objfile);
+      dwarf2_has_info (objfile, NULL);
       dwarf2_build_frame_info (objfile);
       
       /* Check for DSYM file.  */
@@ -674,20 +739,35 @@ macho_symfile_read (struct objfile *objfile, int symfile_flags)
        }
     }
 
-  if (dwarf2_has_info (objfile))
+  if (dwarf2_has_info (objfile, NULL))
     {
       /* DWARF 2 sections */
       dwarf2_build_psymtabs (objfile);
     }
 
-  /* Do not try to read .eh_frame/.debug_frame as they are not relocated
-     and dwarf2_build_frame_info cannot deal with unrelocated sections.  */
-
   /* Then the oso.  */
   if (oso_vector != NULL)
     macho_symfile_read_all_oso (objfile, symfile_flags);
 }
 
+static bfd_byte *
+macho_symfile_relocate (struct objfile *objfile, asection *sectp,
+                        bfd_byte *buf)
+{
+  bfd *abfd = objfile->obfd;
+
+  /* We're only interested in sections with relocation
+     information.  */
+  if ((sectp->flags & SEC_RELOC) == 0)
+    return NULL;
+
+  if (mach_o_debug_level > 0)
+    printf_unfiltered (_("Relocate section '%s' of %s\n"),
+                       sectp->name, objfile->name);
+
+  return bfd_simple_get_relocated_section_contents (abfd, sectp, buf, NULL);
+}
+
 static void
 macho_symfile_finish (struct objfile *objfile)
 {
@@ -750,20 +830,19 @@ macho_symfile_offsets (struct objfile *objfile,
     }
 }
 
-static struct sym_fns macho_sym_fns = {
+static const struct sym_fns macho_sym_fns = {
   bfd_target_mach_o_flavour,
 
-  macho_new_init,               /* sym_new_init: init anything gbl to entire symtab */
-  macho_symfile_init,           /* sym_init: read initial info, setup for sym_read() */
-  macho_symfile_read,           /* sym_read: read a symbol file into symtab */
-  macho_symfile_finish,         /* sym_finish: finished with file, cleanup */
-  macho_symfile_offsets,        /* sym_offsets:  xlate external to internal form */
-  default_symfile_segments,    /* sym_segments: Get segment information from
-                                  a file.  */
-  NULL,                         /* sym_read_linetable */
-  default_symfile_relocate,    /* sym_relocate: Relocate a debug section.  */
-
-  NULL                          /* next: pointer to next struct sym_fns */
+  macho_new_init,               /* init anything gbl to entire symtab */
+  macho_symfile_init,           /* read initial info, setup for sym_read() */
+  macho_symfile_read,           /* read a symbol file into symtab */
+  NULL,                                /* sym_read_psymbols */
+  macho_symfile_finish,         /* finished with file, cleanup */
+  macho_symfile_offsets,        /* xlate external to internal form */
+  default_symfile_segments,    /* Get segment information from a file.  */
+  NULL,
+  macho_symfile_relocate,      /* Relocate a debug section.  */
+  &psym_functions
 };
 
 void
@@ -772,9 +851,9 @@ _initialize_machoread ()
   add_symtab_fns (&macho_sym_fns);
 
   add_setshow_zinteger_cmd ("mach-o", class_obscure,
-                           &mach_o_debug_level, _("\
-Set if printing Mach-O symbols processing."), _("\
-Show if printing Mach-O symbols processing."), NULL,
-                           NULL, NULL,
+                           &mach_o_debug_level,
+                           _("Set if printing Mach-O symbols processing."),
+                           _("Show if printing Mach-O symbols processing."),
+                           NULL, NULL, NULL,
                            &setdebuglist, &showdebuglist);
 }
This page took 0.036499 seconds and 4 git commands to generate.