From patchwork Sun Feb 18 01:10:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 85928 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 40F2A386076C for ; Sun, 18 Feb 2024 01:12:17 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from omta36.uswest2.a.cloudfilter.net (omta36.uswest2.a.cloudfilter.net [35.89.44.35]) by sourceware.org (Postfix) with ESMTPS id 60B873860007 for ; Sun, 18 Feb 2024 01:10:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 60B873860007 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=tromey.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=tromey.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 60B873860007 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=35.89.44.35 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708218615; cv=none; b=cW3lALlwAhjPagBPINftLp2920+bDY0Cp8DrxV+LRlGxrR6xvR3d3FeLlQHyvHcSs9F3y+M1Zhe4aGNM/6T4mW9RKZ9iMgAchZnp4PYM3Oz/CxTQAdVR7dRMX2qY6xponKpRjrUFincj/CB5P989g6daHJ98eIAgM9dV157v6Rc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708218615; c=relaxed/simple; bh=uf+uoRPqnmRIRoW2jS0n/VHDTDjMJD2Fc9LDEHOmX9E=; h=DKIM-Signature:From:Date:Subject:MIME-Version:Message-Id:To; b=eBgzvtQqZ1gCVR4XyfI2Fqhdw3/9cbuJzRn62OBnwfxyP4a6C5C8KVFl1C05UIXKeibg0ZtlVRxPnWAJULHUfgfj6S8OogS0mQSyMsN5RolULSiIdOELppLqMwwdmKnclZa6v+jWcrA0gABjauYzwPrNEpiCSwwSEsgi0x0bkts= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from eig-obgw-5007a.ext.cloudfilter.net ([10.0.29.141]) by cmsmtp with ESMTPS id bU6lrnibxCF6GbVh0rOG2A; Sun, 18 Feb 2024 01:10:06 +0000 Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with ESMTPS id bVgzr8rMuZ4fIbVgzrKoP4; Sun, 18 Feb 2024 01:10:06 +0000 X-Authority-Analysis: v=2.4 cv=OPqE3jaB c=1 sm=1 tr=0 ts=65d158ee a=ApxJNpeYhEAb1aAlGBBbmA==:117 a=ApxJNpeYhEAb1aAlGBBbmA==:17 a=IkcTkHD0fZMA:10 a=k7vzHIieQBIA:10 a=Qbun_eYptAEA:10 a=Pn5-7-ASx1INwsF6yocA:9 a=UzzNDi2jNRczGI5y:21 a=QEXdDO2ut3YA:10 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tromey.com; s=default; h=To:In-Reply-To:References:Message-Id:Content-Transfer-Encoding: Content-Type:MIME-Version:Subject:Date:From:Sender:Reply-To:Cc:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=3aF3v6Jrn11Uw6jhttHSLRI4sA5dS0nlkzNgOmr91cc=; b=qdRNAkh+Ar/f2NgqR6u2KQLG86 wtc7eLX16avbagpkrBkddJmlQtnc6e12/d1DAirPbfj7cVTBxe8wUBp33hcetwo3b1qBzaM67bPnc Yax9bHXX6LQ/jR022HWqgDSkG; Received: from 71-211-170-195.hlrn.qwest.net ([71.211.170.195]:49770 helo=[192.168.0.21]) by box5379.bluehost.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96.2) (envelope-from ) id 1rbVgz-003IPy-03 for gdb-patches@sourceware.org; Sat, 17 Feb 2024 18:10:05 -0700 From: Tom Tromey Date: Sat, 17 Feb 2024 18:10:05 -0700 Subject: [PATCH 4/7] Add unrelocated overload of lookup_minimal_symbol_by_pc_section MIME-Version: 1.0 Message-Id: <20240217-dwarf-race-relocate-v1-4-d3d2d908c1e8@tromey.com> References: <20240217-dwarf-race-relocate-v1-0-d3d2d908c1e8@tromey.com> In-Reply-To: <20240217-dwarf-race-relocate-v1-0-d3d2d908c1e8@tromey.com> To: gdb-patches@sourceware.org X-Mailer: b4 0.12.4 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - box5379.bluehost.com X-AntiAbuse: Original Domain - sourceware.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - tromey.com X-BWhitelist: no X-Source-IP: 71.211.170.195 X-Source-L: No X-Exim-ID: 1rbVgz-003IPy-03 X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: 71-211-170-195.hlrn.qwest.net ([192.168.0.21]) [71.211.170.195]:49770 X-Source-Auth: tom+tromey.com X-Email-Count: 5 X-Org: HG=bhshared;ORG=bluehost; X-Source-Cap: ZWx5bnJvYmk7ZWx5bnJvYmk7Ym94NTM3OS5ibHVlaG9zdC5jb20= X-Local-Domain: yes X-CMAE-Envelope: MS4xfBEvvTH1dpy+P1RhVlNSSKuaFkrUsiA4uzQaNBCNzNNrI+KL2v68kqdhoM70wtxXDbrU74QRq8b8lL9nf2lN0tbYEyWDnG44DUa6+CcWrGRr4Kty7JcY X6yU0zYcPmKn3qgooamNAgk76xON1FjhZIt0JMLS4mvqpEXHHLqT3yjv1+A6yC68u5Vq/9mkRcWxcBgiOj4d74J1pZryGm5TQRA= X-Spam-Status: No, score=-3022.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, GIT_PATCH_0, JMQ_SPF_NEUTRAL, RCVD_IN_MSPIKE_H2, SCC_5_SHORT_WORD_LINES, SPF_HELO_NONE, SPF_PASS, 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.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org This refactors lookup_minimal_symbol_by_pc_section, pulling out the inner loop into a separate function. This function also does all its work using only the per-BFD object -- not the objfile. This overload is used in the next patch, but it seemed simpler to review as its own patch. --- gdb/minsyms.c | 437 ++++++++++++++++++++++++++++++++-------------------------- gdb/minsyms.h | 7 + 2 files changed, 250 insertions(+), 194 deletions(-) diff --git a/gdb/minsyms.c b/gdb/minsyms.c index 36ca11a0b94..2c8bf2a9f0b 100644 --- a/gdb/minsyms.c +++ b/gdb/minsyms.c @@ -747,6 +747,214 @@ msym_prefer_to_msym_type (lookup_msym_prefer prefer) gdb_assert_not_reached ("unhandled lookup_msym_prefer"); } +/* Worker function for the various public overloads. Looks in PER_BFD + for a symbol at UNREL_PC. PREVIOUS is an out parameter that is set + to the closest symbol appearing before UNREL_PC. WANT_TYPE + indicates which sections to look for. WRONG_SECTION is a predicate + that is passed a symbol to decide if it is in the wrong section for + some reason other than not matching WANT_TYPE. */ + +static minimal_symbol * +lookup_minimal_symbol_by_pc + (objfile_per_bfd_storage *per_bfd, + unrelocated_addr unrel_pc, + minimal_symbol **previous, + minimal_symbol_type want_type, + gdb::function_view wrong_section) +{ + /* If there is a minimal symbol table, go search it using a binary + search. */ + if (per_bfd->minimal_symbol_count == 0) + return nullptr; + + int best_zero_sized = -1; + minimal_symbol *best_symbol = nullptr; + + minimal_symbol *msymbol = per_bfd->msymbols.get (); + int lo = 0; + int hi = per_bfd->minimal_symbol_count - 1; + + /* This code assumes that the minimal symbols are sorted by + ascending address values. If the pc value is greater than or + equal to the first symbol's address, then some symbol in this + minimal symbol table is a suitable candidate for being the + "best" symbol. This includes the last real symbol, for cases + where the pc value is larger than any address in this vector. + + By iterating until the address associated with the current + hi index (the endpoint of the test interval) is less than + or equal to the desired pc value, we accomplish two things: + (1) the case where the pc value is larger than any minimal + symbol address is trivially solved, (2) the address associated + with the hi index is always the one we want when the iteration + terminates. In essence, we are iterating the test interval + down until the pc value is pushed out of it from the high end. + + Warning: this code is trickier than it would appear at first. */ + + if (unrel_pc >= msymbol[lo].unrelocated_address ()) + { + while (msymbol[hi].unrelocated_address () > unrel_pc) + { + /* pc is still strictly less than highest address. */ + /* Note "new" will always be >= lo. */ + int newobj = (lo + hi) / 2; + if ((msymbol[newobj].unrelocated_address () >= unrel_pc) + || (lo == newobj)) + { + hi = newobj; + } + else + { + lo = newobj; + } + } + + /* If we have multiple symbols at the same address, we want + hi to point to the last one. That way we can find the + right symbol if it has an index greater than hi. */ + while (hi < per_bfd->minimal_symbol_count - 1 + && (msymbol[hi].unrelocated_address () + == msymbol[hi + 1].unrelocated_address ())) + hi++; + + /* Skip various undesirable symbols. */ + while (hi >= 0) + { + /* Skip any absolute symbols. This is apparently + what adb and dbx do, and is needed for the CM-5. + There are two known possible problems: (1) on + ELF, apparently end, edata, etc. are absolute. + Not sure ignoring them here is a big deal, but if + we want to use them, the fix would go in + elfread.c. (2) I think shared library entry + points on the NeXT are absolute. If we want + special handling for this it probably should be + triggered by a special mst_abs_or_lib or some + such. */ + + if (msymbol[hi].type () == mst_abs) + { + hi--; + continue; + } + + /* Skip any symbol from the wrong section. */ + if (wrong_section (&msymbol[hi])) + { + hi--; + continue; + } + + /* If we are looking for a trampoline and this is a + text symbol, or the other way around, check the + preceding symbol too. If they are otherwise + identical prefer that one. */ + if (hi > 0 + && msymbol[hi].type () != want_type + && msymbol[hi - 1].type () == want_type + && (msymbol[hi].size () == msymbol[hi - 1].size ()) + && (msymbol[hi].unrelocated_address () + == msymbol[hi - 1].unrelocated_address ()) + && (msymbol[hi].section_index () + == msymbol[hi - 1].section_index ())) + { + hi--; + continue; + } + + /* If the minimal symbol has a zero size, save it + but keep scanning backwards looking for one with + a non-zero size. A zero size may mean that the + symbol isn't an object or function (e.g. a + label), or it may just mean that the size was not + specified. */ + if (msymbol[hi].size () == 0) + { + if (best_zero_sized == -1) + best_zero_sized = hi; + hi--; + continue; + } + + /* If we are past the end of the current symbol, try + the previous symbol if it has a larger overlapping + size. This happens on i686-pc-linux-gnu with glibc; + the nocancel variants of system calls are inside + the cancellable variants, but both have sizes. */ + if (hi > 0 + && msymbol[hi].size () != 0 + && unrel_pc >= msymbol[hi].unrelocated_end_address () + && unrel_pc < msymbol[hi - 1].unrelocated_end_address ()) + { + hi--; + continue; + } + + /* Otherwise, this symbol must be as good as we're going + to get. */ + break; + } + + /* If HI has a zero size, and best_zero_sized is set, + then we had two or more zero-sized symbols; prefer + the first one we found (which may have a higher + address). Also, if we ran off the end, be sure + to back up. */ + if (best_zero_sized != -1 + && (hi < 0 || msymbol[hi].size () == 0)) + hi = best_zero_sized; + + /* If the minimal symbol has a non-zero size, and this + PC appears to be outside the symbol's contents, then + refuse to use this symbol. If we found a zero-sized + symbol with an address greater than this symbol's, + use that instead. We assume that if symbols have + specified sizes, they do not overlap. */ + + if (hi >= 0 + && msymbol[hi].size () != 0 + && unrel_pc >= msymbol[hi].unrelocated_end_address ()) + { + if (best_zero_sized != -1) + hi = best_zero_sized; + else + { + /* If needed record this symbol as the closest + previous symbol. */ + if (*previous == nullptr + || (msymbol[hi].unrelocated_address () + > (*previous)->unrelocated_address ())) + *previous = &msymbol[hi]; + } + /* Done. */ + return best_symbol; + } + + if (hi >= 0 + && (best_symbol == nullptr + || (best_symbol->unrelocated_address () + < msymbol[hi].unrelocated_address ()))) + best_symbol = &msymbol[hi]; + } + + return best_symbol; +} + +/* See minsyms.h. */ + +minimal_symbol * +lookup_minimal_symbol_by_pc (objfile_per_bfd_storage *per_bfd, + unrelocated_addr addr) +{ + minimal_symbol *ignore = nullptr; + return lookup_minimal_symbol_by_pc (per_bfd, addr, &ignore, mst_text, + [] (minimal_symbol *msym) + { + return msym->type () != mst_text; + }); +} + /* See minsyms.h. Note that we need to look through ALL the minimal symbol tables @@ -760,10 +968,6 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc_in, struct obj_section *sectio lookup_msym_prefer prefer, bound_minimal_symbol *previous) { - int lo; - int hi; - int newobj; - struct minimal_symbol *msymbol; struct minimal_symbol *best_symbol = NULL; struct objfile *best_objfile = NULL; struct bound_minimal_symbol result; @@ -800,199 +1004,44 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc_in, struct obj_section *sectio if (!frob_address (objfile, pc_in, &unrel_pc)) continue; - /* If this objfile has a minimal symbol table, go search it - using a binary search. */ - - if (objfile->per_bfd->minimal_symbol_count > 0) + minimal_symbol *this_previous = nullptr; + minimal_symbol *minsym + = lookup_minimal_symbol_by_pc (objfile->per_bfd, unrel_pc, + &this_previous, want_type, + [&] (minimal_symbol *check_sym) + { + /* Some types of debug info, such as COFF, don't fill the + bfd_section member, so don't throw away symbols on those + platforms. */ + return (check_sym->obj_section (objfile) != nullptr + && !matching_obj_sections (check_sym->obj_section (objfile), + section)); + }); + + /* If needed record this symbol as the closest previous + symbol. */ + if (previous != nullptr) { - int best_zero_sized = -1; - - msymbol = objfile->per_bfd->msymbols.get (); - lo = 0; - hi = objfile->per_bfd->minimal_symbol_count - 1; - - /* This code assumes that the minimal symbols are sorted by - ascending address values. If the pc value is greater than or - equal to the first symbol's address, then some symbol in this - minimal symbol table is a suitable candidate for being the - "best" symbol. This includes the last real symbol, for cases - where the pc value is larger than any address in this vector. - - By iterating until the address associated with the current - hi index (the endpoint of the test interval) is less than - or equal to the desired pc value, we accomplish two things: - (1) the case where the pc value is larger than any minimal - symbol address is trivially solved, (2) the address associated - with the hi index is always the one we want when the iteration - terminates. In essence, we are iterating the test interval - down until the pc value is pushed out of it from the high end. - - Warning: this code is trickier than it would appear at first. */ - - if (unrel_pc >= msymbol[lo].unrelocated_address ()) + if (previous->minsym == nullptr + || (this_previous->unrelocated_address () + > previous->minsym->unrelocated_address ())) { - while (msymbol[hi].unrelocated_address () > unrel_pc) - { - /* pc is still strictly less than highest address. */ - /* Note "new" will always be >= lo. */ - newobj = (lo + hi) / 2; - if ((msymbol[newobj].unrelocated_address () >= unrel_pc) - || (lo == newobj)) - { - hi = newobj; - } - else - { - lo = newobj; - } - } - - /* If we have multiple symbols at the same address, we want - hi to point to the last one. That way we can find the - right symbol if it has an index greater than hi. */ - while (hi < objfile->per_bfd->minimal_symbol_count - 1 - && (msymbol[hi].unrelocated_address () - == msymbol[hi + 1].unrelocated_address ())) - hi++; - - /* Skip various undesirable symbols. */ - while (hi >= 0) - { - /* Skip any absolute symbols. This is apparently - what adb and dbx do, and is needed for the CM-5. - There are two known possible problems: (1) on - ELF, apparently end, edata, etc. are absolute. - Not sure ignoring them here is a big deal, but if - we want to use them, the fix would go in - elfread.c. (2) I think shared library entry - points on the NeXT are absolute. If we want - special handling for this it probably should be - triggered by a special mst_abs_or_lib or some - such. */ - - if (msymbol[hi].type () == mst_abs) - { - hi--; - continue; - } - - /* Skip any symbol from wrong section. */ - if (/* Some types of debug info, such as COFF, - don't fill the bfd_section member, so don't - throw away symbols on those platforms. */ - msymbol[hi].obj_section (objfile) != nullptr - && (!matching_obj_sections - (msymbol[hi].obj_section (objfile), - section))) - { - hi--; - continue; - } - - /* If we are looking for a trampoline and this is a - text symbol, or the other way around, check the - preceding symbol too. If they are otherwise - identical prefer that one. */ - if (hi > 0 - && msymbol[hi].type () != want_type - && msymbol[hi - 1].type () == want_type - && (msymbol[hi].size () == msymbol[hi - 1].size ()) - && (msymbol[hi].unrelocated_address () - == msymbol[hi - 1].unrelocated_address ()) - && (msymbol[hi].section_index () - == msymbol[hi - 1].section_index ())) - { - hi--; - continue; - } - - /* If the minimal symbol has a zero size, save it - but keep scanning backwards looking for one with - a non-zero size. A zero size may mean that the - symbol isn't an object or function (e.g. a - label), or it may just mean that the size was not - specified. */ - if (msymbol[hi].size () == 0) - { - if (best_zero_sized == -1) - best_zero_sized = hi; - hi--; - continue; - } - - /* If we are past the end of the current symbol, try - the previous symbol if it has a larger overlapping - size. This happens on i686-pc-linux-gnu with glibc; - the nocancel variants of system calls are inside - the cancellable variants, but both have sizes. */ - if (hi > 0 - && msymbol[hi].size () != 0 - && unrel_pc >= msymbol[hi].unrelocated_end_address () - && unrel_pc < msymbol[hi - 1].unrelocated_end_address ()) - { - hi--; - continue; - } - - /* Otherwise, this symbol must be as good as we're going - to get. */ - break; - } - - /* If HI has a zero size, and best_zero_sized is set, - then we had two or more zero-sized symbols; prefer - the first one we found (which may have a higher - address). Also, if we ran off the end, be sure - to back up. */ - if (best_zero_sized != -1 - && (hi < 0 || msymbol[hi].size () == 0)) - hi = best_zero_sized; - - /* If the minimal symbol has a non-zero size, and this - PC appears to be outside the symbol's contents, then - refuse to use this symbol. If we found a zero-sized - symbol with an address greater than this symbol's, - use that instead. We assume that if symbols have - specified sizes, they do not overlap. */ - - if (hi >= 0 - && msymbol[hi].size () != 0 - && unrel_pc >= msymbol[hi].unrelocated_end_address ()) - { - if (best_zero_sized != -1) - hi = best_zero_sized; - else - { - /* If needed record this symbol as the closest - previous symbol. */ - if (previous != nullptr) - { - if (previous->minsym == nullptr - || (msymbol[hi].unrelocated_address () - > previous->minsym->unrelocated_address ())) - { - previous->minsym = &msymbol[hi]; - previous->objfile = objfile; - } - } - /* Go on to the next object file. */ - continue; - } - } - - /* The minimal symbol indexed by hi now is the best one in this - objfile's minimal symbol table. See if it is the best one - overall. */ - - if (hi >= 0 - && ((best_symbol == NULL) || - (best_symbol->unrelocated_address () < - msymbol[hi].unrelocated_address ()))) - { - best_symbol = &msymbol[hi]; - best_objfile = objfile; - } + previous->minsym = this_previous; + previous->objfile = objfile; } + /* Go on to the next object file. */ + continue; + } + + /* MINSYM now is the best one in this objfile's minimal symbol + table. See if it is the best one overall. */ + if (minsym != nullptr + && ((best_symbol == NULL) || + (best_symbol->unrelocated_address () + < minsym->unrelocated_address ()))) + { + best_symbol = minsym; + best_objfile = objfile; } } diff --git a/gdb/minsyms.h b/gdb/minsyms.h index d44f281939b..df77977538f 100644 --- a/gdb/minsyms.h +++ b/gdb/minsyms.h @@ -301,6 +301,13 @@ struct bound_minimal_symbol lookup_minimal_symbol_by_pc_section struct bound_minimal_symbol lookup_minimal_symbol_by_pc (CORE_ADDR); +/* Overload of lookup_minimal_symbol_by_pc that only references the + (unrelocated) per-BFD object and only searches the text + section. */ + +minimal_symbol *lookup_minimal_symbol_by_pc (objfile_per_bfd_storage *per_bfd, + unrelocated_addr addr); + /* Iterate over all the minimal symbols in the objfile OBJF which match NAME. Both the ordinary and demangled names of each symbol are considered. The caller is responsible for canonicalizing NAME,