/* Read ELF (Executable and Linking Format) object files for GDB.
- Copyright (C) 1991-2018 Free Software Foundation, Inc.
+ Copyright (C) 1991-2019 Free Software Foundation, Inc.
Written by Fred Fish at Cygnus Support.
#include "symtab.h"
#include "symfile.h"
#include "objfiles.h"
-#include "buildsym.h"
#include "stabsread.h"
#include "gdb-stabs.h"
#include "complaints.h"
#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"
+#include "mdebugread.h"
/* Forward declarations. */
extern const struct sym_fns elf_sym_fns_gdb_index;
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)
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;
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;
{
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;
}
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);
elf_gnu_ifunc_record_cache (const char *name, CORE_ADDR addr)
{
struct bound_minimal_symbol msym;
- asection *sect;
struct objfile *objfile;
htab_t htab;
struct elf_gnu_ifunc_cache entry_local, *entry_p;
return 0;
if (BMSYMBOL_VALUE_ADDRESS (msym) != addr)
return 0;
- /* minimal symbols have always SYMBOL_OBJ_SECTION non-NULL. */
- sect = MSYMBOL_OBJ_SECTION (msym.objfile, msym.minsym)->the_bfd_section;
objfile = msym.objfile;
/* If .plt jumps back to .plt the symbol is still deferred for later
- resolution and it has no use for GDB. Besides ".text" this symbol can
- reside also in ".opd" for ppc64 function descriptor. */
- if (strcmp (bfd_get_section_name (objfile->obfd, sect), ".plt") == 0)
+ resolution and it has no use for GDB. */
+ const char *target_name = MSYMBOL_LINKAGE_NAME (msym.minsym);
+ size_t len = strlen (target_name);
+
+ /* Note we check the symbol's name instead of checking whether the
+ symbol is in the .plt section because some systems have @plt
+ symbols in the .text section. */
+ if (len > 4 && strcmp (target_name + len - 4, "@plt") == 0)
return 0;
htab = (htab_t) objfile_data (objfile, elf_objfile_gnu_ifunc_cache_data);
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;
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);
continue;
addr = extract_typed_address (buf, ptr_type);
addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
- ¤t_target);
+ current_top_target ());
addr = gdbarch_addr_bits_remove (gdbarch, addr);
if (elf_gnu_ifunc_record_cache (name, addr))
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_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_top_target ());
address = gdbarch_addr_bits_remove (gdbarch, address);
if (name_at_pc)
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);
static void
elf_gnu_ifunc_resolver_return_stop (struct 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;
resolved_address = value_as_address (value);
resolved_pc = gdbarch_convert_from_func_ptr_addr (gdbarch,
resolved_address,
- ¤t_target);
+ current_top_target ());
resolved_pc = gdbarch_addr_bits_remove (gdbarch, resolved_pc);
gdb_assert (current_program_space == b->pspace || b->pspace == NULL);
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
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);
}
}
elf_new_init (struct objfile *ignore)
{
stabsread_new_init ();
- buildsym_new_init ();
}
/* Perform any local cleanups required when we are done with a particular
static void
elf_symfile_finish (struct objfile *objfile)
{
- dwarf2_free_objfile (objfile);
}
/* ELF specific initialization routine for reading symbols. */