From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by sourceware.org (Postfix) with ESMTPS id 660CD384B833 for ; Thu, 2 Jun 2022 14:29:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 660CD384B833 X-IronPort-AV: E=McAfee;i="6400,9594,10365"; a="276039300" X-IronPort-AV: E=Sophos;i="5.91,271,1647327600"; d="scan'208";a="276039300" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Jun 2022 07:29:24 -0700 X-IronPort-AV: E=Sophos;i="5.91,271,1647327600"; d="scan'208";a="582112569" Received: from labpc2407.iul.intel.com (HELO localhost) ([172.28.50.61]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Jun 2022 07:29:23 -0700 From: Markus Metzger To: gdb-patches@sourceware.org Subject: [PATCH v5 14/15] gdb: update gnu ifunc resolve Date: Thu, 2 Jun 2022 15:25:13 +0200 Message-Id: <20220602132514.957983-15-markus.t.metzger@intel.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20220602132514.957983-1-markus.t.metzger@intel.com> References: <20220602132514.957983-1-markus.t.metzger@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-9.2 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_STOCKGEN, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 02 Jun 2022 14:29:27 -0000 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. --- gdb/elfread.c | 153 ++++++++++++++++++++++++++++---------------------- 1 file changed, 87 insertions(+), 66 deletions(-) diff --git a/gdb/elfread.c b/gdb/elfread.c index 32cb27c8967..c097d272a49 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; - 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; - 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; + struct gdbarch *gdbarch = objfile->arch (); + type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; + size_t ptr_size = TYPE_LENGTH (ptr_type); + 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 -- 2.35.3 Intel Deutschland GmbH Registered Address: Am Campeon 10, 85579 Neubiberg, Germany Tel: +49 89 99 8853-0, www.intel.de Managing Directors: Christin Eisenschmid, Sharon Heck, Tiffany Doon Silva Chairperson of the Supervisory Board: Nicole Lau Registered Office: Munich Commercial Register: Amtsgericht Muenchen HRB 186928