{
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));
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);
{ NULL, 0, 0, 0, 0 }
};
-static const struct bfd_elf_special_section *
-elfNN_ia64_get_sec_type_attr (bfd *abfd, asection *sec)
-{
- const struct bfd_elf_special_section *ssect;
-
- /* See if this is one of the special sections. */
- if (sec->name == NULL)
- return NULL;
-
- ssect = _bfd_elf_get_special_section (sec->name,
- elfNN_ia64_special_sections,
- sec->use_rela_p);
- if (ssect != NULL)
- return ssect;
-
- return _bfd_elf_get_sec_type_attr (abfd, sec);
-}
-
static bfd_boolean
elfNN_ia64_object_p (bfd *abfd)
{
#define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
#define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
#define elf_backend_rela_normal 1
-#define elf_backend_get_sec_type_attr elfNN_ia64_get_sec_type_attr
+#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. */