projects
/
deliverable
/
binutils-gdb.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Remove the ns32k target from the obsolete list.
[deliverable/binutils-gdb.git]
/
bfd
/
elf64-alpha.c
diff --git
a/bfd/elf64-alpha.c
b/bfd/elf64-alpha.c
index deb03c183c0c6294c85263f528010c0e07f18449..43c6ed8d3d0b8290bc13ba8099ecf238c0b5c511 100644
(file)
--- a/
bfd/elf64-alpha.c
+++ b/
bfd/elf64-alpha.c
@@
-1,7
+1,5
@@
/* Alpha specific support for 64-bit ELF
/* Alpha specific support for 64-bit ELF
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2006, 2007, 2008, 2009, 2010, 2011, 2012
- Free Software Foundation, Inc.
+ Copyright (C) 1996-2017 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@tamu.edu>.
This file is part of BFD, the Binary File Descriptor library.
Contributed by Richard Henderson <rth@tamu.edu>.
This file is part of BFD, the Binary File Descriptor library.
@@
-225,7
+223,7
@@
struct alpha_elf_link_hash_table
#define alpha_elf_sym_hashes(abfd) \
((struct alpha_elf_link_hash_entry **)elf_sym_hashes(abfd))
#define alpha_elf_sym_hashes(abfd) \
((struct alpha_elf_link_hash_entry **)elf_sym_hashes(abfd))
-/* Should we do dynamic things to this symbol? This differs from the
+/* 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. */
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. */
@@
-299,6
+297,15
@@
elf64_alpha_bfd_link_hash_table_create (bfd *abfd)
return &ret->root.root;
}
\f
return &ret->root.root;
}
\f
+/* Alpha ELF follows MIPS ELF in using a special find_nearest_line
+ routine in order to handle the ECOFF debugging information. */
+
+struct alpha_elf_find_line
+{
+ struct ecoff_debug_info d;
+ struct ecoff_find_line i;
+};
+
/* We have some private fields hanging off of the elf_tdata structure. */
struct alpha_elf_obj_tdata
/* We have some private fields hanging off of the elf_tdata structure. */
struct alpha_elf_obj_tdata
@@
-328,6
+335,10
@@
struct alpha_elf_obj_tdata
/* For every got, this is the sum of the number of words required
to hold all of the member object's local got. */
int local_got_size;
/* For every got, this is the sum of the number of words required
to hold all of the member object's local got. */
int local_got_size;
+
+ /* Used by elf64_alpha_find_nearest_line entry point. */
+ struct alpha_elf_find_line *find_line_info;
+
};
#define alpha_elf_tdata(abfd) \
};
#define alpha_elf_tdata(abfd) \
@@
-475,8
+486,8
@@
static reloc_howto_type elf64_alpha_howto_table[] =
{
HOWTO (R_ALPHA_NONE, /* type */
0, /* rightshift */
{
HOWTO (R_ALPHA_NONE, /* type */
0, /* rightshift */
-
0
, /* size (0 = byte, 1 = short, 2 = long) */
-
8
, /* bitsize */
+
3
, /* size (0 = byte, 1 = short, 2 = long) */
+
0
, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
TRUE, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
@@
-1094,7
+1105,15
@@
elf64_alpha_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
Elf_Internal_Rela *dst)
{
unsigned r_type = ELF64_R_TYPE(dst->r_info);
Elf_Internal_Rela *dst)
{
unsigned r_type = ELF64_R_TYPE(dst->r_info);
- BFD_ASSERT (r_type < (unsigned int) R_ALPHA_max);
+
+ if (r_type >= R_ALPHA_max)
+ {
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%B: unrecognised Alpha reloc number: %d"),
+ abfd, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ r_type = R_ALPHA_NONE;
+ }
cache_ptr->howto = &elf64_alpha_howto_table[r_type];
}
cache_ptr->howto = &elf64_alpha_howto_table[r_type];
}
@@
-1209,7
+1228,7
@@
elf64_alpha_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
asection **secp, bfd_vma *valp)
{
if (sym->st_shndx == SHN_COMMON
asection **secp, bfd_vma *valp)
{
if (sym->st_shndx == SHN_COMMON
- && !
info->relocatable
+ && !
bfd_link_relocatable (info)
&& sym->st_size <= elf_gp_size (abfd))
{
/* Common symbols less than or equal to -G nn bytes are
&& sym->st_size <= elf_gp_size (abfd))
{
/* Common symbols less than or equal to -G nn bytes are
@@
-1281,6
+1300,7
@@
elf64_alpha_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
| SEC_LINKER_CREATED
| (elf64_alpha_use_secureplt ? SEC_READONLY : 0));
s = bfd_make_section_anyway_with_flags (abfd, ".plt", flags);
| SEC_LINKER_CREATED
| (elf64_alpha_use_secureplt ? SEC_READONLY : 0));
s = bfd_make_section_anyway_with_flags (abfd, ".plt", flags);
+ elf_hash_table (info)->splt = s;
if (s == NULL || ! bfd_set_section_alignment (abfd, s, 4))
return FALSE;
if (s == NULL || ! bfd_set_section_alignment (abfd, s, 4))
return FALSE;
@@
-1295,6
+1315,7
@@
elf64_alpha_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED | SEC_READONLY);
s = bfd_make_section_anyway_with_flags (abfd, ".rela.plt", flags);
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED | SEC_READONLY);
s = bfd_make_section_anyway_with_flags (abfd, ".rela.plt", flags);
+ elf_hash_table (info)->srelplt = s;
if (s == NULL || ! bfd_set_section_alignment (abfd, s, 3))
return FALSE;
if (s == NULL || ! bfd_set_section_alignment (abfd, s, 3))
return FALSE;
@@
-1302,6
+1323,7
@@
elf64_alpha_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
{
flags = SEC_ALLOC | SEC_LINKER_CREATED;
s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
{
flags = SEC_ALLOC | SEC_LINKER_CREATED;
s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
+ elf_hash_table (info)->sgotplt = s;
if (s == NULL || ! bfd_set_section_alignment (abfd, s, 3))
return FALSE;
}
if (s == NULL || ! bfd_set_section_alignment (abfd, s, 3))
return FALSE;
}
@@
-1318,6
+1340,7
@@
elf64_alpha_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED | SEC_READONLY);
s = bfd_make_section_anyway_with_flags (abfd, ".rela.got", flags);
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED | SEC_READONLY);
s = bfd_make_section_anyway_with_flags (abfd, ".rela.got", flags);
+ elf_hash_table (info)->srelgot = s;
if (s == NULL
|| !bfd_set_section_alignment (abfd, s, 3))
return FALSE;
if (s == NULL
|| !bfd_set_section_alignment (abfd, s, 3))
return FALSE;
@@
-1430,29
+1453,20
@@
elf64_alpha_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name)
return name[0] == '$';
}
return name[0] == '$';
}
-/* Alpha ELF follows MIPS ELF in using a special find_nearest_line
- routine in order to handle the ECOFF debugging information. We
- still call this mips_elf_find_line because of the slot
- find_line_info in elf_obj_tdata is declared that way. */
-
-struct mips_elf_find_line
-{
- struct ecoff_debug_info d;
- struct ecoff_find_line i;
-};
-
static bfd_boolean
static bfd_boolean
-elf64_alpha_find_nearest_line (bfd *abfd, asection *section, asymbol **symbols,
- bfd_vma offset, const char **filename_ptr,
+elf64_alpha_find_nearest_line (bfd *abfd, asymbol **symbols,
+ asection *section, bfd_vma offset,
+ const char **filename_ptr,
const char **functionname_ptr,
const char **functionname_ptr,
- unsigned int *line_ptr)
+ unsigned int *line_ptr,
+ unsigned int *discriminator_ptr)
{
asection *msec;
{
asection *msec;
- if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections,
- section, symbols, offset,
+ if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
filename_ptr, functionname_ptr,
filename_ptr, functionname_ptr,
- line_ptr, NULL, 0,
+ line_ptr, discriminator_ptr,
+ dwarf_debug_sections, 0,
&elf_tdata (abfd)->dwarf2_find_line_info))
return TRUE;
&elf_tdata (abfd)->dwarf2_find_line_info))
return TRUE;
@@
-1460,7
+1474,7
@@
elf64_alpha_find_nearest_line (bfd *abfd, asection *section, asymbol **symbols,
if (msec != NULL)
{
flagword origflags;
if (msec != NULL)
{
flagword origflags;
- struct
mips
_elf_find_line *fi;
+ struct
alpha
_elf_find_line *fi;
const struct ecoff_debug_swap * const swap =
get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
const struct ecoff_debug_swap * const swap =
get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
@@
-1471,16
+1485,16
@@
elf64_alpha_find_nearest_line (bfd *abfd, asection *section, asymbol **symbols,
if (elf_section_data (msec)->this_hdr.sh_type != SHT_NOBITS)
msec->flags |= SEC_HAS_CONTENTS;
if (elf_section_data (msec)->this_hdr.sh_type != SHT_NOBITS)
msec->flags |= SEC_HAS_CONTENTS;
- fi = elf_tdata (abfd)->find_line_info;
+ fi =
alpha_
elf_tdata (abfd)->find_line_info;
if (fi == NULL)
{
bfd_size_type external_fdr_size;
char *fraw_src;
char *fraw_end;
struct fdr *fdr_ptr;
if (fi == NULL)
{
bfd_size_type external_fdr_size;
char *fraw_src;
char *fraw_end;
struct fdr *fdr_ptr;
- bfd_size_type amt = sizeof (struct
mips
_elf_find_line);
+ bfd_size_type amt = sizeof (struct
alpha
_elf_find_line);
- fi = (struct
mips
_elf_find_line *) bfd_zalloc (abfd, amt);
+ fi = (struct
alpha
_elf_find_line *) bfd_zalloc (abfd, amt);
if (fi == NULL)
{
msec->flags = origflags;
if (fi == NULL)
{
msec->flags = origflags;
@@
-1509,7
+1523,7
@@
elf64_alpha_find_nearest_line (bfd *abfd, asection *section, asymbol **symbols,
for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++)
(*swap->swap_fdr_in) (abfd, fraw_src, fdr_ptr);
for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++)
(*swap->swap_fdr_in) (abfd, fraw_src, fdr_ptr);
- elf_tdata (abfd)->find_line_info = fi;
+
alpha_
elf_tdata (abfd)->find_line_info = fi;
/* Note that we don't bother to ever free this information.
find_nearest_line is either called all the time, as in
/* Note that we don't bother to ever free this information.
find_nearest_line is either called all the time, as in
@@
-1532,9
+1546,9
@@
elf64_alpha_find_nearest_line (bfd *abfd, asection *section, asymbol **symbols,
/* Fall back on the generic ELF find_nearest_line routine. */
/* Fall back on the generic ELF find_nearest_line routine. */
- return _bfd_elf_find_nearest_line (abfd, s
ection, symbols
, offset,
+ return _bfd_elf_find_nearest_line (abfd, s
ymbols, section
, offset,
filename_ptr, functionname_ptr,
filename_ptr, functionname_ptr,
- line_ptr);
+ line_ptr
, discriminator_ptr
);
}
\f
/* Structure used to pass information to alpha_elf_output_extsym. */
}
\f
/* Structure used to pass information to alpha_elf_output_extsym. */
@@
-1748,6
+1762,18
@@
elf64_alpha_want_plt (struct alpha_elf_link_hash_entry *ah)
&& (ah->flags & ~ALPHA_ELF_LINK_HASH_LU_PLT) == 0);
}
&& (ah->flags & ~ALPHA_ELF_LINK_HASH_LU_PLT) == 0);
}
+/* Whether to sort relocs output by ld -r or ld --emit-relocs, by r_offset.
+ Don't do so for code sections. We want to keep ordering of LITERAL/LITUSE
+ as is. On the other hand, elf-eh-frame.c processing requires .eh_frame
+ relocs to be sorted. */
+
+static bfd_boolean
+elf64_alpha_sort_relocs_p (asection *sec)
+{
+ return (sec->flags & SEC_CODE) == 0;
+}
+
+
/* Handle dynamic relocations when doing an Alpha ELF link. */
static bfd_boolean
/* Handle dynamic relocations when doing an Alpha ELF link. */
static bfd_boolean
@@
-1761,7
+1787,7
@@
elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info,
const Elf_Internal_Rela *rel, *relend;
bfd_size_type amt;
const Elf_Internal_Rela *rel, *relend;
bfd_size_type amt;
- if (
info->relocatable
)
+ if (
bfd_link_relocatable (info)
)
return TRUE;
/* Don't do anything special with non-loaded, non-alloced sections.
return TRUE;
/* Don't do anything special with non-loaded, non-alloced sections.
@@
-1810,6
+1836,9
@@
elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info,
|| h->root.root.type == bfd_link_hash_warning)
h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
|| h->root.root.type == bfd_link_hash_warning)
h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
+ /* PR15323, ref flags aren't set for references in the same
+ object. */
+ h->root.root.non_ir_ref = 1;
h->root.ref_regular = 1;
}
h->root.ref_regular = 1;
}
@@
-1818,7
+1847,7
@@
elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info,
have yet been processed. Do something with what we know, as
this may help reduce memory usage and processing time later. */
maybe_dynamic = FALSE;
have yet been processed. Do something with what we know, as
this may help reduce memory usage and processing time later. */
maybe_dynamic = FALSE;
- if (h && ((
info->shared
+ if (h && ((
bfd_link_pic (info)
&& (!info->symbolic
|| info->unresolved_syms_in_shared_libs == RM_IGNORE))
|| !h->root.def_regular
&& (!info->symbolic
|| info->unresolved_syms_in_shared_libs == RM_IGNORE))
|| !h->root.def_regular
@@
-1859,7
+1888,7
@@
elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_ALPHA_REFLONG:
case R_ALPHA_REFQUAD:
case R_ALPHA_REFLONG:
case R_ALPHA_REFQUAD:
- if (
info->shared
|| maybe_dynamic)
+ if (
bfd_link_pic (info)
|| maybe_dynamic)
need = NEED_DYNREL;
break;
need = NEED_DYNREL;
break;
@@
-1879,12
+1908,12
@@
elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_ALPHA_GOTTPREL:
need = NEED_GOT | NEED_GOT_ENTRY;
gotent_flags = ALPHA_ELF_LINK_HASH_TLS_IE;
case R_ALPHA_GOTTPREL:
need = NEED_GOT | NEED_GOT_ENTRY;
gotent_flags = ALPHA_ELF_LINK_HASH_TLS_IE;
- if (
info->shared
)
+ if (
bfd_link_pic (info)
)
info->flags |= DF_STATIC_TLS;
break;
case R_ALPHA_TPREL64:
info->flags |= DF_STATIC_TLS;
break;
case R_ALPHA_TPREL64:
- if (
info->shared && !info->pie
)
+ if (
bfd_link_dll (info)
)
{
info->flags |= DF_STATIC_TLS;
need = NEED_DYNREL;
{
info->flags |= DF_STATIC_TLS;
need = NEED_DYNREL;
@@
-1976,7
+2005,7
@@
elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info,
else
rent->count++;
}
else
rent->count++;
}
- else if (
info->shared
)
+ else if (
bfd_link_pic (info)
)
{
/* If this is a shared library, and the section is to be
loaded into memory, we need a RELATIVE reloc. */
{
/* If this is a shared library, and the section is to be
loaded into memory, we need a RELATIVE reloc. */
@@
-2021,7
+2050,7
@@
elf64_alpha_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
struct alpha_elf_link_hash_entry **sym_hashes;
const Elf_Internal_Rela *rel, *relend;
struct alpha_elf_link_hash_entry **sym_hashes;
const Elf_Internal_Rela *rel, *relend;
- if (
info->relocatable
)
+ if (
bfd_link_relocatable (info)
)
return TRUE;
symtab_hdr = &elf_symtab_hdr (abfd);
return TRUE;
symtab_hdr = &elf_symtab_hdr (abfd);
@@
-2103,7
+2132,7
@@
elf64_alpha_adjust_dynamic_symbol (struct bfd_link_info *info,
{
h->needs_plt = TRUE;
{
h->needs_plt = TRUE;
- s =
bfd_get_linker_section (dynobj, ".plt")
;
+ s =
elf_hash_table(info)->splt
;
if (!s && !elf64_alpha_create_dynamic_sections (dynobj, info))
return FALSE;
if (!s && !elf64_alpha_create_dynamic_sections (dynobj, info))
return FALSE;
@@
-2194,7
+2223,7
@@
elf64_alpha_copy_indirect_symbol (struct bfd_link_info *info,
&& gi->reloc_type == gs->reloc_type
&& gi->addend == gs->addend)
{
&& gi->reloc_type == gs->reloc_type
&& gi->addend == gs->addend)
{
- g
i->use_count += gs
->use_count;
+ g
s->use_count += gi
->use_count;
goto got_found;
}
gi->next = hs->got_entries;
goto got_found;
}
gi->next = hs->got_entries;
@@
-2463,7
+2492,8
@@
elf64_alpha_calc_got_offsets (struct bfd_link_info *info)
/* Constructs the gots. */
static bfd_boolean
/* Constructs the gots. */
static bfd_boolean
-elf64_alpha_size_got_sections (struct bfd_link_info *info)
+elf64_alpha_size_got_sections (struct bfd_link_info *info,
+ bfd_boolean may_merge)
{
bfd *i, *got_list, *cur_got_obj = NULL;
struct alpha_elf_link_hash_table * htab;
{
bfd *i, *got_list, *cur_got_obj = NULL;
struct alpha_elf_link_hash_table * htab;
@@
-2477,7
+2507,7
@@
elf64_alpha_size_got_sections (struct bfd_link_info *info)
consisting of all of the input files. */
if (got_list == NULL)
{
consisting of all of the input files. */
if (got_list == NULL)
{
- for (i = info->input_bfds; i ; i = i->link
_
next)
+ for (i = info->input_bfds; i ; i = i->link
.
next)
{
bfd *this_got;
{
bfd *this_got;
@@
-2494,7
+2524,8
@@
elf64_alpha_size_got_sections (struct bfd_link_info *info)
if (alpha_elf_tdata (this_got)->total_got_size > MAX_GOT_SIZE)
{
/* Yikes! A single object file has too many entries. */
if (alpha_elf_tdata (this_got)->total_got_size > MAX_GOT_SIZE)
{
/* Yikes! A single object file has too many entries. */
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: .got subsegment exceeds 64K (size %d)"),
i, alpha_elf_tdata (this_got)->total_got_size);
return FALSE;
(_("%B: .got subsegment exceeds 64K (size %d)"),
i, alpha_elf_tdata (this_got)->total_got_size);
return FALSE;
@@
-2518,21
+2549,24
@@
elf64_alpha_size_got_sections (struct bfd_link_info *info)
if (cur_got_obj == NULL)
return FALSE;
if (cur_got_obj == NULL)
return FALSE;
- i = alpha_elf_tdata(cur_got_obj)->got_link_next;
- while (i != NULL)
+ if (may_merge)
{
{
- if (elf64_alpha_can_merge_gots (cur_got_obj, i))
+ i = alpha_elf_tdata(cur_got_obj)->got_link_next;
+ while (i != NULL)
{
{
- elf64_alpha_merge_gots (cur_got_obj, i);
+ if (elf64_alpha_can_merge_gots (cur_got_obj, i))
+ {
+ elf64_alpha_merge_gots (cur_got_obj, i);
- alpha_elf_tdata(i)->got->size = 0;
- i = alpha_elf_tdata(i)->got_link_next;
- alpha_elf_tdata(cur_got_obj)->got_link_next = i;
- }
- else
- {
- cur_got_obj = i;
- i = alpha_elf_tdata(i)->got_link_next;
+ alpha_elf_tdata(i)->got->size = 0;
+ i = alpha_elf_tdata(i)->got_link_next;
+ alpha_elf_tdata(cur_got_obj)->got_link_next = i;
+ }
+ else
+ {
+ cur_got_obj = i;
+ i = alpha_elf_tdata(i)->got_link_next;
+ }
}
}
}
}
@@
-2582,15
+2616,13
@@
elf64_alpha_size_plt_section (struct bfd_link_info *info)
{
asection *splt, *spltrel, *sgotplt;
unsigned long entries;
{
asection *splt, *spltrel, *sgotplt;
unsigned long entries;
- bfd *dynobj;
struct alpha_elf_link_hash_table * htab;
htab = alpha_elf_hash_table (info);
if (htab == NULL)
return;
struct alpha_elf_link_hash_table * htab;
htab = alpha_elf_hash_table (info);
if (htab == NULL)
return;
- dynobj = elf_hash_table(info)->dynobj;
- splt = bfd_get_linker_section (dynobj, ".plt");
+ splt = elf_hash_table(info)->splt;
if (splt == NULL)
return;
if (splt == NULL)
return;
@@
-2600,7
+2632,7
@@
elf64_alpha_size_plt_section (struct bfd_link_info *info)
elf64_alpha_size_plt_section_1, splt);
/* Every plt entry requires a JMP_SLOT relocation. */
elf64_alpha_size_plt_section_1, splt);
/* Every plt entry requires a JMP_SLOT relocation. */
- spltrel =
bfd_get_linker_section (dynobj, ".rela.plt")
;
+ spltrel =
elf_hash_table(info)->srelplt
;
entries = 0;
if (splt->size)
{
entries = 0;
if (splt->size)
{
@@
-2616,7
+2648,7
@@
elf64_alpha_size_plt_section (struct bfd_link_info *info)
entire contents of the .got.plt section. */
if (elf64_alpha_use_secureplt)
{
entire contents of the .got.plt section. */
if (elf64_alpha_use_secureplt)
{
- sgotplt =
bfd_get_linker_section (dynobj, ".got.plt")
;
+ sgotplt =
elf_hash_table(info)->sgotplt
;
sgotplt->size = entries ? 16 : 0;
}
}
sgotplt->size = entries ? 16 : 0;
}
}
@@
-2628,14
+2660,14
@@
elf64_alpha_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
bfd *i;
struct alpha_elf_link_hash_table * htab;
bfd *i;
struct alpha_elf_link_hash_table * htab;
- if (
info->relocatable
)
+ if (
bfd_link_relocatable (info)
)
return TRUE;
htab = alpha_elf_hash_table (info);
if (htab == NULL)
return FALSE;
return TRUE;
htab = alpha_elf_hash_table (info);
if (htab == NULL)
return FALSE;
- if (!elf64_alpha_size_got_sections (info))
+ if (!elf64_alpha_size_got_sections (info
, TRUE
))
return FALSE;
/* Allocate space for all of the .got subsections. */
return FALSE;
/* Allocate space for all of the .got subsections. */
@@
-2719,14
+2751,15
@@
elf64_alpha_calc_dynrel_sizes (struct alpha_elf_link_hash_entry *h,
/* If the symbol is a hidden undefined weak, then we never have any
relocations. Avoid the loop which may want to add RELATIVE relocs
/* If the symbol is a hidden undefined weak, then we never have any
relocations. Avoid the loop which may want to add RELATIVE relocs
- based on
info->shared
. */
+ based on
bfd_link_pic (info)
. */
if (h->root.root.type == bfd_link_hash_undefweak && !dynamic)
return TRUE;
for (relent = h->reloc_entries; relent; relent = relent->next)
{
entries = alpha_dynamic_entries_for_reloc (relent->rtype, dynamic,
if (h->root.root.type == bfd_link_hash_undefweak && !dynamic)
return TRUE;
for (relent = h->reloc_entries; relent; relent = relent->next)
{
entries = alpha_dynamic_entries_for_reloc (relent->rtype, dynamic,
- info->shared, info->pie);
+ bfd_link_pic (info),
+ bfd_link_pie (info));
if (entries)
{
relent->srel->size +=
if (entries)
{
relent->srel->size +=
@@
-2762,7
+2795,7
@@
elf64_alpha_size_rela_got_1 (struct alpha_elf_link_hash_entry *h,
/* If the symbol is a hidden undefined weak, then we never have any
relocations. Avoid the loop which may want to add RELATIVE relocs
/* If the symbol is a hidden undefined weak, then we never have any
relocations. Avoid the loop which may want to add RELATIVE relocs
- based on
info->shared
. */
+ based on
bfd_link_pic (info)
. */
if (h->root.root.type == bfd_link_hash_undefweak && !dynamic)
return TRUE;
if (h->root.root.type == bfd_link_hash_undefweak && !dynamic)
return TRUE;
@@
-2770,12
+2803,12
@@
elf64_alpha_size_rela_got_1 (struct alpha_elf_link_hash_entry *h,
for (gotent = h->got_entries; gotent ; gotent = gotent->next)
if (gotent->use_count > 0)
entries += alpha_dynamic_entries_for_reloc (gotent->reloc_type, dynamic,
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, info->pie);
+ bfd_link_pic (info),
+ bfd_link_pie (info));
if (entries > 0)
{
if (entries > 0)
{
- bfd *dynobj = elf_hash_table(info)->dynobj;
- asection *srel = bfd_get_linker_section (dynobj, ".rela.got");
+ asection *srel = elf_hash_table(info)->srelgot;
BFD_ASSERT (srel != NULL);
srel->size += sizeof (Elf64_External_Rela) * entries;
}
BFD_ASSERT (srel != NULL);
srel->size += sizeof (Elf64_External_Rela) * entries;
}
@@
-2789,7
+2822,7
@@
static void
elf64_alpha_size_rela_got_section (struct bfd_link_info *info)
{
unsigned long entries;
elf64_alpha_size_rela_got_section (struct bfd_link_info *info)
{
unsigned long entries;
- bfd *i
, *dynobj
;
+ bfd *i;
asection *srel;
struct alpha_elf_link_hash_table * htab;
asection *srel;
struct alpha_elf_link_hash_table * htab;
@@
-2820,12
+2853,12
@@
elf64_alpha_size_rela_got_section (struct bfd_link_info *info)
gotent ; gotent = gotent->next)
if (gotent->use_count > 0)
entries += (alpha_dynamic_entries_for_reloc
gotent ; gotent = gotent->next)
if (gotent->use_count > 0)
entries += (alpha_dynamic_entries_for_reloc
- (gotent->reloc_type, 0, info->shared, info->pie));
+ (gotent->reloc_type, 0, bfd_link_pic (info),
+ bfd_link_pie (info)));
}
}
}
}
- dynobj = elf_hash_table(info)->dynobj;
- srel = bfd_get_linker_section (dynobj, ".rela.got");
+ srel = elf_hash_table(info)->srelgot;
if (!srel)
{
BFD_ASSERT (entries == 0);
if (!srel)
{
BFD_ASSERT (entries == 0);
@@
-2846,7
+2879,7
@@
elf64_alpha_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
{
bfd *dynobj;
asection *s;
{
bfd *dynobj;
asection *s;
- bfd_boolean relplt;
+ bfd_boolean relplt
, relocs
;
struct alpha_elf_link_hash_table * htab;
htab = alpha_elf_hash_table (info);
struct alpha_elf_link_hash_table * htab;
htab = alpha_elf_hash_table (info);
@@
-2859,7
+2892,7
@@
elf64_alpha_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
if (elf_hash_table (info)->dynamic_sections_created)
{
/* Set the contents of the .interp section to the interpreter. */
if (elf_hash_table (info)->dynamic_sections_created)
{
/* Set the contents of the .interp section to the interpreter. */
- if (
info->executable
)
+ if (
bfd_link_executable (info) && !info->nointerp
)
{
s = bfd_get_linker_section (dynobj, ".interp");
BFD_ASSERT (s != NULL);
{
s = bfd_get_linker_section (dynobj, ".interp");
BFD_ASSERT (s != NULL);
@@
-2883,6
+2916,7
@@
elf64_alpha_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
determined the sizes of the various dynamic sections. Allocate
memory for them. */
relplt = FALSE;
determined the sizes of the various dynamic sections. Allocate
memory for them. */
relplt = FALSE;
+ relocs = FALSE;
for (s = dynobj->sections; s != NULL; s = s->next)
{
const char *name;
for (s = dynobj->sections; s != NULL; s = s->next)
{
const char *name;
@@
-2900,6
+2934,8
@@
elf64_alpha_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
{
if (strcmp (name, ".rela.plt") == 0)
relplt = TRUE;
{
if (strcmp (name, ".rela.plt") == 0)
relplt = TRUE;
+ else
+ relocs = TRUE;
/* We use the reloc_count field as a counter if we need
to copy relocs into the output file. */
/* We use the reloc_count field as a counter if we need
to copy relocs into the output file. */
@@
-2945,7
+2981,7
@@
elf64_alpha_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
#define add_dynamic_entry(TAG, VAL) \
_bfd_elf_add_dynamic_entry (info, TAG, VAL)
#define add_dynamic_entry(TAG, VAL) \
_bfd_elf_add_dynamic_entry (info, TAG, VAL)
- if (
info->executable
)
+ if (
bfd_link_executable (info)
)
{
if (!add_dynamic_entry (DT_DEBUG, 0))
return FALSE;
{
if (!add_dynamic_entry (DT_DEBUG, 0))
return FALSE;
@@
-2964,15
+3000,18
@@
elf64_alpha_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
return FALSE;
}
return FALSE;
}
- if (!add_dynamic_entry (DT_RELA, 0)
- || !add_dynamic_entry (DT_RELASZ, 0)
- || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
- return FALSE;
-
- if (info->flags & DF_TEXTREL)
+ if (relocs)
{
{
- if (!add_dynamic_entry (DT_TEXTREL, 0))
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
return FALSE;
return FALSE;
+
+ if (info->flags & DF_TEXTREL)
+ {
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
+ return FALSE;
+ }
}
}
#undef add_dynamic_entry
}
}
#undef add_dynamic_entry
@@
-3040,10
+3079,11
@@
elf64_alpha_relax_got_load (struct alpha_relax_info *info, bfd_vma symval,
if (insn >> 26 != OP_LDQ)
{
reloc_howto_type *howto = elf64_alpha_howto_table + r_type;
if (insn >> 26 != OP_LDQ)
{
reloc_howto_type *howto = elf64_alpha_howto_table + r_type;
- ((*_bfd_error_handler)
- ("%B: %A+0x%lx: warning: %s relocation against unexpected insn",
- info->abfd, info->sec,
- (unsigned long) irel->r_offset, howto->name));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%B: %A+0x%lx: warning: %s relocation against unexpected insn"),
+ info->abfd, info->sec,
+ (unsigned long) irel->r_offset, howto->name);
return TRUE;
}
return TRUE;
}
@@
-3053,7
+3093,7
@@
elf64_alpha_relax_got_load (struct alpha_relax_info *info, bfd_vma symval,
/* Can't use local-exec relocations in shared libraries. */
if (r_type == R_ALPHA_GOTTPREL
/* Can't use local-exec relocations in shared libraries. */
if (r_type == R_ALPHA_GOTTPREL
- &&
(info->link_info->shared && !info->link_info->pie
))
+ &&
bfd_link_dll (info->link_info
))
return TRUE;
if (r_type == R_ALPHA_LITERAL)
return TRUE;
if (r_type == R_ALPHA_LITERAL)
@@
-3061,7
+3101,7
@@
elf64_alpha_relax_got_load (struct alpha_relax_info *info, bfd_vma symval,
/* Look for nice constant addresses. This includes the not-uncommon
special case of 0 for undefweak symbols. */
if ((info->h && info->h->root.root.type == bfd_link_hash_undefweak)
/* Look for nice constant addresses. This includes the not-uncommon
special case of 0 for undefweak symbols. */
if ((info->h && info->h->root.root.type == bfd_link_hash_undefweak)
- || (!
info->link_info->shared
+ || (!
bfd_link_pic (info->link_info)
&& (symval >= (bfd_vma)-0x8000 || symval < 0x8000)))
{
disp = 0;
&& (symval >= (bfd_vma)-0x8000 || symval < 0x8000)))
{
disp = 0;
@@
-3071,6
+3111,10
@@
elf64_alpha_relax_got_load (struct alpha_relax_info *info, bfd_vma symval,
}
else
{
}
else
{
+ /* We may only create GPREL relocs during the second pass. */
+ if (info->link_info->relax_pass == 0)
+ return TRUE;
+
disp = symval - info->gp;
insn = (OP_LDA << 26) | (insn & 0x03ff0000);
r_type = R_ALPHA_GPREL16;
disp = symval - info->gp;
insn = (OP_LDA << 26) | (insn & 0x03ff0000);
r_type = R_ALPHA_GPREL16;
@@
-3177,7
+3221,9
@@
elf64_alpha_relax_opt_call (struct alpha_relax_info *info, bfd_vma symval)
if (tsec_relocs == NULL)
return 0;
tsec_relend = tsec_relocs + info->tsec->reloc_count;
if (tsec_relocs == NULL)
return 0;
tsec_relend = tsec_relocs + info->tsec->reloc_count;
- tsec_free = (info->link_info->keep_memory ? NULL : tsec_relocs);
+ tsec_free = (elf_section_data (info->tsec)->relocs == tsec_relocs
+ ? NULL
+ : tsec_relocs);
}
/* Recover the symbol's offset within the section. */
}
/* Recover the symbol's offset within the section. */
@@
-3211,22
+3257,29
@@
static bfd_boolean
elf64_alpha_relax_with_lituse (struct alpha_relax_info *info,
bfd_vma symval, Elf_Internal_Rela *irel)
{
elf64_alpha_relax_with_lituse (struct alpha_relax_info *info,
bfd_vma symval, Elf_Internal_Rela *irel)
{
- Elf_Internal_Rela *urel, *irelend = info->relend;
- int flags
, count, i
;
+ Elf_Internal_Rela *urel, *
erel, *
irelend = info->relend;
+ int flags;
bfd_signed_vma disp;
bfd_boolean fits16;
bfd_boolean fits32;
bfd_boolean lit_reused = FALSE;
bfd_boolean all_optimized = TRUE;
bfd_signed_vma disp;
bfd_boolean fits16;
bfd_boolean fits32;
bfd_boolean lit_reused = FALSE;
bfd_boolean all_optimized = TRUE;
+ bfd_boolean changed_contents;
+ bfd_boolean changed_relocs;
+ bfd_byte *contents = info->contents;
+ bfd *abfd = info->abfd;
+ bfd_vma sec_output_vma;
unsigned int lit_insn;
unsigned int lit_insn;
+ int relax_pass;
- lit_insn = bfd_get_32 (
info->abfd, info->
contents + irel->r_offset);
+ lit_insn = bfd_get_32 (
abfd,
contents + irel->r_offset);
if (lit_insn >> 26 != OP_LDQ)
{
if (lit_insn >> 26 != OP_LDQ)
{
- ((*_bfd_error_handler)
- ("%B: %A+0x%lx: warning: LITERAL relocation against unexpected insn",
- info->abfd, info->sec,
- (unsigned long) irel->r_offset));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%B: %A+0x%lx: warning: LITERAL relocation against unexpected insn"),
+ abfd, info->sec,
+ (unsigned long) irel->r_offset);
return TRUE;
}
return TRUE;
}
@@
-3234,25
+3287,32
@@
elf64_alpha_relax_with_lituse (struct alpha_relax_info *info,
if (alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info))
return TRUE;
if (alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info))
return TRUE;
+ changed_contents = info->changed_contents;
+ changed_relocs = info->changed_relocs;
+ sec_output_vma = info->sec->output_section->vma + info->sec->output_offset;
+ relax_pass = info->link_info->relax_pass;
+
/* Summarize how this particular LITERAL is used. */
/* Summarize how this particular LITERAL is used. */
- for (
urel = irel+1, flags = count = 0; urel < irelend; ++urel, ++count
)
+ for (
erel = irel+1, flags = 0; erel < irelend; ++erel
)
{
{
- if (ELF64_R_TYPE (
u
rel->r_info) != R_ALPHA_LITUSE)
+ if (ELF64_R_TYPE (
e
rel->r_info) != R_ALPHA_LITUSE)
break;
break;
- if (
u
rel->r_addend <= 6)
- flags |= 1 <<
u
rel->r_addend;
+ if (
e
rel->r_addend <= 6)
+ flags |= 1 <<
e
rel->r_addend;
}
/* A little preparation for the loop... */
disp = symval - info->gp;
}
/* A little preparation for the loop... */
disp = symval - info->gp;
- for (urel = irel+1
, i = 0; i < count; ++i,
++urel)
+ for (urel = irel+1
; urel < erel;
++urel)
{
{
+ bfd_vma urel_r_offset = urel->r_offset;
unsigned int insn;
int insn_disp;
bfd_signed_vma xdisp;
unsigned int insn;
int insn_disp;
bfd_signed_vma xdisp;
+ Elf_Internal_Rela nrel;
- insn = bfd_get_32 (
info->abfd, info->contents + urel->
r_offset);
+ insn = bfd_get_32 (
abfd, contents + urel_
r_offset);
switch (urel->r_addend)
{
switch (urel->r_addend)
{
@@
-3264,6
+3324,13
@@
elf64_alpha_relax_with_lituse (struct alpha_relax_info *info,
break;
case LITUSE_ALPHA_BASE:
break;
case LITUSE_ALPHA_BASE:
+ /* We may only create GPREL relocs during the second pass. */
+ if (relax_pass == 0)
+ {
+ all_optimized = FALSE;
+ break;
+ }
+
/* We can always optimize 16-bit displacements. */
/* Extract the displacement from the instruction, sign-extending
/* We can always optimize 16-bit displacements. */
/* Extract the displacement from the instruction, sign-extending
@@
-3281,14
+3348,20
@@
elf64_alpha_relax_with_lituse (struct alpha_relax_info *info,
/* Take the op code and dest from this insn, take the base
register from the literal insn. Leave the offset alone. */
insn = (insn & 0xffe0ffff) | (lit_insn & 0x001f0000);
/* Take the op code and dest from this insn, take the base
register from the literal insn. Leave the offset alone. */
insn = (insn & 0xffe0ffff) | (lit_insn & 0x001f0000);
- urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
- R_ALPHA_GPREL16);
- urel->r_addend = irel->r_addend;
- info->changed_relocs = TRUE;
-
- bfd_put_32 (info->abfd, (bfd_vma) insn,
- info->contents + urel->r_offset);
- info->changed_contents = TRUE;
+ bfd_put_32 (abfd, (bfd_vma) insn, contents + urel_r_offset);
+ changed_contents = TRUE;
+
+ nrel = *urel;
+ nrel.r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
+ R_ALPHA_GPREL16);
+ nrel.r_addend = irel->r_addend;
+
+ /* As we adjust, move the reloc to the end so that we don't
+ break the LITERAL+LITUSE chain. */
+ if (urel < --erel)
+ *urel-- = *erel;
+ *erel = nrel;
+ changed_relocs = TRUE;
}
/* If all mem+byte, we can optimize 32-bit mem displacements. */
}
/* If all mem+byte, we can optimize 32-bit mem displacements. */
@@
-3299,15
+3372,16
@@
elf64_alpha_relax_with_lituse (struct alpha_relax_info *info,
irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
R_ALPHA_GPRELHIGH);
lit_insn = (OP_LDAH << 26) | (lit_insn & 0x03ff0000);
irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
R_ALPHA_GPRELHIGH);
lit_insn = (OP_LDAH << 26) | (lit_insn & 0x03ff0000);
- bfd_put_32 (info->abfd, (bfd_vma) lit_insn,
- info->contents + irel->r_offset);
+ bfd_put_32 (abfd, (bfd_vma) lit_insn, contents + irel->r_offset);
lit_reused = TRUE;
lit_reused = TRUE;
-
info->
changed_contents = TRUE;
+ changed_contents = TRUE;
+ /* Since all relocs must be optimized, don't bother swapping
+ this relocation to the end. */
urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
R_ALPHA_GPRELLOW);
urel->r_addend = irel->r_addend;
urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
R_ALPHA_GPRELLOW);
urel->r_addend = irel->r_addend;
-
info->
changed_relocs = TRUE;
+ changed_relocs = TRUE;
}
else
all_optimized = FALSE;
}
else
all_optimized = FALSE;
@@
-3321,14
+3395,19
@@
elf64_alpha_relax_with_lituse (struct alpha_relax_info *info,
insn &= ~ (unsigned) 0x001ff000;
insn |= ((symval & 7) << 13) | 0x1000;
insn &= ~ (unsigned) 0x001ff000;
insn |= ((symval & 7) << 13) | 0x1000;
-
- urel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
- urel->r_addend = 0;
- info->changed_relocs = TRUE;
-
- bfd_put_32 (info->abfd, (bfd_vma) insn,
- info->contents + urel->r_offset);
- info->changed_contents = TRUE;
+ bfd_put_32 (abfd, (bfd_vma) insn, contents + urel_r_offset);
+ changed_contents = TRUE;
+
+ nrel = *urel;
+ nrel.r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
+ nrel.r_addend = 0;
+
+ /* As we adjust, move the reloc to the end so that we don't
+ break the LITERAL+LITUSE chain. */
+ if (urel < --erel)
+ *urel-- = *erel;
+ *erel = nrel;
+ changed_relocs = TRUE;
break;
case LITUSE_ALPHA_JSR:
break;
case LITUSE_ALPHA_JSR:
@@
-3345,18
+3424,15
@@
elf64_alpha_relax_with_lituse (struct alpha_relax_info *info,
if (info->h && info->h->root.root.type == bfd_link_hash_undefweak)
{
insn |= 31 << 16;
if (info->h && info->h->root.root.type == bfd_link_hash_undefweak)
{
insn |= 31 << 16;
- bfd_put_32 (info->abfd, (bfd_vma) insn,
- info->contents + urel->r_offset);
+ bfd_put_32 (abfd, (bfd_vma) insn, contents + urel_r_offset);
-
info->
changed_contents = TRUE;
+ changed_contents = TRUE;
break;
}
/* If not zero, place to jump without needing pv. */
optdest = elf64_alpha_relax_opt_call (info, symval);
break;
}
/* If not zero, place to jump without needing pv. */
optdest = elf64_alpha_relax_opt_call (info, symval);
- org = (info->sec->output_section->vma
- + info->sec->output_offset
- + urel->r_offset + 4);
+ org = sec_output_vma + urel_r_offset + 4;
odisp = (optdest ? optdest : symval) - org;
if (odisp >= -0x400000 && odisp < 0x400000)
odisp = (optdest ? optdest : symval) - org;
if (odisp >= -0x400000 && odisp < 0x400000)
@@
-3368,27
+3444,32
@@
elf64_alpha_relax_with_lituse (struct alpha_relax_info *info,
insn = (OP_BSR << 26) | (insn & 0x03e00000);
else
insn = (OP_BR << 26) | (insn & 0x03e00000);
insn = (OP_BSR << 26) | (insn & 0x03e00000);
else
insn = (OP_BR << 26) | (insn & 0x03e00000);
+ bfd_put_32 (abfd, (bfd_vma) insn, contents + urel_r_offset);
+ changed_contents = TRUE;
- urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
- R_ALPHA_BRADDR);
- urel->r_addend = irel->r_addend;
+ nrel = *urel;
+ nrel.r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
+ R_ALPHA_BRADDR);
+ nrel.r_addend = irel->r_addend;
if (optdest)
if (optdest)
-
urel->
r_addend += optdest - symval;
+
nrel.
r_addend += optdest - symval;
else
all_optimized = FALSE;
else
all_optimized = FALSE;
- bfd_put_32 (info->abfd, (bfd_vma) insn,
- info->contents + urel->r_offset);
-
/* Kill any HINT reloc that might exist for this insn. */
xrel = (elf64_alpha_find_reloc_at_ofs
/* Kill any HINT reloc that might exist for this insn. */
xrel = (elf64_alpha_find_reloc_at_ofs
- (info->relocs, info->relend, urel
->
r_offset,
+ (info->relocs, info->relend, urel
_
r_offset,
R_ALPHA_HINT));
if (xrel)
xrel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
R_ALPHA_HINT));
if (xrel)
xrel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
- info->changed_contents = TRUE;
+ /* As we adjust, move the reloc to the end so that we don't
+ break the LITERAL+LITUSE chain. */
+ if (urel < --erel)
+ *urel-- = *erel;
+ *erel = nrel;
+
info->changed_relocs = TRUE;
}
else
info->changed_relocs = TRUE;
}
else
@@
-3400,14
+3481,14
@@
elf64_alpha_relax_with_lituse (struct alpha_relax_info *info,
{
Elf_Internal_Rela *gpdisp
= (elf64_alpha_find_reloc_at_ofs
{
Elf_Internal_Rela *gpdisp
= (elf64_alpha_find_reloc_at_ofs
- (info->relocs, irelend, urel
->
r_offset + 4,
+ (info->relocs, irelend, urel
_
r_offset + 4,
R_ALPHA_GPDISP));
if (gpdisp)
{
R_ALPHA_GPDISP));
if (gpdisp)
{
- bfd_byte *p_ldah =
info->
contents + gpdisp->r_offset;
+ bfd_byte *p_ldah = contents + gpdisp->r_offset;
bfd_byte *p_lda = p_ldah + gpdisp->r_addend;
bfd_byte *p_lda = p_ldah + gpdisp->r_addend;
- unsigned int ldah = bfd_get_32 (
info->
abfd, p_ldah);
- unsigned int lda = bfd_get_32 (
info->
abfd, p_lda);
+ unsigned int ldah = bfd_get_32 (abfd, p_ldah);
+ unsigned int lda = bfd_get_32 (abfd, p_lda);
/* Verify that the instruction is "ldah $29,0($26)".
Consider a function that ends in a noreturn call,
/* Verify that the instruction is "ldah $29,0($26)".
Consider a function that ends in a noreturn call,
@@
-3416,12
+3497,12
@@
elf64_alpha_relax_with_lituse (struct alpha_relax_info *info,
In that case the insn would use $27 as the base. */
if (ldah == 0x27ba0000 && lda == 0x23bd0000)
{
In that case the insn would use $27 as the base. */
if (ldah == 0x27ba0000 && lda == 0x23bd0000)
{
- bfd_put_32 (
info->
abfd, (bfd_vma) INSN_UNOP, p_ldah);
- bfd_put_32 (
info->
abfd, (bfd_vma) INSN_UNOP, p_lda);
+ bfd_put_32 (abfd, (bfd_vma) INSN_UNOP, p_ldah);
+ bfd_put_32 (abfd, (bfd_vma) INSN_UNOP, p_lda);
gpdisp->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
gpdisp->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
-
info->
changed_contents = TRUE;
-
info->
changed_relocs = TRUE;
+ changed_contents = TRUE;
+ changed_relocs = TRUE;
}
}
}
}
}
}
@@
-3430,6
+3511,9
@@
elf64_alpha_relax_with_lituse (struct alpha_relax_info *info,
}
}
}
}
+ /* If we reused the literal instruction, we must have optimized all. */
+ BFD_ASSERT(!lit_reused || all_optimized);
+
/* If all cases were optimized, we can reduce the use count on this
got entry by one, possibly eliminating it. */
if (all_optimized)
/* If all cases were optimized, we can reduce the use count on this
got entry by one, possibly eliminating it. */
if (all_optimized)
@@
-3449,17
+3533,19
@@
elf64_alpha_relax_with_lituse (struct alpha_relax_info *info,
if (!lit_reused)
{
irel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
if (!lit_reused)
{
irel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
-
info->
changed_relocs = TRUE;
+ changed_relocs = TRUE;
- bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP,
- info->contents + irel->r_offset);
- info->changed_contents = TRUE;
+ bfd_put_32 (abfd, (bfd_vma) INSN_UNOP, contents + irel->r_offset);
+ changed_contents = TRUE;
}
}
-
- return TRUE;
}
}
- else
- return elf64_alpha_relax_got_load (info, symval, irel, R_ALPHA_LITERAL);
+
+ info->changed_contents = changed_contents;
+ info->changed_relocs = changed_relocs;
+
+ if (all_optimized || relax_pass == 0)
+ return TRUE;
+ return elf64_alpha_relax_got_load (info, symval, irel, R_ALPHA_LITERAL);
}
static bfd_boolean
}
static bfd_boolean
@@
-3481,12
+3567,12
@@
elf64_alpha_relax_tls_get_addr (struct alpha_relax_info *info, bfd_vma symval,
/* If the symbol is local, and we've already committed to DF_STATIC_TLS,
then we might as well relax to IE. */
/* If the symbol is local, and we've already committed to DF_STATIC_TLS,
then we might as well relax to IE. */
- else if (
info->link_info->shared
&& !dynamic
+ else if (
bfd_link_pic (info->link_info)
&& !dynamic
&& (info->link_info->flags & DF_STATIC_TLS))
;
/* Otherwise we must be building an executable to do anything. */
&& (info->link_info->flags & DF_STATIC_TLS))
;
/* Otherwise we must be building an executable to do anything. */
- else if (
info->link_info->shared
)
+ else if (
bfd_link_pic (info->link_info)
)
return TRUE;
/* The TLSGD/TLSLDM relocation must be followed by a LITERAL and
return TRUE;
/* The TLSGD/TLSLDM relocation must be followed by a LITERAL and
@@
-3585,7
+3671,9
@@
elf64_alpha_relax_tls_get_addr (struct alpha_relax_info *info, bfd_vma symval,
use_gottprel = FALSE;
new_symndx = is_gd ? ELF64_R_SYM (irel->r_info) : STN_UNDEF;
use_gottprel = FALSE;
new_symndx = is_gd ? ELF64_R_SYM (irel->r_info) : STN_UNDEF;
- switch (!dynamic && !info->link_info->shared)
+ /* Some compilers warn about a Boolean-looking expression being
+ used in a switch. The explicit cast silences them. */
+ switch ((int) (!dynamic && !bfd_link_pic (info->link_info)))
{
case 1:
{
{
case 1:
{
@@
-3719,6
+3807,7
@@
elf64_alpha_relax_section (bfd *abfd, asection *sec,
struct alpha_elf_got_entry **local_got_entries;
struct alpha_relax_info info;
struct alpha_elf_link_hash_table * htab;
struct alpha_elf_got_entry **local_got_entries;
struct alpha_relax_info info;
struct alpha_elf_link_hash_table * htab;
+ int relax_pass;
htab = alpha_elf_hash_table (link_info);
if (htab == NULL)
htab = alpha_elf_hash_table (link_info);
if (htab == NULL)
@@
-3727,22
+3816,26
@@
elf64_alpha_relax_section (bfd *abfd, asection *sec,
/* There's nothing to change, yet. */
*again = FALSE;
/* There's nothing to change, yet. */
*again = FALSE;
- if (
link_info->relocatable
+ if (
bfd_link_relocatable (link_info)
|| ((sec->flags & (SEC_CODE | SEC_RELOC | SEC_ALLOC))
!= (SEC_CODE | SEC_RELOC | SEC_ALLOC))
|| sec->reloc_count == 0)
return TRUE;
BFD_ASSERT (is_alpha_elf (abfd));
|| ((sec->flags & (SEC_CODE | SEC_RELOC | SEC_ALLOC))
!= (SEC_CODE | SEC_RELOC | SEC_ALLOC))
|| sec->reloc_count == 0)
return TRUE;
BFD_ASSERT (is_alpha_elf (abfd));
+ relax_pass = link_info->relax_pass;
/* Make sure our GOT and PLT tables are up-to-date. */
if (htab->relax_trip != link_info->relax_trip)
{
htab->relax_trip = link_info->relax_trip;
/* Make sure our GOT and PLT tables are up-to-date. */
if (htab->relax_trip != link_info->relax_trip)
{
htab->relax_trip = link_info->relax_trip;
- /* This should never fail after the initial round, since the only
- error is GOT overflow, and relaxation only shrinks the table. */
- if (!elf64_alpha_size_got_sections (link_info))
+ /* This should never fail after the initial round, since the only error
+ is GOT overflow, and relaxation only shrinks the table. However, we
+ may only merge got sections during the first pass. If we merge
+ sections after we've created GPREL relocs, the GP for the merged
+ section backs up which may put the relocs out of range. */
+ if (!elf64_alpha_size_got_sections (link_info, relax_pass == 0))
abort ();
if (elf_hash_table (link_info)->dynamic_sections_created)
{
abort ();
if (elf_hash_table (link_info)->dynamic_sections_created)
{
@@
-3797,24
+3890,21
@@
elf64_alpha_relax_section (bfd *abfd, asection *sec,
unsigned long r_symndx = ELF64_R_SYM (irel->r_info);
/* Early exit for unhandled or unrelaxable relocations. */
unsigned long r_symndx = ELF64_R_SYM (irel->r_info);
/* Early exit for unhandled or unrelaxable relocations. */
- switch (r_type)
- {
- case R_ALPHA_LITERAL:
- case R_ALPHA_GPRELHIGH:
- case R_ALPHA_GPRELLOW:
- case R_ALPHA_GOTDTPREL:
- case R_ALPHA_GOTTPREL:
- case R_ALPHA_TLSGD:
- break;
-
- case R_ALPHA_TLSLDM:
- /* The symbol for a TLSLDM reloc is ignored. Collapse the
- reloc to the STN_UNDEF (0) symbol so that they all match. */
- r_symndx = STN_UNDEF;
- break;
-
- default:
- continue;
+ if (r_type != R_ALPHA_LITERAL)
+ {
+ /* We complete everything except LITERAL in the first pass. */
+ if (relax_pass != 0)
+ continue;
+ if (r_type == R_ALPHA_TLSLDM)
+ {
+ /* The symbol for a TLSLDM reloc is ignored. Collapse the
+ reloc to the STN_UNDEF (0) symbol so that they all match. */
+ r_symndx = STN_UNDEF;
+ }
+ else if (r_type != R_ALPHA_GOTDTPREL
+ && r_type != R_ALPHA_GOTTPREL
+ && r_type != R_ALPHA_TLSGD)
+ continue;
}
/* Get the value of the symbol referred to by the reloc. */
}
/* Get the value of the symbol referred to by the reloc. */
@@
-4072,7
+4162,8
@@
elf64_alpha_relocate_section_r (bfd *output_bfd ATTRIBUTE_UNUSED,
r_type = ELF64_R_TYPE (rel->r_info);
if (r_type >= R_ALPHA_max)
{
r_type = ELF64_R_TYPE (rel->r_info);
if (r_type >= R_ALPHA_max)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: unknown relocation type %d"),
input_bfd, (int) r_type);
bfd_set_error (bfd_error_bad_value);
(_("%B: unknown relocation type %d"),
input_bfd, (int) r_type);
bfd_set_error (bfd_error_bad_value);
@@
-4141,9
+4232,9
@@
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
bfd_boolean ret_val;
BFD_ASSERT (is_alpha_elf (input_bfd));
bfd_boolean ret_val;
BFD_ASSERT (is_alpha_elf (input_bfd));
-
+
/* Handle relocatable links with a smaller loop. */
/* Handle relocatable links with a smaller loop. */
- if (
info->relocatable
)
+ if (
bfd_link_relocatable (info)
)
return elf64_alpha_relocate_section_r (output_bfd, info, input_bfd,
input_section, contents, relocs,
local_syms, local_sections);
return elf64_alpha_relocate_section_r (output_bfd, info, input_bfd,
input_section, contents, relocs,
local_syms, local_sections);
@@
-4155,10
+4246,7
@@
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
symtab_hdr = &elf_symtab_hdr (input_bfd);
dynobj = elf_hash_table (info)->dynobj;
symtab_hdr = &elf_symtab_hdr (input_bfd);
dynobj = elf_hash_table (info)->dynobj;
- if (dynobj)
- srelgot = bfd_get_linker_section (dynobj, ".rela.got");
- else
- srelgot = NULL;
+ srelgot = elf_hash_table (info)->srelgot;
if (input_section->flags & SEC_ALLOC)
{
if (input_section->flags & SEC_ALLOC)
{
@@
-4222,7
+4310,8
@@
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
r_type = ELF64_R_TYPE(rel->r_info);
if (r_type >= R_ALPHA_max)
{
r_type = ELF64_R_TYPE(rel->r_info);
if (r_type >= R_ALPHA_max)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: unknown relocation type %d"),
input_bfd, (int) r_type);
bfd_set_error (bfd_error_bad_value);
(_("%B: unknown relocation type %d"),
input_bfd, (int) r_type);
bfd_set_error (bfd_error_bad_value);
@@
-4296,14
+4385,14
@@
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
}
else
{
}
else
{
- bfd_boolean warned;
+ bfd_boolean warned
, ignored
;
struct elf_link_hash_entry *hh;
struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
r_symndx, symtab_hdr, sym_hashes,
hh, sec, value,
struct elf_link_hash_entry *hh;
struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
r_symndx, symtab_hdr, sym_hashes,
hh, sec, value,
- unresolved_reloc, warned);
+ unresolved_reloc, warned
, ignored
);
if (warned)
continue;
if (warned)
continue;
@@
-4368,7
+4457,9
@@
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
/* If the symbol has been forced local, output a
RELATIVE reloc, otherwise it will be handled in
finish_dynamic_symbol. */
/* If the symbol has been forced local, output a
RELATIVE reloc, otherwise it will be handled in
finish_dynamic_symbol. */
- if (info->shared && !dynamic_symbol_p && !undef_weak_ref)
+ if (bfd_link_pic (info)
+ && !dynamic_symbol_p
+ && !undef_weak_ref)
elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
gotent->got_offset, 0,
R_ALPHA_RELATIVE, value);
elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
gotent->got_offset, 0,
R_ALPHA_RELATIVE, value);
@@
-4385,7
+4476,8
@@
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_ALPHA_GPRELLOW:
if (dynamic_symbol_p)
{
case R_ALPHA_GPRELLOW:
if (dynamic_symbol_p)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: gp-relative relocation against dynamic symbol %s"),
input_bfd, h->root.root.root.string);
ret_val = FALSE;
(_("%B: gp-relative relocation against dynamic symbol %s"),
input_bfd, h->root.root.root.string);
ret_val = FALSE;
@@
-4397,7
+4489,8
@@
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_ALPHA_GPRELHIGH:
if (dynamic_symbol_p)
{
case R_ALPHA_GPRELHIGH:
if (dynamic_symbol_p)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: gp-relative relocation against dynamic symbol %s"),
input_bfd, h->root.root.root.string);
ret_val = FALSE;
(_("%B: gp-relative relocation against dynamic symbol %s"),
input_bfd, h->root.root.root.string);
ret_val = FALSE;
@@
-4423,7
+4516,8
@@
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_ALPHA_BRADDR:
if (dynamic_symbol_p)
{
case R_ALPHA_BRADDR:
if (dynamic_symbol_p)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: pc-relative relocation against dynamic symbol %s"),
input_bfd, h->root.root.root.string);
ret_val = FALSE;
(_("%B: pc-relative relocation against dynamic symbol %s"),
input_bfd, h->root.root.root.string);
ret_val = FALSE;
@@
-4451,7
+4545,8
@@
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
&& alpha_elf_tdata (sec->owner)->gotobj
&& gotobj != alpha_elf_tdata (sec->owner)->gotobj)
{
&& alpha_elf_tdata (sec->owner)->gotobj
&& gotobj != alpha_elf_tdata (sec->owner)->gotobj)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: change in gp: BRSGP %s"),
input_bfd, h->root.root.root.string);
ret_val = FALSE;
(_("%B: change in gp: BRSGP %s"),
input_bfd, h->root.root.root.string);
ret_val = FALSE;
@@
-4481,7
+4576,8
@@
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
else if (name[0] == 0)
name = bfd_section_name (input_bfd, sec);
}
else if (name[0] == 0)
name = bfd_section_name (input_bfd, sec);
}
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: !samegp reloc against symbol without .prologue: %s"),
input_bfd, name);
ret_val = FALSE;
(_("%B: !samegp reloc against symbol without .prologue: %s"),
input_bfd, name);
ret_val = FALSE;
@@
-4518,7
+4614,7
@@
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
else if (r_type == R_ALPHA_TPREL64)
{
BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
else if (r_type == R_ALPHA_TPREL64)
{
BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
- if (!
info->shared || info->pie
)
+ if (!
bfd_link_dll (info)
)
{
value -= tp_base;
goto default_reloc;
{
value -= tp_base;
goto default_reloc;
@@
-4526,7
+4622,7
@@
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
dynindx = 0;
dynaddend = value - dtp_base;
}
dynindx = 0;
dynaddend = value - dtp_base;
}
- else if (
info->shared
+ else if (
bfd_link_pic (info)
&& r_symndx != STN_UNDEF
&& (input_section->flags & SEC_ALLOC)
&& !undef_weak_ref
&& r_symndx != STN_UNDEF
&& (input_section->flags & SEC_ALLOC)
&& !undef_weak_ref
@@
-4538,7
+4634,8
@@
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
{
if (r_type == R_ALPHA_REFLONG)
{
{
if (r_type == R_ALPHA_REFLONG)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: unhandled dynamic relocation against %s"),
input_bfd,
h->root.root.root.string);
(_("%B: unhandled dynamic relocation against %s"),
input_bfd,
h->root.root.root.string);
@@
-4563,14
+4660,17
@@
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_ALPHA_SREL64:
if (dynamic_symbol_p)
{
case R_ALPHA_SREL64:
if (dynamic_symbol_p)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: pc-relative relocation against dynamic symbol %s"),
input_bfd, h->root.root.root.string);
ret_val = FALSE;
}
(_("%B: pc-relative relocation against dynamic symbol %s"),
input_bfd, h->root.root.root.string);
ret_val = FALSE;
}
- else if ((info->shared || info->pie) && undef_weak_ref)
+ else if (bfd_link_pic (info)
+ && undef_weak_ref)
{
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: pc-relative relocation against undefined weak symbol %s"),
input_bfd, h->root.root.root.string);
ret_val = FALSE;
(_("%B: pc-relative relocation against undefined weak symbol %s"),
input_bfd, h->root.root.root.string);
ret_val = FALSE;
@@
-4601,13
+4701,14
@@
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
gotent->reloc_done = 1;
/* Note that the module index for the main program is 1. */
gotent->reloc_done = 1;
/* Note that the module index for the main program is 1. */
- bfd_put_64 (output_bfd, !info->shared && !dynamic_symbol_p,
+ bfd_put_64 (output_bfd,
+ !bfd_link_pic (info) && !dynamic_symbol_p,
sgot->contents + gotent->got_offset);
/* If the symbol has been forced local, output a
DTPMOD64 reloc, otherwise it will be handled in
finish_dynamic_symbol. */
sgot->contents + gotent->got_offset);
/* If the symbol has been forced local, output a
DTPMOD64 reloc, otherwise it will be handled in
finish_dynamic_symbol. */
- if (
info->shared
&& !dynamic_symbol_p)
+ if (
bfd_link_pic (info)
&& !dynamic_symbol_p)
elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
gotent->got_offset, 0,
R_ALPHA_DTPMOD64, 0);
elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
gotent->got_offset, 0,
R_ALPHA_DTPMOD64, 0);
@@
-4634,7
+4735,8
@@
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_ALPHA_DTPREL16:
if (dynamic_symbol_p)
{
case R_ALPHA_DTPREL16:
if (dynamic_symbol_p)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: dtp-relative relocation against dynamic symbol %s"),
input_bfd, h->root.root.root.string);
ret_val = FALSE;
(_("%B: dtp-relative relocation against dynamic symbol %s"),
input_bfd, h->root.root.root.string);
ret_val = FALSE;
@@
-4648,16
+4750,18
@@
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_ALPHA_TPRELHI:
case R_ALPHA_TPRELLO:
case R_ALPHA_TPREL16:
case R_ALPHA_TPRELHI:
case R_ALPHA_TPRELLO:
case R_ALPHA_TPREL16:
- if (
info->shared && !info->pie
)
+ if (
bfd_link_dll (info)
)
{
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: TLS local exec code cannot be linked into shared objects"),
input_bfd);
ret_val = FALSE;
}
else if (dynamic_symbol_p)
{
(_("%B: TLS local exec code cannot be linked into shared objects"),
input_bfd);
ret_val = FALSE;
}
else if (dynamic_symbol_p)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
+ /* xgettext:c-format */
(_("%B: tp-relative relocation against dynamic symbol %s"),
input_bfd, h->root.root.root.string);
ret_val = FALSE;
(_("%B: tp-relative relocation against dynamic symbol %s"),
input_bfd, h->root.root.root.string);
ret_val = FALSE;
@@
-4686,7
+4790,7
@@
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
if (r_type == R_ALPHA_GOTDTPREL)
value -= dtp_base;
BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
if (r_type == R_ALPHA_GOTDTPREL)
value -= dtp_base;
- else if (!
info->shared
)
+ else if (!
bfd_link_pic (info)
)
value -= tp_base;
else
{
value -= tp_base;
else
{
@@
-4743,11
+4847,9
@@
elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
if (*name == '\0')
name = bfd_section_name (input_bfd, sec);
}
if (*name == '\0')
name = bfd_section_name (input_bfd, sec);
}
- if (! ((*info->callbacks->reloc_overflow)
- (info, (h ? &h->root.root : NULL), name, howto->name,
- (bfd_vma) 0, input_bfd, input_section,
- rel->r_offset)))
- ret_val = FALSE;
+ (*info->callbacks->reloc_overflow)
+ (info, (h ? &h->root.root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
}
break;
}
break;
@@
-4769,7
+4871,6
@@
elf64_alpha_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
Elf_Internal_Sym *sym)
{
struct alpha_elf_link_hash_entry *ah = (struct alpha_elf_link_hash_entry *)h;
Elf_Internal_Sym *sym)
{
struct alpha_elf_link_hash_entry *ah = (struct alpha_elf_link_hash_entry *)h;
- bfd *dynobj = elf_hash_table(info)->dynobj;
if (h->needs_plt)
{
if (h->needs_plt)
{
@@
-4783,9
+4884,9
@@
elf64_alpha_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
BFD_ASSERT (h->dynindx != -1);
BFD_ASSERT (h->dynindx != -1);
- splt =
bfd_get_linker_section (dynobj, ".plt")
;
+ splt =
elf_hash_table (info)->splt
;
BFD_ASSERT (splt != NULL);
BFD_ASSERT (splt != NULL);
- srel =
bfd_get_linker_section (dynobj, ".rela.plt")
;
+ srel =
elf_hash_table (info)->srelplt
;
BFD_ASSERT (srel != NULL);
for (gotent = ah->got_entries; gotent ; gotent = gotent->next)
BFD_ASSERT (srel != NULL);
for (gotent = ah->got_entries; gotent ; gotent = gotent->next)
@@
-4855,7
+4956,7
@@
elf64_alpha_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
asection *srel;
struct alpha_elf_got_entry *gotent;
asection *srel;
struct alpha_elf_got_entry *gotent;
- srel =
bfd_get_linker_section (dynobj, ".rela.got")
;
+ srel =
elf_hash_table (info)->srelgot
;
BFD_ASSERT (srel != NULL);
for (gotent = ((struct alpha_elf_link_hash_entry *) h)->got_entries;
BFD_ASSERT (srel != NULL);
for (gotent = ((struct alpha_elf_link_hash_entry *) h)->got_entries;
@@
-4890,19
+4991,19
@@
elf64_alpha_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
abort ();
}
abort ();
}
- elf64_alpha_emit_dynrel (output_bfd, info, sgot, srel,
+ elf64_alpha_emit_dynrel (output_bfd, info, sgot, srel,
gotent->got_offset, h->dynindx,
r_type, gotent->addend);
if (gotent->reloc_type == R_ALPHA_TLSGD)
gotent->got_offset, h->dynindx,
r_type, gotent->addend);
if (gotent->reloc_type == R_ALPHA_TLSGD)
- elf64_alpha_emit_dynrel (output_bfd, info, sgot, srel,
+ elf64_alpha_emit_dynrel (output_bfd, info, sgot, srel,
gotent->got_offset + 8, h->dynindx,
R_ALPHA_DTPREL64, gotent->addend);
}
}
/* Mark some specially defined symbols as absolute. */
gotent->got_offset + 8, h->dynindx,
R_ALPHA_DTPREL64, gotent->addend);
}
}
/* Mark some specially defined symbols as absolute. */
- if (
strcmp (h->root.root.string, "_DYNAMIC") == 0
+ if (
h == elf_hash_table (info)->hdynamic
|| h == elf_hash_table (info)->hgot
|| h == elf_hash_table (info)->hplt)
sym->st_shndx = SHN_ABS;
|| h == elf_hash_table (info)->hgot
|| h == elf_hash_table (info)->hplt)
sym->st_shndx = SHN_ABS;
@@
-4928,8
+5029,8
@@
elf64_alpha_finish_dynamic_sections (bfd *output_bfd,
Elf64_External_Dyn *dyncon, *dynconend;
bfd_vma plt_vma, gotplt_vma;
Elf64_External_Dyn *dyncon, *dynconend;
bfd_vma plt_vma, gotplt_vma;
- splt =
bfd_get_linker_section (dynobj, ".plt")
;
- srelaplt =
bfd_get_linker_section (output_bfd, ".rela.plt")
;
+ splt =
elf_hash_table (info)->splt
;
+ srelaplt =
elf_hash_table (info)->srelplt
;
BFD_ASSERT (splt != NULL && sdyn != NULL);
plt_vma = splt->output_section->vma + splt->output_offset;
BFD_ASSERT (splt != NULL && sdyn != NULL);
plt_vma = splt->output_section->vma + splt->output_offset;
@@
-4937,7
+5038,7
@@
elf64_alpha_finish_dynamic_sections (bfd *output_bfd,
gotplt_vma = 0;
if (elf64_alpha_use_secureplt)
{
gotplt_vma = 0;
if (elf64_alpha_use_secureplt)
{
- sgotplt =
bfd_get_linker_section (dynobj, ".got.plt")
;
+ sgotplt =
elf_hash_table (info)->sgotplt
;
BFD_ASSERT (sgotplt != NULL);
if (sgotplt->size > 0)
gotplt_vma = sgotplt->output_section->vma + sgotplt->output_offset;
BFD_ASSERT (sgotplt != NULL);
if (sgotplt->size > 0)
gotplt_vma = sgotplt->output_section->vma + sgotplt->output_offset;
@@
-4961,17
+5062,8
@@
elf64_alpha_finish_dynamic_sections (bfd *output_bfd,
dyn.d_un.d_val = srelaplt ? srelaplt->size : 0;
break;
case DT_JMPREL:
dyn.d_un.d_val = srelaplt ? srelaplt->size : 0;
break;
case DT_JMPREL:
- dyn.d_un.d_ptr = srelaplt ? srelaplt->vma : 0;
- break;
-
- case DT_RELASZ:
- /* My interpretation of the TIS v1.1 ELF document indicates
- that RELASZ should not include JMPREL. This is not what
- the rest of the BFD does. It is, however, what the
- glibc ld.so wants. Do this fixup here until we found
- out who is right. */
- if (srelaplt)
- dyn.d_un.d_val -= srelaplt->size;
+ dyn.d_un.d_ptr = srelaplt ? (srelaplt->output_section->vma
+ + srelaplt->output_offset) : 0;
break;
}
break;
}
@@
-5313,7
+5405,9
@@
elf64_alpha_final_link (bfd *abfd, struct bfd_link_info *info)
}
static enum elf_reloc_type_class
}
static enum elf_reloc_type_class
-elf64_alpha_reloc_type_class (const Elf_Internal_Rela *rela)
+elf64_alpha_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela)
{
switch ((int) ELF64_R_TYPE (rela->r_info))
{
{
switch ((int) ELF64_R_TYPE (rela->r_info))
{
@@
-5412,7
+5506,7
@@
static const struct elf_size_info alpha_elf_size_info =
bfd_elf64_swap_reloca_out
};
bfd_elf64_swap_reloca_out
};
-#define TARGET_LITTLE_SYM
bfd_elf64_alpha
_vec
+#define TARGET_LITTLE_SYM
alpha_elf64
_vec
#define TARGET_LITTLE_NAME "elf64-alpha"
#define ELF_ARCH bfd_arch_alpha
#define ELF_TARGET_ID ALPHA_ELF_DATA
#define TARGET_LITTLE_NAME "elf64-alpha"
#define ELF_ARCH bfd_arch_alpha
#define ELF_TARGET_ID ALPHA_ELF_DATA
@@
-5453,6
+5547,8
@@
static const struct elf_size_info alpha_elf_size_info =
elf64_alpha_add_symbol_hook
#define elf_backend_relocs_compatible \
_bfd_elf_relocs_compatible
elf64_alpha_add_symbol_hook
#define elf_backend_relocs_compatible \
_bfd_elf_relocs_compatible
+#define elf_backend_sort_relocs_p \
+ elf64_alpha_sort_relocs_p
#define elf_backend_check_relocs \
elf64_alpha_check_relocs
#define elf_backend_create_dynamic_sections \
#define elf_backend_check_relocs \
elf64_alpha_check_relocs
#define elf_backend_create_dynamic_sections \
@@
-5498,13
+5594,14
@@
static const struct elf_size_info alpha_elf_size_info =
#define elf_backend_plt_readonly 0
#define elf_backend_want_plt_sym 1
#define elf_backend_got_header_size 0
#define elf_backend_plt_readonly 0
#define elf_backend_want_plt_sym 1
#define elf_backend_got_header_size 0
+#define elf_backend_dtrel_excludes_plt 1
#include "elf64-target.h"
\f
/* FreeBSD support. */
#undef TARGET_LITTLE_SYM
#include "elf64-target.h"
\f
/* FreeBSD support. */
#undef TARGET_LITTLE_SYM
-#define TARGET_LITTLE_SYM
bfd_elf64_alpha_free
bsd_vec
+#define TARGET_LITTLE_SYM
alpha_elf64_f
bsd_vec
#undef TARGET_LITTLE_NAME
#define TARGET_LITTLE_NAME "elf64-alpha-freebsd"
#undef ELF_OSABI
#undef TARGET_LITTLE_NAME
#define TARGET_LITTLE_NAME "elf64-alpha-freebsd"
#undef ELF_OSABI
This page took
0.064711 seconds
and
4
git commands to generate.