From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id AF3413870C29 for ; Tue, 7 May 2024 16:40:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AF3413870C29 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 AF3413870C29 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=1715100008; cv=none; b=sTKDOJo6tfhUPZq4UJ7/7toFBdUm530k9PzGjKZleAMDh8CR+Jkzgwy1nCbfACFyvzl4en24Ya/9MtLgs8xfmMbjbqCuwQ5UFMfv2izji4RGjRbU8W9Fb1j56c0VjLCQOD2P4DSbIvn4U4MNsR+AL/oxN2X+IrCBeKwGMfk/UrE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1715100008; c=relaxed/simple; bh=GCs3T4926Ldu9SglYZPPrQTfIGl3OtFEl4K1KBA0Vec=; h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:To:From; b=OVxQ3FawlRNxMh9tN+B5jwCgMTyBJ2Qtxpiz/THseQDvkM2j8g9ociIqwVO4se7adf5v+GxBk17+g5xoJjJNceEMBEpDW4bwwUtUCHq/AY40+//kz5WAWas4uDe41ooLUhg68FfzKtWljlspcuL9a6BNbm33fECcl0jasLFPM90= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1715100006; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references:autocrypt:autocrypt; bh=6FhcJQ27Esoiu8qWYgOV7DALp4qkJlqjYhdVxuVmCZw=; b=NqTnKYIkZlgQ+1N4uulA12ChjnAKTV+fUlGQO+1rPaq6ZBg2Jxp+PyfAiiWOqOTOek9JXK nAcN77qMGaso5J5J8oVdR3haaH7OHOm2vXi5LnsdNmFPhlOMk376I4iUt37L2tnZrPBA73 FVq+HpMldqSwgOLggNcgv1SEZTskp2I= Received: from mail-qt1-f197.google.com (mail-qt1-f197.google.com [209.85.160.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-491-DlAEfwKvM06H_cvCdKo1nQ-1; Tue, 07 May 2024 12:40:02 -0400 X-MC-Unique: DlAEfwKvM06H_cvCdKo1nQ-1 Received: by mail-qt1-f197.google.com with SMTP id d75a77b69052e-437cb66a391so44569311cf.2 for ; Tue, 07 May 2024 09:40:02 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715100002; x=1715704802; h=in-reply-to:autocrypt:from:content-language:references:cc:to :subject:user-agent:mime-version:date:message-id:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=6FhcJQ27Esoiu8qWYgOV7DALp4qkJlqjYhdVxuVmCZw=; b=l/Fi9Tv3Aa92n9w/pZka340RO/YmSg/EXB+9uj00PlagJ83XahEskXCmqmuvS+eY6i hAbF0g3S56L0OK37s7NoA+fncKJPOLkuA3JLs4cuAzTQQrSLTi1CCdWs/FFVkTFocVuf ohuxy4oTH/ULNQNrAY9cABGnnH56b/gGEY8JWYEREuiyMPFqbF/PyJSrcSjVatuLJ3P0 WBNsQjUhOH5o6PCA9X3GlqQyAzbaQxfxXhWcWFfxPDl/NzxQrBkVRWbjBGWMKBZ6jCa/ zF6SBVFLvvQ3lC4b13aukCkeZGgalFR/dF/Dz4FdV27yuegmCgv4pOCcIjgZ/jGsn3Lx EfMQ== X-Gm-Message-State: AOJu0YzktzaHXsnjeSYFYkJPJ0r9SgqjksfzoFQCQwzMm50lsA5dA5rM 1c+sKLORkHxyhnWFPLN8QJdZxJ0xoqbzXq1V7H5iB7oohAZso/P/XXXa2e0Zr2QcnE2pOZ/6UNQ x7kuh406iAY5rRgJZVOpq6V6FOsfbaBS+Aa/qKHVD75uzw35UXRkYzZBeT71lWpHcxCtZoh5+Sv 4VLaaISqXJmOqmPZWXDjUXgolapG7QtAL5Or4= X-Received: by 2002:ac8:59cd:0:b0:439:dffd:3228 with SMTP id d75a77b69052e-43dbf3d28c5mr1875711cf.26.1715100001791; Tue, 07 May 2024 09:40:01 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHx0QTRfFSmqcZgocj38WAfdM21oXBTkdge17hCAAmupzjnf9J2K1wynfyD2YUW6CvHmoEFUQ== X-Received: by 2002:ac8:59cd:0:b0:439:dffd:3228 with SMTP id d75a77b69052e-43dbf3d28c5mr1875441cf.26.1715100001199; Tue, 07 May 2024 09:40:01 -0700 (PDT) Received: from [192.168.1.18] ([79.123.79.31]) by smtp.gmail.com with ESMTPSA id ci22-20020a05622a261600b0043476c7f668sm6609986qtb.5.2024.05.07.09.39.59 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 07 May 2024 09:40:00 -0700 (PDT) Message-ID: Date: Tue, 7 May 2024 17:39:58 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: RFC: ld: Add --text-section-ordering-file (version 4) To: Binutils Cc: hjl.tools@gmail.com, siddhesh@redhat.com References: <87edat7g1e.fsf@redhat.com> From: Nick Clifton Autocrypt: addr=nickc@redhat.com; keydata= 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 6susi2ReUyNJEJaSnjO5z13TQ1U= In-Reply-To: X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: multipart/mixed; boundary="------------qgQLM9Hq5GXSKVoHJ5JDBPbJ" Content-Language: en-GB X-Spam-Status: No, score=-3.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,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 List-Id: This is a multi-part message in MIME format. --------------qgQLM9Hq5GXSKVoHJ5JDBPbJ Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Hi Guys, So here is an augmented version of Alan's patch. All that it does is to add some documentation and enhance one of the tests so that it checks ordering the .data section as well as the .text section. Any comments ? If there is nothing too seriously wrong with it, I would like to check the patch in so that we can start testing it in the real world. We can always augment or change it later on, but it would be nice to have something that people can play with. Cheers Nick --------------qgQLM9Hq5GXSKVoHJ5JDBPbJ Content-Type: application/x-troff-man; name="section-ordering-file.patch.4" Content-Disposition: attachment; filename="section-ordering-file.patch.4" Content-Transfer-Encoding: 7bit diff --git a/ld/NEWS b/ld/NEWS index f70d2157339..00eb46047d1 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -1,5 +1,8 @@ -*- text -*- +* Add --section-ordering-file option to add extra mapping of input + sections to output sections. + * Add -plugin-save-temps to store plugin intermediate files permanently. Changes in 2.42: diff --git a/ld/ld.h b/ld/ld.h index fcdd9a2c083..0dee944cf2a 100644 --- a/ld/ld.h +++ b/ld/ld.h @@ -196,6 +196,9 @@ typedef struct /* Default linker script. */ char *default_script; + + /* Linker script fragment provided by the --section-order command line option. */ + char *section_ordering_file; } args_type; extern args_type command_line; @@ -325,6 +328,7 @@ extern ld_config_type config; extern FILE * saved_script_handle; extern bool force_make_executable; +extern bool in_section_ordering; extern int yyparse (void); extern void add_cref (const char *, bfd *, asection *, bfd_vma); diff --git a/ld/ld.texi b/ld/ld.texi index ca9574dfc71..231f5896549 100644 --- a/ld/ld.texi +++ b/ld/ld.texi @@ -302,6 +302,7 @@ and the script command language. If @emph{no} binary input files at all are specified, the linker does not produce any output, and issues the message @samp{No input files}. +@anchor{unrecognised-input-files} If the linker cannot recognize the format of an object file, it will assume that it is a linker script. A script specified in this way augments the main linker script used for the link (either the default @@ -1163,18 +1164,32 @@ a linker bug report. @itemx --script=@var{scriptfile} Use @var{scriptfile} as the linker script. This script replaces @command{ld}'s default linker script (rather than adding to it), -unless the script contains @code{INSERT}, so -@var{commandfile} must specify everything necessary to describe the -output file. @xref{Scripts}. If @var{scriptfile} does not exist in -the current directory, @code{ld} looks for it in the directories -specified by any preceding @samp{-L} options. Multiple @samp{-T} -options accumulate. +unless the script contains @code{INSERT}, so @var{commandfile} must +specify everything necessary to describe the output file. +@xref{Scripts}. + +If @var{scriptfile} does not exist in the current directory, @code{ld} +looks for it in the directories specified by any preceding @samp{-L} +options. + +Command line options that appear before the @option{-T} option can +affect the script, but command line options that appear after it do +not. + +Multiple @samp{-T} options will accumulate if they are augmenting the +current script, otherwise the last, non-augmenting, @option{-T} option +will be used. + +There are other ways of specifying linker scripts. See +@xref{--default-script}, @xref{--section-ordering-file} and +@xref{unrecognised-input-files}. @kindex -dT @var{script} @kindex --default-script=@var{script} @cindex script files @item -dT @var{scriptfile} @itemx --default-script=@var{scriptfile} +@anchor{--default-script} Use @var{scriptfile} as the default linker script. @xref{Scripts}. This option is similar to the @option{--script} option except that @@ -2521,6 +2536,53 @@ warning and continue with the link. @end ifset +@kindex --section-ordering-file +@item --section-ordering-file=@var{script} +@anchor{--section-ordering-file} +This option is used to augment the current linker script with +additional mapping of input sections to output sections. This file +must use the same syntax for @code{SECTIONS} as is used in normal +linker scripts, but it should not do anything other than place input +sections into output sections. @pxref{SECTIONS} + +A second constraint on the section ordering script is that it can only +reference output sections that are already defined by whichever linker +script is currently in use. (Ie the default linker script or a script +specified on the command line). The benefit of the section ordering +script however is that the input sections are mapped to the start of +the output sections, so that they can ensure the ordering of sections +in the output section. For example, imagine that the default linker +script looks like this: + +@smallexample +SECTIONS @{ + .text : @{ *(.text.hot) ; *(.text .text.*) @} + .data : @{ *(.data.big) ; *(.data .data.*) @} + @} +@end smallexample + +Then if a section ordering file like this is used: + +@smallexample +SECTIONS @{ + .text : @{ *(.text.first) ; *(.text.z*) @} + .data : @{ foo.o(.data.first) ; *(.data.small) @} + @} +@end smallexample + +This would be equivalent to a linker script like this: + +@smallexample +SECTIONS @{ + .text : @{ *(.text.first) ; *(.text.z*) ; *(.text.hot) ; *(.text .text.*) @} + .data : @{ foo.o(.data.first) ; *(.data.small) ; *(.data.big) ; *(.data .data.*) @} + @} +@end smallexample + +The advantage of the section ordering file is that it can be used to +order those sections that matter to the user without having to worry +about any other sections, or memory regions, or anything else. + @kindex -shared @kindex -Bshareable @item -shared diff --git a/ld/ldfile.c b/ld/ldfile.c index dc9875d8813..f1107a1b7d7 100644 --- a/ld/ldfile.c +++ b/ld/ldfile.c @@ -871,19 +871,7 @@ ldfile_find_command_file (const char *name, return result; } -enum script_open_style { - script_nonT, - script_T, - script_defaultT -}; - -struct script_name_list -{ - struct script_name_list *next; - enum script_open_style open_how; - char name[1]; -}; - +struct script_name_list *processed_scripts = NULL; /* Open command file NAME. */ static void @@ -891,7 +879,6 @@ ldfile_open_command_file_1 (const char *name, enum script_open_style open_how) { FILE *ldlex_input_stack; bool sysrooted; - static struct script_name_list *processed_scripts = NULL; struct script_name_list *script; size_t len; diff --git a/ld/ldfile.h b/ld/ldfile.h index f17677e9e9a..f79abf2310d 100644 --- a/ld/ldfile.h +++ b/ld/ldfile.h @@ -29,7 +29,8 @@ extern const char *ldfile_output_machine_name; /* Structure used to hold the list of directories to search for libraries. */ -typedef struct search_dirs { +typedef struct search_dirs +{ /* Next directory on list. */ struct search_dirs *next; /* Name of directory. */ @@ -38,6 +39,22 @@ typedef struct search_dirs { bool cmdline; } search_dirs_type; +enum script_open_style +{ + script_nonT, + script_T, + script_defaultT +}; + +struct script_name_list +{ + struct script_name_list * next; + enum script_open_style open_how; + char name[1]; +}; + +extern struct script_name_list * processed_scripts; + extern search_dirs_type *search_head; extern void ldfile_add_arch diff --git a/ld/ldlang.c b/ld/ldlang.c index 54d1af62ebe..9e8cc224f4d 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1299,6 +1299,7 @@ output_section_statement_newfunc (struct bfd_hash_entry *entry, ret->s.output_section_statement.section_alignment = NULL; ret->s.output_section_statement.block_value = 1; lang_list_init (&ret->s.output_section_statement.children); + lang_list_init (&ret->s.output_section_statement.sort_children); lang_statement_append (stat_ptr, &ret->s, &ret->s.header.next); /* For every output section statement added to the list, except the @@ -7613,13 +7614,22 @@ lang_enter_output_section_statement (const char *output_section_statement_name, lang_output_section_statement_type *os; os = lang_output_section_statement_lookup (output_section_statement_name, - constraint, 2); + constraint, + in_section_ordering ? 0 : 2); + if (os == NULL) /* && in_section_ordering */ + einfo (_("%F%P:%pS: error: output section '%s' must already exist\n"), + NULL, output_section_statement_name); current_section = os; + /* Make next things chain into subchain of this. */ + push_stat_ptr (in_section_ordering ? &os->sort_children : &os->children); + + if (in_section_ordering) + return os; + if (os->addr_tree == NULL) - { - os->addr_tree = address_exp; - } + os->addr_tree = address_exp; + os->sectype = sectype; if (sectype == type_section || sectype == typed_readonly_section) os->sectype_value = sectype_value; @@ -7629,9 +7639,6 @@ lang_enter_output_section_statement (const char *output_section_statement_name, os->flags = SEC_NO_FLAGS; os->block_value = 1; - /* Make next things chain into subchain of this. */ - push_stat_ptr (&os->children); - os->align_lma_with_input = align_with_input == ALIGN_WITH_INPUT; if (os->align_lma_with_input && align != NULL) einfo (_("%F%P:%pS: error: align with input and explicit align specified\n"), @@ -7971,21 +7978,6 @@ find_rescan_insertion (lang_input_statement_type *add) return iter; } -/* Insert SRCLIST into DESTLIST after given element by chaining - on FIELD as the next-pointer. (Counterintuitively does not need - a pointer to the actual after-node itself, just its chain field.) */ - -static void -lang_list_insert_after (lang_statement_list_type *destlist, - lang_statement_list_type *srclist, - lang_statement_union_type **field) -{ - *(srclist->tail) = *field; - *field = srclist->head; - if (destlist->tail == field) - destlist->tail = srclist->tail; -} - /* Detach new nodes added to DESTLIST since the time ORIGLIST was taken as a copy of it and leave them in ORIGLIST. */ @@ -8033,6 +8025,21 @@ find_next_input_statement (lang_statement_union_type **s) } #endif /* BFD_SUPPORTS_PLUGINS */ +/* Insert SRCLIST into DESTLIST after given element by chaining + on FIELD as the next-pointer. (Counterintuitively does not need + a pointer to the actual after-node itself, just its chain field.) */ + +static void +lang_list_insert_after (lang_statement_list_type *destlist, + lang_statement_list_type *srclist, + lang_statement_union_type **field) +{ + *(srclist->tail) = *field; + *field = srclist->head; + if (destlist->tail == field) + destlist->tail = srclist->tail; +} + /* Add NAME to the list of garbage collection entry points. */ void @@ -8127,9 +8134,34 @@ reset_resolved_wilds (void) lang_for_each_statement (reset_one_wild); } +/* For each output section statement, splice any entries on the + sort_children list before the first wild statement on the children + list. */ + +static void +lang_os_merge_sort_children (void) +{ + lang_output_section_statement_type *os; + for (os = (void *) lang_os_list.head; os != NULL; os = os->next) + { + if (os->sort_children.head != NULL) + { + lang_statement_union_type **where; + for (where = &os->children.head; + *where != NULL; + where = &(*where)->header.next) + if ((*where)->header.type == lang_wild_statement_enum) + break; + lang_list_insert_after (&os->children, &os->sort_children, where); + } + } +} + void lang_process (void) { + lang_os_merge_sort_children (); + /* Finalize dynamic list. */ if (link_info.dynamic_list) lang_finalize_version_expr_head (&link_info.dynamic_list->head); @@ -8817,6 +8849,10 @@ lang_leave_output_section_statement (fill_type *fill, const char *memspec, lang_output_section_phdr_list *phdrs, const char *lma_memspec) { + pop_stat_ptr (); + if (in_section_ordering) + return; + lang_get_regions (¤t_section->region, ¤t_section->lma_region, memspec, lma_memspec, @@ -8825,7 +8861,6 @@ lang_leave_output_section_statement (fill_type *fill, const char *memspec, current_section->fill = fill; current_section->phdrs = phdrs; - pop_stat_ptr (); } /* Set the output format type. -oformat overrides scripts. */ diff --git a/ld/ldlang.h b/ld/ldlang.h index ea1c26d00f3..4c1bb002f8e 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -141,7 +141,12 @@ typedef struct lang_output_section_phdr_list typedef struct lang_output_section_statement_struct { lang_statement_header_type header; + /* Input sections to be mapped to this output section. */ lang_statement_list_type children; + /* Input sections to be mapped to the start of this output section. + These sections are provided by the --section-ordering file, if used. */ + lang_statement_list_type sort_children; + struct lang_output_section_statement_struct *next; struct lang_output_section_statement_struct *prev; const char *name; diff --git a/ld/ldlex.h b/ld/ldlex.h index d575562a357..5708e6f5e34 100644 --- a/ld/ldlex.h +++ b/ld/ldlex.h @@ -62,6 +62,7 @@ enum option_values OPTION_SONAME, OPTION_SORT_COMMON, OPTION_SORT_SECTION, + OPTION_SECTION_ORDERING_FILE, OPTION_STATS, OPTION_SYMBOLIC, OPTION_SYMBOLIC_FUNCTIONS, diff --git a/ld/ldmain.c b/ld/ldmain.c index fe389681bd3..16c8298498d 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -90,6 +90,8 @@ bool version_printed; /* TRUE if we should demangle symbol names. */ bool demangling; +bool in_section_ordering; + args_type command_line; ld_config_type config; @@ -246,6 +248,26 @@ ld_bfd_error_handler (const char *fmt, va_list ap) (*default_bfd_error_handler) (fmt, ap); } +static void +display_external_script (void) +{ + if (saved_script_handle == NULL) + return; + + static const int ld_bufsz = 8193; + size_t n; + char *buf = (char *) xmalloc (ld_bufsz); + + rewind (saved_script_handle); + while ((n = fread (buf, 1, ld_bufsz - 1, saved_script_handle)) > 0) + { + buf[n] = 0; + info_msg ("%s", buf); + } + rewind (saved_script_handle); + free (buf); +} + int main (int argc, char **argv) { @@ -416,26 +438,13 @@ main (int argc, char **argv) if (verbose) { if (saved_script_handle) - info_msg (_("using external linker script:")); + info_msg (_("using external linker script: %s"), processed_scripts->name); else info_msg (_("using internal linker script:")); info_msg ("\n==================================================\n"); if (saved_script_handle) - { - static const int ld_bufsz = 8193; - size_t n; - char *buf = (char *) xmalloc (ld_bufsz); - - rewind (saved_script_handle); - while ((n = fread (buf, 1, ld_bufsz - 1, saved_script_handle)) > 0) - { - buf[n] = 0; - info_msg ("%s", buf); - } - rewind (saved_script_handle); - free (buf); - } + display_external_script (); else { int isfile; @@ -446,6 +455,22 @@ main (int argc, char **argv) info_msg ("\n==================================================\n"); } + if (command_line.section_ordering_file) + { + FILE *hold_script_handle; + + hold_script_handle = saved_script_handle; + ldfile_open_command_file (command_line.section_ordering_file); + if (verbose) + display_external_script (); + saved_script_handle = hold_script_handle; + in_section_ordering = true; + parser_input = input_script; + yyparse (); + in_section_ordering = false; + + } + if (command_line.force_group_allocation || !bfd_link_relocatable (&link_info)) link_info.resolve_section_groups = true; diff --git a/ld/lexsup.c b/ld/lexsup.c index dad3b6059ed..4125d849f2c 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -487,6 +487,9 @@ static const struct ld_option ld_options[] = { {"sort-section", required_argument, NULL, OPTION_SORT_SECTION}, '\0', N_("name|alignment"), N_("Sort sections by name or maximum alignment"), TWO_DASHES }, + { {"section-ordering-file", required_argument, NULL, OPTION_SECTION_ORDERING_FILE}, + '\0', N_("FILE"), + N_("Sort sections by statements in FILE"), TWO_DASHES }, { {"spare-dynamic-tags", required_argument, NULL, OPTION_SPARE_DYNAMIC_TAGS}, '\0', N_("COUNT"), N_("How many tags to reserve in .dynamic section"), TWO_DASHES }, @@ -1400,6 +1403,12 @@ parse_args (unsigned argc, char **argv) einfo (_("%F%P: invalid section sorting option: %s\n"), optarg); break; + case OPTION_SECTION_ORDERING_FILE: + if (command_line.section_ordering_file != NULL + && strcmp (optarg, command_line.section_ordering_file) != 0) + einfo (_("%P: warning: section ordering file changed. Ignoring earlier definition\n")); + command_line.section_ordering_file = optarg; + break; case OPTION_STATS: config.stats = true; break; --- /dev/null 2024-05-07 08:55:17.625424527 +0100 +++ current/ld/testsuite/ld-scripts/section-order.exp 2024-04-30 13:46:31.794038409 +0100 @@ -0,0 +1,45 @@ +# Test for --section-ordering-file FILE. +# Copyright (C) 2024 Free Software Foundation, Inc. +# +# This file is part of the GNU Binutils. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. + +# The --section-ordering-file option is only supported by ELF and +# PE COFF linkers, which allow for arbitrarily named sections, eg: +# .text.* +if { !([is_elf_format] || [is_pecoff_format]) } { + return +} + +set old_ldflags $LDFLAGS +if { [istarget spu*-*-*] } then { + set LDFLAGS "$LDFLAGS --local-store 0:0 --no-overlays" +} elseif { [is_pecoff_format] } then { + set LDFLAGS "$LDFLAGS --image-base 0" +} elseif { [is_xcoff_format] } then { + set LDFLAGS "$LDFLAGS -bnogc" +} + +set test_list [lsort [glob -nocomplain $srcdir/$subdir/section-order*.d]] +foreach test_file $test_list { + set test_name [file rootname $test_file] + set map_file "tmpdir/[file tail $test_name].map" + verbose $test_name + run_dump_test $test_name +} + +set LDFLAGS $old_ldflags --- /dev/null 2024-05-07 08:55:17.625424527 +0100 +++ current/ld/testsuite/ld-scripts/section-order-1a.d 2024-05-07 17:32:48.868700074 +0100 @@ -0,0 +1,31 @@ +#source: section-order-1b.s +#source: section-order-1a.s +#source: start.s +#ld: --section-ordering-file section-order-1a.t +#nm: -n + +#... +[0-9a-f]+ T yyy +#... +[0-9a-f]+ T bar +#... +[0-9a-f]+ T [_]+start +#... +[0-9a-f]+ T xxx +#... +[0-9a-f]+ T foo +#... +[0-9a-f]+ T qqq +#... +[0-9a-f]+ T zzz +#... +[0-9a-f]+ D small +#... +[0-9a-f]+ D big +#... +[0-9a-f]+ d bart +#... +[0-9a-f]+ D ccc +#... +[0-9a-f]+ D bbb +#pass --- /dev/null 2024-05-07 08:55:17.625424527 +0100 +++ current/ld/testsuite/ld-scripts/section-order-1a.t 2024-04-30 13:46:31.793038408 +0100 @@ -0,0 +1,15 @@ +SECTIONS +{ + .text : { + *(.text.yyy) + *(.text.b?r) + *(.text) + *(.text.xxx .text.foo) + } + + .data : { + *(.data.small) + *(.big*) + *(.bar .baz*) + } +} --- /dev/null 2024-05-07 08:55:17.625424527 +0100 +++ current/ld/testsuite/ld-scripts/section-order-1a.s 2024-05-07 15:36:27.933761373 +0100 @@ -0,0 +1,29 @@ + .section .text.foo + .globl foo +foo: + .dc.a 0 + + .section .text.bar + .globl bar +bar: + .dc.a 0 + + .section .data.small + .globl small +small: + .dc.a 0 + + .section .bar + .global bar +bart: + .dc.a 0 + + .section .text.zzz + .global zzz +zzz: + .dc.a 0 + + .section .data.bbb + .global bbb +bbb: + .dc.a 0 --- /dev/null 2024-05-07 08:55:17.625424527 +0100 +++ current/ld/testsuite/ld-scripts/section-order-1b.s 2024-05-07 15:40:15.191164328 +0100 @@ -0,0 +1,34 @@ + .section .text.xxx + .globl xxx +xxx: + .dc.a 0 + + .section .text.yyy + .globl yyy +yyy: + .dc.a 0 + + .section .big + .global big +big: + .dc.a 0 + + .section .baz + .global baz +baz: + .dc.a 0 + + .section .text.qqq + .global qqq +qqq: + .dc.a 0 + + .section .data.ccc + .global ccc +ccc: + .dc.a 0 + + .data + .global data_symbol +data_symbol: + .dc.a 0 --- /dev/null 2024-05-07 08:55:17.625424527 +0100 +++ current/ld/testsuite/ld-scripts/section-order-1b.d 2024-05-07 17:28:27.434992304 +0100 @@ -0,0 +1,17 @@ +#source: section-order-1a.s +#source: section-order-1b.s +#source: start.s +#ld: --section-ordering-file section-order-1b.t +#nm: -n + +#... +[0-9a-f]+ T yyy +#... +[0-9a-f]+ T bar +#... +[0-9a-f]+ T [_]+start +#... +[0-9a-f]+ T xxx +#... +[0-9a-f]+ T foo +#pass --- /dev/null 2024-05-07 08:55:17.625424527 +0100 +++ current/ld/testsuite/ld-scripts/section-order-1b.t 2024-04-30 13:46:31.794038409 +0100 @@ -0,0 +1,9 @@ +SECTIONS { + .text : { + *(.text.yyy) + *(.text.b?r) + *(*t) + *(.text.xxx) + *(.text.foo) + } +} --- /dev/null 2024-05-07 08:55:17.625424527 +0100 +++ current/ld/testsuite/ld-scripts/section-order-1c.d 2024-04-30 13:46:31.794038409 +0100 @@ -0,0 +1,13 @@ +#source: section-order-1b.s +#source: section-order-1a.s +#source: start.s +#ld: --section-ordering-file section-order-1a.t +#nm: -n + +#... +[0-9a-f]+ D small +#... +[0-9a-f]+ D big +#... +[0-9a-f]+ D ba.* +#pass --------------qgQLM9Hq5GXSKVoHJ5JDBPbJ--