/* 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)
\f
static reloc_howto_type *ppc_elf_howto_table[R_PPC_max];
else if (out_attr->i == 1 && in_attr->i == 2)
_bfd_error_handler
(_("Warning: %B uses hard float, %B uses soft float"), obfd, ibfd);
- else if (out_attr->i == 2 && in_attr->i == 1)
+ else if (out_attr->i == 1 && in_attr->i == 3)
+ _bfd_error_handler
+ (_("Warning: %B uses double-precision hard float, %B uses single-precision hard float"),
+ obfd, ibfd);
+ else if (out_attr->i == 3 && in_attr->i == 1)
+ _bfd_error_handler
+ (_("Warning: %B uses double-precision hard float, %B uses single-precision hard float"),
+ ibfd, obfd);
+ else if (out_attr->i == 3 && in_attr->i == 2)
+ _bfd_error_handler
+ (_("Warning: %B uses soft float, %B uses single-precision hard float"),
+ ibfd, obfd);
+ else if (out_attr->i == 2 && (in_attr->i == 1 || in_attr->i == 3))
_bfd_error_handler
(_("Warning: %B uses hard float, %B uses soft float"), ibfd, obfd);
- else if (in_attr->i > 2)
+ else if (in_attr->i > 3)
_bfd_error_handler
(_("Warning: %B uses unknown floating point ABI %d"), ibfd,
in_attr->i);
{
/* Make sure this symbol is output as a dynamic symbol. */
if (eh->elf.dynindx == -1
- && !eh->elf.forced_local)
+ && !eh->elf.forced_local
+ && htab->elf.dynamic_sections_created)
{
if (!bfd_elf_link_record_dynamic_symbol (info, &eh->elf))
return FALSE;
else
eh->elf.got.offset = (bfd_vma) -1;
- if (eh->dyn_relocs == NULL)
+ if (eh->dyn_relocs == NULL
+ || !htab->elf.dynamic_sections_created)
return TRUE;
/* In the shared -Bsymbolic case, discard space allocated for
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
stub_rtype);
irel->r_offset = trampoff + insn_offset;
+ if (r_type == R_PPC_PLTREL24)
+ irel->r_addend = 0;
/* Record the fixup so we don't do it again this section. */
f = bfd_malloc (sizeof (*f));
isec->size = (isec->size + 3) & (bfd_vma) -4;
/* Branch around the trampolines. */
- val = trampoff - isec->size + 0x48000000;
+ val = B + trampoff - isec->size;
dest = contents + isec->size;
isec->size = trampoff;
bfd_put_32 (abfd, val, dest);
}
}
- 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
relocation = (htab->plt->output_section->vma
+ htab->plt->output_offset
+ ent->plt.offset);
- addend = 0;
}
if (r_type == R_PPC_RELAX32_PLT)
goto relax32;
an embedded ELF object, for which the .got section acts like the
AIX .toc section. */
case R_PPC_TOC16: /* phony GOT16 relocations */
- BFD_ASSERT (sec != NULL);
- BFD_ASSERT (bfd_is_und_section (sec)
- || strcmp (bfd_get_section_name (abfd, sec), ".got") == 0
+ if (sec == NULL || sec->output_section == NULL)
+ {
+ unresolved_reloc = TRUE;
+ break;
+ }
+ BFD_ASSERT (strcmp (bfd_get_section_name (abfd, sec), ".got") == 0
|| strcmp (bfd_get_section_name (abfd, sec), ".cgot") == 0);
- addend -= sec->output_section->vma + sec->output_offset + 0x8000;
+ addend -= sec->output_section->vma + sec->output_offset + 0x8000;
break;
case R_PPC_PLTREL24:
case R_PPC_SDAREL16:
{
const char *name;
- struct elf_link_hash_entry *sh;
- BFD_ASSERT (sec != NULL);
+ if (sec == NULL || sec->output_section == NULL)
+ {
+ unresolved_reloc = TRUE;
+ break;
+ }
+
name = bfd_get_section_name (abfd, sec->output_section);
if (! ((CONST_STRNEQ (name, ".sdata")
&& (name[6] == 0 || name[6] == '.'))
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;
case R_PPC_EMB_SDA2REL:
{
const char *name;
- struct elf_link_hash_entry *sh;
- BFD_ASSERT (sec != NULL);
+ if (sec == NULL || sec->output_section == NULL)
+ {
+ unresolved_reloc = TRUE;
+ break;
+ }
+
name = bfd_get_section_name (abfd, sec->output_section);
if (! (CONST_STRNEQ (name, ".sdata2")
|| CONST_STRNEQ (name, ".sbss2")))
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;
{
const char *name;
int reg;
- struct elf_link_hash_entry *sh;
- BFD_ASSERT (sec != NULL);
+ if (sec == NULL || sec->output_section == NULL)
+ {
+ unresolved_reloc = TRUE;
+ break;
+ }
+
name = bfd_get_section_name (abfd, sec->output_section);
if (((CONST_STRNEQ (name, ".sdata")
&& (name[6] == 0 || name[6] == '.'))
&& (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)
{
reg = 0;
}
-
else
{
(*_bfd_error_handler)
case R_PPC_SECTOFF_LO:
case R_PPC_SECTOFF_HI:
case R_PPC_SECTOFF_HA:
- BFD_ASSERT (sec != NULL);
+ if (sec == NULL || sec->output_section == NULL)
+ {
+ unresolved_reloc = TRUE;
+ break;
+ }
addend -= sec->output_section->vma;
break;
/* 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);
}
+ 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;
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);
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");
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)
{
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;
}
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
}
}
- return TRUE;
+ return ret;
}
\f
#define TARGET_LITTLE_SYM bfd_elf32_powerpcle_vec