/* 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.
#include "gdb_assert.h"
#include "aout/stab_gnu.h"
#include "vec.h"
+#include "psympriv.h"
#include <string.h>
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. */
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;
}
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
ms_type = mst_unknown;
}
else
- continue; /* Skip this symbol. */
+ continue; /* Skip this symbol. */
gdb_assert (sym->section->index < nbr_sections);
if (oso_file != NULL
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
struct objfile *main_objfile, int symfile_flags)
{
struct objfile *objfile;
- struct section_addr_info *addrs;
- int len;
int i;
char leading_char;
}
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. */
/* 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. */
/* 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. */
}
}
- 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)
{
}
}
-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
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);
}