mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-23 20:19:49 +00:00
bfd/
* elf64-ppc.c (build_plt_stub): Add relocs on plt call stubs if emitrelocations. (get_relocs): New function, split out from.. (ppc_build_one_stub): ..here. Add relocs on plt_branch stubs if emitrelocations. Remove indx temp. (ppc_size_one_stub): Count new stub relocs. (ppc64_elf_size_stubs): Count new glink reloc. (ppc64_elf_build_stubs): Emit glink reloc if emitrelocations. (ppc64_elf_finish_dynamic_sections): Output glink relocs. * elf32-ppc.c (ppc_elf_finish_dynamic_sections): Describe non-pic glink code. ld/testsuite/ * ld-powerpc/relbrlt.d: Update. Also check .branch_lt section.
This commit is contained in:
parent
c03374d554
commit
176a0d42d0
@ -1,3 +1,17 @@
|
||||
2008-03-01 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf64-ppc.c (build_plt_stub): Add relocs on plt call stubs
|
||||
if emitrelocations.
|
||||
(get_relocs): New function, split out from..
|
||||
(ppc_build_one_stub): ..here. Add relocs on plt_branch stubs if
|
||||
emitrelocations. Remove indx temp.
|
||||
(ppc_size_one_stub): Count new stub relocs.
|
||||
(ppc64_elf_size_stubs): Count new glink reloc.
|
||||
(ppc64_elf_build_stubs): Emit glink reloc if emitrelocations.
|
||||
(ppc64_elf_finish_dynamic_sections): Output glink relocs.
|
||||
* elf32-ppc.c (ppc_elf_finish_dynamic_sections): Describe non-pic
|
||||
glink code.
|
||||
|
||||
2008-02-28 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf32-spu.c (mark_functions_via_relocs): Don't assume that
|
||||
|
@ -7534,7 +7534,7 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
|
||||
* bctr
|
||||
*
|
||||
* # A table of branches, one for each plt entry.
|
||||
* # The idea is that the plt call stub loads ctr (and r11) with these
|
||||
* # The idea is that the plt call stub loads ctr and r11 with these
|
||||
* # addresses, so (r11 - res_0) gives the plt index * 4.
|
||||
* res_0: b PLTresolve
|
||||
* res_1: b PLTresolve
|
||||
@ -7580,6 +7580,28 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
|
||||
NOP
|
||||
};
|
||||
|
||||
/*
|
||||
* Non-PIC glink code is a little simpler.
|
||||
*
|
||||
* # ith PLT code stub.
|
||||
* lis 11,(plt+(i-1)*4)@ha
|
||||
* lwz 11,(plt+(i-1)*4)@l(11)
|
||||
* mtctr 11
|
||||
* bctr
|
||||
*
|
||||
* The branch table is the same, then comes
|
||||
*
|
||||
* PLTresolve:
|
||||
* lis 12,(got+4)@ha
|
||||
* addis 11,11,(-res_0)@ha
|
||||
* lwz 0,(got+4)@l(12) # got[1] address of dl_runtime_resolve
|
||||
* addi 11,11,(-res_0)@l # r11 = index * 4
|
||||
* mtctr 0
|
||||
* add 0,11,11
|
||||
* lwz 12,(got+8)@l(12) # got[2] contains the map address
|
||||
* add 11,0,11 # r11 = index * 12 = reloc offset.
|
||||
* bctr
|
||||
*/
|
||||
static const unsigned int plt_resolve[] =
|
||||
{
|
||||
LIS_12,
|
||||
|
262
bfd/elf64-ppc.c
262
bfd/elf64-ppc.c
@ -8245,7 +8245,7 @@ ppc_type_of_stub (asection *input_sec,
|
||||
/* Build a .plt call stub. */
|
||||
|
||||
static inline bfd_byte *
|
||||
build_plt_stub (bfd *obfd, bfd_byte *p, int offset)
|
||||
build_plt_stub (bfd *obfd, bfd_byte *p, int offset, Elf_Internal_Rela *r)
|
||||
{
|
||||
#define PPC_LO(v) ((v) & 0xffff)
|
||||
#define PPC_HI(v) (((v) >> 16) & 0xffff)
|
||||
@ -8253,6 +8253,28 @@ build_plt_stub (bfd *obfd, bfd_byte *p, int offset)
|
||||
|
||||
if (PPC_HA (offset) != 0)
|
||||
{
|
||||
if (r != NULL)
|
||||
{
|
||||
r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_HA);
|
||||
r[1].r_offset = r[0].r_offset + 8;
|
||||
r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
|
||||
r[1].r_addend = r[0].r_addend;
|
||||
if (PPC_HA (offset + 16) != PPC_HA (offset))
|
||||
{
|
||||
r[2].r_offset = r[1].r_offset + 4;
|
||||
r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO);
|
||||
r[2].r_addend = r[0].r_addend;
|
||||
}
|
||||
else
|
||||
{
|
||||
r[2].r_offset = r[1].r_offset + 8;
|
||||
r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
|
||||
r[2].r_addend = r[0].r_addend + 8;
|
||||
r[3].r_offset = r[2].r_offset + 4;
|
||||
r[3].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
|
||||
r[3].r_addend = r[0].r_addend + 16;
|
||||
}
|
||||
}
|
||||
bfd_put_32 (obfd, ADDIS_R12_R2 | PPC_HA (offset), p), p += 4;
|
||||
bfd_put_32 (obfd, STD_R2_40R1, p), p += 4;
|
||||
bfd_put_32 (obfd, LD_R11_0R12 | PPC_LO (offset), p), p += 4;
|
||||
@ -8268,6 +8290,26 @@ build_plt_stub (bfd *obfd, bfd_byte *p, int offset)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (r != NULL)
|
||||
{
|
||||
r[0].r_offset += 4;
|
||||
r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
|
||||
if (PPC_HA (offset + 16) != PPC_HA (offset))
|
||||
{
|
||||
r[1].r_offset = r[0].r_offset + 4;
|
||||
r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16);
|
||||
r[1].r_addend = r[0].r_addend;
|
||||
}
|
||||
else
|
||||
{
|
||||
r[1].r_offset = r[0].r_offset + 8;
|
||||
r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
|
||||
r[1].r_addend = r[0].r_addend + 16;
|
||||
r[2].r_offset = r[1].r_offset + 4;
|
||||
r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
|
||||
r[2].r_addend = r[0].r_addend + 8;
|
||||
}
|
||||
}
|
||||
bfd_put_32 (obfd, STD_R2_40R1, p), p += 4;
|
||||
bfd_put_32 (obfd, LD_R11_0R2 | PPC_LO (offset), p), p += 4;
|
||||
if (PPC_HA (offset + 16) != PPC_HA (offset))
|
||||
@ -8283,6 +8325,32 @@ build_plt_stub (bfd *obfd, bfd_byte *p, int offset)
|
||||
return p;
|
||||
}
|
||||
|
||||
static Elf_Internal_Rela *
|
||||
get_relocs (asection *sec, int count)
|
||||
{
|
||||
Elf_Internal_Rela *relocs;
|
||||
struct bfd_elf_section_data *elfsec_data;
|
||||
|
||||
elfsec_data = elf_section_data (sec);
|
||||
relocs = elfsec_data->relocs;
|
||||
if (relocs == NULL)
|
||||
{
|
||||
bfd_size_type relsize;
|
||||
relsize = sec->reloc_count * sizeof (*relocs);
|
||||
relocs = bfd_alloc (sec->owner, relsize);
|
||||
if (relocs == NULL)
|
||||
return NULL;
|
||||
elfsec_data->relocs = relocs;
|
||||
elfsec_data->rel_hdr.sh_size = (sec->reloc_count
|
||||
* sizeof (Elf64_External_Rela));
|
||||
elfsec_data->rel_hdr.sh_entsize = sizeof (Elf64_External_Rela);
|
||||
sec->reloc_count = 0;
|
||||
}
|
||||
relocs += sec->reloc_count;
|
||||
sec->reloc_count += count;
|
||||
return relocs;
|
||||
}
|
||||
|
||||
static bfd_boolean
|
||||
ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
||||
{
|
||||
@ -8292,10 +8360,10 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
||||
struct ppc_link_hash_table *htab;
|
||||
bfd_byte *loc;
|
||||
bfd_byte *p;
|
||||
unsigned int indx;
|
||||
struct plt_entry *ent;
|
||||
bfd_vma dest, off;
|
||||
int size;
|
||||
Elf_Internal_Rela *r;
|
||||
|
||||
/* Massage our args to the form they really have. */
|
||||
stub_entry = (struct ppc_stub_hash_entry *) gen_entry;
|
||||
@ -8354,26 +8422,9 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
||||
|
||||
if (info->emitrelocations)
|
||||
{
|
||||
Elf_Internal_Rela *relocs, *r;
|
||||
struct bfd_elf_section_data *elfsec_data;
|
||||
|
||||
elfsec_data = elf_section_data (stub_entry->stub_sec);
|
||||
relocs = elfsec_data->relocs;
|
||||
if (relocs == NULL)
|
||||
{
|
||||
bfd_size_type relsize;
|
||||
relsize = stub_entry->stub_sec->reloc_count * sizeof (*relocs);
|
||||
relocs = bfd_alloc (htab->stub_bfd, relsize);
|
||||
if (relocs == NULL)
|
||||
return FALSE;
|
||||
elfsec_data->relocs = relocs;
|
||||
elfsec_data->rel_hdr.sh_size = (stub_entry->stub_sec->reloc_count
|
||||
* sizeof (Elf64_External_Rela));
|
||||
elfsec_data->rel_hdr.sh_entsize = sizeof (Elf64_External_Rela);
|
||||
stub_entry->stub_sec->reloc_count = 0;
|
||||
}
|
||||
r = relocs + stub_entry->stub_sec->reloc_count;
|
||||
stub_entry->stub_sec->reloc_count += 1;
|
||||
r = get_relocs (stub_entry->stub_sec, 1);
|
||||
if (r == NULL)
|
||||
return FALSE;
|
||||
r->r_offset = loc - stub_entry->stub_sec->contents;
|
||||
r->r_info = ELF64_R_INFO (0, R_PPC64_REL24);
|
||||
r->r_addend = dest;
|
||||
@ -8428,11 +8479,11 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
off = (stub_entry->target_value
|
||||
+ stub_entry->target_section->output_offset
|
||||
+ stub_entry->target_section->output_section->vma);
|
||||
dest = (stub_entry->target_value
|
||||
+ stub_entry->target_section->output_offset
|
||||
+ stub_entry->target_section->output_section->vma);
|
||||
|
||||
bfd_put_64 (htab->brlt->owner, off,
|
||||
bfd_put_64 (htab->brlt->owner, dest,
|
||||
htab->brlt->contents + br_entry->offset);
|
||||
|
||||
if (br_entry->iter == htab->stub_iteration)
|
||||
@ -8449,7 +8500,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
||||
+ htab->brlt->output_offset
|
||||
+ htab->brlt->output_section->vma);
|
||||
rela.r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE);
|
||||
rela.r_addend = off;
|
||||
rela.r_addend = dest;
|
||||
|
||||
rl = htab->relbrlt->contents;
|
||||
rl += (htab->relbrlt->reloc_count++
|
||||
@ -8458,39 +8509,26 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
||||
}
|
||||
else if (info->emitrelocations)
|
||||
{
|
||||
Elf_Internal_Rela *relocs, *r;
|
||||
struct bfd_elf_section_data *elfsec_data;
|
||||
|
||||
elfsec_data = elf_section_data (htab->brlt);
|
||||
relocs = elfsec_data->relocs;
|
||||
if (relocs == NULL)
|
||||
{
|
||||
bfd_size_type relsize;
|
||||
relsize = htab->brlt->reloc_count * sizeof (*relocs);
|
||||
relocs = bfd_alloc (htab->brlt->owner, relsize);
|
||||
if (relocs == NULL)
|
||||
return FALSE;
|
||||
elfsec_data->relocs = relocs;
|
||||
elfsec_data->rel_hdr.sh_size
|
||||
= (stub_entry->stub_sec->reloc_count
|
||||
* sizeof (Elf64_External_Rela));
|
||||
elfsec_data->rel_hdr.sh_entsize
|
||||
= sizeof (Elf64_External_Rela);
|
||||
htab->brlt->reloc_count = 0;
|
||||
}
|
||||
r = relocs + htab->brlt->reloc_count;
|
||||
htab->brlt->reloc_count += 1;
|
||||
r = get_relocs (htab->brlt, 1);
|
||||
if (r == NULL)
|
||||
return FALSE;
|
||||
/* brlt, being SEC_LINKER_CREATED does not go through the
|
||||
normal reloc processing. Symbols and offsets are not
|
||||
translated from input file to output file form, so
|
||||
set up the offset per the output file. */
|
||||
r->r_offset = (br_entry->offset
|
||||
+ htab->brlt->output_offset
|
||||
+ htab->brlt->output_section->vma);
|
||||
r->r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE);
|
||||
r->r_addend = off;
|
||||
r->r_addend = dest;
|
||||
}
|
||||
}
|
||||
|
||||
off = (br_entry->offset
|
||||
+ htab->brlt->output_offset
|
||||
+ htab->brlt->output_section->vma
|
||||
dest = (br_entry->offset
|
||||
+ htab->brlt->output_offset
|
||||
+ htab->brlt->output_section->vma);
|
||||
|
||||
off = (dest
|
||||
- elf_gp (htab->brlt->output_section->owner)
|
||||
- htab->stub_group[stub_entry->id_sec->id].toc_off);
|
||||
|
||||
@ -8504,20 +8542,38 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
indx = off;
|
||||
if (info->emitrelocations)
|
||||
{
|
||||
r = get_relocs (stub_entry->stub_sec, 1 + (PPC_HA (off) != 0));
|
||||
if (r == NULL)
|
||||
return FALSE;
|
||||
r[0].r_offset = loc - stub_entry->stub_sec->contents;
|
||||
if (stub_entry->stub_type == ppc_stub_plt_branch_r2off)
|
||||
r[0].r_offset += 4;
|
||||
r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
|
||||
r[0].r_addend = dest;
|
||||
if (PPC_HA (off) != 0)
|
||||
{
|
||||
r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_HA);
|
||||
r[1].r_offset = r[0].r_offset + 4;
|
||||
r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
|
||||
r[1].r_addend = r[0].r_addend;
|
||||
}
|
||||
}
|
||||
|
||||
if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
|
||||
{
|
||||
if (PPC_HA (indx) != 0)
|
||||
if (PPC_HA (off) != 0)
|
||||
{
|
||||
size = 16;
|
||||
bfd_put_32 (htab->stub_bfd, ADDIS_R12_R2 | PPC_HA (indx), loc);
|
||||
bfd_put_32 (htab->stub_bfd, ADDIS_R12_R2 | PPC_HA (off), loc);
|
||||
loc += 4;
|
||||
bfd_put_32 (htab->stub_bfd, LD_R11_0R12 | PPC_LO (indx), loc);
|
||||
bfd_put_32 (htab->stub_bfd, LD_R11_0R12 | PPC_LO (off), loc);
|
||||
}
|
||||
else
|
||||
{
|
||||
size = 12;
|
||||
bfd_put_32 (htab->stub_bfd, LD_R11_0R2 | PPC_LO (indx), loc);
|
||||
bfd_put_32 (htab->stub_bfd, LD_R11_0R2 | PPC_LO (off), loc);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -8529,17 +8585,17 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
||||
bfd_put_32 (htab->stub_bfd, STD_R2_40R1, loc);
|
||||
loc += 4;
|
||||
size = 20;
|
||||
if (PPC_HA (indx) != 0)
|
||||
if (PPC_HA (off) != 0)
|
||||
{
|
||||
size += 4;
|
||||
bfd_put_32 (htab->stub_bfd, ADDIS_R12_R2 | PPC_HA (indx), loc);
|
||||
bfd_put_32 (htab->stub_bfd, ADDIS_R12_R2 | PPC_HA (off), loc);
|
||||
loc += 4;
|
||||
bfd_put_32 (htab->stub_bfd, LD_R11_0R12 | PPC_LO (indx), loc);
|
||||
bfd_put_32 (htab->stub_bfd, LD_R11_0R12 | PPC_LO (off), loc);
|
||||
loc += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
bfd_put_32 (htab->stub_bfd, LD_R11_0R2 | PPC_LO (indx), loc);
|
||||
bfd_put_32 (htab->stub_bfd, LD_R11_0R2 | PPC_LO (off), loc);
|
||||
loc += 4;
|
||||
}
|
||||
|
||||
@ -8576,21 +8632,23 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
||||
}
|
||||
|
||||
/* Now build the stub. */
|
||||
off = (bfd_vma) -1;
|
||||
dest = (bfd_vma) -1;
|
||||
for (ent = stub_entry->h->elf.plt.plist; ent != NULL; ent = ent->next)
|
||||
if (ent->addend == stub_entry->addend)
|
||||
{
|
||||
off = ent->plt.offset;
|
||||
dest = ent->plt.offset;
|
||||
break;
|
||||
}
|
||||
if (off >= (bfd_vma) -2)
|
||||
if (dest >= (bfd_vma) -2)
|
||||
abort ();
|
||||
|
||||
off &= ~ (bfd_vma) 1;
|
||||
off += (htab->plt->output_offset
|
||||
+ htab->plt->output_section->vma
|
||||
- elf_gp (htab->plt->output_section->owner)
|
||||
- htab->stub_group[stub_entry->id_sec->id].toc_off);
|
||||
dest &= ~ (bfd_vma) 1;
|
||||
dest += (htab->plt->output_offset
|
||||
+ htab->plt->output_section->vma);
|
||||
|
||||
off = (dest
|
||||
- elf_gp (htab->plt->output_section->owner)
|
||||
- htab->stub_group[stub_entry->id_sec->id].toc_off);
|
||||
|
||||
if (off + 0x80008000 > 0xffffffff || (off & 7) != 0)
|
||||
{
|
||||
@ -8602,7 +8660,18 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
p = build_plt_stub (htab->stub_bfd, loc, off);
|
||||
r = NULL;
|
||||
if (info->emitrelocations)
|
||||
{
|
||||
r = get_relocs (stub_entry->stub_sec,
|
||||
(2 + (PPC_HA (off) != 0)
|
||||
+ (PPC_HA (off + 16) == PPC_HA (off))));
|
||||
if (r == NULL)
|
||||
return FALSE;
|
||||
r[0].r_offset = loc - stub_entry->stub_sec->contents;
|
||||
r[0].r_addend = dest;
|
||||
}
|
||||
p = build_plt_stub (htab->stub_bfd, loc, off, r);
|
||||
size = p - loc;
|
||||
break;
|
||||
|
||||
@ -8692,6 +8761,12 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
||||
size -= 4;
|
||||
if (PPC_HA (off + 16) != PPC_HA (off))
|
||||
size += 4;
|
||||
if (info->emitrelocations)
|
||||
{
|
||||
stub_entry->stub_sec->reloc_count
|
||||
+= 2 + (PPC_HA (off) != 0) + (PPC_HA (off + 16) == PPC_HA (off));
|
||||
stub_entry->stub_sec->flags |= SEC_RELOC;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -8726,7 +8801,6 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
||||
if (off + (1 << 25) >= (bfd_vma) (1 << 26))
|
||||
{
|
||||
struct ppc_branch_hash_entry *br_entry;
|
||||
unsigned int indx;
|
||||
|
||||
br_entry = ppc_branch_hash_lookup (&htab->branch_hash_table,
|
||||
stub_entry->root.string + 9,
|
||||
@ -8761,17 +8835,22 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
||||
- elf_gp (htab->brlt->output_section->owner)
|
||||
- htab->stub_group[stub_entry->id_sec->id].toc_off);
|
||||
|
||||
indx = off;
|
||||
if (info->emitrelocations)
|
||||
{
|
||||
stub_entry->stub_sec->reloc_count += 1 + (PPC_HA (off) != 0);
|
||||
stub_entry->stub_sec->flags |= SEC_RELOC;
|
||||
}
|
||||
|
||||
if (stub_entry->stub_type != ppc_stub_plt_branch_r2off)
|
||||
{
|
||||
size = 12;
|
||||
if (PPC_HA (indx) != 0)
|
||||
if (PPC_HA (off) != 0)
|
||||
size = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = 20;
|
||||
if (PPC_HA (indx) != 0)
|
||||
if (PPC_HA (off) != 0)
|
||||
size += 4;
|
||||
|
||||
if (PPC_HA (r2off) != 0)
|
||||
@ -9584,6 +9663,13 @@ ppc64_elf_size_stubs (bfd *output_bfd,
|
||||
|
||||
bfd_hash_traverse (&htab->stub_hash_table, ppc_size_one_stub, info);
|
||||
|
||||
if (info->emitrelocations
|
||||
&& htab->glink != NULL && htab->glink->size != 0)
|
||||
{
|
||||
htab->glink->reloc_count = 1;
|
||||
htab->glink->flags |= SEC_RELOC;
|
||||
}
|
||||
|
||||
for (stub_sec = htab->stub_bfd->sections;
|
||||
stub_sec != NULL;
|
||||
stub_sec = stub_sec->next)
|
||||
@ -9720,12 +9806,19 @@ ppc64_elf_build_stubs (bfd_boolean emit_stub_syms,
|
||||
h->non_elf = 0;
|
||||
}
|
||||
}
|
||||
plt0 = htab->plt->output_section->vma + htab->plt->output_offset - 16;
|
||||
if (info->emitrelocations)
|
||||
{
|
||||
Elf_Internal_Rela *r = get_relocs (htab->glink, 1);
|
||||
if (r == NULL)
|
||||
return FALSE;
|
||||
r->r_offset = (htab->glink->output_offset
|
||||
+ htab->glink->output_section->vma);
|
||||
r->r_info = ELF64_R_INFO (0, R_PPC64_REL64);
|
||||
r->r_addend = plt0;
|
||||
}
|
||||
p = htab->glink->contents;
|
||||
plt0 = (htab->plt->output_section->vma
|
||||
+ htab->plt->output_offset
|
||||
- (htab->glink->output_section->vma
|
||||
+ htab->glink->output_offset
|
||||
+ 16));
|
||||
plt0 -= htab->glink->output_section->vma + htab->glink->output_offset;
|
||||
bfd_put_64 (htab->glink->owner, plt0, p);
|
||||
p += 8;
|
||||
bfd_put_32 (htab->glink->owner, MFLR_R12, p);
|
||||
@ -11583,6 +11676,15 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
|
||||
NULL))
|
||||
return FALSE;
|
||||
|
||||
if (htab->glink != NULL
|
||||
&& htab->glink->reloc_count != 0
|
||||
&& !_bfd_elf_link_output_relocs (output_bfd,
|
||||
htab->glink,
|
||||
&elf_section_data (htab->glink)->rel_hdr,
|
||||
elf_section_data (htab->glink)->relocs,
|
||||
NULL))
|
||||
return FALSE;
|
||||
|
||||
/* We need to handle writing out multiple GOT sections ourselves,
|
||||
since we didn't add them to DYNOBJ. We know dynobj is the first
|
||||
bfd. */
|
||||
|
@ -1,3 +1,7 @@
|
||||
2008-03-01 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* ld-powerpc/relbrlt.d: Update. Also check .branch_lt section.
|
||||
|
||||
2008-02-27 Catherine Moore <clm@codesourcery.com>
|
||||
|
||||
* ld-cris/libdso-10.d: Update expected output for the Dynamic
|
||||
|
@ -1,7 +1,7 @@
|
||||
#source: relbrlt.s
|
||||
#as: -a64
|
||||
#ld: -melf64ppc --emit-relocs
|
||||
#objdump: -dr
|
||||
#objdump: -Dr
|
||||
|
||||
.*: file format elf64-powerpc
|
||||
|
||||
@ -23,6 +23,7 @@ Disassembly of section \.text:
|
||||
|
||||
[0-9a-f ]*<.*plt_branch.*>:
|
||||
[0-9a-f ]*: e9 62 80 00 ld r11,-32768\(r2\)
|
||||
[0-9a-f ]*: R_PPC64_TOC16_DS \*ABS\*\+0x157f00d8
|
||||
[0-9a-f ]*: 7d 69 03 a6 mtctr r11
|
||||
[0-9a-f ]*: 4e 80 04 20 bctr
|
||||
|
||||
@ -32,6 +33,7 @@ Disassembly of section \.text:
|
||||
|
||||
[0-9a-f ]*<.*plt_branch.*>:
|
||||
[0-9a-f ]*: e9 62 80 08 ld r11,-32760\(r2\)
|
||||
[0-9a-f ]*: R_PPC64_TOC16_DS \*ABS\*\+0x157f00e0
|
||||
[0-9a-f ]*: 7d 69 03 a6 mtctr r11
|
||||
[0-9a-f ]*: 4e 80 04 20 bctr
|
||||
\.\.\.
|
||||
@ -40,9 +42,19 @@ Disassembly of section \.text:
|
||||
[0-9a-f ]*: 4e 80 00 20 blr
|
||||
\.\.\.
|
||||
|
||||
[0-9a-f ]*<far2far>:
|
||||
0*13bf00d0 <far2far>:
|
||||
[0-9a-f ]*: 4e 80 00 20 blr
|
||||
\.\.\.
|
||||
|
||||
[0-9a-f ]*<huge>:
|
||||
0*157e00d4 <huge>:
|
||||
[0-9a-f ]*: 4e 80 00 20 blr
|
||||
|
||||
Disassembly of section \.branch_lt:
|
||||
|
||||
0*157f00d8 <\.branch_lt>:
|
||||
[0-9a-f ]*: 00 00 00 00 .*
|
||||
[0-9a-f ]*: R_PPC64_RELATIVE \*ABS\*\+0x13bf00d0
|
||||
[0-9a-f ]*: 13 bf 00 d0 .*
|
||||
[0-9a-f ]*: 00 00 00 00 .*
|
||||
[0-9a-f ]*: R_PPC64_RELATIVE \*ABS\*\+0x157e00d4
|
||||
[0-9a-f ]*: 15 7e 00 d4 .*
|
||||
|
Loading…
Reference in New Issue
Block a user