This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PowerPC non-PIC to PIC editing for protected var access


This is a linker-only solution to the incompatibility between shared
library protected visibility variables and using .dynbss and copy
relocs for non-PIC access to shared library variables.

See https://sourceware.org/ml/binutils/2015-03/msg00443.html

bfd/
	* elf32-ppc.c (struct ppc_elf_link_hash_entry): Add has_addr16_ha
	and has_addr16_lo.  Make has_sda_refs a bitfield.
	(ppc_elf_check_relocs): Set new flags.
	(ppc_elf_link_hash_table_create): Update default_params.
	(ppc_elf_adjust_dynamic_symbol): Clear protected_def in cases
	where we won't be making .dynbss entries or editing code.  Set
	params->pic_fixup when we'll edit code for protected var access.
	(allocate_dynrelocs): Allocate got entry for edited code and
	discard dyn_relocs.
	(struct ppc_elf_relax_info): Add picfixup_size.
	(ppc_elf_relax_section): Rename struct one_fixup to struct
	one_branch_fixup.  Rename fixups to branch_fixups.  Size space for
	pic fixups.
	(ppc_elf_relocate_section): Edit non-PIC accessing protected
	visibility variables to PIC.  Don't emit dyn_relocs for code
	we've edited.
	* elf32-ppc.h (struct ppc_elf_params): Add pic_fixup.
ld/
	* emultempl/ppc32elf.em: Handle --no-pic-fixup.
	(params): Init new field.
	(ppc_before_allocation): Enable relaxation for pic_fixup.

diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index b96dbc8..663a871 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -3135,7 +3135,11 @@ struct ppc_elf_link_hash_entry
 
   /* Nonzero if we have seen a small data relocation referring to this
      symbol.  */
-  unsigned char has_sda_refs;
+  unsigned char has_sda_refs : 1;
+
+  /* Flag use of given relocations.  */
+  unsigned char has_addr16_ha : 1;
+  unsigned char has_addr16_lo : 1;
 };
 
 #define ppc_elf_hash_entry(ent) ((struct ppc_elf_link_hash_entry *) (ent))
@@ -3259,7 +3263,7 @@ static struct bfd_link_hash_table *
 ppc_elf_link_hash_table_create (bfd *abfd)
 {
   struct ppc_elf_link_hash_table *ret;
-  static struct ppc_elf_params default_params = { PLT_OLD, 0, 1, 0, 0, 12 };
+  static struct ppc_elf_params default_params = { PLT_OLD, 0, 1, 0, 0, 12, 0 };
 
   ret = bfd_zmalloc (sizeof (struct ppc_elf_link_hash_table));
   if (ret == NULL)
@@ -4376,6 +4380,10 @@ ppc_elf_check_relocs (bfd *abfd,
 	      /* We may need a copy reloc too.  */
 	      h->non_got_ref = 1;
 	      h->pointer_equality_needed = 1;
+	      if (r_type == R_PPC_ADDR16_HA)
+		ppc_elf_hash_entry (h)->has_addr16_ha = 1;
+	      if (r_type == R_PPC_ADDR16_LO)
+		ppc_elf_hash_entry (h)->has_addr16_lo = 1;
 	    }
 	  goto dodyn;
 
@@ -5554,6 +5562,7 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 		   && !readonly_dynrelocs (h))
 	    h->non_got_ref = 0;
 	}
+      h->protected_def = 0;
       return TRUE;
     }
   else
@@ -5581,12 +5590,34 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
      For such cases we need not do anything here; the relocations will
      be handled correctly by relocate_section.  */
   if (info->shared)
-    return TRUE;
+    {
+      h->protected_def = 0;
+      return TRUE;
+    }
 
   /* If there are no references to this symbol that do not use the
      GOT, we don't need to generate a copy reloc.  */
   if (!h->non_got_ref)
-    return TRUE;
+    {
+      h->protected_def = 0;
+      return TRUE;
+    }
+
+  /* Protected variables do not work with .dynbss.  The copy in
+     .dynbss won't be used by the shared library with the protected
+     definition for the variable.  Editing to PIC, or text relocations
+     are preferable to an incorrect program.  */
+  if (h->protected_def)
+    {
+      if (ELIMINATE_COPY_RELOCS
+	  && ppc_elf_hash_entry (h)->has_addr16_ha
+	  && ppc_elf_hash_entry (h)->has_addr16_lo
+	  && htab->params->pic_fixup == 0
+	  && info->disable_target_specific_optimizations <= 1)
+	htab->params->pic_fixup = 1;
+      h->non_got_ref = 0;
+      return TRUE;
+    }
 
   /* If -z nocopyreloc was given, we won't generate them either.  */
   if (info->nocopyreloc)
@@ -5611,16 +5642,6 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
       return TRUE;
     }
 
-  /* Protected variables do not work with .dynbss.  The copy in
-     .dynbss won't be used by the shared library with the protected
-     definition for the variable.  Text relocations are preferable
-     to an incorrect program.  */
-  if (h->protected_def)
-    {
-      h->non_got_ref = 0;
-      return TRUE;
-    }
-
   /* We must allocate the symbol in our .dynbss section, which will
      become part of the .bss section of the executable.  There will be
      an entry for this symbol in the .dynsym section.  The dynamic
@@ -5929,7 +5950,13 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
     }
 
   eh = (struct ppc_elf_link_hash_entry *) h;
-  if (eh->elf.got.refcount > 0)
+  if (eh->elf.got.refcount > 0
+      || (ELIMINATE_COPY_RELOCS
+	  && !eh->elf.def_regular
+	  && eh->elf.protected_def
+	  && eh->has_addr16_ha
+	  && eh->has_addr16_lo
+	  && htab->params->pic_fixup > 0))
     {
       bfd_boolean dyn;
       unsigned int need;
@@ -6072,7 +6099,11 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	 dynamic.  */
 
       if (!h->non_got_ref
-	  && !h->def_regular)
+	  && !h->def_regular
+	  && !(h->protected_def
+	       && eh->has_addr16_ha
+	       && eh->has_addr16_lo
+	       && htab->params->pic_fixup > 0))
 	{
 	  /* Make sure this symbol is output as a dynamic symbol.
 	     Undefined weak syms won't yet be marked as dynamic.  */
@@ -6713,6 +6744,7 @@ static const int stub_entry[] =
 struct ppc_elf_relax_info
 {
   unsigned int workaround_size;
+  unsigned int picfixup_size;
 };
 
 /* This function implements long branch trampolines, and the ppc476
@@ -6726,9 +6758,9 @@ ppc_elf_relax_section (bfd *abfd,
 		       struct bfd_link_info *link_info,
 		       bfd_boolean *again)
 {
-  struct one_fixup
+  struct one_branch_fixup
   {
-    struct one_fixup *next;
+    struct one_branch_fixup *next;
     asection *tsec;
     /* Final link, can use the symbol offset.  For a
        relocatable link we use the symbol's index.  */
@@ -6741,12 +6773,12 @@ ppc_elf_relax_section (bfd *abfd,
   Elf_Internal_Sym *isymbuf = NULL;
   Elf_Internal_Rela *internal_relocs = NULL;
   Elf_Internal_Rela *irel, *irelend = NULL;
-  struct one_fixup *fixups = NULL;
+  struct one_branch_fixup *branch_fixups = NULL;
   struct ppc_elf_relax_info *relax_info = NULL;
   unsigned changes = 0;
   bfd_boolean workaround_change;
   struct ppc_elf_link_hash_table *htab;
-  bfd_size_type trampbase, trampoff, newsize;
+  bfd_size_type trampbase, trampoff, newsize, picfixup_size;
   asection *got2;
   bfd_boolean maybe_pasted;
 
@@ -6778,7 +6810,8 @@ ppc_elf_relax_section (bfd *abfd,
 	      || isec->sec_info_type == SEC_INFO_TYPE_TARGET);
   isec->sec_info_type = SEC_INFO_TYPE_TARGET;
 
-  if (htab->params->ppc476_workaround)
+  if (htab->params->ppc476_workaround
+      || htab->params->pic_fixup > 0)
     {
       if (elf_section_data (isec)->sec_info == NULL)
 	{
@@ -6799,8 +6832,9 @@ ppc_elf_relax_section (bfd *abfd,
     trampoff += 4;
 
   symtab_hdr = &elf_symtab_hdr (abfd);
-
-  if (htab->params->branch_trampolines)
+  picfixup_size = 0;
+  if (htab->params->branch_trampolines
+      || htab->params->pic_fixup > 0)
     {
       /* Get a copy of the native relocations.  */
       if (isec->reloc_count != 0)
@@ -6819,9 +6853,9 @@ ppc_elf_relax_section (bfd *abfd,
 	  unsigned long r_type = ELF32_R_TYPE (irel->r_info);
 	  bfd_vma toff, roff;
 	  asection *tsec;
-	  struct one_fixup *f;
+	  struct one_branch_fixup *f;
 	  size_t insn_offset = 0;
-	  bfd_vma max_branch_offset, val;
+	  bfd_vma max_branch_offset = 0, val;
 	  bfd_byte *hit_addr;
 	  unsigned long t0;
 	  struct elf_link_hash_entry *h;
@@ -6842,6 +6876,11 @@ ppc_elf_relax_section (bfd *abfd,
 	      max_branch_offset = 1 << 15;
 	      break;
 
+	    case R_PPC_ADDR16_HA:
+	      if (htab->params->pic_fixup > 0)
+		break;
+	      continue;
+
 	    default:
 	      continue;
 	    }
@@ -6963,6 +7002,17 @@ ppc_elf_relax_section (bfd *abfd,
 	      sym_type = h->type;
 	    }
 
+	  if (r_type == R_PPC_ADDR16_HA)
+	    {
+	      if (h != NULL
+		  && !h->def_regular
+		  && h->protected_def
+		  && ppc_elf_hash_entry (h)->has_addr16_ha
+		  && ppc_elf_hash_entry (h)->has_addr16_lo)
+		picfixup_size += 12;
+	      continue;
+	    }
+
 	  /* The condition here under which we call find_plt_ent must
 	     match that in relocate_section.  If we call find_plt_ent here
 	     but not in relocate_section, or vice versa, then the branch
@@ -7080,7 +7130,7 @@ ppc_elf_relax_section (bfd *abfd,
 	    }
 
 	  /* Look for an existing fixup to this address.  */
-	  for (f = fixups; f ; f = f->next)
+	  for (f = branch_fixups; f ; f = f->next)
 	    if (f->tsec == tsec && f->toff == toff)
 	      break;
 
@@ -7125,11 +7175,11 @@ ppc_elf_relax_section (bfd *abfd,
 
 	      /* Record the fixup so we don't do it again this section.  */
 	      f = bfd_malloc (sizeof (*f));
-	      f->next = fixups;
+	      f->next = branch_fixups;
 	      f->tsec = tsec;
 	      f->toff = toff;
 	      f->trampoff = trampoff;
-	      fixups = f;
+	      branch_fixups = f;
 
 	      trampoff += size;
 	      changes++;
@@ -7179,10 +7229,10 @@ ppc_elf_relax_section (bfd *abfd,
 	    }
 	}
 
-      while (fixups != NULL)
+      while (branch_fixups != NULL)
 	{
-	  struct one_fixup *f = fixups;
-	  fixups = fixups->next;
+	  struct one_branch_fixup *f = branch_fixups;
+	  branch_fixups = branch_fixups->next;
 	  free (f);
 	}
     }
@@ -7219,7 +7269,15 @@ ppc_elf_relax_section (bfd *abfd,
       newsize = trampoff + relax_info->workaround_size;
     }
 
-  if (changes || workaround_change)
+  if (htab->params->pic_fixup > 0)
+    {
+      picfixup_size -= relax_info->picfixup_size;
+      if (picfixup_size != 0)
+	relax_info->picfixup_size += picfixup_size;
+      newsize += relax_info->picfixup_size;
+    }
+
+  if (changes != 0 || picfixup_size != 0 || workaround_change)
     isec->size = newsize;
 
   if (isymbuf != NULL
@@ -7246,6 +7304,7 @@ ppc_elf_relax_section (bfd *abfd,
 	}
     }
 
+  changes += picfixup_size;
   if (changes != 0)
     {
       /* Append sufficient NOP relocs so we can write out relocation
@@ -7280,10 +7339,10 @@ ppc_elf_relax_section (bfd *abfd,
   return TRUE;
 
  error_return:
-  while (fixups != NULL)
+  while (branch_fixups != NULL)
     {
-      struct one_fixup *f = fixups;
-      fixups = fixups->next;
+      struct one_branch_fixup *f = branch_fixups;
+      branch_fixups = branch_fixups->next;
       free (f);
     }
   if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
@@ -7599,6 +7658,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
   bfd_boolean ret = TRUE;
   bfd_vma d_offset = (bfd_big_endian (output_bfd) ? 2 : 0);
   bfd_boolean is_vxworks_tls;
+  unsigned int picfixup_size = 0;
+  struct ppc_elf_relax_info *relax_info = NULL;
 
 #ifdef DEBUG
   _bfd_error_handler ("ppc_elf_relocate_section called for %B section %A, "
@@ -7623,6 +7684,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
   is_vxworks_tls = (htab->is_vxworks && info->shared
 		    && !strcmp (input_section->output_section->name,
 				".tls_vars"));
+  if (input_section->sec_info_type == SEC_INFO_TYPE_TARGET)
+    relax_info = elf_section_data (input_section)->sec_info;
   rel = relocs;
   relend = relocs + input_section->reloc_count;
   for (; rel < relend; rel++)
@@ -7980,6 +8043,114 @@ ppc_elf_relocate_section (bfd *output_bfd,
 	  }
 	}
 
+      if (ELIMINATE_COPY_RELOCS
+	  && h != NULL
+	  && !h->def_regular
+	  && h->protected_def
+	  && ppc_elf_hash_entry (h)->has_addr16_ha
+	  && ppc_elf_hash_entry (h)->has_addr16_lo
+	  && htab->params->pic_fixup > 0)
+	{
+	  /* Convert lis;addi or lis;load/store accessing a protected
+	     variable defined in a shared library to PIC.  */
+	  unsigned int insn;
+
+	  if (r_type == R_PPC_ADDR16_HA)
+	    {
+	      insn = bfd_get_32 (output_bfd,
+				 contents + rel->r_offset - d_offset);
+	      if ((insn & (0x3f << 26)) == (15u << 26)
+		  && (insn & (0x1f << 16)) == 0 /* lis */)
+		{
+		  bfd_byte *p;
+		  bfd_vma off;
+		  bfd_vma got_addr;
+
+		  p = (contents + input_section->size
+		       - relax_info->workaround_size
+		       - relax_info->picfixup_size
+		       + picfixup_size);
+		  off = (p - contents) - (rel->r_offset - d_offset);
+		  if (off > 0x1fffffc || (off & 3) != 0)
+		    info->callbacks->einfo
+		      (_("%P: %H: fixup branch overflow\n"),
+		       input_bfd, input_section, rel->r_offset);
+
+		  bfd_put_32 (output_bfd, B | off,
+			      contents + rel->r_offset - d_offset);
+		  got_addr = (htab->got->output_section->vma
+			      + htab->got->output_offset
+			      + (h->got.offset & ~1));
+		  rel->r_info = ELF32_R_INFO (0, R_PPC_ADDR16_HA);
+		  rel->r_addend = got_addr;
+		  rel->r_offset = (p - contents) + d_offset;
+		  insn &= ~0xffff;
+		  insn |= ((unsigned int )(got_addr + 0x8000) >> 16) & 0xffff;
+		  bfd_put_32 (output_bfd, insn, p);
+
+		  /* Convert lis to lwz, loading address from GOT.  */
+		  insn &= ~0xffff;
+		  insn ^= (32u ^ 15u) << 26;
+		  insn |= (insn & (0x1f << 21)) >> 5;
+		  insn |= got_addr & 0xffff;
+		  bfd_put_32 (output_bfd, insn, p + 4);
+
+		  bfd_put_32 (output_bfd, B | ((-4 - off) & 0x3ffffff), p + 8);
+		  picfixup_size += 12;
+
+		  /* Use one of the spare relocs, so --emit-relocs
+		     output is reasonable.  */
+		  memmove (rel + 1, rel, (relend - rel - 1) * sizeof (*rel));
+		  rel++;
+		  rel->r_info = ELF32_R_INFO (0, R_PPC_ADDR16_LO);
+		  rel->r_offset += 4;
+
+		  /* Continue on as if we had a got reloc, to output
+		     dynamic reloc.  */
+		  r_type = R_PPC_GOT16_LO;
+		}
+	      else
+		info->callbacks->einfo
+		  (_("%P: %H: error: %s with unexpected instruction %x\n"),
+		   input_bfd, input_section, rel->r_offset,
+		   "R_PPC_ADDR16_HA", insn);
+	    }
+	  else if (r_type == R_PPC_ADDR16_LO)
+	    {
+	      insn = bfd_get_32 (output_bfd,
+				 contents + rel->r_offset - d_offset);
+	      if ((insn & (0x3f << 26)) == 14u << 26    /* addi */
+		  || (insn & (0x3f << 26)) == 32u << 26 /* lwz */
+		  || (insn & (0x3f << 26)) == 34u << 26 /* lbz */
+		  || (insn & (0x3f << 26)) == 36u << 26 /* stw */
+		  || (insn & (0x3f << 26)) == 38u << 26 /* stb */
+		  || (insn & (0x3f << 26)) == 40u << 26 /* lhz */
+		  || (insn & (0x3f << 26)) == 42u << 26 /* lha */
+		  || (insn & (0x3f << 26)) == 44u << 26 /* sth */
+		  || (insn & (0x3f << 26)) == 46u << 26 /* lmw */
+		  || (insn & (0x3f << 26)) == 47u << 26 /* stmw */
+		  || (insn & (0x3f << 26)) == 48u << 26 /* lfs */
+		  || (insn & (0x3f << 26)) == 50u << 26 /* lfd */
+		  || (insn & (0x3f << 26)) == 52u << 26 /* stfs */
+		  || (insn & (0x3f << 26)) == 54u << 26 /* stfd */
+		  || ((insn & (0x3f << 26)) == 58u << 26 /* lwa,ld,lmd */
+		      && (insn & 3) != 1)
+		  || ((insn & (0x3f << 26)) == 62u << 26 /* std, stmd */
+		      && ((insn & 3) == 0 || (insn & 3) == 3)))
+		{
+		  /* Arrange to apply the reloc addend, if any.  */
+		  relocation = 0;
+		  unresolved_reloc = FALSE;
+		  rel->r_info = ELF32_R_INFO (0, r_type);
+		}
+	      else
+		info->callbacks->einfo
+		  (_("%P: %H: error: %s with unexpected instruction %x\n"),
+		   input_bfd, input_section, rel->r_offset,
+		   "R_PPC_ADDR16_LO", insn);
+	    }
+	}
+
       ifunc = NULL;
       if (!htab->is_vxworks)
 	{
@@ -8324,6 +8495,10 @@ ppc_elf_relocate_section (bfd *output_bfd,
 		  }
 	      }
 
+	    /* If here for a picfixup, we're done.  */
+	    if (r_type != ELF32_R_TYPE (rel->r_info))
+	      continue;
+
 	    relocation = (htab->got->output_section->vma
 			  + htab->got->output_offset
 			  + off
@@ -8471,7 +8646,11 @@ ppc_elf_relocate_section (bfd *output_bfd,
 		  && h != NULL
 		  && h->dynindx != -1
 		  && !h->non_got_ref
-		  && !h->def_regular))
+		  && !h->def_regular
+		  && !(h->protected_def
+		       && ppc_elf_hash_entry (h)->has_addr16_ha
+		       && ppc_elf_hash_entry (h)->has_addr16_lo
+		       && htab->params->pic_fixup > 0)))
 	    {
 	      int skip;
 	      bfd_byte *loc;
@@ -9296,11 +9475,9 @@ ppc_elf_relocate_section (bfd *output_bfd,
 	  || (input_section->output_section->alignment_power
 	      >= htab->params->pagesize_p2)))
     {
-      struct ppc_elf_relax_info *relax_info;
       bfd_vma start_addr, end_addr, addr;
       bfd_vma pagesize = (bfd_vma) 1 << htab->params->pagesize_p2;
 
-      relax_info = elf_section_data (input_section)->sec_info;
       if (relax_info->workaround_size != 0)
 	{
 	  bfd_byte *p;
diff --git a/bfd/elf32-ppc.h b/bfd/elf32-ppc.h
index 2feeec9..8eb8fcb 100644
--- a/bfd/elf32-ppc.h
+++ b/bfd/elf32-ppc.h
@@ -44,6 +44,10 @@ struct ppc_elf_params
   /* Avoid execution falling into new page.  */
   int ppc476_workaround;
   unsigned int pagesize_p2;
+
+  /* The bfd backend detected a non-PIC reference to a protected symbol
+     defined in a shared library.  */
+  int pic_fixup;
 };
 
 void ppc_elf_link_params (struct bfd_link_info *, struct ppc_elf_params *);
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 91e8c11..befab2c 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,9 @@
+2015-04-07  Alan Modra  <amodra@gmail.com>
+
+	* emultempl/ppc32elf.em: Handle --no-pic-fixup.
+	(params): Init new field.
+	(ppc_before_allocation): Enable relaxation for pic_fixup.
+
 2015-04-02  Andrew Turner <andrew@freebsd.org>
 
 	* Makefile.am: Add FreeBSD aarch64 files.
diff --git a/ld/emultempl/ppc32elf.em b/ld/emultempl/ppc32elf.em
index 719e57f..41ff746 100644
--- a/ld/emultempl/ppc32elf.em
+++ b/ld/emultempl/ppc32elf.em
@@ -41,7 +41,7 @@ static int old_got = 0;
 
 static bfd_vma pagesize = 0;
 
-static struct ppc_elf_params params = { PLT_UNSET, -1, 0, 0, 0, 0 };
+static struct ppc_elf_params params = { PLT_UNSET, -1, 0, 0, 0, 0, 0 };
 
 static void
 ppc_after_open_output (void)
@@ -172,7 +172,9 @@ ppc_before_allocation (void)
 	params.branch_trampolines = 1;
     }
 
-  if (params.ppc476_workaround || params.branch_trampolines)
+  if (params.branch_trampolines
+      || params.ppc476_workaround
+      || params.pic_fixup > 0)
     ENABLE_RELAXATION;
 }
 
@@ -249,6 +251,7 @@ PARSE_AND_LIST_PROLOGUE=${PARSE_AND_LIST_PROLOGUE}'
 #define OPTION_NO_STUBSYMS		(OPTION_STUBSYMS + 1)
 #define OPTION_PPC476_WORKAROUND	(OPTION_NO_STUBSYMS + 1)
 #define OPTION_NO_PPC476_WORKAROUND	(OPTION_PPC476_WORKAROUND + 1)
+#define OPTION_NO_PICFIXUP		(OPTION_NO_PPC476_WORKAROUND + 1)
 '
 
 PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
@@ -265,6 +268,7 @@ fi
 PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
   { "ppc476-workaround", optional_argument, NULL, OPTION_PPC476_WORKAROUND },
   { "no-ppc476-workaround", no_argument, NULL, OPTION_NO_PPC476_WORKAROUND },
+  { "no-pic-fixup", no_argument, NULL, OPTION_NO_PICFIXUP },
 '
 
 PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
@@ -282,7 +286,8 @@ fi
 PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'\
   --ppc476-workaround [=pagesize]\n\
                               Avoid a cache bug on ppc476.\n\
-  --no-ppc476-workaround      Disable workaround.\n"
+  --no-ppc476-workaround      Disable workaround.\n\
+  --no-pic-fixup              Don'\''t edit non-pic to pic.\n"
 		   ));
 '
 
@@ -336,6 +341,10 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
     case OPTION_NO_PPC476_WORKAROUND:
       params.ppc476_workaround = 0;
       break;
+
+    case OPTION_NO_PICFIXUP:
+      params.pic_fixup = -1;
+      break;
 '
 
 # Put these extra ppc32elf routines in ld_${EMULATION_NAME}_emulation

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]