aboutsummaryrefslogtreecommitdiff
path: root/gdb/elfread.c
diff options
context:
space:
mode:
authorMarkus Metzger <markus.t.metzger@intel.com>2022-05-30 09:35:29 +0200
committerMarkus Metzger <markus.t.metzger@intel.com>2022-10-18 14:16:10 +0200
commit1dc9084f5e95fd9a1f2f0e9baf9c6e52c5a5ee29 (patch)
tree943425b5c2f0b467b54b9a514d69c8779de15423 /gdb/elfread.c
parent531bd03892bbf95f346819006b365c0b0ccb6d06 (diff)
downloadgdb-1dc9084f5e95fd9a1f2f0e9baf9c6e52c5a5ee29.zip
gdb-1dc9084f5e95fd9a1f2f0e9baf9c6e52c5a5ee29.tar.gz
gdb-1dc9084f5e95fd9a1f2f0e9baf9c6e52c5a5ee29.tar.bz2
gdb: update gnu ifunc resolve
Update elf_gnu_ifunc_resolve_by_cache() and elf_gnu_ifunc_resolve_by_got() to use gdbarch_iterate_over_objfiles_in_search_order() in order to restrict the objfile traversal to the initial namespace. In order to extend this to other namespaces, we'd need to provide context, e.g. via an objfile inside that namespace.
Diffstat (limited to 'gdb/elfread.c')
-rw-r--r--gdb/elfread.c153
1 files changed, 87 insertions, 66 deletions
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 88f5a71..d7fa5a6 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -769,32 +769,42 @@ 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)
{
- for (objfile *objfile : current_program_space->objfiles ())
- {
- htab_t htab;
- struct elf_gnu_ifunc_cache *entry_p;
- void **slot;
-
- htab = elf_objfile_gnu_ifunc_cache_data.get (objfile);
- if (htab == NULL)
- continue;
-
- entry_p = ((struct elf_gnu_ifunc_cache *)
- alloca (sizeof (*entry_p) + strlen (name)));
- strcpy (entry_p->name, name);
-
- slot = htab_find_slot (htab, entry_p, NO_INSERT);
- if (slot == NULL)
- continue;
- entry_p = (struct elf_gnu_ifunc_cache *) *slot;
- gdb_assert (entry_p != NULL);
-
- if (addr_p)
- *addr_p = entry_p->addr;
- return 1;
- }
-
- return 0;
+ int found = 0;
+
+ /* FIXME: we only search the initial namespace.
+
+ To search other namespaces, we would need to provide context, e.g. in
+ form of an objfile in that namespace. */
+ gdbarch_iterate_over_objfiles_in_search_order
+ (target_gdbarch (),
+ [name, &addr_p, &found] (struct objfile *objfile)
+ {
+ htab_t htab;
+ elf_gnu_ifunc_cache *entry_p;
+ void **slot;
+
+ htab = elf_objfile_gnu_ifunc_cache_data.get (objfile);
+ if (htab == NULL)
+ return 0;
+
+ entry_p = ((elf_gnu_ifunc_cache *)
+ alloca (sizeof (*entry_p) + strlen (name)));
+ strcpy (entry_p->name, name);
+
+ slot = htab_find_slot (htab, entry_p, NO_INSERT);
+ if (slot == NULL)
+ return 0;
+ entry_p = (elf_gnu_ifunc_cache *) *slot;
+ gdb_assert (entry_p != NULL);
+
+ if (addr_p)
+ *addr_p = entry_p->addr;
+
+ found = 1;
+ return 1;
+ }, nullptr);
+
+ return found;
}
/* Try to find the target resolved function entry address of a STT_GNU_IFUNC
@@ -810,50 +820,61 @@ elf_gnu_ifunc_resolve_by_got (const char *name, CORE_ADDR *addr_p)
{
char *name_got_plt;
const size_t got_suffix_len = strlen (SYMBOL_GOT_PLT_SUFFIX);
+ int found = 0;
name_got_plt = (char *) alloca (strlen (name) + got_suffix_len + 1);
sprintf (name_got_plt, "%s" SYMBOL_GOT_PLT_SUFFIX, name);
- for (objfile *objfile : current_program_space->objfiles ())
- {
- bfd *obfd = objfile->obfd.get ();
- struct gdbarch *gdbarch = objfile->arch ();
- struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
- size_t ptr_size = ptr_type->length ();
- CORE_ADDR pointer_address, addr;
- asection *plt;
- gdb_byte *buf = (gdb_byte *) alloca (ptr_size);
- struct bound_minimal_symbol msym;
-
- msym = lookup_minimal_symbol (name_got_plt, NULL, objfile);
- if (msym.minsym == NULL)
- continue;
- if (msym.minsym->type () != mst_slot_got_plt)
- continue;
- pointer_address = msym.value_address ();
-
- plt = bfd_get_section_by_name (obfd, ".plt");
- if (plt == NULL)
- continue;
-
- 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, current_inferior ()->top_target ());
- addr = gdbarch_addr_bits_remove (gdbarch, addr);
-
- if (elf_gnu_ifunc_record_cache (name, addr))
- {
- if (addr_p != NULL)
- *addr_p = addr;
- return 1;
- }
- }
-
- return 0;
+ /* FIXME: we only search the initial namespace.
+
+ To search other namespaces, we would need to provide context, e.g. in
+ form of an objfile in that namespace. */
+ gdbarch_iterate_over_objfiles_in_search_order
+ (target_gdbarch (),
+ [name, name_got_plt, &addr_p, &found] (struct objfile *objfile)
+ {
+ bfd *obfd = objfile->obfd.get ();
+ struct gdbarch *gdbarch = objfile->arch ();
+ type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
+ size_t ptr_size = ptr_type->length ();
+ CORE_ADDR pointer_address, addr;
+ asection *plt;
+ gdb_byte *buf = (gdb_byte *) alloca (ptr_size);
+ bound_minimal_symbol msym;
+
+ msym = lookup_minimal_symbol (name_got_plt, NULL, objfile);
+ if (msym.minsym == NULL)
+ return 0;
+ if (msym.minsym->type () != mst_slot_got_plt)
+ return 0;
+ pointer_address = msym.value_address ();
+
+ plt = bfd_get_section_by_name (obfd, ".plt");
+ if (plt == NULL)
+ return 0;
+
+ if (msym.minsym->size () != ptr_size)
+ return 0;
+ if (target_read_memory (pointer_address, buf, ptr_size) != 0)
+ return 0;
+ addr = extract_typed_address (buf, ptr_type);
+ 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))
+ {
+ if (addr_p != NULL)
+ *addr_p = addr;
+
+ found = 1;
+ return 1;
+ }
+
+ return 0;
+ }, nullptr);
+
+ return found;
}
/* Try to find the target resolved function entry address of a STT_GNU_IFUNC