From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pf1-x42d.google.com (mail-pf1-x42d.google.com [IPv6:2607:f8b0:4864:20::42d]) by sourceware.org (Postfix) with ESMTPS id 2D5A23858D3C for ; Sun, 6 Feb 2022 15:11:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2D5A23858D3C Received: by mail-pf1-x42d.google.com with SMTP id a8so9513992pfa.6 for ; Sun, 06 Feb 2022 07:11:49 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=8F2R1sUPfuoR6qdauUSZISukoVE+VTlF++lZJWmMZjI=; b=rT48OwC4KY7ZDLYPSw68HV7QctA8QeAoYdCutWGgyMolTl4G5kiRuzNimX/UbhXO0i WqRH2qsyIL7teKu0hSGTm3YFPJNieD8Y6po7PnhuyTO642ii/2w9btPXE40gpl3FLTTp xFLJzQJJk/+EqZNeye8e70YtBZHQJ5Ub6d/vPlIIU941SDNBvffQ8//i7eoA2UhcIrbY nDL+pD2pRbwdFkrT+6Yil/aX/i1VQfLSW1KH9slpRFE++KJVUXAlqNhSn25FdYy7PEWw iDqTdjJcVkyrHZTlA4F21iXqUiT1F1C5csqNHOsiQ650OvSEVOgPokXIlYrU2X6MsowD mbFQ== X-Gm-Message-State: AOAM530qttKZ9GFxQf1FlMeZXtIF8ZgMaSy05yWUSJ/Ec1Kdnr2HZBmq GDpBGgYgEWdn+OxdgqrIaKo= X-Google-Smtp-Source: ABdhPJxyDw7qU8ZfZmLjRPh8E/x7mD+uWwwAdHFqm5ZKpxI4Rlbo4CTcf4+8pVnjk2y6gtWTiwidwQ== X-Received: by 2002:a05:6a00:124f:: with SMTP id u15mr1168888pfi.77.1644160308070; Sun, 06 Feb 2022 07:11:48 -0800 (PST) Received: from gnu-tgl-3.localdomain ([172.58.38.240]) by smtp.gmail.com with ESMTPSA id k21sm9003748pff.33.2022.02.06.07.11.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Feb 2022 07:11:47 -0800 (PST) Received: by gnu-tgl-3.localdomain (Postfix, from userid 1000) id 91637C0839; Sun, 6 Feb 2022 07:11:46 -0800 (PST) Date: Sun, 6 Feb 2022 07:11:46 -0800 From: "H.J. Lu" To: binutils@sourceware.org, Nick Clifton , Alan Modra Subject: [PATCH v2] ld: Add a remove_1_page_gap_before_relro_segment option Message-ID: References: <20220204143120.792359-1-hjl.tools@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20220204143120.792359-1-hjl.tools@gmail.com> X-Spam-Status: No, score=-3029.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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: 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: Sun, 06 Feb 2022 15:11:51 -0000 On Fri, Feb 04, 2022 at 06:31:20AM -0800, H.J. Lu wrote: > Remove the 1-page gap before the PT_GNU_RELRO segment: > > c804c6f98d3 ld: Rewrite lang_size_relro_segment_1 > 2f83249c13d elf: Remove the 1-page gap before the RELRO segment > > causes issues for some backends, like PowerPC64 (see PR 28827). Add an > linker emulation option, remove_1_page_gap_before_relro_segment, to > opt-in this feature only for x86. > This patch fixed: FAIL: ld-powerpc/pr28827-1 OK for master branch? Thanks. H.J. ---- Remove the 1-page gap before the PT_GNU_RELRO segment: c804c6f98d3 ld: Rewrite lang_size_relro_segment_1 2f83249c13d elf: Remove the 1-page gap before the RELRO segment causes issues for some backends, like PowerPC64 (see PR 28827). Add an linker emulation option, remove_1_page_gap_before_relro_segment, to opt-in this feature only for x86. PR ld/28743 PR ld/28827 * ldemul.c (ldemul_remove_1_page_gap_before_relro_segment): New. * ldemul.h (ldemul_remove_1_page_gap_before_relro_segment): Likewise. (ld_emulation_xfer_struct): Add remove_1_page_gap_before_relro_segment. * ldlang.c (lang_size_relro_segment_1): Remove the 1-page gap only if ldemul_remove_1_page_gap_before_relro_segment returns true. * emulparams/elf32_x86_64.sh: Define REMOVE_1_PAGE_GAP_BEFORE_RELRO_SEGMENT to true. * emulparams/elf_i386.sh: Likewise. * emulparams/elf_i386_be.sh: Likewise. * emulparams/elf_i386_ldso.sh: Likewise. * emulparams/elf_i386_vxworks.sh: Likewise. * emulparams/elf_iamcu.sh: Likewise. * emulparams/elf_k1om.sh: Likewise. * emulparams/elf_l1om.sh: Likewise. * emulparams/elf_x86_64.sh: Likewise. * emultempl/emulation.em (ld_${EMULATION_NAME}_emulation): Initialize the remove_1_page_gap_before_relro_segment field. * testsuite/ld-s390/gotreloc_64-relro-1.dd: Revert commit 2f83249c13d. --- ld/emulparams/elf32_x86_64.sh | 1 + ld/emulparams/elf_i386.sh | 1 + ld/emulparams/elf_i386_be.sh | 1 + ld/emulparams/elf_i386_ldso.sh | 1 + ld/emulparams/elf_i386_vxworks.sh | 1 + ld/emulparams/elf_iamcu.sh | 1 + ld/emulparams/elf_k1om.sh | 1 + ld/emulparams/elf_l1om.sh | 1 + ld/emulparams/elf_x86_64.sh | 1 + ld/emultempl/emulation.em | 1 + ld/ldemul.c | 6 ++++++ ld/ldemul.h | 5 +++++ ld/ldlang.c | 1 + ld/testsuite/ld-s390/gotreloc_64-relro-1.dd | 6 +++--- 14 files changed, 25 insertions(+), 3 deletions(-) diff --git a/ld/emulparams/elf32_x86_64.sh b/ld/emulparams/elf32_x86_64.sh index 4bff41287c1..0fab2c21c26 100644 --- a/ld/emulparams/elf32_x86_64.sh +++ b/ld/emulparams/elf32_x86_64.sh @@ -11,6 +11,7 @@ source_sh ${srcdir}/emulparams/dt-relr.sh SCRIPT_NAME=elf ELFSIZE=32 OUTPUT_FORMAT="elf32-x86-64" +REMOVE_1_PAGE_GAP_BEFORE_RELRO_SEGMENT=true NO_REL_RELOCS=yes TEXT_START_ADDR=0x400000 MAXPAGESIZE="CONSTANT (MAXPAGESIZE)" diff --git a/ld/emulparams/elf_i386.sh b/ld/emulparams/elf_i386.sh index ae17bb4b3f7..3910a40f959 100644 --- a/ld/emulparams/elf_i386.sh +++ b/ld/emulparams/elf_i386.sh @@ -9,6 +9,7 @@ source_sh ${srcdir}/emulparams/static.sh source_sh ${srcdir}/emulparams/dt-relr.sh SCRIPT_NAME=elf OUTPUT_FORMAT="elf32-i386" +REMOVE_1_PAGE_GAP_BEFORE_RELRO_SEGMENT=true NO_RELA_RELOCS=yes TEXT_START_ADDR=0x08048000 MAXPAGESIZE="CONSTANT (MAXPAGESIZE)" diff --git a/ld/emulparams/elf_i386_be.sh b/ld/emulparams/elf_i386_be.sh index dbe68e99e63..b8af9942f95 100644 --- a/ld/emulparams/elf_i386_be.sh +++ b/ld/emulparams/elf_i386_be.sh @@ -3,6 +3,7 @@ source_sh ${srcdir}/emulparams/dynamic_undefined_weak.sh source_sh ${srcdir}/emulparams/call_nop.sh SCRIPT_NAME=elf OUTPUT_FORMAT="elf32-i386" +REMOVE_1_PAGE_GAP_BEFORE_RELRO_SEGMENT=true EXTRA_EM_FILE="elf-x86" NO_RELA_RELOCS=yes TEXT_START_ADDR=0x80000000 diff --git a/ld/emulparams/elf_i386_ldso.sh b/ld/emulparams/elf_i386_ldso.sh index 081de5f8e71..4f8987cfc5b 100644 --- a/ld/emulparams/elf_i386_ldso.sh +++ b/ld/emulparams/elf_i386_ldso.sh @@ -4,6 +4,7 @@ source_sh ${srcdir}/emulparams/dynamic_undefined_weak.sh source_sh ${srcdir}/emulparams/call_nop.sh SCRIPT_NAME=elf OUTPUT_FORMAT="elf32-i386" +REMOVE_1_PAGE_GAP_BEFORE_RELRO_SEGMENT=true EXTRA_EM_FILE="elf-x86" NO_RELA_RELOCS=yes TEXT_START_ADDR=0x08048000 diff --git a/ld/emulparams/elf_i386_vxworks.sh b/ld/emulparams/elf_i386_vxworks.sh index 40c809263d1..33602d82ceb 100644 --- a/ld/emulparams/elf_i386_vxworks.sh +++ b/ld/emulparams/elf_i386_vxworks.sh @@ -1,5 +1,6 @@ SCRIPT_NAME=elf OUTPUT_FORMAT="elf32-i386-vxworks" +REMOVE_1_PAGE_GAP_BEFORE_RELRO_SEGMENT=true NO_RELA_RELOCS=yes TEXT_START_ADDR=0x08048000 MAXPAGESIZE="CONSTANT (MAXPAGESIZE)" diff --git a/ld/emulparams/elf_iamcu.sh b/ld/emulparams/elf_iamcu.sh index c1582235eda..bbbb7aba769 100644 --- a/ld/emulparams/elf_iamcu.sh +++ b/ld/emulparams/elf_iamcu.sh @@ -4,6 +4,7 @@ source_sh ${srcdir}/emulparams/dynamic_undefined_weak.sh source_sh ${srcdir}/emulparams/call_nop.sh SCRIPT_NAME=elf OUTPUT_FORMAT="elf32-iamcu" +REMOVE_1_PAGE_GAP_BEFORE_RELRO_SEGMENT=true NO_RELA_RELOCS=yes TEXT_START_ADDR=0x08048000 MAXPAGESIZE="CONSTANT (MAXPAGESIZE)" diff --git a/ld/emulparams/elf_k1om.sh b/ld/emulparams/elf_k1om.sh index b27f5ea861a..c0bb14384bd 100644 --- a/ld/emulparams/elf_k1om.sh +++ b/ld/emulparams/elf_k1om.sh @@ -5,6 +5,7 @@ source_sh ${srcdir}/emulparams/call_nop.sh SCRIPT_NAME=elf ELFSIZE=64 OUTPUT_FORMAT="elf64-k1om" +REMOVE_1_PAGE_GAP_BEFORE_RELRO_SEGMENT=true NO_REL_RELOCS=yes TEXT_START_ADDR=0x400000 MAXPAGESIZE="CONSTANT (MAXPAGESIZE)" diff --git a/ld/emulparams/elf_l1om.sh b/ld/emulparams/elf_l1om.sh index 70d76829d7b..f9f9e5cc73a 100644 --- a/ld/emulparams/elf_l1om.sh +++ b/ld/emulparams/elf_l1om.sh @@ -5,6 +5,7 @@ source_sh ${srcdir}/emulparams/call_nop.sh SCRIPT_NAME=elf ELFSIZE=64 OUTPUT_FORMAT="elf64-l1om" +REMOVE_1_PAGE_GAP_BEFORE_RELRO_SEGMENT=true NO_REL_RELOCS=yes TEXT_START_ADDR=0x400000 MAXPAGESIZE="CONSTANT (MAXPAGESIZE)" diff --git a/ld/emulparams/elf_x86_64.sh b/ld/emulparams/elf_x86_64.sh index 5f2743ed409..d18d2ecc6cf 100644 --- a/ld/emulparams/elf_x86_64.sh +++ b/ld/emulparams/elf_x86_64.sh @@ -12,6 +12,7 @@ source_sh ${srcdir}/emulparams/dt-relr.sh SCRIPT_NAME=elf ELFSIZE=64 OUTPUT_FORMAT="elf64-x86-64" +REMOVE_1_PAGE_GAP_BEFORE_RELRO_SEGMENT=true NO_REL_RELOCS=yes TEXT_START_ADDR=0x400000 MAXPAGESIZE="CONSTANT (MAXPAGESIZE)" diff --git a/ld/emultempl/emulation.em b/ld/emultempl/emulation.em index cfa6567ac2b..0dab69f8ddf 100644 --- a/ld/emultempl/emulation.em +++ b/ld/emultempl/emulation.em @@ -18,6 +18,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script}, "${EMULATION_NAME}", "${OUTPUT_FORMAT}", + ${REMOVE_1_PAGE_GAP_BEFORE_RELRO_SEGMENT-false}, ${LDEMUL_FINISH-finish_default}, ${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL}, ${LDEMUL_OPEN_DYNAMIC_ARCHIVE-NULL}, diff --git a/ld/ldemul.c b/ld/ldemul.c index 5c5adef06bb..5dd33c072f9 100644 --- a/ld/ldemul.c +++ b/ld/ldemul.c @@ -203,6 +203,12 @@ ldemul_default_target (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) return ld_emulation->target_name; } +bool +ldemul_remove_1_page_gap_before_relro_segment (void) +{ + return ld_emulation->remove_1_page_gap_before_relro_segment; +} + /* If the entry point was not specified as an address, then add the symbol as undefined. This will cause ld to extract an archive element defining the entry if ld is linking against such an archive. diff --git a/ld/ldemul.h b/ld/ldemul.h index 33e690d78ac..a3416e1a4a9 100644 --- a/ld/ldemul.h +++ b/ld/ldemul.h @@ -76,6 +76,8 @@ extern bool ldemul_open_dynamic_archive (const char *, struct search_dirs *, struct lang_input_statement_struct *); extern char *ldemul_default_target (int, char**); +extern bool ldemul_remove_1_page_gap_before_relro_segment + (void); extern void after_parse_default (void); extern void after_open_default @@ -161,6 +163,9 @@ typedef struct ld_emulation_xfer_struct { /* The output format. */ char *target_name; + /* TRUE to remove the 1-page gap before the PT_GNU_RELRO segment. */ + bool remove_1_page_gap_before_relro_segment; + /* Run after assigning values from the script. */ void (*finish) (void); diff --git a/ld/ldlang.c b/ld/ldlang.c index 5dd3df12a0f..042b492d52b 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -6421,6 +6421,7 @@ lang_size_relro_segment_1 (seg_align_type *seg) } if (relro_sec != NULL + && ldemul_remove_1_page_gap_before_relro_segment () && seg->maxpagesize >= (1U << max_alignment_power)) { asection *prev_sec; diff --git a/ld/testsuite/ld-s390/gotreloc_64-relro-1.dd b/ld/testsuite/ld-s390/gotreloc_64-relro-1.dd index 5a107465be2..64151d10a7c 100644 --- a/ld/testsuite/ld-s390/gotreloc_64-relro-1.dd +++ b/ld/testsuite/ld-s390/gotreloc_64-relro-1.dd @@ -5,8 +5,8 @@ Disassembly of section .text: .* : .*: c0 10 00 00 0f 0c [ ]*larl %r1,2000 .*: c0 10 00 00 0f 09 [ ]*larl %r1,2000 -.*: c4 1d 00 00 07 8a [ ]*lrl %r1,1108 <_GLOBAL_OFFSET_TABLE_\+0x28> +.*: c4 1d 00 00 0f 02 [ ]*lrl %r1,1ff8 <_GLOBAL_OFFSET_TABLE_\+0x28> .*: 58 10 c0 28 [ ]*l %r1,40\(%r12\) .*: e3 10 c0 28 00 58 [ ]*ly %r1,40\(%r12\) -.*: c4 18 00 00 07 7e [ ]*lgrl %r1,1100 <_GLOBAL_OFFSET_TABLE_\+0x20> -.*: c4 18 00 00 07 77 [ ]*lgrl %r1,10f8 <_GLOBAL_OFFSET_TABLE_\+0x18> +.*: c4 18 00 00 0e f6 [ ]*lgrl %r1,1ff0 <_GLOBAL_OFFSET_TABLE_\+0x20> +.*: c4 18 00 00 0e ef [ ]*lgrl %r1,1fe8 <_GLOBAL_OFFSET_TABLE_\+0x18> -- 2.34.1