[ARM] Attach linker created dynamic sections to stub bfd

Richard Earnshaw (lists) Richard.Earnshaw@arm.com
Thu Jul 7 14:28:00 GMT 2016


On 11/05/16 14:31, Alan Modra wrote:
> 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.

Sorry for the delay, I'm very behind on my binutils mails.

Are you sure this is safe?  What if we're producing a static executable?

Perhaps the object is misnamed, but it sounds like something that's
related to the dynamic section.

R.

> 
> 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
> 



More information about the Binutils mailing list