public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* PowerPC64 treatment of absolute symbols
@ 2022-02-03  3:10 Alan Modra
  0 siblings, 0 replies; only message in thread
From: Alan Modra @ 2022-02-03  3:10 UTC (permalink / raw)
  To: binutils

Supporting -static-pie on PowerPC64 requires the linker to properly
treat SHN_ABS symbols for cases like glibc's _nl_current_LC_CTYPE_used
absolute symbol.  I've been slow to fix the linker on powerpc because
there is some chance that this will break some shared libraries or
PIEs.

bfd/
	* elf64-ppc.c (ppc64_elf_check_relocs): Consolidate local sym
	handling code.  Don't count dyn relocs against non-dynamic
	absolute symbols.
	(dec_dynrel_count): Adjust to suit.
	(ppc64_elf_edit_toc): Don't remove entries for absolute symbols
	when pic.
	(allocate_got): Don't allocate space for got relocs against
	non-dynamic absolute syms.
	(ppc64_elf_layout_multitoc): Likewise.
	(got_and_plt_relr): Likewise.
	(ppc64_elf_size_dynamic_sections): Likewise for local got.
	(got_and_plt_relr_for_local_syms): Likewise.
	(ppc64_elf_size_stubs): Don't allocate space for relr either.
	(ppc64_elf_relocate_section): Don't write relocs against non-dynamic
	absolute symbols.  Don't optimise got and toc code sequences
	loading absolute symbol entries.
ld/
	* testsuite/ld-powerpc/abs-reloc.s,
	* testsuite/ld-powerpc/abs-static.d,
	* testsuite/ld-powerpc/abs-static.r,
	* testsuite/ld-powerpc/abs-pie.d,
	* testsuite/ld-powerpc/abs-pie.r,
	* testsuite/ld-powerpc/abs-shared.d,
	* testsuite/ld-powerpc/abs-shared.r,
	* testsuite/ld-powerpc/abs-pie-relr.d,
	* testsuite/ld-powerpc/abs-pie-relr.r,
	* testsuite/ld-powerpc/abs-shared-relr.d,
	* testsuite/ld-powerpc/abs-shared-relr.r: New tests.
	* testsuite/ld-powerpc/powerpc.exp: Run them.

diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index b4fa4aed7b6..7223c497d07 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -4779,6 +4779,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
     {
       unsigned long r_symndx;
       struct elf_link_hash_entry *h;
+      Elf_Internal_Sym *isym;
       enum elf_ppc64_reloc_type r_type;
       int tls_type;
       struct _ppc64_elf_section_data *ppc64_sec;
@@ -4786,9 +4787,15 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
       r_symndx = ELF64_R_SYM (rel->r_info);
       if (r_symndx < symtab_hdr->sh_info)
-	h = NULL;
+	{
+	  h = NULL;
+	  isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd, r_symndx);
+	  if (isym == NULL)
+	    return false;
+	}
       else
 	{
+	  isym = NULL;
 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 	  h = elf_follow_link (h);
 
@@ -4859,11 +4866,6 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	}
       else
 	{
-	  Elf_Internal_Sym *isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
-							  abfd, r_symndx);
-	  if (isym == NULL)
-	    return false;
-
 	  if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
 	    {
 	      ifunc = update_local_sym_info (abfd, symtab_hdr, r_symndx,
@@ -5127,16 +5129,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 		  dest = h->root.u.def.section;
 	      }
 	    else
-	      {
-		Elf_Internal_Sym *isym;
-
-		isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
-					      abfd, r_symndx);
-		if (isym == NULL)
-		  return false;
-
-		dest = bfd_section_from_elf_index (abfd, isym->st_shndx);
-	      }
+	      dest = bfd_section_from_elf_index (abfd, isym->st_shndx);
 
 	    if (dest != sec)
 	      ppc64_elf_section_data (sec)->has_14bit_branch = 1;
@@ -5352,11 +5345,13 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	dodyn:
 	  if ((h != NULL
 	       && (h->root.type == bfd_link_hash_defweak
-		   || !h->def_regular))
+		   || (!h->def_regular && !h->root.ldscript_def)))
 	      || (h != NULL
-		  && !bfd_link_executable (info)
-		  && !SYMBOLIC_BIND (info, h))
+		  && !SYMBOL_REFERENCES_LOCAL (info, h))
 	      || (bfd_link_pic (info)
+		  && (h != NULL
+		      ? !bfd_is_abs_symbol (&h->root)
+		      : isym->st_shndx != SHN_ABS)
 		  && must_be_dyn_reloc (info, r_type))
 	      || (!bfd_link_pic (info)
 		  && ifunc != NULL))
@@ -5404,20 +5399,12 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 		}
 	      else
 		{
-		  /* Track dynamic relocs needed for local syms too.
-		     We really need local syms available to do this
-		     easily.  Oh well.  */
+		  /* Track dynamic relocs needed for local syms too.  */
 		  struct ppc_local_dyn_relocs *p;
 		  struct ppc_local_dyn_relocs **head;
 		  bool is_ifunc;
 		  asection *s;
 		  void *vpp;
-		  Elf_Internal_Sym *isym;
-
-		  isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
-						abfd, r_symndx);
-		  if (isym == NULL)
-		    return false;
 
 		  s = bfd_section_from_elf_index (abfd, isym->st_shndx);
 		  if (s == NULL)
@@ -7256,11 +7243,13 @@ dec_dynrel_count (const Elf_Internal_Rela *rel,
 
   if ((h != NULL
        && (h->root.type == bfd_link_hash_defweak
-	   || !h->def_regular))
+	   || (!h->def_regular && !h->root.ldscript_def)))
       || (h != NULL
-	  && !bfd_link_executable (info)
-	  && !SYMBOLIC_BIND (info, h))
+	  && !SYMBOL_REFERENCES_LOCAL (info, h))
       || (bfd_link_pic (info)
+	  && (h != NULL
+	      ? !bfd_is_abs_symbol (&h->root)
+	      : sym_sec != bfd_abs_section_ptr)
 	  && must_be_dyn_reloc (info, r_type))
       || (!bfd_link_pic (info)
 	  && (h != NULL
@@ -9065,7 +9054,9 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
 		  || discarded_section (sym_sec))
 		continue;
 
-	      if (!SYMBOL_REFERENCES_LOCAL (info, h))
+	      if (!SYMBOL_REFERENCES_LOCAL (info, h)
+		  || (bfd_link_pic (info)
+		      && sym_sec == bfd_abs_section_ptr))
 		continue;
 
 	      if (h != NULL)
@@ -9647,7 +9638,9 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
 	      if ((h ? h->type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC)
 		continue;
 
-	      if (!SYMBOL_REFERENCES_LOCAL (info, h))
+	      if (!SYMBOL_REFERENCES_LOCAL (info, h)
+		  || (bfd_link_pic (info)
+		      && sym_sec == bfd_abs_section_ptr))
 		continue;
 
 	      if (h != NULL)
@@ -9781,7 +9774,8 @@ allocate_got (struct elf_link_hash_entry *h,
 	     && (gent->tls_type == 0
 		 ? !info->enable_dt_relr
 		 : !(bfd_link_executable (info)
-		     && SYMBOL_REFERENCES_LOCAL (info, h))))
+		     && SYMBOL_REFERENCES_LOCAL (info, h)))
+	     && !bfd_is_abs_symbol (&h->root))
 	    || (htab->elf.dynamic_sections_created
 		&& h->dynindx != -1
 		&& !SYMBOL_REFERENCES_LOCAL (info, h)))
@@ -10246,6 +10240,8 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd,
       unsigned char *lgot_masks;
       bfd_size_type locsymcount;
       Elf_Internal_Shdr *symtab_hdr;
+      Elf_Internal_Sym *local_syms;
+      Elf_Internal_Sym *isym;
 
       if (!is_ppc64_elf (ibfd))
 	continue;
@@ -10296,8 +10292,22 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd,
       local_plt = (struct plt_entry **) end_lgot_ents;
       end_local_plt = local_plt + locsymcount;
       lgot_masks = (unsigned char *) end_local_plt;
+      local_syms = NULL;
+      if (bfd_link_pic (info))
+	{
+	  local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
+	  if (local_syms == NULL && locsymcount != 0)
+	    {
+	      local_syms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, locsymcount,
+						 0, NULL, NULL, NULL);
+	      if (local_syms == NULL)
+		return false;
+	    }
+	}
       s = ppc64_elf_tdata (ibfd)->got;
-      for (; lgot_ents < end_lgot_ents; ++lgot_ents, ++lgot_masks)
+      for (isym = local_syms;
+	   lgot_ents < end_lgot_ents;
+	   ++lgot_ents, ++lgot_masks, isym != NULL && isym++)
 	{
 	  struct got_entry **pent, *ent;
 
@@ -10330,7 +10340,8 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd,
 		    else if (bfd_link_pic (info)
 			     && (ent->tls_type == 0
 				 ? !info->enable_dt_relr
-				 : !bfd_link_executable (info)))
+				 : !bfd_link_executable (info))
+			     && isym->st_shndx != SHN_ABS)
 		      {
 			asection *srel = ppc64_elf_tdata (ibfd)->relgot;
 			srel->size += rel_size;
@@ -10341,6 +10352,14 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd,
 	    else
 	      *pent = ent->next;
 	}
+      if (local_syms != NULL
+	  && symtab_hdr->contents != (unsigned char *) local_syms)
+	{
+	  if (!info->keep_memory)
+	    free (local_syms);
+	  else
+	    symtab_hdr->contents = (unsigned char *) local_syms;
+	}
 
       /* Allocate space for plt calls to local syms.  */
       lgot_masks = (unsigned char *) end_local_plt;
@@ -12793,6 +12812,8 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info)
       bfd_size_type locsymcount;
       Elf_Internal_Shdr *symtab_hdr;
       asection *s;
+      Elf_Internal_Sym *local_syms;
+      Elf_Internal_Sym *isym;
 
       if (!is_ppc64_elf (ibfd))
 	continue;
@@ -12807,8 +12828,22 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info)
       local_plt = (struct plt_entry **) end_lgot_ents;
       end_local_plt = local_plt + locsymcount;
       lgot_masks = (unsigned char *) end_local_plt;
+      local_syms = NULL;
+      if (bfd_link_pic (info))
+	{
+	  local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
+	  if (local_syms == NULL && locsymcount != 0)
+	    {
+	      local_syms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, locsymcount,
+						 0, NULL, NULL, NULL);
+	      if (local_syms == NULL)
+		return false;
+	    }
+	}
       s = ppc64_elf_tdata (ibfd)->got;
-      for (; lgot_ents < end_lgot_ents; ++lgot_ents, ++lgot_masks)
+      for (isym = local_syms;
+	   lgot_ents < end_lgot_ents;
+	   ++lgot_ents, ++lgot_masks, isym != NULL && isym++)
 	{
 	  struct got_entry *ent;
 
@@ -12832,7 +12867,8 @@ ppc64_elf_layout_multitoc (struct bfd_link_info *info)
 	      else if (bfd_link_pic (info)
 		       && (ent->tls_type == 0
 			   ? !info->enable_dt_relr
-			   : !bfd_link_executable (info)))
+			   : !bfd_link_executable (info))
+		       && isym->st_shndx != SHN_ABS)
 		{
 		  asection *srel = ppc64_elf_tdata (ibfd)->relgot;
 		  srel->size += rel_size;
@@ -13422,7 +13458,8 @@ got_and_plt_relr_for_local_syms (struct bfd_link_info *info)
       struct plt_entry **local_plt, **lplt, **end_local_plt;
       Elf_Internal_Shdr *symtab_hdr;
       bfd_size_type locsymcount;
-      Elf_Internal_Sym *local_syms = NULL;
+      Elf_Internal_Sym *local_syms;
+      Elf_Internal_Sym *isym;
       struct plt_entry *pent;
       struct got_entry *gent;
 
@@ -13435,14 +13472,25 @@ got_and_plt_relr_for_local_syms (struct bfd_link_info *info)
 
       symtab_hdr = &elf_symtab_hdr (ibfd);
       locsymcount = symtab_hdr->sh_info;
+      local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
+      if (local_syms == NULL && locsymcount != 0)
+	{
+	  local_syms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, locsymcount,
+					     0, NULL, NULL, NULL);
+	  if (local_syms == NULL)
+	    return false;
+	}
       end_lgot_ents = lgot_ents + locsymcount;
       local_plt = (struct plt_entry **) end_lgot_ents;
       end_local_plt = local_plt + locsymcount;
-      for (lgot = lgot_ents; lgot < end_lgot_ents; ++lgot)
+      for (lgot = lgot_ents, isym = local_syms;
+	   lgot < end_lgot_ents;
+	   ++lgot, ++isym)
 	for (gent = *lgot; gent != NULL; gent = gent->next)
 	  if (!gent->is_indirect
 	      && gent->tls_type == 0
-	      && gent->got.offset != (bfd_vma) -1)
+	      && gent->got.offset != (bfd_vma) -1
+	      && isym->st_shndx != SHN_ABS)
 	    {
 	      asection *got = ppc64_elf_tdata (gent->owner)->got;
 	      bfd_vma r_offset = (got->output_section->vma
@@ -13456,29 +13504,22 @@ got_and_plt_relr_for_local_syms (struct bfd_link_info *info)
 	    }
 
       if (!htab->opd_abi)
-	for (lplt = local_plt; lplt < end_local_plt; ++lplt)
+	for (lplt = local_plt, isym = local_syms;
+	     lplt < end_local_plt;
+	     ++lplt, ++isym)
 	  for (pent = *lplt; pent != NULL; pent = pent->next)
-	    if (pent->plt.offset != (bfd_vma) -1)
+	    if (pent->plt.offset != (bfd_vma) -1
+		&& ELF_ST_TYPE (isym->st_info) != STT_GNU_IFUNC)
 	      {
-		Elf_Internal_Sym *sym;
-
-		if (!get_sym_h (NULL, &sym, NULL, NULL, &local_syms,
-				lplt - local_plt, ibfd))
+		bfd_vma r_offset = (pent->plt.offset
+				    + htab->pltlocal->output_offset
+				    + htab->pltlocal->output_section->vma);
+		if (!append_relr_off (htab, r_offset))
 		  {
-		  err_exit:
 		    if (symtab_hdr->contents != (unsigned char *) local_syms)
 		      free (local_syms);
 		    return false;
 		  }
-
-		if (ELF_ST_TYPE (sym->st_info) != STT_GNU_IFUNC)
-		  {
-		    bfd_vma r_offset = (pent->plt.offset
-					+ htab->pltlocal->output_offset
-					+ htab->pltlocal->output_section->vma);
-		    if (!append_relr_off (htab, r_offset))
-		      goto err_exit;
-		  }
 	      }
 
       if (local_syms != NULL
@@ -13514,9 +13555,10 @@ got_and_plt_relr (struct elf_link_hash_entry *h, void *inf)
       && (h->root.type == bfd_link_hash_defined
 	  || h->root.type == bfd_link_hash_defweak))
     {
-      if (!htab->elf.dynamic_sections_created
-	  || h->dynindx == -1
-	  || SYMBOL_REFERENCES_LOCAL (info, h))
+      if ((!htab->elf.dynamic_sections_created
+	   || h->dynindx == -1
+	   || SYMBOL_REFERENCES_LOCAL (info, h))
+	  && !bfd_is_abs_symbol (&h->root))
 	for (gent = h->got.glist; gent != NULL; gent = gent->next)
 	  if (!gent->is_indirect
 	      && gent->tls_type == 0
@@ -13805,6 +13847,10 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
 			      ? h->type == STT_GNU_IFUNC
 			      : ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
 			    continue;
+			  if (h != NULL
+			      ? bfd_is_abs_symbol (&h->root)
+			      : sym->st_shndx == SHN_ABS)
+			    continue;
 			  if (h != NULL
 			      && !SYMBOL_REFERENCES_LOCAL (info, h))
 			    continue;
@@ -16553,6 +16599,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
 
 	case R_PPC64_GOT16_DS:
 	  if ((h ? h->elf.type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC
+	      || (bfd_link_pic (info)
+		  && sec == bfd_abs_section_ptr)
 	      || !htab->do_toc_opt)
 	    break;
 	  from = TOCstart + htab->sec_info[input_section->id].toc_off;
@@ -16577,6 +16625,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
 	case R_PPC64_GOT16_LO_DS:
 	case R_PPC64_GOT16_HA:
 	  if ((h ? h->elf.type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC
+	      || (bfd_link_pic (info)
+		  && sec == bfd_abs_section_ptr)
 	      || !htab->do_toc_opt)
 	    break;
 	  from = TOCstart + htab->sec_info[input_section->id].toc_off;
@@ -16607,6 +16657,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
 
 	case R_PPC64_GOT_PCREL34:
 	  if ((h ? h->elf.type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC
+	      || (bfd_link_pic (info)
+		  && sec == bfd_abs_section_ptr)
 	      || !htab->do_toc_opt)
 	    break;
 	  from = (rel->r_offset
@@ -16846,7 +16898,11 @@ ppc64_elf_relocate_section (bfd *output_bfd,
 				  && bfd_link_executable (info)
 				  && (h == NULL
 				      || SYMBOL_REFERENCES_LOCAL (info,
-								  &h->elf)))))
+								  &h->elf)))
+			     && (h != NULL
+				 ? !bfd_is_abs_symbol (&h->elf.root)
+				 : sym->st_shndx != SHN_ABS)))
+
 		  relgot = ppc64_elf_tdata (ent->owner)->relgot;
 		if (relgot != NULL)
 		  {
@@ -17555,7 +17611,11 @@ ppc64_elf_relocate_section (bfd *output_bfd,
 	case R_PPC64_GOT16_HA:
 	case R_PPC64_TOC16_HA:
 	  if (htab->do_toc_opt && relocation + addend + 0x8000 < 0x10000
-	      && !ppc64_elf_tdata (input_bfd)->unexpected_toc_insn)
+	      && !ppc64_elf_tdata (input_bfd)->unexpected_toc_insn
+	      && !(bfd_link_pic (info)
+		   && (h != NULL
+		       ? bfd_is_abs_symbol (&h->elf.root)
+		       : sec == bfd_abs_section_ptr)))
 	    {
 	      bfd_byte *p;
 	    nop_it:
@@ -17586,6 +17646,10 @@ ppc64_elf_relocate_section (bfd *output_bfd,
 	case R_PPC64_TOC16_LO_DS:
 	  if (htab->do_toc_opt && relocation + addend + 0x8000 < 0x10000
 	      && !ppc64_elf_tdata (input_bfd)->unexpected_toc_insn
+	      && !(bfd_link_pic (info)
+		   && (h != NULL
+		       ? bfd_is_abs_symbol (&h->elf.root)
+		       : sec == bfd_abs_section_ptr))
 	      && offset_in_range (input_section, rel->r_offset & ~3, 4))
 	    {
 	      bfd_byte *p = contents + (rel->r_offset & ~3);
diff --git a/ld/testsuite/ld-powerpc/abs-pie-relr.d b/ld/testsuite/ld-powerpc/abs-pie-relr.d
new file mode 100644
index 00000000000..edf0b430c78
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/abs-pie-relr.d
@@ -0,0 +1,34 @@
+#source: abs-reloc.s
+#as: -a64
+#ld: -melf64ppc -pie --hash-style=sysv -z pack-relative-relocs --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0
+#objdump: -sdr
+
+#...
+Contents of section .got:
+.* (00000000 00018300|00830100 00000000) (00000000 00000001|01000000 00000000) .*
+.* (00000000 00000002|02000000 00000000) (12345678 9abcdef0|f0debc9a 78563412) .*
+.* (00000000 00000002|02000000 00000000) (12345678 9abcdef0|f0debc9a 78563412) .*
+.* (00000000 00000001|01000000 00000000) .*
+Contents of section \.data:
+.* (00000000 00010338|38030100 00000000) (00000000 00000001|01000000 00000000) .*
+.* (00000000 00000002|02000000 00000000) (12345678 9abcdef0|f0debc9a 78563412) .*
+#...
+.* <_start>:
+.*:	(3c 4c 00 02|02 00 4c 3c) 	addis   r2,r12,2
+.*:	(38 42 81 58|58 81 42 38) 	addi    r2,r2,-32424
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(38 62 80 38|38 80 62 38) 	addi    r3,r2,-32712
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(e8 82 80 08|08 80 82 e8) 	ld      r4,-32760\(r2\)
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(e8 a2 80 10|10 80 a2 e8) 	ld      r5,-32752\(r2\)
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(e8 c2 80 18|18 80 c2 e8) 	ld      r6,-32744\(r2\)
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(38 e2 80 38|38 80 e2 38) 	addi    r7,r2,-32712
+.*:	(3d 02 00 00|00 00 02 3d) 	addis   r8,r2,0
+.*:	(e9 08 80 30|30 80 08 e9) 	ld      r8,-32720\(r8\)
+.*:	(3d 22 00 00|00 00 22 3d) 	addis   r9,r2,0
+.*:	(e9 29 80 20|20 80 29 e9) 	ld      r9,-32736\(r9\)
+.*:	(3d 42 00 00|00 00 42 3d) 	addis   r10,r2,0
+.*:	(e9 4a 80 28|28 80 4a e9) 	ld      r10,-32728\(r10\)
diff --git a/ld/testsuite/ld-powerpc/abs-pie-relr.r b/ld/testsuite/ld-powerpc/abs-pie-relr.r
new file mode 100644
index 00000000000..22effe89541
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/abs-pie-relr.r
@@ -0,0 +1,8 @@
+#source: abs-reloc.s
+#as: -a64
+#ld: -melf64ppc -pie --hash-style=sysv -z pack-relative-relocs --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0
+#readelf: -rW
+
+Relocation section '\.relr\.dyn' at offset .* contains 1 entry:
+  1 offset
+0+10338
diff --git a/ld/testsuite/ld-powerpc/abs-pie.d b/ld/testsuite/ld-powerpc/abs-pie.d
new file mode 100644
index 00000000000..b0930b6269f
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/abs-pie.d
@@ -0,0 +1,34 @@
+#source: abs-reloc.s
+#as: -a64
+#ld: -melf64ppc -pie --hash-style=sysv --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0
+#objdump: -sdr
+
+#...
+Contents of section \.got:
+.* (00000000 00018400|00840100 00000000) (00000000 00000001|01000000 00000000) .*
+.* (00000000 00000002|02000000 00000000) (12345678 9abcdef0|f0debc9a 78563412) .*
+.* (00000000 00000002|02000000 00000000) (12345678 9abcdef0|f0debc9a 78563412) .*
+.* (00000000 00000001|01000000 00000000) .*
+Contents of section \.data:
+.* (00000000 00010438|38040100 00000000) (00000000 00000001|01000000 00000000) .*
+.* (00000000 00000002|02000000 00000000) (12345678 9abcdef0|f0debc9a 78563412) .*
+#...
+.* <_start>:
+.*:	(3c 4c 00 02|02 00 4c 3c) 	addis   r2,r12,2
+.*:	(38 42 82 10|10 82 42 38) 	addi    r2,r2,-32240
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(38 62 80 38|38 80 62 38) 	addi    r3,r2,-32712
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(e8 82 80 08|08 80 82 e8) 	ld      r4,-32760\(r2\)
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(e8 a2 80 10|10 80 a2 e8) 	ld      r5,-32752\(r2\)
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(e8 c2 80 18|18 80 c2 e8) 	ld      r6,-32744\(r2\)
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(38 e2 80 38|38 80 e2 38) 	addi    r7,r2,-32712
+.*:	(3d 02 00 00|00 00 02 3d) 	addis   r8,r2,0
+.*:	(e9 08 80 30|30 80 08 e9) 	ld      r8,-32720\(r8\)
+.*:	(3d 22 00 00|00 00 22 3d) 	addis   r9,r2,0
+.*:	(e9 29 80 20|20 80 29 e9) 	ld      r9,-32736\(r9\)
+.*:	(3d 42 00 00|00 00 42 3d) 	addis   r10,r2,0
+.*:	(e9 4a 80 28|28 80 4a e9) 	ld      r10,-32728\(r10\)
diff --git a/ld/testsuite/ld-powerpc/abs-pie.r b/ld/testsuite/ld-powerpc/abs-pie.r
new file mode 100644
index 00000000000..2ae4d0e96a2
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/abs-pie.r
@@ -0,0 +1,8 @@
+#source: abs-reloc.s
+#as: -a64
+#ld: -melf64ppc -pie --hash-style=sysv --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0
+#readelf: -rW
+
+Relocation section '\.rela\.dyn' at offset .* contains 1 entry:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+0+10438 +0+16 R_PPC64_RELATIVE +10438
diff --git a/ld/testsuite/ld-powerpc/abs-reloc.s b/ld/testsuite/ld-powerpc/abs-reloc.s
new file mode 100644
index 00000000000..a5898e1dcb1
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/abs-reloc.s
@@ -0,0 +1,49 @@
+ .globl x
+ .hidden x
+
+ .section .toc,"aw"
+ .p2align 3
+.Lx:
+ .quad x
+.La:
+ .quad a
+.Lb:
+ .quad b
+.Lc:
+ .quad c
+
+ .data
+ .p2align 3
+x:
+ .quad x
+ .quad a
+ .quad b
+ .quad c
+
+ .text
+ .p2align 2
+ .globl _start
+ .type _start,@function
+_start:
+0:
+ addis 2,12,.TOC.-0b@ha
+ addi 2,2,.TOC.-0b@l
+ .localentry _start,.-_start
+ addis 3,2,.Lx@toc@ha
+ ld 3,.Lx@toc@l(3)
+ addis 4,2,.La@toc@ha
+ ld 4,.La@toc@l(4)
+ addis 5,2,.Lb@toc@ha
+ ld 5,.Lb@toc@l(5)
+ addis 6,2,.Lc@toc@ha
+ ld 6,.Lc@toc@l(6)
+
+ addis 7,2,x@got@ha
+ ld 7,x@got@l(7)
+ addis 8,2,a@got@ha
+ ld 8,a@got@l(8)
+ addis 9,2,b@got@ha
+ ld 9,b@got@l(9)
+ addis 10,2,c@got@ha
+ ld 10,c@got@l(10)
+ .size _start,.-_start
diff --git a/ld/testsuite/ld-powerpc/abs-shared-relr.d b/ld/testsuite/ld-powerpc/abs-shared-relr.d
new file mode 100644
index 00000000000..1460809bf0b
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/abs-shared-relr.d
@@ -0,0 +1,34 @@
+#source: abs-reloc.s
+#as: -a64
+#ld: -melf64ppc -shared --hash-style=sysv -z pack-relative-relocs --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0
+#objdump: -sdr
+
+#...
+Contents of section \.got:
+.* (00000000 00018400|00840100 00000000) 00000000 00000000 .*
+.* (00000000 00000002|02000000 00000000) 00000000 00000000 .*
+.* (00000000 00000002|02000000 00000000) 00000000 00000000 .*
+.* 00000000 00000000 .*
+Contents of section \.data:
+.* (00000000 00010438|38040100 00000000) 00000000 00000000 .*
+.* (00000000 00000002|02000000 00000000) 00000000 00000000 .*
+#...
+.* <_start>:
+.*:	(3c 4c 00 02|02 00 4c 3c) 	addis   r2,r12,2
+.*:	(38 42 81 b0|b0 81 42 38) 	addi    r2,r2,-32336
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(38 62 80 38|38 80 62 38) 	addi    r3,r2,-32712
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(e8 82 80 08|08 80 82 e8) 	ld      r4,-32760\(r2\)
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(e8 a2 80 10|10 80 a2 e8) 	ld      r5,-32752\(r2\)
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(e8 c2 80 18|18 80 c2 e8) 	ld      r6,-32744\(r2\)
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(38 e2 80 38|38 80 e2 38) 	addi    r7,r2,-32712
+.*:	(3d 02 00 00|00 00 02 3d) 	addis   r8,r2,0
+.*:	(e9 08 80 30|30 80 08 e9) 	ld      r8,-32720\(r8\)
+.*:	(3d 22 00 00|00 00 22 3d) 	addis   r9,r2,0
+.*:	(e9 29 80 20|20 80 29 e9) 	ld      r9,-32736\(r9\)
+.*:	(3d 42 00 00|00 00 42 3d) 	addis   r10,r2,0
+.*:	(e9 4a 80 28|28 80 4a e9) 	ld      r10,-32728\(r10\)
diff --git a/ld/testsuite/ld-powerpc/abs-shared-relr.r b/ld/testsuite/ld-powerpc/abs-shared-relr.r
new file mode 100644
index 00000000000..978c43a38e9
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/abs-shared-relr.r
@@ -0,0 +1,17 @@
+#source: abs-reloc.s
+#as: -a64
+#ld: -melf64ppc -pie --hash-style=sysv -z pack-relative-relocs --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0
+#readelf: -rW
+
+Relocation section '\.rela\.dyn' at offset .* contains 6 entries:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+0+10408  0+500000026 R_PPC64_ADDR64         0+1 a \+ 0
+0+10430  0+500000014 R_PPC64_GLOB_DAT       0+1 a \+ 0
+0+10440  0+500000026 R_PPC64_ADDR64         0+1 a \+ 0
+0+10418  0+400000026 R_PPC64_ADDR64         123456789abcdef0 c \+ 0
+0+10428  0+400000014 R_PPC64_GLOB_DAT       123456789abcdef0 c \+ 0
+0+10450  0+400000026 R_PPC64_ADDR64         123456789abcdef0 c \+ 0
+
+Relocation section '\.relr\.dyn' at offset .* contains 1 entry:
+  1 offset
+0+10438
diff --git a/ld/testsuite/ld-powerpc/abs-shared.d b/ld/testsuite/ld-powerpc/abs-shared.d
new file mode 100644
index 00000000000..b66a4b0b863
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/abs-shared.d
@@ -0,0 +1,34 @@
+#source: abs-reloc.s
+#as: -a64
+#ld: -melf64ppc -shared --hash-style=sysv --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0
+#objdump: -sdr
+
+#...
+Contents of section \.got:
+.* (00000000 00018400|00840100 00000000) 00000000 00000000 .*
+.* (00000000 00000002|02000000 00000000) 00000000 00000000 .*
+.* (00000000 00000002|02000000 00000000) 00000000 00000000 .*
+.* 00000000 00000000 .*
+Contents of section \.data:
+.* (00000000 00010438|38040100 00000000) 00000000 00000000 .*
+.* (00000000 00000002|02000000 00000000) 00000000 00000000 .*
+#...
+.* <_start>:
+.*:	(3c 4c 00 02|02 00 4c 3c) 	addis   r2,r12,2
+.*:	(38 42 81 a0|a0 81 42 38) 	addi    r2,r2,-32352
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(38 62 80 38|38 80 62 38) 	addi    r3,r2,-32712
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(e8 82 80 08|08 80 82 e8) 	ld      r4,-32760\(r2\)
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(e8 a2 80 10|10 80 a2 e8) 	ld      r5,-32752\(r2\)
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(e8 c2 80 18|18 80 c2 e8) 	ld      r6,-32744\(r2\)
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(38 e2 80 38|38 80 e2 38) 	addi    r7,r2,-32712
+.*:	(3d 02 00 00|00 00 02 3d) 	addis   r8,r2,0
+.*:	(e9 08 80 30|30 80 08 e9) 	ld      r8,-32720\(r8\)
+.*:	(3d 22 00 00|00 00 22 3d) 	addis   r9,r2,0
+.*:	(e9 29 80 20|20 80 29 e9) 	ld      r9,-32736\(r9\)
+.*:	(3d 42 00 00|00 00 42 3d) 	addis   r10,r2,0
+.*:	(e9 4a 80 28|28 80 4a e9) 	ld      r10,-32728\(r10\)
diff --git a/ld/testsuite/ld-powerpc/abs-shared.r b/ld/testsuite/ld-powerpc/abs-shared.r
new file mode 100644
index 00000000000..70fb78139ba
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/abs-shared.r
@@ -0,0 +1,14 @@
+#source: abs-reloc.s
+#as: -a64
+#ld: -melf64ppc -shared --hash-style=sysv --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0
+#readelf: -rW
+
+Relocation section '\.rela\.dyn' at offset .* contains 7 entries:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+0+10438  0+000000016 R_PPC64_RELATIVE +10438
+0+10408  0+500000026 R_PPC64_ADDR64         0+1 a \+ 0
+0+10430  0+500000014 R_PPC64_GLOB_DAT       0+1 a \+ 0
+0+10440  0+500000026 R_PPC64_ADDR64         0+1 a \+ 0
+0+10418  0+400000026 R_PPC64_ADDR64         123456789abcdef0 c \+ 0
+0+10428  0+400000014 R_PPC64_GLOB_DAT       123456789abcdef0 c \+ 0
+0+10450  0+400000026 R_PPC64_ADDR64         123456789abcdef0 c \+ 0
diff --git a/ld/testsuite/ld-powerpc/abs-static.d b/ld/testsuite/ld-powerpc/abs-static.d
new file mode 100644
index 00000000000..fafb1a6e944
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/abs-static.d
@@ -0,0 +1,32 @@
+#source: abs-reloc.s
+#as: -a64
+#ld: -melf64ppc -static --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0
+#objdump: -sdr
+
+#...
+Contents of section \.got:
+.* (00000000 10018100|00810110 00000000) (12345678 9abcdef0|f0debc9a 78563412) .*
+.* (12345678 9abcdef0|f0debc9a 78563412) .*
+Contents of section \.data:
+.* (00000000 10010118|18010110 00000000) (00000000 00000001|01000000 00000000) .*
+.* (00000000 00000002|02000000 00000000) (12345678 9abcdef0|f0debc9a 78563412) .*
+#...
+.* <_start>:
+.*:	(3c 40 10 02|02 10 40 3c) 	lis     r2,4098
+.*:	(38 42 81 00|00 81 42 38) 	addi    r2,r2,-32512
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(38 62 80 18|18 80 62 38) 	addi    r3,r2,-32744
+.*:	(3c 82 ef fe|fe ef 82 3c) 	addis   r4,r2,-4098
+.*:	(38 84 7f 01|01 7f 84 38) 	addi    r4,r4,32513
+.*:	(3c a2 ef fe|fe ef a2 3c) 	addis   r5,r2,-4098
+.*:	(38 a5 7f 02|02 7f a5 38) 	addi    r5,r5,32514
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(e8 c2 80 08|08 80 c2 e8) 	ld      r6,-32760\(r2\)
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(38 e2 80 18|18 80 e2 38) 	addi    r7,r2,-32744
+.*:	(3d 02 ef fe|fe ef 02 3d) 	addis   r8,r2,-4098
+.*:	(39 08 7f 01|01 7f 08 39) 	addi    r8,r8,32513
+.*:	(3d 22 ef fe|fe ef 22 3d) 	addis   r9,r2,-4098
+.*:	(39 29 7f 02|02 7f 29 39) 	addi    r9,r9,32514
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(e9 42 80 10|10 80 42 e9) 	ld      r10,-32752\(r2\)
diff --git a/ld/testsuite/ld-powerpc/abs-static.r b/ld/testsuite/ld-powerpc/abs-static.r
new file mode 100644
index 00000000000..4b5886cb021
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/abs-static.r
@@ -0,0 +1,6 @@
+#source: abs-reloc.s
+#as: -a64
+#ld: -melf64ppc -static --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0
+#readelf: -rW
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp
index 3d738f5f93c..318bf92c85f 100644
--- a/ld/testsuite/ld-powerpc/powerpc.exp
+++ b/ld/testsuite/ld-powerpc/powerpc.exp
@@ -354,6 +354,26 @@ set ppc64elftests {
     {"startstop" "-shared -melf64ppc --hash-style=sysv --gc-sections -z start-stop-gc" ""
 	"-a64 -mpower10" {startstop.s}
 	{{objdump -d startstop.d} {readelf {-rW} startstop.r}} "startstop.so"}
+    {"abs-static" "-melf64ppc -static --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0" ""
+	"-a64" {abs-reloc.s}
+	{{objdump {-sdr} abs-static.d}
+	 {readelf {-rW} abs-static.r}} "abs-static"}
+    {"abs-pie" "-melf64ppc -pie --hash-style=sysv --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0" ""
+	"-a64" {abs-reloc.s}
+	{{objdump {-sdr} abs-pie.d}
+	 {readelf {-rW} abs-pie.r}} "abs-pie"}
+    {"abs-shared" "-melf64ppc -shared --hash-style=sysv --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0" ""
+	"-a64" {abs-reloc.s}
+	{{objdump {-sdr} abs-shared.d}
+	 {readelf {-rW} abs-shared.r}} "abs-shared"}
+    {"abs-pie-relr" "-melf64ppc -pie --hash-style=sysv -z pack-relative-relocs --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0" ""
+	"-a64" {abs-reloc.s}
+	{{objdump {-sdr} abs-pie-relr.d}
+	 {readelf {-rW} abs-pie-relr.r}} "abs-pie-relr"}
+    {"abs-shared-relr" "-melf64ppc -shared --hash-style=sysv -z pack-relative-relocs --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0" ""
+	"-a64" {abs-reloc.s}
+	{{objdump {-sdr} abs-shared-relr.d}
+	 {readelf {-rW} abs-shared-relr.r}} "abs-shared-relr"}
 }
 
 set ppceabitests {

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-02-03  3:10 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-03  3:10 PowerPC64 treatment of absolute symbols Alan Modra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).