{
struct bfd_link_info *info;
bfd_size_type ofs;
+ bfd_boolean only_got;
};
#define elfNN_ia64_hash_table(p) \
PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
const char *string));
static void elfNN_ia64_hash_copy_indirect
- PARAMS ((const struct elf_backend_data *, struct elf_link_hash_entry *,
+ PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *,
struct elf_link_hash_entry *));
static void elfNN_ia64_hash_hide_symbol
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean));
elf_code_to_howto_index[ia64_howto_table[i].type] = i;
}
- BFD_ASSERT (rtype <= R_IA64_MAX_RELOC_CODE);
+ if (rtype > R_IA64_MAX_RELOC_CODE)
+ return 0;
i = elf_code_to_howto_index[rtype];
if (i >= NELEMS (ia64_howto_table))
return 0;
if (template == 0x16)
{
- /* For BBB, we need to put nop.m in slot 0 and keep the original
- predicate. */
- t0 &= PREDICATE_BITS << 5;
+ /* For BBB, we need to put nop.m in slot 0. We keep the original
+ predicate only if slot 0 isn't br. */
+ if (br_slot == 0)
+ t0 = 0LL;
+ else
+ t0 &= PREDICATE_BITS << 5;
t0 |= 0x1LL << (X4_SHIFT + 5);
}
else
static void
elfNN_ia64_relax_brl (bfd_byte *contents, bfd_vma off)
{
- unsigned int template, t0, t1, t2, t3;
+ int template;
bfd_byte *hit_addr;
+ bfd_vma t0, t1, i0, i1, i2;
hit_addr = (bfd_byte *) (contents + off);
hit_addr -= (long) hit_addr & 0x3;
- t0 = bfd_getl32 (hit_addr + 0);
- t1 = bfd_getl32 (hit_addr + 4);
- t2 = bfd_getl32 (hit_addr + 8);
- t3 = bfd_getl32 (hit_addr + 12);
-
- /* Turn a MLX bundle into a MBB bundle with the same stop-bit
- variety. */
- template = 0x12;
- if ((t0 & 0x1f) == 5)
- template += 1;
+ t0 = bfd_getl64 (hit_addr);
+ t1 = bfd_getl64 (hit_addr + 8);
/* Keep the instruction in slot 0. */
- t0 &= 0xffffffe0;
- t1 &= 0x3fff;
-
- t0 |= template;
-
+ i0 = (t0 >> 5) & 0x1ffffffffffLL;
+ /* Use nop.b for slot 1. */
+ i1 = 0x4000000000LL;
/* For slot 2, turn brl into br by masking out bit 40. */
- t2 &= 0xff800000;
- t3 &= 0x7fffffff;
+ i2 = (t1 >> 23) & 0x0ffffffffffLL;
- /* Use nop.b for slot 1. */
- t2 |= 0x100000;
+ /* Turn a MLX bundle into a MBB bundle with the same stop-bit
+ variety. */
+ if (t0 & 0x1)
+ template = 0x13;
+ else
+ template = 0x12;
+ t0 = (i1 << 46) | (i0 << 5) | template;
+ t1 = (i2 << 23) | (i1 >> 18);
- bfd_putl32 (t0, hit_addr);
- bfd_putl32 (t1, hit_addr + 4);
- bfd_putl32 (t2, hit_addr + 8);
- bfd_putl32 (t3, hit_addr + 12);
+ bfd_putl64 (t0, hit_addr);
+ bfd_putl64 (t1, hit_addr + 8);
}
\f
/* These functions do relaxation for IA-64 ELF. */
elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
ia64_info->got_sec->size = data.ofs;
- /* ??? Resize .rela.got too. */
+ if (ia64_info->root.dynamic_sections_created
+ && ia64_info->rel_got_sec != NULL)
+ {
+ /* Resize .rela.got. */
+ ia64_info->rel_got_sec->size = 0;
+ if (link_info->shared
+ && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
+ ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
+ data.only_got = TRUE;
+ elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries,
+ &data);
+ }
}
if (!link_info->need_relax_finalize)
if (sec->flags & SEC_SMALL_DATA)
hdr->sh_flags |= SHF_IA_64_SHORT;
+ /* Some HP linkers look for the SHF_IA_64_HP_TLS flag instead of SHF_TLS. */
+
+ if (elfNN_ia64_hpux_vec (abfd->xvec) && (sec->flags & SHF_TLS))
+ hdr->sh_flags |= SHF_IA_64_HP_TLS;
+
return TRUE;
}
}
static void
-elfNN_ia64_hash_copy_indirect (bed, xdir, xind)
- const struct elf_backend_data *bed ATTRIBUTE_UNUSED;
+elfNN_ia64_hash_copy_indirect (info, xdir, xind)
+ struct bfd_link_info *info;
struct elf_link_hash_entry *xdir, *xind;
{
struct elfNN_ia64_link_hash_entry *dir, *ind;
/* Copy over the got and plt data. This would have been done
by check_relocs. */
- if (dir->info == NULL)
+ if (ind->info != NULL)
{
struct elfNN_ia64_dyn_sym_info *dyn_i;
+ struct elfNN_ia64_dyn_sym_info **pdyn;
- dir->info = dyn_i = ind->info;
+ pdyn = &dir->info;
+ while ((dyn_i = *pdyn) != NULL)
+ pdyn = &dyn_i->next;
+ *pdyn = dyn_i = ind->info;
ind->info = NULL;
/* Fix up the dyn_sym_info pointers to the global symbol. */
for (; dyn_i; dyn_i = dyn_i->next)
dyn_i->h = &dir->root;
}
- BFD_ASSERT (ind->info == NULL);
/* Copy over the dynindx. */
- if (dir->root.dynindx == -1)
+ if (ind->root.dynindx != -1)
{
+ if (dir->root.dynindx != -1)
+ _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+ dir->root.dynstr_index);
dir->root.dynindx = ind->root.dynindx;
dir->root.dynstr_index = ind->root.dynstr_index;
ind->root.dynindx = -1;
ind->root.dynstr_index = 0;
}
- BFD_ASSERT (ind->root.dynindx == -1);
}
static void
if (!x->info->executable
&& (!h
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
- || h->root.type != bfd_link_hash_undefweak))
+ || (h->root.type != bfd_link_hash_undefweak
+ && h->root.type != bfd_link_hash_undefined)))
{
if (h && h->dynindx == -1)
{
&& ELF_ST_VISIBILITY (dyn_i->h->other)
&& dyn_i->h->root.type == bfd_link_hash_undefweak);
+ /* Take care of the GOT and PLT relocations. */
+
+ if ((!resolved_zero
+ && (dynamic_symbol || shared)
+ && (dyn_i->want_got || dyn_i->want_gotx))
+ || (dyn_i->want_ltoff_fptr
+ && dyn_i->h
+ && dyn_i->h->dynindx != -1))
+ {
+ if (!dyn_i->want_ltoff_fptr
+ || !x->info->pie
+ || dyn_i->h == NULL
+ || dyn_i->h->root.type != bfd_link_hash_undefweak)
+ ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
+ }
+ if ((dynamic_symbol || shared) && dyn_i->want_tprel)
+ ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
+ if (dynamic_symbol && dyn_i->want_dtpmod)
+ ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
+ if (dynamic_symbol && dyn_i->want_dtprel)
+ ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
+
+ if (x->only_got)
+ return TRUE;
+
+ if (ia64_info->rel_fptr_sec && dyn_i->want_fptr)
+ {
+ if (dyn_i->h == NULL || dyn_i->h->root.type != bfd_link_hash_undefweak)
+ ia64_info->rel_fptr_sec->size += sizeof (ElfNN_External_Rela);
+ }
+
+ if (!resolved_zero && dyn_i->want_pltoff)
+ {
+ bfd_size_type t = 0;
+
+ /* Dynamic symbols get one IPLT relocation. Local symbols in
+ shared libraries get two REL relocations. Local symbols in
+ main applications get nothing. */
+ if (dynamic_symbol)
+ t = sizeof (ElfNN_External_Rela);
+ else if (shared)
+ t = 2 * sizeof (ElfNN_External_Rela);
+
+ ia64_info->rel_pltoff_sec->size += t;
+ }
+
/* Take care of the normal data relocations. */
for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
rent->srel->size += sizeof (ElfNN_External_Rela) * count;
}
- /* Take care of the GOT and PLT relocations. */
-
- if ((!resolved_zero
- && (dynamic_symbol || shared)
- && (dyn_i->want_got || dyn_i->want_gotx))
- || (dyn_i->want_ltoff_fptr
- && dyn_i->h
- && dyn_i->h->dynindx != -1))
- {
- if (!dyn_i->want_ltoff_fptr
- || !x->info->pie
- || dyn_i->h == NULL
- || dyn_i->h->root.type != bfd_link_hash_undefweak)
- ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
- }
- if ((dynamic_symbol || shared) && dyn_i->want_tprel)
- ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
- if (dynamic_symbol && dyn_i->want_dtpmod)
- ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
- if (dynamic_symbol && dyn_i->want_dtprel)
- ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
- if (ia64_info->rel_fptr_sec && dyn_i->want_fptr)
- {
- if (dyn_i->h == NULL || dyn_i->h->root.type != bfd_link_hash_undefweak)
- ia64_info->rel_fptr_sec->size += sizeof (ElfNN_External_Rela);
- }
-
- if (!resolved_zero && dyn_i->want_pltoff)
- {
- bfd_size_type t = 0;
-
- /* Dynamic symbols get one IPLT relocation. Local symbols in
- shared libraries get two REL relocations. Local symbols in
- main applications get nothing. */
- if (dynamic_symbol)
- t = sizeof (ElfNN_External_Rela);
- else if (shared)
- t = 2 * sizeof (ElfNN_External_Rela);
-
- ia64_info->rel_pltoff_sec->size += t;
- }
-
return TRUE;
}
if (info->shared && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
+ data.only_got = FALSE;
elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
}
/* Make sure we've got ourselves a nice fat __gp value. */
if (!info->relocatable)
{
- bfd_vma gp_val = _bfd_get_gp_value (abfd);
+ bfd_vma gp_val;
struct elf_link_hash_entry *gp;
- if (gp_val == 0)
- {
- if (! elfNN_ia64_choose_gp (abfd, info))
- return FALSE;
- gp_val = _bfd_get_gp_value (abfd);
- }
+ /* We assume after gp is set, section size will only decrease. We
+ need to adjust gp for it. */
+ _bfd_set_gp_value (abfd, 0);
+ if (! elfNN_ia64_choose_gp (abfd, info))
+ return FALSE;
+ gp_val = _bfd_get_gp_value (abfd);
gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
FALSE, FALSE);
}
}
-static struct bfd_elf_special_section const
- ia64_special_sections_s[]=
+static const struct bfd_elf_special_section elfNN_ia64_special_sections[] =
{
{ ".sbss", 5, -1, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
{ ".sdata", 6, -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
{ NULL, 0, 0, 0, 0 }
};
-static struct bfd_elf_special_section const *
- elfNN_ia64_special_sections[27] =
-{
- NULL, /* 'a' */
- NULL, /* 'b' */
- NULL, /* 'c' */
- NULL, /* 'd' */
- NULL, /* 'e' */
- NULL, /* 'f' */
- NULL, /* 'g' */
- NULL, /* 'h' */
- NULL, /* 'i' */
- NULL, /* 'j' */
- NULL, /* 'k' */
- NULL, /* 'l' */
- NULL, /* 'm' */
- NULL, /* 'n' */
- NULL, /* 'o' */
- NULL, /* 'p' */
- NULL, /* 'q' */
- NULL, /* 'r' */
- ia64_special_sections_s, /* 's' */
- NULL, /* 't' */
- NULL, /* 'u' */
- NULL, /* 'v' */
- NULL, /* 'w' */
- NULL, /* 'x' */
- NULL, /* 'y' */
- NULL, /* 'z' */
- NULL /* other */
-};
-
static bfd_boolean
elfNN_ia64_object_p (bfd *abfd)
{
elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
asymbol *asym)
{
- elf_symbol_type *elfsym = (elf_symbol_type *) asym;;
+ elf_symbol_type *elfsym = (elf_symbol_type *) asym;
switch (elfsym->internal_elf_sym.st_shndx)
{
#define elf_backend_special_sections elfNN_ia64_special_sections
/* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
- SHF_LINK_ORDER. But it doesn't set theh sh_link or sh_info fields.
+ SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
We don't want to flood users with so many error messages. We turn
off the warning for now. It will be turned on later when the Intel
compiler is fixed. */