#define ECOFF_64
#include "ecoffswap.h"
-static int alpha_elf_dynamic_symbol_p
+static bfd_boolean alpha_elf_dynamic_symbol_p
PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *));
static struct bfd_hash_entry * elf64_alpha_link_hash_newfunc
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
#define alpha_elf_sym_hashes(abfd) \
((struct alpha_elf_link_hash_entry **)elf_sym_hashes(abfd))
-/* Should we do dynamic things to this symbol? */
+/* Should we do dynamic things to this symbol? This differs from the
+ generic version in that we never need to consider function pointer
+ equality wrt PLT entries -- we don't create a PLT entry if a symbol's
+ address is ever taken. */
-static int
+static inline bfd_boolean
alpha_elf_dynamic_symbol_p (h, info)
struct elf_link_hash_entry *h;
struct bfd_link_info *info;
{
- if (h == NULL)
- return FALSE;
-
- while (h->root.type == bfd_link_hash_indirect
- || h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
- if (h->dynindx == -1)
- return FALSE;
-
- if (h->root.type == bfd_link_hash_undefweak
- || h->root.type == bfd_link_hash_defweak)
- return TRUE;
-
- switch (ELF_ST_VISIBILITY (h->other))
- {
- case STV_DEFAULT:
- break;
- case STV_HIDDEN:
- case STV_INTERNAL:
- return FALSE;
- case STV_PROTECTED:
- if (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
- return FALSE;
- break;
- }
-
- if ((info->shared && !info->symbolic)
- || ((h->elf_link_hash_flags
- & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR))
- == (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)))
- return TRUE;
-
- return FALSE;
+ return _bfd_elf_dynamic_symbol_p (h, info, 0);
}
/* Create an entry in a Alpha ELF linker hash table. */
}
else
{
- tsec_relocs = (_bfd_elf64_link_read_relocs
+ tsec_relocs = (_bfd_elf_link_read_relocs
(info->abfd, info->tsec, (PTR) NULL,
(Elf_Internal_Rela *) NULL,
info->link_info->keep_memory));
/* We are not currently changing any sizes, so only one pass. */
*again = FALSE;
- if (link_info->relocateable
+ if (link_info->relocatable
|| (sec->flags & SEC_RELOC) == 0
|| sec->reloc_count == 0)
return TRUE;
local_got_entries = alpha_elf_tdata(abfd)->local_got_entries;
/* Load the relocations for this section. */
- internal_relocs = (_bfd_elf64_link_read_relocs
+ internal_relocs = (_bfd_elf_link_read_relocs
(abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
link_info->keep_memory));
if (internal_relocs == NULL)
bfd_vma *valp;
{
if (sym->st_shndx == SHN_COMMON
- && !info->relocateable
+ && !info->relocatable
&& sym->st_size <= elf_gp_size (abfd))
{
/* Common symbols less than or equal to -G nn bytes are
bfd_boolean got_created;
bfd_size_type amt;
- if (info->relocateable)
+ if (info->relocatable)
return TRUE;
dynobj = elf_hash_table(info)->dynobj;
{
bfd *i;
- if (info->relocateable)
+ if (info->relocatable)
return TRUE;
/* First, take care of the indirect symbols created by versioning. */
if (elf_hash_table (info)->dynamic_sections_created)
{
/* Set the contents of the .interp section to the interpreter. */
- if (!info->shared)
+ if (info->executable)
{
s = bfd_get_section_by_name (dynobj, ".interp");
BFD_ASSERT (s != NULL);
#define add_dynamic_entry(TAG, VAL) \
bfd_elf64_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
- if (!info->shared)
+ if (info->executable)
{
if (!add_dynamic_entry (DT_DEBUG, 0))
return FALSE;
const char *section_name;
/* Handle relocatable links with a smaller loop. */
- if (info->relocateable)
+ if (info->relocatable)
return elf64_alpha_relocate_section_r (output_bfd, info, input_bfd,
input_section, contents, relocs,
local_syms, local_sections);
}
else if (h->root.root.type == bfd_link_hash_undefweak)
undef_weak_ref = TRUE;
- else if (info->shared
+ else if (!info->executable
&& !info->no_undefined
&& ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
;
(!info->shared || info->no_undefined
|| ELF_ST_VISIBILITY (h->root.other)))))
return FALSE;
- ret_val = FALSE;
continue;
}
value -= gp;
goto default_reloc;
- case R_ALPHA_GPREL16:
case R_ALPHA_GPREL32:
+ /* If the target section was a removed linkonce section,
+ r_symndx will be zero. In this case, assume that the
+ switch will not be used, so don't fill it in. If we
+ do nothing here, we'll get relocation truncated messages,
+ due to the placement of the application above 4GB. */
+ if (r_symndx == 0)
+ {
+ r = bfd_reloc_ok;
+ break;
+ }
+ /* FALLTHRU */
+
+ case R_ALPHA_GPREL16:
case R_ALPHA_GPRELLOW:
if (dynamic_symbol_p)
{
sizeof (Elf_External_Note),
8,
1,
- 64, 8,
+ 64, 3,
ELFCLASS64, EV_CURRENT,
bfd_elf64_write_out_phdrs,
bfd_elf64_write_shdrs_and_ehdr,