gdb: Add sparc*-*-linux catch syscall support.
[deliverable/binutils-gdb.git] / gdb / machoread.c
index 12fefaf1e09f068ab62eab060b8b3f296d800cde..a810bb2c8cc48a662b65e52866bbdad30ecf6522 100644 (file)
@@ -1,5 +1,5 @@
 /* Darwin support for GDB, the GNU debugger.
-   Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
 
    Contributed by AdaCore.
 
 /* If non-zero displays debugging message.  */
 static int mach_o_debug_level = 0;
 
-static void
-macho_new_init (struct objfile *objfile)
-{
-}
-
-static void
-macho_symfile_init (struct objfile *objfile)
-{
-  objfile->flags |= OBJF_REORDERED;
-  init_entry_point_info (objfile);
-}
-
 /* Dwarf debugging information are never in the final executable.  They stay
    in object files and the executable contains the list of object files read
    during the link.
@@ -77,15 +65,45 @@ typedef struct oso_el
 }
 oso_el;
 
-/* Vector of object files to be read after the executable.  */
+/* Vector of object files to be read after the executable.  This is one
+   global variable but it's life-time is the one of macho_symfile_read.  */
 DEF_VEC_O (oso_el);
 static VEC (oso_el) *oso_vector;
 
-/*  Add a new OSO to the vector.  */
+struct macho_oso_data
+{
+  /* Per objfile symbol table.  This is used to apply relocation to sections
+     It is loaded only once, then relocated, and free after sections are
+     relocated.  */
+  asymbol **symbol_table;
+
+  /* The offsets for this objfile.  Used to relocate the symbol_table.  */
+  struct oso_el *oso;
+
+  struct objfile *main_objfile;
+};
+
+/* Data for OSO being processed.  */
+
+static struct macho_oso_data current_oso;
 
 static void
-macho_add_oso (const asymbol *oso_sym, int nbr_sections,
-              asymbol **symbols, bfd_vma *offsets)
+macho_new_init (struct objfile *objfile)
+{
+}
+
+static void
+macho_symfile_init (struct objfile *objfile)
+{
+  objfile->flags |= OBJF_REORDERED;
+  init_entry_point_info (objfile);
+}
+
+/*  Add a new OSO to the vector of OSO to load.  */
+
+static void
+macho_register_oso (const asymbol *oso_sym, int nbr_sections,
+                    asymbol **symbols, bfd_vma *offsets)
 {
   oso_el el;
 
@@ -135,8 +153,8 @@ macho_symtab_read (struct objfile *objfile,
               /* An empty SO entry terminates a chunk for an OSO file.  */
              if ((sym->name == NULL || sym->name[0] == 0) && oso_file != NULL)
                {
-                 macho_add_oso (oso_file, nbr_sections,
-                                 first_symbol, first_offset);
+                 macho_register_oso (oso_file, nbr_sections,
+                                      first_symbol, first_offset);
                  first_symbol = NULL;
                  first_offset = NULL;
                  oso_file = NULL;
@@ -258,7 +276,7 @@ macho_symtab_read (struct objfile *objfile,
 
   /* Just in case there is no trailing SO entry.  */
   if (oso_file != NULL)
-    macho_add_oso (oso_file, nbr_sections, first_symbol, first_offset);
+    macho_register_oso (oso_file, nbr_sections, first_symbol, first_offset);
 }
 
 /* If NAME describes an archive member (ie: ARCHIVE '(' MEMBER ')'),
@@ -292,16 +310,16 @@ oso_el_compare_name (const void *vl, const void *vr)
 /* Add an oso file as a symbol file.  */
 
 static void
-macho_add_oso_symfile (oso_el *oso, bfd *abfd, struct objfile *main_objfile)
+macho_add_oso_symfile (oso_el *oso, bfd *abfd,
+                       struct objfile *main_objfile, int symfile_flags)
 {
-  struct section_addr_info *addrs;
-  int len;
+  struct objfile *objfile;
   int i;
   char leading_char;
 
   if (mach_o_debug_level > 0)
     printf_unfiltered (_("Loading symbols from oso: %s\n"), oso->name);
-      
+
   if (!bfd_check_format (abfd, bfd_object))
     {
       warning (_("`%s': can't read symbols: %s."), oso->name,
@@ -311,65 +329,88 @@ macho_add_oso_symfile (oso_el *oso, bfd *abfd, struct objfile *main_objfile)
     }
 
   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);
     }
 
-  symbol_file_add_from_bfd (abfd, 0, addrs, 0);
+  /* 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.  */
+  abfd->filename = xstrdup (abfd->filename);
+
+  gdb_assert (current_oso.symbol_table == NULL);
+  current_oso.main_objfile = main_objfile;
+
+  /* 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 | SYMFILE_VERBOSE), NULL,
+     main_objfile->flags & (OBJF_REORDERED | OBJF_SHARED
+                            | OBJF_READNOW | OBJF_USERLOADED));
+  add_separate_debug_objfile (objfile, main_objfile);
+
+  current_oso.main_objfile = NULL;
+  if (current_oso.symbol_table)
+    {
+      xfree (current_oso.symbol_table);
+      current_oso.symbol_table = NULL;
+    }
 }
 
 /* Read symbols from the vector of oso files.  */
 
 static void
-macho_oso_symfile (struct objfile *main_objfile)
+macho_symfile_read_all_oso (struct objfile *main_objfile, int symfile_flags)
 {
   int ix;
   VEC (oso_el) *vec;
@@ -453,7 +494,8 @@ macho_oso_symfile (struct objfile *main_objfile)
                       && !memcmp (member_name, oso2->name + pfx_len + 1,
                                   member_len))
                     {
-                      macho_add_oso_symfile (oso2, member_bfd, main_objfile);
+                      macho_add_oso_symfile (oso2, member_bfd,
+                                             main_objfile, symfile_flags);
                       oso2->name = NULL;
                       break;
                     }
@@ -486,7 +528,7 @@ macho_oso_symfile (struct objfile *main_objfile)
             warning (_("`%s': can't open to read symbols: %s."), oso->name,
                      bfd_errmsg (bfd_get_error ()));
           else
-            macho_add_oso_symfile (oso, abfd, main_objfile);
+            macho_add_oso_symfile (oso, abfd, main_objfile, symfile_flags);
 
           ix++;
         }
@@ -670,7 +712,66 @@ macho_symfile_read (struct objfile *objfile, int symfile_flags)
 
   /* Then the oso.  */
   if (oso_vector != NULL)
-    macho_oso_symfile (objfile);
+    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);
+
+  if (current_oso.symbol_table == NULL)
+    {
+      int storage;
+      int i;
+      char leading_char;
+
+      storage = bfd_get_symtab_upper_bound (abfd);
+      current_oso.symbol_table = (asymbol **) xmalloc (storage);
+      bfd_canonicalize_symtab (abfd, current_oso.symbol_table);
+
+      leading_char = bfd_get_symbol_leading_char (abfd);
+
+      for (i = 0; current_oso.symbol_table[i]; i++)
+        {
+          asymbol *sym = current_oso.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, current_oso.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);
+                }
+            }
+        }
+    }
+
+  return bfd_simple_get_relocated_section_contents (abfd, sectp, buf, NULL);
 }
 
 static void
@@ -745,6 +846,9 @@ static struct sym_fns macho_sym_fns = {
   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 */
+  macho_symfile_relocate,      /* sym_relocate: Relocate a debug section.  */
+
   NULL                          /* next: pointer to next struct sym_fns */
 };
 
This page took 0.027925 seconds and 4 git commands to generate.