X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Felfread.c;h=f2483025baa20dba0ecf1dbb1364b4c1d2663b02;hb=935676c92feb5f35e4634ef58c20ffdfd0979b07;hp=138d316b4fead489481014726dc7da7993ff5a5b;hpb=9a3c826307ae6ad4dd6fbd72431e7d9d4947f1dd;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/elfread.c b/gdb/elfread.c index 138d316b4f..f2483025ba 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-2015 Free Software Foundation, Inc. + Copyright (C) 1991-2017 Free Software Foundation, Inc. Written by Fred Fish at Cygnus Support. @@ -46,8 +46,7 @@ #include "gdb_bfd.h" #include "build-id.h" #include "location.h" - -extern void _initialize_elfread (void); +#include "auxv.h" /* Forward declarations. */ extern const struct sym_fns elf_sym_fns_gdb_index; @@ -190,7 +189,8 @@ elf_locate_sections (bfd *ignore_abfd, asection *sectp, void *eip) } static struct minimal_symbol * -record_minimal_symbol (const char *name, int name_len, int copy_name, +record_minimal_symbol (minimal_symbol_reader &reader, + const char *name, int name_len, bool copy_name, CORE_ADDR address, enum minimal_symbol_type ms_type, asection *bfd_section, struct objfile *objfile) @@ -201,11 +201,10 @@ record_minimal_symbol (const char *name, int name_len, int copy_name, || ms_type == mst_text_gnu_ifunc) address = gdbarch_addr_bits_remove (gdbarch, address); - return prim_record_minimal_symbol_full (name, name_len, copy_name, address, - ms_type, - gdb_bfd_section_index (objfile->obfd, - bfd_section), - objfile); + return reader.record_full (name, name_len, copy_name, address, + ms_type, + gdb_bfd_section_index (objfile->obfd, + bfd_section)); } /* Read the symbol table of an ELF file. @@ -225,15 +224,15 @@ record_minimal_symbol (const char *name, int name_len, int copy_name, #define ST_SYNTHETIC 2 static void -elf_symtab_read (struct objfile *objfile, int type, +elf_symtab_read (minimal_symbol_reader &reader, + struct objfile *objfile, int type, long number_of_symbols, asymbol **symbol_table, - int copy_names) + bool copy_names) { struct gdbarch *gdbarch = get_objfile_arch (objfile); asymbol *sym; long i; CORE_ADDR symaddr; - CORE_ADDR offset; enum minimal_symbol_type ms_type; /* Name of the last file symbol. This is either a constant string or is saved on the objfile's filename cache. */ @@ -263,8 +262,6 @@ elf_symtab_read (struct objfile *objfile, int type, continue; } - offset = ANOFFSET (objfile->section_offsets, - gdb_bfd_section_index (objfile->obfd, sym->section)); if (type == ST_DYNAMIC && sym->section == bfd_und_section_ptr && (sym->flags & BSF_FUNCTION)) @@ -320,7 +317,7 @@ elf_symtab_read (struct objfile *objfile, int type, continue; msym = record_minimal_symbol - (sym->name, strlen (sym->name), copy_names, + (reader, sym->name, strlen (sym->name), copy_names, symaddr, mst_solib_trampoline, sect, objfile); if (msym != NULL) { @@ -460,7 +457,7 @@ elf_symtab_read (struct objfile *objfile, int type, continue; /* Skip this symbol. */ } msym = record_minimal_symbol - (sym->name, strlen (sym->name), copy_names, symaddr, + (reader, sym->name, strlen (sym->name), copy_names, symaddr, ms_type, sym->section, objfile); if (msym) @@ -489,7 +486,7 @@ elf_symtab_read (struct objfile *objfile, int type, { int len = atsign - sym->name; - record_minimal_symbol (sym->name, len, 1, symaddr, + record_minimal_symbol (reader, sym->name, len, true, symaddr, ms_type, sym->section, objfile); } } @@ -506,8 +503,8 @@ elf_symtab_read (struct objfile *objfile, int type, { struct minimal_symbol *mtramp; - mtramp = record_minimal_symbol (sym->name, len - 4, 1, - symaddr, + mtramp = record_minimal_symbol (reader, sym->name, len - 4, + true, symaddr, mst_solib_trampoline, sym->section, objfile); if (mtramp) @@ -533,16 +530,14 @@ elf_symtab_read (struct objfile *objfile, int type, DYN_SYMBOL_TABLE is no longer easily available for OBJFILE. */ static void -elf_rel_plt_read (struct objfile *objfile, asymbol **dyn_symbol_table) +elf_rel_plt_read (minimal_symbol_reader &reader, + struct objfile *objfile, asymbol **dyn_symbol_table) { bfd *obfd = objfile->obfd; const struct elf_backend_data *bed = get_elf_backend_data (obfd); asection *plt, *relplt, *got_plt; 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 = get_objfile_arch (objfile); struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; size_t ptr_size = TYPE_LENGTH (ptr_type); @@ -576,7 +571,7 @@ elf_rel_plt_read (struct objfile *objfile, asymbol **dyn_symbol_table) if (! bed->s->slurp_reloc_table (obfd, relplt, dyn_symbol_table, TRUE)) return; - back_to = make_cleanup (free_current_contents, &string_buffer); + std::string string_buffer; reloc_count = relplt->size / elf_section_data (relplt)->this_hdr.sh_entsize; for (reloc = 0; reloc < reloc_count; reloc++) @@ -584,11 +579,10 @@ elf_rel_plt_read (struct objfile *objfile, asymbol **dyn_symbol_table) const char *name; struct minimal_symbol *msym; CORE_ADDR address; + const char *got_suffix = SYMBOL_GOT_PLT_SUFFIX; const size_t got_suffix_len = strlen (SYMBOL_GOT_PLT_SUFFIX); - size_t name_len; name = bfd_asymbol_name (*relplt->relocation[reloc].sym_ptr_ptr); - name_len = strlen (name); address = relplt->relocation[reloc].address; /* Does the pointer reside in the .got.plt section? */ @@ -601,23 +595,16 @@ elf_rel_plt_read (struct objfile *objfile, asymbol **dyn_symbol_table) OBJFILE the symbol is undefined and the objfile having NAME defined may not yet have been loaded. */ - if (string_buffer_size < name_len + got_suffix_len + 1) - { - string_buffer_size = 2 * (name_len + got_suffix_len); - string_buffer = (char *) xrealloc (string_buffer, string_buffer_size); - } - memcpy (string_buffer, name, name_len); - memcpy (&string_buffer[name_len], SYMBOL_GOT_PLT_SUFFIX, - got_suffix_len + 1); + string_buffer.assign (name); + string_buffer.append (got_suffix, got_suffix + got_suffix_len); - msym = record_minimal_symbol (string_buffer, name_len + got_suffix_len, - 1, address, mst_slot_got_plt, got_plt, + msym = record_minimal_symbol (reader, string_buffer.c_str (), + string_buffer.size (), + true, address, mst_slot_got_plt, got_plt, objfile); if (msym) SET_MSYMBOL_SIZE (msym, ptr_size); } - - do_cleanups (back_to); } /* The data pointer is htab_t for gnu_ifunc_record_cache_unchecked. */ @@ -863,6 +850,8 @@ elf_gnu_ifunc_resolve_addr (struct gdbarch *gdbarch, CORE_ADDR pc) CORE_ADDR start_at_pc, address; struct type *func_func_type = builtin_type (gdbarch)->builtin_func_func; struct value *function, *address_val; + CORE_ADDR hwcap = 0; + struct value *hwcap_val; /* Try first any non-intrusive methods without an inferior call. */ @@ -876,12 +865,17 @@ elf_gnu_ifunc_resolve_addr (struct gdbarch *gdbarch, CORE_ADDR pc) name_at_pc = NULL; function = allocate_value (func_func_type); + VALUE_LVAL (function) = lval_memory; set_value_address (function, pc); - /* STT_GNU_IFUNC resolver functions have no parameters. FUNCTION is the - function entry address. ADDRESS may be a function descriptor. */ + /* STT_GNU_IFUNC resolver functions usually receive the HWCAP vector as + parameter. FUNCTION is the function entry address. ADDRESS may be a + function descriptor. */ - address_val = call_function_by_hand (function, 0, NULL); + target_auxv_search (¤t_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 = value_as_address (address_val); address = gdbarch_convert_from_func_ptr_addr (gdbarch, address, ¤t_target); @@ -902,7 +896,7 @@ elf_gnu_ifunc_resolver_stop (struct breakpoint *b) 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 = pid_to_thread_id (inferior_ptid); + int thread_id = ptid_to_global_thread_id (inferior_ptid); gdb_assert (b->type == bp_gnu_ifunc_resolver); @@ -921,19 +915,18 @@ elf_gnu_ifunc_resolver_stop (struct breakpoint *b) if (b_return == b) { - struct symtab_and_line sal; - /* No need to call find_pc_line for symbols resolving as this is only a helper breakpointer never shown to the user. */ - init_sal (&sal); + symtab_and_line sal; sal.pspace = current_inferior ()->pspace; sal.pc = prev_pc; sal.section = find_pc_overlay (sal.pc); sal.explicit_pc = 1; - b_return = set_momentary_breakpoint (get_frame_arch (prev_frame), sal, - prev_frame_id, - bp_gnu_ifunc_resolver_return); + b_return + = set_momentary_breakpoint (get_frame_arch (prev_frame), sal, + prev_frame_id, + bp_gnu_ifunc_resolver_return).release (); /* set_momentary_breakpoint invalidates PREV_FRAME. */ prev_frame = NULL; @@ -957,8 +950,6 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b) struct value *func_func; struct value *value; CORE_ADDR resolved_address, resolved_pc; - struct symtab_and_line sal; - struct symtabs_and_lines sals, sals_end; gdb_assert (b->type == bp_gnu_ifunc_resolver_return); @@ -985,6 +976,7 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b) gdb_assert (b->loc->next == NULL); func_func = allocate_value (func_func_type); + VALUE_LVAL (func_func) = lval_memory; set_value_address (func_func, b->loc->related_address); value = allocate_value (value_type); @@ -997,16 +989,12 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b) resolved_pc = gdbarch_addr_bits_remove (gdbarch, resolved_pc); gdb_assert (current_program_space == b->pspace || b->pspace == NULL); - elf_gnu_ifunc_record_cache (event_location_to_string (b->location), + elf_gnu_ifunc_record_cache (event_location_to_string (b->location.get ()), resolved_pc); - sal = find_pc_line (resolved_pc, 0); - sals.nelts = 1; - sals.sals = &sal; - sals_end.nelts = 0; - b->type = bp_breakpoint; - update_breakpoint_locations (b, sals, sals_end); + update_breakpoint_locations (b, current_program_space, + find_pc_line (resolved_pc, 0), {}); } /* A helper function for elf_symfile_read that reads the minimal @@ -1017,7 +1005,6 @@ elf_read_minimal_symbols (struct objfile *objfile, int symfile_flags, const struct elfinfo *ei) { bfd *synth_abfd, *abfd = objfile->obfd; - struct cleanup *back_to; long symcount = 0, dynsymcount = 0, synthcount, storage_needed; asymbol **symbol_table = NULL, **dyn_symbol_table = NULL; asymbol *synthsyms; @@ -1045,8 +1032,7 @@ elf_read_minimal_symbols (struct objfile *objfile, int symfile_flags, return; } - init_minimal_symbol_collection (); - back_to = make_cleanup_discard_minimal_symbols (); + minimal_symbol_reader reader (objfile); /* Allocate struct to keep track of the symfile. */ dbx = XCNEW (struct dbx_symfile_info); @@ -1073,7 +1059,8 @@ elf_read_minimal_symbols (struct objfile *objfile, int symfile_flags, bfd_get_filename (objfile->obfd), bfd_errmsg (bfd_get_error ())); - elf_symtab_read (objfile, ST_REGULAR, symcount, symbol_table, 0); + elf_symtab_read (reader, objfile, ST_REGULAR, symcount, symbol_table, + false); } /* Add the dynamic symbols. */ @@ -1098,9 +1085,10 @@ elf_read_minimal_symbols (struct objfile *objfile, int symfile_flags, bfd_get_filename (objfile->obfd), bfd_errmsg (bfd_get_error ())); - elf_symtab_read (objfile, ST_DYNAMIC, dynsymcount, dyn_symbol_table, 0); + elf_symtab_read (reader, objfile, ST_DYNAMIC, dynsymcount, + dyn_symbol_table, false); - elf_rel_plt_read (objfile, dyn_symbol_table); + elf_rel_plt_read (reader, objfile, dyn_symbol_table); } /* Contrary to binutils --strip-debug/--only-keep-debug the strip command from @@ -1127,16 +1115,17 @@ elf_read_minimal_symbols (struct objfile *objfile, int symfile_flags, &synthsyms); if (synthcount > 0) { - asymbol **synth_symbol_table; long i; - make_cleanup (xfree, synthsyms); - synth_symbol_table = XNEWVEC (asymbol *, synthcount); + std::unique_ptr + synth_symbol_table (new asymbol *[synthcount]); for (i = 0; i < synthcount; i++) synth_symbol_table[i] = synthsyms + i; - make_cleanup (xfree, synth_symbol_table); - elf_symtab_read (objfile, ST_SYNTHETIC, synthcount, - synth_symbol_table, 1); + elf_symtab_read (reader, objfile, ST_SYNTHETIC, synthcount, + synth_symbol_table.get (), true); + + xfree (synthsyms); + synthsyms = NULL; } /* Install any minimal symbols that have been collected as the current @@ -1145,8 +1134,7 @@ elf_read_minimal_symbols (struct objfile *objfile, int symfile_flags, responsibility to install them. "mdebug" appears to be the only one which will do this. */ - install_minimal_symbols (objfile); - do_cleanups (back_to); + reader.install (); if (symtab_create_debug) fprintf_unfiltered (gdb_stdlog, "Done reading minimal symbols.\n"); @@ -1177,7 +1165,7 @@ elf_read_minimal_symbols (struct objfile *objfile, int symfile_flags, capability even for files compiled without -g. */ static void -elf_symfile_read (struct objfile *objfile, int symfile_flags) +elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) { bfd *abfd = objfile->obfd; struct elfinfo ei; @@ -1259,21 +1247,18 @@ elf_symfile_read (struct objfile *objfile, int symfile_flags) && objfile->separate_debug_objfile == NULL && objfile->separate_debug_objfile_backlink == NULL) { - char *debugfile; - - debugfile = find_separate_debug_file_by_buildid (objfile); + gdb::unique_xmalloc_ptr debugfile + (find_separate_debug_file_by_buildid (objfile)); if (debugfile == NULL) - debugfile = find_separate_debug_file_by_debuglink (objfile); + debugfile.reset (find_separate_debug_file_by_debuglink (objfile)); - if (debugfile) + if (debugfile != NULL) { - struct cleanup *cleanup = make_cleanup (xfree, debugfile); - bfd *abfd = symfile_bfd_open (debugfile); + gdb_bfd_ref_ptr abfd (symfile_bfd_open (debugfile.get ())); - make_cleanup_bfd_unref (abfd); - symbol_file_add_separate (abfd, debugfile, symfile_flags, objfile); - do_cleanups (cleanup); + symbol_file_add_separate (abfd.get (), debugfile.get (), + symfile_flags, objfile); } } } @@ -1325,35 +1310,27 @@ elf_symfile_init (struct objfile *objfile) /* Implementation of `sym_get_probes', as documented in symfile.h. */ -static VEC (probe_p) * +static const std::vector & elf_get_probes (struct objfile *objfile) { - VEC (probe_p) *probes_per_bfd; + std::vector *probes_per_bfd; /* Have we parsed this objfile's probes already? */ - probes_per_bfd = (VEC (probe_p) *) bfd_data (objfile->obfd, probe_key); + probes_per_bfd = (std::vector *) bfd_data (objfile->obfd, probe_key); - if (!probes_per_bfd) + if (probes_per_bfd == NULL) { - int ix; - const struct probe_ops *probe_ops; + probes_per_bfd = new std::vector; /* 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_bfd, objfile); - - if (probes_per_bfd == NULL) - { - VEC_reserve (probe_p, probes_per_bfd, 1); - gdb_assert (probes_per_bfd != NULL); - } + 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; + return *probes_per_bfd; } /* Helper function used to free the space allocated for storing SystemTap @@ -1362,14 +1339,12 @@ elf_get_probes (struct objfile *objfile) static void probe_key_free (bfd *abfd, void *d) { - int ix; - VEC (probe_p) *probes = (VEC (probe_p) *) d; - struct probe *probe; + std::vector *probes = (std::vector *) d; - for (ix = 0; VEC_iterate (probe_p, probes, ix, probe); ix++) - probe->pops->destroy (probe); + for (probe *p : *probes) + delete p; - VEC_free (probe_p, probes); + delete probes; }