|
|
010229e |
diff -rup ../binutils-2.19.51.0.14.original/bfd/ChangeLog bfd/ChangeLog
|
|
|
010229e |
--- ../binutils-2.19.51.0.14.original/bfd/ChangeLog 2010-02-08 15:39:17.000000000 +0000
|
|
|
010229e |
+++ bfd/ChangeLog 2010-02-08 15:40:38.000000000 +0000
|
|
|
010229e |
@@ -1,3 +1,30 @@
|
|
|
010229e |
+2010-02-08 Nick Clifton <nickc@redhat.com>
|
|
|
010229e |
+
|
|
|
010229e |
+ BZ 562249
|
|
|
010229e |
+ Import this patch from the mainline:
|
|
|
010229e |
+
|
|
|
010229e |
+ 2009-12-17 Alan Modra <amodra@bigpond.net.au>
|
|
|
010229e |
+
|
|
|
010229e |
+ PR ld/11088
|
|
|
010229e |
+ * elf64-ppc.c (ppc64_elf_gc_sweep_hook): Don't abort if symbol
|
|
|
010229e |
+ hiding has nulled out plt.plist.
|
|
|
010229e |
+
|
|
|
010229e |
+ PR ld/11088
|
|
|
010229e |
+ * elf32-ppc.c (update_plt_info): Clear sec here when addend is
|
|
|
010229e |
+ less than 32768..
|
|
|
010229e |
+ (ppc_elf_check_relocs): ..rather than doing so here. Ignore new
|
|
|
010229e |
+ relax relocs.
|
|
|
010229e |
+ (ppc_elf_gc_sweep_hook): Don't segfault when symbol hiding has
|
|
|
010229e |
+ removed plt_entry records.
|
|
|
010229e |
+ (ppc_elf_tls_setup): Handle PIE calls to __tls_get_addr correctly.
|
|
|
010229e |
+ (ppc_elf_tls_optimize): Likewise. Also dec __tls_get_addr refcount
|
|
|
010229e |
+ when optimizing code using new tlsgd and tlsld marker relocs.
|
|
|
010229e |
+ (ppc_elf_relax_section): Differentiate relaxed PLTREL24 relocs
|
|
|
010229e |
+ from ADDR24 relocs using plt or glink. Don't clear the addend
|
|
|
010229e |
+ for R_PPC_RELAX_PLTREL24.
|
|
|
010229e |
+ (ppc_elf_relocate_section): Correctly handle addends on relaxed
|
|
|
010229e |
+ PLTREL24 relocs.
|
|
|
010229e |
+
|
|
|
010229e |
2009-07-22 H.J. Lu <hongjiu.lu@intel.com>
|
|
|
010229e |
|
|
|
010229e |
PR ld/10433
|
|
|
010229e |
diff -rup ../binutils-2.19.51.0.14.original/bfd/elf32-ppc.c bfd/elf32-ppc.c
|
|
|
010229e |
--- ../binutils-2.19.51.0.14.original/bfd/elf32-ppc.c 2010-02-08 15:39:17.000000000 +0000
|
|
|
010229e |
+++ bfd/elf32-ppc.c 2010-02-08 16:01:59.000000000 +0000
|
|
|
010229e |
@@ -3309,9 +3309,13 @@ update_plt_info (bfd *abfd, struct plt_e
|
|
|
010229e |
{
|
|
|
010229e |
struct plt_entry *ent;
|
|
|
010229e |
|
|
|
010229e |
+ if (addend < 32768)
|
|
|
010229e |
+ sec = NULL;
|
|
|
010229e |
+
|
|
|
010229e |
for (ent = *plist; ent != NULL; ent = ent->next)
|
|
|
010229e |
if (ent->sec == sec && ent->addend == addend)
|
|
|
010229e |
break;
|
|
|
010229e |
+
|
|
|
010229e |
if (ent == NULL)
|
|
|
010229e |
{
|
|
|
010229e |
bfd_size_type amt = sizeof (*ent);
|
|
|
010229e |
@@ -3500,8 +3504,7 @@ ppc_elf_check_relocs (bfd *abfd,
|
|
|
010229e |
ppc_elf_tdata (abfd)->makes_plt_call = 1;
|
|
|
010229e |
addend = rel->r_addend;
|
|
|
010229e |
}
|
|
|
010229e |
- if (!update_plt_info (abfd, ifunc,
|
|
|
010229e |
- addend < 32768 ? NULL : got2, addend))
|
|
|
010229e |
+ if (!update_plt_info (abfd, ifunc, got2, addend))
|
|
|
010229e |
return FALSE;
|
|
|
010229e |
|
|
|
010229e |
if (htab->glink == NULL)
|
|
|
010229e |
@@ -3727,8 +3730,7 @@ ppc_elf_check_relocs (bfd *abfd,
|
|
|
010229e |
addend = rel->r_addend;
|
|
|
010229e |
}
|
|
|
010229e |
h->needs_plt = 1;
|
|
|
010229e |
- if (!update_plt_info (abfd, &h->plt.plist,
|
|
|
010229e |
- addend < 32768 ? NULL : got2, addend))
|
|
|
010229e |
+ if (!update_plt_info (abfd, &h->plt.plist, got2, addend))
|
|
|
010229e |
return FALSE;
|
|
|
010229e |
}
|
|
|
010229e |
break;
|
|
|
010229e |
@@ -3759,10 +3761,9 @@ ppc_elf_check_relocs (bfd *abfd,
|
|
|
010229e |
case R_PPC_EMB_MRKREF:
|
|
|
010229e |
case R_PPC_NONE:
|
|
|
010229e |
case R_PPC_max:
|
|
|
010229e |
- case R_PPC_RELAX32:
|
|
|
010229e |
- case R_PPC_RELAX32PC:
|
|
|
010229e |
- case R_PPC_RELAX32_PLT:
|
|
|
010229e |
- case R_PPC_RELAX32PC_PLT:
|
|
|
010229e |
+ case R_PPC_RELAX:
|
|
|
010229e |
+ case R_PPC_RELAX_PLT:
|
|
|
010229e |
+ case R_PPC_RELAX_PLTREL24:
|
|
|
010229e |
break;
|
|
|
010229e |
|
|
|
010229e |
/* These should only appear in dynamic objects. */
|
|
|
010229e |
@@ -4431,7 +4432,8 @@ ppc_elf_gc_sweep_hook (bfd *abfd,
|
|
|
010229e |
{
|
|
|
010229e |
bfd_vma addend = r_type == R_PPC_PLTREL24 ? rel->r_addend : 0;
|
|
|
010229e |
struct plt_entry *ent = find_plt_ent (ifunc, got2, addend);
|
|
|
010229e |
- if (ent->plt.refcount > 0)
|
|
|
010229e |
+
|
|
|
010229e |
+ if (ent != NULL && ent->plt.refcount > 0)
|
|
|
010229e |
ent->plt.refcount -= 1;
|
|
|
010229e |
continue;
|
|
|
010229e |
}
|
|
|
010229e |
@@ -4505,7 +4507,8 @@ ppc_elf_gc_sweep_hook (bfd *abfd,
|
|
|
010229e |
bfd_vma addend = r_type == R_PPC_PLTREL24 ? rel->r_addend : 0;
|
|
|
010229e |
struct plt_entry *ent = find_plt_ent (&h->plt.plist,
|
|
|
010229e |
got2, addend);
|
|
|
010229e |
- if (ent->plt.refcount > 0)
|
|
|
010229e |
+
|
|
|
010229e |
+ if (ent != NULL && ent->plt.refcount > 0)
|
|
|
010229e |
ent->plt.refcount -= 1;
|
|
|
010229e |
}
|
|
|
010229e |
break;
|
|
|
010229e |
@@ -4591,6 +4594,7 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUT
|
|
|
010229e |
{
|
|
|
010229e |
Elf_Internal_Sym *locsyms = NULL;
|
|
|
010229e |
Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (ibfd);
|
|
|
010229e |
+ asection *got2 = bfd_get_section_by_name (ibfd, ".got2");
|
|
|
010229e |
|
|
|
010229e |
for (sec = ibfd->sections; sec != NULL; sec = sec->next)
|
|
|
010229e |
if (sec->has_tls_reloc && !bfd_is_abs_section (sec->output_section))
|
|
|
010229e |
@@ -4684,6 +4688,13 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUT
|
|
|
010229e |
else
|
|
|
010229e |
continue;
|
|
|
010229e |
|
|
|
010229e |
+ case R_PPC_TLSGD:
|
|
|
010229e |
+ case R_PPC_TLSLD:
|
|
|
010229e |
+ expecting_tls_get_addr = 2;
|
|
|
010229e |
+ tls_set = 0;
|
|
|
010229e |
+ tls_clear = 0;
|
|
|
010229e |
+ break;
|
|
|
010229e |
+
|
|
|
010229e |
default:
|
|
|
010229e |
continue;
|
|
|
010229e |
}
|
|
|
010229e |
@@ -4691,7 +4702,8 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUT
|
|
|
010229e |
if (pass == 0)
|
|
|
010229e |
{
|
|
|
010229e |
if (!expecting_tls_get_addr
|
|
|
010229e |
- || !sec->has_tls_get_addr_call)
|
|
|
010229e |
+ || (expecting_tls_get_addr == 1
|
|
|
010229e |
+ && ! sec->has_tls_get_addr_call))
|
|
|
010229e |
continue;
|
|
|
010229e |
|
|
|
010229e |
if (rel + 1 < relend
|
|
|
010229e |
@@ -4707,6 +4719,23 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUT
|
|
|
010229e |
break;
|
|
|
010229e |
}
|
|
|
010229e |
|
|
|
010229e |
+ if (expecting_tls_get_addr)
|
|
|
010229e |
+ {
|
|
|
010229e |
+ struct plt_entry *ent;
|
|
|
010229e |
+ bfd_vma addend = 0;
|
|
|
010229e |
+
|
|
|
010229e |
+ if (info->shared
|
|
|
010229e |
+ && ELF32_R_TYPE (rel[1].r_info) == R_PPC_PLTREL24)
|
|
|
010229e |
+ addend = rel[1].r_addend;
|
|
|
010229e |
+ ent = find_plt_ent (&htab->tls_get_addr->plt.plist,
|
|
|
010229e |
+ got2, addend);
|
|
|
010229e |
+ if (ent != NULL && ent->plt.refcount > 0)
|
|
|
010229e |
+ ent->plt.refcount -= 1;
|
|
|
010229e |
+
|
|
|
010229e |
+ if (expecting_tls_get_addr == 2)
|
|
|
010229e |
+ continue;
|
|
|
010229e |
+ }
|
|
|
010229e |
+
|
|
|
010229e |
if (h != NULL)
|
|
|
010229e |
{
|
|
|
010229e |
tls_mask = &ppc_elf_hash_entry (h)->tls_mask;
|
|
|
010229e |
@@ -4751,16 +4780,6 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUT
|
|
|
010229e |
*got_count -= 1;
|
|
|
010229e |
}
|
|
|
010229e |
|
|
|
010229e |
- if (expecting_tls_get_addr)
|
|
|
010229e |
- {
|
|
|
010229e |
- struct plt_entry *ent;
|
|
|
010229e |
-
|
|
|
010229e |
- ent = find_plt_ent (&htab->tls_get_addr->plt.plist,
|
|
|
010229e |
- NULL, 0);
|
|
|
010229e |
- if (ent != NULL && ent->plt.refcount > 0)
|
|
|
010229e |
- ent->plt.refcount -= 1;
|
|
|
010229e |
- }
|
|
|
010229e |
-
|
|
|
010229e |
*tls_mask |= tls_set;
|
|
|
010229e |
*tls_mask &= ~tls_clear;
|
|
|
010229e |
}
|
|
|
010229e |
@@ -6098,28 +6117,29 @@ ppc_elf_relax_section (bfd *abfd,
|
|
|
010229e |
{
|
|
|
010229e |
size = 4 * ARRAY_SIZE (shared_stub_entry);
|
|
|
010229e |
insn_offset = 12;
|
|
|
010229e |
- stub_rtype = R_PPC_RELAX32PC;
|
|
|
010229e |
}
|
|
|
010229e |
else
|
|
|
010229e |
{
|
|
|
010229e |
size = 4 * ARRAY_SIZE (stub_entry);
|
|
|
010229e |
insn_offset = 0;
|
|
|
010229e |
- stub_rtype = R_PPC_RELAX32;
|
|
|
010229e |
}
|
|
|
010229e |
|
|
|
010229e |
- if (R_PPC_RELAX32_PLT - R_PPC_RELAX32
|
|
|
010229e |
- != R_PPC_RELAX32PC_PLT - R_PPC_RELAX32PC)
|
|
|
010229e |
- abort ();
|
|
|
010229e |
+ stub_rtype = R_PPC_RELAX;
|
|
|
010229e |
if (tsec == htab->plt
|
|
|
010229e |
|| tsec == htab->glink)
|
|
|
010229e |
- stub_rtype += R_PPC_RELAX32_PLT - R_PPC_RELAX32;
|
|
|
010229e |
+ {
|
|
|
010229e |
+ stub_rtype = R_PPC_RELAX_PLT;
|
|
|
010229e |
+ if (r_type == R_PPC_PLTREL24)
|
|
|
010229e |
+ stub_rtype = R_PPC_RELAX_PLTREL24;
|
|
|
010229e |
+ }
|
|
|
010229e |
|
|
|
010229e |
/* Hijack the old relocation. Since we need two
|
|
|
010229e |
relocations for this use a "composite" reloc. */
|
|
|
010229e |
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
|
|
|
010229e |
stub_rtype);
|
|
|
010229e |
irel->r_offset = trampoff + insn_offset;
|
|
|
010229e |
- if (r_type == R_PPC_PLTREL24)
|
|
|
010229e |
+ if (r_type == R_PPC_PLTREL24
|
|
|
010229e |
+ && stub_rtype != R_PPC_RELAX_PLTREL24)
|
|
|
010229e |
irel->r_addend = 0;
|
|
|
010229e |
|
|
|
010229e |
/* Record the fixup so we don't do it again this section. */
|
|
|
010229e |
@@ -6289,7 +6309,7 @@ ppc_elf_relax_section (bfd *abfd,
|
|
|
010229e |
{
|
|
|
010229e |
/* Convert the internal relax relocs to external form. */
|
|
|
010229e |
for (irel = internal_relocs; irel < irelend; irel++)
|
|
|
010229e |
- if (ELF32_R_TYPE (irel->r_info) == R_PPC_RELAX32)
|
|
|
010229e |
+ if (ELF32_R_TYPE (irel->r_info) == R_PPC_RELAX)
|
|
|
010229e |
{
|
|
|
010229e |
unsigned long r_symndx = ELF32_R_SYM (irel->r_info);
|
|
|
010229e |
|
|
|
010229e |
@@ -7461,32 +7481,36 @@ ppc_elf_relocate_section (bfd *output_bf
|
|
|
010229e |
}
|
|
|
010229e |
break;
|
|
|
010229e |
|
|
|
010229e |
- case R_PPC_RELAX32PC_PLT:
|
|
|
010229e |
- case R_PPC_RELAX32_PLT:
|
|
|
010229e |
- {
|
|
|
010229e |
- struct plt_entry *ent = find_plt_ent (&h->plt.plist, got2, addend);
|
|
|
010229e |
-
|
|
|
010229e |
- if (htab->plt_type == PLT_NEW)
|
|
|
010229e |
- relocation = (htab->glink->output_section->vma
|
|
|
010229e |
- + htab->glink->output_offset
|
|
|
010229e |
- + ent->glink_offset);
|
|
|
010229e |
- else
|
|
|
010229e |
- relocation = (htab->plt->output_section->vma
|
|
|
010229e |
- + htab->plt->output_offset
|
|
|
010229e |
- + ent->plt.offset);
|
|
|
010229e |
- }
|
|
|
010229e |
- if (r_type == R_PPC_RELAX32_PLT)
|
|
|
010229e |
- goto relax32;
|
|
|
010229e |
- /* Fall thru */
|
|
|
010229e |
+ case R_PPC_RELAX_PLT:
|
|
|
010229e |
+ case R_PPC_RELAX_PLTREL24:
|
|
|
010229e |
+ if (h != NULL)
|
|
|
010229e |
+ {
|
|
|
010229e |
+ struct plt_entry *ent;
|
|
|
010229e |
+ bfd_vma got2_addend = 0;
|
|
|
010229e |
|
|
|
010229e |
- case R_PPC_RELAX32PC:
|
|
|
010229e |
- relocation -= (input_section->output_section->vma
|
|
|
010229e |
- + input_section->output_offset
|
|
|
010229e |
- + rel->r_offset - 4);
|
|
|
010229e |
+ if (r_type == R_PPC_RELAX_PLTREL24)
|
|
|
010229e |
+ {
|
|
|
010229e |
+ if (info->shared)
|
|
|
010229e |
+ got2_addend = addend;
|
|
|
010229e |
+ addend = 0;
|
|
|
010229e |
+ }
|
|
|
010229e |
+ ent = find_plt_ent (&h->plt.plist, got2, got2_addend);
|
|
|
010229e |
+ if (htab->plt_type == PLT_NEW)
|
|
|
010229e |
+ relocation = (htab->glink->output_section->vma
|
|
|
010229e |
+ + htab->glink->output_offset
|
|
|
010229e |
+ + ent->glink_offset);
|
|
|
010229e |
+ else
|
|
|
010229e |
+ relocation = (htab->plt->output_section->vma
|
|
|
010229e |
+ + htab->plt->output_offset
|
|
|
010229e |
+ + ent->plt.offset);
|
|
|
010229e |
+ }
|
|
|
010229e |
/* Fall thru */
|
|
|
010229e |
|
|
|
010229e |
- case R_PPC_RELAX32:
|
|
|
010229e |
- relax32:
|
|
|
010229e |
+ case R_PPC_RELAX:
|
|
|
010229e |
+ if (info->shared)
|
|
|
010229e |
+ relocation -= (input_section->output_section->vma
|
|
|
010229e |
+ + input_section->output_offset
|
|
|
010229e |
+ + rel->r_offset - 4);
|
|
|
010229e |
{
|
|
|
010229e |
unsigned long t0;
|
|
|
010229e |
unsigned long t1;
|
|
|
010229e |
diff -rup ../binutils-2.19.51.0.14.original/include/elf/ppc.h include/elf/ppc.h
|
|
|
010229e |
--- ../binutils-2.19.51.0.14.original/include/elf/ppc.h 2010-02-08 15:39:06.000000000 +0000
|
|
|
010229e |
+++ include/elf/ppc.h 2010-02-08 16:47:05.000000000 +0000
|
|
|
010229e |
@@ -73,10 +73,9 @@ START_RELOC_NUMBERS (elf_ppc_reloc_type)
|
|
|
010229e |
|
|
|
010229e |
#ifndef RELOC_MACROS_GEN_FUNC
|
|
|
010229e |
/* Fake relocations for branch stubs, only used internally by ld. */
|
|
|
010229e |
- RELOC_NUMBER (R_PPC_RELAX32, 48)
|
|
|
010229e |
- RELOC_NUMBER (R_PPC_RELAX32PC, 49)
|
|
|
010229e |
- RELOC_NUMBER (R_PPC_RELAX32_PLT, 50)
|
|
|
010229e |
- RELOC_NUMBER (R_PPC_RELAX32PC_PLT, 51)
|
|
|
010229e |
+ RELOC_NUMBER (R_PPC_RELAX, 48)
|
|
|
010229e |
+ RELOC_NUMBER (R_PPC_RELAX_PLT, 49)
|
|
|
010229e |
+ RELOC_NUMBER (R_PPC_RELAX_PLTREL24, 50)
|
|
|
010229e |
#endif
|
|
|
010229e |
|
|
|
010229e |
/* Relocs added to support TLS. */
|
|
|
1c83073 |
--- ../binutils-2.19.51.0.14.original/bfd/elf64-ppc.c 2010-02-08 15:39:17.000000000 +0000
|
|
|
1c83073 |
+++ bfd/elf64-ppc.c 2010-02-09 15:36:43.000000000 +0000
|
|
|
1c83073 |
@@ -5640,9 +5640,7 @@ ppc64_elf_gc_sweep_hook (bfd *abfd, stru
|
|
|
1c83073 |
for (ent = *ifunc; ent != NULL; ent = ent->next)
|
|
|
1c83073 |
if (ent->addend == rel->r_addend)
|
|
|
1c83073 |
break;
|
|
|
1c83073 |
- if (ent == NULL)
|
|
|
1c83073 |
- abort ();
|
|
|
1c83073 |
- if (ent->plt.refcount > 0)
|
|
|
1c83073 |
+ if (ent != NULL && ent->plt.refcount > 0)
|
|
|
1c83073 |
ent->plt.refcount -= 1;
|
|
|
1c83073 |
continue;
|
|
|
1c83073 |
}
|
|
|
1c83073 |
@@ -5721,9 +5719,7 @@ ppc64_elf_gc_sweep_hook (bfd *abfd, stru
|
|
|
1c83073 |
for (ent = h->plt.plist; ent != NULL; ent = ent->next)
|
|
|
1c83073 |
if (ent->addend == rel->r_addend)
|
|
|
1c83073 |
break;
|
|
|
1c83073 |
- if (ent == NULL)
|
|
|
1c83073 |
- abort ();
|
|
|
1c83073 |
- if (ent->plt.refcount > 0)
|
|
|
1c83073 |
+ if (ent != NULL && ent->plt.refcount > 0)
|
|
|
1c83073 |
ent->plt.refcount -= 1;
|
|
|
1c83073 |
}
|
|
|
1c83073 |
break;
|