Set dynamic tag VMA and size from dynamic section when possible

Marcin Kościelnicki koriakin@0x04.net
Wed Jun 8 15:47:00 GMT 2016


On 13/05/16 07:18, Alan Modra wrote:
> Rather than searching the output for a specific named section, it's
> better, where possible, to use a linker created dynamic section to set
> a dynamic tag's value.  That way ld doesn't depend on the output
> section name, making it possibile to map dynamic sections differently.
>
> The ARM backend used to report an error on a missing .rel.plt output
> section.  That no longer happens, because merging .rel.plt into
> .rel.dyn is now supported.  I've updated the testcase that used to
> check for an error, to instead check that dynamic relocs and tags
> are correct.

This silently breaks linking glibc on s390 (and any other shared library 
involving local STT_GNU_IFUNC) - .rela.plt and .rela.iplt are distinct 
linker sections, and DT_PLTRELSZ now includes only .rela.plt, so ld.so 
doesn't see R_390_IRELATIVE relocations at all.  I'll fix s390 (by 
including irelplt as well as srelplt in the calculation), but I'm going 
to guess some other architectures are affected as well.
>
> bfd/
> 	* elf-m10300.c (_bfd_mn10300_elf_finish_dynamic_sections): Use
> 	linker dynamic sections in calculating size and address of
> 	* dynamic tags rather than using output sections.  Remove asserts.
> 	* elf32-arm.c (elf32_arm_finish_dynamic_sections): Likewise.
> 	* elf32-cr16.c (_bfd_cr16_elf_finish_dynamic_sections): Likewise.
> 	* elf32-cris.c (elf_cris_finish_dynamic_sections): Likewise.
> 	* elf32-i370.c (i370_elf_finish_dynamic_sections): Likewise.
> 	* elf32-lm32.c (lm32_elf_finish_dynamic_sections): Likewise.
> 	* elf32-m32r.c (m32r_elf_finish_dynamic_sections): Likewise.
> 	* elf32-m68k.c (elf_m68k_finish_dynamic_sections): Likewise.
> 	* elf32-metag.c (elf_metag_finish_dynamic_sections): Likewise.
> 	* elf32-microblaze.c (microblaze_elf_finish_dynamic_sections): Likewise.
> 	* elf32-nds32.c (nds32_elf_finish_dynamic_sections): Likewise.
> 	* elf32-nios2.c (nios2_elf32_finish_dynamic_sections): Likewise.
> 	* elf32-or1k.c (or1k_elf_finish_dynamic_sections): Likewise.
> 	* elf32-s390.c (elf_s390_finish_dynamic_sections): Likewise.
> 	* elf32-score.c (s3_bfd_score_elf_finish_dynamic_sections): Likewise.
> 	* elf32-score7.c (s7_bfd_score_elf_finish_dynamic_sections): Likewise.
> 	* elf32-vax.c (elf_vax_finish_dynamic_sections): Likewise.
> 	* elf32-xtensa.c (elf_xtensa_finish_dynamic_sections): Likewise.
> 	* elf64-alpha.c (elf64_alpha_finish_dynamic_sections): Likewise.
> 	* elf64-s390.c (elf_s390_finish_dynamic_sections): Likewise.
> 	* elf64-sh64.c (sh64_elf64_finish_dynamic_sections): Likewise.
> 	* elflink.c (bfd_elf_final_link): Likewise.
> 	* elfxx-mips.c (_bfd_mips_elf_finish_dynamic_sections): Likewise.
> 	* elfxx-sparc.c (sparc_finish_dyn): Likewise.  Adjust error message.
> 	* elf32-arc.c (GET_SYMBOL_OR_SECTION): Remove ASSERT arg and
> 	don't set doit.  Look up dynobj section.
> 	(elf_arc_finish_dynamic_sections): Adjust GET_SYMBOL_OR_SECTION
> 	invocation and dynamic tag vma calculation.  Don't test
> 	boolean var == TRUE.
> 	* elfnn-aarch64.c (elfNN_aarch64_finish_dynamic_sections): Fix
> 	DT_JMPREL calc.
> ld/
> 	* testsuite/ld-arm/arm-elf.exp: Adjust for arm-no-rel-plt now passing.
> 	Use different output file name for static app without .rel.plt.
> 	* testsuite/ld-arm/arm-no-rel-plt.ld: Align .rel.dyn and .rela.dyn.
> 	* testsuite/ld-arm/arm-no-rel-plt.out: Delete.
> 	* testsuite/ld-arm/arm-no-rel-plt.r: New.
> 	* testsuite/ld-arm/arm-static-app.d: Don't check file name.
> 	* testsuite/ld-arm/arm-static-app.r: Likewise.
>
> diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c
> index 949f14a..c1936eb 100644
> --- a/bfd/elf-m10300.c
> +++ b/bfd/elf-m10300.c
> @@ -5462,15 +5462,13 @@ _bfd_mn10300_elf_finish_dynamic_sections (bfd * output_bfd,
>  	    case DT_JMPREL:
>  	      name = ".rela.plt";
>  	    get_vma:
> -	      s = bfd_get_section_by_name (output_bfd, name);
> -	      BFD_ASSERT (s != NULL);
> -	      dyn.d_un.d_ptr = s->vma;
> +	      s = bfd_get_linker_section (dynobj, name);
> +	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>  	      break;
>
>  	    case DT_PLTRELSZ:
> -	      s = bfd_get_section_by_name (output_bfd, ".rela.plt");
> -	      BFD_ASSERT (s != NULL);
> +	      s = bfd_get_linker_section (dynobj, ".rela.plt");
>  	      dyn.d_un.d_val = s->size;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>  	      break;
> @@ -5485,7 +5483,7 @@ _bfd_mn10300_elf_finish_dynamic_sections (bfd * output_bfd,
>  		 the linker script arranges for .rela.plt to follow all
>  		 other relocation sections, we don't have to worry
>  		 about changing the DT_RELA entry.  */
> -	      s = bfd_get_section_by_name (output_bfd, ".rela.plt");
> +	      s = bfd_get_linker_section (dynobj, ".rela.plt");
>  	      if (s != NULL)
>  		dyn.d_un.d_val -= s->size;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
> diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c
> index 2df91b1..f7b0fff 100644
> --- a/bfd/elf32-arc.c
> +++ b/bfd/elf32-arc.c
> @@ -2395,19 +2395,13 @@ GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
>    return TRUE;
>  }
>
> -#define GET_SYMBOL_OR_SECTION(TAG, SYMBOL, SECTION, ASSERT)	\
> +#define GET_SYMBOL_OR_SECTION(TAG, SYMBOL, SECTION)		\
>    case TAG:							\
>    if (SYMBOL != NULL)						\
> -    {								\
> -      h = elf_link_hash_lookup (elf_hash_table (info),		\
> -				SYMBOL, FALSE, FALSE, TRUE);	\
> -    }								\
> +    h = elf_link_hash_lookup (elf_hash_table (info),		\
> +			      SYMBOL, FALSE, FALSE, TRUE);	\
>    else if (SECTION != NULL)					\
> -    {								\
> -      s = bfd_get_section_by_name (output_bfd, SECTION);	\
> -      BFD_ASSERT (s != NULL || !ASSERT);			\
> -      do_it = TRUE;						\
> -    }								\
> +    s = bfd_get_linker_section (dynobj, SECTION);		\
>    break;
>
>  /* Function :  elf_arc_finish_dynamic_sections
> @@ -2445,15 +2439,15 @@ elf_arc_finish_dynamic_sections (bfd * output_bfd,
>
>  	  switch (internal_dyn.d_tag)
>  	    {
> -	      GET_SYMBOL_OR_SECTION (DT_INIT, "_init", NULL, TRUE)
> -	      GET_SYMBOL_OR_SECTION (DT_FINI, "_fini", NULL, TRUE)
> -	      GET_SYMBOL_OR_SECTION (DT_PLTGOT, NULL, ".plt", TRUE)
> -	      GET_SYMBOL_OR_SECTION (DT_JMPREL, NULL, ".rela.plt", TRUE)
> -	      GET_SYMBOL_OR_SECTION (DT_PLTRELSZ, NULL, ".rela.plt", TRUE)
> -	      GET_SYMBOL_OR_SECTION (DT_RELASZ, NULL, ".rela.plt", FALSE)
> -	      GET_SYMBOL_OR_SECTION (DT_VERSYM, NULL, ".gnu.version", TRUE)
> -	      GET_SYMBOL_OR_SECTION (DT_VERDEF, NULL, ".gnu.version_d", TRUE)
> -	      GET_SYMBOL_OR_SECTION (DT_VERNEED, NULL, ".gnu.version_r", TRUE)
> +	      GET_SYMBOL_OR_SECTION (DT_INIT, "_init", NULL)
> +	      GET_SYMBOL_OR_SECTION (DT_FINI, "_fini", NULL)
> +	      GET_SYMBOL_OR_SECTION (DT_PLTGOT, NULL, ".plt")
> +	      GET_SYMBOL_OR_SECTION (DT_JMPREL, NULL, ".rela.plt")
> +	      GET_SYMBOL_OR_SECTION (DT_PLTRELSZ, NULL, ".rela.plt")
> +	      GET_SYMBOL_OR_SECTION (DT_RELASZ, NULL, ".rela.plt")
> +	      GET_SYMBOL_OR_SECTION (DT_VERSYM, NULL, ".gnu.version")
> +	      GET_SYMBOL_OR_SECTION (DT_VERDEF, NULL, ".gnu.version_d")
> +	      GET_SYMBOL_OR_SECTION (DT_VERNEED, NULL, ".gnu.version_r")
>  	      default:
>  		break;
>  	    }
> @@ -2490,7 +2484,8 @@ elf_arc_finish_dynamic_sections (bfd * output_bfd,
>  		  case DT_VERSYM:
>  		  case DT_VERDEF:
>  		  case DT_VERNEED:
> -		    internal_dyn.d_un.d_ptr = s->vma;
> +		    internal_dyn.d_un.d_ptr = (s->output_section->vma
> +					       + s->output_offset);
>  		    do_it = TRUE;
>  		    break;
>
> @@ -2510,7 +2505,7 @@ elf_arc_finish_dynamic_sections (bfd * output_bfd,
>  		}
>  	    }
>
> -	  if (do_it == TRUE)
> +	  if (do_it)
>  	    bfd_elf32_swap_dyn_out (output_bfd, &internal_dyn, dyncon);
>  	}
>
> diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
> index 326a728..65b593a 100644
> --- a/bfd/elf32-arm.c
> +++ b/bfd/elf32-arm.c
> @@ -15281,27 +15281,26 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
>  	      goto get_vma_if_bpabi;
>
>  	    case DT_PLTGOT:
> -	      name = ".got";
> +	      name = htab->symbian_p ? ".got" : ".got.plt";
>  	      goto get_vma;
>  	    case DT_JMPREL:
>  	      name = RELOC_SECTION (htab, ".plt");
>  	    get_vma:
> -	      s = bfd_get_section_by_name (output_bfd, name);
> +	      s = bfd_get_linker_section (dynobj, name);
>  	      if (s == NULL)
>  		{
> -		  /* PR ld/14397: Issue an error message if a required section is missing.  */
>  		  (*_bfd_error_handler)
> -		    (_("error: required section '%s' not found in the linker script"), name);
> +		    (_("could not find section %s"), name);
>  		  bfd_set_error (bfd_error_invalid_operation);
>  		  return FALSE;
>  		}
>  	      if (!htab->symbian_p)
> -		dyn.d_un.d_ptr = s->vma;
> +		dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>  	      else
>  		/* In the BPABI, tags in the PT_DYNAMIC section point
>  		   at the file offset, not the memory address, for the
>  		   convenience of the post linker.  */
> -		dyn.d_un.d_ptr = s->filepos;
> +		dyn.d_un.d_ptr = s->output_section->filepos + s->output_offset;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>  	      break;
>
> diff --git a/bfd/elf32-cr16.c b/bfd/elf32-cr16.c
> index 21aeda7..20015a4 100644
> --- a/bfd/elf32-cr16.c
> +++ b/bfd/elf32-cr16.c
> @@ -2743,21 +2743,19 @@ _bfd_cr16_elf_finish_dynamic_sections (bfd * output_bfd,
>                break;
>
>              case DT_PLTGOT:
> -              name = ".got";
> +              name = ".got.plt";
>                goto get_vma;
>
>              case DT_JMPREL:
>                name = ".rela.plt";
>              get_vma:
> -              s = bfd_get_section_by_name (output_bfd, name);
> -              BFD_ASSERT (s != NULL);
> -              dyn.d_un.d_ptr = s->vma;
> +              s = bfd_get_linker_section (dynobj, name);
> +              dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>                bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>                break;
>
>              case DT_PLTRELSZ:
> -              s = bfd_get_section_by_name (output_bfd, ".rela.plt");
> -              BFD_ASSERT (s != NULL);
> +              s = bfd_get_linker_section (dynobj, ".rela.plt");
>                dyn.d_un.d_val = s->size;
>                bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>                break;
> @@ -2772,7 +2770,7 @@ _bfd_cr16_elf_finish_dynamic_sections (bfd * output_bfd,
>                   the linker script arranges for .rela.plt to follow all
>                   other relocation sections, we don't have to worry
>                   about changing the DT_RELA entry.  */
> -              s = bfd_get_section_by_name (output_bfd, ".rela.plt");
> +              s = bfd_get_linker_section (dynobj, ".rela.plt");
>                if (s != NULL)
>                  dyn.d_un.d_val -= s->size;
>                bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
> diff --git a/bfd/elf32-cris.c b/bfd/elf32-cris.c
> index 64dc3ae..4aa1d45 100644
> --- a/bfd/elf32-cris.c
> +++ b/bfd/elf32-cris.c
> @@ -2336,22 +2336,21 @@ elf_cris_finish_dynamic_sections (bfd *output_bfd,
>  	      break;
>
>  	    case DT_PLTGOT:
> -	      s = bfd_get_section_by_name (output_bfd, ".got");
> -	      BFD_ASSERT (s != NULL);
> -	      dyn.d_un.d_ptr = s->vma;
> +	      dyn.d_un.d_ptr = sgot->output_section->vma + sgot->output_offset;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>  	      break;
>
>  	    case DT_JMPREL:
>  	      /* Yes, we *can* have a .plt and no .plt.rela, for instance
>  		 if all symbols are found in the .got (not .got.plt).  */
> -	      s = bfd_get_section_by_name (output_bfd, ".rela.plt");
> -	      dyn.d_un.d_ptr = s != NULL ? s->vma : 0;
> +	      s = bfd_get_linker_section (dynobj, ".rela.plt");
> +	      dyn.d_un.d_ptr = s != NULL ? (s->output_section->vma
> +					    + s->output_offset) : 0;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>  	      break;
>
>  	    case DT_PLTRELSZ:
> -	      s = bfd_get_section_by_name (output_bfd, ".rela.plt");
> +	      s = bfd_get_linker_section (dynobj, ".rela.plt");
>  	      if (s == NULL)
>  		dyn.d_un.d_val = 0;
>  	      else
> @@ -2367,7 +2366,7 @@ elf_cris_finish_dynamic_sections (bfd *output_bfd,
>  		 linker script arranges for .rela.plt to follow all
>  		 other relocation sections, we don't have to worry
>  		 about changing the DT_RELA entry.  */
> -	      s = bfd_get_section_by_name (output_bfd, ".rela.plt");
> +	      s = bfd_get_linker_section (dynobj, ".rela.plt");
>  	      if (s != NULL)
>  		dyn.d_un.d_val -= s->size;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
> diff --git a/bfd/elf32-i370.c b/bfd/elf32-i370.c
> index 57af406..9fd7219 100644
> --- a/bfd/elf32-i370.c
> +++ b/bfd/elf32-i370.c
> @@ -919,13 +919,13 @@ i370_elf_finish_dynamic_sections (bfd *output_bfd,
>  	    {
>  	      asection *s;
>
> -	      s = bfd_get_section_by_name (output_bfd, name);
> +	      s = bfd_get_linker_section (dynobj, name);
>  	      if (s == NULL)
>  		dyn.d_un.d_val = 0;
>  	      else
>  		{
>  		  if (! size)
> -		    dyn.d_un.d_ptr = s->vma;
> +		    dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>  		  else
>  		    dyn.d_un.d_val = s->size;
>  		}
> diff --git a/bfd/elf32-lm32.c b/bfd/elf32-lm32.c
> index a1aecc7..bdeefcf 100644
> --- a/bfd/elf32-lm32.c
> +++ b/bfd/elf32-lm32.c
> @@ -1456,19 +1456,17 @@ lm32_elf_finish_dynamic_sections (bfd *output_bfd,
>                break;
>
>              case DT_PLTGOT:
> -              s = htab->sgot->output_section;
> +              s = htab->sgotplt;
>                goto get_vma;
>              case DT_JMPREL:
> -              s = htab->srelplt->output_section;
> +              s = htab->srelplt;
>              get_vma:
> -              BFD_ASSERT (s != NULL);
> -              dyn.d_un.d_ptr = s->vma;
> +              dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>                bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>                break;
>
>              case DT_PLTRELSZ:
> -              s = htab->srelplt->output_section;
> -              BFD_ASSERT (s != NULL);
> +              s = htab->srelplt;
>  	      dyn.d_un.d_val = s->size;
>                bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>                break;
> @@ -1485,7 +1483,7 @@ lm32_elf_finish_dynamic_sections (bfd *output_bfd,
>                   about changing the DT_RELA entry.  */
>                if (htab->srelplt != NULL)
>                  {
> -                  s = htab->srelplt->output_section;
> +                  s = htab->srelplt;
>  		  dyn.d_un.d_val -= s->size;
>                  }
>                bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
> diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c
> index d7d5241..22f3b1e 100644
> --- a/bfd/elf32-m32r.c
> +++ b/bfd/elf32-m32r.c
> @@ -3353,19 +3353,17 @@ m32r_elf_finish_dynamic_sections (bfd *output_bfd,
>                break;
>
>              case DT_PLTGOT:
> -              s = htab->sgot->output_section;
> +              s = htab->sgotplt;
>                goto get_vma;
>              case DT_JMPREL:
> -              s = htab->srelplt->output_section;
> +              s = htab->srelplt;
>              get_vma:
> -              BFD_ASSERT (s != NULL);
> -              dyn.d_un.d_ptr = s->vma;
> +              dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>                bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>                break;
>
>              case DT_PLTRELSZ:
> -              s = htab->srelplt->output_section;
> -              BFD_ASSERT (s != NULL);
> +              s = htab->srelplt;
>  	      dyn.d_un.d_val = s->size;
>                bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>                break;
> @@ -3382,7 +3380,7 @@ m32r_elf_finish_dynamic_sections (bfd *output_bfd,
>                   about changing the DT_RELA entry.  */
>                if (htab->srelplt != NULL)
>                  {
> -                  s = htab->srelplt->output_section;
> +                  s = htab->srelplt;
>  		  dyn.d_un.d_val -= s->size;
>                  }
>                bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
> diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c
> index 7e2d9f5..586f4c9 100644
> --- a/bfd/elf32-m68k.c
> +++ b/bfd/elf32-m68k.c
> @@ -4496,20 +4496,18 @@ elf_m68k_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
>  	      break;
>
>  	    case DT_PLTGOT:
> -	      name = ".got";
> +	      name = ".got.plt";
>  	      goto get_vma;
>  	    case DT_JMPREL:
>  	      name = ".rela.plt";
>  	    get_vma:
> -	      s = bfd_get_section_by_name (output_bfd, name);
> -	      BFD_ASSERT (s != NULL);
> -	      dyn.d_un.d_ptr = s->vma;
> +	      s = bfd_get_linker_section (dynobj, name);
> +	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>  	      break;
>
>  	    case DT_PLTRELSZ:
> -	      s = bfd_get_section_by_name (output_bfd, ".rela.plt");
> -	      BFD_ASSERT (s != NULL);
> +	      s = bfd_get_linker_section (dynobj, ".rela.plt");
>  	      dyn.d_un.d_val = s->size;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>  	      break;
> @@ -4522,7 +4520,7 @@ elf_m68k_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
>  		 linker script arranges for .rela.plt to follow all
>  		 other relocation sections, we don't have to worry
>  		 about changing the DT_RELA entry.  */
> -	      s = bfd_get_section_by_name (output_bfd, ".rela.plt");
> +	      s = bfd_get_linker_section (dynobj, ".rela.plt");
>  	      if (s != NULL)
>  		dyn.d_un.d_val -= s->size;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
> diff --git a/bfd/elf32-metag.c b/bfd/elf32-metag.c
> index 8b517be..a98618a 100644
> --- a/bfd/elf32-metag.c
> +++ b/bfd/elf32-metag.c
> @@ -3330,16 +3330,14 @@ elf_metag_finish_dynamic_sections (bfd *output_bfd,
>  	      continue;
>
>  	    case DT_PLTGOT:
> -	      s = htab->sgot->output_section;
> -	      BFD_ASSERT (s != NULL);
> -	      dyn.d_un.d_ptr = s->vma + htab->sgot->output_offset;
> +	      s = htab->sgot;
> +	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>  	      break;
>
>  	    case DT_JMPREL:
> -	      s = htab->srelplt->output_section;
> -	      BFD_ASSERT (s != NULL);
> -	      dyn.d_un.d_ptr = s->vma;
> +	      s = htab->srelplt;
> +	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>  	      break;
>
> diff --git a/bfd/elf32-microblaze.c b/bfd/elf32-microblaze.c
> index 7cc2a73..e28ff0b 100644
> --- a/bfd/elf32-microblaze.c
> +++ b/bfd/elf32-microblaze.c
> @@ -3403,13 +3403,13 @@ microblaze_elf_finish_dynamic_sections (bfd *output_bfd,
>              {
>                asection *s;
>
> -              s = bfd_get_section_by_name (output_bfd, name);
> +              s = bfd_get_linker_section (dynobj, name);
>                if (s == NULL)
>                  dyn.d_un.d_val = 0;
>                else
>                  {
>                    if (! size)
> -                    dyn.d_un.d_ptr = s->vma;
> +                    dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>                    else
>                      dyn.d_un.d_val = s->size;
>                  }
> diff --git a/bfd/elf32-nds32.c b/bfd/elf32-nds32.c
> index 60cd51e..4f3522a 100644
> --- a/bfd/elf32-nds32.c
> +++ b/bfd/elf32-nds32.c
> @@ -5710,20 +5710,17 @@ nds32_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
>  	      break;
>
>  	    case DT_PLTGOT:
> -	      /* name = ".got"; */
> -	      s = htab->sgot->output_section;
> +	      s = htab->sgotplt;
>  	      goto get_vma;
>  	    case DT_JMPREL:
> -	      s = htab->srelplt->output_section;
> +	      s = htab->srelplt;
>  	    get_vma:
> -	      BFD_ASSERT (s != NULL);
> -	      dyn.d_un.d_ptr = s->vma;
> +	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>  	      break;
>
>  	    case DT_PLTRELSZ:
> -	      s = htab->srelplt->output_section;
> -	      BFD_ASSERT (s != NULL);
> +	      s = htab->srelplt;
>  	      dyn.d_un.d_val = s->size;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>  	      break;
> @@ -5740,7 +5737,7 @@ nds32_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
>  		 about changing the DT_RELA entry.  */
>  	      if (htab->srelplt != NULL)
>  		{
> -		  s = htab->srelplt->output_section;
> +		  s = htab->srelplt;
>  		  dyn.d_un.d_val -= s->size;
>  		}
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
> diff --git a/bfd/elf32-nios2.c b/bfd/elf32-nios2.c
> index b19169c..bf8f4ce 100644
> --- a/bfd/elf32-nios2.c
> +++ b/bfd/elf32-nios2.c
> @@ -5344,22 +5344,19 @@ nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
>  	      break;
>
>  	    case DT_PLTGOT:
> -	      s = htab->root.sgot;
> -	      BFD_ASSERT (s != NULL);
> -	      dyn.d_un.d_ptr = s->output_section->vma;
> +	      s = htab->root.sgotplt;
> +	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>  	      break;
>
>  	    case DT_JMPREL:
>  	      s = htab->root.srelplt;
> -	      BFD_ASSERT (s != NULL);
> -	      dyn.d_un.d_ptr = s->output_section->vma;
> +	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>  	      break;
>
>  	    case DT_PLTRELSZ:
>  	      s = htab->root.srelplt;
> -	      BFD_ASSERT (s != NULL);
>  	      dyn.d_un.d_val = s->size;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>  	      break;
> @@ -5379,9 +5376,9 @@ nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
>  	      break;
>
>  	    case DT_NIOS2_GP:
> -	      s = htab->root.sgot;
> -	      BFD_ASSERT (s != NULL);
> -	      dyn.d_un.d_ptr = s->output_section->vma + 0x7ff0;
> +	      s = htab->root.sgotplt;
> +	      dyn.d_un.d_ptr
> +		= s->output_section->vma + s->output_offset + 0x7ff0;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>  	      break;
>  	    }
> diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c
> index 1daa7b6..d7963b4 100644
> --- a/bfd/elf32-or1k.c
> +++ b/bfd/elf32-or1k.c
> @@ -1759,20 +1759,17 @@ or1k_elf_finish_dynamic_sections (bfd *output_bfd,
>                continue;
>
>              case DT_PLTGOT:
> -              s = htab->sgot->output_section;
> -              BFD_ASSERT (s != NULL);
> -              dyn.d_un.d_ptr = s->vma;
> +              s = htab->sgotplt;
> +              dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>                break;
>
>              case DT_JMPREL:
> -              s = htab->srelplt->output_section;
> -              BFD_ASSERT (s != NULL);
> -              dyn.d_un.d_ptr = s->vma;
> +              s = htab->srelplt;
> +              dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>                break;
>
>              case DT_PLTRELSZ:
> -              s = htab->srelplt->output_section;
> -              BFD_ASSERT (s != NULL);
> +              s = htab->srelplt;
>                dyn.d_un.d_val = s->size;
>                break;
>
> @@ -1788,19 +1785,8 @@ or1k_elf_finish_dynamic_sections (bfd *output_bfd,
>                   about changing the DT_RELA entry.  */
>                if (htab->srelplt != NULL)
>                  {
> -                  /* FIXME: this calculation sometimes produces
> -                     wrong result, the problem is that the dyn.d_un.d_val
> -                     is not always correct, needs investigation why
> -                     that happens. In the meantime, reading the
> -                     ".rela.dyn" section by name seems to yield
> -                     correct result.
> -
> -                  s = htab->srelplt->output_section;
> +                  s = htab->srelplt;
>                    dyn.d_un.d_val -= s->size;
> -                  */
> -
> -                  s = bfd_get_section_by_name (output_bfd, ".rela.dyn");
> -                  dyn.d_un.d_val = s ? s->size : 0;
>                  }
>                break;
>              }
> diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c
> index 972f4d3..88a3c96 100644
> --- a/bfd/elf32-s390.c
> +++ b/bfd/elf32-s390.c
> @@ -3953,15 +3953,17 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
>  	      continue;
>
>  	    case DT_PLTGOT:
> -	      dyn.d_un.d_ptr = htab->elf.sgot->output_section->vma;
> +	      s = htab->elf.sgotplt;
> +	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>  	      break;
>
>  	    case DT_JMPREL:
> -	      dyn.d_un.d_ptr = htab->elf.srelplt->output_section->vma;
> +	      s = htab->elf.srelplt;
> +	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>  	      break;
>
>  	    case DT_PLTRELSZ:
> -	      s = htab->elf.srelplt->output_section;
> +	      s = htab->elf.srelplt;
>  	      dyn.d_un.d_val = s->size;
>  	      break;
>  	    }
> diff --git a/bfd/elf32-score.c b/bfd/elf32-score.c
> index 56b7cd7..ab564a9 100644
> --- a/bfd/elf32-score.c
> +++ b/bfd/elf32-score.c
> @@ -3618,21 +3618,19 @@ s3_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
>            switch (dyn.d_tag)
>              {
>              case DT_RELENT:
> -              s = score_elf_rel_dyn_section (dynobj, FALSE);
> -              BFD_ASSERT (s != NULL);
>                dyn.d_un.d_val = SCORE_ELF_REL_SIZE (dynobj);
>                break;
>
>              case DT_STRSZ:
>                /* Rewrite DT_STRSZ.  */
> -              dyn.d_un.d_val = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
> -                    break;
> +              dyn.d_un.d_val
> +                = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
> +              break;
>
>              case DT_PLTGOT:
>                name = ".got";
> -              s = bfd_get_section_by_name (output_bfd, name);
> -              BFD_ASSERT (s != NULL);
> -              dyn.d_un.d_ptr = s->vma;
> +              s = bfd_get_linker_section (dynobj, name);
> +              dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>                break;
>
>              case DT_SCORE_BASE_ADDRESS:
> @@ -3665,9 +3663,7 @@ s3_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
>              case DT_SCORE_SYMTABNO:
>                name = ".dynsym";
>                elemsize = SCORE_ELF_SYM_SIZE (output_bfd);
> -              s = bfd_get_section_by_name (output_bfd, name);
> -              BFD_ASSERT (s != NULL);
> -
> +              s = bfd_get_linker_section (dynobj, name);
>                dyn.d_un.d_val = s->size / elemsize;
>                break;
>
> diff --git a/bfd/elf32-score7.c b/bfd/elf32-score7.c
> index 349f866..04e2d70 100644
> --- a/bfd/elf32-score7.c
> +++ b/bfd/elf32-score7.c
> @@ -3429,21 +3429,19 @@ s7_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
>            switch (dyn.d_tag)
>              {
>              case DT_RELENT:
> -              s = score_elf_rel_dyn_section (dynobj, FALSE);
> -              BFD_ASSERT (s != NULL);
>                dyn.d_un.d_val = SCORE_ELF_REL_SIZE (dynobj);
>                break;
>
>              case DT_STRSZ:
>                /* Rewrite DT_STRSZ.  */
> -              dyn.d_un.d_val = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
> -                    break;
> +              dyn.d_un.d_val
> +                = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
> +              break;
>
>              case DT_PLTGOT:
>                name = ".got";
> -              s = bfd_get_section_by_name (output_bfd, name);
> -              BFD_ASSERT (s != NULL);
> -              dyn.d_un.d_ptr = s->vma;
> +              s = bfd_get_linker_section (dynobj, name);
> +              dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>                break;
>
>              case DT_SCORE_BASE_ADDRESS:
> @@ -3476,9 +3474,7 @@ s7_bfd_score_elf_finish_dynamic_sections (bfd *output_bfd,
>              case DT_SCORE_SYMTABNO:
>                name = ".dynsym";
>                elemsize = SCORE_ELF_SYM_SIZE (output_bfd);
> -              s = bfd_get_section_by_name (output_bfd, name);
> -              BFD_ASSERT (s != NULL);
> -
> +              s = bfd_get_linker_section (dynobj, name);
>                dyn.d_un.d_val = s->size / elemsize;
>                break;
>
> diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c
> index 56f1d75..355bdd9 100644
> --- a/bfd/elf32-vax.c
> +++ b/bfd/elf32-vax.c
> @@ -1929,20 +1929,18 @@ elf_vax_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
>  	      break;
>
>  	    case DT_PLTGOT:
> -	      name = ".got";
> +	      name = ".got.plt";
>  	      goto get_vma;
>  	    case DT_JMPREL:
>  	      name = ".rela.plt";
>  	    get_vma:
> -	      s = bfd_get_section_by_name (output_bfd, name);
> -	      BFD_ASSERT (s != NULL);
> -	      dyn.d_un.d_ptr = s->vma;
> +	      s = bfd_get_linker_section (dynobj, name);
> +	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>  	      break;
>
>  	    case DT_PLTRELSZ:
> -	      s = bfd_get_section_by_name (output_bfd, ".rela.plt");
> -	      BFD_ASSERT (s != NULL);
> +	      s = bfd_get_linker_section (dynobj, ".rela.plt");
>  	      dyn.d_un.d_val = s->size;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
>  	      break;
> @@ -1955,7 +1953,7 @@ elf_vax_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
>  		 linker script arranges for .rela.plt to follow all
>  		 other relocation sections, we don't have to worry
>  		 about changing the DT_RELA entry.  */
> -	      s = bfd_get_section_by_name (output_bfd, ".rela.plt");
> +	      s = bfd_get_linker_section (dynobj, ".rela.plt");
>  	      if (s != NULL)
>  		dyn.d_un.d_val -= s->size;
>  	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
> diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c
> index 7873292..3a74c2a 100644
> --- a/bfd/elf32-xtensa.c
> +++ b/bfd/elf32-xtensa.c
> @@ -3430,19 +3430,22 @@ elf_xtensa_finish_dynamic_sections (bfd *output_bfd,
>  	  break;
>
>  	case DT_XTENSA_GOT_LOC_OFF:
> -	  dyn.d_un.d_ptr = htab->sgotloc->output_section->vma;
> +	  dyn.d_un.d_ptr = (htab->sgotloc->output_section->vma
> +			    + htab->sgotloc->output_offset);
>  	  break;
>
>  	case DT_PLTGOT:
> -	  dyn.d_un.d_ptr = htab->sgot->output_section->vma;
> +	  dyn.d_un.d_ptr = (htab->sgot->output_section->vma
> +			    + htab->sgot->output_offset);
>  	  break;
>
>  	case DT_JMPREL:
> -	  dyn.d_un.d_ptr = htab->srelplt->output_section->vma;
> +	  dyn.d_un.d_ptr = (htab->srelplt->output_section->vma
> +			    + htab->srelplt->output_offset);
>  	  break;
>
>  	case DT_PLTRELSZ:
> -	  dyn.d_un.d_val = htab->srelplt->output_section->size;
> +	  dyn.d_un.d_val = htab->srelplt->size;
>  	  break;
>
>  	case DT_RELASZ:
> @@ -3453,7 +3456,7 @@ elf_xtensa_finish_dynamic_sections (bfd *output_bfd,
>  	     for .rela.plt to follow all other relocation sections, we
>  	     don't have to worry about changing the DT_RELA entry.  */
>  	  if (htab->srelplt)
> -	    dyn.d_un.d_val -= htab->srelplt->output_section->size;
> +	    dyn.d_un.d_val -= htab->srelplt->size;
>  	  break;
>  	}
>
> diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c
> index 54796b8..557b2a1 100644
> --- a/bfd/elf64-alpha.c
> +++ b/bfd/elf64-alpha.c
> @@ -5011,7 +5011,7 @@ elf64_alpha_finish_dynamic_sections (bfd *output_bfd,
>        bfd_vma plt_vma, gotplt_vma;
>
>        splt = bfd_get_linker_section (dynobj, ".plt");
> -      srelaplt = bfd_get_linker_section (output_bfd, ".rela.plt");
> +      srelaplt = bfd_get_linker_section (dynobj, ".rela.plt");
>        BFD_ASSERT (splt != NULL && sdyn != NULL);
>
>        plt_vma = splt->output_section->vma + splt->output_offset;
> @@ -5043,7 +5043,8 @@ elf64_alpha_finish_dynamic_sections (bfd *output_bfd,
>  	      dyn.d_un.d_val = srelaplt ? srelaplt->size : 0;
>  	      break;
>  	    case DT_JMPREL:
> -	      dyn.d_un.d_ptr = srelaplt ? srelaplt->vma : 0;
> +	      dyn.d_un.d_ptr = srelaplt ? (srelaplt->output_section->vma
> +					   + srelaplt->output_offset) : 0;
>  	      break;
>
>  	    case DT_RELASZ:
> diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c
> index 1261044..b085169 100644
> --- a/bfd/elf64-s390.c
> +++ b/bfd/elf64-s390.c
> @@ -3749,15 +3749,17 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
>  	      continue;
>
>  	    case DT_PLTGOT:
> -	      dyn.d_un.d_ptr = htab->elf.sgot->output_section->vma;
> +	      s = htab->elf.sgotplt;
> +	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>  	      break;
>
>  	    case DT_JMPREL:
> -	      dyn.d_un.d_ptr = htab->elf.srelplt->output_section->vma;
> +	      s = htab->elf.srelplt;
> +	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>  	      break;
>
>  	    case DT_PLTRELSZ:
> -	      s = htab->elf.srelplt->output_section;
> +	      s = htab->elf.srelplt;
>  	      dyn.d_un.d_val = s->size;
>  	      break;
>
> @@ -3769,7 +3771,7 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
>  		 linker script arranges for .rela.plt to follow all
>  		 other relocation sections, we don't have to worry
>  		 about changing the DT_RELA entry.  */
> -	      s = htab->elf.srelplt->output_section;
> +	      s = htab->elf.srelplt;
>  	      dyn.d_un.d_val -= s->size;
>  	      break;
>  	    }
> diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c
> index 645bce2..8a8804a 100644
> --- a/bfd/elf64-sh64.c
> +++ b/bfd/elf64-sh64.c
> @@ -3817,21 +3817,19 @@ sh64_elf64_finish_dynamic_sections (bfd *output_bfd,
>  	      break;
>
>  	    case DT_PLTGOT:
> -	      name = ".got";
> +	      name = ".got.plt";
>  	      goto get_vma;
>
>  	    case DT_JMPREL:
>  	      name = ".rela.plt";
>  	    get_vma:
> -	      s = bfd_get_section_by_name (output_bfd, name);
> -	      BFD_ASSERT (s != NULL);
> -	      dyn.d_un.d_ptr = s->vma;
> +	      s = bfd_get_linker_section (dynobj, name);
> +	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>  	      bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
>  	      break;
>
>  	    case DT_PLTRELSZ:
> -	      s = bfd_get_section_by_name (output_bfd, ".rela.plt");
> -	      BFD_ASSERT (s != NULL);
> +	      s = bfd_get_linker_section (dynobj, ".rela.plt");
>  	      dyn.d_un.d_val = s->size;
>  	      bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
>  	      break;
> @@ -3846,7 +3844,7 @@ sh64_elf64_finish_dynamic_sections (bfd *output_bfd,
>  		 the linker script arranges for .rela.plt to follow all
>  		 other relocation sections, we don't have to worry
>  		 about changing the DT_RELA entry.  */
> -	      s = bfd_get_section_by_name (output_bfd, ".rela.plt");
> +	      s = bfd_get_linker_section (dynobj, ".rela.plt");
>  	      if (s != NULL)
>  		dyn.d_un.d_val -= s->size;
>  	      bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
> diff --git a/bfd/elflink.c b/bfd/elflink.c
> index 5f2fa52..1223d27 100644
> --- a/bfd/elflink.c
> +++ b/bfd/elflink.c
> @@ -11895,18 +11895,18 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
>
>  	    case DT_PREINIT_ARRAYSZ:
>  	      name = ".preinit_array";
> -	      goto get_size;
> +	      goto get_out_size;
>  	    case DT_INIT_ARRAYSZ:
>  	      name = ".init_array";
> -	      goto get_size;
> +	      goto get_out_size;
>  	    case DT_FINI_ARRAYSZ:
>  	      name = ".fini_array";
> -	    get_size:
> +	    get_out_size:
>  	      o = bfd_get_section_by_name (abfd, name);
>  	      if (o == NULL)
>  		{
>  		  (*_bfd_error_handler)
> -		    (_("%B: could not find output section %s"), abfd, name);
> +		    (_("could not find section %s"), name);
>  		  goto error_return;
>  		}
>  	      if (o->size == 0)
> @@ -11917,13 +11917,15 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
>
>  	    case DT_PREINIT_ARRAY:
>  	      name = ".preinit_array";
> -	      goto get_vma;
> +	      goto get_out_vma;
>  	    case DT_INIT_ARRAY:
>  	      name = ".init_array";
> -	      goto get_vma;
> +	      goto get_out_vma;
>  	    case DT_FINI_ARRAY:
>  	      name = ".fini_array";
> -	      goto get_vma;
> +	    get_out_vma:
> +	      o = bfd_get_section_by_name (abfd, name);
> +	      goto do_vma;
>
>  	    case DT_HASH:
>  	      name = ".hash";
> @@ -11946,11 +11948,12 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
>  	    case DT_VERSYM:
>  	      name = ".gnu.version";
>  	    get_vma:
> -	      o = bfd_get_section_by_name (abfd, name);
> +	      o = bfd_get_linker_section (dynobj, name);
> +	    do_vma:
>  	      if (o == NULL)
>  		{
>  		  (*_bfd_error_handler)
> -		    (_("%B: could not find output section %s"), abfd, name);
> +		    (_("could not find section %s"), name);
>  		  goto error_return;
>  		}
>  	      if (elf_section_data (o->output_section)->this_hdr.sh_type == SHT_NOTE)
> @@ -11960,7 +11963,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
>  		  bfd_set_error (bfd_error_nonrepresentable_section);
>  		  goto error_return;
>  		}
> -	      dyn.d_un.d_ptr = o->vma;
> +	      dyn.d_un.d_ptr = o->output_section->vma + o->output_offset;
>  	      break;
>
>  	    case DT_REL:
> diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
> index 81bb011..fcce22f 100644
> --- a/bfd/elfnn-aarch64.c
> +++ b/bfd/elfnn-aarch64.c
> @@ -9053,7 +9053,8 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
>  	      break;
>
>  	    case DT_JMPREL:
> -	      dyn.d_un.d_ptr = htab->root.srelplt->output_section->vma;
> +	      s = htab->root.srelplt;
> +	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>  	      break;
>
>  	    case DT_PLTRELSZ:
> diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
> index f9e8f76..f215341 100644
> --- a/bfd/elfxx-mips.c
> +++ b/bfd/elfxx-mips.c
> @@ -11466,7 +11466,7 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd,
>  	    case DT_MIPS_SYMTABNO:
>  	      name = ".dynsym";
>  	      elemsize = MIPS_ELF_SYM_SIZE (output_bfd);
> -	      s = bfd_get_section_by_name (output_bfd, name);
> +	      s = bfd_get_linker_section (dynobj, name);
>
>  	      if (s != NULL)
>  		dyn.d_un.d_val = s->size / elemsize;
> diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c
> index fc12805..bde53df 100644
> --- a/bfd/elfxx-sparc.c
> +++ b/bfd/elfxx-sparc.c
> @@ -4630,13 +4630,13 @@ sparc_finish_dyn (bfd *output_bfd, struct bfd_link_info *info,
>  	    {
>  	      asection *s;
>
> -	      s = bfd_get_section_by_name (output_bfd, name);
> +	      s = bfd_get_linker_section (dynobj, name);
>  	      if (s == NULL)
>  		dyn.d_un.d_val = 0;
>  	      else
>  		{
>  		  if (! size)
> -		    dyn.d_un.d_ptr = s->vma;
> +		    dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
>  		  else
>  		    dyn.d_un.d_val = s->size;
>  		}
> diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
> index f34ce5f..db25a8d 100644
> --- a/ld/testsuite/ld-arm/arm-elf.exp
> +++ b/ld/testsuite/ld-arm/arm-elf.exp
> @@ -286,11 +286,11 @@ set armelftests_nonacl {
>      {"Simple static application without .rel.plt in linker script"
>  	"-T arm-no-rel-plt.ld" "" "" {arm-static-app.s}
>       {{objdump -fdw arm-static-app.d} {objdump -rw arm-static-app.r}}
> -     "arm-static-app"}
> +     "arm-static-app-no-rel-plt"}
>      {"Simple dynamic application without .rel.plt in linker script"
>  	"tmpdir/arm-lib.so -T arm-no-rel-plt.ld" "" "" {arm-app.s}
> -     {{ld arm-no-rel-plt.out}}
> -     "arm-app"}
> +     {{readelf -dr arm-no-rel-plt.r}}
> +     "arm-app-no-rel-plt"}
>      {"Non-pcrel function reference" "tmpdir/arm-lib.so" "" "" {arm-app-abs32.s}
>       {{objdump -fdw arm-app-abs32.d} {objdump -Rw arm-app-abs32.r}}
>       "arm-app-abs32"}
> diff --git a/ld/testsuite/ld-arm/arm-no-rel-plt.ld b/ld/testsuite/ld-arm/arm-no-rel-plt.ld
> index 391e663..d175a3d 100644
> --- a/ld/testsuite/ld-arm/arm-no-rel-plt.ld
> +++ b/ld/testsuite/ld-arm/arm-no-rel-plt.ld
> @@ -14,7 +14,7 @@ SECTIONS
>    .gnu.version    : { *(.gnu.version) }
>    .gnu.version_d  : { *(.gnu.version_d) }
>    .gnu.version_r  : { *(.gnu.version_r) }
> -  .rel.dyn        :
> +  .rel.dyn ALIGN (0x100) :
>      {
>        *(.rel.init)
>        *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
> @@ -34,7 +34,7 @@ SECTIONS
>        PROVIDE_HIDDEN (__rela_iplt_start = .);
>        PROVIDE_HIDDEN (__rela_iplt_end = .);
>      }
> -  .rela.dyn       :
> +  .rela.dyn ALIGN (0x100) :
>      {
>        *(.rela.init)
>        *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
> diff --git a/ld/testsuite/ld-arm/arm-no-rel-plt.out b/ld/testsuite/ld-arm/arm-no-rel-plt.out
> deleted file mode 100644
> index 948d5a5..0000000
> --- a/ld/testsuite/ld-arm/arm-no-rel-plt.out
> +++ /dev/null
> @@ -1,2 +0,0 @@
> -.*: error: required section '.rel.plt' not found in the linker script
> -.*: final link failed: Invalid operation
> diff --git a/ld/testsuite/ld-arm/arm-no-rel-plt.r b/ld/testsuite/ld-arm/arm-no-rel-plt.r
> new file mode 100644
> index 0000000..686957e
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/arm-no-rel-plt.r
> @@ -0,0 +1,9 @@
> +#...
> + 0x00000017 \(JMPREL\) +0x.*08
> + 0x00000011 \(REL\) +0x.*00
> +#...
> +
> +Relocation section '\.rel\.dyn' at offset 0x.*00 contains 2 entries:
> + Offset +Info +Type +Sym\.Value +Sym\. Name
> +.* R_ARM_COPY .* data_obj
> +.* R_ARM_JUMP_SLOT .* lib_func1
> diff --git a/ld/testsuite/ld-arm/arm-static-app.d b/ld/testsuite/ld-arm/arm-static-app.d
> index 40355c8..9547cd9 100644
> --- a/ld/testsuite/ld-arm/arm-static-app.d
> +++ b/ld/testsuite/ld-arm/arm-static-app.d
> @@ -1,5 +1,5 @@
>
> -tmpdir/arm-static-app:     file format elf32-(little|big)arm.*
> +.*:     file format elf32-(little|big)arm.*
>  architecture: arm.*, flags 0x00000112:
>  EXEC_P, HAS_SYMS, D_PAGED
>  start address 0x.*
> diff --git a/ld/testsuite/ld-arm/arm-static-app.r b/ld/testsuite/ld-arm/arm-static-app.r
> index 92df70e..cad5905 100644
> --- a/ld/testsuite/ld-arm/arm-static-app.r
> +++ b/ld/testsuite/ld-arm/arm-static-app.r
> @@ -1,3 +1,3 @@
>
> -tmpdir/arm-static-app:     file format elf32-(little|big)arm.*
> +.*:     file format elf32-(little|big)arm.*
>
>



More information about the Binutils mailing list