From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from out30-43.freemail.mail.aliyun.com (out30-43.freemail.mail.aliyun.com [115.124.30.43]) by sourceware.org (Postfix) with ESMTPS id 02E62385840A for ; Fri, 29 Jul 2022 07:48:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 02E62385840A X-Alimail-AntiSpam: AC=PASS; BC=-1|-1; BR=01201311R181e4; CH=green; DM=||false|; DS=||; FP=0|-1|-1|-1|0|-1|-1|-1; HT=ay29a033018045170; MF=rjiejie@linux.alibaba.com; NM=1; PH=DS; RN=2; SR=0; TI=SMTPD_---0VKkWVPT_1659080918; Received: from localhost(mailfrom:rjiejie@linux.alibaba.com fp:SMTPD_---0VKkWVPT_1659080918) by smtp.aliyun-inc.com; Fri, 29 Jul 2022 15:48:39 +0800 From: Jojo R To: rjiejie@linux.alibaba.com, binutils@sourceware.org Subject: [PATCH] Support multiple .eh_frame sections Date: Fri, 29 Jul 2022 15:48:37 +0800 Message-Id: <20220729074837.82957-1-rjiejie@linux.alibaba.com> X-Mailer: git-send-email 2.24.3 (Apple Git-128) MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-18.7 required=5.0 tests=BAYES_00, ENV_AND_HDR_SPF_MATCH, GIT_PATCH_0, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP, UNPARSEABLE_RELAY, USER_IN_DEF_SPF_WL 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: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 29 Jul 2022 07:48:49 -0000 This patch is based on MULTIPLE_FRAME_SECTIONS and EH_FRAME_LINKONCE, it allows backend to enable this feature and use '--gc-sections' simply. * gas/dw2gencfi.h (TARGET_MULTIPLE_EH_FRAME_SECTIONS): New. (MULTIPLE_FRAME_SECTIONS): Add TARGET_MULTIPLE_EH_FRAME_SECTIONS. * gas/dw2gencfi.c (EH_FRAME_LINKONCE): Add TARGET_MULTIPLE_EH_FRAME_SECTIONS. (is_now_linkonce_segment): Likewise. (get_cfi_seg): Create relocation info between .eh_frame.* and .text.* section. * bfd/elf-bfd.h (elf_backend_can_make_multiple_eh_frame): New. * bfd/elfxx-target.h (elf_backend_can_make_multiple_eh_frame): Likewise. * bfd/elflink.c (_bfd_elf_default_action_discarded): Add checking for elf_backend_can_make_multiple_eh_frame. --- bfd/elf-bfd.h | 3 +++ bfd/elflink.c | 7 +++++++ bfd/elfxx-target.h | 4 ++++ gas/dw2gencfi.c | 27 +++++++++++++++++++++++++-- gas/dw2gencfi.h | 7 ++++++- 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 65bd1128263..f9b64faa080 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1432,6 +1432,9 @@ struct elf_backend_data bool (*elf_backend_can_make_lsda_relative_eh_frame) (bfd *, struct bfd_link_info *, asection *); + /* Tell linker to support multiple eh_frame sections. */ + bool elf_backend_can_make_multiple_eh_frame; + /* This function returns an encoding after computing the encoded value (and storing it in ENCODED) for the given OFFSET into OSEC, to be stored in at LOC_OFFSET into the LOC_SEC input section. diff --git a/bfd/elflink.c b/bfd/elflink.c index 2b1450fa4e1..395718d72a6 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -10924,6 +10924,13 @@ elf_section_ignore_discarded_relocs (asection *sec) unsigned int _bfd_elf_default_action_discarded (asection *sec) { + const struct elf_backend_data *bed; + bed = get_elf_backend_data (sec->owner); + + if (bed->elf_backend_can_make_multiple_eh_frame + && strncmp (sec->name, ".eh_frame.", 10) == 0) + return 0; + if (sec->flags & SEC_DEBUGGING) return PRETEND; diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index 0579f64d1a0..3927a377a0e 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -654,6 +654,9 @@ #ifndef elf_backend_can_make_lsda_relative_eh_frame #define elf_backend_can_make_lsda_relative_eh_frame _bfd_elf_can_make_relative #endif +#ifndef elf_backend_can_make_multiple_eh_frame +#define elf_backend_can_make_multiple_eh_frame 0 +#endif #ifndef elf_backend_encode_eh_address #define elf_backend_encode_eh_address _bfd_elf_encode_eh_address #endif @@ -887,6 +890,7 @@ static const struct elf_backend_data elfNN_bed = elf_backend_eh_frame_address_size, elf_backend_can_make_relative_eh_frame, elf_backend_can_make_lsda_relative_eh_frame, + elf_backend_can_make_multiple_eh_frame, elf_backend_encode_eh_address, elf_backend_write_section, elf_backend_elfsym_local_is_section, diff --git a/gas/dw2gencfi.c b/gas/dw2gencfi.c index 6be8cb50495..461ab601321 100644 --- a/gas/dw2gencfi.c +++ b/gas/dw2gencfi.c @@ -75,7 +75,8 @@ # define tc_cfi_endproc(fde) ((void) (fde)) #endif -#define EH_FRAME_LINKONCE (SUPPORT_FRAME_LINKONCE || compact_eh) +#define EH_FRAME_LINKONCE (SUPPORT_FRAME_LINKONCE || compact_eh \ + || TARGET_MULTIPLE_EH_FRAME_SECTIONS) #ifndef DWARF2_FORMAT #define DWARF2_FORMAT(SEC) dwarf2_format_32bit @@ -277,6 +278,9 @@ is_now_linkonce_segment (void) if (compact_eh) return now_seg; + if (TARGET_MULTIPLE_EH_FRAME_SECTIONS) + return now_seg; + if ((bfd_section_flags (now_seg) & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE @@ -1333,14 +1337,33 @@ static segT get_cfi_seg (segT cseg, const char *base, flagword flags, int align) { /* Exclude .debug_frame sections for Compact EH. */ - if (SUPPORT_FRAME_LINKONCE || ((flags & SEC_DEBUGGING) == 0 && compact_eh)) + if (SUPPORT_FRAME_LINKONCE || ((flags & SEC_DEBUGGING) == 0 && compact_eh) + || ((flags & SEC_DEBUGGING) == 0 && TARGET_MULTIPLE_EH_FRAME_SECTIONS)) { + segT iseg = cseg; struct dwcfi_seg_list *l; l = dwcfi_hash_find_or_make (cseg, base, flags); cseg = l->seg; subseg_set (cseg, l->subseg); + + if (TARGET_MULTIPLE_EH_FRAME_SECTIONS + && (flags & DWARF2_EH_FRAME_READ_ONLY)) + { + const frchainS *ifrch = seg_info (iseg)->frchainP; + const frchainS *frch = seg_info (cseg)->frchainP; + expressionS exp; + + exp.X_op = O_symbol; + exp.X_add_symbol = (symbolS *) local_symbol_make (cseg->name, cseg, 0, frch->frch_root);; + exp.X_add_number = 0; + subseg_set (iseg, ifrch->frch_subseg); + fix_new_exp (ifrch->frch_root, 0, 0, &exp, 0, BFD_RELOC_NONE); + + /* Restore the original segment info. */ + subseg_set (cseg, l->subseg); + } } else { diff --git a/gas/dw2gencfi.h b/gas/dw2gencfi.h index d570cdb8db3..0f5ae77d800 100644 --- a/gas/dw2gencfi.h +++ b/gas/dw2gencfi.h @@ -66,7 +66,12 @@ extern void cfi_add_CFA_restore_state (void); #define SUPPORT_COMPACT_EH 0 #endif -#define MULTIPLE_FRAME_SECTIONS (SUPPORT_FRAME_LINKONCE || SUPPORT_COMPACT_EH) +#ifndef TARGET_MULTIPLE_EH_FRAME_SECTIONS +#define TARGET_MULTIPLE_EH_FRAME_SECTIONS 0 +#endif + +#define MULTIPLE_FRAME_SECTIONS (SUPPORT_FRAME_LINKONCE || SUPPORT_COMPACT_EH \ + || TARGET_MULTIPLE_EH_FRAME_SECTIONS) struct cfi_insn_data { -- 2.17.1