X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=bfd%2Felf64-alpha.c;h=1df020c3975b7ec4afdfdba58d06aa07265122c6;hb=cf35638d431e230d51d54550e8a249e730264ea5;hp=76d0661a11657055261af2a583636279f8eede74;hpb=01f0fe5e0450edf168c1f612feb93cf588e4e7ea;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index 76d0661a11..1df020c397 100644 --- a/bfd/elf64-alpha.c +++ b/bfd/elf64-alpha.c @@ -1,13 +1,13 @@ /* Alpha specific support for 64-bit ELF Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2006 Free Software Foundation, Inc. + 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Richard Henderson . This file is part of BFD, the Binary File Descriptor library. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,13 +17,15 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + /* We need a published ABI spec for this. Until one comes out, don't assume this'll remain unchanged forever. */ -#include "bfd.h" #include "sysdep.h" +#include "bfd.h" #include "libbfd.h" #include "elf-bfd.h" @@ -101,6 +103,57 @@ bfd_boolean elf64_alpha_use_secureplt = FALSE; #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so" + +/* Used to implement multiple .got subsections. */ +struct alpha_elf_got_entry +{ + struct alpha_elf_got_entry *next; + + /* Which .got subsection? */ + bfd *gotobj; + + /* The addend in effect for this entry. */ + bfd_vma addend; + + /* The .got offset for this entry. */ + int got_offset; + + /* The .plt offset for this entry. */ + int plt_offset; + + /* How many references to this entry? */ + int use_count; + + /* The relocation type of this entry. */ + unsigned char reloc_type; + + /* How a LITERAL is used. */ + unsigned char flags; + + /* Have we initialized the dynamic relocation for this entry? */ + unsigned char reloc_done; + + /* Have we adjusted this entry for SEC_MERGE? */ + unsigned char reloc_xlated; +}; + +struct alpha_elf_reloc_entry +{ + struct alpha_elf_reloc_entry *next; + + /* Which .reloc section? */ + asection *srel; + + /* What kind of relocation? */ + unsigned int rtype; + + /* Is this against read-only section? */ + unsigned int reltext : 1; + + /* How many did we find? */ + unsigned long count; +}; + struct alpha_elf_link_hash_entry { struct elf_link_hash_entry root; @@ -123,56 +176,11 @@ struct alpha_elf_link_hash_entry #define ALPHA_ELF_LINK_HASH_TLS_IE 0x80 /* Used to implement multiple .got subsections. */ - struct alpha_elf_got_entry - { - struct alpha_elf_got_entry *next; - - /* Which .got subsection? */ - bfd *gotobj; - - /* The addend in effect for this entry. */ - bfd_vma addend; - - /* The .got offset for this entry. */ - int got_offset; - - /* The .plt offset for this entry. */ - int plt_offset; - - /* How many references to this entry? */ - int use_count; - - /* The relocation type of this entry. */ - unsigned char reloc_type; - - /* How a LITERAL is used. */ - unsigned char flags; - - /* Have we initialized the dynamic relocation for this entry? */ - unsigned char reloc_done; - - /* Have we adjusted this entry for SEC_MERGE? */ - unsigned char reloc_xlated; - } *got_entries; + struct alpha_elf_got_entry *got_entries; /* Used to count non-got, non-plt relocations for delayed sizing of relocation sections. */ - struct alpha_elf_reloc_entry - { - struct alpha_elf_reloc_entry *next; - - /* Which .reloc section? */ - asection *srel; - - /* What kind of relocation? */ - unsigned int rtype; - - /* Is this against read-only section? */ - unsigned int reltext : 1; - - /* How many did we find? */ - unsigned long count; - } *reloc_entries; + struct alpha_elf_reloc_entry *reloc_entries; }; /* Alpha ELF linker hash table. */ @@ -184,6 +192,10 @@ struct alpha_elf_link_hash_table /* The head of a list of .got subsections linked through alpha_elf_tdata(abfd)->got_link_next. */ bfd *got_list; + + /* The most recent relax pass that we've seen. The GOTs + should be regenerated if this doesn't match. */ + int relax_trip; }; /* Look up an entry in a Alpha ELF linker hash table. */ @@ -204,7 +216,8 @@ struct alpha_elf_link_hash_table /* Get the Alpha ELF linker hash table from a link_info structure. */ #define alpha_elf_hash_table(p) \ - ((struct alpha_elf_link_hash_table *) ((p)->hash)) + (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \ + == ALPHA_ELF_DATA ? ((struct alpha_elf_link_hash_table *) ((p)->hash)) : NULL) /* Get the object's symbols as our own entry type. */ @@ -275,7 +288,8 @@ elf64_alpha_bfd_link_hash_table_create (bfd *abfd) if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, elf64_alpha_link_hash_newfunc, - sizeof (struct alpha_elf_link_hash_entry))) + sizeof (struct alpha_elf_link_hash_entry), + ALPHA_ELF_DATA)) { free (ret); return NULL; @@ -318,14 +332,16 @@ struct alpha_elf_obj_tdata #define alpha_elf_tdata(abfd) \ ((struct alpha_elf_obj_tdata *) (abfd)->tdata.any) +#define is_alpha_elf(bfd) \ + (bfd_get_flavour (bfd) == bfd_target_elf_flavour \ + && elf_tdata (bfd) != NULL \ + && elf_object_id (bfd) == ALPHA_ELF_DATA) + static bfd_boolean elf64_alpha_mkobject (bfd *abfd) { - bfd_size_type amt = sizeof (struct alpha_elf_obj_tdata); - abfd->tdata.any = bfd_zalloc (abfd, amt); - if (abfd->tdata.any == NULL) - return FALSE; - return TRUE; + return bfd_elf_allocate_object (abfd, sizeof (struct alpha_elf_obj_tdata), + ALPHA_ELF_DATA); } static bfd_boolean @@ -450,8 +466,9 @@ elf64_alpha_reloc_gpdisp (bfd *abfd, arelent *reloc_entry, from smaller values. Start with zero, widen, *then* decrement. */ #define MINUS_ONE (((bfd_vma)0) - 1) + #define SKIP_HOWTO(N) \ - HOWTO(N, 0, 0, 0, 0, 0, 0, elf64_alpha_reloc_bad, 0, 0, 0, 0, 0) + HOWTO(N, 0, 0, 0, 0, 0, complain_overflow_dont, elf64_alpha_reloc_bad, 0, 0, 0, 0, 0) static reloc_howto_type elf64_alpha_howto_table[] = { @@ -477,7 +494,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "REFLONG", /* name */ FALSE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -492,7 +509,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "REFQUAD", /* name */ FALSE, /* partial_inplace */ MINUS_ONE, /* src_mask */ @@ -509,7 +526,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "GPREL32", /* name */ FALSE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -524,7 +541,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "ELF_LITERAL", /* name */ FALSE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -590,7 +607,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "BRADDR", /* name */ FALSE, /* partial_inplace */ 0x1fffff, /* src_mask */ @@ -605,7 +622,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "HINT", /* name */ FALSE, /* partial_inplace */ 0x3fff, /* src_mask */ @@ -620,7 +637,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "SREL16", /* name */ FALSE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -635,7 +652,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "SREL32", /* name */ FALSE, /* partial_inplace */ 0xffffffff, /* src_mask */ @@ -650,7 +667,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "SREL64", /* name */ FALSE, /* partial_inplace */ MINUS_ONE, /* src_mask */ @@ -672,7 +689,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "GPRELHIGH", /* name */ FALSE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -687,7 +704,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "GPRELLOW", /* name */ FALSE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -702,7 +719,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "GPREL16", /* name */ FALSE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -788,7 +805,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = TRUE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "BRSGP", /* name */ FALSE, /* partial_inplace */ 0x1fffff, /* src_mask */ @@ -803,7 +820,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "TLSGD", /* name */ FALSE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -818,7 +835,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "TLSLDM", /* name */ FALSE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -833,7 +850,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "DTPMOD64", /* name */ FALSE, /* partial_inplace */ MINUS_ONE, /* src_mask */ @@ -849,7 +866,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "GOTDTPREL", /* name */ FALSE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -864,7 +881,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "DTPREL64", /* name */ FALSE, /* partial_inplace */ MINUS_ONE, /* src_mask */ @@ -879,7 +896,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "DTPRELHI", /* name */ FALSE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -894,7 +911,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "DTPRELLO", /* name */ FALSE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -909,7 +926,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "DTPREL16", /* name */ FALSE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -925,7 +942,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "GOTTPREL", /* name */ FALSE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -940,7 +957,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "TPREL64", /* name */ FALSE, /* partial_inplace */ MINUS_ONE, /* src_mask */ @@ -955,7 +972,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "TPRELHI", /* name */ FALSE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -970,7 +987,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "TPRELLO", /* name */ FALSE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -985,7 +1002,7 @@ static reloc_howto_type elf64_alpha_howto_table[] = FALSE, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - 0, /* special_function */ + bfd_elf_generic_reloc, /* special_function */ "TPREL16", /* name */ FALSE, /* partial_inplace */ 0xffff, /* src_mask */ @@ -1052,6 +1069,23 @@ elf64_alpha_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, return 0; } +static reloc_howto_type * +elf64_alpha_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, + const char *r_name) +{ + unsigned int i; + + for (i = 0; + i < (sizeof (elf64_alpha_howto_table) + / sizeof (elf64_alpha_howto_table[0])); + i++) + if (elf64_alpha_howto_table[i].name != NULL + && strcasecmp (elf64_alpha_howto_table[i].name, r_name) == 0) + return &elf64_alpha_howto_table[i]; + + return NULL; +} + /* Given an Alpha ELF reloc type, fill in an arelent structure. */ static void @@ -1208,6 +1242,9 @@ elf64_alpha_create_got_section (bfd *abfd, flagword flags; asection *s; + if (! is_alpha_elf (abfd)) + return FALSE; + flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED); s = bfd_make_section_anyway_with_flags (abfd, ".got", flags); @@ -1234,6 +1271,9 @@ elf64_alpha_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) flagword flags; struct elf_link_hash_entry *h; + if (! is_alpha_elf (abfd)) + return FALSE; + /* We need to create .plt, .rela.plt, .got, and .rela.got sections. */ flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_IN_MEMORY @@ -1717,7 +1757,6 @@ elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info, { bfd *dynobj; asection *sreloc; - const char *rel_sec_name; Elf_Internal_Shdr *symtab_hdr; struct alpha_elf_link_hash_entry **sym_hashes; const Elf_Internal_Rela *rel, *relend; @@ -1735,14 +1774,15 @@ elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info, if ((sec->flags & SEC_ALLOC) == 0) return TRUE; - dynobj = elf_hash_table(info)->dynobj; + BFD_ASSERT (is_alpha_elf (abfd)); + + dynobj = elf_hash_table (info)->dynobj; if (dynobj == NULL) - elf_hash_table(info)->dynobj = dynobj = abfd; + elf_hash_table (info)->dynobj = dynobj = abfd; sreloc = NULL; - rel_sec_name = NULL; - symtab_hdr = &elf_tdata(abfd)->symtab_hdr; - sym_hashes = alpha_elf_sym_hashes(abfd); + symtab_hdr = &elf_symtab_hdr (abfd); + sym_hashes = alpha_elf_sym_hashes (abfd); relend = relocs + sec->reloc_count; for (rel = relocs; rel < relend; ++rel) @@ -1826,8 +1866,8 @@ elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_ALPHA_TLSLDM: /* The symbol for a TLSLDM reloc is ignored. Collapse the - reloc to the 0 symbol so that they all match. */ - r_symndx = 0; + reloc to the STN_UNDEF (0) symbol so that they all match. */ + r_symndx = STN_UNDEF; h = 0; maybe_dynamic = FALSE; /* FALLTHRU */ @@ -1890,41 +1930,16 @@ elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info, if (need & NEED_DYNREL) { - if (rel_sec_name == NULL) - { - rel_sec_name = (bfd_elf_string_from_elf_section - (abfd, elf_elfheader(abfd)->e_shstrndx, - elf_section_data(sec)->rel_hdr.sh_name)); - if (rel_sec_name == NULL) - return FALSE; - - BFD_ASSERT (strncmp (rel_sec_name, ".rela", 5) == 0 - && strcmp (bfd_get_section_name (abfd, sec), - rel_sec_name+5) == 0); - } - /* We need to create the section here now whether we eventually use it or not so that it gets mapped to an output section by - the linker. If not used, we'll kill it in - size_dynamic_sections. */ + the linker. If not used, we'll kill it in size_dynamic_sections. */ if (sreloc == NULL) { - sreloc = bfd_get_section_by_name (dynobj, rel_sec_name); + sreloc = _bfd_elf_make_dynamic_reloc_section + (sec, dynobj, 3, abfd, /*rela?*/ TRUE); + if (sreloc == NULL) - { - flagword flags; - - flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY - | SEC_LINKER_CREATED | SEC_READONLY); - if (sec->flags & SEC_ALLOC) - flags |= SEC_ALLOC | SEC_LOAD; - sreloc = bfd_make_section_with_flags (dynobj, - rel_sec_name, - flags); - if (sreloc == NULL - || !bfd_set_section_alignment (dynobj, sreloc, 3)) - return FALSE; - } + return FALSE; } if (h) @@ -2032,6 +2047,19 @@ elf64_alpha_adjust_dynamic_symbol (struct bfd_link_info *info, return TRUE; } +/* Record STO_ALPHA_NOPV and STO_ALPHA_STD_GPLOAD. */ + +static void +elf64_alpha_merge_symbol_attribute (struct elf_link_hash_entry *h, + const Elf_Internal_Sym *isym, + bfd_boolean definition, + bfd_boolean dynamic) +{ + if (!dynamic && definition) + h->other = ((h->other & ELF_ST_VISIBILITY (-1)) + | (isym->st_other & ~ELF_ST_VISIBILITY (-1))); +} + /* Symbol versioning can create new symbols, and make our old symbols indirect to the new ones. Consolidate the got and reloc information in these situations. */ @@ -2296,7 +2324,13 @@ elf64_alpha_calc_got_offsets_for_symbol (struct alpha_elf_link_hash_entry *h, static void elf64_alpha_calc_got_offsets (struct bfd_link_info *info) { - bfd *i, *got_list = alpha_elf_hash_table(info)->got_list; + bfd *i, *got_list; + struct alpha_elf_link_hash_table * htab; + + htab = alpha_elf_hash_table (info); + if (htab == NULL) + return; + got_list = htab->got_list; /* First, zero out the .got sizes, as we may be recalculating the .got after optimizing it. */ @@ -2304,7 +2338,7 @@ elf64_alpha_calc_got_offsets (struct bfd_link_info *info) alpha_elf_tdata(i)->got->size = 0; /* Next, fill in the offsets for all the global entries. */ - alpha_elf_link_hash_traverse (alpha_elf_hash_table (info), + alpha_elf_link_hash_traverse (htab, elf64_alpha_calc_got_offsets_for_symbol, NULL); @@ -2342,9 +2376,12 @@ static bfd_boolean elf64_alpha_size_got_sections (struct bfd_link_info *info) { bfd *i, *got_list, *cur_got_obj = NULL; - int something_changed = 0; + struct alpha_elf_link_hash_table * htab; - got_list = alpha_elf_hash_table (info)->got_list; + htab = alpha_elf_hash_table (info); + if (htab == NULL) + return FALSE; + got_list = htab->got_list; /* On the first time through, pretend we have an existing got list consisting of all of the input files. */ @@ -2352,7 +2389,12 @@ elf64_alpha_size_got_sections (struct bfd_link_info *info) { for (i = info->input_bfds; i ; i = i->link_next) { - bfd *this_got = alpha_elf_tdata (i)->gotobj; + bfd *this_got; + + if (! is_alpha_elf (i)) + continue; + + this_got = alpha_elf_tdata (i)->gotobj; if (this_got == NULL) continue; @@ -2379,13 +2421,13 @@ elf64_alpha_size_got_sections (struct bfd_link_info *info) if (got_list == NULL) return TRUE; - alpha_elf_hash_table (info)->got_list = got_list; - - /* Force got offsets to be recalculated. */ - something_changed = 1; + htab->got_list = got_list; } cur_got_obj = got_list; + if (cur_got_obj == NULL) + return FALSE; + i = alpha_elf_tdata(cur_got_obj)->got_link_next; while (i != NULL) { @@ -2396,8 +2438,6 @@ elf64_alpha_size_got_sections (struct bfd_link_info *info) 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; - - something_changed = 1; } else { @@ -2408,8 +2448,7 @@ elf64_alpha_size_got_sections (struct bfd_link_info *info) /* Once the gots have been merged, fill in the got offsets for everything therein. */ - if (1 || something_changed) - elf64_alpha_calc_got_offsets (info); + elf64_alpha_calc_got_offsets (info); return TRUE; } @@ -2444,28 +2483,34 @@ elf64_alpha_size_plt_section_1 (struct alpha_elf_link_hash_entry *h, PTR data) return TRUE; } -/* Called from relax_section to rebuild the PLT in light of - potential changes in the function's status. */ +/* Called from relax_section to rebuild the PLT in light of potential changes + in the function's status. */ -static bfd_boolean +static void elf64_alpha_size_plt_section (struct bfd_link_info *info) { 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; dynobj = elf_hash_table(info)->dynobj; splt = bfd_get_section_by_name (dynobj, ".plt"); if (splt == NULL) - return TRUE; + return; splt->size = 0; - alpha_elf_link_hash_traverse (alpha_elf_hash_table (info), + alpha_elf_link_hash_traverse (htab, elf64_alpha_size_plt_section_1, splt); /* Every plt entry requires a JMP_SLOT relocation. */ spltrel = bfd_get_section_by_name (dynobj, ".rela.plt"); + entries = 0; if (splt->size) { if (elf64_alpha_use_secureplt) @@ -2473,8 +2518,6 @@ elf64_alpha_size_plt_section (struct bfd_link_info *info) else entries = (splt->size - OLD_PLT_HEADER_SIZE) / OLD_PLT_ENTRY_SIZE; } - else - entries = 0; spltrel->size = entries * sizeof (Elf64_External_Rela); /* When using the secureplt, we need two words somewhere in the data @@ -2485,8 +2528,6 @@ elf64_alpha_size_plt_section (struct bfd_link_info *info) sgotplt = bfd_get_section_by_name (dynobj, ".got.plt"); sgotplt->size = entries ? 16 : 0; } - - return TRUE; } static bfd_boolean @@ -2494,20 +2535,24 @@ elf64_alpha_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) { bfd *i; + struct alpha_elf_link_hash_table * htab; if (info->relocatable) return TRUE; + htab = alpha_elf_hash_table (info); + if (htab == NULL) + return FALSE; + /* First, take care of the indirect symbols created by versioning. */ - alpha_elf_link_hash_traverse (alpha_elf_hash_table (info), - elf64_alpha_merge_ind_symbols, + alpha_elf_link_hash_traverse (htab, elf64_alpha_merge_ind_symbols, NULL); if (!elf64_alpha_size_got_sections (info)) return FALSE; /* Allocate space for all of the .got subsections. */ - i = alpha_elf_hash_table (info)->got_list; + i = htab->got_list; for ( ; i ; i = alpha_elf_tdata(i)->got_link_next) { asection *s = alpha_elf_tdata(i)->got; @@ -2657,18 +2702,23 @@ elf64_alpha_size_rela_got_1 (struct alpha_elf_link_hash_entry *h, /* Set the sizes of the dynamic relocation sections. */ -static bfd_boolean +static void elf64_alpha_size_rela_got_section (struct bfd_link_info *info) { unsigned long entries; bfd *i, *dynobj; asection *srel; + struct alpha_elf_link_hash_table * htab; + + htab = alpha_elf_hash_table (info); + if (htab == NULL) + return; /* Shared libraries often require RELATIVE relocs, and some relocs require attention for the main application as well. */ entries = 0; - for (i = alpha_elf_hash_table(info)->got_list; + for (i = htab->got_list; i ; i = alpha_elf_tdata(i)->got_link_next) { bfd *j; @@ -2696,15 +2746,13 @@ elf64_alpha_size_rela_got_section (struct bfd_link_info *info) if (!srel) { BFD_ASSERT (entries == 0); - return TRUE; + return; } srel->size = sizeof (Elf64_External_Rela) * entries; /* Now do the non-local symbols. */ - alpha_elf_link_hash_traverse (alpha_elf_hash_table (info), + alpha_elf_link_hash_traverse (htab, elf64_alpha_size_rela_got_1, info); - - return TRUE; } /* Set the sizes of the dynamic sections. */ @@ -2716,6 +2764,11 @@ elf64_alpha_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, bfd *dynobj; asection *s; bfd_boolean relplt; + struct alpha_elf_link_hash_table * htab; + + htab = alpha_elf_hash_table (info); + if (htab == NULL) + return FALSE; dynobj = elf_hash_table(info)->dynobj; BFD_ASSERT(dynobj != NULL); @@ -2735,7 +2788,7 @@ elf64_alpha_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, symbols need dynamic relocation entries and which don't. We've collected information in check_relocs that we can now apply to size the dynamic relocation sections. */ - alpha_elf_link_hash_traverse (alpha_elf_hash_table (info), + alpha_elf_link_hash_traverse (htab, elf64_alpha_calc_dynrel_sizes, info); elf64_alpha_size_rela_got_section (info); @@ -2758,7 +2811,7 @@ elf64_alpha_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, of the dynobj section names depend upon the input files. */ name = bfd_get_section_name (dynobj, s); - if (strncmp (name, ".rela", 5) == 0) + if (CONST_STRNEQ (name, ".rela")) { if (s->size != 0) { @@ -2770,7 +2823,7 @@ elf64_alpha_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, s->reloc_count = 0; } } - else if (strncmp (name, ".got", 4) != 0 + else if (! CONST_STRNEQ (name, ".got") && strcmp (name, ".plt") != 0 && strcmp (name, ".dynbss") != 0) { @@ -3062,7 +3115,7 @@ elf64_alpha_relax_opt_call (struct alpha_relax_info *info, bfd_vma symval) /* We've now determined that we can skip an initial gp load. Verify that the call and the target use the same gp. */ - if (info->link_info->hash->creator != info->tsec->owner->xvec + if (info->link_info->output_bfd->xvec != info->tsec->owner->xvec || info->gotobj != alpha_elf_tdata (info->tsec->owner)->gotobj) return 0; @@ -3329,9 +3382,9 @@ elf64_alpha_relax_tls_get_addr (struct alpha_relax_info *info, bfd_vma symval, Elf_Internal_Rela *irel, bfd_boolean is_gd) { bfd_byte *pos[5]; - unsigned int insn; + unsigned int insn, tlsgd_reg; Elf_Internal_Rela *gpdisp, *hint; - bfd_boolean dynamic, use_gottprel, pos1_unusable; + bfd_boolean dynamic, use_gottprel; unsigned long new_symndx; dynamic = alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info); @@ -3372,7 +3425,6 @@ elf64_alpha_relax_tls_get_addr (struct alpha_relax_info *info, bfd_vma symval, pos[2] = info->contents + irel[2].r_offset; pos[3] = info->contents + gpdisp->r_offset; pos[4] = pos[3] + gpdisp->r_addend; - pos1_unusable = FALSE; /* Generally, the positions are not allowed to be out of order, lest the modified insn sequence have different register lifetimes. We can make @@ -3383,8 +3435,6 @@ elf64_alpha_relax_tls_get_addr (struct alpha_relax_info *info, bfd_vma symval, pos[0] = pos[1]; pos[1] = tmp; } - else if (pos[1] < pos[0]) - pos1_unusable = TRUE; if (pos[1] >= pos[2] || pos[2] >= pos[3]) return TRUE; @@ -3441,7 +3491,15 @@ elf64_alpha_relax_tls_get_addr (struct alpha_relax_info *info, bfd_vma symval, as appropriate. */ use_gottprel = FALSE; - new_symndx = is_gd ? ELF64_R_SYM (irel->r_info) : 0; + 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: @@ -3455,7 +3513,7 @@ elf64_alpha_relax_tls_get_addr (struct alpha_relax_info *info, bfd_vma symval, if (disp >= -0x8000 && disp < 0x8000) { - insn = (OP_LDA << 26) | (16 << 21) | (31 << 16); + insn = (OP_LDA << 26) | (tlsgd_reg << 21) | (31 << 16); bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]); bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[1]); @@ -3466,11 +3524,11 @@ elf64_alpha_relax_tls_get_addr (struct alpha_relax_info *info, bfd_vma symval, } else if (disp >= -(bfd_signed_vma) 0x80000000 && disp < (bfd_signed_vma) 0x7fff8000 - && !pos1_unusable) + && pos[0] + 4 == pos[1]) { - insn = (OP_LDAH << 26) | (16 << 21) | (31 << 16); + insn = (OP_LDAH << 26) | (tlsgd_reg << 21) | (31 << 16); bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]); - insn = (OP_LDA << 26) | (16 << 21) | (16 << 16); + insn = (OP_LDA << 26) | (tlsgd_reg << 21) | (tlsgd_reg << 16); bfd_put_32 (info->abfd, (bfd_vma) insn, pos[1]); irel[0].r_offset = pos[0] - info->contents; @@ -3485,7 +3543,7 @@ elf64_alpha_relax_tls_get_addr (struct alpha_relax_info *info, bfd_vma symval, default: use_gottprel = TRUE; - insn = (OP_LDQ << 26) | (16 << 21) | (29 << 16); + insn = (OP_LDQ << 26) | (tlsgd_reg << 21) | (29 << 16); bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]); bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[1]); @@ -3575,8 +3633,13 @@ elf64_alpha_relax_section (bfd *abfd, asection *sec, Elf_Internal_Sym *isymbuf = NULL; struct alpha_elf_got_entry **local_got_entries; struct alpha_relax_info info; + struct alpha_elf_link_hash_table * htab; + + htab = alpha_elf_hash_table (link_info); + if (htab == NULL) + return FALSE; - /* We are not currently changing any sizes, so only one pass. */ + /* There's nothing to change, yet. */ *again = FALSE; if (link_info->relocatable @@ -3585,7 +3648,25 @@ elf64_alpha_relax_section (bfd *abfd, asection *sec, || sec->reloc_count == 0) return TRUE; - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + BFD_ASSERT (is_alpha_elf (abfd)); + + /* 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)) + abort (); + if (elf_hash_table (link_info)->dynamic_sections_created) + { + elf64_alpha_size_plt_section (link_info); + elf64_alpha_size_rela_got_section (link_info); + } + } + + symtab_hdr = &elf_symtab_hdr (abfd); local_got_entries = alpha_elf_tdata(abfd)->local_got_entries; /* Load the relocations for this section. */ @@ -3643,8 +3724,8 @@ elf64_alpha_relax_section (bfd *abfd, asection *sec, case R_ALPHA_TLSLDM: /* The symbol for a TLSLDM reloc is ignored. Collapse the - reloc to the 0 symbol so that they all match. */ - r_symndx = 0; + reloc to the STN_UNDEF (0) symbol so that they all match. */ + r_symndx = STN_UNDEF; break; default: @@ -3794,13 +3875,6 @@ elf64_alpha_relax_section (bfd *abfd, asection *sec, } } - if (!elf64_alpha_size_plt_section (link_info)) - return FALSE; - if (!elf64_alpha_size_got_sections (link_info)) - return FALSE; - if (!elf64_alpha_size_rela_got_section (link_info)) - return FALSE; - if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf) { @@ -3896,9 +3970,11 @@ elf64_alpha_relocate_section_r (bfd *output_bfd ATTRIBUTE_UNUSED, unsigned long symtab_hdr_sh_info; Elf_Internal_Rela *rel; Elf_Internal_Rela *relend; + struct elf_link_hash_entry **sym_hashes; bfd_boolean ret_val = TRUE; - symtab_hdr_sh_info = elf_tdata (input_bfd)->symtab_hdr.sh_info; + symtab_hdr_sh_info = elf_symtab_hdr (input_bfd).sh_info; + sym_hashes = elf_sym_hashes (input_bfd); relend = relocs + input_section->reloc_count; for (rel = relocs; rel < relend; rel++) @@ -3908,7 +3984,7 @@ elf64_alpha_relocate_section_r (bfd *output_bfd ATTRIBUTE_UNUSED, asection *sec; unsigned long r_type; - r_type = ELF64_R_TYPE(rel->r_info); + r_type = ELF64_R_TYPE (rel->r_info); if (r_type >= R_ALPHA_max) { (*_bfd_error_handler) @@ -3919,22 +3995,49 @@ elf64_alpha_relocate_section_r (bfd *output_bfd ATTRIBUTE_UNUSED, continue; } - r_symndx = ELF64_R_SYM(rel->r_info); - /* The symbol associated with GPDISP and LITUSE is immaterial. Only the addend is significant. */ if (r_type == R_ALPHA_GPDISP || r_type == R_ALPHA_LITUSE) continue; + r_symndx = ELF64_R_SYM (rel->r_info); if (r_symndx < symtab_hdr_sh_info) { sym = local_syms + r_symndx; - if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) - { - sec = local_sections[r_symndx]; - rel->r_addend += sec->output_offset + sym->st_value; - } + sec = local_sections[r_symndx]; + } + else + { + struct elf_link_hash_entry *h; + + h = sym_hashes[r_symndx - symtab_hdr_sh_info]; + + 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->root.type != bfd_link_hash_defined + && h->root.type != bfd_link_hash_defweak) + continue; + + sym = NULL; + sec = h->root.u.def.section; + } + + if (sec != NULL && elf_discarded_section (sec)) + { + /* For relocs against symbols from removed linkonce sections, + or sections discarded by a linker script, we just want the + section contents zeroed. */ + _bfd_clear_contents (elf64_alpha_howto_table + r_type, + input_bfd, contents + rel->r_offset); + rel->r_info = 0; + rel->r_addend = 0; + continue; } + + if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION) + rel->r_addend += sec->output_offset; } return ret_val; @@ -3958,6 +4061,8 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, struct alpha_elf_got_entry **local_got_entries; bfd_boolean ret_val; + BFD_ASSERT (is_alpha_elf (input_bfd)); + /* Handle relocatable links with a smaller loop. */ if (info->relocatable) return elf64_alpha_relocate_section_r (output_bfd, info, input_bfd, @@ -3968,7 +4073,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, ret_val = TRUE; - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; + symtab_hdr = &elf_symtab_hdr (input_bfd); dynobj = elf_hash_table (info)->dynobj; if (dynobj) @@ -4049,9 +4154,9 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, r_symndx = ELF64_R_SYM(rel->r_info); /* The symbol for a TLSLDM reloc is ignored. Collapse the - reloc to the 0 symbol so that they all match. */ + reloc to the STN_UNDEF (0) symbol so that they all match. */ if (r_type == R_ALPHA_TLSLDM) - r_symndx = 0; + r_symndx = STN_UNDEF; if (r_symndx < symtab_hdr->sh_info) { @@ -4061,10 +4166,10 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, msec = sec; value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel); - /* If this is a tp-relative relocation against sym 0, + /* If this is a tp-relative relocation against sym STN_UNDEF (0), this is hackery from relax_section. Force the value to be the tls module base. */ - if (r_symndx == 0 + if (r_symndx == STN_UNDEF && (r_type == R_ALPHA_TLSLDM || r_type == R_ALPHA_GOTTPREL || r_type == R_ALPHA_TPREL64 @@ -4134,6 +4239,17 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, gotent = h->got_entries; } + if (sec != NULL && elf_discarded_section (sec)) + { + /* For relocs against symbols from removed linkonce sections, + or sections discarded by a linker script, we just want the + section contents zeroed. Avoid any special processing. */ + _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset); + rel->r_info = 0; + rel->r_addend = 0; + continue; + } + addend = rel->r_addend; value += addend; @@ -4193,18 +4309,6 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, goto default_reloc; 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) @@ -4351,7 +4455,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, dynaddend = value - dtp_base; } else if (info->shared - && r_symndx != 0 + && r_symndx != STN_UNDEF && (input_section->flags & SEC_ALLOC) && !undef_weak_ref) { @@ -4399,7 +4503,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, /* ??? .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 == 0) + if (r_symndx == STN_UNDEF) howto = (elf64_alpha_howto_table + (r_type - R_ALPHA_SREL32 + R_ALPHA_REFLONG)); goto default_reloc; @@ -4870,7 +4974,12 @@ elf64_alpha_final_link (bfd *abfd, struct bfd_link_info *info) const struct ecoff_debug_swap *swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; HDRR *symhdr = &debug.symbolic_header; - PTR mdebug_handle = NULL; + void * mdebug_handle = NULL; + struct alpha_elf_link_hash_table * htab; + + htab = alpha_elf_hash_table (info); + if (htab == NULL) + return FALSE; /* Go through the sections and collect the mdebug information. */ mdebug_sec = NULL; @@ -4979,15 +5088,11 @@ elf64_alpha_final_link (bfd *abfd, struct bfd_link_info *info) input_section = p->u.indirect.section; input_bfd = input_section->owner; - if (bfd_get_flavour (input_bfd) != bfd_target_elf_flavour - || (get_elf_backend_data (input_bfd) - ->elf_backend_ecoff_debug_swap) == NULL) - { - /* I don't know what a non ALPHA ELF bfd would be - doing with a .mdebug section, but I don't really - want to deal with it. */ - continue; - } + if (! is_alpha_elf (input_bfd)) + /* I don't know what a non ALPHA ELF bfd would be + doing with a .mdebug section, but I don't really + want to deal with it. */ + continue; input_swap = (get_elf_backend_data (input_bfd) ->elf_backend_ecoff_debug_swap); @@ -5010,7 +5115,7 @@ elf64_alpha_final_link (bfd *abfd, struct bfd_link_info *info) interesting information, try to find the symbol in the linker global hash table and save the information for the output external symbols. */ - eraw_src = input_debug.external_ext; + eraw_src = (char *) input_debug.external_ext; eraw_end = (eraw_src + (input_debug.symbolic_header.iextMax * input_swap->external_ext_size)); @@ -5029,8 +5134,7 @@ elf64_alpha_final_link (bfd *abfd, struct bfd_link_info *info) continue; name = input_debug.ssext + ext.asym.iss; - h = alpha_elf_link_hash_lookup (alpha_elf_hash_table (info), - name, FALSE, FALSE, TRUE); + h = alpha_elf_link_hash_lookup (htab, name, FALSE, FALSE, TRUE); if (h == NULL || h->esym.ifd != -2) continue; @@ -5094,7 +5198,7 @@ elf64_alpha_final_link (bfd *abfd, struct bfd_link_info *info) /* The .got subsections... */ { bfd *i, *dynobj = elf_hash_table(info)->dynobj; - for (i = alpha_elf_hash_table(info)->got_list; + for (i = htab->got_list; i != NULL; i = alpha_elf_tdata(i)->got_link_next) { @@ -5145,9 +5249,9 @@ elf64_alpha_reloc_type_class (const Elf_Internal_Rela *rela) static const struct bfd_elf_special_section elf64_alpha_special_sections[] = { - { ".sbss", 5, -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_ALPHA_GPREL }, - { ".sdata", 6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_ALPHA_GPREL }, - { NULL, 0, 0, 0, 0 } + { STRING_COMMA_LEN (".sbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_ALPHA_GPREL }, + { STRING_COMMA_LEN (".sdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_ALPHA_GPREL }, + { NULL, 0, 0, 0, 0 } }; /* ECOFF swapping routines. These are used when dealing with the @@ -5213,6 +5317,7 @@ static const struct elf_size_info alpha_elf_size_info = ELFCLASS64, EV_CURRENT, bfd_elf64_write_out_phdrs, bfd_elf64_write_shdrs_and_ehdr, + bfd_elf64_checksum_contents, bfd_elf64_write_relocs, bfd_elf64_swap_symbol_in, bfd_elf64_swap_symbol_out, @@ -5229,14 +5334,18 @@ static const struct elf_size_info alpha_elf_size_info = #define TARGET_LITTLE_SYM bfd_elf64_alpha_vec #define TARGET_LITTLE_NAME "elf64-alpha" #define ELF_ARCH bfd_arch_alpha +#define ELF_TARGET_ID ALPHA_ELF_DATA #define ELF_MACHINE_CODE EM_ALPHA #define ELF_MAXPAGESIZE 0x10000 +#define ELF_COMMONPAGESIZE 0x2000 #define bfd_elf64_bfd_link_hash_table_create \ elf64_alpha_bfd_link_hash_table_create #define bfd_elf64_bfd_reloc_type_lookup \ elf64_alpha_bfd_reloc_type_lookup +#define bfd_elf64_bfd_reloc_name_lookup \ + elf64_alpha_bfd_reloc_name_lookup #define elf_info_to_howto \ elf64_alpha_info_to_howto @@ -5261,16 +5370,22 @@ static const struct elf_size_info alpha_elf_size_info = #define elf_backend_add_symbol_hook \ elf64_alpha_add_symbol_hook +#define elf_backend_relocs_compatible \ + _bfd_elf_relocs_compatible #define elf_backend_check_relocs \ elf64_alpha_check_relocs #define elf_backend_create_dynamic_sections \ elf64_alpha_create_dynamic_sections #define elf_backend_adjust_dynamic_symbol \ elf64_alpha_adjust_dynamic_symbol +#define elf_backend_merge_symbol_attribute \ + elf64_alpha_merge_symbol_attribute #define elf_backend_always_size_sections \ elf64_alpha_always_size_sections #define elf_backend_size_dynamic_sections \ elf64_alpha_size_dynamic_sections +#define elf_backend_omit_section_dynsym \ + ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) #define elf_backend_relocate_section \ elf64_alpha_relocate_section #define elf_backend_finish_dynamic_symbol \ @@ -5305,6 +5420,8 @@ static const struct elf_size_info alpha_elf_size_info = #define TARGET_LITTLE_SYM bfd_elf64_alpha_freebsd_vec #undef TARGET_LITTLE_NAME #define TARGET_LITTLE_NAME "elf64-alpha-freebsd" +#undef ELF_OSABI +#define ELF_OSABI ELFOSABI_FREEBSD /* The kernel recognizes executables as valid only if they carry a "FreeBSD" label in the ELF header. So we put this label on all @@ -5319,7 +5436,7 @@ elf64_alpha_fbsd_post_process_headers (bfd * abfd, i_ehdrp = elf_elfheader (abfd); /* Put an ABI label supported by FreeBSD >= 4.1. */ - i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD; + i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi; #ifdef OLD_FREEBSD_ABI_LABEL /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard. */ memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8);