From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1805) id B19A23858406; Tue, 18 Oct 2022 13:25:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B19A23858406 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1666099548; bh=wQ7btKVEtHD4hoX48gdf+64GFVF/4MSt74c9zLuOlO8=; h=From:To:Subject:Date:From; b=mloXrOg5HvMPJeHmMkP1foY8f78lhu3/3C2K/exaioVquZ00cXQXG1QE7uYNyqw/B Zw7zIWYkukw93+naa4kdup7m0dgMBw0mvMjGKzxBmVF4SIH6+SM8joaWG/E86/pV+E 8Srv/L1SKo1bwzldOIpgRwxVa05rWf4MRAAvD2Ro= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Markus Metzger To: gdb-cvs@sourceware.org Subject: [binutils-gdb] gdb: update gnu ifunc resolve X-Act-Checkin: binutils-gdb X-Git-Author: Markus Metzger X-Git-Refname: refs/heads/master X-Git-Oldrev: 531bd03892bbf95f346819006b365c0b0ccb6d06 X-Git-Newrev: 1dc9084f5e95fd9a1f2f0e9baf9c6e52c5a5ee29 Message-Id: <20221018132548.B19A23858406@sourceware.org> Date: Tue, 18 Oct 2022 13:25:48 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D1dc9084f5e95= fd9a1f2f0e9baf9c6e52c5a5ee29 commit 1dc9084f5e95fd9a1f2f0e9baf9c6e52c5a5ee29 Author: Markus Metzger Date: Mon May 30 09:35:29 2022 +0200 gdb: update gnu ifunc resolve =20 Update elf_gnu_ifunc_resolve_by_cache() and elf_gnu_ifunc_resolve_by_go= t() to use gdbarch_iterate_over_objfiles_in_search_order() in order to restrict the objfile traversal to the initial namespace. =20 In order to extend this to other namespaces, we'd need to provide conte= xt, e.g. via an objfile inside that namespace. Diff: --- gdb/elfread.c | 153 +++++++++++++++++++++++++++++++++---------------------= ---- 1 file changed, 87 insertions(+), 66 deletions(-) diff --git a/gdb/elfread.c b/gdb/elfread.c index 88f5a713c4f..d7fa5a6de09 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -769,32 +769,42 @@ elf_gnu_ifunc_record_cache (const char *name, CORE_AD= DR 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 =3D elf_objfile_gnu_ifunc_cache_data.get (objfile); - if (htab =3D=3D NULL) - continue; - - entry_p =3D ((struct elf_gnu_ifunc_cache *) - alloca (sizeof (*entry_p) + strlen (name))); - strcpy (entry_p->name, name); - - slot =3D htab_find_slot (htab, entry_p, NO_INSERT); - if (slot =3D=3D NULL) - continue; - entry_p =3D (struct elf_gnu_ifunc_cache *) *slot; - gdb_assert (entry_p !=3D NULL); - - if (addr_p) - *addr_p =3D entry_p->addr; - return 1; - } - - return 0; + int found =3D 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 =3D elf_objfile_gnu_ifunc_cache_data.get (objfile); + if (htab =3D=3D NULL) + return 0; + + entry_p =3D ((elf_gnu_ifunc_cache *) + alloca (sizeof (*entry_p) + strlen (name))); + strcpy (entry_p->name, name); + + slot =3D htab_find_slot (htab, entry_p, NO_INSERT); + if (slot =3D=3D NULL) + return 0; + entry_p =3D (elf_gnu_ifunc_cache *) *slot; + gdb_assert (entry_p !=3D NULL); + + if (addr_p) + *addr_p =3D entry_p->addr; + + found =3D 1; + return 1; + }, nullptr); + + return found; } =20 /* Try to find the target resolved function entry address of a STT_GNU_IFU= NC @@ -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 =3D strlen (SYMBOL_GOT_PLT_SUFFIX); + int found =3D 0; =20 name_got_plt =3D (char *) alloca (strlen (name) + got_suffix_len + 1); sprintf (name_got_plt, "%s" SYMBOL_GOT_PLT_SUFFIX, name); =20 - for (objfile *objfile : current_program_space->objfiles ()) - { - bfd *obfd =3D objfile->obfd.get (); - struct gdbarch *gdbarch =3D objfile->arch (); - struct type *ptr_type =3D builtin_type (gdbarch)->builtin_data_ptr; - size_t ptr_size =3D ptr_type->length (); - CORE_ADDR pointer_address, addr; - asection *plt; - gdb_byte *buf =3D (gdb_byte *) alloca (ptr_size); - struct bound_minimal_symbol msym; - - msym =3D lookup_minimal_symbol (name_got_plt, NULL, objfile); - if (msym.minsym =3D=3D NULL) - continue; - if (msym.minsym->type () !=3D mst_slot_got_plt) - continue; - pointer_address =3D msym.value_address (); - - plt =3D bfd_get_section_by_name (obfd, ".plt"); - if (plt =3D=3D NULL) - continue; - - if (msym.minsym->size () !=3D ptr_size) - continue; - if (target_read_memory (pointer_address, buf, ptr_size) !=3D 0) - continue; - addr =3D extract_typed_address (buf, ptr_type); - addr =3D gdbarch_convert_from_func_ptr_addr - (gdbarch, addr, current_inferior ()->top_target ()); - addr =3D gdbarch_addr_bits_remove (gdbarch, addr); - - if (elf_gnu_ifunc_record_cache (name, addr)) - { - if (addr_p !=3D NULL) - *addr_p =3D 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 =3D objfile->obfd.get (); + struct gdbarch *gdbarch =3D objfile->arch (); + type *ptr_type =3D builtin_type (gdbarch)->builtin_data_ptr; + size_t ptr_size =3D ptr_type->length (); + CORE_ADDR pointer_address, addr; + asection *plt; + gdb_byte *buf =3D (gdb_byte *) alloca (ptr_size); + bound_minimal_symbol msym; + + msym =3D lookup_minimal_symbol (name_got_plt, NULL, objfile); + if (msym.minsym =3D=3D NULL) + return 0; + if (msym.minsym->type () !=3D mst_slot_got_plt) + return 0; + pointer_address =3D msym.value_address (); + + plt =3D bfd_get_section_by_name (obfd, ".plt"); + if (plt =3D=3D NULL) + return 0; + + if (msym.minsym->size () !=3D ptr_size) + return 0; + if (target_read_memory (pointer_address, buf, ptr_size) !=3D 0) + return 0; + addr =3D extract_typed_address (buf, ptr_type); + addr =3D gdbarch_convert_from_func_ptr_addr + (gdbarch, addr, current_inferior ()->top_target ()); + addr =3D gdbarch_addr_bits_remove (gdbarch, addr); + + if (elf_gnu_ifunc_record_cache (name, addr)) + { + if (addr_p !=3D NULL) + *addr_p =3D addr; + + found =3D 1; + return 1; + } + + return 0; + }, nullptr); + + return found; } =20 /* Try to find the target resolved function entry address of a STT_GNU_IFU= NC