/* Read ELF (Executable and Linking Format) object files for GDB.
- Copyright (C) 1991-2012 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 <string.h>
#include "elf-bfd.h"
#include "elf/common.h"
#include "elf/internal.h"
#include "demangle.h"
#include "psympriv.h"
#include "filenames.h"
+#include "probe.h"
+#include "arch-utils.h"
#include "gdbtypes.h"
#include "value.h"
#include "infcall.h"
#include "gdbthread.h"
#include "regcache.h"
#include "bcache.h"
+#include "gdb_bfd.h"
+#include "build-id.h"
extern void _initialize_elfread (void);
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. */
+
+static const struct objfile_data *probe_key = NULL;
+
static void free_elfinfo (void *);
/* Minimal symbols located at the GOT entries for .plt - that is the real
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)
{
binaries are not relocatable. */
if (bfd_get_section_size (sect) > 0 && j == num_segments
&& (bfd_get_section_flags (abfd, sect) & SEC_LOAD) != 0)
- warning (_("Loadable segment \"%s\" outside of ELF segments"),
+ warning (_("Loadable section \"%s\" outside of ELF segments"),
bfd_section_name (abfd, sect));
}
{
ei->stabsect = sectp;
}
- else if (strcmp (sectp->name, ".stab.index") == 0)
- {
- ei->stabindexsect = sectp;
- }
else if (strcmp (sectp->name, ".mdebug") == 0)
{
ei->mdebugsect = sectp;
if (ms_type == mst_text || ms_type == mst_file_text
|| ms_type == mst_text_gnu_ifunc)
- address = gdbarch_smash_text_address (gdbarch, address);
+ 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.
/* Name of filesym. 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);
for (i = 0; i < number_of_symbols; i++)
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
+ && sym->section == bfd_und_section_ptr
&& (sym->flags & BSF_FUNCTION))
{
struct minimal_symbol *msym;
&& bfd_get_section_by_name (abfd, ".plt") != NULL)
continue;
- symaddr += ANOFFSET (objfile->section_offsets, sect->index);
+ symaddr += ANOFFSET (objfile->section_offsets,
+ gdb_bfd_section_index (objfile->obfd, sect));
msym = record_minimal_symbol
(sym->name, strlen (sym->name), copy_names,
}
filesym = sym;
filesymname = bcache (filesym->name, strlen (filesym->name) + 1,
- objfile->filename_cache);
+ 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;
symaddr = sym->value + sym->section->vma;
/* Relocate all non-absolute and non-TLS symbols by the
section offset. */
- if (sym->section != &bfd_abs_section
+ 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->section == &bfd_abs_section)
+ if (sym->section == bfd_abs_section_ptr)
{
/* This is a hack to get the minimal symbol type
right for Irix 5, which has absolute addresses
}
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;
}
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)
{
symaddr = sym->value + sym->section->vma;
/* Relocate non-absolute symbols by the
section offset. */
- if (sym->section != &bfd_abs_section)
+ if (sym->section != bfd_abs_section_ptr)
symaddr += offset;
sectinfo->sections[special_local_sect] = symaddr;
/* The special local symbols don't go in the
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)
- 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 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
destination symbol. The @plt symbol will be used in
disassembly, and the trampoline will be used when we are
sym->section, objfile);
if (mtramp)
{
- MSYMBOL_SIZE (mtramp) = MSYMBOL_SIZE (msym);
+ SET_MSYMBOL_SIZE (mtramp, MSYMBOL_SIZE (msym));
+ mtramp->created_by_gdb = 1;
mtramp->filename = filesymname;
gdbarch_elf_make_msymbol_special (gdbarch, sym, mtramp);
}
bfd *obfd = objfile->obfd;
const struct elf_backend_data *bed = get_elf_backend_data (obfd);
asection *plt, *relplt, *got_plt;
- unsigned u;
int plt_elf_idx;
bfd_size_type reloc_count, reloc;
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);
reloc_count = relplt->size / elf_section_data (relplt)->this_hdr.sh_entsize;
for (reloc = 0; reloc < reloc_count; reloc++)
{
- const char *name, *name_got_plt;
+ const char *name;
struct minimal_symbol *msym;
CORE_ADDR address;
const size_t got_suffix_len = strlen (SYMBOL_GOT_PLT_SUFFIX);
1, address, mst_slot_got_plt, got_plt,
objfile);
if (msym)
- MSYMBOL_SIZE (msym) = ptr_size;
+ SET_MSYMBOL_SIZE (msym, ptr_size);
}
do_cleanups (back_to);
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;
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 (SYMBOL_VALUE_ADDRESS (msym.minsym) != 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 = SYMBOL_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
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)
{
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;
prev_frame_id,
bp_gnu_ifunc_resolver_return);
+ /* set_momentary_breakpoint invalidates PREV_FRAME. */
+ prev_frame = NULL;
+
/* Add new b_return to the ring list b->related_breakpoint. */
gdb_assert (b_return->related_breakpoint == b_return);
b_return->related_breakpoint = b->related_breakpoint;
struct type *func_func_type = builtin_type (gdbarch)->builtin_func_func;
struct type *value_type = TYPE_TARGET_TYPE (func_func_type);
struct regcache *regcache = get_thread_regcache (inferior_ptid);
+ struct value *func_func;
struct value *value;
CORE_ADDR resolved_address, resolved_pc;
struct symtab_and_line sal;
gdb_assert (b->type == bp_gnu_ifunc_resolver_return);
- value = allocate_value (value_type);
- gdbarch_return_value (gdbarch, func_func_type, value_type, regcache,
- value_contents_raw (value), NULL);
- resolved_address = value_as_address (value);
- resolved_pc = gdbarch_convert_from_func_ptr_addr (gdbarch,
- resolved_address,
- ¤t_target);
-
while (b->related_breakpoint != b)
{
struct breakpoint *b_next = b->related_breakpoint;
b = b_next;
}
gdb_assert (b->type == bp_gnu_ifunc_resolver);
+ gdb_assert (b->loc->next == NULL);
+
+ func_func = allocate_value (func_func_type);
+ set_value_address (func_func, b->loc->related_address);
+
+ value = allocate_value (value_type);
+ gdbarch_return_value (gdbarch, func_func, value_type, regcache,
+ value_contents_raw (value), NULL);
+ resolved_address = value_as_address (value);
+ resolved_pc = gdbarch_convert_from_func_ptr_addr (gdbarch,
+ resolved_address,
+ ¤t_target);
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);
}
-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 = 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_close_or_warn (abfd);
-
- xfree (found);
-
- return retval;
-}
-
-static char *
-build_id_to_debug_filename (struct build_id *build_id)
-{
- char *link, *debugdir, *retval = NULL;
-
- /* 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 = debug_file_directory;
- do
- {
- char *s, *debugdir_end;
- gdb_byte *data = build_id->data;
- size_t size = build_id->size;
-
- while (*debugdir == DIRNAME_SEPARATOR)
- debugdir++;
-
- debugdir_end = strchr (debugdir, DIRNAME_SEPARATOR);
- if (debugdir_end == NULL)
- debugdir_end = &debugdir[strlen (debugdir)];
-
- memcpy (link, debugdir, debugdir_end - debugdir);
- s = &link[debugdir_end - debugdir];
- 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;
-
- debugdir = debugdir_end;
- }
- while (*debugdir != 0);
-
- 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.
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));
+ }
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));
+ dbx = XCNEW (struct dbx_symfile_info);
+ set_objfile_data (objfile, dbx_objfile_data_key, dbx);
make_cleanup (free_elfinfo, (void *) objfile);
/* 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. */
+ chain of info into the dbx_symfile_info of the objfile, which can
+ later be used by elfstab_offset_sections. */
storage_needed = bfd_get_symtab_upper_bound (objfile->obfd);
if (storage_needed < 0)
install_minimal_symbols (objfile);
do_cleanups (back_to);
+ if (symtab_create_debug)
+ fprintf_unfiltered (gdb_stdlog, "Done reading minimal symbols.\n");
+
/* Now process debugging information, which is contained in
special ELF sections. */
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;
if (debugfile)
{
+ struct cleanup *cleanup = make_cleanup (xfree, debugfile);
bfd *abfd = symfile_bfd_open (debugfile);
- symbol_file_add_separate (abfd, symfile_flags, objfile);
- xfree (debugfile);
+ make_cleanup_bfd_unref (abfd);
+ symbol_file_add_separate (abfd, debugfile, symfile_flags, objfile);
+ do_cleanups (cleanup);
}
}
}
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. */
+/* This cleans up the objfile's dbx symfile info, 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 dbx_symfile_info *dbxinfo = DBX_SYMFILE_INFO (objfile);
struct stab_section_info *ssi, *nssi;
ssi = dbxinfo->stab_section_info;
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);
}
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 dbx_symfile_info *dbx = DBX_SYMFILE_INFO (objfile);
struct stab_section_info *maybe = dbx->stab_section_info;
struct stab_section_info *questionable = 0;
int i;
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;
+
+ /* Have we parsed this objfile's probes already? */
+ probes_per_objfile = objfile_data (objfile, probe_key);
+
+ if (!probes_per_objfile)
+ {
+ int ix;
+ const struct probe_ops *probe_ops;
+
+ /* Here we try to gather information about all types of probes from the
+ objfile. */
+ for (ix = 0; VEC_iterate (probe_ops_cp, all_probe_ops, ix, probe_ops);
+ ix++)
+ probe_ops->get_probes (&probes_per_objfile, objfile);
+
+ if (probes_per_objfile == NULL)
+ {
+ VEC_reserve (probe_p, probes_per_objfile, 1);
+ gdb_assert (probes_per_objfile != NULL);
+ }
+
+ set_objfile_data (objfile, probe_key, probes_per_objfile);
+ }
+
+ return probes_per_objfile;
+}
+
+/* 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)));
+}
+
+/* Helper function used to free the space allocated for storing SystemTap
+ probe information. */
+
+static void
+probe_key_free (struct objfile *objfile, void *d)
+{
+ int ix;
+ VEC (probe_p) *probes = d;
+ struct probe *probe;
+
+ for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++)
+ probe->pops->destroy (probe);
+
+ VEC_free (probe_p, probes);
+}
+
\f
+
+/* Implementation `sym_probe_fns', as documented in symfile.h. */
+
+static const struct sym_probe_fns elf_probe_fns =
+{
+ elf_get_probes, /* sym_get_probes */
+ elf_symfile_relocate_probe, /* sym_relocate_probe */
+};
+
/* 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 */
elf_symfile_segments, /* Get segment information from a file. */
NULL,
default_symfile_relocate, /* Relocate a debug section. */
+ &elf_probe_fns, /* sym_probe_fns */
&psym_functions
};
static 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 */
elf_symfile_segments, /* Get segment information from a file. */
NULL,
default_symfile_relocate, /* Relocate a debug section. */
+ &elf_probe_fns, /* sym_probe_fns */
&psym_functions
};
DWARF-specific GNU index rather than psymtab. */
static 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 */
elf_symfile_segments, /* Get segment information from a file. */
NULL,
default_symfile_relocate, /* Relocate a debug section. */
+ &elf_probe_fns, /* sym_probe_fns */
&dwarf2_gdb_index_functions
};
void
_initialize_elfread (void)
{
- add_symtab_fns (&elf_sym_fns);
+ probe_key = register_objfile_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;