X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Felfread.c;h=32cb27c8967e3053cc6e276633be4a2e9f79c436;hb=387e00f3b3e6ea3719f144d7090c1a242174be4d;hp=82437f8acc7e3f4b25b2069c1e16e67ccb27f802;hpb=1adeb822668d3bd7182ca9b8cf42a7261deb3c7f;p=binutils-gdb.git diff --git a/gdb/elfread.c b/gdb/elfread.c index 82437f8acc7..32cb27c8967 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-2018 Free Software Foundation, Inc. + Copyright (C) 1991-2022 Free Software Foundation, Inc. Written by Fred Fish at Cygnus Support. @@ -28,10 +28,7 @@ #include "symtab.h" #include "symfile.h" #include "objfiles.h" -#include "buildsym.h" #include "stabsread.h" -#include "gdb-stabs.h" -#include "complaints.h" #include "demangle.h" #include "psympriv.h" #include "filenames.h" @@ -41,17 +38,19 @@ #include "value.h" #include "infcall.h" #include "gdbthread.h" +#include "inferior.h" #include "regcache.h" #include "bcache.h" #include "gdb_bfd.h" #include "build-id.h" #include "location.h" #include "auxv.h" - -/* Forward declarations. */ -extern const struct sym_fns elf_sym_fns_gdb_index; -extern const struct sym_fns elf_sym_fns_debug_names; -extern const struct sym_fns elf_sym_fns_lazy_psyms; +#include "mdebugread.h" +#include "ctfread.h" +#include "gdbsupport/gdb_string_view.h" +#include "gdbsupport/scoped_fd.h" +#include "debuginfod-support.h" +#include "dwarf2/public.h" /* The struct elfinfo is available only during ELF symbol table and psymtab reading. It is destroyed at the completion of psymtab-reading. @@ -61,11 +60,16 @@ struct elfinfo { 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> elfread_data; + /* Per-BFD data for probe info. */ -static const struct bfd_data *probe_key = NULL; +static const struct bfd_key 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 @@ -76,14 +80,13 @@ static const struct bfd_data *probe_key = NULL; /* 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) @@ -103,34 +106,28 @@ 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) { int j; - CORE_ADDR vma; - if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0) + if ((bfd_section_flags (sect) & SEC_ALLOC) == 0) continue; - vma = bfd_get_section_vma (abfd, sect); + Elf_Internal_Shdr *this_hdr = &elf_section_data (sect)->this_hdr; for (j = 0; j < num_segments; j++) - if (segments[j]->p_memsz > 0 - && vma >= segments[j]->p_vaddr - && (vma - segments[j]->p_vaddr) < segments[j]->p_memsz) + if (ELF_SECTION_IN_SEGMENT (this_hdr, segments[j])) { data->segment_info[i] = j + 1; break; @@ -145,10 +142,15 @@ elf_symfile_segments (bfd *abfd) 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) - warning (_("Loadable section \"%s\" outside of ELF segments"), - bfd_section_name (abfd, sect)); + + /* Exclude debuginfo files from this warning, too, since those + are often not strictly compliant with the standard. See, e.g., + ld/24717 for more discussion. */ + if (!is_debuginfo_file (abfd) + && bfd_section_size (sect) > 0 && j == num_segments + && (bfd_section_flags (sect) & SEC_LOAD) != 0) + warning (_("Loadable section \"%s\" outside of ELF segments\n in %s"), + bfd_section_name (sect), bfd_get_filename (abfd)); } return data; @@ -174,11 +176,8 @@ elf_symfile_segments (bfd *abfd) -kingdon). */ static void -elf_locate_sections (bfd *ignore_abfd, asection *sectp, void *eip) +elf_locate_sections (asection *sectp, struct elfinfo *ei) { - struct elfinfo *ei; - - ei = (struct elfinfo *) eip; if (strcmp (sectp->name, ".stab") == 0) { ei->stabsect = sectp; @@ -187,25 +186,40 @@ elf_locate_sections (bfd *ignore_abfd, asection *sectp, void *eip) { 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) { - 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); - return reader.record_full (name, name_len, copy_name, address, - ms_type, - gdb_bfd_section_index (objfile->obfd, - bfd_section)); + /* 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, 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; + + return result; } /* Read the symbol table of an ELF file. @@ -230,7 +244,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; @@ -252,6 +266,8 @@ elf_symtab_read (minimal_symbol_reader &reader, continue; } + elf_symbol_type *elf_sym = (elf_symbol_type *) sym; + /* Skip "special" symbols, e.g. ARM mapping symbols. These are symbols which do not correspond to objects in the symbol table, but have some other target-specific meaning. */ @@ -288,12 +304,12 @@ elf_symtab_read (minimal_symbol_reader &reader, 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) @@ -317,7 +333,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) { @@ -334,11 +350,7 @@ elf_symtab_read (minimal_symbol_reader &reader, if (type == ST_DYNAMIC && !stripped) continue; if (sym->flags & BSF_FILE) - { - filesymname - = (const char *) bcache (sym->name, strlen (sym->name) + 1, - objfile->per_bfd->filename_cache); - } + filesymname = objfile->intern (sym->name); else if (sym->flags & BSF_SECTION_SYM) continue; else if (sym->flags & (BSF_GLOBAL | BSF_LOCAL | BSF_WEAK @@ -363,7 +375,7 @@ elf_symtab_read (minimal_symbol_reader &reader, NOTE: uweigand-20071112: Synthetic symbols do not have an ELF-private part, so do not touch those. */ unsigned int shndx = type == ST_SYNTHETIC ? 0 : - ((elf_symbol_type *) sym)->internal_elf_sym.st_shndx; + elf_sym->internal_elf_sym.st_shndx; switch (shndx) { @@ -422,7 +434,11 @@ elf_symtab_read (minimal_symbol_reader &reader, { if (sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) { - if (sym->section->flags & SEC_LOAD) + if (sym->flags & BSF_GNU_INDIRECT_FUNCTION) + { + ms_type = mst_data_gnu_ifunc; + } + else if (sym->section->flags & SEC_LOAD) { ms_type = mst_data; } @@ -457,7 +473,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) @@ -467,8 +483,7 @@ elf_symtab_read (minimal_symbol_reader &reader, if (type != ST_SYNTHETIC) { /* 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->set_size (elf_sym->internal_elf_sym.st_size); } msym->filename = filesymname; @@ -481,40 +496,39 @@ elf_symtab_read (minimal_symbol_reader &reader, if (msym != NULL) { const char *atsign = strchr (sym->name, '@'); - - if (atsign != NULL && atsign[1] == '@' && atsign > sym->name) + bool is_at_symbol = atsign != nullptr && atsign > sym->name; + bool is_plt = is_at_symbol && strcmp (atsign, "@plt") == 0; + int len = is_at_symbol ? atsign - sym->name : 0; + + if (is_at_symbol + && !is_plt + && (elf_sym->version & VERSYM_HIDDEN) == 0) + record_minimal_symbol (reader, + gdb::string_view (sym->name, len), + true, symaddr, ms_type, sym->section, + objfile); + else if (is_plt) { - int len = atsign - sym->name; - - record_minimal_symbol (reader, sym->name, len, true, 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 - trying to find the target. */ - if (msym && ms_type == mst_text && type == ST_SYNTHETIC) - { - int len = strlen (sym->name); - - if (len > 4 && strcmp (sym->name + len - 4, "@plt") == 0) - { - struct minimal_symbol *mtramp; - - mtramp = record_minimal_symbol (reader, sym->name, len - 4, - true, symaddr, - mst_solib_trampoline, - sym->section, objfile); - if (mtramp) + /* 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 trying to find the target. */ + if (ms_type == mst_text && type == ST_SYNTHETIC) { - SET_MSYMBOL_SIZE (mtramp, MSYMBOL_SIZE (msym)); - mtramp->created_by_gdb = 1; - mtramp->filename = filesymname; - if (elf_make_msymbol_special_p) - gdbarch_elf_make_msymbol_special (gdbarch, - sym, mtramp); + struct minimal_symbol *mtramp; + + mtramp = record_minimal_symbol + (reader, gdb::string_view (sym->name, len), true, + symaddr, mst_solib_trampoline, sym->section, objfile); + if (mtramp) + { + mtramp->set_size (msym->size()); + mtramp->created_by_gdb = 1; + mtramp->filename = filesymname; + if (elf_make_msymbol_special_p) + gdbarch_elf_make_msymbol_special (gdbarch, + sym, mtramp); + } } } } @@ -537,7 +551,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); @@ -586,9 +600,9 @@ elf_rel_plt_read (minimal_symbol_reader &reader, 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; @@ -614,25 +628,26 @@ elf_rel_plt_read (minimal_symbol_reader &reader, else continue; - /* We cannot check if NAME is a reference to mst_text_gnu_ifunc as in - OBJFILE the symbol is undefined and the objfile having NAME defined - may not yet have been loaded. */ + /* We cannot check if NAME is a reference to + mst_text_gnu_ifunc/mst_data_gnu_ifunc as in OBJFILE the + symbol is undefined and the objfile having NAME defined may + not yet have been loaded. */ 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) - SET_MSYMBOL_SIZE (msym, ptr_size); + msym->set_size (ptr_size); } } /* 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 + elf_objfile_gnu_ifunc_cache_data; /* Map function names to CORE_ADDR in elf_objfile_gnu_ifunc_cache_data. */ @@ -688,13 +703,13 @@ elf_gnu_ifunc_record_cache (const char *name, CORE_ADDR addr) msym = lookup_minimal_symbol_by_pc (addr); if (msym.minsym == NULL) return 0; - if (BMSYMBOL_VALUE_ADDRESS (msym) != addr) + if (msym.value_address () != addr) return 0; objfile = msym.objfile; /* 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 @@ -703,15 +718,13 @@ elf_gnu_ifunc_record_cache (const char *name, CORE_ADDR addr) 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; @@ -726,7 +739,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) { @@ -756,15 +769,13 @@ elf_gnu_ifunc_record_cache (const char *name, CORE_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; @@ -798,16 +809,15 @@ static int 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); + 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; @@ -818,21 +828,21 @@ elf_gnu_ifunc_resolve_by_got (const char *name, CORE_ADDR *addr_p) msym = lookup_minimal_symbol (name_got_plt, NULL, objfile); if (msym.minsym == NULL) continue; - if (MSYMBOL_TYPE (msym.minsym) != mst_slot_got_plt) + if (msym.minsym->type () != mst_slot_got_plt) continue; - pointer_address = BMSYMBOL_VALUE_ADDRESS (msym); + pointer_address = msym.value_address (); plt = bfd_get_section_by_name (obfd, ".plt"); if (plt == NULL) continue; - if (MSYMBOL_SIZE (msym.minsym) != ptr_size) + if (msym.minsym->size () != 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_convert_from_func_ptr_addr + (gdbarch, addr, current_inferior ()->top_target ()); addr = gdbarch_addr_bits_remove (gdbarch, addr); if (elf_gnu_ifunc_record_cache (name, addr)) @@ -848,21 +858,21 @@ elf_gnu_ifunc_resolve_by_got (const char *name, CORE_ADDR *addr_p) /* 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 @@ -899,13 +909,13 @@ elf_gnu_ifunc_resolve_addr (struct gdbarch *gdbarch, CORE_ADDR pc) parameter. FUNCTION is the function entry address. ADDRESS may be a function descriptor. */ - target_auxv_search (¤t_target, AT_HWCAP, &hwcap); + target_auxv_search (current_inferior ()->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, - ¤t_target); + address = gdbarch_convert_from_func_ptr_addr + (gdbarch, address, current_inferior ()->top_target ()); address = gdbarch_addr_bits_remove (gdbarch, address); if (name_at_pc) @@ -917,13 +927,13 @@ elf_gnu_ifunc_resolve_addr (struct gdbarch *gdbarch, CORE_ADDR pc) /* Handle inferior hit of bp_gnu_ifunc_resolver, see its definition. */ static void -elf_gnu_ifunc_resolver_stop (struct breakpoint *b) +elf_gnu_ifunc_resolver_stop (code_breakpoint *b) { struct breakpoint *b_return; struct frame_info *prev_frame = get_prev_frame (get_current_frame ()); struct frame_id prev_frame_id = get_stack_frame_id (prev_frame); CORE_ADDR prev_pc = get_frame_pc (prev_frame); - int thread_id = ptid_to_global_thread_id (inferior_ptid); + int thread_id = inferior_thread ()->global_num; gdb_assert (b->type == bp_gnu_ifunc_resolver); @@ -968,12 +978,13 @@ elf_gnu_ifunc_resolver_stop (struct breakpoint *b) /* Handle inferior hit of bp_gnu_ifunc_resolver_return, see its definition. */ static void -elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b) +elf_gnu_ifunc_resolver_return_stop (code_breakpoint *b) { + thread_info *thread = inferior_thread (); struct gdbarch *gdbarch = get_frame_arch (get_current_frame ()); 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 regcache *regcache = get_thread_regcache (thread); struct value *func_func; struct value *value; CORE_ADDR resolved_address, resolved_pc; @@ -997,7 +1008,7 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b) "gnu-indirect-function breakpoint type %d"), (int) b->type); } - b = b_next; + b = (code_breakpoint *) b_next; } gdb_assert (b->type == bp_gnu_ifunc_resolver); gdb_assert (b->loc->next == NULL); @@ -1008,11 +1019,10 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b) value = allocate_value (value_type); gdbarch_return_value (gdbarch, func_func, value_type, regcache, - value_contents_raw (value), NULL); + value_contents_raw (value).data (), NULL); resolved_address = value_as_address (value); - resolved_pc = gdbarch_convert_from_func_ptr_addr (gdbarch, - resolved_address, - ¤t_target); + resolved_pc = gdbarch_convert_from_func_ptr_addr + (gdbarch, resolved_address, current_inferior ()->top_target ()); resolved_pc = gdbarch_addr_bits_remove (gdbarch, resolved_pc); gdb_assert (current_program_space == b->pspace || b->pspace == NULL); @@ -1021,7 +1031,8 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b) b->type = bp_breakpoint; update_breakpoint_locations (b, current_program_space, - find_pc_line (resolved_pc, 0), {}); + find_function_start_sal (resolved_pc, NULL, true), + {}); } /* A helper function for elf_symfile_read that reads the minimal @@ -1035,13 +1046,12 @@ elf_read_minimal_symbols (struct objfile *objfile, int symfile_flags, 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)); + gdb_printf (gdb_stdlog, + "Reading minimal symbols of objfile %s ...\n", + objfile_name (objfile)); } /* If we already have minsyms, then we can skip some work here. @@ -1051,20 +1061,17 @@ elf_read_minimal_symbols (struct objfile *objfile, int symfile_flags, 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 symbols previously read\n"); + gdb_printf (gdb_stdlog, + "... minimal symbols previously read\n"); return; } 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); @@ -1164,7 +1171,7 @@ elf_read_minimal_symbols (struct objfile *objfile, int symfile_flags, reader.install (); if (symtab_create_debug) - fprintf_unfiltered (gdb_stdlog, "Done reading minimal symbols.\n"); + gdb_printf (gdb_stdlog, "Done reading minimal symbols.\n"); } /* Scan and build partial symbols for a symbol file. @@ -1196,10 +1203,14 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) { bfd *abfd = objfile->obfd; struct elfinfo ei; + bool has_dwarf2 = true; memset ((char *) &ei, 0, sizeof (ei)); if (!(objfile->flags & OBJF_READNEVER)) - bfd_map_over_sections (abfd, elf_locate_sections, (void *) & ei); + { + for (asection *sect : gdb_bfd_sections (abfd)) + elf_locate_sections (sect, &ei); + } elf_read_minimal_symbols (objfile, symfile_flags, &ei); @@ -1220,7 +1231,7 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) const struct ecoff_debug_swap *swap; /* .mdebug section, presumably holding ECOFF debugging - information. */ + information. */ swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; if (swap) elfmdebug_build_psymtabs (objfile, swap, ei.mdebugsect); @@ -1230,7 +1241,7 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) asection *str_sect; /* Stab sections have an associated string table that looks like - a separate section. */ + a separate section. */ str_sect = bfd_get_section_by_name (abfd, ".stabstr"); /* FIXME should probably warn about a stab section without a stabstr. */ @@ -1238,51 +1249,24 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) 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)) - { - dw_index_kind index_kind; - - /* elf_sym_fns_gdb_index cannot handle simultaneous non-DWARF - debug information present in OBJFILE. If there is such debug - info present never use an index. */ - if (!objfile_has_partial_symbols (objfile) - && dwarf2_initialize_objfile (objfile, &index_kind)) - { - switch (index_kind) - { - case dw_index_kind::GDB_INDEX: - objfile_set_sym_fns (objfile, &elf_sym_fns_gdb_index); - break; - case dw_index_kind::DEBUG_NAMES: - objfile_set_sym_fns (objfile, &elf_sym_fns_debug_names); - break; - } - } - 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_set_sym_fns (objfile, &elf_sym_fns_lazy_psyms); - } - } + if (dwarf2_has_info (objfile, NULL, true)) + dwarf2_initialize_objfile (objfile); /* 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'. - .gnu_debugdata is !objfile_has_partial_symbols because it contains only + .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) + else if (!objfile->has_partial_symbols () && objfile->separate_debug_objfile == NULL && objfile->separate_debug_objfile_backlink == NULL) { @@ -1293,35 +1277,57 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) if (!debugfile.empty ()) { - gdb_bfd_ref_ptr abfd (symfile_bfd_open (debugfile.c_str ())); + gdb_bfd_ref_ptr debug_bfd (symfile_bfd_open (debugfile.c_str ())); - symbol_file_add_separate (abfd.get (), debugfile.c_str (), + symbol_file_add_separate (debug_bfd.get (), debugfile.c_str (), symfile_flags, objfile); } - } -} + else + { + has_dwarf2 = false; + const struct bfd_build_id *build_id = build_id_bfd_get (objfile->obfd); -/* Callback to lazily read psymtabs. */ + 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)); -static void -read_psyms (struct objfile *objfile) -{ - if (dwarf2_has_info (objfile, NULL)) - dwarf2_build_psymtabs (objfile); + 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. */ + 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 (); - buildsym_new_init (); } /* Perform any local cleanups required when we are done with a particular @@ -1332,7 +1338,6 @@ elf_new_init (struct objfile *ignore) static void elf_symfile_finish (struct objfile *objfile) { - dwarf2_free_objfile (objfile); } /* ELF specific initialization routine for reading symbols. */ @@ -1348,43 +1353,24 @@ elf_symfile_init (struct objfile *objfile) /* Implementation of `sym_get_probes', as documented in symfile.h. */ -static const std::vector & +static const elfread_data & elf_get_probes (struct objfile *objfile) { - std::vector *probes_per_bfd; - - /* Have we parsed this objfile's probes already? */ - probes_per_bfd = (std::vector *) 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; + 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 *probes = (std::vector *) d; - - for (probe *p : *probes) - delete p; - - delete probes; -} - /* Implementation `sym_probe_fns', as documented in symfile.h. */ @@ -1401,66 +1387,12 @@ static const struct sym_fns elf_sym_fns = 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 */ - NULL, /* sym_read_psymbols */ - elf_symfile_finish, /* finished with file, cleanup */ - 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_probe_fns, /* sym_probe_fns */ - &psym_functions -}; - -/* The same as elf_sym_fns, but not registered and lazily reads - psymbols. */ - -const struct sym_fns elf_sym_fns_lazy_psyms = -{ - 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 */ - read_psyms, /* sym_read_psymbols */ elf_symfile_finish, /* finished with file, cleanup */ 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_probe_fns, /* sym_probe_fns */ - &psym_functions -}; - -/* The same as elf_sym_fns, but not registered and uses the - DWARF-specific GNU index rather than psymtab. */ -const struct sym_fns elf_sym_fns_gdb_index = -{ - 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 */ - NULL, /* sym_read_psymbols */ - elf_symfile_finish, /* finished with file, cleanup */ - default_symfile_offsets, /* Translate ext. to int. relocatin */ - 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 -}; - -/* The same as elf_sym_fns, but not registered and uses the - DWARF-specific .debug_names index rather than psymtab. */ -const struct sym_fns elf_sym_fns_debug_names = -{ - 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 */ - NULL, /* sym_read_psymbols */ - elf_symfile_finish, /* finished with file, cleanup */ - default_symfile_offsets, /* Translate ext. to int. relocatin */ - elf_symfile_segments, /* Get segment information from a file. */ - NULL, - default_symfile_relocate, /* Relocate a debug section. */ - &elf_probe_fns, /* sym_probe_fns */ - &dwarf2_debug_names_functions }; /* STT_GNU_IFUNC resolver vector to be installed to gnu_ifunc_fns_p. */ @@ -1473,12 +1405,11 @@ 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 () { - 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; }