/* IA-64 support for 64-bit ELF
- Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of BFD, the Binary File Descriptor library.
PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
boolean *again));
static boolean is_unwind_section_name
- PARAMS ((const char *));
+ PARAMS ((bfd *abfd, const char *));
static boolean elfNN_ia64_section_from_shdr
PARAMS ((bfd *, ElfNN_Internal_Shdr *, char *));
static boolean elfNN_ia64_section_flags
static void elfNN_ia64_hash_copy_indirect
PARAMS ((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 *));
+ PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, boolean));
static struct bfd_link_hash_table *elfNN_ia64_hash_table_create
PARAMS ((bfd *abfd));
static struct elfNN_ia64_local_hash_entry *elfNN_ia64_local_hash_lookup
PARAMS ((bfd *abfd, PTR ptr));
static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
PARAMS ((const Elf_Internal_Rela *));
+static boolean elfNN_ia64_hpux_vec
+ PARAMS ((const bfd_target *vec));
static void elfNN_hpux_post_process_headers
PARAMS ((bfd *abfd, struct bfd_link_info *info));
+boolean elfNN_hpux_backend_section_from_bfd_section
+ PARAMS ((bfd *abfd, asection *sec, int *retval));
\f
/* ia64-specific relocation */
tsec = bfd_abs_section_ptr;
else if (isym.st_shndx == SHN_COMMON)
tsec = bfd_com_section_ptr;
+ else if (isym.st_shndx == SHN_IA_64_ANSI_COMMON)
+ tsec = bfd_com_section_ptr;
else
tsec = bfd_section_from_elf_index (abfd, isym.st_shndx);
/* Return true if NAME is an unwind table section name. */
static inline boolean
-is_unwind_section_name (name)
+is_unwind_section_name (abfd, name)
+ bfd *abfd;
const char *name;
{
size_t len1, len2, len3;
+ if (elfNN_ia64_hpux_vec (abfd->xvec)
+ && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
+ return false;
+
len1 = sizeof (ELF_STRING_ia64_unwind) - 1;
len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
len3 = sizeof (ELF_STRING_ia64_unwind_once) - 1;
switch (hdr->sh_type)
{
case SHT_IA_64_UNWIND:
+ case SHT_IA_64_HP_OPT_ANOT:
break;
case SHT_IA_64_EXT:
name = bfd_get_section_name (abfd, sec);
- if (is_unwind_section_name (name))
+ if (is_unwind_section_name (abfd, name))
{
/* We don't have the sections numbered at this point, so sh_info
is set later, in elfNN_ia64_final_write_processing. */
}
else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
hdr->sh_type = SHT_IA_64_EXT;
+ else if (strcmp (name, ".HP.opt_annot") == 0)
+ hdr->sh_type = SHT_IA_64_HP_OPT_ANOT;
else if (strcmp (name, ".reloc") == 0)
/*
* This is an ugly, but unfortunately necessary hack that is
/* Count how many PT_IA_64_UNWIND segments we need. */
for (s = abfd->sections; s; s = s->next)
- if (is_unwind_section_name(s->name) && (s->flags & SEC_LOAD))
+ if (is_unwind_section_name (abfd, s->name) && (s->flags & SEC_LOAD))
++ret;
return ret;
struct elf_segment_map *m, **pm;
Elf_Internal_Shdr *hdr;
asection *s;
+ boolean unwind_found;
+ asection *unwind_sec;
/* If we need a PT_IA_64_ARCHEXT segment, it must come before
all PT_LOAD segments. */
if (s && (s->flags & SEC_LOAD))
{
for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
- if (m->p_type == PT_IA_64_UNWIND && m->sections[0] == s)
- break;
+ if (m->p_type == PT_IA_64_UNWIND)
+ {
+ /* Look through all sections in the unwind segment
+ for a match since there may be multiple sections
+ to a segment. */
+
+ unwind_sec = m->sections[0];
+ unwind_found = false;
+ while (unwind_sec != NULL && !unwind_found)
+ {
+ if (unwind_sec == s)
+ unwind_found = true;
+ else
+ unwind_sec = unwind_sec -> next;
+ }
+ if (unwind_found)
+ break;
+ }
if (m == NULL)
{
}
static void
-elfNN_ia64_hash_hide_symbol (info, xh)
- struct bfd_link_info *info ATTRIBUTE_UNUSED;
+elfNN_ia64_hash_hide_symbol (info, xh, force_local)
+ struct bfd_link_info *info;
struct elf_link_hash_entry *xh;
+ boolean force_local;
{
struct elfNN_ia64_link_hash_entry *h;
struct elfNN_ia64_dyn_sym_info *dyn_i;
h = (struct elfNN_ia64_link_hash_entry *)xh;
- h->root.elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
- if ((h->root.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
- h->root.dynindx = -1;
+ _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
for (dyn_i = h->info; dyn_i; dyn_i = dyn_i->next)
dyn_i->want_plt2 = 0;
= (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
struct elfNN_ia64_dyn_sym_info *dyn_i;
+ if (entry->root.root.type == bfd_link_hash_warning)
+ entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
+
for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
if (! (*data->func) (dyn_i, data->data))
return false;
outrel.r_info = ELFNN_R_INFO (dynindx, type);
outrel.r_addend = addend;
outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
- if (outrel.r_offset == (bfd_vma) -1)
+ if ((outrel.r_offset | 1) == (bfd_vma) -1)
{
/* Run for the hills. We shouldn't be outputting a relocation
for this. So do what everyone else does and output a no-op. */
}
}
+static boolean
+elfNN_ia64_hpux_vec (const bfd_target *vec)
+{
+ extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
+ return (vec == & bfd_elfNN_ia64_hpux_big_vec);
+}
+
static void
elfNN_hpux_post_process_headers (abfd, info)
bfd *abfd;
i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_HPUX;
i_ehdrp->e_ident[EI_ABIVERSION] = 1;
}
+
+boolean
+elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asection *sec;
+ int *retval;
+{
+ if (bfd_is_com_section (sec))
+ {
+ *retval = SHN_IA_64_ANSI_COMMON;
+ return true;
+ }
+ return false;
+}
\f
#define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
#define TARGET_LITTLE_NAME "elfNN-ia64-little"
#undef TARGET_BIG_NAME
#define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
+/* We need to undo the AIX specific functions. */
+
+#undef elf_backend_add_symbol_hook
+#define elf_backend_add_symbol_hook elfNN_ia64_add_symbol_hook
+
+#undef bfd_elfNN_bfd_link_add_symbols
+#define bfd_elfNN_bfd_link_add_symbols _bfd_generic_link_add_symbols
+
+/* These are HP-UX specific functions. */
+
#undef elf_backend_post_process_headers
#define elf_backend_post_process_headers elfNN_hpux_post_process_headers
+#undef elf_backend_section_from_bfd_section
+#define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
+
#undef ELF_MAXPAGESIZE
#define ELF_MAXPAGESIZE 0x1000 /* 1K */