From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-yb1-xb34.google.com (mail-yb1-xb34.google.com [IPv6:2607:f8b0:4864:20::b34]) by sourceware.org (Postfix) with ESMTPS id 1A74B3858C2A for ; Sat, 20 Jan 2024 14:13:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1A74B3858C2A Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 1A74B3858C2A Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::b34 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1705759988; cv=none; b=q68JBdkvD8+qmO5TE1oNDonZdEkSOhwEgFlgt0oR9DsvHmSBe1c+ahLAYOCp797YtBlRTVOxE7t+GmrKTSx12MJqJaqx4MTocm2pHrXYgXN2Ubp6jcqWSvNE0wnoYy5m8at6dt55kdrJwDO+5kyosEZNJH2lDRZQ2dqFLtHQYMw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1705759988; c=relaxed/simple; bh=Tqp6ZGJQh5w1gEGJMnUA5lIHEoAoKYJwa47JXZPbBpA=; h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To; b=uKs4Ze79znWSkB3GFw05sZk6JQMViAiv09hgpzKKHJO/m1nHB/zCI+Aisbf/uu3YkZX/gHuxolYU/y3h08Rys51rUegYZqIlzjVyD8HLKFy2Gk5DeysLfY1wErcn7dk25nLNhTpqYMghLdI+zHvdC93oaad+nQa6PrRJ69UTR+A= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-yb1-xb34.google.com with SMTP id 3f1490d57ef6-dc261316b0dso1308117276.3 for ; Sat, 20 Jan 2024 06:13:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1705759984; x=1706364784; darn=sourceware.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=w6SqVkLY/y4EnWRgrhYlMVQhKbHNh02mRmLQnUF4+NI=; b=DiIG0B6yIZsbFA8f9x6KVUWXR6gRXJkY4QoKR+kNrFzJP/YMol39XIREWFGxxPdjJB dapAYM23kxvA18ZqrsrSkd42jJmKNjnG5GfsgZ2FL0ytVy4dqC9N15AUEPF+plP8AH4P dklyuoaW5CftcUPgYD8MQz1CHcOlnrXjLzWdljmcKgU+PJD7z1SP4fT9/Scr9mas1VBM l8Ts45Ih2LnE0U48+BOWodpZsiXoyiLIHgUsvS6j34cmotD901U2Wspqyk9j9BxP/JUu u+sYj/SbXqXAd+cWcmBo+6gGXBK4qEqSEKSM6GyaQ6WYwmsrISy2HO3oTANRBD+sOVtR yf5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1705759984; x=1706364784; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=w6SqVkLY/y4EnWRgrhYlMVQhKbHNh02mRmLQnUF4+NI=; b=OPwucBwkfb5PMWlhYadlKSjkfculUMMsthGpBz8TngpXBhHD+KgwQuQTT1HpxUFhxS KNUp0J++4Znl/eUo955ck8x8/mBfoVDvn5Kat2yHxkguh/truaWjKJle6vkPF9zFNy2w i6h5G5MnUjaBVtYzort7qwrp/be/pSYwzscydpX5ejZl/FwVbytftuOMwTLrLXEilHq9 kaqbkG/7uGzxWU0tkOxiWWNGX8m+BNsAc9+0SPqGZnn9bv2jq+rT78IInFMjfgUJxeej XuoaMOlIcrnBPHncE4rz7ygfNhKYOsHq6N2cVD9WgosRsMme9URVM0y24cHfXyNAHGIW wT4A== X-Gm-Message-State: AOJu0YwVF8IhFwVYjvAsVuz4oybKIE4LG/HbxCHag9ZrAUYnkNHyqdnk BDD/hpr+LDor5IGDxGq89YiExItn7uFJBbBn7sGnNSlvlCcSr0b99GYA8qfC4BC2S3FA+25YdVt 3rfeEDdkgm4Kfr7o3R3og+T+TvEs= X-Google-Smtp-Source: AGHT+IHHeWxcgCuM3iS6j84dMQMb4bn1EBsz+o7sMp+okzQjFBf1N61CxXciKGV9ojSc0QMjSy4KCjtHAnqOL/4sB4I= X-Received: by 2002:a25:6887:0:b0:dc2:6618:7fcc with SMTP id d129-20020a256887000000b00dc266187fccmr847865ybc.126.1705759984234; Sat, 20 Jan 2024 06:13:04 -0800 (PST) MIME-Version: 1.0 References: <20240119194552.1255481-1-hjl.tools@gmail.com> <20240119194552.1255481-2-hjl.tools@gmail.com> In-Reply-To: From: "H.J. Lu" Date: Sat, 20 Jan 2024 06:12:28 -0800 Message-ID: Subject: Re: [PATCH 1/4] ld: Add --text-section-ordering-file FILE To: Fangrui Song Cc: binutils@sourceware.org, goldstein.w.n@gmail.com Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-3020.2 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,KAM_ASCII_DIVIDERS,KAM_INFOUSMEBIZ,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Fri, Jan 19, 2024 at 3:15=E2=80=AFPM Fangrui Song wrote: > > On Fri, Jan 19, 2024 at 2:13=E2=80=AFPM H.J. Lu wro= te: > > > > On Fri, Jan 19, 2024 at 1:57=E2=80=AFPM Fangrui Song wro= te: > > > > > > On Fri, Jan 19, 2024 at 11:45=E2=80=AFAM H.J. Lu wrote: > > > > > > > > Add --text-section-ordering-file FILE to specify the text section > > > > ordering file. Inside the text section ordering file, when seeing = an > > > > input file name without section list and the file name starts with = '.', > > > > treat the filename as a section name and create a wild card as the = file > > > > name. > > > > > > > > A text section ordering file which contains text section wildcards: > > > > > > > > --- > > > > text_section_foo* > > > > text_section_b?r > > > > text_section_name > > > > --- > > > > > > > > can be used to group input text sections together to: > > > > > > > > 1. Reduce gaps between text sections. > > > > 2. Put hot text sections close to each other. > > > > > > > > Text sections in the text section ordering file are placed at the > > > > beginning of the output text section and code text sections are mov= ed > > > > toward the end so that the first section in the text section orderi= ng > > > > file is aligned to the output section alignment. > > > > > > > > --text-section-ordering-file must be placed before -T/--script opti= on > > > > so that the text section ordering file can always be included in li= nker > > > > scripts. Nested INCLUDE in the text section order file is disallow= ed. > > > > > > > > NB: Gold has the command-line option, --section-ordering-file FILE,= to > > > > layout sections in the order specified. --text-section-ordering-fi= le > > > > supports the same section ordering file format, but it applies only= to > > > > text sections. > > > > > > Thanks for adding the feature to ld! However, I think a > > > symbol-oriented option likely works better than a section-oriented > > > option. > > > > > > https://maskray.me/blog/2020-11-15-explain-gnu-linker-options#symbol-= ordering-filefile > > > > > > This option (--symbol-ordering-file=3D) is unique to ld.lld. gold has= a > > > --section-ordering-file, sorted by section name. In practice, text an= d > > > data sections mostly have different names. However, clang > > > -fno-unique-section-names (GCC feature request > > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D95095) can create > > > sections of the same that defeat --section-ordering-file. > > > > --text-section-ordering-file is implemented on the existing linker fram= ework. > > A symbol-oriented option will require major changes in ld. > > > > > > > > > > > * ld.h (ld_config_type): Add text_section_ordering_file. > > > > * ldfile.c (in_text_section_ordering_file): New. > > > > (try_open): Add an argument for the original file name. Du= mp > > > > the text section order file for verbose output. > > > > (ldfile_find_command_file): Pass the original file name to > > > > try_open. > > > > (ldfile_open_command_file_1): Don't allow nested INCLUDE in= the > > > > text section order file. If the text section order file is > > > > specified, set in_text_section_ordering_file, load the file= and > > > > don't set saved_script_handle. Clear seen_eof_include_file= . > > > > * ldlang.c (lang_add_wild): When seeing an input file name > > > > without section list and the file name starts with '.', tre= at > > > > the filename as a section name and create a wild card as th= e > > > > file name. > > > > * ldlex.h (option_values): Add OPTION_TEXT_SECTION_ORDERING= _FILE. > > > > (in_text_section_ordering_file): New. > > > > (seen_eof_include_file): Likewise. > > > > * ldlex.l (in_text_section_ordering_file): New. > > > > (seen_eof_include_file): Likewise. > > > > (<>): Set seen_eof_include_file. > > > > * lexsup.c (ld_options): Document --text-section-ordering-f= ile. > > > > (parse_args): Handle OPTION_TEXT_SECTION_ORDERING_FILE. Is= sue > > > > an error if --text-section-ordering-file is placed after > > > > -T/--script. > > > > * scripttempl/elf.sc: Include the text section order file a= nd > > > > place code text sections toward the end. > > > > * testsuite/ld-scripts/start.s: New file. > > > > * testsuite/ld-scripts/text-order-1a.d: New file. > > > > * testsuite/ld-scripts/text-order-1a.s: Likewise. > > > > * testsuite/ld-scripts/text-order-1a.t: Likewise. > > > > * testsuite/ld-scripts/text-order-1b.d: Likewise. > > > > * testsuite/ld-scripts/text-order-1b.s: Likewise. > > > > * testsuite/ld-scripts/text-order-1b.t: Likewise. > > > > * testsuite/ld-scripts/text-order-1c.d: Likewise. > > > > * testsuite/ld-scripts/text-order-1d.t: Likewise. > > > > * testsuite/ld-scripts/text-order.exp: Likewise. > > > > --- > > > > ld/ld.h | 3 + > > > > ld/ldfile.c | 74 +++++++++++++++++++++= ++-- > > > > ld/ldlang.c | 39 +++++++++++-- > > > > ld/ldlex.h | 3 + > > > > ld/ldlex.l | 7 +++ > > > > ld/lexsup.c | 11 ++++ > > > > ld/scripttempl/elf.sc | 5 +- > > > > ld/testsuite/ld-scripts/start.s | 12 ++++ > > > > ld/testsuite/ld-scripts/text-order-1a.d | 20 +++++++ > > > > ld/testsuite/ld-scripts/text-order-1a.s | 8 +++ > > > > ld/testsuite/ld-scripts/text-order-1a.t | 5 ++ > > > > ld/testsuite/ld-scripts/text-order-1b.d | 20 +++++++ > > > > ld/testsuite/ld-scripts/text-order-1b.s | 8 +++ > > > > ld/testsuite/ld-scripts/text-order-1b.t | 4 ++ > > > > ld/testsuite/ld-scripts/text-order-1c.d | 9 +++ > > > > ld/testsuite/ld-scripts/text-order-1c.t | 5 ++ > > > > ld/testsuite/ld-scripts/text-order.exp | 42 ++++++++++++++ > > > > 17 files changed, 264 insertions(+), 11 deletions(-) > > > > create mode 100644 ld/testsuite/ld-scripts/start.s > > > > create mode 100644 ld/testsuite/ld-scripts/text-order-1a.d > > > > create mode 100644 ld/testsuite/ld-scripts/text-order-1a.s > > > > create mode 100644 ld/testsuite/ld-scripts/text-order-1a.t > > > > create mode 100644 ld/testsuite/ld-scripts/text-order-1b.d > > > > create mode 100644 ld/testsuite/ld-scripts/text-order-1b.s > > > > create mode 100644 ld/testsuite/ld-scripts/text-order-1b.t > > > > create mode 100644 ld/testsuite/ld-scripts/text-order-1c.d > > > > create mode 100644 ld/testsuite/ld-scripts/text-order-1c.t > > > > create mode 100644 ld/testsuite/ld-scripts/text-order.exp > > > > > > > > diff --git a/ld/ld.h b/ld/ld.h > > > > index 54d9079678c..a80255a73ba 100644 > > > > --- a/ld/ld.h > > > > +++ b/ld/ld.h > > > > @@ -316,6 +316,9 @@ typedef struct > > > > > > > > /* Compress DWARF debug sections. */ > > > > enum compressed_debug_section_type compress_debug; > > > > + > > > > + /* The optional text section ordering file. */ > > > > + const char *text_section_ordering_file; > > > > } ld_config_type; > > > > > > > > extern ld_config_type config; > > > > diff --git a/ld/ldfile.c b/ld/ldfile.c > > > > index dc9875d8813..6e9fbb7730f 100644 > > > > --- a/ld/ldfile.c > > > > +++ b/ld/ldfile.c > > > > @@ -736,7 +736,7 @@ ldfile_open_file (lang_input_statement_type *en= try) > > > > /* Try to open NAME. */ > > > > > > > > static FILE * > > > > -try_open (const char *name, bool *sysrooted) > > > > +try_open (const char *name, const char *orig_name, bool *sysrooted= ) > > > > { > > > > FILE *result; > > > > > > > > @@ -750,7 +750,34 @@ try_open (const char *name, bool *sysrooted) > > > > > > > > if (verbose) > > > > { > > > > - if (result =3D=3D NULL) > > > > + if (config.text_section_ordering_file !=3D NULL > > > > + && strcmp (orig_name, config.text_section_ordering_file) = =3D=3D 0) > > > > + { > > > > + if (result =3D=3D NULL) > > > > + info_msg (_("cannot find text section ordering file: %s= \n"), > > > > + name); > > > > + else > > > > + { > > > > + static const int ld_bufsz =3D 8193; > > > > + size_t n; > > > > + char *buf =3D (char *) xmalloc (ld_bufsz); > > > > + > > > > + info_msg (_("opened text section ordering file: %s\n"= ), > > > > + name); > > > > + info_msg ("=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n"); > > > > + > > > > + while ((n =3D fread (buf, 1, ld_bufsz - 1, result)) >= 0) > > > > + { > > > > + buf[n] =3D 0; > > > > + info_msg ("%s", buf); > > > > + } > > > > + rewind (result); > > > > + free (buf); > > > > + > > > > + info_msg ("=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n\n"); > > > > + } > > > > + } > > > > + else if (result =3D=3D NULL) > > > > info_msg (_("cannot find script file %s\n"), name); > > > > else > > > > info_msg (_("opened script file %s\n"), name); > > > > @@ -832,7 +859,7 @@ ldfile_find_command_file (const char *name, > > > > if (!default_only) > > > > { > > > > /* First try raw name. */ > > > > - result =3D try_open (name, sysrooted); > > > > + result =3D try_open (name, name, sysrooted); > > > > if (result !=3D NULL) > > > > return result; > > > > } > > > > @@ -859,7 +886,7 @@ ldfile_find_command_file (const char *name, > > > > search =3D search->next) > > > > { > > > > path =3D concat (search->name, slash, name, (const char *) N= ULL); > > > > - result =3D try_open (path, sysrooted); > > > > + result =3D try_open (path, name, sysrooted); > > > > free (path); > > > > if (result) > > > > break; > > > > @@ -908,6 +935,38 @@ ldfile_open_command_file_1 (const char *name, = enum script_open_style open_how) > > > > } > > > > } > > > > > > > > + /* Don't allow nested INCLUDE in the text section ordering file.= */ > > > > + if (in_text_section_ordering_file) > > > > + { > > > > + einfo (_("%F%P: error: nested include '%s' in the text secti= on " > > > > + "ordering file: '%s'\n"), name, > > > > + config.text_section_ordering_file); > > > > + return; > > > > + } > > > > + > > > > + if (strcmp (name, "config.text_section_ordering_file") =3D=3D 0) > > > > + { > > > > + /* Support > > > > + > > > > + INCLUDE config.text_section_ordering_file; > > > > + > > > > + in input text sections in linker script. */ > > > > + if (config.text_section_ordering_file =3D=3D NULL) > > > > + { > > > > + /* Skip if the text section ordering file isn't specified= . */ > > > > + lex_push_file (NULL, name, false); > > > > + return; > > > > + } > > > > + > > > > + /* Load the text section ordering file. */ > > > > + name =3D config.text_section_ordering_file; > > > > + > > > > + /* Set the in the text section ordering file marker. */ > > > > + in_text_section_ordering_file =3D 1; > > > > + } > > > > + else > > > > + in_text_section_ordering_file =3D 0; > > > > + > > > > /* FIXME: This memory is never freed, but that should not really= matter. > > > > It will be released when the linker exits, and it is unlikely= to ever > > > > be more than a few tens of bytes. */ > > > > @@ -932,7 +991,12 @@ ldfile_open_command_file_1 (const char *name, = enum script_open_style open_how) > > > > > > > > lineno =3D 1; > > > > > > > > - saved_script_handle =3D ldlex_input_stack; > > > > + /* Clear the end of the include file marker. */ > > > > + seen_eof_include_file =3D 0; > > > > + > > > > + /* The text section ordering file isn't a real linker script fil= e. */ > > > > + if (!in_text_section_ordering_file) > > > > + saved_script_handle =3D ldlex_input_stack; > > > > } > > > > > > > > /* Open command file NAME in the current directory, -L directories= , > > > > diff --git a/ld/ldlang.c b/ld/ldlang.c > > > > index 229401c8342..d2b4d43d8ae 100644 > > > > --- a/ld/ldlang.c > > > > +++ b/ld/ldlang.c > > > > @@ -8512,12 +8512,43 @@ lang_add_wild (struct wildcard_spec *filesp= ec, > > > > > > > > if (filespec !=3D NULL && filespec->name !=3D NULL) > > > > { > > > > - if (strcmp (filespec->name, "*") =3D=3D 0) > > > > - filespec->name =3D NULL; > > > > - else if (!wildcardp (filespec->name)) > > > > - lang_has_input_file =3D true; > > > > + if (in_text_section_ordering_file !=3D 0 > > > > + && section_list =3D=3D NULL > > > > + && filespec->name[0] =3D=3D '.' > > > > + && filespec->sorted =3D=3D none > > > > + && filespec->exclude_name_list =3D=3D NULL > > > > + && filespec->section_flag_list =3D=3D NULL > > > > + && !filespec->reversed) > > > > + { > > > > + /* When seeing an input file name without section list in= the > > > > + text section ordering file and the file name starts wi= th > > > > + '.', treat the filename as a section name and create a > > > > + wild card as the file name. */ > > > > + struct wildcard_list *single_section > > > > + =3D (struct wildcard_list *) xmalloc (sizeof (*single_s= ection)); > > > > + memset (single_section, 0, sizeof (*single_section)); > > > > + single_section->spec.name =3D filespec->name; > > > > + single_section->spec.sorted =3D none; > > > > + /* A NULL indicates the wild card file name, "*". */ > > > > + filespec->name =3D NULL; > > > > + section_list =3D single_section; > > > > + } > > > > + else > > > > + { > > > > + if (strcmp (filespec->name, "*") =3D=3D 0) > > > > + filespec->name =3D NULL; > > > > + else if (!wildcardp (filespec->name)) > > > > + lang_has_input_file =3D true; > > > > + } > > > > } > > > > > > > > + /* NB: Clear the in the text section ordering file marker after > > > > + processing the last entry when the end of the text section > > > > + ordering file is reached. */ > > > > + if (in_text_section_ordering_file !=3D 0 > > > > + && seen_eof_include_file !=3D 0) > > > > + in_text_section_ordering_file =3D 0; > > > > + > > > > new_stmt =3D new_stat (lang_wild_statement, stat_ptr); > > > > new_stmt->filename =3D NULL; > > > > new_stmt->filenames_sorted =3D false; > > > > diff --git a/ld/ldlex.h b/ld/ldlex.h > > > > index e5ac2fa7fca..a2c49656e1a 100644 > > > > --- a/ld/ldlex.h > > > > +++ b/ld/ldlex.h > > > > @@ -68,6 +68,7 @@ enum option_values > > > > OPTION_TASK_LINK, > > > > OPTION_TBSS, > > > > OPTION_TDATA, > > > > + OPTION_TEXT_SECTION_ORDERING_FILE, > > > > OPTION_TTEXT, > > > > OPTION_TTEXT_SEGMENT, > > > > OPTION_TRODATA_SEGMENT, > > > > @@ -484,6 +485,8 @@ extern input_type parser_input; > > > > > > > > extern unsigned int lineno; > > > > extern const char *lex_string; > > > > +extern int in_text_section_ordering_file; > > > > +extern int seen_eof_include_file; > > > > > > > > /* In ldlex.l. */ > > > > extern int yylex (void); > > > > diff --git a/ld/ldlex.l b/ld/ldlex.l > > > > index e113c90812b..b41e1220661 100644 > > > > --- a/ld/ldlex.l > > > > +++ b/ld/ldlex.l > > > > @@ -43,6 +43,12 @@ input_type parser_input; > > > > /* Line number in the current input file. */ > > > > unsigned int lineno; > > > > > > > > +/* 1 if the current input file is the text section ordering file. = */ > > > > +int in_text_section_ordering_file =3D 0; > > > > + > > > > +/* 1 if the end of the include file is reached. */ > > > > +int seen_eof_include_file =3D 0; > > > > + > > > > /* The string we are currently lexing, or NULL if we are reading a > > > > file. */ > > > > const char *lex_string =3D NULL; > > > > @@ -487,6 +493,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-= zA-Z0-9\[\]\-\!\^\\]|::)* > > > > > > > > lineno =3D lineno_stack[include_stack_ptr]; > > > > input_flags.sysrooted =3D sysrooted_stack[include_stack_ptr]; > > > > + seen_eof_include_file =3D 1; > > > > > > > > return END; > > > > } > > > > diff --git a/ld/lexsup.c b/ld/lexsup.c > > > > index 099dff8ecde..21385628020 100644 > > > > --- a/ld/lexsup.c > > > > +++ b/ld/lexsup.c > > > > @@ -484,6 +484,9 @@ static const struct ld_option ld_options[] =3D > > > > { {"sort-section", required_argument, NULL, OPTION_SORT_SECTION}= , > > > > '\0', N_("name|alignment"), > > > > N_("Sort sections by name or maximum alignment"), TWO_DASHES }= , > > > > + { {"text-section-ordering-file", required_argument, NULL, OPTION= _TEXT_SECTION_ORDERING_FILE}, > > > > + '\0', N_("FILE"), > > > > + N_("Sort text sections by FILE"), TWO_DASHES }, > > > > { {"spare-dynamic-tags", required_argument, NULL, OPTION_SPARE_D= YNAMIC_TAGS}, > > > > '\0', N_("COUNT"), N_("How many tags to reserve in .dynamic se= ction"), > > > > TWO_DASHES }, > > > > @@ -670,6 +673,7 @@ parse_args (unsigned argc, char **argv) > > > > dynamic_list > > > > } opt_dynamic_list =3D dynamic_list_unset; > > > > struct bfd_elf_dynamic_list *export_list =3D NULL; > > > > + bool seen_linker_script =3D false; > > > > > > > > shortopts =3D (char *) xmalloc (OPTION_COUNT * 3 + 2); > > > > longopts =3D (struct option *) > > > > @@ -1394,6 +1398,12 @@ parse_args (unsigned argc, char **argv) > > > > einfo (_("%F%P: invalid section sorting option: %s\n"), > > > > optarg); > > > > break; > > > > + case OPTION_TEXT_SECTION_ORDERING_FILE: > > > > + if (seen_linker_script) > > > > + einfo (_("%F%P: --text-section-ordering-file must be pl= aced" > > > > + " before -T/--script\n")); > > > > + config.text_section_ordering_file =3D optarg; > > > > + break; > > > > case OPTION_STATS: > > > > config.stats =3D true; > > > > break; > > > > @@ -1410,6 +1420,7 @@ parse_args (unsigned argc, char **argv) > > > > ++trace_files; > > > > break; > > > > case 'T': > > > > + seen_linker_script =3D true; > > > > previous_script_handle =3D saved_script_handle; > > > > ldfile_open_script_file (optarg); > > > > parser_input =3D input_script; > > > > diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc > > > > index fae7c2ad71c..8014dfbfa27 100644 > > > > --- a/ld/scripttempl/elf.sc > > > > +++ b/ld/scripttempl/elf.sc > > > > @@ -553,11 +553,12 @@ cat < > > > .text ${RELOCATING-0} : > > > > { > > > > ${RELOCATING+${TEXT_START_SYMBOLS}} > > > > + ${RELOCATING+INCLUDE config.text_section_ordering_file} > > > > + ${RELOCATING+*(.text.hot .text.hot.*)} > > > > + ${RELOCATING+*(SORT(.text.sorted.*))} > > > > ${RELOCATING+*(.text.unlikely .text.*_unlikely .text.unlikely.= *)} > > > > ${RELOCATING+*(.text.exit .text.exit.*)} > > > > ${RELOCATING+*(.text.startup .text.startup.*)} > > > > - ${RELOCATING+*(.text.hot .text.hot.*)} > > > > - ${RELOCATING+*(SORT(.text.sorted.*))} > > > > *(.text .stub${RELOCATING+ .text.* .gnu.linkonce.t.*}) > > > > /* .gnu.warning sections are handled specially by elf.em. */ > > > > *(.gnu.warning) > > I see the inflexibility of the current framework. > --text-section-ordering-file seems less general as I'd expect, and > placing ${RELOCATING+INCLUDE config.text_section_ordering_file} beside > the existing text input section descriptions does not make things more > flexible. > It is a shame that the new feature only applies to .text . Data > sections and other code sections should be reorderable as well. > > I believe tuning the semantics can make it more useful. > lld's -z keep-text-section-prefix and --symbol-ordering-file=3D work the > following way: > > * When -z keep-text-section-prefix is specified, .text.hot.* sections > are placed into the output section .text.hot. .text.unlikely, > .text.startup, etc are similar. Otherwise, all .text.* go to .text. > * There is no fixed order among the text output sections. The first > seen one wins. https://github.com/llvm/llvm-project/blob/main/lld/test/EL= F/text-section-prefix.s > If the user add `asm(".section .text.hot,\"axR\",%progbits"); > asm(".section .text.unlikely,\"axR\",%progbits");` to the crtbegin > source file, the output section order can be fixed in a desired way, > regardless of whether .text.startup/.text.hot appears first in > application code. > * Normally a wildcard pattern in an input section description (e.g. > *(.text .text.*)) uses the input order. However, if > --symbol-ordering-file=3D is specified, it overrides the order. > https://github.com/llvm/llvm-project/blob/main/lld/test/ELF/symbol-orderi= ng-file.s > > Back to GNU ld, I wonder whether we can say, when > config.text_section_ordering_file is present, drop all the existing > rules (e.g. ${RELOCATING+*(.text.exit .text.exit.*)}), and keep just > *(.text .text.*). > Make the ordering file decide how the wildcard is ordered. > Since the section order priorities in ld are 1. The exact section name match. 2. The first section name match. matches in --text-section-ordering-file will override other matches after INCLUDE. I updated my tests to show it: https://gitlab.com/x86-binutils/binutils-gdb/-/commit/cd5b222a2fed565e49dbc= 4b4d7b61de2380919b7 --=20 H.J.