From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-x634.google.com (mail-pl1-x634.google.com [IPv6:2607:f8b0:4864:20::634]) by sourceware.org (Postfix) with ESMTPS id CD73D3858D20 for ; Fri, 4 Feb 2022 14:31:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CD73D3858D20 Received: by mail-pl1-x634.google.com with SMTP id t9so3074657plg.13 for ; Fri, 04 Feb 2022 06:31:25 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=vOFC5gI8M8CrxRYp4ZmSUIaPiAJWdio48V35+ydkEk8=; b=V2q33Lwl5KSzCdwkZHC2/ZUpXXfUMmOjw15nQafI7mgPIVeMK1nZPMr+zIX0FlWFIo SjP6LHYVucep0/6F43FB3hitPtF1TvZOPodj6NSqYDnLkq/31t5O6AuaDkg/IYhhR/Be aT7WW07axXzBEFmWCtEKACSKpm++xytSddHMGt4+nmusp7BRFxVxWx+SO/QNlx2xZ1tL DWgBzGU1I5kvqdw4AqVxCy6DJf0vnaedEwNnLq5wjUPtRSENb+n41ChY8/92tSSYJDzK iZxslF7yJPmDrMl5u0yOwOYN0Pg9AZJeR2ZJU4rxJ/nubDMqRC3wYPGiKKNWWeIHoKFA CVjg== X-Gm-Message-State: AOAM5305FILYB5e4oQCQmJ8awE7gJBv4UwrRiqxPjTACcj3JHflZIVOa ieQQ19vNakINFnD6Dt/Scnc= X-Google-Smtp-Source: ABdhPJyY8XkTlLeqxWXNzW6Th34cXN4ENEjCuwOOrbGq8WVEUWd7c33y5xBijXAbAz2yKcJv/I1lLg== X-Received: by 2002:a17:902:e5cb:: with SMTP id u11mr3257734plf.146.1643985084699; Fri, 04 Feb 2022 06:31:24 -0800 (PST) Received: from gnu-tgl-3.localdomain ([172.58.38.240]) by smtp.gmail.com with ESMTPSA id f15sm2726021pfn.19.2022.02.04.06.31.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Feb 2022 06:31:23 -0800 (PST) Received: from gnu-tgl-3.. (localhost [IPv6:::1]) by gnu-tgl-3.localdomain (Postfix) with ESMTP id C854EC00AF; Fri, 4 Feb 2022 06:31:20 -0800 (PST) From: "H.J. Lu" To: binutils@sourceware.org Subject: [PATCH] ld: Add a remove_1_page_gap_before_relro_segment option Date: Fri, 4 Feb 2022 06:31:20 -0800 Message-Id: <20220204143120.792359-1-hjl.tools@gmail.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3030.0 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: Fri, 04 Feb 2022 14:31:28 -0000 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/aix.em (ld_${EMULATION_NAME}_emulation): Initialize the remove_1_page_gap_before_relro_segment field to false. * emultempl/armcoff.em (ld_${EMULATION_NAME}_emulation): Likewise. * emultempl/beos.em (ld_${EMULATION_NAME}_emulation): Likewise. * emultempl/generic.em (ld_${EMULATION_NAME}_emulation): Likewise. * emultempl/msp430.em (ld_${EMULATION_NAME}_emulation): Likewise. * emultempl/pe.em (ld_${EMULATION_NAME}_emulation): Likewise. * emultempl/pep.em (ld_${EMULATION_NAME}_emulation): Likewise. * emultempl/ticoff.em (ld_${EMULATION_NAME}_emulation): Likewise. * emultempl/vanilla.em (ld_${EMULATION_NAME}_emulation): Likewise. * emultempl/elf.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/aix.em | 1 + ld/emultempl/armcoff.em | 1 + ld/emultempl/beos.em | 1 + ld/emultempl/elf.em | 1 + ld/emultempl/generic.em | 1 + ld/emultempl/msp430.em | 1 + ld/emultempl/pe.em | 1 + ld/emultempl/pep.em | 1 + ld/emultempl/ticoff.em | 1 + ld/emultempl/vanilla.em | 1 + ld/ldemul.c | 6 ++++++ ld/ldemul.h | 5 +++++ ld/ldlang.c | 1 + ld/testsuite/ld-s390/gotreloc_64-relro-1.dd | 6 +++--- 23 files changed, 34 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/aix.em b/ld/emultempl/aix.em index b82305dc09e..20ba8094fe1 100644 --- a/ld/emultempl/aix.em +++ b/ld/emultempl/aix.em @@ -1617,6 +1617,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = { gld${EMULATION_NAME}_get_script, "${EMULATION_NAME}", "${OUTPUT_FORMAT}", + false, finish_default, gld${EMULATION_NAME}_create_output_section_statements, gld${EMULATION_NAME}_open_dynamic_archive, diff --git a/ld/emultempl/armcoff.em b/ld/emultempl/armcoff.em index b82855ae04f..e9cfc708374 100644 --- a/ld/emultempl/armcoff.em +++ b/ld/emultempl/armcoff.em @@ -271,6 +271,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = gld${EMULATION_NAME}_get_script, "${EMULATION_NAME}", "${OUTPUT_FORMAT}", + false, gld${EMULATION_NAME}_finish, NULL, /* create output section statements */ NULL, /* open dynamic archive */ diff --git a/ld/emultempl/beos.em b/ld/emultempl/beos.em index bebad8af2f7..b8ac583a5ce 100644 --- a/ld/emultempl/beos.em +++ b/ld/emultempl/beos.em @@ -778,6 +778,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = gld_${EMULATION_NAME}_get_script, "${EMULATION_NAME}", "${OUTPUT_FORMAT}", + false, finish_default, NULL, /* create output section statements */ NULL, /* open dynamic archive */ diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em index 7325872e1d9..a3eb7bfe63b 100644 --- a/ld/emultempl/elf.em +++ b/ld/emultempl/elf.em @@ -927,6 +927,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-ldelf_open_dynamic_archive}, diff --git a/ld/emultempl/generic.em b/ld/emultempl/generic.em index e7c990e7260..91dc3f155b9 100644 --- a/ld/emultempl/generic.em +++ b/ld/emultempl/generic.em @@ -146,6 +146,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script}, "${EMULATION_NAME}", "${OUTPUT_FORMAT}", + false, ${LDEMUL_FINISH-finish_default}, ${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL}, ${LDEMUL_OPEN_DYNAMIC_ARCHIVE-NULL}, diff --git a/ld/emultempl/msp430.em b/ld/emultempl/msp430.em index abfbdcb64a8..eb0bc280f09 100644 --- a/ld/emultempl/msp430.em +++ b/ld/emultempl/msp430.em @@ -922,6 +922,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script}, "${EMULATION_NAME}", "${OUTPUT_FORMAT}", + false, gld${EMULATION_NAME}_finish, ${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL}, ${LDEMUL_OPEN_DYNAMIC_ARCHIVE-NULL}, diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index 3c6a07e8e86..e6b16650062 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -2445,6 +2445,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = gld_${EMULATION_NAME}_get_script, "${EMULATION_NAME}", "${OUTPUT_FORMAT}", + false, gld_${EMULATION_NAME}_finish, NULL, /* Create output section statements. */ gld_${EMULATION_NAME}_open_dynamic_archive, diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em index 848daa16746..baee87c6ae2 100644 --- a/ld/emultempl/pep.em +++ b/ld/emultempl/pep.em @@ -2257,6 +2257,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = gld_${EMULATION_NAME}_get_script, "${EMULATION_NAME}", "${OUTPUT_FORMAT}", + false, gld_${EMULATION_NAME}_finish, NULL, /* Create output section statements. */ gld_${EMULATION_NAME}_open_dynamic_archive, diff --git a/ld/emultempl/ticoff.em b/ld/emultempl/ticoff.em index 1ac483b9c7f..8b5401ce558 100644 --- a/ld/emultempl/ticoff.em +++ b/ld/emultempl/ticoff.em @@ -171,6 +171,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = gld_${EMULATION_NAME}_get_script, "${EMULATION_NAME}", "${OUTPUT_FORMAT}", + false, finish_default, NULL, /* create output section statements */ NULL, /* open dynamic archive */ diff --git a/ld/emultempl/vanilla.em b/ld/emultempl/vanilla.em index dc47ca13efb..d45d08194cb 100644 --- a/ld/emultempl/vanilla.em +++ b/ld/emultempl/vanilla.em @@ -72,6 +72,7 @@ struct ld_emulation_xfer_struct ld_vanilla_emulation = vanilla_get_script, "vanilla", "a.out-sunos-big", + false, finish_default, NULL, /* create output section statements */ NULL, /* open dynamic archive */ 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