From patchwork Wed Nov 3 16:28:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 47012 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 589423858409 for ; Wed, 3 Nov 2021 16:38:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 589423858409 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1635957509; bh=8OdslCkpqKasIR1zpme9n9qduq4cVAxfQBRjHkRCjZY=; h=To:Subject:In-Reply-To:References:Date:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=MQ5YPS66bxcAD7OQWHbY7QOf0DAhkalESGz+PqZ+BI5xnu6z/aiOIbUkGh09QtvhL a0+v5/35UR0lI+V8yATVNv2m04hLsXSDab/2ousHarbeEaHwh+k553yyo/f3vC1iUV sv8AW9NX1Dfcm3m7PWzOgAqBmb67dSUNWgSaPpt4= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id D6DD53858C39 for ; Wed, 3 Nov 2021 16:28:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D6DD53858C39 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-236-yx2hi18xOAuJafmGJ-I6Jg-1; Wed, 03 Nov 2021 12:28:39 -0400 X-MC-Unique: yx2hi18xOAuJafmGJ-I6Jg-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9300E8799EB; Wed, 3 Nov 2021 16:28:38 +0000 (UTC) Received: from oldenburg.str.redhat.com (unknown [10.39.192.3]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 54B6560CC4; Wed, 3 Nov 2021 16:28:37 +0000 (UTC) To: gcc-patches@gcc.gnu.org Subject: [PATCH 1/4] libgcc: Remove tbase member from struct unw_eh_callback_data In-Reply-To: References: X-From-Line: eb8f3783f4345df6bf08431cac2fe7bb81421898 Mon Sep 17 00:00:00 2001 Message-Id: Date: Wed, 03 Nov 2021 17:28:35 +0100 User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Florian Weimer via Gcc-patches From: Florian Weimer Reply-To: Florian Weimer Cc: Jakub Jelinek , libc-alpha@sourceware.org Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" It is always a null pointer. libgcc/ChangeLog * unwind-dw2-fde-dip.c (struct unw_eh_callback_data): Remove tbase member. (base_from_cb_data): Adjust. (_Unwind_IteratePhdrCallback): Likewise. (_Unwind_Find_FDE): Likewise. --- libgcc/unwind-dw2-fde-dip.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/libgcc/unwind-dw2-fde-dip.c b/libgcc/unwind-dw2-fde-dip.c index 5095b6830bf..4a4d990f455 100644 --- a/libgcc/unwind-dw2-fde-dip.c +++ b/libgcc/unwind-dw2-fde-dip.c @@ -104,7 +104,6 @@ static const fde * _Unwind_Find_registered_FDE (void *pc, struct dwarf_eh_bases struct unw_eh_callback_data { _Unwind_Ptr pc; - void *tbase; void *dbase; void *func; const fde *ret; @@ -154,7 +153,7 @@ base_from_cb_data (unsigned char encoding, struct unw_eh_callback_data *data) return 0; case DW_EH_PE_textrel: - return (_Unwind_Ptr) data->tbase; + return 0; case DW_EH_PE_datarel: return (_Unwind_Ptr) data->dbase; default: @@ -431,7 +430,7 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) As soon as GLIBC will provide API so to notify that a library has been removed, we could cache this (and thus use search_object). */ ob.pc_begin = NULL; - ob.tbase = data->tbase; + ob.tbase = NULL; ob.dbase = data->dbase; ob.u.single = (fde *) eh_frame; ob.s.i = 0; @@ -461,7 +460,6 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases) return ret; data.pc = (_Unwind_Ptr) pc; - data.tbase = NULL; data.dbase = NULL; data.func = NULL; data.ret = NULL; @@ -472,7 +470,7 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases) if (data.ret) { - bases->tbase = data.tbase; + bases->tbase = NULL; bases->dbase = data.dbase; bases->func = data.func; } From patchwork Wed Nov 3 16:28:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 47014 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 297A63858C39 for ; Wed, 3 Nov 2021 16:40:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 297A63858C39 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1635957608; bh=YuHMe4z3BFhXdhfe+qXL5Vl2HiGaRCMl72hQuD0FCNg=; h=To:Subject:In-Reply-To:References:Date:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=Yn1YzXChj7BxkAGFA0MwbWStzpWI9ApqFXzyUhB/qbo/hcFUmJiQusvV6T7yZQc/N F58OHBavnka9+ZsOb5AMWacytheLvpLbTP0eah1gL2SGvRl6D4jbFr95IwJSE9igpJ lk3uMKmKbIWDdI1K7t9J39bDPap7a+t9384mmr/4= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id B03F93858409 for ; Wed, 3 Nov 2021 16:28:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B03F93858409 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-582-UjepW000MAeb0S_PNqu98Q-1; Wed, 03 Nov 2021 12:28:46 -0400 X-MC-Unique: UjepW000MAeb0S_PNqu98Q-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 4F7B218125C2; Wed, 3 Nov 2021 16:28:45 +0000 (UTC) Received: from oldenburg.str.redhat.com (unknown [10.39.192.3]) by smtp.corp.redhat.com (Postfix) with ESMTPS id AA96A5F4F5; Wed, 3 Nov 2021 16:28:43 +0000 (UTC) To: gcc-patches@gcc.gnu.org Subject: [PATCH 2/4] libgcc: Remove dbase member from struct unw_eh_callback_data if NULL In-Reply-To: References: X-From-Line: f885ea5d19633e1281b083d93bb67ca6d18f86c0 Mon Sep 17 00:00:00 2001 Message-Id: Date: Wed, 03 Nov 2021 17:28:41 +0100 User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=unavailable autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Florian Weimer via Gcc-patches From: Florian Weimer Reply-To: Florian Weimer Cc: Jakub Jelinek , libc-alpha@sourceware.org Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Only i386 and nios2 need this member at present. libgcc/ChangeLog * unwind-dw2-fde-dip.c (NEED_DBASE_MEMBER): Define. (struct unw_eh_callback_data): Make dbase member conditional. (unw_eh_callback_data_dbase): New function. (base_from_cb_data): Simplify for the non-dbase case. (_Unwind_IteratePhdrCallback): Adjust. (_Unwind_Find_FDE): Likewise. --- libgcc/unwind-dw2-fde-dip.c | 46 +++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/libgcc/unwind-dw2-fde-dip.c b/libgcc/unwind-dw2-fde-dip.c index 4a4d990f455..3f302826d2d 100644 --- a/libgcc/unwind-dw2-fde-dip.c +++ b/libgcc/unwind-dw2-fde-dip.c @@ -101,15 +101,35 @@ static const fde * _Unwind_Find_registered_FDE (void *pc, struct dwarf_eh_bases #define PT_GNU_EH_FRAME (PT_LOOS + 0x474e550) #endif +#ifdef CRT_GET_RFIB_DATA +#define NEED_DBASE_MEMBER 1 +#else +#define NEED_DBASE_MEMBER 0 +#endif + struct unw_eh_callback_data { _Unwind_Ptr pc; +#if NEED_DBASE_MEMBER void *dbase; +#endif void *func; const fde *ret; int check_cache; }; +/* Returns DATA->dbase if available, else NULL. */ +static inline _Unwind_Ptr +unw_eh_callback_data_dbase (const struct unw_eh_callback_data *data + __attribute__ ((unused))) +{ +#if NEED_DBASE_MEMBER + return (_Unwind_Ptr) data->dbase; +#else + return 0; +#endif +} + struct unw_eh_frame_hdr { unsigned char version; @@ -139,9 +159,11 @@ static struct frame_hdr_cache_element *frame_hdr_cache_head; /* Like base_of_encoded_value, but take the base from a struct unw_eh_callback_data instead of an _Unwind_Context. */ -static _Unwind_Ptr -base_from_cb_data (unsigned char encoding, struct unw_eh_callback_data *data) +static inline _Unwind_Ptr +base_from_cb_data (unsigned char encoding __attribute__ ((unused)), + _Unwind_Ptr dbase __attribute__ ((unused))) { +#if NEED_DBASE_MEMBER if (encoding == DW_EH_PE_omit) return 0; @@ -155,10 +177,13 @@ base_from_cb_data (unsigned char encoding, struct unw_eh_callback_data *data) case DW_EH_PE_textrel: return 0; case DW_EH_PE_datarel: - return (_Unwind_Ptr) data->dbase; + return dbase; default: gcc_unreachable (); } +#else /* !NEED_DBASE_MEMBER */ + return 0; +#endif } static int @@ -358,9 +383,10 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) # endif #endif + _Unwind_Ptr dbase = unw_eh_callback_data_dbase (data); p = read_encoded_value_with_base (hdr->eh_frame_ptr_enc, base_from_cb_data (hdr->eh_frame_ptr_enc, - data), + dbase), (const unsigned char *) (hdr + 1), &eh_frame); @@ -374,7 +400,7 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) p = read_encoded_value_with_base (hdr->fde_count_enc, base_from_cb_data (hdr->fde_count_enc, - data), + dbase), p, &fde_count); /* Shouldn't happen. */ if (fde_count == 0) @@ -431,7 +457,7 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) removed, we could cache this (and thus use search_object). */ ob.pc_begin = NULL; ob.tbase = NULL; - ob.dbase = data->dbase; + ob.dbase = (void *) dbase; ob.u.single = (fde *) eh_frame; ob.s.i = 0; ob.s.b.mixed_encoding = 1; /* Need to assume worst case. */ @@ -442,7 +468,7 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) unsigned int encoding = get_fde_encoding (data->ret); read_encoded_value_with_base (encoding, - base_from_cb_data (encoding, data), + base_from_cb_data (encoding, dbase), data->ret->pc_begin, &func); data->func = (void *) func; } @@ -460,7 +486,9 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases) return ret; data.pc = (_Unwind_Ptr) pc; +#if NEED_DBASE_MEMBER data.dbase = NULL; +#endif data.func = NULL; data.ret = NULL; data.check_cache = 1; @@ -471,7 +499,11 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases) if (data.ret) { bases->tbase = NULL; +#if NEED_DBASE_MEMBER bases->dbase = data.dbase; +#else + bases->dbase = NULL; +#endif bases->func = data.func; } return data.ret; From patchwork Wed Nov 3 16:28:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 47016 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 1886F3858D39 for ; Wed, 3 Nov 2021 16:41:47 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1886F3858D39 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1635957707; bh=qKRPFTqNFH5Hk4bpOff+Jem3rqdIzBbQVE/H+JTfspU=; h=To:Subject:In-Reply-To:References:Date:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=ZED96/b3bNXVF1jEXiTyOPGvj7lTc61eAUXjllY0lq1Lzs/OwxlvZMDb188RZTz8v uPOa5C+E7silxoT1IUpwAQy/3D67t7BTfr7h5qLFK+UQCaCm7GkeOpNrswrx779i/N b0nOJqIoRvL6Mz5+j4MNiQSYe3Zdlx9lBUf68Zc8= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 251773858013 for ; Wed, 3 Nov 2021 16:28:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 251773858013 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-250-EuI_jWiHOGuwDcrggiBNNQ-1; Wed, 03 Nov 2021 12:28:53 -0400 X-MC-Unique: EuI_jWiHOGuwDcrggiBNNQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id CFDFC18125C2; Wed, 3 Nov 2021 16:28:52 +0000 (UTC) Received: from oldenburg.str.redhat.com (unknown [10.39.192.3]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 1768968D7D; Wed, 3 Nov 2021 16:28:49 +0000 (UTC) To: gcc-patches@gcc.gnu.org Subject: [PATCH 3/4] libgcc: Split FDE search code from PT_GNU_EH_FRAME lookup In-Reply-To: References: X-From-Line: 53daedec153e3bf9b1a9c14f61cfe23385de80c9 Mon Sep 17 00:00:00 2001 Message-Id: <53daedec153e3bf9b1a9c14f61cfe23385de80c9.1635955148.git.fweimer@redhat.com> Date: Wed, 03 Nov 2021 17:28:48 +0100 User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=unavailable autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Florian Weimer via Gcc-patches From: Florian Weimer Reply-To: Florian Weimer Cc: Jakub Jelinek , libc-alpha@sourceware.org Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" This allows switching to a different implementation for PT_GNU_EH_FRAME lookup in a subsequent commit. This moves some of the PT_GNU_EH_FRAME parsing out of the glibc loader lock that is implied by dl_iterate_phdr. However, the FDE is already parsed outside the lock before this change, so this does not introduce additional crashes in case of a concurrent dlclose. libunwind/ChangeLog * unwind-dw2-fde-dip.c (struct unw_eh_callback_data): Add hdr. Remove func, ret. (struct find_fde_tail_result): New. (find_fde_tail): New function. Split from _Unwind_IteratePhdrCallback. (_Unwind_Find_FDE): Add call to find_fde_tail. --- libgcc/unwind-dw2-fde-dip.c | 91 +++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 39 deletions(-) diff --git a/libgcc/unwind-dw2-fde-dip.c b/libgcc/unwind-dw2-fde-dip.c index 3f302826d2d..272c0ec46c0 100644 --- a/libgcc/unwind-dw2-fde-dip.c +++ b/libgcc/unwind-dw2-fde-dip.c @@ -113,8 +113,7 @@ struct unw_eh_callback_data #if NEED_DBASE_MEMBER void *dbase; #endif - void *func; - const fde *ret; + const struct unw_eh_frame_hdr *hdr; int check_cache; }; @@ -197,10 +196,6 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) #else _Unwind_Ptr load_base; #endif - const unsigned char *p; - const struct unw_eh_frame_hdr *hdr; - _Unwind_Ptr eh_frame; - struct object ob; _Unwind_Ptr pc_low = 0, pc_high = 0; struct ext_dl_phdr_info @@ -348,10 +343,8 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) return 0; /* Read .eh_frame_hdr header. */ - hdr = (const struct unw_eh_frame_hdr *) + data->hdr = (const struct unw_eh_frame_hdr *) __RELOC_POINTER (p_eh_frame_hdr->p_vaddr, load_base); - if (hdr->version != 1) - return 1; #ifdef CRT_GET_RFIB_DATA # if defined __i386__ || defined __nios2__ @@ -383,12 +376,34 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) # endif #endif - _Unwind_Ptr dbase = unw_eh_callback_data_dbase (data); + return 1; +} + +/* Result type of find_fde_tail below. */ +struct find_fde_tail_result +{ + const fde *entry; + void *func; +}; + +/* Find the FDE for the program counter PC, in a previously located + PT_GNU_EH_FRAME data region. */ +static struct find_fde_tail_result +find_fde_tail (_Unwind_Ptr pc, + const struct unw_eh_frame_hdr *hdr, + _Unwind_Ptr dbase) +{ + const unsigned char *p = (const unsigned char *) (hdr + 1); + _Unwind_Ptr eh_frame; + struct object ob; + + if (hdr->version != 1) + return (struct find_fde_tail_result) { NULL, }; + p = read_encoded_value_with_base (hdr->eh_frame_ptr_enc, base_from_cb_data (hdr->eh_frame_ptr_enc, dbase), - (const unsigned char *) (hdr + 1), - &eh_frame); + p, &eh_frame); /* We require here specific table encoding to speed things up. Also, DW_EH_PE_datarel here means using PT_GNU_EH_FRAME start @@ -404,7 +419,7 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) p, &fde_count); /* Shouldn't happen. */ if (fde_count == 0) - return 1; + return (struct find_fde_tail_result) { NULL, }; if ((((_Unwind_Ptr) p) & 3) == 0) { struct fde_table { @@ -419,9 +434,9 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) _Unwind_Ptr range; mid = fde_count - 1; - if (data->pc < table[0].initial_loc + data_base) - return 1; - else if (data->pc < table[mid].initial_loc + data_base) + if (pc < table[0].initial_loc + data_base) + return (struct find_fde_tail_result) { NULL, }; + else if (pc < table[mid].initial_loc + data_base) { lo = 0; hi = mid; @@ -429,9 +444,9 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) while (lo < hi) { mid = (lo + hi) / 2; - if (data->pc < table[mid].initial_loc + data_base) + if (pc < table[mid].initial_loc + data_base) hi = mid; - else if (data->pc >= table[mid + 1].initial_loc + data_base) + else if (pc >= table[mid + 1].initial_loc + data_base) lo = mid + 1; else break; @@ -445,10 +460,11 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) f_enc_size = size_of_encoded_value (f_enc); read_encoded_value_with_base (f_enc & 0x0f, 0, &f->pc_begin[f_enc_size], &range); - if (data->pc < table[mid].initial_loc + data_base + range) - data->ret = f; - data->func = (void *) (table[mid].initial_loc + data_base); - return 1; + void *func = (void *) (table[mid].initial_loc + data_base); + if (pc < table[mid].initial_loc + data_base + range) + return (struct find_fde_tail_result) { f, func }; + else + return (struct find_fde_tail_result) { NULL, func }; } } @@ -461,18 +477,18 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) ob.u.single = (fde *) eh_frame; ob.s.i = 0; ob.s.b.mixed_encoding = 1; /* Need to assume worst case. */ - data->ret = linear_search_fdes (&ob, (fde *) eh_frame, (void *) data->pc); - if (data->ret != NULL) + const fde *entry = linear_search_fdes (&ob, (fde *) eh_frame, (void *) pc); + if (entry != NULL) { _Unwind_Ptr func; - unsigned int encoding = get_fde_encoding (data->ret); + unsigned int encoding = get_fde_encoding (entry); read_encoded_value_with_base (encoding, base_from_cb_data (encoding, dbase), - data->ret->pc_begin, &func); - data->func = (void *) func; + entry->pc_begin, &func); + return (struct find_fde_tail_result) { entry, (void *) func }; } - return 1; + return (struct find_fde_tail_result) { NULL, }; } const fde * @@ -489,24 +505,21 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases) #if NEED_DBASE_MEMBER data.dbase = NULL; #endif - data.func = NULL; - data.ret = NULL; data.check_cache = 1; - if (dl_iterate_phdr (_Unwind_IteratePhdrCallback, &data) < 0) + if (dl_iterate_phdr (_Unwind_IteratePhdrCallback, &data) <= 0) return NULL; - if (data.ret) + _Unwind_Ptr dbase = unw_eh_callback_data_dbase (&data); + struct find_fde_tail_result result = find_fde_tail ((_Unwind_Ptr) pc, + data.hdr, dbase); + if (result.entry != NULL) { bases->tbase = NULL; -#if NEED_DBASE_MEMBER - bases->dbase = data.dbase; -#else - bases->dbase = NULL; -#endif - bases->func = data.func; + bases->dbase = (void *) dbase; + bases->func = result.func; } - return data.ret; + return result.entry; } #else From patchwork Wed Nov 3 16:28:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 47017 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 E5A623858419 for ; Wed, 3 Nov 2021 16:42:43 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E5A623858419 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1635957763; bh=KOIPiB0u0B9vBOh0n3qIdJXW3jsfKrvRvZazyMCQHS8=; h=To:Subject:In-Reply-To:References:Date:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=xKmj0i6ZS7j2g/KDSUQ9Rz+n+L0lYceB5iJmyjgtNBAzYKv2fzj/rlwpCHOvu4JFI +RtjTQGQGE3owk+1LmDVLjHmfqW0LsAWW9WzzRFNkuEbciYiyNoD9cJqQtqlBG9hWX eWKRdseoUk36cAFvH2V1yhag2FOaL++n60L9X1sQ= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 4D07B385800A for ; Wed, 3 Nov 2021 16:29:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 4D07B385800A Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-177-suS8xzUhOzipRLqN0QiVhQ-1; Wed, 03 Nov 2021 12:29:00 -0400 X-MC-Unique: suS8xzUhOzipRLqN0QiVhQ-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 14DFB5074C; Wed, 3 Nov 2021 16:28:59 +0000 (UTC) Received: from oldenburg.str.redhat.com (unknown [10.39.192.3]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C9D61607A1; Wed, 3 Nov 2021 16:28:57 +0000 (UTC) To: gcc-patches@gcc.gnu.org Subject: [PATCH 4/4] libgcc: Use _dl_find_eh_frame in _Unwind_Find_FDE In-Reply-To: References: X-From-Line: adeb300eebaa792d64fca85f1e72fed03c1b32d1 Mon Sep 17 00:00:00 2001 Message-Id: Date: Wed, 03 Nov 2021 17:28:55 +0100 User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Florian Weimer via Gcc-patches From: Florian Weimer Reply-To: Florian Weimer Cc: Jakub Jelinek , libc-alpha@sourceware.org Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" libgcc/ChangeLog * unwind-dw2-fde-dip.c (USE_DL_FIND_EH_FRAME) (DL_FIND_EH_FRAME_CONDITION): New macros. [__GLIBC__ && !DL_FIND_EH_FRAME_DBASE] (_dl_find_eh_frame): Declare weak function. (_Unwind_Find_FDE): Call _dl_find_eh_frame if available. --- libgcc/unwind-dw2-fde-dip.c | 50 +++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/libgcc/unwind-dw2-fde-dip.c b/libgcc/unwind-dw2-fde-dip.c index 272c0ec46c0..b5b4a23dc56 100644 --- a/libgcc/unwind-dw2-fde-dip.c +++ b/libgcc/unwind-dw2-fde-dip.c @@ -129,6 +129,30 @@ unw_eh_callback_data_dbase (const struct unw_eh_callback_data *data #endif } +#ifdef DL_FIND_EH_FRAME_DBASE +#if DL_FIND_EH_FRAME_DBASE != NEED_DBASE_MEMBER +#error "DL_FIND_EH_FRAME_DBASE != NEED_DBASE_MEMBER" +#endif +#define USE_DL_FIND_EH_FRAME 1 +#define DL_FIND_EH_FRAME_CONDITION 1 +#endif + +/* Fallback declaration for old glibc headers. DL_FIND_EH_FRAME_DBASE is used + as a proxy to determine if declares _dl_find_eh_frame. */ +#if defined __GLIBC__ && !defined DL_FIND_EH_FRAME_DBASE +#if NEED_DBASE_MEMBER +void *_dl_find_eh_frame (void *__pc, void **__dbase) __attribute__ ((weak)); +#else +void *_dl_find_eh_frame (void *__pc) __attribute__ ((weak)); +#endif +#define USE_DL_FIND_EH_FRAME 1 +#define DL_FIND_EH_FRAME_CONDITION (_dl_find_eh_frame != NULL) +#endif + +#ifndef USE_DL_FIND_EH_FRAME +#define USE_DL_FIND_EH_FRAME 0 +#endif + struct unw_eh_frame_hdr { unsigned char version; @@ -501,6 +525,32 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases) if (ret != NULL) return ret; +#if USE_DL_FIND_EH_FRAME + if (DL_FIND_EH_FRAME_CONDITION) + { + void *dbase; + void *eh_frame; +#if NEED_DBASE_MEMBER + eh_frame = _dl_find_eh_frame (pc, &dbase); +#else + dbase = NULL; + eh_frame = _dl_find_eh_frame (pc); +#endif + if (eh_frame == NULL) + return NULL; + + struct find_fde_tail_result result + = find_fde_tail ((_Unwind_Ptr) pc, eh_frame, (_Unwind_Ptr) dbase); + if (result.entry != NULL) + { + bases->tbase = NULL; + bases->dbase = (void *) dbase; + bases->func = result.func; + } + return result.entry; + } +#endif + data.pc = (_Unwind_Ptr) pc; #if NEED_DBASE_MEMBER data.dbase = NULL;