aboutsummaryrefslogtreecommitdiff
path: root/ld/emultempl
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2021-01-13 13:33:34 +1030
committerAlan Modra <amodra@gmail.com>2021-01-13 22:06:02 +1030
commitb209b5a6b8a4433be961a0f016439f381de65bfc (patch)
treeb540de64953f26165ed65e17c6b96a58b95e30c8 /ld/emultempl
parent8c4645b4887660eb704f152f2a14c5108d56c9d7 (diff)
downloadfsf-binutils-gdb-b209b5a6b8a4433be961a0f016439f381de65bfc.zip
fsf-binutils-gdb-b209b5a6b8a4433be961a0f016439f381de65bfc.tar.gz
fsf-binutils-gdb-b209b5a6b8a4433be961a0f016439f381de65bfc.tar.bz2
SHF_LINK_ORDER fixup_link_order in ld
This moves the SHF_LINK_ORDER sorting from bfd_elf_final_link to the linker which means generic ELF targets now support SHF_LINK_ORDER and we cope with odd cases that require resizing of output sections. The patch also fixes two bugs in the current implementation, introduced by commit cd6d537c48fa. The pattern test used by that commit meant that sections matching something like "*(.IA_64.unwind* .gnu.linkonce.ia64unw.*)" would not properly sort a mix of sections matching the two wildcards. That commit also assumed a stable qsort. bfd/ PR 27160 * section.c (struct bfd_section): Remove pattern field. (BFD_FAKE_SECTION): Adjust to suit. * bfd-in2.h: Regenerate. * elflink.c (compare_link_order, elf_fixup_link_order): Delete. (bfd_elf_final_link): Don't call elf_fixup_link_order. ld/ PR 27160 * ldlang.h (lang_output_section_statement_type): Add data field. (lang_input_section_type, lang_section_bst_type): Add pattern field. (statement_list): Declare. (lang_add_section): Adjust prototype. * emultempl/aarch64elf.em: Adjust lang_add_section calls. * emultempl/armelf.em: Likewise. * emultempl/beos.em: Likewise. * emultempl/cskyelf.em: Likewise. * emultempl/hppaelf.em: Likewise. * emultempl/m68hc1xelf.em: Likewise. * emultempl/metagelf.em: Likewise. * emultempl/mipself.em: Likewise. * emultempl/mmo.em: Likewise. * emultempl/msp430.em: Likewise. * emultempl/nios2elf.em: Likewise. * emultempl/pe.em: Likewise. * emultempl/pep.em: Likewise. * emultempl/ppc64elf.em: Likewise. * emultempl/spuelf.em: Likewise. * emultempl/vms.em: Likewise. * ldelf.c: Likewise. * ldelfgen.c: Include ldctor.h. (struct os_sections): New. (add_link_order_input_section, link_order_scan): New functions. (compare_link_order, fixup_link_order): New functions. (ldelf_map_segments): Call link_order_scan and fixup_link_order. * ldlang.c (statement_list): Make global. (output_section_callback_fast): Save pattern in tree node. (lang_add_section): Add pattern parameter, save in lang_input_section. (output_section_callback_tree_to_list): Adjust lang_add_section calls. (lang_insert_orphan, output_section_callback): Likewise. (ldlang_place_orphan): Likewise. (gc_section_callback): Don't set section->pattern * testsuite/ld-elf/pr26256-2a.d: Don't xfail generic. * testsuite/ld-elf/pr26256-3b.d: Likewise. * testsuite/ld-elf/pr26256-2b.d: Likewise. notarget xgate.
Diffstat (limited to 'ld/emultempl')
-rw-r--r--ld/emultempl/aarch64elf.em2
-rw-r--r--ld/emultempl/armelf.em2
-rw-r--r--ld/emultempl/beos.em2
-rw-r--r--ld/emultempl/cskyelf.em2
-rw-r--r--ld/emultempl/hppaelf.em2
-rw-r--r--ld/emultempl/m68hc1xelf.em2
-rw-r--r--ld/emultempl/metagelf.em2
-rw-r--r--ld/emultempl/mipself.em2
-rw-r--r--ld/emultempl/mmo.em2
-rw-r--r--ld/emultempl/msp430.em5
-rw-r--r--ld/emultempl/nios2elf.em2
-rw-r--r--ld/emultempl/pe.em4
-rw-r--r--ld/emultempl/pep.em4
-rw-r--r--ld/emultempl/ppc64elf.em2
-rw-r--r--ld/emultempl/spuelf.em4
-rw-r--r--ld/emultempl/vms.em2
16 files changed, 21 insertions, 20 deletions
diff --git a/ld/emultempl/aarch64elf.em b/ld/emultempl/aarch64elf.em
index bda5afc..a185560 100644
--- a/ld/emultempl/aarch64elf.em
+++ b/ld/emultempl/aarch64elf.em
@@ -192,7 +192,7 @@ elf${ELFSIZE}_aarch64_add_stub_section (const char *stub_sec_name,
info.input_section = input_section;
lang_list_init (&info.add);
- lang_add_section (&info.add, stub_sec, NULL, os);
+ lang_add_section (&info.add, stub_sec, NULL, NULL, os);
if (info.add.head == NULL)
goto err_ret;
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
index 0c03108..a4cf93b 100644
--- a/ld/emultempl/armelf.em
+++ b/ld/emultempl/armelf.em
@@ -246,7 +246,7 @@ elf32_arm_add_stub_section (const char * stub_sec_name,
info.input_section = after_input_section;
lang_list_init (&info.add);
- lang_add_section (&info.add, stub_sec, NULL, os);
+ lang_add_section (&info.add, stub_sec, NULL, NULL, os);
if (info.add.head == NULL)
goto err_ret;
diff --git a/ld/emultempl/beos.em b/ld/emultempl/beos.em
index 64c0e11..bb4395f 100644
--- a/ld/emultempl/beos.em
+++ b/ld/emultempl/beos.em
@@ -704,7 +704,7 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
The sections still have to be sorted, but that has to wait until
all such sections have been processed by us. The sorting is done by
sort_sections. */
- lang_add_section (&l->wild_statement.children, s, NULL, os);
+ lang_add_section (&l->wild_statement.children, s, NULL, NULL, os);
return os;
}
diff --git a/ld/emultempl/cskyelf.em b/ld/emultempl/cskyelf.em
index ce4047b..ca38cf6 100644
--- a/ld/emultempl/cskyelf.em
+++ b/ld/emultempl/cskyelf.em
@@ -189,7 +189,7 @@ elf32_csky_add_stub_section (const char *stub_sec_name,
info.input_section = input_section;
lang_list_init (&info.add);
- lang_add_section (&info.add, stub_sec, NULL, os);
+ lang_add_section (&info.add, stub_sec, NULL, NULL, os);
if (info.add.head == NULL)
goto err_ret;
diff --git a/ld/emultempl/hppaelf.em b/ld/emultempl/hppaelf.em
index bbb8b7f..f195a17 100644
--- a/ld/emultempl/hppaelf.em
+++ b/ld/emultempl/hppaelf.em
@@ -193,7 +193,7 @@ hppaelf_add_stub_section (const char *stub_sec_name, asection *input_section)
info.input_section = input_section;
lang_list_init (&info.add);
- lang_add_section (&info.add, stub_sec, NULL, os);
+ lang_add_section (&info.add, stub_sec, NULL, NULL, os);
if (info.add.head == NULL)
goto err_ret;
diff --git a/ld/emultempl/m68hc1xelf.em b/ld/emultempl/m68hc1xelf.em
index c4546c6..212db7c 100644
--- a/ld/emultempl/m68hc1xelf.em
+++ b/ld/emultempl/m68hc1xelf.em
@@ -275,7 +275,7 @@ m68hc11elf_add_stub_section (const char *stub_sec_name,
at the correct place. */
info.input_section = tramp_section;
lang_list_init (&info.add);
- lang_add_section (&info.add, stub_sec, NULL, os);
+ lang_add_section (&info.add, stub_sec, NULL, NULL, os);
if (info.add.head == NULL)
goto err_ret;
diff --git a/ld/emultempl/metagelf.em b/ld/emultempl/metagelf.em
index 51bec07..41ada3f 100644
--- a/ld/emultempl/metagelf.em
+++ b/ld/emultempl/metagelf.em
@@ -169,7 +169,7 @@ metagelf_add_stub_section (const char *stub_sec_name, asection *input_section)
info.input_section = input_section;
lang_list_init (&info.add);
- lang_add_section (&info.add, stub_sec, NULL, os);
+ lang_add_section (&info.add, stub_sec, NULL, NULL, os);
if (info.add.head == NULL)
goto err_ret;
diff --git a/ld/emultempl/mipself.em b/ld/emultempl/mipself.em
index d27aa76..e27e53c 100644
--- a/ld/emultempl/mipself.em
+++ b/ld/emultempl/mipself.em
@@ -175,7 +175,7 @@ mips_add_stub_section (const char *stub_sec_name, asection *input_section,
/* Initialize a statement list that contains only the new statement. */
lang_list_init (&info.add);
- lang_add_section (&info.add, stub_sec, NULL, os);
+ lang_add_section (&info.add, stub_sec, NULL, NULL, os);
if (info.add.head == NULL)
goto err_ret;
diff --git a/ld/emultempl/mmo.em b/ld/emultempl/mmo.em
index 4289e77..fa0b19a 100644
--- a/ld/emultempl/mmo.em
+++ b/ld/emultempl/mmo.em
@@ -102,7 +102,7 @@ mmo_place_orphan (asection *s,
(regardless of whether the linker script lists it as input). */
if (os != NULL)
{
- lang_add_section (&os->children, s, NULL, os);
+ lang_add_section (&os->children, s, NULL, NULL, os);
return os;
}
diff --git a/ld/emultempl/msp430.em b/ld/emultempl/msp430.em
index e3ea3c6..7e364af 100644
--- a/ld/emultempl/msp430.em
+++ b/ld/emultempl/msp430.em
@@ -325,7 +325,7 @@ gld${EMULATION_NAME}_place_orphan (asection * s,
/* Always place orphaned sections in lower. Optimal placement of either
sections is performed later, once section sizes have been finalized. */
- lang_add_section (& lower->children, s, NULL, lower);
+ lang_add_section (& lower->children, s, NULL, NULL, lower);
end:
free (upper_name);
free (lower_name);
@@ -358,7 +358,8 @@ change_output_section (lang_statement_union_type **head,
lang_statement_list_type *old_list
= (lang_statement_list_type *) &old_os->children;
s->output_section = NULL;
- lang_add_section (&new_os->children, s, NULL, new_os);
+ lang_add_section (&new_os->children, s,
+ curr->input_section.pattern, NULL, new_os);
/* Remove the section from the old output section. */
if (prev == NULL)
diff --git a/ld/emultempl/nios2elf.em b/ld/emultempl/nios2elf.em
index 2905980..fcc2756 100644
--- a/ld/emultempl/nios2elf.em
+++ b/ld/emultempl/nios2elf.em
@@ -186,7 +186,7 @@ nios2elf_add_stub_section (const char *stub_sec_name, asection *input_section,
info.input_section = input_section;
lang_list_init (&info.add);
- lang_add_section (&info.add, stub_sec, NULL, os);
+ lang_add_section (&info.add, stub_sec, NULL, NULL, os);
if (info.add.head == NULL)
goto err_ret;
diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index ab7d4c4..f9060be 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -2085,7 +2085,7 @@ gld_${EMULATION_NAME}_place_orphan (asection *s,
If the section already exists but does not have any flags set,
then it has been created by the linker, probably as a result of
a --section-start command line switch. */
- lang_add_section (&add_child, s, NULL, os);
+ lang_add_section (&add_child, s, NULL, NULL, os);
break;
}
@@ -2099,7 +2099,7 @@ gld_${EMULATION_NAME}_place_orphan (asection *s,
unused one and use that. */
if (os == NULL && match_by_name)
{
- lang_add_section (&match_by_name->children, s, NULL, match_by_name);
+ lang_add_section (&match_by_name->children, s, NULL, NULL, match_by_name);
return match_by_name;
}
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index 3fdd605..ca335b5 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -1905,7 +1905,7 @@ gld_${EMULATION_NAME}_place_orphan (asection *s,
If the section already exists but does not have any flags set,
then it has been created by the linker, probably as a result of
a --section-start command line switch. */
- lang_add_section (&add_child, s, NULL, os);
+ lang_add_section (&add_child, s, NULL, NULL, os);
break;
}
@@ -1919,7 +1919,7 @@ gld_${EMULATION_NAME}_place_orphan (asection *s,
unused one and use that. */
if (os == NULL && match_by_name)
{
- lang_add_section (&match_by_name->children, s, NULL, match_by_name);
+ lang_add_section (&match_by_name->children, s, NULL, NULL, match_by_name);
return match_by_name;
}
diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em
index 403fd09..8253604 100644
--- a/ld/emultempl/ppc64elf.em
+++ b/ld/emultempl/ppc64elf.em
@@ -445,7 +445,7 @@ ppc_add_stub_section (const char *stub_sec_name, asection *input_section)
info.input_section = input_section;
lang_list_init (&info.add);
- lang_add_section (&info.add, stub_sec, NULL, os);
+ lang_add_section (&info.add, stub_sec, NULL, NULL, os);
if (info.add.head == NULL)
goto err_ret;
diff --git a/ld/emultempl/spuelf.em b/ld/emultempl/spuelf.em
index 2afad3e..0c51b8e 100644
--- a/ld/emultempl/spuelf.em
+++ b/ld/emultempl/spuelf.em
@@ -151,7 +151,7 @@ spu_place_special_section (asection *s, asection *o, const char *output_name)
lang_statement_list_type add;
lang_list_init (&add);
- lang_add_section (&add, s, NULL, os);
+ lang_add_section (&add, s, NULL, NULL, os);
*add.tail = os->children.head;
os->children.head = add.head;
}
@@ -168,7 +168,7 @@ spu_place_special_section (asection *s, asection *o, const char *output_name)
lang_add_assignment (exp_assign (".", e_size, FALSE));
pop_stat_ptr ();
}
- lang_add_section (&os->children, s, NULL, os);
+ lang_add_section (&os->children, s, NULL, NULL, os);
}
s->output_section->size += s->size;
diff --git a/ld/emultempl/vms.em b/ld/emultempl/vms.em
index 3aa00e3..4c86962 100644
--- a/ld/emultempl/vms.em
+++ b/ld/emultempl/vms.em
@@ -116,7 +116,7 @@ vms_place_orphan (asection *s,
if (hold_data.os != NULL)
{
- lang_add_section (&hold_data.os->children, s, NULL, hold_data.os);
+ lang_add_section (&hold_data.os->children, s, NULL, NULL, hold_data.os);
return hold_data.os;
}
else