/* Read ELF (Executable and Linking Format) object files for GDB.
- Copyright (C) 1991-2019 Free Software Foundation, Inc.
+ Copyright (C) 1991-2020 Free Software Foundation, Inc.
Written by Fred Fish at Cygnus Support.
#include "auxv.h"
#include "mdebugread.h"
#include "ctfread.h"
+#include "gdbsupport/gdb_string_view.h"
+#include "gdbsupport/scoped_fd.h"
+#include "debuginfod-support.h"
/* Forward declarations. */
extern const struct sym_fns elf_sym_fns_gdb_index;
/* Locate the segments in ABFD. */
-static struct symfile_segment_data *
+static symfile_segment_data_up
elf_symfile_segments (bfd *abfd)
{
Elf_Internal_Phdr *phdrs, **segments;
long phdrs_size;
int num_phdrs, num_segments, num_sections, i;
asection *sect;
- struct symfile_segment_data *data;
phdrs_size = bfd_get_elf_phdr_upper_bound (abfd);
if (phdrs_size == -1)
if (num_segments == 0)
return NULL;
- data = XCNEW (struct symfile_segment_data);
- data->num_segments = num_segments;
- data->segment_bases = XCNEWVEC (CORE_ADDR, num_segments);
- data->segment_sizes = XCNEWVEC (CORE_ADDR, num_segments);
+ symfile_segment_data_up data (new symfile_segment_data);
+ data->segments.reserve (num_segments);
for (i = 0; i < num_segments; i++)
- {
- data->segment_bases[i] = segments[i]->p_vaddr;
- data->segment_sizes[i] = segments[i]->p_memsz;
- }
+ data->segments.emplace_back (segments[i]->p_vaddr, segments[i]->p_memsz);
num_sections = bfd_count_sections (abfd);
- data->segment_info = XCNEWVEC (int, num_sections);
+
+ /* All elements are initialized to 0 (map to no segment). */
+ data->segment_info.resize (num_sections);
for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next)
{
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)
{
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
if (ms_type == mst_text || ms_type == mst_file_text
|| ms_type == mst_text_gnu_ifunc)
address = gdbarch_addr_bits_remove (gdbarch, address);
+ /* We only setup section information for allocatable sections. Usually
+ we'd only expect to find msymbols for allocatable sections, but if the
+ ELF is malformed then this might not be the case. In that case don't
+ create an msymbol that references an uninitialised section object. */
+ int section_index = 0;
+ if ((bfd_section_flags (bfd_section) & SEC_ALLOC) == SEC_ALLOC)
+ section_index = gdb_bfd_section_index (objfile->obfd, bfd_section);
+
struct minimal_symbol *result
- = reader.record_full (name, name_len, copy_name, address,
- ms_type,
- gdb_bfd_section_index (objfile->obfd,
- bfd_section));
+ = reader.record_full (name, copy_name, address, ms_type, section_index);
if ((objfile->flags & OBJF_MAINLINE) == 0
&& (ms_type == mst_data || ms_type == mst_bss))
result->maybe_copied = 1;
long number_of_symbols, asymbol **symbol_table,
bool copy_names)
{
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
asymbol *sym;
long i;
CORE_ADDR symaddr;
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 (type == ST_DYNAMIC && !stripped)
continue;
if (sym->flags & BSF_FILE)
- {
- filesymname
- = ((const char *) objfile->per_bfd->filename_cache.insert
- (sym->name, strlen (sym->name) + 1));
- }
+ filesymname = objfile->intern (sym->name);
else if (sym->flags & BSF_SECTION_SYM)
continue;
else if (sym->flags & (BSF_GLOBAL | BSF_LOCAL | BSF_WEAK
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));
const struct elf_backend_data *bed = get_elf_backend_data (obfd);
asection *relplt, *got_plt;
bfd_size_type reloc_count, reloc;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
size_t ptr_size = TYPE_LENGTH (ptr_type);
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)
/* 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
{
struct elf_gnu_ifunc_cache *entry_found_p
= (struct elf_gnu_ifunc_cache *) *slot;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
if (entry_found_p->addr != addr)
{
for (objfile *objfile : current_program_space->objfiles ())
{
bfd *obfd = objfile->obfd;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
size_t ptr_size = TYPE_LENGTH (ptr_type);
CORE_ADDR pointer_address, addr;
symbol_file_add_separate (debug_bfd.get (), debugfile.c_str (),
symfile_flags, objfile);
}
- else
+ else
+ {
has_dwarf2 = false;
+ const struct bfd_build_id *build_id = build_id_bfd_get (objfile->obfd);
+
+ if (build_id != nullptr)
+ {
+ gdb::unique_xmalloc_ptr<char> symfile_path;
+ scoped_fd fd (debuginfod_debuginfo_query (build_id->data,
+ build_id->size,
+ objfile->original_name,
+ &symfile_path));
+
+ if (fd.get () >= 0)
+ {
+ /* File successfully retrieved from server. */
+ gdb_bfd_ref_ptr debug_bfd (symfile_bfd_open (symfile_path.get ()));
+
+ if (debug_bfd == nullptr)
+ warning (_("File \"%s\" from debuginfod cannot be opened as bfd"),
+ objfile->original_name);
+ else if (build_id_verify (debug_bfd.get (), build_id->size, build_id->data))
+ {
+ symbol_file_add_separate (debug_bfd.get (), symfile_path.get (),
+ symfile_flags, objfile);
+ has_dwarf2 = true;
+ }
+ }
+ }
+ }
}
/* Read the CTF section only if there is no DWARF info. */
elf_gnu_ifunc_resolver_return_stop
};
+void _initialize_elfread ();
void
-_initialize_elfread (void)
+_initialize_elfread ()
{
add_symtab_fns (bfd_target_elf_flavour, &elf_sym_fns);