[ARM] Attach linker created dynamic sections to stub bfd
Alan Modra
amodra@gmail.com
Wed May 11 13:31:00 GMT 2016
Attaching dynamic sections to the first BFD is nice. For one, it's a
known good BFD of the right format. It also handles odd user input
better, say a file with a user .got section, always putting the
GOT/PLT headers first.
Because this does a little tidying as well as just $subject, I'm
asking for an ARM maintainer's approval before committing.
bfd/
* elf32-arm.c (struct elf32_arm_link_hash_table): Delete
bfd_of_glue_owner. Replace with root.dynobj throughout file.
(bfd_elf32_arm_add_glue_sections_to_bfd): Make static. Remove
relocatable check. Call from..
(bfd_elf32_arm_init_stub_bfd): ..here. New function. Set
root.dynobj and stub bfd class.
(bfd_elf32_arm_get_bfd_for_interworking): Delete.
(elf32_arm_check_relocs): Don't set root.dynobj.
* bfd-in.h (bfd_elf32_arm_get_bfd_for_interworking): Delete.
(bfd_elf32_arm_add_glue_sections_to_bfd): Delete.
(bfd_elf32_arm_init_stub_bfd): Declare.
* bfd-in2.h: Regenerate.
ld/
* emultempl/armelf.em (arm_elf_before_allocation): Delete NULL
dynobj code.
(arm_elf_create_output_section_statements): Call
bfd_elf32_arm_init_stub_bfd rather than
bfd_elf32_arm_add_glue_sections_to_bfd and
bfd_elf32_arm_get_bfd_for_interworking.
diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index a3a28e5..a83bb31 100644
--- a/bfd/bfd-in.h
+++ b/bfd/bfd-in.h
@@ -897,10 +897,7 @@ void bfd_elf32_arm_set_target_relocs
(bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
bfd_arm_stm32l4xx_fix, int, int, int, int, int);
-extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
- (bfd *, struct bfd_link_info *);
-
-extern bfd_boolean bfd_elf32_arm_add_glue_sections_to_bfd
+extern bfd_boolean bfd_elf32_arm_init_stub_bfd
(bfd *, struct bfd_link_info *);
/* ELF ARM mapping symbol support. */
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 326a728..946a0c5 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -3052,9 +3052,6 @@ struct elf32_arm_link_hash_table
struct a8_erratum_fix *a8_erratum_fixes;
unsigned int num_a8_erratum_fixes;
- /* An arbitrary input BFD chosen to hold the glue sections. */
- bfd * bfd_of_glue_owner;
-
/* Nonzero to output a BE8 image. */
int byteswap_code;
@@ -5989,23 +5986,23 @@ bfd_elf32_arm_allocate_interworking_sections (struct bfd_link_info * info)
globals = elf32_arm_hash_table (info);
BFD_ASSERT (globals != NULL);
- arm_allocate_glue_section_space (globals->bfd_of_glue_owner,
+ arm_allocate_glue_section_space (globals->root.dynobj,
globals->arm_glue_size,
ARM2THUMB_GLUE_SECTION_NAME);
- arm_allocate_glue_section_space (globals->bfd_of_glue_owner,
+ arm_allocate_glue_section_space (globals->root.dynobj,
globals->thumb_glue_size,
THUMB2ARM_GLUE_SECTION_NAME);
- arm_allocate_glue_section_space (globals->bfd_of_glue_owner,
+ arm_allocate_glue_section_space (globals->root.dynobj,
globals->vfp11_erratum_glue_size,
VFP11_ERRATUM_VENEER_SECTION_NAME);
- arm_allocate_glue_section_space (globals->bfd_of_glue_owner,
+ arm_allocate_glue_section_space (globals->root.dynobj,
globals->stm32l4xx_erratum_glue_size,
STM32L4XX_ERRATUM_VENEER_SECTION_NAME);
- arm_allocate_glue_section_space (globals->bfd_of_glue_owner,
+ arm_allocate_glue_section_space (globals->root.dynobj,
globals->bx_glue_size,
ARM_BX_GLUE_SECTION_NAME);
@@ -6030,10 +6027,10 @@ record_arm_to_thumb_glue (struct bfd_link_info * link_info,
globals = elf32_arm_hash_table (link_info);
BFD_ASSERT (globals != NULL);
- BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+ BFD_ASSERT (globals->root.dynobj != NULL);
- s = bfd_get_linker_section
- (globals->bfd_of_glue_owner, ARM2THUMB_GLUE_SECTION_NAME);
+ s = bfd_get_linker_section (globals->root.dynobj,
+ ARM2THUMB_GLUE_SECTION_NAME);
BFD_ASSERT (s != NULL);
@@ -6060,7 +6057,7 @@ record_arm_to_thumb_glue (struct bfd_link_info * link_info,
output yet - not that it is a Thumb function. */
bh = NULL;
val = globals->arm_glue_size + 1;
- _bfd_generic_link_add_one_symbol (link_info, globals->bfd_of_glue_owner,
+ _bfd_generic_link_add_one_symbol (link_info, globals->root.dynobj,
tmp_name, BSF_GLOBAL, s, val,
NULL, TRUE, FALSE, &bh);
@@ -6103,14 +6100,14 @@ record_arm_bx_glue (struct bfd_link_info * link_info, int reg)
globals = elf32_arm_hash_table (link_info);
BFD_ASSERT (globals != NULL);
- BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+ BFD_ASSERT (globals->root.dynobj != NULL);
/* Check if this veneer has already been allocated. */
if (globals->bx_glue_offset[reg])
return;
- s = bfd_get_linker_section
- (globals->bfd_of_glue_owner, ARM_BX_GLUE_SECTION_NAME);
+ s = bfd_get_linker_section (globals->root.dynobj,
+ ARM_BX_GLUE_SECTION_NAME);
BFD_ASSERT (s != NULL);
@@ -6129,7 +6126,7 @@ record_arm_bx_glue (struct bfd_link_info * link_info, int reg)
bh = NULL;
val = globals->bx_glue_size;
- _bfd_generic_link_add_one_symbol (link_info, globals->bfd_of_glue_owner,
+ _bfd_generic_link_add_one_symbol (link_info, globals->root.dynobj,
tmp_name, BSF_FUNCTION | BSF_LOCAL, s, val,
NULL, TRUE, FALSE, &bh);
@@ -6198,10 +6195,10 @@ record_vfp11_erratum_veneer (struct bfd_link_info *link_info,
hash_table = elf32_arm_hash_table (link_info);
BFD_ASSERT (hash_table != NULL);
- BFD_ASSERT (hash_table->bfd_of_glue_owner != NULL);
+ BFD_ASSERT (hash_table->root.dynobj != NULL);
- s = bfd_get_linker_section
- (hash_table->bfd_of_glue_owner, VFP11_ERRATUM_VENEER_SECTION_NAME);
+ s = bfd_get_linker_section (hash_table->root.dynobj,
+ VFP11_ERRATUM_VENEER_SECTION_NAME);
sec_data = elf32_arm_section_data (s);
@@ -6222,7 +6219,7 @@ record_vfp11_erratum_veneer (struct bfd_link_info *link_info,
bh = NULL;
val = hash_table->vfp11_erratum_glue_size;
- _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner,
+ _bfd_generic_link_add_one_symbol (link_info, hash_table->root.dynobj,
tmp_name, BSF_FUNCTION | BSF_LOCAL, s, val,
NULL, TRUE, FALSE, &bh);
@@ -6273,7 +6270,7 @@ record_vfp11_erratum_veneer (struct bfd_link_info *link_info,
/* FIXME: Creates an ARM symbol. Thumb mode will need attention if it
ever requires this erratum fix. */
_bfd_generic_link_add_one_symbol (link_info,
- hash_table->bfd_of_glue_owner, "$a",
+ hash_table->root.dynobj, "$a",
BSF_LOCAL, s, 0, NULL,
TRUE, FALSE, &bh);
@@ -6318,10 +6315,10 @@ record_stm32l4xx_erratum_veneer (struct bfd_link_info *link_info,
hash_table = elf32_arm_hash_table (link_info);
BFD_ASSERT (hash_table != NULL);
- BFD_ASSERT (hash_table->bfd_of_glue_owner != NULL);
+ BFD_ASSERT (hash_table->root.dynobj != NULL);
- s = bfd_get_linker_section
- (hash_table->bfd_of_glue_owner, STM32L4XX_ERRATUM_VENEER_SECTION_NAME);
+ s = bfd_get_linker_section (hash_table->root.dynobj,
+ STM32L4XX_ERRATUM_VENEER_SECTION_NAME);
BFD_ASSERT (s != NULL);
@@ -6342,7 +6339,7 @@ record_stm32l4xx_erratum_veneer (struct bfd_link_info *link_info,
bh = NULL;
val = hash_table->stm32l4xx_erratum_glue_size;
- _bfd_generic_link_add_one_symbol (link_info, hash_table->bfd_of_glue_owner,
+ _bfd_generic_link_add_one_symbol (link_info, hash_table->root.dynobj,
tmp_name, BSF_FUNCTION | BSF_LOCAL, s, val,
NULL, TRUE, FALSE, &bh);
@@ -6392,7 +6389,7 @@ record_stm32l4xx_erratum_veneer (struct bfd_link_info *link_info,
bh = NULL;
/* Creates a THUMB symbol since there is no other choice. */
_bfd_generic_link_add_one_symbol (link_info,
- hash_table->bfd_of_glue_owner, "$t",
+ hash_table->root.dynobj, "$t",
BSF_LOCAL, s, 0, NULL,
TRUE, FALSE, &bh);
@@ -6456,7 +6453,7 @@ bfd_elf32_arm_use_long_plt (void)
/* Add the glue sections to ABFD. This function is called from the
linker scripts in ld/emultempl/{armelf}.em. */
-bfd_boolean
+static bfd_boolean
bfd_elf32_arm_add_glue_sections_to_bfd (bfd *abfd,
struct bfd_link_info *info)
{
@@ -6465,11 +6462,6 @@ bfd_elf32_arm_add_glue_sections_to_bfd (bfd *abfd,
&& globals->stm32l4xx_fix != BFD_ARM_STM32L4XX_FIX_NONE;
bfd_boolean addglue;
- /* If we are only performing a partial
- link do not bother adding the glue. */
- if (bfd_link_relocatable (info))
- return TRUE;
-
addglue = arm_make_glue_section (abfd, ARM2THUMB_GLUE_SECTION_NAME)
&& arm_make_glue_section (abfd, THUMB2ARM_GLUE_SECTION_NAME)
&& arm_make_glue_section (abfd, VFP11_ERRATUM_VENEER_SECTION_NAME)
@@ -6482,33 +6474,23 @@ bfd_elf32_arm_add_glue_sections_to_bfd (bfd *abfd,
&& arm_make_glue_section (abfd, STM32L4XX_ERRATUM_VENEER_SECTION_NAME);
}
-/* Select a BFD to be used to hold the sections used by the glue code.
- This function is called from the linker scripts in ld/emultempl/
- {armelf/pe}.em. */
+/* Initialize the linker stubs BFD so that we can use it for linker
+ created dynamic sections, and for glue.
+ This function is called from ld/emultempl/armelf.em. */
bfd_boolean
-bfd_elf32_arm_get_bfd_for_interworking (bfd *abfd, struct bfd_link_info *info)
+bfd_elf32_arm_init_stub_bfd (bfd *abfd, struct bfd_link_info *info)
{
- struct elf32_arm_link_hash_table *globals;
-
- /* If we are only performing a partial link
- do not bother getting a bfd to hold the glue. */
- if (bfd_link_relocatable (info))
- return TRUE;
+ struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
- /* Make sure we don't attach the glue sections to a dynamic object. */
- BFD_ASSERT (!(abfd->flags & DYNAMIC));
+ elf_elfheader (abfd)->e_ident[EI_CLASS] = ELFCLASS32;
+ htab->root.dynobj = abfd;
- globals = elf32_arm_hash_table (info);
- BFD_ASSERT (globals != NULL);
-
- if (globals->bfd_of_glue_owner != NULL)
+ if (bfd_link_relocatable (info))
return TRUE;
- /* Save the bfd for later use. */
- globals->bfd_of_glue_owner = abfd;
-
- return TRUE;
+ /* Also use the stub BFD for stubs placed in a single output section. */
+ return bfd_elf32_arm_add_glue_sections_to_bfd (abfd, info);
}
static void
@@ -6565,7 +6547,7 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd,
/* PR 5398: If we have not decided to include any loadable sections in
the output then we will not have a glue owner bfd. This is OK, it
just means that there is nothing else for us to do here. */
- if (globals->bfd_of_glue_owner == NULL)
+ if (globals->root.dynobj == NULL)
return TRUE;
/* Rummage around all the relocs and map the glue vectors. */
@@ -7836,11 +7818,11 @@ elf32_thumb_to_arm_stub (struct bfd_link_info * info,
globals = elf32_arm_hash_table (info);
BFD_ASSERT (globals != NULL);
- BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+ BFD_ASSERT (globals->root.dynobj != NULL);
my_offset = myh->root.u.def.value;
- s = bfd_get_linker_section (globals->bfd_of_glue_owner,
+ s = bfd_get_linker_section (globals->root.dynobj,
THUMB2ARM_GLUE_SECTION_NAME);
BFD_ASSERT (s != NULL);
@@ -7933,7 +7915,7 @@ elf32_arm_create_thumb_stub (struct bfd_link_info * info,
globals = elf32_arm_hash_table (info);
BFD_ASSERT (globals != NULL);
- BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+ BFD_ASSERT (globals->root.dynobj != NULL);
my_offset = myh->root.u.def.value;
@@ -8029,9 +8011,9 @@ elf32_arm_to_thumb_stub (struct bfd_link_info * info,
globals = elf32_arm_hash_table (info);
BFD_ASSERT (globals != NULL);
- BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+ BFD_ASSERT (globals->root.dynobj != NULL);
- s = bfd_get_linker_section (globals->bfd_of_glue_owner,
+ s = bfd_get_linker_section (globals->root.dynobj,
ARM2THUMB_GLUE_SECTION_NAME);
BFD_ASSERT (s != NULL);
BFD_ASSERT (s->contents != NULL);
@@ -8083,9 +8065,9 @@ elf32_arm_to_thumb_export_stub (struct elf_link_hash_entry *h, void * inf)
globals = elf32_arm_hash_table (info);
BFD_ASSERT (globals != NULL);
- BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+ BFD_ASSERT (globals->root.dynobj != NULL);
- s = bfd_get_linker_section (globals->bfd_of_glue_owner,
+ s = bfd_get_linker_section (globals->root.dynobj,
ARM2THUMB_GLUE_SECTION_NAME);
BFD_ASSERT (s != NULL);
BFD_ASSERT (s->contents != NULL);
@@ -8118,9 +8100,9 @@ elf32_arm_bx_glue (struct bfd_link_info * info, int reg)
globals = elf32_arm_hash_table (info);
BFD_ASSERT (globals != NULL);
- BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
+ BFD_ASSERT (globals->root.dynobj != NULL);
- s = bfd_get_linker_section (globals->bfd_of_glue_owner,
+ s = bfd_get_linker_section (globals->root.dynobj,
ARM_BX_GLUE_SECTION_NAME);
BFD_ASSERT (s != NULL);
BFD_ASSERT (s->contents != NULL);
@@ -11936,30 +11918,30 @@ elf32_arm_final_link (bfd *abfd, struct bfd_link_info *info)
/* Write out any glue sections now that we have created all the
stubs. */
- if (globals->bfd_of_glue_owner != NULL)
+ if (globals->root.dynobj != NULL)
{
if (! elf32_arm_output_glue_section (info, abfd,
- globals->bfd_of_glue_owner,
+ globals->root.dynobj,
ARM2THUMB_GLUE_SECTION_NAME))
return FALSE;
if (! elf32_arm_output_glue_section (info, abfd,
- globals->bfd_of_glue_owner,
+ globals->root.dynobj,
THUMB2ARM_GLUE_SECTION_NAME))
return FALSE;
if (! elf32_arm_output_glue_section (info, abfd,
- globals->bfd_of_glue_owner,
+ globals->root.dynobj,
VFP11_ERRATUM_VENEER_SECTION_NAME))
return FALSE;
if (! elf32_arm_output_glue_section (info, abfd,
- globals->bfd_of_glue_owner,
+ globals->root.dynobj,
STM32L4XX_ERRATUM_VENEER_SECTION_NAME))
return FALSE;
if (! elf32_arm_output_glue_section (info, abfd,
- globals->bfd_of_glue_owner,
+ globals->root.dynobj,
ARM_BX_GLUE_SECTION_NAME))
return FALSE;
}
@@ -13532,8 +13514,6 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
return FALSE;
}
- if (htab->root.dynobj == NULL)
- htab->root.dynobj = abfd;
if (!create_ifunc_sections (info))
return FALSE;
@@ -16091,7 +16071,7 @@ elf32_arm_output_arch_local_syms (bfd *output_bfd,
/* ARM->Thumb glue. */
if (htab->arm_glue_size > 0)
{
- osi.sec = bfd_get_linker_section (htab->bfd_of_glue_owner,
+ osi.sec = bfd_get_linker_section (htab->root.dynobj,
ARM2THUMB_GLUE_SECTION_NAME);
osi.sec_shndx = _bfd_elf_section_from_bfd_section
@@ -16114,7 +16094,7 @@ elf32_arm_output_arch_local_syms (bfd *output_bfd,
/* Thumb->ARM glue. */
if (htab->thumb_glue_size > 0)
{
- osi.sec = bfd_get_linker_section (htab->bfd_of_glue_owner,
+ osi.sec = bfd_get_linker_section (htab->root.dynobj,
THUMB2ARM_GLUE_SECTION_NAME);
osi.sec_shndx = _bfd_elf_section_from_bfd_section
@@ -16131,7 +16111,7 @@ elf32_arm_output_arch_local_syms (bfd *output_bfd,
/* ARMv4 BX veneers. */
if (htab->bx_glue_size > 0)
{
- osi.sec = bfd_get_linker_section (htab->bfd_of_glue_owner,
+ osi.sec = bfd_get_linker_section (htab->root.dynobj,
ARM_BX_GLUE_SECTION_NAME);
osi.sec_shndx = _bfd_elf_section_from_bfd_section
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
index caa2fbf..044f7bd 100644
--- a/ld/emultempl/armelf.em
+++ b/ld/emultempl/armelf.em
@@ -83,29 +83,6 @@ arm_elf_before_allocation (void)
/* Auto-select Cortex-A8 erratum fix if it wasn't explicitly specified. */
bfd_elf32_arm_set_cortex_a8_fix (link_info.output_bfd, &link_info);
- /* We should be able to set the size of the interworking stub section. We
- can't do it until later if we have dynamic sections, though. */
- if (elf_hash_table (&link_info)->dynobj == NULL)
- {
- /* Here we rummage through the found bfds to collect glue information. */
- LANG_FOR_EACH_INPUT_STATEMENT (is)
- {
- /* Initialise mapping tables for code/data. */
- bfd_elf32_arm_init_maps (is->the_bfd);
-
- if (!bfd_elf32_arm_process_before_allocation (is->the_bfd,
- &link_info)
- || !bfd_elf32_arm_vfp11_erratum_scan (is->the_bfd, &link_info)
- || !bfd_elf32_arm_stm32l4xx_erratum_scan (is->the_bfd,
- &link_info))
- /* xgettext:c-format */
- einfo (_("Errors encountered processing file %s"), is->filename);
- }
-
- /* We have seen it all. Allocate it, and carry on. */
- bfd_elf32_arm_allocate_interworking_sections (& link_info);
- }
-
/* Call the standard elf routine. */
gld${EMULATION_NAME}_before_allocation ();
}
@@ -528,9 +505,8 @@ arm_elf_create_output_section_statements (void)
stub_file->the_bfd->flags |= BFD_LINKER_CREATED;
ldlang_add_file (stub_file);
- /* Also use the stub file for stubs placed in a single output section. */
- bfd_elf32_arm_add_glue_sections_to_bfd (stub_file->the_bfd, &link_info);
- bfd_elf32_arm_get_bfd_for_interworking (stub_file->the_bfd, &link_info);
+ if (!bfd_elf32_arm_init_stub_bfd (stub_file->the_bfd, &link_info))
+ einfo ("%X%P: can not create BFD %E\n");
}
/* Avoid processing the fake stub_file in vercheck, stat_needed and
--
Alan Modra
Australia Development Lab, IBM
More information about the Binutils
mailing list