mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-24 10:35:12 +08:00
PR 6844
* elf32-ppc.c (SYM_VAL): Define. Use throughout to find symbol vma. (ppc_elf_relocate_section): Correct GOT offset calculation. (ppc_elf_finish_dynamic_symbol): Use PPC_HA and PPC_LO. (ppc_elf_finish_dynamic_sections): Likewise. Error if htab->elf.hgot symbol is not defined in htab->got section.
This commit is contained in:
parent
9fa33bee6a
commit
e87d403811
@ -1,3 +1,12 @@
|
||||
2008-09-16 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
PR 6844
|
||||
* elf32-ppc.c (SYM_VAL): Define. Use throughout to find symbol vma.
|
||||
(ppc_elf_relocate_section): Correct GOT offset calculation.
|
||||
(ppc_elf_finish_dynamic_symbol): Use PPC_HA and PPC_LO.
|
||||
(ppc_elf_finish_dynamic_sections): Likewise. Error if
|
||||
htab->elf.hgot symbol is not defined in htab->got section.
|
||||
|
||||
2008-09-16 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
PR 6888
|
||||
|
110
bfd/elf32-ppc.c
110
bfd/elf32-ppc.c
@ -157,6 +157,12 @@ static const bfd_vma ppc_elf_vxworks_pic_plt0_entry
|
||||
/* Offset of tp and dtp pointers from start of TLS block. */
|
||||
#define TP_OFFSET 0x7000
|
||||
#define DTP_OFFSET 0x8000
|
||||
|
||||
/* The value of a defined global symbol. */
|
||||
#define SYM_VAL(SYM) \
|
||||
((SYM)->root.u.def.section->output_section->vma \
|
||||
+ (SYM)->root.u.def.section->output_offset \
|
||||
+ (SYM)->root.u.def.value)
|
||||
|
||||
static reloc_howto_type *ppc_elf_howto_table[R_PPC_max];
|
||||
|
||||
@ -6656,8 +6662,10 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
}
|
||||
}
|
||||
|
||||
relocation = htab->got->output_offset + off;
|
||||
relocation -= htab->elf.hgot->root.u.def.value;
|
||||
relocation = (htab->got->output_section->vma
|
||||
+ htab->got->output_offset
|
||||
+ off
|
||||
- SYM_VAL (htab->elf.hgot));
|
||||
|
||||
/* Addends on got relocations don't make much sense.
|
||||
x+off@got is actually x@got+off, and since the got is
|
||||
@ -7014,7 +7022,6 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC_SDAREL16:
|
||||
{
|
||||
const char *name;
|
||||
struct elf_link_hash_entry *sh;
|
||||
|
||||
if (sec == NULL || sec->output_section == NULL)
|
||||
{
|
||||
@ -7036,10 +7043,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
howto->name,
|
||||
name);
|
||||
}
|
||||
sh = htab->sdata[0].sym;
|
||||
addend -= (sh->root.u.def.value
|
||||
+ sh->root.u.def.section->output_offset
|
||||
+ sh->root.u.def.section->output_section->vma);
|
||||
addend -= SYM_VAL (htab->sdata[0].sym);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -7047,7 +7051,6 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
case R_PPC_EMB_SDA2REL:
|
||||
{
|
||||
const char *name;
|
||||
struct elf_link_hash_entry *sh;
|
||||
|
||||
if (sec == NULL || sec->output_section == NULL)
|
||||
{
|
||||
@ -7071,10 +7074,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
ret = FALSE;
|
||||
continue;
|
||||
}
|
||||
sh = htab->sdata[1].sym;
|
||||
addend -= (sh->root.u.def.value
|
||||
+ sh->root.u.def.section->output_offset
|
||||
+ sh->root.u.def.section->output_section->vma);
|
||||
addend -= SYM_VAL (htab->sdata[1].sym);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -7084,7 +7084,6 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
{
|
||||
const char *name;
|
||||
int reg;
|
||||
struct elf_link_hash_entry *sh;
|
||||
|
||||
if (sec == NULL || sec->output_section == NULL)
|
||||
{
|
||||
@ -7099,19 +7098,13 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
&& (name[5] == 0 || name[5] == '.'))))
|
||||
{
|
||||
reg = 13;
|
||||
sh = htab->sdata[0].sym;
|
||||
addend -= (sh->root.u.def.value
|
||||
+ sh->root.u.def.section->output_offset
|
||||
+ sh->root.u.def.section->output_section->vma);
|
||||
addend -= SYM_VAL (htab->sdata[0].sym);
|
||||
}
|
||||
else if (CONST_STRNEQ (name, ".sdata2")
|
||||
|| CONST_STRNEQ (name, ".sbss2"))
|
||||
{
|
||||
reg = 2;
|
||||
sh = htab->sdata[1].sym;
|
||||
addend -= (sh->root.u.def.value
|
||||
+ sh->root.u.def.section->output_offset
|
||||
+ sh->root.u.def.section->output_section->vma);
|
||||
addend -= SYM_VAL (htab->sdata[1].sym);
|
||||
}
|
||||
else if (strcmp (name, ".PPC.EMB.sdata0") == 0
|
||||
|| strcmp (name, ".PPC.EMB.sbss0") == 0)
|
||||
@ -7366,31 +7359,22 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
|
||||
/* Fill in the .plt on VxWorks. */
|
||||
if (info->shared)
|
||||
{
|
||||
bfd_vma got_offset_hi = (got_offset >> 16)
|
||||
+ ((got_offset & 0x8000) >> 15);
|
||||
|
||||
bfd_put_32 (output_bfd,
|
||||
plt_entry[0] | (got_offset_hi & 0xffff),
|
||||
plt_entry[0] | PPC_HA (got_offset),
|
||||
htab->plt->contents + ent->plt.offset + 0);
|
||||
bfd_put_32 (output_bfd,
|
||||
plt_entry[1] | (got_offset & 0xffff),
|
||||
plt_entry[1] | PPC_LO (got_offset),
|
||||
htab->plt->contents + ent->plt.offset + 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
bfd_vma got_loc
|
||||
= (got_offset
|
||||
+ htab->elf.hgot->root.u.def.value
|
||||
+ htab->elf.hgot->root.u.def.section->output_offset
|
||||
+ htab->elf.hgot->root.u.def.section->output_section->vma);
|
||||
bfd_vma got_loc_hi = (got_loc >> 16)
|
||||
+ ((got_loc & 0x8000) >> 15);
|
||||
bfd_vma got_loc = got_offset + SYM_VAL (htab->elf.hgot);
|
||||
|
||||
bfd_put_32 (output_bfd,
|
||||
plt_entry[0] | (got_loc_hi & 0xffff),
|
||||
plt_entry[0] | PPC_HA (got_loc),
|
||||
htab->plt->contents + ent->plt.offset + 0);
|
||||
bfd_put_32 (output_bfd,
|
||||
plt_entry[1] | (got_loc & 0xffff),
|
||||
plt_entry[1] | PPC_LO (got_loc),
|
||||
htab->plt->contents + ent->plt.offset + 4);
|
||||
}
|
||||
|
||||
@ -7550,9 +7534,7 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
|
||||
+ ent->sec->output_section->vma
|
||||
+ ent->sec->output_offset);
|
||||
else if (htab->elf.hgot != NULL)
|
||||
got = (htab->elf.hgot->root.u.def.value
|
||||
+ htab->elf.hgot->root.u.def.section->output_section->vma
|
||||
+ htab->elf.hgot->root.u.def.section->output_offset);
|
||||
got = SYM_VAL (htab->elf.hgot);
|
||||
|
||||
plt -= got;
|
||||
|
||||
@ -7618,9 +7600,7 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
|
||||
s = htab->relbss;
|
||||
BFD_ASSERT (s != NULL);
|
||||
|
||||
rela.r_offset = (h->root.u.def.value
|
||||
+ h->root.u.def.section->output_section->vma
|
||||
+ h->root.u.def.section->output_offset);
|
||||
rela.r_offset = SYM_VAL (h);
|
||||
rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_COPY);
|
||||
rela.r_addend = 0;
|
||||
loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
|
||||
@ -7670,7 +7650,8 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
|
||||
asection *splt;
|
||||
struct ppc_elf_link_hash_table *htab;
|
||||
bfd_vma got;
|
||||
bfd * dynobj;
|
||||
bfd *dynobj;
|
||||
bfd_boolean ret = TRUE;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "ppc_elf_finish_dynamic_sections called\n");
|
||||
@ -7686,9 +7667,7 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
|
||||
|
||||
got = 0;
|
||||
if (htab->elf.hgot != NULL)
|
||||
got = (htab->elf.hgot->root.u.def.value
|
||||
+ htab->elf.hgot->root.u.def.section->output_section->vma
|
||||
+ htab->elf.hgot->root.u.def.section->output_offset);
|
||||
got = SYM_VAL (htab->elf.hgot);
|
||||
|
||||
if (htab->elf.dynamic_sections_created)
|
||||
{
|
||||
@ -7752,17 +7731,28 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
|
||||
easily find the address of the _GLOBAL_OFFSET_TABLE_. */
|
||||
if (htab->got != NULL)
|
||||
{
|
||||
unsigned char *p = htab->got->contents;
|
||||
bfd_vma val;
|
||||
if (htab->elf.hgot->root.u.def.section == htab->got)
|
||||
{
|
||||
unsigned char *p = htab->got->contents;
|
||||
bfd_vma val;
|
||||
|
||||
p += htab->elf.hgot->root.u.def.value;
|
||||
if (htab->plt_type == PLT_OLD)
|
||||
bfd_put_32 (output_bfd, 0x4e800021 /* blrl */, p - 4);
|
||||
p += htab->elf.hgot->root.u.def.value;
|
||||
if (htab->plt_type == PLT_OLD)
|
||||
bfd_put_32 (output_bfd, 0x4e800021 /* blrl */, p - 4);
|
||||
|
||||
val = 0;
|
||||
if (sdyn != NULL)
|
||||
val = sdyn->output_section->vma + sdyn->output_offset;
|
||||
bfd_put_32 (output_bfd, val, p);
|
||||
val = 0;
|
||||
if (sdyn != NULL)
|
||||
val = sdyn->output_section->vma + sdyn->output_offset;
|
||||
bfd_put_32 (output_bfd, val, p);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*_bfd_error_handler) (_("%s not defined in linker created %s"),
|
||||
htab->elf.hgot->root.root.string,
|
||||
htab->got->name);
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
elf_section_data (htab->got->output_section)->this_hdr.sh_entsize = 4;
|
||||
}
|
||||
@ -7777,15 +7767,11 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
|
||||
|
||||
if (!info->shared)
|
||||
{
|
||||
bfd_vma got_value =
|
||||
(htab->elf.hgot->root.u.def.section->output_section->vma
|
||||
+ htab->elf.hgot->root.u.def.section->output_offset
|
||||
+ htab->elf.hgot->root.u.def.value);
|
||||
bfd_vma got_hi = (got_value >> 16) + ((got_value & 0x8000) >> 15);
|
||||
bfd_vma got_value = SYM_VAL (htab->elf.hgot);
|
||||
|
||||
bfd_put_32 (output_bfd, plt_entry[0] | (got_hi & 0xffff),
|
||||
bfd_put_32 (output_bfd, plt_entry[0] | PPC_HA (got_value),
|
||||
splt->contents + 0);
|
||||
bfd_put_32 (output_bfd, plt_entry[1] | (got_value & 0xffff),
|
||||
bfd_put_32 (output_bfd, plt_entry[1] | PPC_LO (got_value),
|
||||
splt->contents + 4);
|
||||
}
|
||||
else
|
||||
@ -8050,7 +8036,7 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define TARGET_LITTLE_SYM bfd_elf32_powerpcle_vec
|
||||
|
Loading…
Reference in New Issue
Block a user