asection *sgotplt;
/* Short-cuts to frequently used symbols on VxWorks targets. */
- struct elf_link_hash_entry *hgot, *hplt;
+ struct elf_link_hash_entry *hplt;
/* True if the target system is VxWorks. */
int is_vxworks;
case R_PPC_ADDR14_BRNTAKEN:
case R_PPC_UADDR32:
case R_PPC_UADDR16:
+ if (info->shared)
+ break;
+
case R_PPC_PLT32:
case R_PPC_PLTREL24:
+ case R_PPC_PLTREL32:
case R_PPC_PLT16_LO:
case R_PPC_PLT16_HI:
case R_PPC_PLT16_HA:
if (htab->is_vxworks)
{
- /* Save the GOT and PLT symbols in the hash table for easy access.
- Mark them as having relocations; they might not, but we won't
- know for sure until we build the GOT in finish_dynamic_symbol. */
+ /* Save the PLT symbol in the hash table for easy access.
+ Mark GOT and PLT syms as having relocations; they might not,
+ but we won't know for sure until we build the GOT in
+ finish_dynamic_symbol. */
- htab->hgot = elf_link_hash_lookup (elf_hash_table (info),
- "_GLOBAL_OFFSET_TABLE_",
- FALSE, FALSE, FALSE);
- if (htab->hgot)
- htab->hgot->indx = -2;
+ if (htab->elf.hgot)
+ htab->elf.hgot->indx = -2;
htab->hplt = elf_link_hash_lookup (elf_hash_table (info),
"_PROCEDURE_LINKAGE_TABLE_",
FALSE, FALSE, FALSE);
{
unsigned int g_o_t = 32768;
- /* If we haven't allocated the header, do so now. */
+ /* If we haven't allocated the header, do so now. When we get here,
+ for old plt/got the got size will be 0 to 32764 (not allocated),
+ or 32780 to 65536 (header allocated). For new plt/got, the
+ corresponding ranges are 0 to 32768 and 32780 to 65536. */
if (htab->got->size <= 32768)
{
g_o_t = htab->got->size;
+ if (htab->old_plt)
+ g_o_t += 4;
htab->got->size += htab->got_header_size;
}
- if (htab->old_plt && !htab->is_vxworks)
- g_o_t += 4;
htab->elf.hgot->root.u.def.value = g_o_t;
}
_bfd_elf_provide_symbol (info, lsect->sym_name, val, s);
}
}
+
+/* What to do when ld finds relocations against symbols defined in
+ discarded sections. */
+
+static unsigned int
+ppc_elf_action_discarded (asection *sec)
+{
+ if (strcmp (".fixup", sec->name) == 0)
+ return 0;
+
+ if (strcmp (".got2", sec->name) == 0)
+ return 0;
+
+ return _bfd_elf_default_action_discarded (sec);
+}
\f
/* Fill in the address for a pointer generated in a linker section. */
}
else
{
- bfd_vma got_loc = (got_offset
- + htab->hgot->root.u.def.value
- + htab->hgot->root.u.def.section->output_offset
- + htab->hgot->root.u.def.section->output_section->vma);
+ 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);
rela.r_offset = (htab->plt->output_section->vma
+ htab->plt->output_offset
+ ent->plt.offset + 2);
- rela.r_info = ELF32_R_INFO (htab->hgot->indx,
+ rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
R_PPC_ADDR16_HA);
rela.r_addend = got_offset;
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
rela.r_offset = (htab->plt->output_section->vma
+ htab->plt->output_offset
+ ent->plt.offset + 6);
- rela.r_info = ELF32_R_INFO (htab->hgot->indx,
+ rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
R_PPC_ADDR16_LO);
rela.r_addend = got_offset;
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
unsigned char *p = htab->got->contents;
bfd_vma val;
- p += elf_hash_table (info)->hgot->root.u.def.value;
+ p += htab->elf.hgot->root.u.def.value;
if (htab->old_plt && !htab->is_vxworks)
bfd_put_32 (output_bfd, 0x4e800021 /* blrl */, p - 4);
if (!info->shared)
{
bfd_vma got_value =
- (htab->hgot->root.u.def.section->output_section->vma
- + htab->hgot->root.u.def.section->output_offset
- + htab->hgot->root.u.def.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_put_32 (output_bfd, plt_entry[0] | (got_hi & 0xffff),
rela.r_offset = (htab->plt->output_section->vma
+ htab->plt->output_offset
+ 2);
- rela.r_info = ELF32_R_INFO (htab->hgot->indx, R_PPC_ADDR16_HA);
+ rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_PPC_ADDR16_HA);
rela.r_addend = 0;
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
loc += sizeof (Elf32_External_Rela);
rela.r_offset = (htab->plt->output_section->vma
+ htab->plt->output_offset
+ 6);
- rela.r_info = ELF32_R_INFO (htab->hgot->indx, R_PPC_ADDR16_LO);
+ rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_PPC_ADDR16_LO);
rela.r_addend = 0;
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
loc += sizeof (Elf32_External_Rela);
Elf_Internal_Rela rel;
bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
- rel.r_info = ELF32_R_INFO (htab->hgot->indx, R_PPC_ADDR16_HA);
+ rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_PPC_ADDR16_HA);
bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
loc += sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
- rel.r_info = ELF32_R_INFO (htab->hgot->indx, R_PPC_ADDR16_LO);
+ rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_PPC_ADDR16_LO);
bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
loc += sizeof (Elf32_External_Rela);
#define elf_backend_write_section ppc_elf_write_section
#define elf_backend_get_sec_type_attr ppc_elf_get_sec_type_attr
#define elf_backend_plt_sym_val ppc_elf_plt_sym_val
+#define elf_backend_action_discarded ppc_elf_action_discarded
#include "elf32-target.h"