From patchwork Wed Nov 20 14:32:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nick Clifton X-Patchwork-Id: 101583 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 3AC873858D26 for ; Wed, 20 Nov 2024 14:33:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3AC873858D26 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=EOP8vX08 X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id B7B1E3858D20 for ; Wed, 20 Nov 2024 14:32:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B7B1E3858D20 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org B7B1E3858D20 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732113142; cv=none; b=NrJ5ItC3SSpiuMBfDDqfOTM3lVp+b/W2DgXqt2PzRriu5YwUmn0bD5/MkIRO8Wr2bbuSsGeSGqM3cEgFhLl8aUc6OnoMIcWb2vbrmMXP5RYvxwtcgVDdnGSjJiZkfCUPiaAZpXYunKsEU2cTNCkdEia0G6ukImHrGXOhecn+m2o= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1732113142; c=relaxed/simple; bh=boCoplaaZGeGUJ9nr2ZLGOl5Gcx2Eu76RGLCOnjSUaM=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=uChq+IWTa7bHaUkQkSyHWDb1aOhCVcOPgiQsK/c/VXmebkW/0cJsyKwmG2/TxqOr4FVzjodeue9urlOTIhEZEJ6fReoy3VWNRUx3polp89+olgxGtfIWVWzJTbzRtYuNZzAZcrg1oXTZoipKAubGLRIrozaeV31gUpHeK3Wt4TQ= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B7B1E3858D20 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1732113142; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type; bh=rEfV/UsifdfCOzHWMgnYYQ7u8aQ9QXJwENp/sUw0cog=; b=EOP8vX08bKDrJd5NuT2r9DrD0ZyXu1YumIiCXaRhL+6XeFOu5dzxXv5gYjbOwHXaGtRZgW mJVIz+NgLoW+1kW3/agsIKrMgt/cply0WH7wukrGRSRDSaSJgl7hr7gnhwiEIJHcL6sL6J j1zIPcopclGKarRsOcZuZApZmv9jEjE= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-425-PaPU-Cl-NeSWWBbdiEKkRw-1; Wed, 20 Nov 2024 09:32:21 -0500 X-MC-Unique: PaPU-Cl-NeSWWBbdiEKkRw-1 X-Mimecast-MFC-AGG-ID: PaPU-Cl-NeSWWBbdiEKkRw Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 3EE001955F41 for ; Wed, 20 Nov 2024 14:32:20 +0000 (UTC) Received: from prancer.redhat.com (unknown [10.42.28.103]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 5DA7B1956086 for ; Wed, 20 Nov 2024 14:32:19 +0000 (UTC) From: Nick Clifton To: binutils@sourceware.org Subject: RFC: Default ELF linker script refactoring Date: Wed, 20 Nov 2024 14:32:17 +0000 Message-ID: <877c8yht72.fsf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: fczd_CiOKVbcmwhQc9uJKjnsWvtVAfGsqc4mx8sEHc0_1732113140 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-8.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_ASCII_DIVIDERS, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP 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.30 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: binutils-bounces~patchwork=sourceware.org@sourceware.org Hi Guys, I have been working on refactoring the default linker script for ELF targets in order to make it easier to understand and modify. In particular I am interested in separating out the alignment operations from the section placement operations as I suspect that we are doing too much and/or incorrect alignment in various places. The patch below represents my progress so far. The comment at the start might be of interest to others since I find conditional shell script syntax very confusing, especially given the fact that there are multiple different ways of expressing the same operation. In theory this patch makes no actual changes to the linker scripts, well apart from some new comments, but I am posting it here to see if anyone has any comments, suggestions or concerns before I apply it. Cheers Nick diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc index 84b433256a6..30556ee776e 100644 --- a/ld/scripttempl/elf.sc +++ b/ld/scripttempl/elf.sc @@ -115,6 +115,50 @@ # # Each of these can also have corresponding .rel.* and .rela.* sections. +# ------------------------------------------------------------------------ +# I get very confused by the multiple forms of conditional shell script +# syntax that are used in this file so here is a note, maybe just for me, +# to explain how it works: +# +# The following all mean "if foo is defined then do/insert ": +# +# test -z "$foo" || +# test -n "$foo" && +# if test -n "$foo"; then +# if [ -n "$foo" ]; then +# ${foo-} +# +# Whereas the following all mean "if foo is undefined then do/insert ": +# +# test -n "$foo" || +# test -z "$foo" && +# if test -z "$foo"; then +# if [ -z "$foo" ]; then +# ${foo+} +# +# If multiple symbols are tested together then they operate as an IOR for +# positive tests and a NOR for negative tests. ie, the following all do +# if either or both of and are defined: +# +# test -z "$foo$bar" || +# test -n "$foo$bar" && +# if test -n "$foo$bar"; then +# +# Whilst the following only do if neither nor are defined: +# +# test -n "$foo$bar" || +# if -z "$foo$bar"; then +# test -z "$foo$bar" && +# +# Also: +# foo=${foo-${bar-${baz}}} +# means: +# If foo is defined, leave it unchanged. Otherwise if bar is defined +# then set foo equal to bar, otherwise set foo equal to baz. + +# NC. +# ------------------------------------------------------------------------ + if test -n "$NOP"; then FILL="=$NOP" else @@ -136,6 +180,7 @@ test "$LD_FLAG" = "N" && DATA_ADDR=. test -z "${ETEXT_NAME}" && ETEXT_NAME=${USER_LABEL_PREFIX}etext test -n "$RELRO_NOW" && unset SEPARATE_GOTPLT test -z "$ATTRS_SECTIONS" && ATTRS_SECTIONS=".gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }" + if test -z "$DATA_SEGMENT_ALIGN"; then test -n "$CREATE_SHLIB$CREATE_PIE" && test -n "$SHLIB_DATA_ADDR" && COMMONPAGESIZE="" test -z "$CREATE_SHLIB$CREATE_PIE" && test -n "$DATA_ADDR" && COMMONPAGESIZE="" @@ -144,7 +189,8 @@ if test -z "$DATA_SEGMENT_ALIGN"; then DATA_SEGMENT_END="" if test -n "${COMMONPAGESIZE}"; then if test "${SEGMENT_SIZE}" != "${MAXPAGESIZE}"; then - DATA_SEGMENT_ALIGN="ALIGN (${SEGMENT_SIZE}) - ((${MAXPAGESIZE} - .) & (${MAXPAGESIZE} - 1)); . = DATA_SEGMENT_ALIGN (${MAXPAGESIZE}, ${COMMONPAGESIZE})" + DATA_SEGMENT_ALIGN="ALIGN (${SEGMENT_SIZE}) - ((${MAXPAGESIZE} - .) & (${MAXPAGESIZE} - 1)); \ + . = DATA_SEGMENT_ALIGN (${MAXPAGESIZE}, ${COMMONPAGESIZE})" else DATA_SEGMENT_ALIGN="DATA_SEGMENT_ALIGN (${MAXPAGESIZE}, ${COMMONPAGESIZE})" fi @@ -152,15 +198,19 @@ if test -z "$DATA_SEGMENT_ALIGN"; then DATA_SEGMENT_RELRO_END=". = DATA_SEGMENT_RELRO_END (${SEPARATE_GOTPLT-0}, .);" fi fi + if test -z "${INITIAL_READONLY_SECTIONS}${CREATE_SHLIB}"; then INITIAL_READONLY_SECTIONS=".interp ${RELOCATING-0} : { *(.interp) }" fi + if test -z "$PLT"; then IPLT=".iplt ${RELOCATING-0} : { *(.iplt) }" PLT=".plt ${RELOCATING-0} : { *(.plt)${RELOCATING+${IREL_IN_PLT+ *(.iplt)}} } ${IREL_IN_PLT-$IPLT}" fi + test -n "${DATA_PLT-${BSS_PLT-text}}" && TEXT_PLT= + if test -z "$GOT"; then if test -z "$SEPARATE_GOTPLT"; then GOT=".got ${RELOCATING-0} : {${RELOCATING+ *(.got.plt) *(.igot.plt)} *(.got)${RELOCATING+ *(.igot)} }" @@ -233,17 +283,21 @@ if test -z "${NO_SMALL_DATA}"; then else NO_SMALL_DATA=" " fi + if test -z "${SDATA_GOT}${DATA_GOT}"; then if test -n "${NO_SMALL_DATA}"; then DATA_GOT=" " fi fi + if test -z "${SDATA_GOT}${DATA_GOT}"; then if test -z "${NO_SMALL_DATA}"; then SDATA_GOT=" " fi fi + test -n "$SEPARATE_GOTPLT" && SEPARATE_GOTPLT=" " + test "${LARGE_SECTIONS}" = "yes" && REL_LARGE=" .rel.ldata ${RELOCATING-0} : { *(.rel.ldata${RELOCATING+ .rel.ldata.* .rel.gnu.linkonce.l.*}) } .rela.ldata ${RELOCATING-0} : { *(.rela.ldata${RELOCATING+ .rela.ldata.* .rela.gnu.linkonce.l.*}) } @@ -251,23 +305,7 @@ test "${LARGE_SECTIONS}" = "yes" && REL_LARGE=" .rela.lbss ${RELOCATING-0} : { *(.rela.lbss${RELOCATING+ .rela.lbss.* .rela.gnu.linkonce.lb.*}) } .rel.lrodata ${RELOCATING-0} : { *(.rel.lrodata${RELOCATING+ .rel.lrodata.* .rel.gnu.linkonce.lr.*}) } .rela.lrodata ${RELOCATING-0} : { *(.rela.lrodata${RELOCATING+ .rela.lrodata.* .rela.gnu.linkonce.lr.*}) }" -test "${LARGE_SECTIONS}" = "yes" && LARGE_BSS=" - .lbss ${RELOCATING-0} : - { - ${RELOCATING+*(.dynlbss)} - *(.lbss${RELOCATING+ .lbss.* .gnu.linkonce.lb.*}) - ${RELOCATING+*(LARGE_COMMON)} - }" -test "${LARGE_SECTIONS}" = "yes" && LARGE_SECTIONS=" - .lrodata ${RELOCATING-0} ${RELOCATING+ALIGN(${MAXPAGESIZE}) + (. & (${MAXPAGESIZE} - 1))} : - { - *(.lrodata${RELOCATING+ .lrodata.* .gnu.linkonce.lr.*}) - } - .ldata ${RELOCATING-0} ${RELOCATING+ALIGN(${MAXPAGESIZE}) + (. & (${MAXPAGESIZE} - 1))} : - { - *(.ldata${RELOCATING+ .ldata.* .gnu.linkonce.l.*}) - ${RELOCATING+. = ALIGN(. != 0 ? ${ALIGNMENT} : 1);} - }" + if test "${ENABLE_INITFINI_ARRAY}" = "yes"; then SORT_INIT_ARRAY="KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))" SORT_FINI_ARRAY="KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))" @@ -279,26 +317,6 @@ else CTORS_IN_INIT_ARRAY= DTORS_IN_FINI_ARRAY= fi -PREINIT_ARRAY=".preinit_array : - { - ${CREATE_SHLIB-PROVIDE_HIDDEN ($(def_symbol "__preinit_array_start"));} - KEEP (*(.preinit_array)) - ${CREATE_SHLIB-PROVIDE_HIDDEN ($(def_symbol "__preinit_array_end"));} - }" -INIT_ARRAY=".init_array : - { - ${CREATE_SHLIB-PROVIDE_HIDDEN ($(def_symbol "__init_array_start"));} - ${SORT_INIT_ARRAY} - KEEP (*(.init_array ${CTORS_IN_INIT_ARRAY})) - ${CREATE_SHLIB-PROVIDE_HIDDEN ($(def_symbol "__init_array_end"));} - }" -FINI_ARRAY=".fini_array : - { - ${CREATE_SHLIB-PROVIDE_HIDDEN ($(def_symbol "__fini_array_start"));} - ${SORT_FINI_ARRAY} - KEEP (*(.fini_array ${DTORS_IN_FINI_ARRAY})) - ${CREATE_SHLIB-PROVIDE_HIDDEN ($(def_symbol "__fini_array_end"));} - }" CTOR=".ctors ${CONSTRUCTING-0} : { ${CONSTRUCTING+${CTOR_START}} @@ -335,32 +353,6 @@ DTOR=".dtors ${CONSTRUCTING-0} : KEEP (*(.dtors)) ${CONSTRUCTING+${DTOR_END}} }" -STACK=".stack ${RELOCATING-0}${RELOCATING+${STACK_ADDR}} : - { - ${RELOCATING+$(def_symbol "_stack");} - *(.stack) - ${RELOCATING+${STACK_SENTINEL}} - }" -test "${HAVE_NOINIT}" = "yes" && NOINIT=" - /* This section contains data that is not initialized during load, - or during the application's initialization sequence. */ - .noinit ${RELOCATING-0} (NOLOAD) : ${RELOCATING+ALIGN(${ALIGNMENT})} - { - ${RELOCATING+PROVIDE (__noinit_start = .);} - *(.noinit${RELOCATING+ .noinit.* .gnu.linkonce.n.*}) - ${RELOCATING+. = ALIGN(${ALIGNMENT});} - ${RELOCATING+PROVIDE (__noinit_end = .);} - }" -test "${HAVE_PERSISTENT}" = "yes" && PERSISTENT=" - /* This section contains data that is initialized during load, - but not during the application's initialization sequence. */ - .persistent ${RELOCATING-0} : ${RELOCATING+ALIGN(${ALIGNMENT})} - { - ${RELOCATING+PROVIDE (__persistent_start = .);} - *(.persistent${RELOCATING+ .persistent.* .gnu.linkonce.p.*}) - ${RELOCATING+. = ALIGN(${ALIGNMENT});} - ${RELOCATING+PROVIDE (__persistent_end = .);} - }" TEXT_START_ADDR="SEGMENT_START(\"text-segment\", ${TEXT_START_ADDR})" SHLIB_TEXT_START_ADDR="SEGMENT_START(\"text-segment\", ${SHLIB_TEXT_START_ADDR:-0})" @@ -410,6 +402,20 @@ cat < ldscripts/dyntmp.$$ <> ldscripts/dyntmp.$$ <> ldscripts/dyntmp.$$ + cat >> ldscripts/dyntmp.$$ <> ldscripts/dyntmp.$$ + cat >> ldscripts/dyntmp.$$ <> ldscripts/dyntmp.$$ <