diff options
author | Ian Lance Taylor <ian@airs.com> | 1998-05-15 07:29:35 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1998-05-15 07:29:35 +0000 |
commit | 26c7ca95b46ccf6757225c0b9dfa832f530fc23b (patch) | |
tree | e2661ca761a139f7e1d8d4ba2b9edd36d46ade02 /ld | |
parent | f1a0162a2805dadd13b943e386ac9af09e921430 (diff) | |
download | gdb-26c7ca95b46ccf6757225c0b9dfa832f530fc23b.zip gdb-26c7ca95b46ccf6757225c0b9dfa832f530fc23b.tar.gz gdb-26c7ca95b46ccf6757225c0b9dfa832f530fc23b.tar.bz2 |
* ldlex.l: Recognize keyword SORT.
* ldgram.y (current_file): Change to struct wildcard_spec.
(%union): Add new fields cname and wildcard.
(wildcard_name, wildcard_spec): New nonterminals.
(file_NAME_list): Use wildcard_spec.
(input_section_spec): Change current_file usage.
* ld.h (struct wildcard_spec): Define.
* ldlang.h (lang_wild_statement_struct): Add new fields
sections_sorted and filenames_sorted.
(lang_add_wild): Update declaration.
* ldlang.c (wild_sort): New static function.
(wild_section): Use wild_sort.
(print_wild_statement): Print sorting information.
(lang_add_wild): Add new parameters sections_sorted and
filenames_sorted. Change all callers.
* mri.c (mri_draw_tree): Update calls to lang_add_wild.
* scripttempl/elf.sc: Sort .ctors.* and .dtors.* by section name.
* scripttempl/elfd10v.sc: Likewise.
* scripttempl/elfd30v.sc: Likewise.
* scripttempl/elfppc.sc: Likewise.
Diffstat (limited to 'ld')
-rw-r--r-- | ld/ChangeLog | 23 | ||||
-rw-r--r-- | ld/ld.h | 49 | ||||
-rw-r--r-- | ld/ldlang.c | 223 | ||||
-rw-r--r-- | ld/scripttempl/elf.sc | 44 | ||||
-rw-r--r-- | ld/scripttempl/elfd10v.sc | 198 | ||||
-rw-r--r-- | ld/scripttempl/elfd30v.sc | 18 | ||||
-rw-r--r-- | ld/scripttempl/elfppc.sc | 4 |
7 files changed, 464 insertions, 95 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index 7d643b1..457b6e8 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,26 @@ +Fri May 15 00:22:35 1998 Ian Lance Taylor <ian@cygnus.com> + + * ldlex.l: Recognize keyword SORT. + * ldgram.y (current_file): Change to struct wildcard_spec. + (%union): Add new fields cname and wildcard. + (wildcard_name, wildcard_spec): New nonterminals. + (file_NAME_list): Use wildcard_spec. + (input_section_spec): Change current_file usage. + * ld.h (struct wildcard_spec): Define. + * ldlang.h (lang_wild_statement_struct): Add new fields + sections_sorted and filenames_sorted. + (lang_add_wild): Update declaration. + * ldlang.c (wild_sort): New static function. + (wild_section): Use wild_sort. + (print_wild_statement): Print sorting information. + (lang_add_wild): Add new parameters sections_sorted and + filenames_sorted. Change all callers. + * mri.c (mri_draw_tree): Update calls to lang_add_wild. + * scripttempl/elf.sc: Sort .ctors.* and .dtors.* by section name. + * scripttempl/elfd10v.sc: Likewise. + * scripttempl/elfd30v.sc: Likewise. + * scripttempl/elfppc.sc: Likewise. + Thu May 14 18:39:16 1998 Richard Henderson <rth@cygnus.com> * emulparams/m32relf.sh (TEMPLATE_NAME): Define. @@ -1,5 +1,5 @@ /* ld.h -- general linker header file - Copyright (C) 1991, 93, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1991, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. This file is part of GLD, the Gnu Linker. @@ -21,27 +21,31 @@ #ifndef LD_H #define LD_H -#ifdef ENABLE_NLS -#include <libintl.h> -#define _(String) gettext (String) -#ifdef gettext_noop -#define N_(String) gettext_noop (String) -#else -#define N_(String) (String) +#ifdef HAVE_LOCALE_H +# include <locale.h> #endif + +#ifdef ENABLE_NLS +# include <libintl.h> +# define _(String) gettext (String) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif #else /* Stubs that do something close enough. */ -#define textdomain(String) (String) -#define gettext(String) (String) -#define dgettext(Domain,Message) (Message) -#define dcgettext(Domain,Message,Type) (Message) -#define bindtextdomain(Domain,Directory) (Domain) -#define _(String) (String) -#define N_(String) (String) -/* In this case we don't care about the value. */ -#ifndef LC_MESSAGES -#define LC_MESSAGES 0 +# define textdomain(String) (String) +# define gettext(String) (String) +# define dgettext(Domain,Message) (Message) +# define dcgettext(Domain,Message,Type) (Message) +# define bindtextdomain(Domain,Directory) (Domain) +# define _(String) (String) +# define N_(String) (String) #endif + +#ifndef LC_MESSAGES +# define LC_MESSAGES 0 #endif /* Look in this environment name for the linker to pretend to be */ @@ -55,6 +59,15 @@ discarded. */ #define DISCARD_SECTION_NAME "/DISCARD/" +/* A wildcard specification. This is only used in ldgram.y, but it + winds up in ldgram.h, so we need to define it outside. */ + +struct wildcard_spec +{ + const char *name; + boolean sorted; +}; + /* Extra information we hold on sections */ typedef struct user_section_struct { diff --git a/ld/ldlang.c b/ld/ldlang.c index e4a2af2..3721716 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -6,7 +6,7 @@ This file is part of GLD, the Gnu Linker. GLD 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 1, or (at your option) +the Free Software Foundation; either version 2, or (at your option) any later version. GLD is distributed in the hope that it will be useful, @@ -73,6 +73,9 @@ static void init_os PARAMS ((lang_output_section_statement_type *s)); static void exp_init_os PARAMS ((etree_type *)); static void section_already_linked PARAMS ((bfd *, asection *, PTR)); static boolean wildcardp PARAMS ((const char *)); +static lang_statement_union_type *wild_sort + PARAMS ((lang_wild_statement_type *, lang_input_statement_type *, + asection *)); static void wild_section PARAMS ((lang_wild_statement_type *ptr, const char *section, lang_input_statement_type *file, @@ -571,9 +574,9 @@ lang_map () { lang_memory_region_type *m; - minfo ("\nMemory Configuration\n\n"); + minfo (_("\nMemory Configuration\n\n")); fprintf (config.map_file, "%-16s %-18s %-18s %s\n", - "Name", "Origin", "Length", "Attributes"); + _("Name"), _("Origin"), _("Length"), _("Attributes")); for (m = lang_memory_region_list; m != (lang_memory_region_type *) NULL; @@ -615,7 +618,7 @@ lang_map () print_nl (); } - fprintf (config.map_file, "\nLinker script and memory map\n\n"); + fprintf (config.map_file, _("\nLinker script and memory map\n\n")); print_statements (); } @@ -632,7 +635,7 @@ init_os (s) return; if (strcmp (s->name, DISCARD_SECTION_NAME) == 0) - einfo ("%P%F: Illegal use of `%s' section", DISCARD_SECTION_NAME); + einfo (_("%P%F: Illegal use of `%s' section"), DISCARD_SECTION_NAME); new = ((section_userdata_type *) stat_alloc (sizeof (section_userdata_type))); @@ -642,7 +645,7 @@ init_os (s) s->bfd_section = bfd_make_section (output_bfd, s->name); if (s->bfd_section == (asection *) NULL) { - einfo ("%P%F: output format %s cannot represent section called %s\n", + einfo (_("%P%F: output format %s cannot represent section called %s\n"), output_bfd->xvec->name, s->name); } s->bfd_section->output_section = s->bfd_section; @@ -763,7 +766,7 @@ section_already_linked (abfd, sec, data) break; case SEC_LINK_DUPLICATES_ONE_ONLY: - einfo ("%P: %B: warning: ignoring duplicate section `%s'\n", + einfo (_("%P: %B: warning: ignoring duplicate section `%s'\n"), abfd, name); break; @@ -777,7 +780,7 @@ section_already_linked (abfd, sec, data) case SEC_LINK_DUPLICATES_SAME_SIZE: if (bfd_section_size (abfd, sec) != bfd_section_size (l->sec->owner, l->sec)) - einfo ("%P: %B: warning: duplicate section `%s' has different size\n", + einfo (_("%P: %B: warning: duplicate section `%s' has different size\n"), abfd, name); break; } @@ -948,6 +951,62 @@ wild_doit (ptr, section, output, file) } } +/* Handle wildcard sorting. This returns the lang_input_section which + should follow the one we are going to create for SECTION and FILE, + based on the sorting requirements of WILD. It returns NULL if the + new section should just go at the end of the current list. */ + +static lang_statement_union_type * +wild_sort (wild, file, section) + lang_wild_statement_type *wild; + lang_input_statement_type *file; + asection *section; +{ + const char *section_name; + lang_statement_union_type *l; + + if (! wild->filenames_sorted && ! wild->sections_sorted) + return NULL; + + section_name = bfd_get_section_name (file->the_bfd, section); + for (l = wild->children.head; l != NULL; l = l->next) + { + lang_input_section_type *ls; + + if (l->header.type != lang_input_section_enum) + continue; + ls = &l->input_section; + + /* Sorting by filename takes precedence over sorting by section + name. */ + + if (wild->filenames_sorted) + { + int i; + + i = strcmp (file->filename, ls->ifile->filename); + if (i < 0) + continue; + else if (i > 0) + break; + } + + /* Here either the files are not sorted by name, or we are + looking at the sections for this file. */ + + if (wild->sections_sorted) + { + if (strcmp (section_name, + bfd_get_section_name (ls->ifile->the_bfd, + ls->section)) + > 0) + break; + } + } + + return l; +} + /* Expand a wild statement for a particular FILE. SECTION may be NULL, in which case it is a wild card. */ @@ -992,8 +1051,38 @@ wild_section (ptr, section, file, output) else match = strcmp (section, name) == 0 ? true : false; } + if (match) - wild_doit (&ptr->children, s, output, file); + { + lang_statement_union_type *before; + + before = wild_sort (ptr, file, s); + + /* Here BEFORE points to the lang_input_section which + should follow the one we are about to add. If BEFORE + is NULL, then the section should just go at the end + of the current list. */ + + if (before == NULL) + wild_doit (&ptr->children, s, output, file); + else + { + lang_statement_list_type list; + lang_statement_union_type **pp; + + lang_list_init (&list); + wild_doit (&list, s, output, file); + ASSERT (list.head != NULL && list.head->next == NULL); + + for (pp = &ptr->children.head; + *pp != before; + pp = &(*pp)->next) + ASSERT (*pp != NULL); + + list.head->next = *pp; + *pp = list.head; + } + } } } } @@ -1062,15 +1151,15 @@ load_symbols (entry, place) { char **p; - einfo ("%B: file not recognized: %E\n", entry->the_bfd); - einfo ("%B: matching formats:", entry->the_bfd); + einfo (_("%B: file not recognized: %E\n"), entry->the_bfd); + einfo (_("%B: matching formats:"), entry->the_bfd); for (p = matching; *p != NULL; p++) einfo (" %s", *p); einfo ("%F\n"); } else if (err != bfd_error_file_not_recognized || place == NULL) - einfo ("%F%B: file not recognized: %E\n", entry->the_bfd); + einfo (_("%F%B: file not recognized: %E\n"), entry->the_bfd); bfd_close (entry->the_bfd); entry->the_bfd = NULL; @@ -1120,13 +1209,13 @@ load_symbols (entry, place) while (member != NULL) { if (! bfd_check_format (member, bfd_object)) - einfo ("%F%B: object %B in archive is not object\n", + einfo (_("%F%B: object %B in archive is not object\n"), entry->the_bfd, member); if (! ((*link_info.callbacks->add_archive_element) (&link_info, member, "--whole-archive"))) abort (); if (! bfd_link_add_symbols (member, &link_info)) - einfo ("%F%B: could not read symbols: %E\n", member); + einfo (_("%F%B: could not read symbols: %E\n"), member); member = bfd_openr_next_archived_file (entry->the_bfd, member); } @@ -1138,7 +1227,7 @@ load_symbols (entry, place) } if (! bfd_link_add_symbols (entry->the_bfd, &link_info)) - einfo ("%F%B: could not read symbols: %E\n", entry->the_bfd); + einfo (_("%F%B: could not read symbols: %E\n"), entry->the_bfd); entry->loaded = true; } @@ -1254,9 +1343,9 @@ open_output (name) { if (bfd_get_error () == bfd_error_invalid_target) { - einfo ("%P%F: target %s not found\n", output_target); + einfo (_("%P%F: target %s not found\n"), output_target); } - einfo ("%P%F: cannot open output file %s: %E\n", name); + einfo (_("%P%F: cannot open output file %s: %E\n"), name); } delete_output_file_on_failure = true; @@ -1264,15 +1353,15 @@ open_output (name) /* output->flags |= D_PAGED;*/ if (! bfd_set_format (output, bfd_object)) - einfo ("%P%F:%s: can not make object file: %E\n", name); + einfo (_("%P%F:%s: can not make object file: %E\n"), name); if (! bfd_set_arch_mach (output, ldfile_output_architecture, ldfile_output_machine)) - einfo ("%P%F:%s: can not set architecture: %E\n", name); + einfo (_("%P%F:%s: can not set architecture: %E\n"), name); link_info.hash = bfd_link_hash_table_create (output); if (link_info.hash == (struct bfd_link_hash_table *) NULL) - einfo ("%P%F: can not create link hash table: %E\n"); + einfo (_("%P%F: can not create link hash table: %E\n")); bfd_set_gp_size (output, g_switch_value); return output; @@ -1459,7 +1548,7 @@ lang_place_undefineds () h = bfd_link_hash_lookup (link_info.hash, ptr->name, true, false, true); if (h == (struct bfd_link_hash_entry *) NULL) - einfo ("%P%F: bfd_link_hash_lookup failed: %E\n"); + einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); if (h->type == bfd_link_hash_new) { h->type = bfd_link_hash_undefined; @@ -1582,7 +1671,7 @@ print_output_section_statement (output_section_statement) addr = exp_get_abs_int (output_section_statement->load_base, 0, "load base", lang_final_phase_enum); - minfo (" load address 0x%V", addr); + minfo (_(" load address 0x%V"), addr); } } @@ -1711,7 +1800,7 @@ print_input_section (in) --len; } - minfo ("%W (size before relaxing)\n", i->_raw_size); + minfo (_("%W (size before relaxing)\n"), i->_raw_size); } bfd_link_hash_traverse (link_info.hash, print_one_symbol, (PTR) i); @@ -1790,7 +1879,7 @@ static void print_address_statement (address) lang_address_statement_type *address; { - minfo ("Address of section %s set to ", address->section_name); + minfo (_("Address of section %s set to "), address->section_name); exp_print_tree (address->address); print_nl (); } @@ -1864,15 +1953,25 @@ print_wild_statement (w, os) { print_space (); + if (w->filenames_sorted) + minfo ("SORT("); if (w->filename != NULL) minfo ("%s", w->filename); else minfo ("*"); + if (w->filenames_sorted) + minfo (")"); + minfo ("("); + if (w->sections_sorted) + minfo ("SORT("); if (w->section_name != NULL) - minfo ("(%s)", w->section_name); + minfo ("%s", w->section_name); else - minfo ("(*)"); + minfo ("*"); + if (w->sections_sorted) + minfo (")"); + minfo (")"); print_nl (); @@ -1917,7 +2016,7 @@ print_statement (s, os) switch (s->header.type) { default: - fprintf (config.map_file, "Fail with %d\n", s->header.type); + fprintf (config.map_file, _("Fail with %d\n"), s->header.type); FAIL (); break; case lang_constructors_statement_enum: @@ -2143,7 +2242,7 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) if (os->children.head == NULL || os->children.head->next != NULL || os->children.head->header.type != lang_input_section_enum) - einfo ("%P%X: Internal error on COFF shared library section %s\n", + einfo (_("%P%X: Internal error on COFF shared library section %s\n"), os->name); input = os->children.head->input_section.section; @@ -2185,7 +2284,7 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) && lang_memory_region_list != NULL && (strcmp (lang_memory_region_list->name, "*default*") != 0 || lang_memory_region_list->next != NULL)) - einfo ("%P: warning: no memory region specified for section `%s'\n", + einfo (_("%P: warning: no memory region specified for section `%s'\n"), bfd_get_section_name (output_bfd, os->bfd_section)); dot = os->region->current; @@ -2196,7 +2295,7 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) olddot = dot; dot = align_power (dot, os->bfd_section->alignment_power); if (dot != olddot && config.warn_section_align) - einfo ("%P: warning: changing start of section %s by %u bytes\n", + einfo (_("%P: warning: changing start of section %s by %u bytes\n"), os->name, (unsigned int) (dot - olddot)); } } @@ -2210,7 +2309,7 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) dot, &dot); if (r.valid == false) { - einfo ("%F%S: non constant address expression for section %s\n", + einfo (_("%F%S: non constant address expression for section %s\n"), os->name); } dot = r.value + r.section->bfd_section->vma; @@ -2254,7 +2353,7 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) { if (os->addr_tree != (etree_type *) NULL) { - einfo ("%X%P: address 0x%v of %B section %s is not within region %s\n", + einfo (_("%X%P: address 0x%v of %B section %s is not within region %s\n"), os->region->current, os->bfd_section->owner, os->bfd_section->name, @@ -2262,7 +2361,7 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) } else { - einfo ("%X%P: region %s is full (%B section %s)\n", + einfo (_("%X%P: region %s is full (%B section %s)\n"), os->region->name, os->bfd_section->owner, os->bfd_section->name); @@ -2364,7 +2463,7 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) boolean again; if (! bfd_relax_section (i->owner, i, &link_info, &again)) - einfo ("%P%F: can't relax section: %E\n"); + einfo (_("%P%F: can't relax section: %E\n")); if (again) relax_again = true; } @@ -2391,7 +2490,7 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) dot, &newdot); - if (newdot != dot && !relax) + if (newdot != dot) { /* The assignment changed dot. Insert a pad. */ if (output_section_statement == abs_output_section) @@ -2400,7 +2499,7 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) the default memory address. */ lang_memory_region_lookup ("*default*")->current = newdot; } - else + else if (!relax) { lang_statement_union_type *new = ((lang_statement_union_type *) @@ -2525,7 +2624,7 @@ lang_do_assignments (s, output_section_statement, fill, dot) lang_final_phase_enum, dot, &dot); s->data_statement.value = value.value; if (value.valid == false) - einfo ("%F%P: invalid data statement\n"); + einfo (_("%F%P: invalid data statement\n")); } switch (s->data_statement.type) { @@ -2554,7 +2653,7 @@ lang_do_assignments (s, output_section_statement, fill, dot) lang_final_phase_enum, dot, &dot); s->reloc_statement.addend_value = value.value; if (value.valid == false) - einfo ("%F%P: invalid reloc statement\n"); + einfo (_("%F%P: invalid reloc statement\n")); } dot += bfd_get_reloc_size (s->reloc_statement.howto); break; @@ -2688,7 +2787,7 @@ lang_finish () h->u.def.section->output_section) + h->u.def.section->output_offset); if (! bfd_set_start_address (output_bfd, val)) - einfo ("%P%F:%s: can't set start address\n", entry_symbol); + einfo (_("%P%F:%s: can't set start address\n"), entry_symbol); } else { @@ -2700,16 +2799,16 @@ lang_finish () if (ts != (asection *) NULL) { if (warn) - einfo ("%P: warning: cannot find entry symbol %s; defaulting to %V\n", + einfo (_("%P: warning: cannot find entry symbol %s; defaulting to %V\n"), entry_symbol, bfd_get_section_vma (output_bfd, ts)); if (! bfd_set_start_address (output_bfd, bfd_get_section_vma (output_bfd, ts))) - einfo ("%P%F: can't set start address\n"); + einfo (_("%P%F: can't set start address\n")); } else { if (warn) - einfo ("%P: warning: cannot find entry symbol %s; not setting start address\n", + einfo (_("%P: warning: cannot find entry symbol %s; not setting start address\n"), entry_symbol); } } @@ -2750,7 +2849,7 @@ lang_check () if (compatible == NULL) { if (command_line.warn_mismatch) - einfo ("%P: warning: %s architecture of input file `%B' is incompatible with %s output\n", + einfo (_("%P: warning: %s architecture of input file `%B' is incompatible with %s output\n"), bfd_printable_name (input_bfd), input_bfd, bfd_printable_name (output_bfd)); } @@ -2768,7 +2867,7 @@ lang_check () if (! bfd_merge_private_bfd_data (input_bfd, output_bfd)) { if (command_line.warn_mismatch) - einfo ("%E%X: failed to merge target specific data of file %B\n", + einfo (_("%E%X: failed to merge target specific data of file %B\n"), input_bfd); } if (! command_line.warn_mismatch) @@ -2853,8 +2952,8 @@ lang_one_common (h, info) if (! header_printed) { - minfo ("\nAllocating common symbols\n"); - minfo ("Common symbol size file\n\n"); + minfo (_("\nAllocating common symbols\n")); + minfo (_("Common symbol size file\n\n")); header_printed = true; } @@ -2943,7 +3042,7 @@ lang_place_orphans () /* This message happens when using the svr3.ifile linker script, so I have disabled it. */ - info_msg ("%P: no [COMMON] command, defaulting to .bss\n"); + info_msg (_("%P: no [COMMON] command, defaulting to .bss\n")); #endif default_common_section = lang_output_section_statement_lookup (".bss"); @@ -3006,7 +3105,7 @@ lang_set_flags (ptr, flags) break; default: - einfo ("%P%F: invalid syntax in flags\n"); + einfo (_("%P%F: invalid syntax in flags\n")); break; } flags++; @@ -3329,9 +3428,11 @@ lang_process () /* EXPORTED TO YACC */ void -lang_add_wild (section_name, filename) - CONST char *CONST section_name; - CONST char *CONST filename; +lang_add_wild (section_name, sections_sorted, filename, filenames_sorted) + const char *const section_name; + boolean sections_sorted; + const char *const filename; + boolean filenames_sorted; { lang_wild_statement_type *new = new_stat (lang_wild_statement, stat_ptr); @@ -3345,7 +3446,9 @@ lang_add_wild (section_name, filename) lang_has_input_file = true; } new->section_name = section_name; + new->sections_sorted = sections_sorted; new->filename = filename; + new->filenames_sorted = filenames_sorted; lang_list_init (&new->children); } @@ -3504,7 +3607,7 @@ lang_startup (name) { if (startup_file != (char *) NULL) { - einfo ("%P%Fmultiple STARTUP files\n"); + einfo (_("%P%Fmultiple STARTUP files\n")); } first_file->filename = name; first_file->local_sym_name = name; @@ -3547,7 +3650,7 @@ lang_abs_symbol_at_beginning_of (secname, name) h = bfd_link_hash_lookup (link_info.hash, name, true, true, true); if (h == (struct bfd_link_hash_entry *) NULL) - einfo ("%P%F: bfd_link_hash_lookup failed: %E\n"); + einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); if (h->type == bfd_link_hash_new || h->type == bfd_link_hash_undefined) @@ -3581,7 +3684,7 @@ lang_abs_symbol_at_end_of (secname, name) h = bfd_link_hash_lookup (link_info.hash, name, true, true, true); if (h == (struct bfd_link_hash_entry *) NULL) - einfo ("%P%F: bfd_link_hash_lookup failed: %E\n"); + einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); if (h->type == bfd_link_hash_new || h->type == bfd_link_hash_undefined) @@ -3766,7 +3869,7 @@ lang_record_phdrs () flags, l->at == NULL ? false : true, at, l->filehdr, l->phdrs, c, secs)) - einfo ("%F%P: bfd_record_phdr failed: %E\n"); + einfo (_("%F%P: bfd_record_phdr failed: %E\n")); } free (secs); @@ -3785,7 +3888,7 @@ lang_record_phdrs () pl != NULL; pl = pl->next) if (! pl->used && strcmp (pl->name, "NONE") != 0) - einfo ("%X%P: section `%s' assigned to non-existent phdr `%s'\n", + einfo (_("%X%P: section `%s' assigned to non-existent phdr `%s'\n"), u->output_section_statement.name, pl->name); } } @@ -4054,7 +4157,7 @@ lang_register_vers_node (name, version, deps) /* Make sure this node has a unique name. */ for (t = lang_elf_version_info; t != NULL; t = t->next) if (strcmp (t->name, name) == 0) - einfo ("%X%P: duplicate version tag `%s'\n", name); + einfo (_("%X%P: duplicate version tag `%s'\n"), name); /* Check the global and local match names, and make sure there aren't any duplicates. */ @@ -4067,7 +4170,7 @@ lang_register_vers_node (name, version, deps) for (e2 = t->locals; e2 != NULL; e2 = e2->next) if (strcmp (e1->match, e2->match) == 0) - einfo ("%X%P: duplicate expression `%s' in version information\n", + einfo (_("%X%P: duplicate expression `%s' in version information\n"), e1->match); } } @@ -4080,7 +4183,7 @@ lang_register_vers_node (name, version, deps) for (e2 = t->globals; e2 != NULL; e2 = e2->next) if (strcmp (e1->match, e2->match) == 0) - einfo ("%X%P: duplicate expression `%s' in version information\n", + einfo (_("%X%P: duplicate expression `%s' in version information\n"), e1->match); } } @@ -4117,7 +4220,7 @@ lang_add_vers_depend (list, name) } } - einfo ("%X%P: unable to find version dependency `%s'\n", name); + einfo (_("%X%P: unable to find version dependency `%s'\n"), name); return ret; } diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc index 27f2e9d..5fceace 100644 --- a/ld/scripttempl/elf.sc +++ b/ld/scripttempl/elf.sc @@ -2,8 +2,10 @@ # Unusual variables checked by this code: # NOP - two byte opcode for no-op (defaults to 0) # DATA_ADDR - if end-of-text-plus-one-page isn't right for data start +# INITIAL_READONLY_SECTIONS - at start of text segment # OTHER_READONLY_SECTIONS - other than .text .init .rodata ... # (e.g., .PARISC.milli) +# OTHER_TEXT_SECTIONS - these get put in .text when relocating # OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ... # (e.g., .PARISC.global) # OTHER_SECTIONS - at the end @@ -13,21 +15,29 @@ # .text section. # DATA_START_SYMBOLS - symbols that appear at the start of the # .data section. +# OTHER_GOT_SYMBOLS - symbols defined just before .got. +# OTHER_GOT_SECTIONS - sections just after .got and .sdata. # OTHER_BSS_SYMBOLS - symbols that appear at the start of the # .bss section besides __bss_start. # DATA_PLT - .plt should be in data segment, not text segment. +# TEXT_DYNAMIC - .dynamic in text segment, not data segment. # EMBEDDED - whether this is for an embedded system. +# SHLIB_TEXT_START_ADDR - if set, add to SIZEOF_HEADERS to set +# start address of shared library. # # When adding sections, do note that the names of some sections are used # when specifying the start address of the next. # + test -z "$ENTRY" && ENTRY=_start test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT} test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT} if [ -z "$MACHINE" ]; then OUTPUT_ARCH=${ARCH}; else OUTPUT_ARCH=${ARCH}:${MACHINE}; fi +test -z "${ELFSIZE}" && ELFSIZE=32 test "$LD_FLAG" = "N" && DATA_ADDR=. INTERP=".interp ${RELOCATING-0} : { *(.interp) }" PLT=".plt ${RELOCATING-0} : { *(.plt) }" +DYNAMIC=".dynamic ${RELOCATING-0} : { *(.dynamic) }" # if this is for an embedded system, don't add SIZEOF_HEADERS. if [ -z "$EMBEDDED" ]; then @@ -54,8 +64,10 @@ SECTIONS { /* Read-only sections, merged into text segment: */ ${CREATE_SHLIB-${RELOCATING+. = ${TEXT_BASE_ADDRESS};}} - ${CREATE_SHLIB+${RELOCATING+. = SIZEOF_HEADERS;}} + ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_TEXT_START_ADDR:-0} + SIZEOF_HEADERS;}} ${CREATE_SHLIB-${INTERP}} + ${INITIAL_READONLY_SECTIONS} + ${TEXT_DYNAMIC+${DYNAMIC}} .hash ${RELOCATING-0} : { *(.hash) } .dynsym ${RELOCATING-0} : { *(.dynsym) } .dynstr ${RELOCATING-0} : { *(.dynstr) } @@ -63,17 +75,17 @@ SECTIONS .gnu.version_d ${RELOCATING-0} : { *(.gnu.version_d) } .gnu.version_r ${RELOCATING-0} : { *(.gnu.version_r) } .rel.text ${RELOCATING-0} : - { *(.rel.text) *(.rel.gnu.linkonce.t*) } + { *(.rel.text) ${RELOCATING+*(.rel.gnu.linkonce.t*)} } .rela.text ${RELOCATING-0} : - { *(.rela.text) *(.rela.gnu.linkonce.t*) } + { *(.rela.text) ${RELOCATING+*(.rela.gnu.linkonce.t*)} } .rel.data ${RELOCATING-0} : - { *(.rel.data) *(.rel.gnu.linkonce.d*) } + { *(.rel.data) ${RELOCATING+*(.rel.gnu.linkonce.d*)} } .rela.data ${RELOCATING-0} : - { *(.rela.data) *(.rela.gnu.linkonce.d*) } + { *(.rela.data) ${RELOCATING+*(.rela.gnu.linkonce.d*)} } .rel.rodata ${RELOCATING-0} : - { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } + { *(.rel.rodata) ${RELOCATING+*(.rel.gnu.linkonce.r*)} } .rela.rodata ${RELOCATING-0} : - { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } + { *(.rela.rodata) ${RELOCATING+*(.rela.gnu.linkonce.r*)} } .rel.got ${RELOCATING-0} : { *(.rel.got) } .rela.got ${RELOCATING-0} : { *(.rela.got) } .rel.ctors ${RELOCATING-0} : { *(.rel.ctors) } @@ -94,26 +106,29 @@ SECTIONS { ${RELOCATING+${TEXT_START_SYMBOLS}} *(.text) + *(.stub) /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) - *(.gnu.linkonce.t*) + ${RELOCATING+*(.gnu.linkonce.t*)} + ${RELOCATING+${OTHER_TEXT_SECTIONS}} } =${NOP-0} ${RELOCATING+_etext = .;} ${RELOCATING+PROVIDE (etext = .);} .fini ${RELOCATING-0} : { *(.fini) } =${NOP-0} - .rodata ${RELOCATING-0} : { *(.rodata) *(.gnu.linkonce.r*) } + .rodata ${RELOCATING-0} : { *(.rodata) ${RELOCATING+*(.gnu.linkonce.r*)} } .rodata1 ${RELOCATING-0} : { *(.rodata1) } ${RELOCATING+${OTHER_READONLY_SECTIONS}} /* Adjust the address for the data segment. We want to adjust up to the same address within the page on the next page up. */ - ${RELOCATING+. = ${DATA_ADDR-ALIGN(${MAXPAGESIZE}) + (. & (${MAXPAGESIZE} - 1))};} + ${CREATE_SHLIB-${RELOCATING+. = ${DATA_ADDR-ALIGN(${MAXPAGESIZE}) + (. & (${MAXPAGESIZE} - 1))};}} + ${CREATE_SHLIB+${RELOCATING+. = ${SHLIB_DATA_ADDR-ALIGN(${MAXPAGESIZE}) + (. & (${MAXPAGESIZE} - 1))};}} .data ${RELOCATING-0} : { ${RELOCATING+${DATA_START_SYMBOLS}} *(.data) - *(.gnu.linkonce.d*) + ${RELOCATING+*(.gnu.linkonce.d*)} ${CONSTRUCTING+CONSTRUCTORS} } .data1 ${RELOCATING-0} : { *(.data1) } @@ -121,22 +136,26 @@ SECTIONS .ctors ${RELOCATING-0} : { ${CONSTRUCTING+${CTOR_START}} + *(SORT(.ctors.*)) *(.ctors) ${CONSTRUCTING+${CTOR_END}} } .dtors ${RELOCATING-0} : { ${CONSTRUCTING+${DTOR_START}} + *(SORT(.dtors.*)) *(.dtors) ${CONSTRUCTING+${DTOR_END}} } ${DATA_PLT+${PLT}} + ${RELOCATING+${OTHER_GOT_SYMBOLS}} .got ${RELOCATING-0} : { *(.got.plt) *(.got) } - .dynamic ${RELOCATING-0} : { *(.dynamic) } + ${TEXT_DYNAMIC-${DYNAMIC}} /* We want the small data sections together, so single-instruction offsets can access them all, and initialized data all before uninitialized, so we can shorten the on-disk segment size. */ .sdata ${RELOCATING-0} : { *(.sdata) } + ${RELOCATING+${OTHER_GOT_SECTIONS}} ${RELOCATING+_edata = .;} ${RELOCATING+PROVIDE (edata = .);} ${RELOCATING+__bss_start = .;} @@ -148,6 +167,7 @@ SECTIONS *(.bss) *(COMMON) } + ${RELOCATING+. = ALIGN(${ELFSIZE} / 8);} ${RELOCATING+_end = . ;} ${RELOCATING+PROVIDE (end = .);} diff --git a/ld/scripttempl/elfd10v.sc b/ld/scripttempl/elfd10v.sc new file mode 100644 index 0000000..0356f1d --- /dev/null +++ b/ld/scripttempl/elfd10v.sc @@ -0,0 +1,198 @@ +# +# Unusual variables checked by this code: +# NOP - two byte opcode for no-op (defaults to 0) +# DATA_ADDR - if end-of-text-plus-one-page isn't right for data start +# OTHER_READONLY_SECTIONS - other than .text .init .rodata ... +# (e.g., .PARISC.milli) +# OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ... +# (e.g., .PARISC.global) +# OTHER_SECTIONS - at the end +# EXECUTABLE_SYMBOLS - symbols that must be defined for an +# executable (e.g., _DYNAMIC_LINK) +# TEXT_START_SYMBOLS - symbols that appear at the start of the +# .text section. +# DATA_START_SYMBOLS - symbols that appear at the start of the +# .data section. +# OTHER_BSS_SYMBOLS - symbols that appear at the start of the +# .bss section besides __bss_start. +# DATA_PLT - .plt should be in data segment, not text segment. +# EMBEDDED - whether this is for an embedded system. +# +# When adding sections, do note that the names of some sections are used +# when specifying the start address of the next. +# +test -z "$ENTRY" && ENTRY=_start +test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT} +test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT} +if [ -z "$MACHINE" ]; then OUTPUT_ARCH=${ARCH}; else OUTPUT_ARCH=${ARCH}:${MACHINE}; fi +test "$LD_FLAG" = "N" && DATA_ADDR=. +INTERP=".interp ${RELOCATING-0} : { *(.interp) }" +PLT=".plt ${RELOCATING-0} : { *(.plt) }" + +# if this is for an embedded system, don't add SIZEOF_HEADERS. +if [ -z "$EMBEDDED" ]; then + test -z "${READONLY_BASE_ADDRESS}" && READONLY_BASE_ADDRESS="${READONLY_START_ADDR} + SIZEOF_HEADERS" +else + test -z "${READONLY_BASE_ADDRESS}" && READONLY_BASE_ADDRESS="${READONLY_START_ADDR}" +fi + +cat <<EOF +OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}", + "${LITTLE_OUTPUT_FORMAT}") +OUTPUT_ARCH(${OUTPUT_ARCH}) +ENTRY(${ENTRY}) + +${RELOCATING+${LIB_SEARCH_DIRS}} +${RELOCATING+/* Do we need any of these for elf? + __DYNAMIC = 0; ${STACKZERO+${STACKZERO}} ${SHLIB_PATH+${SHLIB_PATH}} */} +${RELOCATING+${EXECUTABLE_SYMBOLS}} +${RELOCATING- /* For some reason, the Solaris linker makes bad executables + if gld -r is used and the intermediate file has sections starting + at non-zero addresses. Could be a Solaris ld bug, could be a GNU ld + bug. But for now assigning the zero vmas works. */} +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + ${CREATE_SHLIB-${RELOCATING+. = ${READONLY_BASE_ADDRESS};}} + ${CREATE_SHLIB+${RELOCATING+. = SIZEOF_HEADERS;}} + ${CREATE_SHLIB-${INTERP}} + .hash ${RELOCATING-0} : { *(.hash) } + .dynsym ${RELOCATING-0} : { *(.dynsym) } + .dynstr ${RELOCATING-0} : { *(.dynstr) } + .rel.text ${RELOCATING-0} : { *(.rel.text) } + .rela.text ${RELOCATING-0} : { *(.rela.text) } + .rel.data ${RELOCATING-0} : { *(.rel.data) } + .rela.data ${RELOCATING-0} : { *(.rela.data) } + .rel.rodata ${RELOCATING-0} : { *(.rel.rodata) } + .rela.rodata ${RELOCATING-0} : { *(.rela.rodata) } + .rel.got ${RELOCATING-0} : { *(.rel.got) } + .rela.got ${RELOCATING-0} : { *(.rela.got) } + .rel.ctors ${RELOCATING-0} : { *(.rel.ctors) } + .rela.ctors ${RELOCATING-0} : { *(.rela.ctors) } + .rel.dtors ${RELOCATING-0} : { *(.rel.dtors) } + .rela.dtors ${RELOCATING-0} : { *(.rela.dtors) } + .rel.init ${RELOCATING-0} : { *(.rel.init) } + .rela.init ${RELOCATING-0} : { *(.rela.init) } + .rel.fini ${RELOCATING-0} : { *(.rel.fini) } + .rela.fini ${RELOCATING-0} : { *(.rela.fini) } + .rel.bss ${RELOCATING-0} : { *(.rel.bss) } + .rela.bss ${RELOCATING-0} : { *(.rela.bss) } + .rel.plt ${RELOCATING-0} : { *(.rel.plt) } + .rela.plt ${RELOCATING-0} : { *(.rela.plt) } + ${DATA_PLT-${PLT}} + .rodata ${RELOCATING-0} : { *(.rodata) *(.gnu.linkonce.r*) } + .rodata1 ${RELOCATING-0} : { *(.rodata1) } + ${RELOCATING+${OTHER_READONLY_SECTIONS}} + + /* Adjust the address for the data segment. */ + ${RELOCATING+. = ${DATA_ADDR-ALIGN(4);}} + + .data ${RELOCATING-0} : + { + ${RELOCATING+${DATA_START_SYMBOLS}} + *(.data) + *(.gnu.linkonce.d*) + ${CONSTRUCTING+CONSTRUCTORS} + } + .data1 ${RELOCATING-0} : { *(.data1) } + ${RELOCATING+${OTHER_READWRITE_SECTIONS}} + .ctors ${RELOCATING-0} : + { + ${CONSTRUCTING+${CTOR_START}} + *(SORT(.ctors.*)) + *(.ctors) + ${CONSTRUCTING+${CTOR_END}} + } + .dtors ${RELOCATING-0} : + { + ${CONSTRUCTING+${DTOR_START}} + *(SORT(.dtors.*)) + *(.dtors) + ${CONSTRUCTING+${DTOR_END}} + } + .got ${RELOCATING-0} : { *(.got.plt) *(.got) } + .dynamic ${RELOCATING-0} : { *(.dynamic) } + ${DATA_PLT+${PLT}} + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata ${RELOCATING-0} : { *(.sdata) } + ${RELOCATING+_edata = .;} + ${RELOCATING+PROVIDE (edata = .);} + ${RELOCATING+__bss_start = .;} + ${RELOCATING+${OTHER_BSS_SYMBOLS}} + .sbss ${RELOCATING-0} : { *(.sbss) *(.scommon) } + .bss ${RELOCATING-0} : + { + *(.dynbss) + *(.bss) + *(COMMON) + } + ${RELOCATING+_end = . ;} + ${RELOCATING+PROVIDE (end = .);} + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + + .comment 0 : { *(.comment) } + + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + ${RELOCATING+${OTHER_RELOCATING_SECTIONS}} + + /* These must appear regardless of ${RELOCATING}. */ + ${OTHER_SECTIONS} + + + /* Hmmm, there's got to be a better way. This sets the stack to the + top of the simulator memory (i.e. top of 64K data space). */ + .stack 0x00007FFE : { _stack = .; *(.stack) } + + .text ${RELOCATING+${TEXT_START_ADDR}} : + { + ${RELOCATING+${TEXT_START_SYMBOLS}} + *(.init) + *(.fini) + *(.text) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t*) + } =${NOP-0} + ${RELOCATING+_etext = .;} + ${RELOCATING+PROVIDE (etext = .);} +} +EOF diff --git a/ld/scripttempl/elfd30v.sc b/ld/scripttempl/elfd30v.sc index f96ed05..036f645 100644 --- a/ld/scripttempl/elfd30v.sc +++ b/ld/scripttempl/elfd30v.sc @@ -4,9 +4,10 @@ OUTPUT_ARCH(${ARCH}) MEMORY { - text : ORIGIN = ${TEXT_START_ADDR}, LENGTH = ${TEXT_SIZE} - data : ORIGIN = ${DATA_START_ADDR}, LENGTH = ${DATA_SIZE} - emem : ORIGIN = ${EMEM_START_ADDR}, LENGTH = ${EMEM_SIZE} + text ${TEXT_DEF_SECTION} : ORIGIN = ${TEXT_START_ADDR}, LENGTH = ${TEXT_SIZE} + data ${DATA_DEF_SECTION} : ORIGIN = ${DATA_START_ADDR}, LENGTH = ${DATA_SIZE} + emem ${EMEM_DEF_SECTION} : ORIGIN = ${EMEM_START_ADDR}, LENGTH = ${EMEM_SIZE} + eit : ORIGIN = ${EIT_START_ADDR}, LENGTH = ${EIT_SIZE} } SECTIONS @@ -27,6 +28,7 @@ SECTIONS .rela.etext ${RELOCATING-0} : { *(.rela.etest) } .rela.sdata ${RELOCATING-0} : { *(.rela.sdata) } .rela.edata ${RELOCATING-0} : { *(.rela.edata) } + .rela.eit_v ${RELOCATING-0} : { *(.rela.eit_v) } .rela.sbss ${RELOCATING-0} : { *(.rela.sbss) } .rela.ebss ${RELOCATING-0} : { *(.rela.ebss) } .rela.srodata ${RELOCATING-0} : { *(.rela.srodata) } @@ -47,6 +49,7 @@ SECTIONS .rel.edata ${RELOCATING-0} : { *(.rel.edata) } .rel.sbss ${RELOCATING-0} : { *(.rel.sbss) } .rel.ebss ${RELOCATING-0} : { *(.rel.ebss) } + .rel.eit_v ${RELOCATING-0} : { *(.rel.eit_v) } .rel.srodata ${RELOCATING-0} : { *(.rel.srodata) } .rel.erodata ${RELOCATING-0} : { *(.rel.erodata) } .rel.got ${RELOCATING-0} : { *(.rel.got) } @@ -86,6 +89,7 @@ SECTIONS .ctors ${RELOCATING-0} : { ${CONSTRUCTING+ __CTOR_LIST__ = .; } + *(SORT(.ctors.*)) *(.ctors) ${CONSTRUCTING+ __CTOR_END__ = .; } } ${RELOCATING+ > ${DATA_MEMORY}} @@ -93,6 +97,7 @@ SECTIONS .dtors ${RELOCATING-0} : { ${CONSTRUCTING+ __DTOR_LIST__ = .; } + *(SORT(.dtors.*)) *(.dtors) ${CONSTRUCTING+ __DTOR_END__ = .; } } ${RELOCATING+ > ${DATA_MEMORY}} @@ -139,6 +144,13 @@ SECTIONS ${RELOCATING+ _end = . ; } } ${RELOCATING+ > ${DATA_MEMORY}} + .eit_v ${RELOCATING-0} : + { + ${RELOCATING+ PROVIDE (__eit_start = .) ; } + *(.eit_v) + ${RELOCATING+ PROVIDE (__eit_end = .) ; } + } ${RELOCATING+ > eit} + /* Stabs debugging sections. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } diff --git a/ld/scripttempl/elfppc.sc b/ld/scripttempl/elfppc.sc index 33763bf..5671d56 100644 --- a/ld/scripttempl/elfppc.sc +++ b/ld/scripttempl/elfppc.sc @@ -129,11 +129,11 @@ SECTIONS .got2 ${RELOCATING-0} : { *(.got2) } ${RELOCATING+PROVIDE (__CTOR_LIST__ = .);} - .ctors ${RELOCATING-0} : { *(.ctors) } + .ctors ${RELOCATING-0} : { *(SORT(.ctors.*)) *(.ctors) } ${RELOCATING+PROVIDE (__CTOR_END__ = .);} ${RELOCATING+PROVIDE (__DTOR_LIST__ = .);} - .dtors ${RELOCATING-0} : { *(.dtors) } + .dtors ${RELOCATING-0} : { *(SORT(.dtors.*)) *(.dtors) } ${RELOCATING+PROVIDE (__DTOR_END__ = .);} ${RELOCATING+PROVIDE (_FIXUP_START_ = .);} |