{
asection *msec;
- if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
+ if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections,
+ section, symbols, offset,
filename_ptr, functionname_ptr,
line_ptr, 0,
&elf_tdata (abfd)->dwarf2_find_line_info))
bfd_boolean strip;
asection *sec, *output_section;
- if (h->root.root.type == bfd_link_hash_warning)
- h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
-
if (h->root.indx == -2)
strip = FALSE;
else if ((h->root.def_dynamic
break;
case R_ALPHA_TPREL64:
- if (info->shared || maybe_dynamic)
+ if (info->shared && !info->pie)
+ {
+ info->flags |= DF_STATIC_TLS;
+ need = NEED_DYNREL;
+ }
+ else if (maybe_dynamic)
need = NEED_DYNREL;
- if (info->shared)
- info->flags |= DF_STATIC_TLS;
break;
}
indirect to the new ones. Consolidate the got and reloc information
in these situations. */
-static bfd_boolean
-elf64_alpha_merge_ind_symbols (struct alpha_elf_link_hash_entry *hi,
- PTR dummy ATTRIBUTE_UNUSED)
+static void
+elf64_alpha_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
{
- struct alpha_elf_link_hash_entry *hs;
+ struct alpha_elf_link_hash_entry *hi
+ = (struct alpha_elf_link_hash_entry *) ind;
+ struct alpha_elf_link_hash_entry *hs
+ = (struct alpha_elf_link_hash_entry *) dir;
- if (hi->root.root.type != bfd_link_hash_indirect)
- return TRUE;
- hs = hi;
- do {
- hs = (struct alpha_elf_link_hash_entry *)hs->root.root.u.i.link;
- } while (hs->root.root.type == bfd_link_hash_indirect);
+ /* Do the merging in the superclass. */
+ _bfd_elf_link_hash_copy_indirect(info, dir, ind);
/* Merge the flags. Whee. */
-
hs->flags |= hi->flags;
+ /* ??? It's unclear to me what's really supposed to happen when
+ "merging" defweak and defined symbols, given that we don't
+ actually throw away the defweak. This more-or-less copies
+ the logic related to got and plt entries in the superclass. */
+ if (ind->root.type != bfd_link_hash_indirect)
+ return;
+
/* Merge the .got entries. Cannibalize the old symbol's list in
doing so, since we don't need it anymore. */
}
}
hi->reloc_entries = NULL;
-
- return TRUE;
}
/* Is it possible to merge two object file's .got tables? */
{
struct alpha_elf_got_entry *gotent;
- if (h->root.root.type == bfd_link_hash_warning)
- h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
-
for (gotent = h->got_entries; gotent; gotent = gotent->next)
if (gotent->use_count > 0)
{
if (htab == NULL)
return FALSE;
- /* First, take care of the indirect symbols created by versioning. */
- alpha_elf_link_hash_traverse (htab, elf64_alpha_merge_ind_symbols,
- NULL);
-
if (!elf64_alpha_size_got_sections (info))
return FALSE;
/* The number of dynamic relocations required by a static relocation. */
static int
-alpha_dynamic_entries_for_reloc (int r_type, int dynamic, int shared)
+alpha_dynamic_entries_for_reloc (int r_type, int dynamic, int shared, int pie)
{
switch (r_type)
{
case R_ALPHA_TLSLDM:
return shared;
case R_ALPHA_LITERAL:
- case R_ALPHA_GOTTPREL:
return dynamic || shared;
+ case R_ALPHA_GOTTPREL:
+ return dynamic || (shared && !pie);
case R_ALPHA_GOTDTPREL:
return dynamic;
/* May appear in data sections. */
case R_ALPHA_REFLONG:
case R_ALPHA_REFQUAD:
- case R_ALPHA_TPREL64:
return dynamic || shared;
+ case R_ALPHA_TPREL64:
+ return dynamic || (shared && !pie);
/* Everything else is illegal. We'll issue an error during
relocate_section. */
struct alpha_elf_reloc_entry *relent;
unsigned long entries;
- if (h->root.root.type == bfd_link_hash_warning)
- h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
-
/* If the symbol was defined as a common symbol in a regular object
file, and there was no definition in any dynamic object, then the
linker will have allocated space for the symbol in a common
for (relent = h->reloc_entries; relent; relent = relent->next)
{
entries = alpha_dynamic_entries_for_reloc (relent->rtype, dynamic,
- info->shared);
+ info->shared, info->pie);
if (entries)
{
relent->srel->size +=
struct alpha_elf_got_entry *gotent;
unsigned long entries;
- if (h->root.root.type == bfd_link_hash_warning)
- h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
-
/* If we're using a plt for this symbol, then all of its relocations
for its got entries go into .rela.plt. */
if (h->root.needs_plt)
entries = 0;
for (gotent = h->got_entries; gotent ; gotent = gotent->next)
if (gotent->use_count > 0)
- entries += alpha_dynamic_entries_for_reloc (gotent->reloc_type,
- dynamic, info->shared);
+ entries += alpha_dynamic_entries_for_reloc (gotent->reloc_type, dynamic,
+ info->shared, info->pie);
if (entries > 0)
{
gotent ; gotent = gotent->next)
if (gotent->use_count > 0)
entries += (alpha_dynamic_entries_for_reloc
- (gotent->reloc_type, 0, info->shared));
+ (gotent->reloc_type, 0, info->shared, info->pie));
}
}
linker does that before adjust_dynamic_symbol is called, and
it is that function which decides whether anything needs to
go into these sections. */
- s->flags |= SEC_EXCLUDE;
+ if (!CONST_STRNEQ (name, ".got"))
+ s->flags |= SEC_EXCLUDE;
}
else if ((s->flags & SEC_HAS_CONTENTS) != 0)
{
return TRUE;
/* Can't use local-exec relocations in shared libraries. */
- if (r_type == R_ALPHA_GOTTPREL && info->link_info->shared)
+ if (r_type == R_ALPHA_GOTTPREL
+ && (info->link_info->shared && !info->link_info->pie))
return TRUE;
if (r_type == R_ALPHA_LITERAL)
pos[3] = info->contents + gpdisp->r_offset;
pos[4] = pos[3] + gpdisp->r_addend;
+ /* Beware of the compiler hoisting part of the sequence out a loop
+ and adjusting the destination register for the TLSGD insn. If this
+ happens, there will be a move into $16 before the JSR insn, so only
+ transformations of the first insn pair should use this register. */
+ tlsgd_reg = bfd_get_32 (info->abfd, pos[0]);
+ tlsgd_reg = (tlsgd_reg >> 21) & 31;
+
/* Generally, the positions are not allowed to be out of order, lest the
modified insn sequence have different register lifetimes. We can make
an exception when pos 1 is adjacent to pos 0. */
use_gottprel = FALSE;
new_symndx = is_gd ? ELF64_R_SYM (irel->r_info) : STN_UNDEF;
- /* Beware of the compiler hoisting part of the sequence out a loop
- and adjusting the destination register for the TLSGD insn. If this
- happens, there will be a move into $16 before the JSR insn, so only
- transformations of the first insn pair should use this register. */
- tlsgd_reg = bfd_get_32 (info->abfd, pos[0]);
- tlsgd_reg = (tlsgd_reg >> 21) & 31;
-
switch (!dynamic && !info->link_info->shared)
{
case 1:
bfd_vma value;
bfd_vma addend;
bfd_boolean dynamic_symbol_p;
+ bfd_boolean unresolved_reloc = FALSE;
bfd_boolean undef_weak_ref = FALSE;
unsigned long r_type;
else
{
bfd_boolean warned;
- bfd_boolean unresolved_reloc;
struct elf_link_hash_entry *hh;
struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
else if (r_type == R_ALPHA_TPREL64)
{
BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
- if (!info->shared)
+ if (!info->shared || info->pie)
{
value -= tp_base;
goto default_reloc;
else if (info->shared
&& r_symndx != STN_UNDEF
&& (input_section->flags & SEC_ALLOC)
- && !undef_weak_ref)
+ && !undef_weak_ref
+ && !(unresolved_reloc
+ && (_bfd_elf_section_offset (output_bfd, info,
+ input_section,
+ rel->r_offset)
+ == (bfd_vma) -1)))
{
if (r_type == R_ALPHA_REFLONG)
{
/* ??? .eh_frame references to discarded sections will be smashed
to relocations against SHN_UNDEF. The .eh_frame format allows
NULL to be encoded as 0 in any format, so this works here. */
- if (r_symndx == STN_UNDEF)
+ if (r_symndx == STN_UNDEF
+ || (unresolved_reloc
+ && _bfd_elf_section_offset (output_bfd, info,
+ input_section,
+ rel->r_offset) == (bfd_vma) -1))
howto = (elf64_alpha_howto_table
+ (r_type - R_ALPHA_SREL32 + R_ALPHA_REFLONG));
goto default_reloc;
case R_ALPHA_TPRELHI:
case R_ALPHA_TPRELLO:
case R_ALPHA_TPREL16:
- if (info->shared)
+ if (info->shared && !info->pie)
{
(*_bfd_error_handler)
(_("%B: TLS local exec code cannot be linked into shared objects"),
elf64_alpha_adjust_dynamic_symbol
#define elf_backend_merge_symbol_attribute \
elf64_alpha_merge_symbol_attribute
+#define elf_backend_copy_indirect_symbol \
+ elf64_alpha_copy_indirect_symbol
#define elf_backend_always_size_sections \
elf64_alpha_always_size_sections
#define elf_backend_size_dynamic_sections \