/* Read ELF (Executable and Linking Format) object files for GDB.
- Copyright (C) 1991-2018 Free Software Foundation, Inc.
+ Copyright (C) 1991-2020 Free Software Foundation, Inc.
Written by Fred Fish at Cygnus Support.
#include "symfile.h"
#include "objfiles.h"
#include "stabsread.h"
-#include "gdb-stabs.h"
#include "complaints.h"
#include "demangle.h"
#include "psympriv.h"
#include "build-id.h"
#include "location.h"
#include "auxv.h"
+#include "mdebugread.h"
+#include "ctfread.h"
+#include "gdbsupport/gdb_string_view.h"
/* Forward declarations. */
extern const struct sym_fns elf_sym_fns_gdb_index;
{
asection *stabsect; /* Section pointer for .stab section */
asection *mdebugsect; /* Section pointer for .mdebug section */
+ asection *ctfsect; /* Section pointer for .ctf section */
};
+/* Type for per-BFD data. */
+
+typedef std::vector<std::unique_ptr<probe>> elfread_data;
+
/* Per-BFD data for probe info. */
-static const struct bfd_data *probe_key = NULL;
+static const struct bfd_key<elfread_data> probe_key;
/* Minimal symbols located at the GOT entries for .plt - that is the real
pointer where the given entry will jump to. It gets updated by the real
{
int j;
- if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0)
+ if ((bfd_section_flags (sect) & SEC_ALLOC) == 0)
continue;
Elf_Internal_Shdr *this_hdr = &elf_section_data (sect)->this_hdr;
RealView) use SHT_NOBITS for uninitialized data. Since it is
uninitialized, it doesn't need a program header. Such
binaries are not relocatable. */
- if (bfd_get_section_size (sect) > 0 && j == num_segments
- && (bfd_get_section_flags (abfd, sect) & SEC_LOAD) != 0)
+ if (bfd_section_size (sect) > 0 && j == num_segments
+ && (bfd_section_flags (sect) & SEC_LOAD) != 0)
warning (_("Loadable section \"%s\" outside of ELF segments"),
- bfd_section_name (abfd, sect));
+ bfd_section_name (sect));
}
return data;
{
ei->mdebugsect = sectp;
}
+ else if (strcmp (sectp->name, ".ctf") == 0)
+ {
+ ei->ctfsect = sectp;
+ }
}
static struct minimal_symbol *
record_minimal_symbol (minimal_symbol_reader &reader,
- const char *name, int name_len, bool copy_name,
+ gdb::string_view name, bool copy_name,
CORE_ADDR address,
enum minimal_symbol_type ms_type,
asection *bfd_section, struct objfile *objfile)
|| ms_type == mst_text_gnu_ifunc)
address = gdbarch_addr_bits_remove (gdbarch, address);
- return reader.record_full (name, name_len, copy_name, address,
- ms_type,
- gdb_bfd_section_index (objfile->obfd,
- bfd_section));
+ struct minimal_symbol *result
+ = reader.record_full (name, copy_name, address,
+ ms_type,
+ gdb_bfd_section_index (objfile->obfd,
+ bfd_section));
+ if ((objfile->flags & OBJF_MAINLINE) == 0
+ && (ms_type == mst_data || ms_type == mst_bss))
+ result->maybe_copied = 1;
+
+ return result;
}
/* Read the symbol table of an ELF file.
covers the stub's address. */
for (sect = abfd->sections; sect != NULL; sect = sect->next)
{
- if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0)
+ if ((bfd_section_flags (sect) & SEC_ALLOC) == 0)
continue;
- if (symaddr >= bfd_get_section_vma (abfd, sect)
- && symaddr < bfd_get_section_vma (abfd, sect)
- + bfd_get_section_size (sect))
+ if (symaddr >= bfd_section_vma (sect)
+ && symaddr < bfd_section_vma (sect)
+ + bfd_section_size (sect))
break;
}
if (!sect)
continue;
msym = record_minimal_symbol
- (reader, sym->name, strlen (sym->name), copy_names,
+ (reader, sym->name, copy_names,
symaddr, mst_solib_trampoline, sect, objfile);
if (msym != NULL)
{
if (sym->flags & BSF_FILE)
{
filesymname
- = (const char *) bcache (sym->name, strlen (sym->name) + 1,
- objfile->per_bfd->filename_cache);
+ = ((const char *) objfile->per_bfd->filename_cache.insert
+ (sym->name, strlen (sym->name) + 1));
}
else if (sym->flags & BSF_SECTION_SYM)
continue;
continue; /* Skip this symbol. */
}
msym = record_minimal_symbol
- (reader, sym->name, strlen (sym->name), copy_names, symaddr,
+ (reader, sym->name, copy_names, symaddr,
ms_type, sym->section, objfile);
if (msym)
{
int len = atsign - sym->name;
- record_minimal_symbol (reader, sym->name, len, true, symaddr,
- ms_type, sym->section, objfile);
+ record_minimal_symbol (reader,
+ gdb::string_view (sym->name, len),
+ true, symaddr, ms_type, sym->section,
+ objfile);
}
}
{
struct minimal_symbol *mtramp;
- mtramp = record_minimal_symbol (reader, sym->name, len - 4,
- true, symaddr,
- mst_solib_trampoline,
- sym->section, objfile);
+ mtramp = record_minimal_symbol
+ (reader, gdb::string_view (sym->name, len - 4), true,
+ symaddr, mst_solib_trampoline, sym->section, objfile);
if (mtramp)
{
SET_MSYMBOL_SIZE (mtramp, MSYMBOL_SIZE (msym));
if (section == NULL)
return false;
- return (bfd_get_section_vma (obfd, section) <= address
- && (address < bfd_get_section_vma (obfd, section)
- + bfd_get_section_size (section)));
+ return (bfd_section_vma (section) <= address
+ && (address < bfd_section_vma (section)
+ + bfd_section_size (section)));
};
reloc_count = relplt->size / elf_section_data (relplt)->this_hdr.sh_entsize;
string_buffer.assign (name);
string_buffer.append (got_suffix, got_suffix + got_suffix_len);
- msym = record_minimal_symbol (reader, string_buffer.c_str (),
- string_buffer.size (),
+ msym = record_minimal_symbol (reader, string_buffer,
true, address, mst_slot_got_plt,
msym_section, objfile);
if (msym)
/* The data pointer is htab_t for gnu_ifunc_record_cache_unchecked. */
-static const struct objfile_data *elf_objfile_gnu_ifunc_cache_data;
+static const struct objfile_key<htab, htab_deleter>
+ elf_objfile_gnu_ifunc_cache_data;
/* Map function names to CORE_ADDR in elf_objfile_gnu_ifunc_cache_data. */
/* If .plt jumps back to .plt the symbol is still deferred for later
resolution and it has no use for GDB. */
- const char *target_name = MSYMBOL_LINKAGE_NAME (msym.minsym);
+ const char *target_name = msym.minsym->linkage_name ();
size_t len = strlen (target_name);
/* Note we check the symbol's name instead of checking whether the
if (len > 4 && strcmp (target_name + len - 4, "@plt") == 0)
return 0;
- htab = (htab_t) objfile_data (objfile, elf_objfile_gnu_ifunc_cache_data);
+ htab = elf_objfile_gnu_ifunc_cache_data.get (objfile);
if (htab == NULL)
{
- htab = htab_create_alloc_ex (1, elf_gnu_ifunc_cache_hash,
- elf_gnu_ifunc_cache_eq,
- NULL, &objfile->objfile_obstack,
- hashtab_obstack_allocate,
- dummy_obstack_deallocate);
- set_objfile_data (objfile, elf_objfile_gnu_ifunc_cache_data, htab);
+ htab = htab_create_alloc (1, elf_gnu_ifunc_cache_hash,
+ elf_gnu_ifunc_cache_eq,
+ NULL, xcalloc, xfree);
+ elf_objfile_gnu_ifunc_cache_data.set (objfile, htab);
}
entry_local.addr = addr;
static int
elf_gnu_ifunc_resolve_by_cache (const char *name, CORE_ADDR *addr_p)
{
- struct objfile *objfile;
-
- ALL_PSPACE_OBJFILES (current_program_space, objfile)
+ for (objfile *objfile : current_program_space->objfiles ())
{
htab_t htab;
struct elf_gnu_ifunc_cache *entry_p;
void **slot;
- htab = (htab_t) objfile_data (objfile, elf_objfile_gnu_ifunc_cache_data);
+ htab = elf_objfile_gnu_ifunc_cache_data.get (objfile);
if (htab == NULL)
continue;
elf_gnu_ifunc_resolve_by_got (const char *name, CORE_ADDR *addr_p)
{
char *name_got_plt;
- struct objfile *objfile;
const size_t got_suffix_len = strlen (SYMBOL_GOT_PLT_SUFFIX);
name_got_plt = (char *) alloca (strlen (name) + got_suffix_len + 1);
sprintf (name_got_plt, "%s" SYMBOL_GOT_PLT_SUFFIX, name);
- ALL_PSPACE_OBJFILES (current_program_space, objfile)
+ for (objfile *objfile : current_program_space->objfiles ())
{
bfd *obfd = objfile->obfd;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
/* Try to find the target resolved function entry address of a STT_GNU_IFUNC
function NAME. If the address is found it is stored to *ADDR_P (if ADDR_P
- is not NULL) and the function returns 1. It returns 0 otherwise.
+ is not NULL) and the function returns true. It returns false otherwise.
Both the elf_objfile_gnu_ifunc_cache_data hash table and
SYMBOL_GOT_PLT_SUFFIX locations are searched by this function. */
-static int
+static bool
elf_gnu_ifunc_resolve_name (const char *name, CORE_ADDR *addr_p)
{
if (elf_gnu_ifunc_resolve_by_cache (name, addr_p))
- return 1;
+ return true;
if (elf_gnu_ifunc_resolve_by_got (name, addr_p))
- return 1;
+ return true;
- return 0;
+ return false;
}
/* Call STT_GNU_IFUNC - a function returning addresss of a real function to
target_auxv_search (current_top_target (), AT_HWCAP, &hwcap);
hwcap_val = value_from_longest (builtin_type (gdbarch)
->builtin_unsigned_long, hwcap);
- address_val = call_function_by_hand (function, NULL, 1, &hwcap_val);
+ address_val = call_function_by_hand (function, NULL, hwcap_val);
address = value_as_address (address_val);
address = gdbarch_convert_from_func_ptr_addr (gdbarch, address, current_top_target ());
address = gdbarch_addr_bits_remove (gdbarch, address);
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)
{
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)
+ && ei->mdebugsect == NULL
+ && ei->ctfsect == NULL)
{
if (symtab_create_debug)
fprintf_unfiltered (gdb_stdlog,
minimal_symbol_reader reader (objfile);
- /* Allocate struct to keep track of the symfile. */
- dbx = XCNEW (struct dbx_symfile_info);
- set_objfile_data (objfile, dbx_objfile_data_key, dbx);
-
/* Process the normal ELF symbol table first. */
storage_needed = bfd_get_symtab_upper_bound (objfile->obfd);
{
bfd *abfd = objfile->obfd;
struct elfinfo ei;
+ bool has_dwarf2 = true;
memset ((char *) &ei, 0, sizeof (ei));
if (!(objfile->flags & OBJF_READNEVER))
elfstab_build_psymtabs (objfile,
ei.stabsect,
str_sect->filepos,
- bfd_section_size (abfd, str_sect));
+ bfd_section_size (str_sect));
}
- if (dwarf2_has_info (objfile, NULL))
+ if (dwarf2_has_info (objfile, NULL, true))
{
dw_index_kind index_kind;
symbol_file_add_separate (debug_bfd.get (), debugfile.c_str (),
symfile_flags, objfile);
}
+ else
+ has_dwarf2 = false;
+ }
+
+ /* Read the CTF section only if there is no DWARF info. */
+ if (!has_dwarf2 && ei.ctfsect)
+ {
+ elfctf_build_psymtabs (objfile);
}
}
/* Initialize anything that needs initializing when a completely new symbol
file is specified (not just adding some symbols from another file, e.g. a
- shared library).
-
- We reinitialize buildsym, since we may be reading stabs from an ELF
- file. */
+ shared library). */
static void
elf_new_init (struct objfile *ignore)
{
- stabsread_new_init ();
}
/* Perform any local cleanups required when we are done with a particular
/* Implementation of `sym_get_probes', as documented in symfile.h. */
-static const std::vector<probe *> &
+static const elfread_data &
elf_get_probes (struct objfile *objfile)
{
- std::vector<probe *> *probes_per_bfd;
-
- /* Have we parsed this objfile's probes already? */
- probes_per_bfd = (std::vector<probe *> *) bfd_data (objfile->obfd, probe_key);
+ elfread_data *probes_per_bfd = probe_key.get (objfile->obfd);
if (probes_per_bfd == NULL)
{
- probes_per_bfd = new std::vector<probe *>;
+ probes_per_bfd = probe_key.emplace (objfile->obfd);
/* Here we try to gather information about all types of probes from the
objfile. */
for (const static_probe_ops *ops : all_static_probe_ops)
ops->get_probes (probes_per_bfd, objfile);
-
- set_bfd_data (objfile->obfd, probe_key, probes_per_bfd);
}
return *probes_per_bfd;
}
-/* Helper function used to free the space allocated for storing SystemTap
- probe information. */
-
-static void
-probe_key_free (bfd *abfd, void *d)
-{
- std::vector<probe *> *probes = (std::vector<probe *> *) d;
-
- for (probe *p : *probes)
- delete p;
-
- delete probes;
-}
-
\f
/* Implementation `sym_probe_fns', as documented in symfile.h. */
elf_symfile_read, /* read a symbol file into symtab */
NULL, /* sym_read_psymbols */
elf_symfile_finish, /* finished with file, cleanup */
- default_symfile_offsets, /* Translate ext. to int. relocatin */
+ default_symfile_offsets, /* Translate ext. to int. relocation */
elf_symfile_segments, /* Get segment information from a file. */
NULL,
default_symfile_relocate, /* Relocate a debug section. */
elf_symfile_read, /* read a symbol file into symtab */
NULL, /* sym_read_psymbols */
elf_symfile_finish, /* finished with file, cleanup */
- default_symfile_offsets, /* Translate ext. to int. relocatin */
+ default_symfile_offsets, /* Translate ext. to int. relocation */
elf_symfile_segments, /* Get segment information from a file. */
NULL,
default_symfile_relocate, /* Relocate a debug section. */
void
_initialize_elfread (void)
{
- 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 ();
gnu_ifunc_fns_p = &elf_gnu_ifunc_fns;
}