mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 18:14:13 +08:00
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. 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.
This commit is contained in:
parent
d9b67d9f41
commit
d3e454b956
@ -1,3 +1,23 @@
|
||||
2015-04-07 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2015-04-07 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* elf.c (_bfd_elf_is_local_label_name): Treat assembler generated
|
||||
|
253
bfd/elf32-ppc.c
253
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;
|
||||
|
@ -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 *);
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user