X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Felfread.c;h=75bdd75250b11cf56ad26ad8552e0981056a95b2;hb=5bb6e9dd7090cacb02bbe9f20d8b101a59a3bf99;hp=1b5b4e0aa8086046fae20a93170c715e65488127;hpb=405feb71d4733a36cdc0629e9e4ccecd1a40dc39;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/elfread.c b/gdb/elfread.c index 1b5b4e0aa8..75bdd75250 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -1,6 +1,6 @@ /* 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. @@ -48,6 +48,9 @@ #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; @@ -82,14 +85,13 @@ static const struct bfd_key probe_key; /* 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) @@ -109,19 +111,16 @@ elf_symfile_segments (bfd *abfd) 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) { @@ -198,22 +197,27 @@ elf_locate_sections (bfd *ignore_abfd, asection *sectp, void *eip) 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; @@ -243,7 +247,7 @@ elf_symtab_read (minimal_symbol_reader &reader, 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; @@ -330,7 +334,7 @@ elf_symtab_read (minimal_symbol_reader &reader, 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) { @@ -347,11 +351,7 @@ elf_symtab_read (minimal_symbol_reader &reader, 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 @@ -474,7 +474,7 @@ elf_symtab_read (minimal_symbol_reader &reader, 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) @@ -503,8 +503,10 @@ elf_symtab_read (minimal_symbol_reader &reader, { 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); } } @@ -520,10 +522,9 @@ elf_symtab_read (minimal_symbol_reader &reader, { 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)); @@ -554,7 +555,7 @@ elf_rel_plt_read (minimal_symbol_reader &reader, 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); @@ -639,8 +640,7 @@ elf_rel_plt_read (minimal_symbol_reader &reader, 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) @@ -713,7 +713,7 @@ elf_gnu_ifunc_record_cache (const char *name, CORE_ADDR addr) /* 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 @@ -743,7 +743,7 @@ elf_gnu_ifunc_record_cache (const char *name, CORE_ADDR addr) { 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) { @@ -821,7 +821,7 @@ elf_gnu_ifunc_resolve_by_got (const char *name, CORE_ADDR *addr_p) 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; @@ -1310,8 +1310,36 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) 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 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. */ @@ -1468,8 +1496,9 @@ static const struct gnu_ifunc_fns elf_gnu_ifunc_fns = 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);