/* Read ELF (Executable and Linking Format) object files for GDB.
- Copyright (C) 1991-2013 Free Software Foundation, Inc.
+ Copyright (C) 1991-2014 Free Software Foundation, Inc.
Written by Fred Fish at Cygnus Support.
#include "defs.h"
#include "bfd.h"
-#include "gdb_string.h"
#include "elf-bfd.h"
#include "elf/common.h"
#include "elf/internal.h"
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 const struct bfd_data *probe_key = NULL;
static void free_elfinfo (void *);
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++)
{
}
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)
{
&& bfd_get_section_by_name (abfd, ".plt") != NULL)
continue;
- symaddr += ANOFFSET (objfile->section_offsets,
- gdb_bfd_section_index (objfile->obfd, sect));
-
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;
+ gdbarch_elf_make_msymbol_special (gdbarch, sym, msym);
+ }
continue;
}
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. */
{
if (sym->name[0] == '.')
continue;
- symaddr += offset;
}
}
else if (sym->section->flags & SEC_CODE)
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)
msym = lookup_minimal_symbol_by_pc (addr);
if (msym.minsym == NULL)
return 0;
- if (SYMBOL_VALUE_ADDRESS (msym.minsym) != addr)
+ if (BMSYMBOL_VALUE_ADDRESS (msym) != addr)
return 0;
/* minimal symbols have always SYMBOL_OBJ_SECTION non-NULL. */
- sect = SYMBOL_OBJ_SECTION (msym.objfile, msym.minsym)->the_bfd_section;
+ 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
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,
¤t_target);
+ addr = gdbarch_addr_bits_remove (gdbarch, addr);
if (addr_p)
*addr_p = addr;
address = value_as_address (address_val);
address = gdbarch_convert_from_func_ptr_addr (gdbarch, address,
¤t_target);
+ address = gdbarch_addr_bits_remove (gdbarch, address);
if (name_at_pc)
elf_gnu_ifunc_record_cache (name_at_pc, address);
resolved_pc = gdbarch_convert_from_func_ptr_addr (gdbarch,
resolved_address,
¤t_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);
update_breakpoint_locations (b, sals, sals_end);
}
-/* 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;
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. */
dbx = XCNEW (struct dbx_symfile_info);
set_objfile_data (objfile, dbx_objfile_data_key, dbx);
if (symtab_create_debug)
fprintf_unfiltered (gdb_stdlog, "Done reading minimal symbols.\n");
+}
+
+/* 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.
- /* Now process debugging information, which is contained in
- special ELF sections. */
+ 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.
- /* We first have to find them... */
+ 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
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;
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_can_evaluate_probe_arguments', as documented in
- symfile.h. */
-
-static int
-elf_can_evaluate_probe_arguments (struct probe *probe)
-{
- return probe->pops->can_evaluate_probe_arguments (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,
- const struct section_offsets *new_offsets,
- const 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;
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_can_evaluate_probe_arguments, /* sym_can_evaluate_probe_arguments */
- elf_evaluate_probe_argument, /* sym_evaluate_probe_argument */
- elf_compile_to_ax, /* sym_compile_to_ax */
- elf_symfile_relocate_probe, /* sym_relocate_probe */
};
/* Register that we are able to handle ELF object file formats. */
void
_initialize_elfread (void)
{
- probe_key = register_objfile_data_with_cleanup (NULL, probe_key_free);
+ 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 ();