elf64-alpha.c revision 60510
133965Sjdp/* Alpha specific support for 64-bit ELF 260510Sobrien Copyright 1996, 97, 98, 1999 Free Software Foundation, Inc. 333965Sjdp Contributed by Richard Henderson <rth@tamu.edu>. 433965Sjdp 533965SjdpThis file is part of BFD, the Binary File Descriptor library. 633965Sjdp 733965SjdpThis program is free software; you can redistribute it and/or modify 833965Sjdpit under the terms of the GNU General Public License as published by 933965Sjdpthe Free Software Foundation; either version 2 of the License, or 1033965Sjdp(at your option) any later version. 1133965Sjdp 1233965SjdpThis program is distributed in the hope that it will be useful, 1333965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 1433965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1533965SjdpGNU General Public License for more details. 1633965Sjdp 1733965SjdpYou should have received a copy of the GNU General Public License 1833965Sjdpalong with this program; if not, write to the Free Software 1933965SjdpFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 2033965Sjdp 2157406Sjdp/* $FreeBSD: head/contrib/binutils/bfd/elf64-alpha.c 60510 2000-05-13 16:46:57Z obrien $ */ 2257406Sjdp 2333965Sjdp/* We need a published ABI spec for this. Until one comes out, don't 2433965Sjdp assume this'll remain unchanged forever. */ 2533965Sjdp 2633965Sjdp#include "bfd.h" 2733965Sjdp#include "sysdep.h" 2833965Sjdp#include "libbfd.h" 2933965Sjdp#include "elf-bfd.h" 3033965Sjdp 3133965Sjdp#include "elf/alpha.h" 3233965Sjdp 3333965Sjdp#define ALPHAECOFF 3433965Sjdp 3533965Sjdp#define NO_COFF_RELOCS 3633965Sjdp#define NO_COFF_SYMBOLS 3733965Sjdp#define NO_COFF_LINENOS 3833965Sjdp 3933965Sjdp/* Get the ECOFF swapping routines. Needed for the debug information. */ 4033965Sjdp#include "coff/internal.h" 4133965Sjdp#include "coff/sym.h" 4233965Sjdp#include "coff/symconst.h" 4333965Sjdp#include "coff/ecoff.h" 4433965Sjdp#include "coff/alpha.h" 4533965Sjdp#include "aout/ar.h" 4633965Sjdp#include "libcoff.h" 4733965Sjdp#include "libecoff.h" 4833965Sjdp#define ECOFF_64 4933965Sjdp#include "ecoffswap.h" 5033965Sjdp 5133965Sjdpstatic boolean elf64_alpha_mkobject PARAMS ((bfd *)); 5233965Sjdpstatic struct bfd_hash_entry * elf64_alpha_link_hash_newfunc 5333965Sjdp PARAMS((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); 5433965Sjdpstatic struct bfd_link_hash_table * elf64_alpha_bfd_link_hash_table_create 5533965Sjdp PARAMS((bfd *)); 5633965Sjdp 5733965Sjdpstatic bfd_reloc_status_type elf64_alpha_reloc_nil 5833965Sjdp PARAMS((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); 5933965Sjdpstatic bfd_reloc_status_type elf64_alpha_reloc_bad 6033965Sjdp PARAMS((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); 6133965Sjdpstatic bfd_reloc_status_type elf64_alpha_do_reloc_gpdisp 6233965Sjdp PARAMS((bfd *, bfd_vma, bfd_byte *, bfd_byte *)); 6333965Sjdpstatic bfd_reloc_status_type elf64_alpha_reloc_gpdisp 6433965Sjdp PARAMS((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); 6533965Sjdp 6633965Sjdpstatic reloc_howto_type * elf64_alpha_bfd_reloc_type_lookup 6733965Sjdp PARAMS((bfd *, bfd_reloc_code_real_type)); 6833965Sjdpstatic void elf64_alpha_info_to_howto 6933965Sjdp PARAMS((bfd *, arelent *, Elf64_Internal_Rela *)); 7033965Sjdp 7133965Sjdpstatic boolean elf64_alpha_object_p 7233965Sjdp PARAMS((bfd *)); 7333965Sjdpstatic boolean elf64_alpha_section_from_shdr 7433965Sjdp PARAMS((bfd *, Elf64_Internal_Shdr *, char *)); 7533965Sjdpstatic boolean elf64_alpha_fake_sections 7633965Sjdp PARAMS((bfd *, Elf64_Internal_Shdr *, asection *)); 7733965Sjdpstatic boolean elf64_alpha_create_got_section 7833965Sjdp PARAMS((bfd *, struct bfd_link_info *)); 7933965Sjdpstatic boolean elf64_alpha_create_dynamic_sections 8033965Sjdp PARAMS((bfd *, struct bfd_link_info *)); 8133965Sjdp 8233965Sjdpstatic boolean elf64_alpha_read_ecoff_info 8333965Sjdp PARAMS((bfd *, asection *, struct ecoff_debug_info *)); 8433965Sjdpstatic boolean elf64_alpha_is_local_label_name 8533965Sjdp PARAMS((bfd *, const char *)); 8633965Sjdpstatic boolean elf64_alpha_find_nearest_line 8733965Sjdp PARAMS((bfd *, asection *, asymbol **, bfd_vma, const char **, 8833965Sjdp const char **, unsigned int *)); 8933965Sjdp 9033965Sjdp#if defined(__STDC__) || defined(ALMOST_STDC) 9133965Sjdpstruct alpha_elf_link_hash_entry; 9233965Sjdp#endif 9333965Sjdp 9433965Sjdpstatic boolean elf64_alpha_output_extsym 9533965Sjdp PARAMS((struct alpha_elf_link_hash_entry *, PTR)); 9633965Sjdp 9733965Sjdpstatic boolean elf64_alpha_can_merge_gots 9833965Sjdp PARAMS((bfd *, bfd *)); 9933965Sjdpstatic void elf64_alpha_merge_gots 10033965Sjdp PARAMS((bfd *, bfd *)); 10133965Sjdpstatic boolean elf64_alpha_calc_got_offsets_for_symbol 10233965Sjdp PARAMS ((struct alpha_elf_link_hash_entry *, PTR)); 10333965Sjdpstatic void elf64_alpha_calc_got_offsets PARAMS ((struct bfd_link_info *)); 10460510Sobrienstatic boolean elf64_alpha_size_got_sections 10560510Sobrien PARAMS ((bfd *, struct bfd_link_info *)); 10633965Sjdpstatic boolean elf64_alpha_always_size_sections 10733965Sjdp PARAMS ((bfd *, struct bfd_link_info *)); 10833965Sjdpstatic boolean elf64_alpha_calc_dynrel_sizes 10933965Sjdp PARAMS ((struct alpha_elf_link_hash_entry *, struct bfd_link_info *)); 11060510Sobrienstatic boolean elf64_alpha_add_symbol_hook 11160510Sobrien PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *, 11260510Sobrien const char **, flagword *, asection **, bfd_vma *)); 11333965Sjdpstatic boolean elf64_alpha_check_relocs 11433965Sjdp PARAMS((bfd *, struct bfd_link_info *, asection *sec, 11533965Sjdp const Elf_Internal_Rela *)); 11633965Sjdpstatic boolean elf64_alpha_adjust_dynamic_symbol 11733965Sjdp PARAMS((struct bfd_link_info *, struct elf_link_hash_entry *)); 11833965Sjdpstatic boolean elf64_alpha_size_dynamic_sections 11933965Sjdp PARAMS((bfd *, struct bfd_link_info *)); 12033965Sjdpstatic boolean elf64_alpha_relocate_section 12133965Sjdp PARAMS((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, 12233965Sjdp Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); 12333965Sjdpstatic boolean elf64_alpha_finish_dynamic_symbol 12433965Sjdp PARAMS((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, 12533965Sjdp Elf_Internal_Sym *)); 12633965Sjdpstatic boolean elf64_alpha_finish_dynamic_sections 12733965Sjdp PARAMS((bfd *, struct bfd_link_info *)); 12833965Sjdpstatic boolean elf64_alpha_final_link 12933965Sjdp PARAMS((bfd *, struct bfd_link_info *)); 13048850Sdfrstatic boolean elf64_alpha_merge_ind_symbols 13148850Sdfr PARAMS((struct alpha_elf_link_hash_entry *, PTR)); 13260510Sobrienstatic Elf_Internal_Rela * elf64_alpha_find_reloc_at_ofs 13360510Sobrien PARAMS ((Elf_Internal_Rela *, Elf_Internal_Rela *, bfd_vma, int)); 13433965Sjdp 13533965Sjdp 13633965Sjdpstruct alpha_elf_link_hash_entry 13733965Sjdp{ 13833965Sjdp struct elf_link_hash_entry root; 13933965Sjdp 14033965Sjdp /* External symbol information. */ 14133965Sjdp EXTR esym; 14233965Sjdp 14333965Sjdp /* Cumulative flags for all the .got entries. */ 14433965Sjdp int flags; 14533965Sjdp 14633965Sjdp /* Contexts (LITUSE) in which a literal was referenced. */ 14733965Sjdp#define ALPHA_ELF_LINK_HASH_LU_ADDR 0x01 14833965Sjdp#define ALPHA_ELF_LINK_HASH_LU_MEM 0x02 14933965Sjdp#define ALPHA_ELF_LINK_HASH_LU_BYTE 0x04 15033965Sjdp#define ALPHA_ELF_LINK_HASH_LU_FUNC 0x08 15133965Sjdp 15233965Sjdp /* Used to implement multiple .got subsections. */ 15333965Sjdp struct alpha_elf_got_entry 15433965Sjdp { 15533965Sjdp struct alpha_elf_got_entry *next; 15633965Sjdp 15733965Sjdp /* which .got subsection? */ 15833965Sjdp bfd *gotobj; 15933965Sjdp 16033965Sjdp /* the addend in effect for this entry. */ 16133965Sjdp bfd_vma addend; 16233965Sjdp 16333965Sjdp /* the .got offset for this entry. */ 16433965Sjdp int got_offset; 16533965Sjdp 16633965Sjdp int flags; 16733965Sjdp 16833965Sjdp /* An additional flag. */ 16933965Sjdp#define ALPHA_ELF_GOT_ENTRY_RELOCS_DONE 0x10 17060510Sobrien 17160510Sobrien int use_count; 17233965Sjdp } *got_entries; 17333965Sjdp 17433965Sjdp /* used to count non-got, non-plt relocations for delayed sizing 17533965Sjdp of relocation sections. */ 17633965Sjdp struct alpha_elf_reloc_entry 17733965Sjdp { 17833965Sjdp struct alpha_elf_reloc_entry *next; 17933965Sjdp 18033965Sjdp /* which .reloc section? */ 18133965Sjdp asection *srel; 18233965Sjdp 18333965Sjdp /* what kind of relocation? */ 18433965Sjdp unsigned long rtype; 18533965Sjdp 18633965Sjdp /* how many did we find? */ 18733965Sjdp unsigned long count; 18833965Sjdp } *reloc_entries; 18933965Sjdp}; 19033965Sjdp 19133965Sjdp/* Alpha ELF linker hash table. */ 19233965Sjdp 19333965Sjdpstruct alpha_elf_link_hash_table 19433965Sjdp{ 19533965Sjdp struct elf_link_hash_table root; 19633965Sjdp 19733965Sjdp /* The head of a list of .got subsections linked through 19833965Sjdp alpha_elf_tdata(abfd)->got_link_next. */ 19933965Sjdp bfd *got_list; 20033965Sjdp}; 20133965Sjdp 20233965Sjdp/* Look up an entry in a Alpha ELF linker hash table. */ 20333965Sjdp 20433965Sjdp#define alpha_elf_link_hash_lookup(table, string, create, copy, follow) \ 20533965Sjdp ((struct alpha_elf_link_hash_entry *) \ 20633965Sjdp elf_link_hash_lookup (&(table)->root, (string), (create), \ 20733965Sjdp (copy), (follow))) 20833965Sjdp 20933965Sjdp/* Traverse a Alpha ELF linker hash table. */ 21033965Sjdp 21133965Sjdp#define alpha_elf_link_hash_traverse(table, func, info) \ 21233965Sjdp (elf_link_hash_traverse \ 21333965Sjdp (&(table)->root, \ 21433965Sjdp (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \ 21533965Sjdp (info))) 21633965Sjdp 21733965Sjdp/* Get the Alpha ELF linker hash table from a link_info structure. */ 21833965Sjdp 21933965Sjdp#define alpha_elf_hash_table(p) \ 22033965Sjdp ((struct alpha_elf_link_hash_table *) ((p)->hash)) 22133965Sjdp 22233965Sjdp/* Get the object's symbols as our own entry type. */ 22333965Sjdp 22433965Sjdp#define alpha_elf_sym_hashes(abfd) \ 22533965Sjdp ((struct alpha_elf_link_hash_entry **)elf_sym_hashes(abfd)) 22633965Sjdp 22733965Sjdp/* Should we do dynamic things to this symbol? */ 22833965Sjdp 22933965Sjdp#define alpha_elf_dynamic_symbol_p(h, info) \ 23060510Sobrien ((((info)->shared && !(info)->symbolic) \ 23160510Sobrien || (((h)->elf_link_hash_flags \ 23260510Sobrien & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)) \ 23360510Sobrien == (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)) \ 23460510Sobrien || (h)->root.type == bfd_link_hash_undefweak \ 23560510Sobrien || (h)->root.type == bfd_link_hash_defweak) \ 23660510Sobrien && (h)->dynindx != -1) 23733965Sjdp 23833965Sjdp/* Create an entry in a Alpha ELF linker hash table. */ 23933965Sjdp 24033965Sjdpstatic struct bfd_hash_entry * 24133965Sjdpelf64_alpha_link_hash_newfunc (entry, table, string) 24233965Sjdp struct bfd_hash_entry *entry; 24333965Sjdp struct bfd_hash_table *table; 24433965Sjdp const char *string; 24533965Sjdp{ 24633965Sjdp struct alpha_elf_link_hash_entry *ret = 24733965Sjdp (struct alpha_elf_link_hash_entry *) entry; 24833965Sjdp 24933965Sjdp /* Allocate the structure if it has not already been allocated by a 25033965Sjdp subclass. */ 25133965Sjdp if (ret == (struct alpha_elf_link_hash_entry *) NULL) 25233965Sjdp ret = ((struct alpha_elf_link_hash_entry *) 25333965Sjdp bfd_hash_allocate (table, 25433965Sjdp sizeof (struct alpha_elf_link_hash_entry))); 25533965Sjdp if (ret == (struct alpha_elf_link_hash_entry *) NULL) 25633965Sjdp return (struct bfd_hash_entry *) ret; 25733965Sjdp 25833965Sjdp /* Call the allocation method of the superclass. */ 25933965Sjdp ret = ((struct alpha_elf_link_hash_entry *) 26033965Sjdp _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, 26133965Sjdp table, string)); 26233965Sjdp if (ret != (struct alpha_elf_link_hash_entry *) NULL) 26333965Sjdp { 26433965Sjdp /* Set local fields. */ 26533965Sjdp memset (&ret->esym, 0, sizeof (EXTR)); 26633965Sjdp /* We use -2 as a marker to indicate that the information has 26733965Sjdp not been set. -1 means there is no associated ifd. */ 26833965Sjdp ret->esym.ifd = -2; 26933965Sjdp ret->flags = 0; 27033965Sjdp ret->got_entries = NULL; 27133965Sjdp ret->reloc_entries = NULL; 27233965Sjdp } 27333965Sjdp 27433965Sjdp return (struct bfd_hash_entry *) ret; 27533965Sjdp} 27633965Sjdp 27733965Sjdp/* Create a Alpha ELF linker hash table. */ 27833965Sjdp 27933965Sjdpstatic struct bfd_link_hash_table * 28033965Sjdpelf64_alpha_bfd_link_hash_table_create (abfd) 28133965Sjdp bfd *abfd; 28233965Sjdp{ 28333965Sjdp struct alpha_elf_link_hash_table *ret; 28433965Sjdp 28533965Sjdp ret = ((struct alpha_elf_link_hash_table *) 28633965Sjdp bfd_zalloc (abfd, sizeof (struct alpha_elf_link_hash_table))); 28733965Sjdp if (ret == (struct alpha_elf_link_hash_table *) NULL) 28833965Sjdp return NULL; 28933965Sjdp 29033965Sjdp if (! _bfd_elf_link_hash_table_init (&ret->root, abfd, 29133965Sjdp elf64_alpha_link_hash_newfunc)) 29233965Sjdp { 29333965Sjdp bfd_release (abfd, ret); 29433965Sjdp return NULL; 29533965Sjdp } 29633965Sjdp 29733965Sjdp return &ret->root.root; 29833965Sjdp} 29933965Sjdp 30033965Sjdp/* We have some private fields hanging off of the elf_tdata structure. */ 30133965Sjdp 30233965Sjdpstruct alpha_elf_obj_tdata 30333965Sjdp{ 30433965Sjdp struct elf_obj_tdata root; 30533965Sjdp 30633965Sjdp /* For every input file, these are the got entries for that object's 30733965Sjdp local symbols. */ 30833965Sjdp struct alpha_elf_got_entry ** local_got_entries; 30933965Sjdp 31033965Sjdp /* For every input file, this is the object that owns the got that 31133965Sjdp this input file uses. */ 31233965Sjdp bfd *gotobj; 31333965Sjdp 31433965Sjdp /* For every got, this is a linked list through the objects using this got */ 31533965Sjdp bfd *in_got_link_next; 31633965Sjdp 31733965Sjdp /* For every got, this is a link to the next got subsegment. */ 31833965Sjdp bfd *got_link_next; 31933965Sjdp 32033965Sjdp /* For every got, this is the section. */ 32133965Sjdp asection *got; 32233965Sjdp 32333965Sjdp /* For every got, this is it's total number of *entries*. */ 32433965Sjdp int total_got_entries; 32533965Sjdp 32633965Sjdp /* For every got, this is the sum of the number of *entries* required 32733965Sjdp to hold all of the member object's local got. */ 32833965Sjdp int n_local_got_entries; 32933965Sjdp}; 33033965Sjdp 33133965Sjdp#define alpha_elf_tdata(abfd) \ 33233965Sjdp ((struct alpha_elf_obj_tdata *) (abfd)->tdata.any) 33333965Sjdp 33433965Sjdpstatic boolean 33533965Sjdpelf64_alpha_mkobject (abfd) 33633965Sjdp bfd *abfd; 33733965Sjdp{ 33833965Sjdp abfd->tdata.any = bfd_zalloc (abfd, sizeof (struct alpha_elf_obj_tdata)); 33933965Sjdp if (abfd->tdata.any == NULL) 34033965Sjdp return false; 34133965Sjdp return true; 34233965Sjdp} 34333965Sjdp 34433965Sjdpstatic boolean 34533965Sjdpelf64_alpha_object_p (abfd) 34633965Sjdp bfd *abfd; 34733965Sjdp{ 34833965Sjdp /* Allocate our special target data. */ 34933965Sjdp struct alpha_elf_obj_tdata *new_tdata; 35033965Sjdp new_tdata = bfd_zalloc (abfd, sizeof (struct alpha_elf_obj_tdata)); 35133965Sjdp if (new_tdata == NULL) 35233965Sjdp return false; 35333965Sjdp new_tdata->root = *abfd->tdata.elf_obj_data; 35433965Sjdp abfd->tdata.any = new_tdata; 35533965Sjdp 35633965Sjdp /* Set the right machine number for an Alpha ELF file. */ 35733965Sjdp return bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0); 35833965Sjdp} 35933965Sjdp 36033965Sjdp/* In case we're on a 32-bit machine, construct a 64-bit "-1" value 36133965Sjdp from smaller values. Start with zero, widen, *then* decrement. */ 36233965Sjdp#define MINUS_ONE (((bfd_vma)0) - 1) 36333965Sjdp 36433965Sjdpstatic reloc_howto_type elf64_alpha_howto_table[] = 36533965Sjdp{ 36633965Sjdp HOWTO (R_ALPHA_NONE, /* type */ 36733965Sjdp 0, /* rightshift */ 36833965Sjdp 0, /* size (0 = byte, 1 = short, 2 = long) */ 36933965Sjdp 8, /* bitsize */ 37033965Sjdp true, /* pc_relative */ 37133965Sjdp 0, /* bitpos */ 37233965Sjdp complain_overflow_dont, /* complain_on_overflow */ 37333965Sjdp elf64_alpha_reloc_nil, /* special_function */ 37433965Sjdp "NONE", /* name */ 37533965Sjdp false, /* partial_inplace */ 37633965Sjdp 0, /* src_mask */ 37733965Sjdp 0, /* dst_mask */ 37833965Sjdp true), /* pcrel_offset */ 37933965Sjdp 38033965Sjdp /* A 32 bit reference to a symbol. */ 38133965Sjdp HOWTO (R_ALPHA_REFLONG, /* type */ 38233965Sjdp 0, /* rightshift */ 38333965Sjdp 2, /* size (0 = byte, 1 = short, 2 = long) */ 38433965Sjdp 32, /* bitsize */ 38533965Sjdp false, /* pc_relative */ 38633965Sjdp 0, /* bitpos */ 38733965Sjdp complain_overflow_bitfield, /* complain_on_overflow */ 38833965Sjdp 0, /* special_function */ 38933965Sjdp "REFLONG", /* name */ 39033965Sjdp false, /* partial_inplace */ 39133965Sjdp 0xffffffff, /* src_mask */ 39233965Sjdp 0xffffffff, /* dst_mask */ 39333965Sjdp false), /* pcrel_offset */ 39433965Sjdp 39533965Sjdp /* A 64 bit reference to a symbol. */ 39633965Sjdp HOWTO (R_ALPHA_REFQUAD, /* type */ 39733965Sjdp 0, /* rightshift */ 39833965Sjdp 4, /* size (0 = byte, 1 = short, 2 = long) */ 39933965Sjdp 64, /* bitsize */ 40033965Sjdp false, /* pc_relative */ 40133965Sjdp 0, /* bitpos */ 40233965Sjdp complain_overflow_bitfield, /* complain_on_overflow */ 40333965Sjdp 0, /* special_function */ 40433965Sjdp "REFQUAD", /* name */ 40533965Sjdp false, /* partial_inplace */ 40633965Sjdp MINUS_ONE, /* src_mask */ 40733965Sjdp MINUS_ONE, /* dst_mask */ 40833965Sjdp false), /* pcrel_offset */ 40933965Sjdp 41033965Sjdp /* A 32 bit GP relative offset. This is just like REFLONG except 41133965Sjdp that when the value is used the value of the gp register will be 41233965Sjdp added in. */ 41333965Sjdp HOWTO (R_ALPHA_GPREL32, /* type */ 41433965Sjdp 0, /* rightshift */ 41533965Sjdp 2, /* size (0 = byte, 1 = short, 2 = long) */ 41633965Sjdp 32, /* bitsize */ 41733965Sjdp false, /* pc_relative */ 41833965Sjdp 0, /* bitpos */ 41933965Sjdp complain_overflow_bitfield, /* complain_on_overflow */ 42033965Sjdp 0, /* special_function */ 42133965Sjdp "GPREL32", /* name */ 42233965Sjdp false, /* partial_inplace */ 42333965Sjdp 0xffffffff, /* src_mask */ 42433965Sjdp 0xffffffff, /* dst_mask */ 42533965Sjdp false), /* pcrel_offset */ 42633965Sjdp 42733965Sjdp /* Used for an instruction that refers to memory off the GP register. */ 42833965Sjdp HOWTO (R_ALPHA_LITERAL, /* type */ 42933965Sjdp 0, /* rightshift */ 43033965Sjdp 2, /* size (0 = byte, 1 = short, 2 = long) */ 43133965Sjdp 16, /* bitsize */ 43233965Sjdp false, /* pc_relative */ 43333965Sjdp 0, /* bitpos */ 43433965Sjdp complain_overflow_signed, /* complain_on_overflow */ 43533965Sjdp 0, /* special_function */ 43633965Sjdp "ELF_LITERAL", /* name */ 43733965Sjdp false, /* partial_inplace */ 43833965Sjdp 0xffff, /* src_mask */ 43933965Sjdp 0xffff, /* dst_mask */ 44033965Sjdp false), /* pcrel_offset */ 44133965Sjdp 44233965Sjdp /* This reloc only appears immediately following an ELF_LITERAL reloc. 44333965Sjdp It identifies a use of the literal. The symbol index is special: 44433965Sjdp 1 means the literal address is in the base register of a memory 44533965Sjdp format instruction; 2 means the literal address is in the byte 44633965Sjdp offset register of a byte-manipulation instruction; 3 means the 44733965Sjdp literal address is in the target register of a jsr instruction. 44833965Sjdp This does not actually do any relocation. */ 44933965Sjdp HOWTO (R_ALPHA_LITUSE, /* type */ 45033965Sjdp 0, /* rightshift */ 45133965Sjdp 2, /* size (0 = byte, 1 = short, 2 = long) */ 45233965Sjdp 32, /* bitsize */ 45333965Sjdp false, /* pc_relative */ 45433965Sjdp 0, /* bitpos */ 45533965Sjdp complain_overflow_dont, /* complain_on_overflow */ 45633965Sjdp elf64_alpha_reloc_nil, /* special_function */ 45733965Sjdp "LITUSE", /* name */ 45833965Sjdp false, /* partial_inplace */ 45933965Sjdp 0, /* src_mask */ 46033965Sjdp 0, /* dst_mask */ 46133965Sjdp false), /* pcrel_offset */ 46233965Sjdp 46333965Sjdp /* Load the gp register. This is always used for a ldah instruction 46433965Sjdp which loads the upper 16 bits of the gp register. The symbol 46533965Sjdp index of the GPDISP instruction is an offset in bytes to the lda 46633965Sjdp instruction that loads the lower 16 bits. The value to use for 46733965Sjdp the relocation is the difference between the GP value and the 46833965Sjdp current location; the load will always be done against a register 46933965Sjdp holding the current address. 47033965Sjdp 47133965Sjdp NOTE: Unlike ECOFF, partial in-place relocation is not done. If 47233965Sjdp any offset is present in the instructions, it is an offset from 47333965Sjdp the register to the ldah instruction. This lets us avoid any 47433965Sjdp stupid hackery like inventing a gp value to do partial relocation 47533965Sjdp against. Also unlike ECOFF, we do the whole relocation off of 47633965Sjdp the GPDISP rather than a GPDISP_HI16/GPDISP_LO16 pair. An odd, 47733965Sjdp space consuming bit, that, since all the information was present 47833965Sjdp in the GPDISP_HI16 reloc. */ 47933965Sjdp HOWTO (R_ALPHA_GPDISP, /* type */ 48033965Sjdp 16, /* rightshift */ 48133965Sjdp 2, /* size (0 = byte, 1 = short, 2 = long) */ 48233965Sjdp 16, /* bitsize */ 48333965Sjdp false, /* pc_relative */ 48433965Sjdp 0, /* bitpos */ 48533965Sjdp complain_overflow_dont, /* complain_on_overflow */ 48633965Sjdp elf64_alpha_reloc_gpdisp, /* special_function */ 48733965Sjdp "GPDISP", /* name */ 48833965Sjdp false, /* partial_inplace */ 48933965Sjdp 0xffff, /* src_mask */ 49033965Sjdp 0xffff, /* dst_mask */ 49133965Sjdp true), /* pcrel_offset */ 49233965Sjdp 49333965Sjdp /* A 21 bit branch. */ 49433965Sjdp HOWTO (R_ALPHA_BRADDR, /* type */ 49533965Sjdp 2, /* rightshift */ 49633965Sjdp 2, /* size (0 = byte, 1 = short, 2 = long) */ 49733965Sjdp 21, /* bitsize */ 49833965Sjdp true, /* pc_relative */ 49933965Sjdp 0, /* bitpos */ 50033965Sjdp complain_overflow_signed, /* complain_on_overflow */ 50133965Sjdp 0, /* special_function */ 50233965Sjdp "BRADDR", /* name */ 50333965Sjdp false, /* partial_inplace */ 50433965Sjdp 0x1fffff, /* src_mask */ 50533965Sjdp 0x1fffff, /* dst_mask */ 50633965Sjdp true), /* pcrel_offset */ 50733965Sjdp 50833965Sjdp /* A hint for a jump to a register. */ 50933965Sjdp HOWTO (R_ALPHA_HINT, /* type */ 51033965Sjdp 2, /* rightshift */ 51133965Sjdp 2, /* size (0 = byte, 1 = short, 2 = long) */ 51233965Sjdp 14, /* bitsize */ 51333965Sjdp true, /* pc_relative */ 51433965Sjdp 0, /* bitpos */ 51533965Sjdp complain_overflow_dont, /* complain_on_overflow */ 51633965Sjdp 0, /* special_function */ 51733965Sjdp "HINT", /* name */ 51833965Sjdp false, /* partial_inplace */ 51933965Sjdp 0x3fff, /* src_mask */ 52033965Sjdp 0x3fff, /* dst_mask */ 52133965Sjdp true), /* pcrel_offset */ 52233965Sjdp 52333965Sjdp /* 16 bit PC relative offset. */ 52433965Sjdp HOWTO (R_ALPHA_SREL16, /* type */ 52533965Sjdp 0, /* rightshift */ 52633965Sjdp 1, /* size (0 = byte, 1 = short, 2 = long) */ 52733965Sjdp 16, /* bitsize */ 52833965Sjdp true, /* pc_relative */ 52933965Sjdp 0, /* bitpos */ 53033965Sjdp complain_overflow_signed, /* complain_on_overflow */ 53133965Sjdp 0, /* special_function */ 53233965Sjdp "SREL16", /* name */ 53333965Sjdp false, /* partial_inplace */ 53433965Sjdp 0xffff, /* src_mask */ 53533965Sjdp 0xffff, /* dst_mask */ 53633965Sjdp false), /* pcrel_offset */ 53733965Sjdp 53833965Sjdp /* 32 bit PC relative offset. */ 53933965Sjdp HOWTO (R_ALPHA_SREL32, /* type */ 54033965Sjdp 0, /* rightshift */ 54133965Sjdp 2, /* size (0 = byte, 1 = short, 2 = long) */ 54233965Sjdp 32, /* bitsize */ 54333965Sjdp true, /* pc_relative */ 54433965Sjdp 0, /* bitpos */ 54533965Sjdp complain_overflow_signed, /* complain_on_overflow */ 54633965Sjdp 0, /* special_function */ 54733965Sjdp "SREL32", /* name */ 54833965Sjdp false, /* partial_inplace */ 54933965Sjdp 0xffffffff, /* src_mask */ 55033965Sjdp 0xffffffff, /* dst_mask */ 55133965Sjdp false), /* pcrel_offset */ 55233965Sjdp 55333965Sjdp /* A 64 bit PC relative offset. */ 55433965Sjdp HOWTO (R_ALPHA_SREL64, /* type */ 55533965Sjdp 0, /* rightshift */ 55633965Sjdp 4, /* size (0 = byte, 1 = short, 2 = long) */ 55733965Sjdp 64, /* bitsize */ 55833965Sjdp true, /* pc_relative */ 55933965Sjdp 0, /* bitpos */ 56033965Sjdp complain_overflow_signed, /* complain_on_overflow */ 56133965Sjdp 0, /* special_function */ 56233965Sjdp "SREL64", /* name */ 56333965Sjdp false, /* partial_inplace */ 56433965Sjdp MINUS_ONE, /* src_mask */ 56533965Sjdp MINUS_ONE, /* dst_mask */ 56633965Sjdp false), /* pcrel_offset */ 56733965Sjdp 56833965Sjdp /* Push a value on the reloc evaluation stack. */ 56938889Sjdp /* Not implemented -- it's dumb. */ 57038889Sjdp HOWTO (R_ALPHA_OP_PUSH, /* type */ 57133965Sjdp 0, /* rightshift */ 57233965Sjdp 0, /* size (0 = byte, 1 = short, 2 = long) */ 57333965Sjdp 0, /* bitsize */ 57433965Sjdp false, /* pc_relative */ 57533965Sjdp 0, /* bitpos */ 57633965Sjdp complain_overflow_dont, /* complain_on_overflow */ 57733965Sjdp elf64_alpha_reloc_bad, /* special_function */ 57833965Sjdp "OP_PUSH", /* name */ 57933965Sjdp false, /* partial_inplace */ 58033965Sjdp 0, /* src_mask */ 58133965Sjdp 0, /* dst_mask */ 58233965Sjdp false), /* pcrel_offset */ 58333965Sjdp 58433965Sjdp /* Store the value from the stack at the given address. Store it in 58533965Sjdp a bitfield of size r_size starting at bit position r_offset. */ 58638889Sjdp /* Not implemented -- it's dumb. */ 58738889Sjdp HOWTO (R_ALPHA_OP_STORE, /* type */ 58833965Sjdp 0, /* rightshift */ 58933965Sjdp 4, /* size (0 = byte, 1 = short, 2 = long) */ 59033965Sjdp 64, /* bitsize */ 59133965Sjdp false, /* pc_relative */ 59233965Sjdp 0, /* bitpos */ 59333965Sjdp complain_overflow_dont, /* complain_on_overflow */ 59433965Sjdp elf64_alpha_reloc_bad, /* special_function */ 59533965Sjdp "OP_STORE", /* name */ 59633965Sjdp false, /* partial_inplace */ 59733965Sjdp 0, /* src_mask */ 59833965Sjdp MINUS_ONE, /* dst_mask */ 59933965Sjdp false), /* pcrel_offset */ 60033965Sjdp 60133965Sjdp /* Subtract the reloc address from the value on the top of the 60233965Sjdp relocation stack. */ 60338889Sjdp /* Not implemented -- it's dumb. */ 60438889Sjdp HOWTO (R_ALPHA_OP_PSUB, /* type */ 60533965Sjdp 0, /* rightshift */ 60633965Sjdp 0, /* size (0 = byte, 1 = short, 2 = long) */ 60733965Sjdp 0, /* bitsize */ 60833965Sjdp false, /* pc_relative */ 60933965Sjdp 0, /* bitpos */ 61033965Sjdp complain_overflow_dont, /* complain_on_overflow */ 61133965Sjdp elf64_alpha_reloc_bad, /* special_function */ 61233965Sjdp "OP_PSUB", /* name */ 61333965Sjdp false, /* partial_inplace */ 61433965Sjdp 0, /* src_mask */ 61533965Sjdp 0, /* dst_mask */ 61633965Sjdp false), /* pcrel_offset */ 61733965Sjdp 61833965Sjdp /* Shift the value on the top of the relocation stack right by the 61933965Sjdp given value. */ 62038889Sjdp /* Not implemented -- it's dumb. */ 62138889Sjdp HOWTO (R_ALPHA_OP_PRSHIFT, /* type */ 62233965Sjdp 0, /* rightshift */ 62333965Sjdp 0, /* size (0 = byte, 1 = short, 2 = long) */ 62433965Sjdp 0, /* bitsize */ 62533965Sjdp false, /* pc_relative */ 62633965Sjdp 0, /* bitpos */ 62733965Sjdp complain_overflow_dont, /* complain_on_overflow */ 62833965Sjdp elf64_alpha_reloc_bad, /* special_function */ 62933965Sjdp "OP_PRSHIFT", /* name */ 63033965Sjdp false, /* partial_inplace */ 63133965Sjdp 0, /* src_mask */ 63233965Sjdp 0, /* dst_mask */ 63333965Sjdp false), /* pcrel_offset */ 63433965Sjdp 63538889Sjdp /* Change the value of GP used by +r_addend until the next GPVALUE or the 63638889Sjdp end of the input bfd. */ 63738889Sjdp /* Not implemented -- it's dumb. */ 63838889Sjdp HOWTO (R_ALPHA_GPVALUE, 63938889Sjdp 0, /* rightshift */ 64038889Sjdp 0, /* size (0 = byte, 1 = short, 2 = long) */ 64138889Sjdp 0, /* bitsize */ 64238889Sjdp false, /* pc_relative */ 64338889Sjdp 0, /* bitpos */ 64438889Sjdp complain_overflow_dont, /* complain_on_overflow */ 64538889Sjdp elf64_alpha_reloc_bad, /* special_function */ 64638889Sjdp "GPVALUE", /* name */ 64738889Sjdp false, /* partial_inplace */ 64838889Sjdp 0, /* src_mask */ 64938889Sjdp 0, /* dst_mask */ 65038889Sjdp false), /* pcrel_offset */ 65138889Sjdp 65238889Sjdp /* The high 16 bits of the displacement from GP to the target. */ 65338889Sjdp HOWTO (R_ALPHA_GPRELHIGH, 65438889Sjdp 0, /* rightshift */ 65560510Sobrien 2, /* size (0 = byte, 1 = short, 2 = long) */ 65660510Sobrien 16, /* bitsize */ 65738889Sjdp false, /* pc_relative */ 65838889Sjdp 0, /* bitpos */ 65960510Sobrien complain_overflow_signed, /* complain_on_overflow */ 66038889Sjdp elf64_alpha_reloc_bad, /* special_function */ 66138889Sjdp "GPRELHIGH", /* name */ 66238889Sjdp false, /* partial_inplace */ 66360510Sobrien 0xffff, /* src_mask */ 66460510Sobrien 0xffff, /* dst_mask */ 66538889Sjdp false), /* pcrel_offset */ 66638889Sjdp 66738889Sjdp /* The low 16 bits of the displacement from GP to the target. */ 66838889Sjdp HOWTO (R_ALPHA_GPRELLOW, 66938889Sjdp 0, /* rightshift */ 67060510Sobrien 2, /* size (0 = byte, 1 = short, 2 = long) */ 67160510Sobrien 16, /* bitsize */ 67238889Sjdp false, /* pc_relative */ 67338889Sjdp 0, /* bitpos */ 67438889Sjdp complain_overflow_dont, /* complain_on_overflow */ 67538889Sjdp elf64_alpha_reloc_bad, /* special_function */ 67638889Sjdp "GPRELLOW", /* name */ 67738889Sjdp false, /* partial_inplace */ 67860510Sobrien 0xffff, /* src_mask */ 67960510Sobrien 0xffff, /* dst_mask */ 68038889Sjdp false), /* pcrel_offset */ 68138889Sjdp 68238889Sjdp /* A 16-bit displacement from the GP to the target. */ 68338889Sjdp /* XXX: Not implemented. */ 68438889Sjdp HOWTO (R_ALPHA_IMMED_GP_16, 68538889Sjdp 0, /* rightshift */ 68660510Sobrien 2, /* size (0 = byte, 1 = short, 2 = long) */ 68760510Sobrien 16, /* bitsize */ 68838889Sjdp false, /* pc_relative */ 68938889Sjdp 0, /* bitpos */ 69060510Sobrien complain_overflow_signed, /* complain_on_overflow */ 69160510Sobrien 0, /* special_function */ 69238889Sjdp "IMMED_GP_16", /* name */ 69338889Sjdp false, /* partial_inplace */ 69460510Sobrien 0xffff, /* src_mask */ 69560510Sobrien 0xffff, /* dst_mask */ 69638889Sjdp false), /* pcrel_offset */ 69738889Sjdp 69838889Sjdp /* The high bits of a 32-bit displacement from the GP to the target; the 69938889Sjdp low bits are supplied in the subsequent R_ALPHA_IMMED_LO32 relocs. */ 70038889Sjdp /* XXX: Not implemented. */ 70138889Sjdp HOWTO (R_ALPHA_IMMED_GP_HI32, 70238889Sjdp 0, /* rightshift */ 70338889Sjdp 0, /* size (0 = byte, 1 = short, 2 = long) */ 70438889Sjdp 0, /* bitsize */ 70538889Sjdp false, /* pc_relative */ 70638889Sjdp 0, /* bitpos */ 70738889Sjdp complain_overflow_dont, /* complain_on_overflow */ 70838889Sjdp elf64_alpha_reloc_bad, /* special_function */ 70938889Sjdp "IMMED_GP_HI32", /* name */ 71038889Sjdp false, /* partial_inplace */ 71138889Sjdp 0, /* src_mask */ 71238889Sjdp 0, /* dst_mask */ 71338889Sjdp false), /* pcrel_offset */ 71438889Sjdp 71538889Sjdp /* The high bits of a 32-bit displacement to the starting address of the 71638889Sjdp current section (the relocation target is ignored); the low bits are 71738889Sjdp supplied in the subsequent R_ALPHA_IMMED_LO32 relocs. */ 71838889Sjdp /* XXX: Not implemented. */ 71938889Sjdp HOWTO (R_ALPHA_IMMED_SCN_HI32, 72038889Sjdp 0, /* rightshift */ 72138889Sjdp 0, /* size (0 = byte, 1 = short, 2 = long) */ 72238889Sjdp 0, /* bitsize */ 72338889Sjdp false, /* pc_relative */ 72438889Sjdp 0, /* bitpos */ 72538889Sjdp complain_overflow_dont, /* complain_on_overflow */ 72638889Sjdp elf64_alpha_reloc_bad, /* special_function */ 72738889Sjdp "IMMED_SCN_HI32", /* name */ 72838889Sjdp false, /* partial_inplace */ 72938889Sjdp 0, /* src_mask */ 73038889Sjdp 0, /* dst_mask */ 73138889Sjdp false), /* pcrel_offset */ 73238889Sjdp 73338889Sjdp /* The high bits of a 32-bit displacement from the previous br, bsr, jsr 73438889Sjdp or jmp insn (as tagged by a BRADDR or HINT reloc) to the target; the 73538889Sjdp low bits are supplied by subsequent R_ALPHA_IMMED_LO32 relocs. */ 73638889Sjdp /* XXX: Not implemented. */ 73738889Sjdp HOWTO (R_ALPHA_IMMED_BR_HI32, 73838889Sjdp 0, /* rightshift */ 73938889Sjdp 0, /* size (0 = byte, 1 = short, 2 = long) */ 74038889Sjdp 0, /* bitsize */ 74138889Sjdp false, /* pc_relative */ 74238889Sjdp 0, /* bitpos */ 74338889Sjdp complain_overflow_dont, /* complain_on_overflow */ 74438889Sjdp elf64_alpha_reloc_bad, /* special_function */ 74538889Sjdp "IMMED_BR_HI32", /* name */ 74638889Sjdp false, /* partial_inplace */ 74738889Sjdp 0, /* src_mask */ 74838889Sjdp 0, /* dst_mask */ 74938889Sjdp false), /* pcrel_offset */ 75038889Sjdp 75138889Sjdp /* The low 16 bits of a displacement calculated in a previous HI32 reloc. */ 75238889Sjdp /* XXX: Not implemented. */ 75338889Sjdp HOWTO (R_ALPHA_IMMED_LO32, 75438889Sjdp 0, /* rightshift */ 75538889Sjdp 0, /* size (0 = byte, 1 = short, 2 = long) */ 75638889Sjdp 0, /* bitsize */ 75738889Sjdp false, /* pc_relative */ 75838889Sjdp 0, /* bitpos */ 75938889Sjdp complain_overflow_dont, /* complain_on_overflow */ 76038889Sjdp elf64_alpha_reloc_bad, /* special_function */ 76138889Sjdp "IMMED_LO32", /* name */ 76238889Sjdp false, /* partial_inplace */ 76338889Sjdp 0, /* src_mask */ 76438889Sjdp 0, /* dst_mask */ 76538889Sjdp false), /* pcrel_offset */ 76638889Sjdp 76733965Sjdp /* Misc ELF relocations. */ 76838889Sjdp 76938889Sjdp /* A dynamic relocation to copy the target into our .dynbss section. */ 77038889Sjdp /* Not generated, as all Alpha objects use PIC, so it is not needed. It 77138889Sjdp is present because every other ELF has one, but should not be used 77238889Sjdp because .dynbss is an ugly thing. */ 77333965Sjdp HOWTO (R_ALPHA_COPY, 77433965Sjdp 0, 77533965Sjdp 0, 77633965Sjdp 0, 77733965Sjdp false, 77833965Sjdp 0, 77933965Sjdp complain_overflow_dont, 78033965Sjdp bfd_elf_generic_reloc, 78133965Sjdp "COPY", 78233965Sjdp false, 78333965Sjdp 0, 78433965Sjdp 0, 78533965Sjdp true), 78633965Sjdp 78738889Sjdp /* A dynamic relocation for a .got entry. */ 78833965Sjdp HOWTO (R_ALPHA_GLOB_DAT, 78933965Sjdp 0, 79033965Sjdp 0, 79133965Sjdp 0, 79233965Sjdp false, 79333965Sjdp 0, 79433965Sjdp complain_overflow_dont, 79533965Sjdp bfd_elf_generic_reloc, 79633965Sjdp "GLOB_DAT", 79733965Sjdp false, 79833965Sjdp 0, 79933965Sjdp 0, 80033965Sjdp true), 80133965Sjdp 80238889Sjdp /* A dynamic relocation for a .plt entry. */ 80333965Sjdp HOWTO (R_ALPHA_JMP_SLOT, 80433965Sjdp 0, 80533965Sjdp 0, 80633965Sjdp 0, 80733965Sjdp false, 80833965Sjdp 0, 80933965Sjdp complain_overflow_dont, 81033965Sjdp bfd_elf_generic_reloc, 81133965Sjdp "JMP_SLOT", 81233965Sjdp false, 81333965Sjdp 0, 81433965Sjdp 0, 81533965Sjdp true), 81633965Sjdp 81738889Sjdp /* A dynamic relocation to add the base of the DSO to a 64-bit field. */ 81833965Sjdp HOWTO (R_ALPHA_RELATIVE, 81933965Sjdp 0, 82033965Sjdp 0, 82133965Sjdp 0, 82233965Sjdp false, 82333965Sjdp 0, 82433965Sjdp complain_overflow_dont, 82533965Sjdp bfd_elf_generic_reloc, 82633965Sjdp "RELATIVE", 82733965Sjdp false, 82833965Sjdp 0, 82933965Sjdp 0, 83033965Sjdp true) 83133965Sjdp}; 83233965Sjdp 83333965Sjdp/* A relocation function which doesn't do anything. */ 83433965Sjdp 83533965Sjdpstatic bfd_reloc_status_type 83633965Sjdpelf64_alpha_reloc_nil (abfd, reloc, sym, data, sec, output_bfd, error_message) 83733965Sjdp bfd *abfd; 83833965Sjdp arelent *reloc; 83933965Sjdp asymbol *sym; 84033965Sjdp PTR data; 84133965Sjdp asection *sec; 84233965Sjdp bfd *output_bfd; 84333965Sjdp char **error_message; 84433965Sjdp{ 84533965Sjdp if (output_bfd) 84633965Sjdp reloc->address += sec->output_offset; 84733965Sjdp return bfd_reloc_ok; 84833965Sjdp} 84933965Sjdp 85033965Sjdp/* A relocation function used for an unsupported reloc. */ 85133965Sjdp 85233965Sjdpstatic bfd_reloc_status_type 85333965Sjdpelf64_alpha_reloc_bad (abfd, reloc, sym, data, sec, output_bfd, error_message) 85433965Sjdp bfd *abfd; 85533965Sjdp arelent *reloc; 85633965Sjdp asymbol *sym; 85733965Sjdp PTR data; 85833965Sjdp asection *sec; 85933965Sjdp bfd *output_bfd; 86033965Sjdp char **error_message; 86133965Sjdp{ 86233965Sjdp if (output_bfd) 86333965Sjdp reloc->address += sec->output_offset; 86433965Sjdp return bfd_reloc_notsupported; 86533965Sjdp} 86633965Sjdp 86733965Sjdp/* Do the work of the GPDISP relocation. */ 86833965Sjdp 86933965Sjdpstatic bfd_reloc_status_type 87033965Sjdpelf64_alpha_do_reloc_gpdisp (abfd, gpdisp, p_ldah, p_lda) 87133965Sjdp bfd *abfd; 87233965Sjdp bfd_vma gpdisp; 87333965Sjdp bfd_byte *p_ldah; 87433965Sjdp bfd_byte *p_lda; 87533965Sjdp{ 87633965Sjdp bfd_reloc_status_type ret = bfd_reloc_ok; 87733965Sjdp bfd_vma addend; 87833965Sjdp unsigned long i_ldah, i_lda; 87933965Sjdp 88033965Sjdp i_ldah = bfd_get_32 (abfd, p_ldah); 88133965Sjdp i_lda = bfd_get_32 (abfd, p_lda); 88233965Sjdp 88333965Sjdp /* Complain if the instructions are not correct. */ 88433965Sjdp if (((i_ldah >> 26) & 0x3f) != 0x09 88533965Sjdp || ((i_lda >> 26) & 0x3f) != 0x08) 88633965Sjdp ret = bfd_reloc_dangerous; 88733965Sjdp 88833965Sjdp /* Extract the user-supplied offset, mirroring the sign extensions 88933965Sjdp that the instructions perform. */ 89033965Sjdp addend = ((i_ldah & 0xffff) << 16) | (i_lda & 0xffff); 89133965Sjdp addend = (addend ^ 0x80008000) - 0x80008000; 89233965Sjdp 89333965Sjdp gpdisp += addend; 89433965Sjdp 89548850Sdfr if ((bfd_signed_vma) gpdisp < -(bfd_signed_vma) 0x80000000 89648850Sdfr || (bfd_signed_vma) gpdisp >= (bfd_signed_vma) 0x7fff8000) 89733965Sjdp ret = bfd_reloc_overflow; 89833965Sjdp 89933965Sjdp /* compensate for the sign extension again. */ 90033965Sjdp i_ldah = ((i_ldah & 0xffff0000) 90133965Sjdp | (((gpdisp >> 16) + ((gpdisp >> 15) & 1)) & 0xffff)); 90233965Sjdp i_lda = (i_lda & 0xffff0000) | (gpdisp & 0xffff); 90333965Sjdp 90433965Sjdp bfd_put_32 (abfd, i_ldah, p_ldah); 90533965Sjdp bfd_put_32 (abfd, i_lda, p_lda); 90633965Sjdp 90733965Sjdp return ret; 90833965Sjdp} 90933965Sjdp 91033965Sjdp/* The special function for the GPDISP reloc. */ 91133965Sjdp 91233965Sjdpstatic bfd_reloc_status_type 91333965Sjdpelf64_alpha_reloc_gpdisp (abfd, reloc_entry, sym, data, input_section, 91433965Sjdp output_bfd, err_msg) 91533965Sjdp bfd *abfd; 91633965Sjdp arelent *reloc_entry; 91733965Sjdp asymbol *sym; 91833965Sjdp PTR data; 91933965Sjdp asection *input_section; 92033965Sjdp bfd *output_bfd; 92133965Sjdp char **err_msg; 92233965Sjdp{ 92333965Sjdp bfd_reloc_status_type ret; 92433965Sjdp bfd_vma gp, relocation; 92533965Sjdp bfd_byte *p_ldah, *p_lda; 92633965Sjdp 92733965Sjdp /* Don't do anything if we're not doing a final link. */ 92833965Sjdp if (output_bfd) 92933965Sjdp { 93033965Sjdp reloc_entry->address += input_section->output_offset; 93133965Sjdp return bfd_reloc_ok; 93233965Sjdp } 93333965Sjdp 93433965Sjdp if (reloc_entry->address > input_section->_cooked_size || 93533965Sjdp reloc_entry->address + reloc_entry->addend > input_section->_cooked_size) 93633965Sjdp return bfd_reloc_outofrange; 93733965Sjdp 93833965Sjdp /* The gp used in the portion of the output object to which this 93933965Sjdp input object belongs is cached on the input bfd. */ 94033965Sjdp gp = _bfd_get_gp_value (abfd); 94133965Sjdp 94233965Sjdp relocation = (input_section->output_section->vma 94333965Sjdp + input_section->output_offset 94433965Sjdp + reloc_entry->address); 94533965Sjdp 94633965Sjdp p_ldah = (bfd_byte *) data + reloc_entry->address; 94733965Sjdp p_lda = p_ldah + reloc_entry->addend; 94833965Sjdp 94933965Sjdp ret = elf64_alpha_do_reloc_gpdisp (abfd, gp - relocation, p_ldah, p_lda); 95033965Sjdp 95133965Sjdp /* Complain if the instructions are not correct. */ 95233965Sjdp if (ret == bfd_reloc_dangerous) 95360510Sobrien *err_msg = _("GPDISP relocation did not find ldah and lda instructions"); 95433965Sjdp 95533965Sjdp return ret; 95633965Sjdp} 95733965Sjdp 95833965Sjdp/* A mapping from BFD reloc types to Alpha ELF reloc types. */ 95933965Sjdp 96033965Sjdpstruct elf_reloc_map 96133965Sjdp{ 96233965Sjdp bfd_reloc_code_real_type bfd_reloc_val; 96333965Sjdp int elf_reloc_val; 96433965Sjdp}; 96533965Sjdp 96633965Sjdpstatic const struct elf_reloc_map elf64_alpha_reloc_map[] = 96733965Sjdp{ 96833965Sjdp {BFD_RELOC_NONE, R_ALPHA_NONE}, 96933965Sjdp {BFD_RELOC_32, R_ALPHA_REFLONG}, 97033965Sjdp {BFD_RELOC_64, R_ALPHA_REFQUAD}, 97133965Sjdp {BFD_RELOC_CTOR, R_ALPHA_REFQUAD}, 97233965Sjdp {BFD_RELOC_GPREL32, R_ALPHA_GPREL32}, 97333965Sjdp {BFD_RELOC_ALPHA_ELF_LITERAL, R_ALPHA_LITERAL}, 97433965Sjdp {BFD_RELOC_ALPHA_LITUSE, R_ALPHA_LITUSE}, 97533965Sjdp {BFD_RELOC_ALPHA_GPDISP, R_ALPHA_GPDISP}, 97633965Sjdp {BFD_RELOC_23_PCREL_S2, R_ALPHA_BRADDR}, 97733965Sjdp {BFD_RELOC_ALPHA_HINT, R_ALPHA_HINT}, 97833965Sjdp {BFD_RELOC_16_PCREL, R_ALPHA_SREL16}, 97933965Sjdp {BFD_RELOC_32_PCREL, R_ALPHA_SREL32}, 98033965Sjdp {BFD_RELOC_64_PCREL, R_ALPHA_SREL64}, 98160510Sobrien 98260510Sobrien/* The BFD_RELOC_ALPHA_USER_* relocations are used by the assembler to process 98360510Sobrien the explicit !<reloc>!sequence relocations, and are mapped into the normal 98460510Sobrien relocations at the end of processing. */ 98560510Sobrien {BFD_RELOC_ALPHA_USER_LITERAL, R_ALPHA_LITERAL}, 98660510Sobrien {BFD_RELOC_ALPHA_USER_LITUSE_BASE, R_ALPHA_LITUSE}, 98760510Sobrien {BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF, R_ALPHA_LITUSE}, 98860510Sobrien {BFD_RELOC_ALPHA_USER_LITUSE_JSR, R_ALPHA_LITUSE}, 98960510Sobrien {BFD_RELOC_ALPHA_USER_GPDISP, R_ALPHA_GPDISP}, 99060510Sobrien {BFD_RELOC_ALPHA_USER_GPRELHIGH, R_ALPHA_GPRELHIGH}, 99160510Sobrien {BFD_RELOC_ALPHA_USER_GPRELLOW, R_ALPHA_GPRELLOW}, 99233965Sjdp}; 99333965Sjdp 99433965Sjdp/* Given a BFD reloc type, return a HOWTO structure. */ 99533965Sjdp 99633965Sjdpstatic reloc_howto_type * 99733965Sjdpelf64_alpha_bfd_reloc_type_lookup (abfd, code) 99833965Sjdp bfd *abfd; 99933965Sjdp bfd_reloc_code_real_type code; 100033965Sjdp{ 100133965Sjdp const struct elf_reloc_map *i, *e; 100233965Sjdp i = e = elf64_alpha_reloc_map; 100333965Sjdp e += sizeof (elf64_alpha_reloc_map) / sizeof (struct elf_reloc_map); 100433965Sjdp for (; i != e; ++i) 100533965Sjdp { 100633965Sjdp if (i->bfd_reloc_val == code) 100733965Sjdp return &elf64_alpha_howto_table[i->elf_reloc_val]; 100833965Sjdp } 100933965Sjdp return 0; 101033965Sjdp} 101133965Sjdp 101233965Sjdp/* Given an Alpha ELF reloc type, fill in an arelent structure. */ 101333965Sjdp 101433965Sjdpstatic void 101533965Sjdpelf64_alpha_info_to_howto (abfd, cache_ptr, dst) 101633965Sjdp bfd *abfd; 101733965Sjdp arelent *cache_ptr; 101833965Sjdp Elf64_Internal_Rela *dst; 101933965Sjdp{ 102033965Sjdp unsigned r_type; 102133965Sjdp 102233965Sjdp r_type = ELF64_R_TYPE(dst->r_info); 102333965Sjdp BFD_ASSERT (r_type < (unsigned int) R_ALPHA_max); 102433965Sjdp cache_ptr->howto = &elf64_alpha_howto_table[r_type]; 102533965Sjdp} 102633965Sjdp 102760510Sobrien/* These functions do relaxation for Alpha ELF. 102860510Sobrien 102960510Sobrien Currently I'm only handling what I can do with existing compiler 103060510Sobrien and assembler support, which means no instructions are removed, 103160510Sobrien though some may be nopped. At this time GCC does not emit enough 103260510Sobrien information to do all of the relaxing that is possible. It will 103360510Sobrien take some not small amount of work for that to happen. 103460510Sobrien 103560510Sobrien There are a couple of interesting papers that I once read on this 103660510Sobrien subject, that I cannot find references to at the moment, that 103760510Sobrien related to Alpha in particular. They are by David Wall, then of 103860510Sobrien DEC WRL. */ 103960510Sobrien 104060510Sobrien#define OP_LDA 0x08 104160510Sobrien#define OP_LDAH 0x09 104260510Sobrien#define INSN_JSR 0x68004000 104360510Sobrien#define INSN_JSR_MASK 0xfc00c000 104460510Sobrien#define OP_LDQ 0x29 104560510Sobrien#define OP_BR 0x30 104660510Sobrien#define OP_BSR 0x34 104760510Sobrien#define INSN_UNOP 0x2fe00000 104860510Sobrien 104960510Sobrienstruct alpha_relax_info 105060510Sobrien{ 105160510Sobrien bfd *abfd; 105260510Sobrien asection *sec; 105360510Sobrien bfd_byte *contents; 105460510Sobrien Elf_Internal_Rela *relocs, *relend; 105560510Sobrien struct bfd_link_info *link_info; 105660510Sobrien boolean changed_contents; 105760510Sobrien boolean changed_relocs; 105860510Sobrien bfd_vma gp; 105960510Sobrien bfd *gotobj; 106060510Sobrien asection *tsec; 106160510Sobrien struct alpha_elf_link_hash_entry *h; 106260510Sobrien struct alpha_elf_got_entry *gotent; 106360510Sobrien unsigned char other; 106460510Sobrien}; 106560510Sobrien 106660510Sobrienstatic Elf_Internal_Rela * elf64_alpha_relax_with_lituse 106760510Sobrien PARAMS((struct alpha_relax_info *info, bfd_vma symval, 106860510Sobrien Elf_Internal_Rela *irel, Elf_Internal_Rela *irelend)); 106960510Sobrien 107060510Sobrienstatic boolean elf64_alpha_relax_without_lituse 107160510Sobrien PARAMS((struct alpha_relax_info *info, bfd_vma symval, 107260510Sobrien Elf_Internal_Rela *irel)); 107360510Sobrien 107460510Sobrienstatic bfd_vma elf64_alpha_relax_opt_call 107560510Sobrien PARAMS((struct alpha_relax_info *info, bfd_vma symval)); 107660510Sobrien 107760510Sobrienstatic boolean elf64_alpha_relax_section 107860510Sobrien PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info, 107960510Sobrien boolean *again)); 108060510Sobrien 108160510Sobrienstatic Elf_Internal_Rela * 108260510Sobrienelf64_alpha_find_reloc_at_ofs (rel, relend, offset, type) 108360510Sobrien Elf_Internal_Rela *rel, *relend; 108460510Sobrien bfd_vma offset; 108560510Sobrien int type; 108660510Sobrien{ 108760510Sobrien while (rel < relend) 108860510Sobrien { 108960510Sobrien if (rel->r_offset == offset && ELF64_R_TYPE (rel->r_info) == type) 109060510Sobrien return rel; 109160510Sobrien ++rel; 109260510Sobrien } 109360510Sobrien return NULL; 109460510Sobrien} 109560510Sobrien 109660510Sobrienstatic Elf_Internal_Rela * 109760510Sobrienelf64_alpha_relax_with_lituse (info, symval, irel, irelend) 109860510Sobrien struct alpha_relax_info *info; 109960510Sobrien bfd_vma symval; 110060510Sobrien Elf_Internal_Rela *irel, *irelend; 110160510Sobrien{ 110260510Sobrien Elf_Internal_Rela *urel; 110360510Sobrien int flags, count, i; 110460510Sobrien bfd_signed_vma disp; 110560510Sobrien boolean fits16; 110660510Sobrien boolean fits32; 110760510Sobrien boolean lit_reused = false; 110860510Sobrien boolean all_optimized = true; 110960510Sobrien unsigned int lit_insn; 111060510Sobrien 111160510Sobrien lit_insn = bfd_get_32 (info->abfd, info->contents + irel->r_offset); 111260510Sobrien if (lit_insn >> 26 != OP_LDQ) 111360510Sobrien { 111460510Sobrien ((*_bfd_error_handler) 111560510Sobrien ("%s: %s+0x%lx: warning: LITERAL relocation against unexpected insn", 111660510Sobrien bfd_get_filename (info->abfd), info->sec->name, 111760510Sobrien (unsigned long)irel->r_offset)); 111860510Sobrien return irel; 111960510Sobrien } 112060510Sobrien 112160510Sobrien /* Summarize how this particular LITERAL is used. */ 112260510Sobrien for (urel = irel+1, flags = count = 0; urel < irelend; ++urel, ++count) 112360510Sobrien { 112460510Sobrien if (ELF64_R_TYPE (urel->r_info) != R_ALPHA_LITUSE) 112560510Sobrien break; 112660510Sobrien if (urel->r_addend >= 0 && urel->r_addend <= 3) 112760510Sobrien flags |= 1 << urel->r_addend; 112860510Sobrien } 112960510Sobrien 113060510Sobrien /* A little preparation for the loop... */ 113160510Sobrien disp = symval - info->gp; 113260510Sobrien fits16 = (disp >= -(bfd_signed_vma)0x8000 && disp < 0x8000); 113360510Sobrien fits32 = (disp >= -(bfd_signed_vma)0x80000000 && disp < 0x7fff8000); 113460510Sobrien 113560510Sobrien for (urel = irel+1, i = 0; i < count; ++i, ++urel) 113660510Sobrien { 113760510Sobrien unsigned int insn; 113860510Sobrien insn = bfd_get_32 (info->abfd, info->contents + urel->r_offset); 113960510Sobrien 114060510Sobrien switch (urel->r_addend) 114160510Sobrien { 114260510Sobrien default: /* 0 = ADDRESS FORMAT */ 114360510Sobrien /* This type is really just a placeholder to note that all 114460510Sobrien uses cannot be optimized, but to still allow some. */ 114560510Sobrien all_optimized = false; 114660510Sobrien break; 114760510Sobrien 114860510Sobrien case 1: /* MEM FORMAT */ 114960510Sobrien /* We can always optimize 16-bit displacements. */ 115060510Sobrien if (fits16) 115160510Sobrien { 115260510Sobrien /* FIXME: sanity check the insn for mem format with 115360510Sobrien zero addend. */ 115460510Sobrien 115560510Sobrien /* Take the op code and dest from this insn, take the base 115660510Sobrien register from the literal insn. Leave the offset alone. */ 115760510Sobrien insn = (insn & 0xffe00000) | (lit_insn & 0x001f0000); 115860510Sobrien urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), 115960510Sobrien R_ALPHA_GPRELLOW); 116060510Sobrien urel->r_addend = irel->r_addend; 116160510Sobrien info->changed_relocs = true; 116260510Sobrien 116360510Sobrien bfd_put_32 (info->abfd, insn, info->contents + urel->r_offset); 116460510Sobrien info->changed_contents = true; 116560510Sobrien } 116660510Sobrien 116760510Sobrien /* If all mem+byte, we can optimize 32-bit mem displacements. */ 116860510Sobrien else if (fits32 && !(flags & ~6)) 116960510Sobrien { 117060510Sobrien /* FIXME: sanity check that lit insn Ra is mem insn Rb, and 117160510Sobrien that mem_insn disp is zero. */ 117260510Sobrien 117360510Sobrien irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), 117460510Sobrien R_ALPHA_GPRELHIGH); 117560510Sobrien lit_insn = (OP_LDAH << 26) | (lit_insn & 0x03ff0000); 117660510Sobrien bfd_put_32 (info->abfd, lit_insn, 117760510Sobrien info->contents + irel->r_offset); 117860510Sobrien lit_reused = true; 117960510Sobrien info->changed_contents = true; 118060510Sobrien 118160510Sobrien urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), 118260510Sobrien R_ALPHA_GPRELLOW); 118360510Sobrien urel->r_addend = irel->r_addend; 118460510Sobrien info->changed_relocs = true; 118560510Sobrien } 118660510Sobrien else 118760510Sobrien all_optimized = false; 118860510Sobrien break; 118960510Sobrien 119060510Sobrien case 2: /* BYTE OFFSET FORMAT */ 119160510Sobrien /* We can always optimize byte instructions. */ 119260510Sobrien 119360510Sobrien /* FIXME: sanity check the insn for byte op. Check that the 119460510Sobrien literal dest reg is indeed Rb in the byte insn. */ 119560510Sobrien 119660510Sobrien insn = (insn & ~0x001ff000) | ((symval & 7) << 13) | 0x1000; 119760510Sobrien 119860510Sobrien urel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE); 119960510Sobrien urel->r_addend = 0; 120060510Sobrien info->changed_relocs = true; 120160510Sobrien 120260510Sobrien bfd_put_32 (info->abfd, insn, info->contents + urel->r_offset); 120360510Sobrien info->changed_contents = true; 120460510Sobrien break; 120560510Sobrien 120660510Sobrien case 3: /* CALL FORMAT */ 120760510Sobrien { 120860510Sobrien /* If not zero, place to jump without needing pv. */ 120960510Sobrien bfd_vma optdest = elf64_alpha_relax_opt_call (info, symval); 121060510Sobrien bfd_vma org = (info->sec->output_section->vma 121160510Sobrien + info->sec->output_offset 121260510Sobrien + urel->r_offset + 4); 121360510Sobrien bfd_signed_vma odisp; 121460510Sobrien 121560510Sobrien odisp = (optdest ? optdest : symval) - org; 121660510Sobrien if (odisp >= -0x400000 && odisp < 0x400000) 121760510Sobrien { 121860510Sobrien Elf_Internal_Rela *xrel; 121960510Sobrien 122060510Sobrien /* Preserve branch prediction call stack when possible. */ 122160510Sobrien if ((insn & INSN_JSR_MASK) == INSN_JSR) 122260510Sobrien insn = (OP_BSR << 26) | (insn & 0x03e00000); 122360510Sobrien else 122460510Sobrien insn = (OP_BR << 26) | (insn & 0x03e00000); 122560510Sobrien 122660510Sobrien urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), 122760510Sobrien R_ALPHA_BRADDR); 122860510Sobrien urel->r_addend = irel->r_addend; 122960510Sobrien 123060510Sobrien if (optdest) 123160510Sobrien urel->r_addend += optdest - symval; 123260510Sobrien else 123360510Sobrien all_optimized = false; 123460510Sobrien 123560510Sobrien bfd_put_32 (info->abfd, insn, info->contents + urel->r_offset); 123660510Sobrien 123760510Sobrien /* Kill any HINT reloc that might exist for this insn. */ 123860510Sobrien xrel = (elf64_alpha_find_reloc_at_ofs 123960510Sobrien (info->relocs, info->relend, urel->r_offset, 124060510Sobrien R_ALPHA_HINT)); 124160510Sobrien if (xrel) 124260510Sobrien xrel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE); 124360510Sobrien 124460510Sobrien info->changed_contents = true; 124560510Sobrien info->changed_relocs = true; 124660510Sobrien } 124760510Sobrien else 124860510Sobrien all_optimized = false; 124960510Sobrien 125060510Sobrien /* ??? If target gp == current gp we can eliminate the gp reload. 125160510Sobrien This does depend on every place a gp could be reloaded will 125260510Sobrien be, which currently happens for all code produced by gcc, but 125360510Sobrien not necessarily by hand-coded assembly, or if sibling calls 125460510Sobrien are enabled in gcc. 125560510Sobrien 125660510Sobrien Perhaps conditionalize this on a flag being set in the target 125760510Sobrien object file's header, and have gcc set it? */ 125860510Sobrien } 125960510Sobrien break; 126060510Sobrien } 126160510Sobrien } 126260510Sobrien 126360510Sobrien /* If all cases were optimized, we can reduce the use count on this 126460510Sobrien got entry by one, possibly eliminating it. */ 126560510Sobrien if (all_optimized) 126660510Sobrien { 126760510Sobrien info->gotent->use_count -= 1; 126860510Sobrien alpha_elf_tdata (info->gotent->gotobj)->total_got_entries -= 1; 126960510Sobrien if (!info->h) 127060510Sobrien alpha_elf_tdata (info->gotent->gotobj)->n_local_got_entries -= 1; 127160510Sobrien 127260510Sobrien /* If the literal instruction is no longer needed (it may have been 127360510Sobrien reused. We can eliminate it. 127460510Sobrien ??? For now, I don't want to deal with compacting the section, 127560510Sobrien so just nop it out. */ 127660510Sobrien if (!lit_reused) 127760510Sobrien { 127860510Sobrien irel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE); 127960510Sobrien info->changed_relocs = true; 128060510Sobrien 128160510Sobrien bfd_put_32 (info->abfd, INSN_UNOP, info->contents + irel->r_offset); 128260510Sobrien info->changed_contents = true; 128360510Sobrien } 128460510Sobrien } 128560510Sobrien 128660510Sobrien return irel + count; 128760510Sobrien} 128860510Sobrien 128960510Sobrienstatic bfd_vma 129060510Sobrienelf64_alpha_relax_opt_call (info, symval) 129160510Sobrien struct alpha_relax_info *info; 129260510Sobrien bfd_vma symval; 129360510Sobrien{ 129460510Sobrien /* If the function has the same gp, and we can identify that the 129560510Sobrien function does not use its function pointer, we can eliminate the 129660510Sobrien address load. */ 129760510Sobrien 129860510Sobrien /* If the symbol is marked NOPV, we are being told the function never 129960510Sobrien needs its procedure value. */ 130060510Sobrien if (info->other == STO_ALPHA_NOPV) 130160510Sobrien return symval; 130260510Sobrien 130360510Sobrien /* If the symbol is marked STD_GP, we are being told the function does 130460510Sobrien a normal ldgp in the first two words. */ 130560510Sobrien else if (info->other == STO_ALPHA_STD_GPLOAD) 130660510Sobrien ; 130760510Sobrien 130860510Sobrien /* Otherwise, we may be able to identify a GP load in the first two 130960510Sobrien words, which we can then skip. */ 131060510Sobrien else 131160510Sobrien { 131260510Sobrien Elf_Internal_Rela *tsec_relocs, *tsec_relend, *tsec_free, *gpdisp; 131360510Sobrien bfd_vma ofs; 131460510Sobrien 131560510Sobrien /* Load the relocations from the section that the target symbol is in. */ 131660510Sobrien if (info->sec == info->tsec) 131760510Sobrien { 131860510Sobrien tsec_relocs = info->relocs; 131960510Sobrien tsec_relend = info->relend; 132060510Sobrien tsec_free = NULL; 132160510Sobrien } 132260510Sobrien else 132360510Sobrien { 132460510Sobrien tsec_relocs = (_bfd_elf64_link_read_relocs 132560510Sobrien (info->abfd, info->tsec, (PTR) NULL, 132660510Sobrien (Elf_Internal_Rela *) NULL, 132760510Sobrien info->link_info->keep_memory)); 132860510Sobrien if (tsec_relocs == NULL) 132960510Sobrien return 0; 133060510Sobrien tsec_relend = tsec_relocs + info->tsec->reloc_count; 133160510Sobrien tsec_free = (info->link_info->keep_memory ? NULL : tsec_relocs); 133260510Sobrien } 133360510Sobrien 133460510Sobrien /* Recover the symbol's offset within the section. */ 133560510Sobrien ofs = (symval - info->tsec->output_section->vma 133660510Sobrien - info->tsec->output_offset); 133760510Sobrien 133860510Sobrien /* Look for a GPDISP reloc. */ 133960510Sobrien gpdisp = (elf64_alpha_find_reloc_at_ofs 134060510Sobrien (tsec_relocs, tsec_relend, ofs, R_ALPHA_GPDISP)); 134160510Sobrien 134260510Sobrien if (!gpdisp || gpdisp->r_addend != 4) 134360510Sobrien { 134460510Sobrien if (tsec_free) 134560510Sobrien free (tsec_free); 134660510Sobrien return 0; 134760510Sobrien } 134860510Sobrien if (tsec_free) 134960510Sobrien free (tsec_free); 135060510Sobrien } 135160510Sobrien 135260510Sobrien /* We've now determined that we can skip an initial gp load. Verify 135360510Sobrien that the call and the target use the same gp. */ 135460510Sobrien if (info->link_info->hash->creator != info->tsec->owner->xvec 135560510Sobrien || info->gotobj != alpha_elf_tdata (info->tsec->owner)->gotobj) 135660510Sobrien return 0; 135760510Sobrien 135860510Sobrien return symval + 8; 135960510Sobrien} 136060510Sobrien 136160510Sobrienstatic boolean 136260510Sobrienelf64_alpha_relax_without_lituse (info, symval, irel) 136360510Sobrien struct alpha_relax_info *info; 136460510Sobrien bfd_vma symval; 136560510Sobrien Elf_Internal_Rela *irel; 136660510Sobrien{ 136760510Sobrien unsigned int insn; 136860510Sobrien bfd_signed_vma disp; 136960510Sobrien 137060510Sobrien /* Get the instruction. */ 137160510Sobrien insn = bfd_get_32 (info->abfd, info->contents + irel->r_offset); 137260510Sobrien 137360510Sobrien if (insn >> 26 != OP_LDQ) 137460510Sobrien { 137560510Sobrien ((*_bfd_error_handler) 137660510Sobrien ("%s: %s+0x%lx: warning: LITERAL relocation against unexpected insn", 137760510Sobrien bfd_get_filename (info->abfd), info->sec->name, 137860510Sobrien (unsigned long) irel->r_offset)); 137960510Sobrien return true; 138060510Sobrien } 138160510Sobrien 138260510Sobrien /* So we aren't told much. Do what we can with the address load and 138360510Sobrien fake the rest. All of the optimizations here require that the 138460510Sobrien offset from the GP fit in 16 bits. */ 138560510Sobrien 138660510Sobrien disp = symval - info->gp; 138760510Sobrien if (disp < -0x8000 || disp >= 0x8000) 138860510Sobrien return true; 138960510Sobrien 139060510Sobrien /* On the LITERAL instruction itself, consider exchanging 139160510Sobrien `ldq R,X(gp)' for `lda R,Y(gp)'. */ 139260510Sobrien 139360510Sobrien insn = (OP_LDA << 26) | (insn & 0x03ff0000); 139460510Sobrien bfd_put_32 (info->abfd, insn, info->contents + irel->r_offset); 139560510Sobrien info->changed_contents = true; 139660510Sobrien 139760510Sobrien irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), R_ALPHA_GPRELLOW); 139860510Sobrien info->changed_relocs = true; 139960510Sobrien 140060510Sobrien /* Reduce the use count on this got entry by one, possibly 140160510Sobrien eliminating it. */ 140260510Sobrien info->gotent->use_count -= 1; 140360510Sobrien alpha_elf_tdata (info->gotent->gotobj)->total_got_entries -= 1; 140460510Sobrien if (!info->h) 140560510Sobrien alpha_elf_tdata (info->gotent->gotobj)->n_local_got_entries -= 1; 140660510Sobrien 140760510Sobrien /* ??? Search forward through this basic block looking for insns 140860510Sobrien that use the target register. Stop after an insn modifying the 140960510Sobrien register is seen, or after a branch or call. 141060510Sobrien 141160510Sobrien Any such memory load insn may be substituted by a load directly 141260510Sobrien off the GP. This allows the memory load insn to be issued before 141360510Sobrien the calculated GP register would otherwise be ready. 141460510Sobrien 141560510Sobrien Any such jsr insn can be replaced by a bsr if it is in range. 141660510Sobrien 141760510Sobrien This would mean that we'd have to _add_ relocations, the pain of 141860510Sobrien which gives one pause. */ 141960510Sobrien 142060510Sobrien return true; 142160510Sobrien} 142260510Sobrien 142360510Sobrienstatic boolean 142460510Sobrienelf64_alpha_relax_section (abfd, sec, link_info, again) 142560510Sobrien bfd *abfd; 142660510Sobrien asection *sec; 142760510Sobrien struct bfd_link_info *link_info; 142860510Sobrien boolean *again; 142960510Sobrien{ 143060510Sobrien Elf_Internal_Shdr *symtab_hdr; 143160510Sobrien Elf_Internal_Rela *internal_relocs; 143260510Sobrien Elf_Internal_Rela *free_relocs = NULL; 143360510Sobrien Elf_Internal_Rela *irel, *irelend; 143460510Sobrien bfd_byte *free_contents = NULL; 143560510Sobrien Elf64_External_Sym *extsyms = NULL; 143660510Sobrien Elf64_External_Sym *free_extsyms = NULL; 143760510Sobrien struct alpha_elf_got_entry **local_got_entries; 143860510Sobrien struct alpha_relax_info info; 143960510Sobrien 144060510Sobrien /* We are not currently changing any sizes, so only one pass. */ 144160510Sobrien *again = false; 144260510Sobrien 144360510Sobrien if (link_info->relocateable 144460510Sobrien || (sec->flags & SEC_RELOC) == 0 144560510Sobrien || sec->reloc_count == 0) 144660510Sobrien return true; 144760510Sobrien 144860510Sobrien /* If this is the first time we have been called for this section, 144960510Sobrien initialize the cooked size. */ 145060510Sobrien if (sec->_cooked_size == 0) 145160510Sobrien sec->_cooked_size = sec->_raw_size; 145260510Sobrien 145360510Sobrien symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 145460510Sobrien local_got_entries = alpha_elf_tdata(abfd)->local_got_entries; 145560510Sobrien 145660510Sobrien /* Load the relocations for this section. */ 145760510Sobrien internal_relocs = (_bfd_elf64_link_read_relocs 145860510Sobrien (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL, 145960510Sobrien link_info->keep_memory)); 146060510Sobrien if (internal_relocs == NULL) 146160510Sobrien goto error_return; 146260510Sobrien if (! link_info->keep_memory) 146360510Sobrien free_relocs = internal_relocs; 146460510Sobrien 146560510Sobrien memset(&info, 0, sizeof(info)); 146660510Sobrien info.abfd = abfd; 146760510Sobrien info.sec = sec; 146860510Sobrien info.link_info = link_info; 146960510Sobrien info.relocs = internal_relocs; 147060510Sobrien info.relend = irelend = internal_relocs + sec->reloc_count; 147160510Sobrien 147260510Sobrien /* Find the GP for this object. */ 147360510Sobrien info.gotobj = alpha_elf_tdata (abfd)->gotobj; 147460510Sobrien if (info.gotobj) 147560510Sobrien { 147660510Sobrien asection *sgot = alpha_elf_tdata (info.gotobj)->got; 147760510Sobrien info.gp = _bfd_get_gp_value (info.gotobj); 147860510Sobrien if (info.gp == 0) 147960510Sobrien { 148060510Sobrien info.gp = (sgot->output_section->vma 148160510Sobrien + sgot->output_offset 148260510Sobrien + 0x8000); 148360510Sobrien _bfd_set_gp_value (info.gotobj, info.gp); 148460510Sobrien } 148560510Sobrien } 148660510Sobrien 148760510Sobrien for (irel = internal_relocs; irel < irelend; irel++) 148860510Sobrien { 148960510Sobrien bfd_vma symval; 149060510Sobrien Elf_Internal_Sym isym; 149160510Sobrien struct alpha_elf_got_entry *gotent; 149260510Sobrien 149360510Sobrien if (ELF64_R_TYPE (irel->r_info) != (int) R_ALPHA_LITERAL) 149460510Sobrien continue; 149560510Sobrien 149660510Sobrien /* Get the section contents. */ 149760510Sobrien if (info.contents == NULL) 149860510Sobrien { 149960510Sobrien if (elf_section_data (sec)->this_hdr.contents != NULL) 150060510Sobrien info.contents = elf_section_data (sec)->this_hdr.contents; 150160510Sobrien else 150260510Sobrien { 150360510Sobrien info.contents = (bfd_byte *) bfd_malloc (sec->_raw_size); 150460510Sobrien if (info.contents == NULL) 150560510Sobrien goto error_return; 150660510Sobrien free_contents = info.contents; 150760510Sobrien 150860510Sobrien if (! bfd_get_section_contents (abfd, sec, info.contents, 150960510Sobrien (file_ptr) 0, sec->_raw_size)) 151060510Sobrien goto error_return; 151160510Sobrien } 151260510Sobrien } 151360510Sobrien 151460510Sobrien /* Read this BFD's symbols if we haven't done so already. */ 151560510Sobrien if (extsyms == NULL) 151660510Sobrien { 151760510Sobrien if (symtab_hdr->contents != NULL) 151860510Sobrien extsyms = (Elf64_External_Sym *) symtab_hdr->contents; 151960510Sobrien else 152060510Sobrien { 152160510Sobrien extsyms = ((Elf64_External_Sym *) 152260510Sobrien bfd_malloc (symtab_hdr->sh_size)); 152360510Sobrien if (extsyms == NULL) 152460510Sobrien goto error_return; 152560510Sobrien free_extsyms = extsyms; 152660510Sobrien if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0 152760510Sobrien || (bfd_read (extsyms, 1, symtab_hdr->sh_size, abfd) 152860510Sobrien != symtab_hdr->sh_size)) 152960510Sobrien goto error_return; 153060510Sobrien } 153160510Sobrien } 153260510Sobrien 153360510Sobrien /* Get the value of the symbol referred to by the reloc. */ 153460510Sobrien if (ELF64_R_SYM (irel->r_info) < symtab_hdr->sh_info) 153560510Sobrien { 153660510Sobrien /* A local symbol. */ 153760510Sobrien bfd_elf64_swap_symbol_in (abfd, 153860510Sobrien extsyms + ELF64_R_SYM (irel->r_info), 153960510Sobrien &isym); 154060510Sobrien if (isym.st_shndx == SHN_UNDEF) 154160510Sobrien info.tsec = bfd_und_section_ptr; 154260510Sobrien else if (isym.st_shndx > 0 && isym.st_shndx < SHN_LORESERVE) 154360510Sobrien info.tsec = bfd_section_from_elf_index (abfd, isym.st_shndx); 154460510Sobrien else if (isym.st_shndx == SHN_ABS) 154560510Sobrien info.tsec = bfd_abs_section_ptr; 154660510Sobrien else if (isym.st_shndx == SHN_COMMON) 154760510Sobrien info.tsec = bfd_com_section_ptr; 154860510Sobrien else 154960510Sobrien continue; /* who knows. */ 155060510Sobrien 155160510Sobrien info.h = NULL; 155260510Sobrien info.other = isym.st_other; 155360510Sobrien gotent = local_got_entries[ELF64_R_SYM(irel->r_info)]; 155460510Sobrien symval = isym.st_value; 155560510Sobrien } 155660510Sobrien else 155760510Sobrien { 155860510Sobrien unsigned long indx; 155960510Sobrien struct alpha_elf_link_hash_entry *h; 156060510Sobrien 156160510Sobrien indx = ELF64_R_SYM (irel->r_info) - symtab_hdr->sh_info; 156260510Sobrien h = alpha_elf_sym_hashes (abfd)[indx]; 156360510Sobrien BFD_ASSERT (h != NULL); 156460510Sobrien 156560510Sobrien while (h->root.root.type == bfd_link_hash_indirect 156660510Sobrien || h->root.root.type == bfd_link_hash_warning) 156760510Sobrien h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link; 156860510Sobrien 156960510Sobrien /* We can't do anthing with undefined or dynamic symbols. */ 157060510Sobrien if (h->root.root.type == bfd_link_hash_undefined 157160510Sobrien || h->root.root.type == bfd_link_hash_undefweak 157260510Sobrien || alpha_elf_dynamic_symbol_p (&h->root, link_info)) 157360510Sobrien continue; 157460510Sobrien 157560510Sobrien info.h = h; 157660510Sobrien info.gotent = gotent; 157760510Sobrien info.tsec = h->root.root.u.def.section; 157860510Sobrien info.other = h->root.other; 157960510Sobrien gotent = h->got_entries; 158060510Sobrien symval = h->root.root.u.def.value; 158160510Sobrien } 158260510Sobrien 158360510Sobrien /* Search for the got entry to be used by this relocation. */ 158460510Sobrien while (gotent->gotobj != info.gotobj || gotent->addend != irel->r_addend) 158560510Sobrien gotent = gotent->next; 158660510Sobrien info.gotent = gotent; 158760510Sobrien 158860510Sobrien symval += info.tsec->output_section->vma + info.tsec->output_offset; 158960510Sobrien symval += irel->r_addend; 159060510Sobrien 159160510Sobrien BFD_ASSERT(info.gotent != NULL); 159260510Sobrien 159360510Sobrien /* If there exist LITUSE relocations immediately following, this 159460510Sobrien opens up all sorts of interesting optimizations, because we 159560510Sobrien now know every location that this address load is used. */ 159660510Sobrien 159760510Sobrien if (irel+1 < irelend && ELF64_R_TYPE (irel[1].r_info) == R_ALPHA_LITUSE) 159860510Sobrien { 159960510Sobrien irel = elf64_alpha_relax_with_lituse (&info, symval, irel, irelend); 160060510Sobrien if (irel == NULL) 160160510Sobrien goto error_return; 160260510Sobrien } 160360510Sobrien else 160460510Sobrien { 160560510Sobrien if (!elf64_alpha_relax_without_lituse (&info, symval, irel)) 160660510Sobrien goto error_return; 160760510Sobrien } 160860510Sobrien } 160960510Sobrien 161060510Sobrien if (!elf64_alpha_size_got_sections (abfd, link_info)) 161160510Sobrien return false; 161260510Sobrien 161360510Sobrien if (info.changed_relocs) 161460510Sobrien { 161560510Sobrien elf_section_data (sec)->relocs = internal_relocs; 161660510Sobrien } 161760510Sobrien else if (free_relocs != NULL) 161860510Sobrien { 161960510Sobrien free (free_relocs); 162060510Sobrien } 162160510Sobrien 162260510Sobrien if (info.changed_contents) 162360510Sobrien { 162460510Sobrien elf_section_data (sec)->this_hdr.contents = info.contents; 162560510Sobrien } 162660510Sobrien else if (free_contents != NULL) 162760510Sobrien { 162860510Sobrien if (! link_info->keep_memory) 162960510Sobrien free (free_contents); 163060510Sobrien else 163160510Sobrien { 163260510Sobrien /* Cache the section contents for elf_link_input_bfd. */ 163360510Sobrien elf_section_data (sec)->this_hdr.contents = info.contents; 163460510Sobrien } 163560510Sobrien } 163660510Sobrien 163760510Sobrien if (free_extsyms != NULL) 163860510Sobrien { 163960510Sobrien if (! link_info->keep_memory) 164060510Sobrien free (free_extsyms); 164160510Sobrien else 164260510Sobrien { 164360510Sobrien /* Cache the symbols for elf_link_input_bfd. */ 164460510Sobrien symtab_hdr->contents = extsyms; 164560510Sobrien } 164660510Sobrien } 164760510Sobrien 164860510Sobrien *again = info.changed_contents || info.changed_relocs; 164960510Sobrien 165060510Sobrien return true; 165160510Sobrien 165260510Sobrien error_return: 165360510Sobrien if (free_relocs != NULL) 165460510Sobrien free (free_relocs); 165560510Sobrien if (free_contents != NULL) 165660510Sobrien free (free_contents); 165760510Sobrien if (free_extsyms != NULL) 165860510Sobrien free (free_extsyms); 165960510Sobrien return false; 166060510Sobrien} 166160510Sobrien 166233965Sjdp/* PLT/GOT Stuff */ 166333965Sjdp#define PLT_HEADER_SIZE 32 166433965Sjdp#define PLT_HEADER_WORD1 0xc3600000 /* br $27,.+4 */ 166533965Sjdp#define PLT_HEADER_WORD2 0xa77b000c /* ldq $27,12($27) */ 166633965Sjdp#define PLT_HEADER_WORD3 0x47ff041f /* nop */ 166733965Sjdp#define PLT_HEADER_WORD4 0x6b7b0000 /* jmp $27,($27) */ 166833965Sjdp 166933965Sjdp#define PLT_ENTRY_SIZE 12 167038889Sjdp#define PLT_ENTRY_WORD1 0xc3800000 /* br $28, plt0 */ 167138889Sjdp#define PLT_ENTRY_WORD2 0 167238889Sjdp#define PLT_ENTRY_WORD3 0 167333965Sjdp 167433965Sjdp#define MAX_GOT_ENTRIES (64*1024 / 8) 167533965Sjdp 167657406Sjdp#define ELF_DYNAMIC_INTERPRETER "/usr/libexec/ld-elf.so.1" 167733965Sjdp 167833965Sjdp/* Handle an Alpha specific section when reading an object file. This 167933965Sjdp is called when elfcode.h finds a section with an unknown type. 168060510Sobrien FIXME: We need to handle the SHF_ALPHA_GPREL flag, but I'm not sure 168133965Sjdp how to. */ 168233965Sjdp 168333965Sjdpstatic boolean 168433965Sjdpelf64_alpha_section_from_shdr (abfd, hdr, name) 168533965Sjdp bfd *abfd; 168633965Sjdp Elf64_Internal_Shdr *hdr; 168733965Sjdp char *name; 168833965Sjdp{ 168933965Sjdp asection *newsect; 169033965Sjdp 169133965Sjdp /* There ought to be a place to keep ELF backend specific flags, but 169233965Sjdp at the moment there isn't one. We just keep track of the 169333965Sjdp sections by their name, instead. Fortunately, the ABI gives 169433965Sjdp suggested names for all the MIPS specific sections, so we will 169533965Sjdp probably get away with this. */ 169633965Sjdp switch (hdr->sh_type) 169733965Sjdp { 169833965Sjdp case SHT_ALPHA_DEBUG: 169933965Sjdp if (strcmp (name, ".mdebug") != 0) 170033965Sjdp return false; 170133965Sjdp break; 170233965Sjdp#ifdef ERIC_neverdef 170333965Sjdp case SHT_ALPHA_REGINFO: 170433965Sjdp if (strcmp (name, ".reginfo") != 0 170533965Sjdp || hdr->sh_size != sizeof (Elf64_External_RegInfo)) 170633965Sjdp return false; 170733965Sjdp break; 170833965Sjdp#endif 170933965Sjdp default: 171033965Sjdp return false; 171133965Sjdp } 171233965Sjdp 171333965Sjdp if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) 171433965Sjdp return false; 171533965Sjdp newsect = hdr->bfd_section; 171633965Sjdp 171733965Sjdp if (hdr->sh_type == SHT_ALPHA_DEBUG) 171833965Sjdp { 171933965Sjdp if (! bfd_set_section_flags (abfd, newsect, 172033965Sjdp (bfd_get_section_flags (abfd, newsect) 172133965Sjdp | SEC_DEBUGGING))) 172233965Sjdp return false; 172333965Sjdp } 172433965Sjdp 172533965Sjdp#ifdef ERIC_neverdef 172633965Sjdp /* For a .reginfo section, set the gp value in the tdata information 172733965Sjdp from the contents of this section. We need the gp value while 172833965Sjdp processing relocs, so we just get it now. */ 172933965Sjdp if (hdr->sh_type == SHT_ALPHA_REGINFO) 173033965Sjdp { 173133965Sjdp Elf64_External_RegInfo ext; 173233965Sjdp Elf64_RegInfo s; 173333965Sjdp 173433965Sjdp if (! bfd_get_section_contents (abfd, newsect, (PTR) &ext, 173533965Sjdp (file_ptr) 0, sizeof ext)) 173633965Sjdp return false; 173733965Sjdp bfd_alpha_elf64_swap_reginfo_in (abfd, &ext, &s); 173833965Sjdp elf_gp (abfd) = s.ri_gp_value; 173933965Sjdp } 174033965Sjdp#endif 174133965Sjdp 174233965Sjdp return true; 174333965Sjdp} 174433965Sjdp 174533965Sjdp/* Set the correct type for an Alpha ELF section. We do this by the 174633965Sjdp section name, which is a hack, but ought to work. */ 174733965Sjdp 174833965Sjdpstatic boolean 174933965Sjdpelf64_alpha_fake_sections (abfd, hdr, sec) 175033965Sjdp bfd *abfd; 175133965Sjdp Elf64_Internal_Shdr *hdr; 175233965Sjdp asection *sec; 175333965Sjdp{ 175433965Sjdp register const char *name; 175533965Sjdp 175633965Sjdp name = bfd_get_section_name (abfd, sec); 175733965Sjdp 175833965Sjdp if (strcmp (name, ".mdebug") == 0) 175933965Sjdp { 176033965Sjdp hdr->sh_type = SHT_ALPHA_DEBUG; 176133965Sjdp /* In a shared object on Irix 5.3, the .mdebug section has an 176233965Sjdp entsize of 0. FIXME: Does this matter? */ 176333965Sjdp if ((abfd->flags & DYNAMIC) != 0 ) 176433965Sjdp hdr->sh_entsize = 0; 176533965Sjdp else 176633965Sjdp hdr->sh_entsize = 1; 176733965Sjdp } 176833965Sjdp#ifdef ERIC_neverdef 176933965Sjdp else if (strcmp (name, ".reginfo") == 0) 177033965Sjdp { 177133965Sjdp hdr->sh_type = SHT_ALPHA_REGINFO; 177233965Sjdp /* In a shared object on Irix 5.3, the .reginfo section has an 177333965Sjdp entsize of 0x18. FIXME: Does this matter? */ 177433965Sjdp if ((abfd->flags & DYNAMIC) != 0) 177533965Sjdp hdr->sh_entsize = sizeof (Elf64_External_RegInfo); 177633965Sjdp else 177733965Sjdp hdr->sh_entsize = 1; 177833965Sjdp 177933965Sjdp /* Force the section size to the correct value, even if the 178033965Sjdp linker thinks it is larger. The link routine below will only 178133965Sjdp write out this much data for .reginfo. */ 178233965Sjdp hdr->sh_size = sec->_raw_size = sizeof (Elf64_External_RegInfo); 178333965Sjdp } 178433965Sjdp else if (strcmp (name, ".hash") == 0 178533965Sjdp || strcmp (name, ".dynamic") == 0 178633965Sjdp || strcmp (name, ".dynstr") == 0) 178733965Sjdp { 178833965Sjdp hdr->sh_entsize = 0; 178933965Sjdp hdr->sh_info = SIZEOF_ALPHA_DYNSYM_SECNAMES; 179033965Sjdp } 179133965Sjdp#endif 179233965Sjdp else if (strcmp (name, ".sdata") == 0 179333965Sjdp || strcmp (name, ".sbss") == 0 179433965Sjdp || strcmp (name, ".lit4") == 0 179533965Sjdp || strcmp (name, ".lit8") == 0) 179633965Sjdp hdr->sh_flags |= SHF_ALPHA_GPREL; 179733965Sjdp 179833965Sjdp return true; 179933965Sjdp} 180033965Sjdp 180160510Sobrien/* Hook called by the linker routine which adds symbols from an object 180260510Sobrien file. We use it to put .comm items in .sbss, and not .bss. */ 180333965Sjdp 180460510Sobrienstatic boolean 180560510Sobrienelf64_alpha_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) 180633965Sjdp bfd *abfd; 180760510Sobrien struct bfd_link_info *info; 180860510Sobrien const Elf_Internal_Sym *sym; 180960510Sobrien const char **namep; 181060510Sobrien flagword *flagsp; 181160510Sobrien asection **secp; 181260510Sobrien bfd_vma *valp; 181333965Sjdp{ 181460510Sobrien if (sym->st_shndx == SHN_COMMON 181560510Sobrien && !info->relocateable 181660510Sobrien && sym->st_size <= bfd_get_gp_size (abfd)) 181760510Sobrien { 181860510Sobrien /* Common symbols less than or equal to -G nn bytes are 181960510Sobrien automatically put into .sbss. */ 182033965Sjdp 182160510Sobrien asection *scomm = bfd_get_section_by_name (abfd, ".scommon"); 182233965Sjdp 182360510Sobrien if (scomm == NULL) 182460510Sobrien { 182560510Sobrien scomm = bfd_make_section (abfd, ".scommon"); 182660510Sobrien if (scomm == NULL 182760510Sobrien || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC 182860510Sobrien | SEC_IS_COMMON 182960510Sobrien | SEC_LINKER_CREATED))) 183060510Sobrien return false; 183160510Sobrien } 183233965Sjdp 183360510Sobrien *secp = scomm; 183460510Sobrien *valp = sym->st_size; 183533965Sjdp } 183633965Sjdp 183760510Sobrien return true; 183833965Sjdp} 183933965Sjdp 184033965Sjdp/* Create the .got section. */ 184133965Sjdp 184233965Sjdpstatic boolean 184333965Sjdpelf64_alpha_create_got_section(abfd, info) 184433965Sjdp bfd *abfd; 184533965Sjdp struct bfd_link_info *info; 184633965Sjdp{ 184733965Sjdp asection *s; 184833965Sjdp 184933965Sjdp if (bfd_get_section_by_name (abfd, ".got")) 185033965Sjdp return true; 185133965Sjdp 185233965Sjdp s = bfd_make_section (abfd, ".got"); 185333965Sjdp if (s == NULL 185433965Sjdp || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD 185533965Sjdp | SEC_HAS_CONTENTS 185633965Sjdp | SEC_IN_MEMORY 185733965Sjdp | SEC_LINKER_CREATED)) 185833965Sjdp || !bfd_set_section_alignment (abfd, s, 3)) 185933965Sjdp return false; 186033965Sjdp 186133965Sjdp alpha_elf_tdata (abfd)->got = s; 186233965Sjdp 186333965Sjdp return true; 186433965Sjdp} 186533965Sjdp 186633965Sjdp/* Create all the dynamic sections. */ 186733965Sjdp 186833965Sjdpstatic boolean 186933965Sjdpelf64_alpha_create_dynamic_sections (abfd, info) 187033965Sjdp bfd *abfd; 187133965Sjdp struct bfd_link_info *info; 187233965Sjdp{ 187333965Sjdp asection *s; 187433965Sjdp struct elf_link_hash_entry *h; 187533965Sjdp 187633965Sjdp /* We need to create .plt, .rela.plt, .got, and .rela.got sections. */ 187733965Sjdp 187833965Sjdp s = bfd_make_section (abfd, ".plt"); 187933965Sjdp if (s == NULL 188033965Sjdp || ! bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD 188133965Sjdp | SEC_HAS_CONTENTS 188233965Sjdp | SEC_IN_MEMORY 188333965Sjdp | SEC_LINKER_CREATED 188433965Sjdp | SEC_CODE)) 188533965Sjdp || ! bfd_set_section_alignment (abfd, s, 3)) 188633965Sjdp return false; 188733965Sjdp 188833965Sjdp /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the 188933965Sjdp .plt section. */ 189033965Sjdp h = NULL; 189133965Sjdp if (! (_bfd_generic_link_add_one_symbol 189233965Sjdp (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s, 189333965Sjdp (bfd_vma) 0, (const char *) NULL, false, 189433965Sjdp get_elf_backend_data (abfd)->collect, 189533965Sjdp (struct bfd_link_hash_entry **) &h))) 189633965Sjdp return false; 189733965Sjdp h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; 189833965Sjdp h->type = STT_OBJECT; 189933965Sjdp 190033965Sjdp if (info->shared 190133965Sjdp && ! _bfd_elf_link_record_dynamic_symbol (info, h)) 190233965Sjdp return false; 190333965Sjdp 190433965Sjdp s = bfd_make_section (abfd, ".rela.plt"); 190533965Sjdp if (s == NULL 190633965Sjdp || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD 190733965Sjdp | SEC_HAS_CONTENTS 190833965Sjdp | SEC_IN_MEMORY 190933965Sjdp | SEC_LINKER_CREATED 191033965Sjdp | SEC_READONLY)) 191133965Sjdp || ! bfd_set_section_alignment (abfd, s, 3)) 191233965Sjdp return false; 191333965Sjdp 191433965Sjdp /* We may or may not have created a .got section for this object, but 191533965Sjdp we definitely havn't done the rest of the work. */ 191633965Sjdp 191733965Sjdp if (!elf64_alpha_create_got_section (abfd, info)) 191833965Sjdp return false; 191933965Sjdp 192033965Sjdp s = bfd_make_section(abfd, ".rela.got"); 192133965Sjdp if (s == NULL 192233965Sjdp || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD 192333965Sjdp | SEC_HAS_CONTENTS 192433965Sjdp | SEC_IN_MEMORY 192533965Sjdp | SEC_LINKER_CREATED 192633965Sjdp | SEC_READONLY)) 192733965Sjdp || !bfd_set_section_alignment (abfd, s, 3)) 192833965Sjdp return false; 192933965Sjdp 193033965Sjdp /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the 193133965Sjdp dynobj's .got section. We don't do this in the linker script 193233965Sjdp because we don't want to define the symbol if we are not creating 193333965Sjdp a global offset table. */ 193433965Sjdp h = NULL; 193533965Sjdp if (!(_bfd_generic_link_add_one_symbol 193633965Sjdp (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, 193733965Sjdp alpha_elf_tdata(abfd)->got, (bfd_vma) 0, (const char *) NULL, 193833965Sjdp false, get_elf_backend_data (abfd)->collect, 193933965Sjdp (struct bfd_link_hash_entry **) &h))) 194033965Sjdp return false; 194133965Sjdp h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; 194233965Sjdp h->type = STT_OBJECT; 194333965Sjdp 194433965Sjdp if (info->shared 194533965Sjdp && ! _bfd_elf_link_record_dynamic_symbol (info, h)) 194633965Sjdp return false; 194733965Sjdp 194833965Sjdp elf_hash_table (info)->hgot = h; 194933965Sjdp 195033965Sjdp return true; 195133965Sjdp} 195233965Sjdp 195333965Sjdp/* Read ECOFF debugging information from a .mdebug section into a 195433965Sjdp ecoff_debug_info structure. */ 195533965Sjdp 195633965Sjdpstatic boolean 195733965Sjdpelf64_alpha_read_ecoff_info (abfd, section, debug) 195833965Sjdp bfd *abfd; 195933965Sjdp asection *section; 196033965Sjdp struct ecoff_debug_info *debug; 196133965Sjdp{ 196233965Sjdp HDRR *symhdr; 196333965Sjdp const struct ecoff_debug_swap *swap; 196433965Sjdp char *ext_hdr = NULL; 196533965Sjdp 196633965Sjdp swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; 196760510Sobrien memset (debug, 0, sizeof(*debug)); 196833965Sjdp 196933965Sjdp ext_hdr = (char *) bfd_malloc ((size_t) swap->external_hdr_size); 197033965Sjdp if (ext_hdr == NULL && swap->external_hdr_size != 0) 197133965Sjdp goto error_return; 197233965Sjdp 197333965Sjdp if (bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0, 197433965Sjdp swap->external_hdr_size) 197533965Sjdp == false) 197633965Sjdp goto error_return; 197733965Sjdp 197833965Sjdp symhdr = &debug->symbolic_header; 197933965Sjdp (*swap->swap_hdr_in) (abfd, ext_hdr, symhdr); 198033965Sjdp 198133965Sjdp /* The symbolic header contains absolute file offsets and sizes to 198233965Sjdp read. */ 198333965Sjdp#define READ(ptr, offset, count, size, type) \ 198433965Sjdp if (symhdr->count == 0) \ 198533965Sjdp debug->ptr = NULL; \ 198633965Sjdp else \ 198733965Sjdp { \ 198833965Sjdp debug->ptr = (type) bfd_malloc ((size_t) (size * symhdr->count)); \ 198933965Sjdp if (debug->ptr == NULL) \ 199033965Sjdp goto error_return; \ 199133965Sjdp if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \ 199233965Sjdp || (bfd_read (debug->ptr, size, symhdr->count, \ 199333965Sjdp abfd) != size * symhdr->count)) \ 199433965Sjdp goto error_return; \ 199533965Sjdp } 199633965Sjdp 199733965Sjdp READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *); 199833965Sjdp READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR); 199933965Sjdp READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR); 200033965Sjdp READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR); 200133965Sjdp READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR); 200233965Sjdp READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext), 200333965Sjdp union aux_ext *); 200433965Sjdp READ (ss, cbSsOffset, issMax, sizeof (char), char *); 200533965Sjdp READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *); 200633965Sjdp READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR); 200733965Sjdp READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR); 200833965Sjdp READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, PTR); 200933965Sjdp#undef READ 201033965Sjdp 201133965Sjdp debug->fdr = NULL; 201233965Sjdp debug->adjust = NULL; 201333965Sjdp 201433965Sjdp return true; 201533965Sjdp 201633965Sjdp error_return: 201733965Sjdp if (ext_hdr != NULL) 201833965Sjdp free (ext_hdr); 201933965Sjdp if (debug->line != NULL) 202033965Sjdp free (debug->line); 202133965Sjdp if (debug->external_dnr != NULL) 202233965Sjdp free (debug->external_dnr); 202333965Sjdp if (debug->external_pdr != NULL) 202433965Sjdp free (debug->external_pdr); 202533965Sjdp if (debug->external_sym != NULL) 202633965Sjdp free (debug->external_sym); 202733965Sjdp if (debug->external_opt != NULL) 202833965Sjdp free (debug->external_opt); 202933965Sjdp if (debug->external_aux != NULL) 203033965Sjdp free (debug->external_aux); 203133965Sjdp if (debug->ss != NULL) 203233965Sjdp free (debug->ss); 203333965Sjdp if (debug->ssext != NULL) 203433965Sjdp free (debug->ssext); 203533965Sjdp if (debug->external_fdr != NULL) 203633965Sjdp free (debug->external_fdr); 203733965Sjdp if (debug->external_rfd != NULL) 203833965Sjdp free (debug->external_rfd); 203933965Sjdp if (debug->external_ext != NULL) 204033965Sjdp free (debug->external_ext); 204133965Sjdp return false; 204233965Sjdp} 204333965Sjdp 204433965Sjdp/* Alpha ELF local labels start with '$'. */ 204533965Sjdp 204633965Sjdpstatic boolean 204733965Sjdpelf64_alpha_is_local_label_name (abfd, name) 204833965Sjdp bfd *abfd; 204933965Sjdp const char *name; 205033965Sjdp{ 205133965Sjdp return name[0] == '$'; 205233965Sjdp} 205333965Sjdp 205433965Sjdp/* Alpha ELF follows MIPS ELF in using a special find_nearest_line 205533965Sjdp routine in order to handle the ECOFF debugging information. We 205633965Sjdp still call this mips_elf_find_line because of the slot 205733965Sjdp find_line_info in elf_obj_tdata is declared that way. */ 205833965Sjdp 205933965Sjdpstruct mips_elf_find_line 206033965Sjdp{ 206133965Sjdp struct ecoff_debug_info d; 206233965Sjdp struct ecoff_find_line i; 206333965Sjdp}; 206433965Sjdp 206533965Sjdpstatic boolean 206633965Sjdpelf64_alpha_find_nearest_line (abfd, section, symbols, offset, filename_ptr, 206733965Sjdp functionname_ptr, line_ptr) 206833965Sjdp bfd *abfd; 206933965Sjdp asection *section; 207033965Sjdp asymbol **symbols; 207133965Sjdp bfd_vma offset; 207233965Sjdp const char **filename_ptr; 207333965Sjdp const char **functionname_ptr; 207433965Sjdp unsigned int *line_ptr; 207533965Sjdp{ 207633965Sjdp asection *msec; 207733965Sjdp 207833965Sjdp msec = bfd_get_section_by_name (abfd, ".mdebug"); 207933965Sjdp if (msec != NULL) 208033965Sjdp { 208133965Sjdp flagword origflags; 208233965Sjdp struct mips_elf_find_line *fi; 208333965Sjdp const struct ecoff_debug_swap * const swap = 208433965Sjdp get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; 208533965Sjdp 208633965Sjdp /* If we are called during a link, alpha_elf_final_link may have 208733965Sjdp cleared the SEC_HAS_CONTENTS field. We force it back on here 208833965Sjdp if appropriate (which it normally will be). */ 208933965Sjdp origflags = msec->flags; 209033965Sjdp if (elf_section_data (msec)->this_hdr.sh_type != SHT_NOBITS) 209133965Sjdp msec->flags |= SEC_HAS_CONTENTS; 209233965Sjdp 209333965Sjdp fi = elf_tdata (abfd)->find_line_info; 209433965Sjdp if (fi == NULL) 209533965Sjdp { 209633965Sjdp bfd_size_type external_fdr_size; 209733965Sjdp char *fraw_src; 209833965Sjdp char *fraw_end; 209933965Sjdp struct fdr *fdr_ptr; 210033965Sjdp 210133965Sjdp fi = ((struct mips_elf_find_line *) 210233965Sjdp bfd_zalloc (abfd, sizeof (struct mips_elf_find_line))); 210333965Sjdp if (fi == NULL) 210433965Sjdp { 210533965Sjdp msec->flags = origflags; 210633965Sjdp return false; 210733965Sjdp } 210833965Sjdp 210933965Sjdp if (!elf64_alpha_read_ecoff_info (abfd, msec, &fi->d)) 211033965Sjdp { 211133965Sjdp msec->flags = origflags; 211233965Sjdp return false; 211333965Sjdp } 211433965Sjdp 211533965Sjdp /* Swap in the FDR information. */ 211633965Sjdp fi->d.fdr = ((struct fdr *) 211733965Sjdp bfd_alloc (abfd, 211833965Sjdp (fi->d.symbolic_header.ifdMax * 211933965Sjdp sizeof (struct fdr)))); 212033965Sjdp if (fi->d.fdr == NULL) 212133965Sjdp { 212233965Sjdp msec->flags = origflags; 212333965Sjdp return false; 212433965Sjdp } 212533965Sjdp external_fdr_size = swap->external_fdr_size; 212633965Sjdp fdr_ptr = fi->d.fdr; 212733965Sjdp fraw_src = (char *) fi->d.external_fdr; 212833965Sjdp fraw_end = (fraw_src 212933965Sjdp + fi->d.symbolic_header.ifdMax * external_fdr_size); 213033965Sjdp for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++) 213133965Sjdp (*swap->swap_fdr_in) (abfd, (PTR) fraw_src, fdr_ptr); 213233965Sjdp 213333965Sjdp elf_tdata (abfd)->find_line_info = fi; 213433965Sjdp 213533965Sjdp /* Note that we don't bother to ever free this information. 213633965Sjdp find_nearest_line is either called all the time, as in 213733965Sjdp objdump -l, so the information should be saved, or it is 213833965Sjdp rarely called, as in ld error messages, so the memory 213933965Sjdp wasted is unimportant. Still, it would probably be a 214033965Sjdp good idea for free_cached_info to throw it away. */ 214133965Sjdp } 214233965Sjdp 214333965Sjdp if (_bfd_ecoff_locate_line (abfd, section, offset, &fi->d, swap, 214433965Sjdp &fi->i, filename_ptr, functionname_ptr, 214533965Sjdp line_ptr)) 214633965Sjdp { 214733965Sjdp msec->flags = origflags; 214833965Sjdp return true; 214933965Sjdp } 215033965Sjdp 215133965Sjdp msec->flags = origflags; 215233965Sjdp } 215333965Sjdp 215433965Sjdp /* Fall back on the generic ELF find_nearest_line routine. */ 215533965Sjdp 215633965Sjdp return _bfd_elf_find_nearest_line (abfd, section, symbols, offset, 215733965Sjdp filename_ptr, functionname_ptr, 215833965Sjdp line_ptr); 215933965Sjdp} 216033965Sjdp 216133965Sjdp/* Structure used to pass information to alpha_elf_output_extsym. */ 216233965Sjdp 216333965Sjdpstruct extsym_info 216433965Sjdp{ 216533965Sjdp bfd *abfd; 216633965Sjdp struct bfd_link_info *info; 216733965Sjdp struct ecoff_debug_info *debug; 216833965Sjdp const struct ecoff_debug_swap *swap; 216933965Sjdp boolean failed; 217033965Sjdp}; 217133965Sjdp 217233965Sjdpstatic boolean 217333965Sjdpelf64_alpha_output_extsym (h, data) 217433965Sjdp struct alpha_elf_link_hash_entry *h; 217533965Sjdp PTR data; 217633965Sjdp{ 217733965Sjdp struct extsym_info *einfo = (struct extsym_info *) data; 217833965Sjdp boolean strip; 217933965Sjdp asection *sec, *output_section; 218033965Sjdp 218133965Sjdp if (h->root.indx == -2) 218233965Sjdp strip = false; 218333965Sjdp else if (((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 218433965Sjdp || (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0) 218533965Sjdp && (h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 218633965Sjdp && (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) 218733965Sjdp strip = true; 218833965Sjdp else if (einfo->info->strip == strip_all 218933965Sjdp || (einfo->info->strip == strip_some 219033965Sjdp && bfd_hash_lookup (einfo->info->keep_hash, 219133965Sjdp h->root.root.root.string, 219233965Sjdp false, false) == NULL)) 219333965Sjdp strip = true; 219433965Sjdp else 219533965Sjdp strip = false; 219633965Sjdp 219733965Sjdp if (strip) 219833965Sjdp return true; 219933965Sjdp 220033965Sjdp if (h->esym.ifd == -2) 220133965Sjdp { 220233965Sjdp h->esym.jmptbl = 0; 220333965Sjdp h->esym.cobol_main = 0; 220433965Sjdp h->esym.weakext = 0; 220533965Sjdp h->esym.reserved = 0; 220633965Sjdp h->esym.ifd = ifdNil; 220733965Sjdp h->esym.asym.value = 0; 220833965Sjdp h->esym.asym.st = stGlobal; 220933965Sjdp 221033965Sjdp if (h->root.root.type != bfd_link_hash_defined 221133965Sjdp && h->root.root.type != bfd_link_hash_defweak) 221233965Sjdp h->esym.asym.sc = scAbs; 221333965Sjdp else 221433965Sjdp { 221533965Sjdp const char *name; 221633965Sjdp 221733965Sjdp sec = h->root.root.u.def.section; 221833965Sjdp output_section = sec->output_section; 221933965Sjdp 222033965Sjdp /* When making a shared library and symbol h is the one from 222133965Sjdp the another shared library, OUTPUT_SECTION may be null. */ 222233965Sjdp if (output_section == NULL) 222333965Sjdp h->esym.asym.sc = scUndefined; 222433965Sjdp else 222533965Sjdp { 222633965Sjdp name = bfd_section_name (output_section->owner, output_section); 222733965Sjdp 222833965Sjdp if (strcmp (name, ".text") == 0) 222933965Sjdp h->esym.asym.sc = scText; 223033965Sjdp else if (strcmp (name, ".data") == 0) 223133965Sjdp h->esym.asym.sc = scData; 223233965Sjdp else if (strcmp (name, ".sdata") == 0) 223333965Sjdp h->esym.asym.sc = scSData; 223433965Sjdp else if (strcmp (name, ".rodata") == 0 223533965Sjdp || strcmp (name, ".rdata") == 0) 223633965Sjdp h->esym.asym.sc = scRData; 223733965Sjdp else if (strcmp (name, ".bss") == 0) 223833965Sjdp h->esym.asym.sc = scBss; 223933965Sjdp else if (strcmp (name, ".sbss") == 0) 224033965Sjdp h->esym.asym.sc = scSBss; 224133965Sjdp else if (strcmp (name, ".init") == 0) 224233965Sjdp h->esym.asym.sc = scInit; 224333965Sjdp else if (strcmp (name, ".fini") == 0) 224433965Sjdp h->esym.asym.sc = scFini; 224533965Sjdp else 224633965Sjdp h->esym.asym.sc = scAbs; 224733965Sjdp } 224833965Sjdp } 224933965Sjdp 225033965Sjdp h->esym.asym.reserved = 0; 225133965Sjdp h->esym.asym.index = indexNil; 225233965Sjdp } 225333965Sjdp 225433965Sjdp if (h->root.root.type == bfd_link_hash_common) 225533965Sjdp h->esym.asym.value = h->root.root.u.c.size; 225633965Sjdp else if (h->root.root.type == bfd_link_hash_defined 225733965Sjdp || h->root.root.type == bfd_link_hash_defweak) 225833965Sjdp { 225933965Sjdp if (h->esym.asym.sc == scCommon) 226033965Sjdp h->esym.asym.sc = scBss; 226133965Sjdp else if (h->esym.asym.sc == scSCommon) 226233965Sjdp h->esym.asym.sc = scSBss; 226333965Sjdp 226433965Sjdp sec = h->root.root.u.def.section; 226533965Sjdp output_section = sec->output_section; 226633965Sjdp if (output_section != NULL) 226733965Sjdp h->esym.asym.value = (h->root.root.u.def.value 226833965Sjdp + sec->output_offset 226933965Sjdp + output_section->vma); 227033965Sjdp else 227133965Sjdp h->esym.asym.value = 0; 227233965Sjdp } 227333965Sjdp else if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) 227433965Sjdp { 227533965Sjdp /* Set type and value for a symbol with a function stub. */ 227633965Sjdp h->esym.asym.st = stProc; 227733965Sjdp sec = bfd_get_section_by_name (einfo->abfd, ".plt"); 227833965Sjdp if (sec == NULL) 227933965Sjdp h->esym.asym.value = 0; 228033965Sjdp else 228133965Sjdp { 228233965Sjdp output_section = sec->output_section; 228333965Sjdp if (output_section != NULL) 228460510Sobrien h->esym.asym.value = (h->root.plt.offset 228533965Sjdp + sec->output_offset 228633965Sjdp + output_section->vma); 228733965Sjdp else 228833965Sjdp h->esym.asym.value = 0; 228933965Sjdp } 229033965Sjdp#if 0 /* FIXME? */ 229133965Sjdp h->esym.ifd = 0; 229233965Sjdp#endif 229333965Sjdp } 229433965Sjdp 229533965Sjdp if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap, 229633965Sjdp h->root.root.root.string, 229733965Sjdp &h->esym)) 229833965Sjdp { 229933965Sjdp einfo->failed = true; 230033965Sjdp return false; 230133965Sjdp } 230233965Sjdp 230333965Sjdp return true; 230433965Sjdp} 230533965Sjdp 230633965Sjdp/* FIXME: Create a runtime procedure table from the .mdebug section. 230733965Sjdp 230833965Sjdpstatic boolean 230933965Sjdpmips_elf_create_procedure_table (handle, abfd, info, s, debug) 231033965Sjdp PTR handle; 231133965Sjdp bfd *abfd; 231233965Sjdp struct bfd_link_info *info; 231333965Sjdp asection *s; 231433965Sjdp struct ecoff_debug_info *debug; 231533965Sjdp*/ 231633965Sjdp 231733965Sjdp/* Handle dynamic relocations when doing an Alpha ELF link. */ 231833965Sjdp 231933965Sjdpstatic boolean 232033965Sjdpelf64_alpha_check_relocs (abfd, info, sec, relocs) 232133965Sjdp bfd *abfd; 232233965Sjdp struct bfd_link_info *info; 232333965Sjdp asection *sec; 232433965Sjdp const Elf_Internal_Rela *relocs; 232533965Sjdp{ 232633965Sjdp bfd *dynobj; 232733965Sjdp asection *sreloc; 232833965Sjdp const char *rel_sec_name; 232933965Sjdp Elf_Internal_Shdr *symtab_hdr; 233033965Sjdp struct alpha_elf_link_hash_entry **sym_hashes; 233133965Sjdp struct alpha_elf_got_entry **local_got_entries; 233233965Sjdp const Elf_Internal_Rela *rel, *relend; 233333965Sjdp int got_created; 233433965Sjdp 233533965Sjdp if (info->relocateable) 233633965Sjdp return true; 233733965Sjdp 233833965Sjdp dynobj = elf_hash_table(info)->dynobj; 233933965Sjdp if (dynobj == NULL) 234033965Sjdp elf_hash_table(info)->dynobj = dynobj = abfd; 234133965Sjdp 234233965Sjdp sreloc = NULL; 234333965Sjdp rel_sec_name = NULL; 234433965Sjdp symtab_hdr = &elf_tdata(abfd)->symtab_hdr; 234533965Sjdp sym_hashes = alpha_elf_sym_hashes(abfd); 234633965Sjdp local_got_entries = alpha_elf_tdata(abfd)->local_got_entries; 234733965Sjdp got_created = 0; 234833965Sjdp 234933965Sjdp relend = relocs + sec->reloc_count; 235033965Sjdp for (rel = relocs; rel < relend; ++rel) 235133965Sjdp { 235233965Sjdp unsigned long r_symndx, r_type; 235333965Sjdp struct alpha_elf_link_hash_entry *h; 235433965Sjdp 235533965Sjdp r_symndx = ELF64_R_SYM (rel->r_info); 235633965Sjdp if (r_symndx < symtab_hdr->sh_info) 235733965Sjdp h = NULL; 235833965Sjdp else 235933965Sjdp { 236033965Sjdp h = sym_hashes[r_symndx - symtab_hdr->sh_info]; 236138889Sjdp 236238889Sjdp while (h->root.root.type == bfd_link_hash_indirect 236338889Sjdp || h->root.root.type == bfd_link_hash_warning) 236438889Sjdp h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link; 236538889Sjdp 236633965Sjdp h->root.elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR; 236733965Sjdp } 236833965Sjdp r_type = ELF64_R_TYPE (rel->r_info); 236933965Sjdp 237033965Sjdp switch (r_type) 237133965Sjdp { 237233965Sjdp case R_ALPHA_LITERAL: 237333965Sjdp { 237433965Sjdp struct alpha_elf_got_entry *gotent; 237533965Sjdp int flags = 0; 237633965Sjdp 237733965Sjdp if (h) 237833965Sjdp { 237933965Sjdp /* Search for and possibly create a got entry. */ 238033965Sjdp for (gotent = h->got_entries; gotent ; gotent = gotent->next) 238133965Sjdp if (gotent->gotobj == abfd && 238233965Sjdp gotent->addend == rel->r_addend) 238333965Sjdp break; 238433965Sjdp 238533965Sjdp if (!gotent) 238633965Sjdp { 238733965Sjdp gotent = ((struct alpha_elf_got_entry *) 238833965Sjdp bfd_alloc (abfd, 238933965Sjdp sizeof (struct alpha_elf_got_entry))); 239033965Sjdp if (!gotent) 239133965Sjdp return false; 239233965Sjdp 239333965Sjdp gotent->gotobj = abfd; 239433965Sjdp gotent->addend = rel->r_addend; 239533965Sjdp gotent->got_offset = -1; 239633965Sjdp gotent->flags = 0; 239760510Sobrien gotent->use_count = 1; 239833965Sjdp 239933965Sjdp gotent->next = h->got_entries; 240033965Sjdp h->got_entries = gotent; 240133965Sjdp 240233965Sjdp alpha_elf_tdata (abfd)->total_got_entries++; 240333965Sjdp } 240460510Sobrien else 240560510Sobrien gotent->use_count += 1; 240633965Sjdp } 240733965Sjdp else 240833965Sjdp { 240933965Sjdp /* This is a local .got entry -- record for merge. */ 241033965Sjdp if (!local_got_entries) 241133965Sjdp { 241233965Sjdp size_t size; 241333965Sjdp size = (symtab_hdr->sh_info 241433965Sjdp * sizeof (struct alpha_elf_got_entry *)); 241533965Sjdp 241633965Sjdp local_got_entries = ((struct alpha_elf_got_entry **) 241733965Sjdp bfd_alloc (abfd, size)); 241833965Sjdp if (!local_got_entries) 241933965Sjdp return false; 242033965Sjdp 242133965Sjdp memset (local_got_entries, 0, size); 242233965Sjdp alpha_elf_tdata (abfd)->local_got_entries = 242333965Sjdp local_got_entries; 242433965Sjdp } 242533965Sjdp 242633965Sjdp for (gotent = local_got_entries[ELF64_R_SYM(rel->r_info)]; 242733965Sjdp gotent != NULL && gotent->addend != rel->r_addend; 242833965Sjdp gotent = gotent->next) 242933965Sjdp continue; 243033965Sjdp if (!gotent) 243133965Sjdp { 243233965Sjdp gotent = ((struct alpha_elf_got_entry *) 243333965Sjdp bfd_alloc (abfd, 243433965Sjdp sizeof (struct alpha_elf_got_entry))); 243533965Sjdp if (!gotent) 243633965Sjdp return false; 243733965Sjdp 243833965Sjdp gotent->gotobj = abfd; 243933965Sjdp gotent->addend = rel->r_addend; 244033965Sjdp gotent->got_offset = -1; 244133965Sjdp gotent->flags = 0; 244260510Sobrien gotent->use_count = 1; 244333965Sjdp 244433965Sjdp gotent->next = local_got_entries[ELF64_R_SYM(rel->r_info)]; 244533965Sjdp local_got_entries[ELF64_R_SYM(rel->r_info)] = gotent; 244633965Sjdp 244733965Sjdp alpha_elf_tdata(abfd)->total_got_entries++; 244833965Sjdp alpha_elf_tdata(abfd)->n_local_got_entries++; 244933965Sjdp } 245060510Sobrien else 245160510Sobrien gotent->use_count += 1; 245233965Sjdp } 245333965Sjdp 245433965Sjdp /* Remember how this literal is used from its LITUSEs. 245533965Sjdp This will be important when it comes to decide if we can 245633965Sjdp create a .plt entry for a function symbol. */ 245733965Sjdp if (rel+1 < relend 245833965Sjdp && ELF64_R_TYPE (rel[1].r_info) == R_ALPHA_LITUSE) 245933965Sjdp { 246033965Sjdp do 246133965Sjdp { 246233965Sjdp ++rel; 246333965Sjdp if (rel->r_addend >= 1 && rel->r_addend <= 3) 246433965Sjdp flags |= 1 << rel->r_addend; 246533965Sjdp } 246633965Sjdp while (rel+1 < relend && 246733965Sjdp ELF64_R_TYPE (rel[1].r_info) == R_ALPHA_LITUSE); 246833965Sjdp } 246933965Sjdp else 247033965Sjdp { 247133965Sjdp /* No LITUSEs -- presumably the address is not being 247233965Sjdp loaded for nothing. */ 247333965Sjdp flags = ALPHA_ELF_LINK_HASH_LU_ADDR; 247433965Sjdp } 247533965Sjdp 247633965Sjdp gotent->flags |= flags; 247733965Sjdp if (h) 247833965Sjdp { 247933965Sjdp /* Make a guess as to whether a .plt entry will be needed. */ 248033965Sjdp if ((h->flags |= flags) == ALPHA_ELF_LINK_HASH_LU_FUNC) 248133965Sjdp h->root.elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; 248233965Sjdp else 248333965Sjdp h->root.elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; 248433965Sjdp } 248533965Sjdp } 248633965Sjdp /* FALLTHRU */ 248733965Sjdp 248833965Sjdp case R_ALPHA_GPDISP: 248933965Sjdp case R_ALPHA_GPREL32: 249060510Sobrien case R_ALPHA_GPRELHIGH: 249160510Sobrien case R_ALPHA_GPRELLOW: 249233965Sjdp /* We don't actually use the .got here, but the sections must 249333965Sjdp be created before the linker maps input sections to output 249433965Sjdp sections. */ 249533965Sjdp if (!got_created) 249633965Sjdp { 249733965Sjdp if (!elf64_alpha_create_got_section (abfd, info)) 249833965Sjdp return false; 249933965Sjdp 250033965Sjdp /* Make sure the object's gotobj is set to itself so 250133965Sjdp that we default to every object with its own .got. 250233965Sjdp We'll merge .gots later once we've collected each 250333965Sjdp object's info. */ 250433965Sjdp alpha_elf_tdata(abfd)->gotobj = abfd; 250533965Sjdp 250633965Sjdp got_created = 1; 250733965Sjdp } 250833965Sjdp break; 250933965Sjdp 251033965Sjdp case R_ALPHA_SREL16: 251133965Sjdp case R_ALPHA_SREL32: 251233965Sjdp case R_ALPHA_SREL64: 251333965Sjdp if (h == NULL) 251433965Sjdp break; 251533965Sjdp /* FALLTHRU */ 251633965Sjdp 251733965Sjdp case R_ALPHA_REFLONG: 251833965Sjdp case R_ALPHA_REFQUAD: 251933965Sjdp if (rel_sec_name == NULL) 252033965Sjdp { 252133965Sjdp rel_sec_name = (bfd_elf_string_from_elf_section 252233965Sjdp (abfd, elf_elfheader(abfd)->e_shstrndx, 252333965Sjdp elf_section_data(sec)->rel_hdr.sh_name)); 252433965Sjdp if (rel_sec_name == NULL) 252533965Sjdp return false; 252633965Sjdp 252733965Sjdp BFD_ASSERT (strncmp (rel_sec_name, ".rela", 5) == 0 252833965Sjdp && strcmp (bfd_get_section_name (abfd, sec), 252933965Sjdp rel_sec_name+5) == 0); 253033965Sjdp } 253133965Sjdp 253233965Sjdp /* We need to create the section here now whether we eventually 253333965Sjdp use it or not so that it gets mapped to an output section by 253433965Sjdp the linker. If not used, we'll kill it in 253533965Sjdp size_dynamic_sections. */ 253633965Sjdp if (sreloc == NULL) 253733965Sjdp { 253833965Sjdp sreloc = bfd_get_section_by_name (dynobj, rel_sec_name); 253933965Sjdp if (sreloc == NULL) 254033965Sjdp { 254133965Sjdp sreloc = bfd_make_section (dynobj, rel_sec_name); 254233965Sjdp if (sreloc == NULL 254333965Sjdp || !bfd_set_section_flags (dynobj, sreloc, 254433965Sjdp (SEC_ALLOC|SEC_LOAD 254533965Sjdp | SEC_HAS_CONTENTS 254633965Sjdp | SEC_IN_MEMORY 254733965Sjdp | SEC_LINKER_CREATED 254833965Sjdp | SEC_READONLY)) 254933965Sjdp || !bfd_set_section_alignment (dynobj, sreloc, 3)) 255033965Sjdp return false; 255133965Sjdp } 255233965Sjdp } 255333965Sjdp 255433965Sjdp if (h) 255533965Sjdp { 255633965Sjdp /* Since we havn't seen all of the input symbols yet, we 255733965Sjdp don't know whether we'll actually need a dynamic relocation 255833965Sjdp entry for this reloc. So make a record of it. Once we 255933965Sjdp find out if this thing needs dynamic relocation we'll 256033965Sjdp expand the relocation sections by the appropriate amount. */ 256133965Sjdp 256233965Sjdp struct alpha_elf_reloc_entry *rent; 256333965Sjdp 256433965Sjdp for (rent = h->reloc_entries; rent; rent = rent->next) 256533965Sjdp if (rent->rtype == r_type && rent->srel == sreloc) 256633965Sjdp break; 256733965Sjdp 256833965Sjdp if (!rent) 256933965Sjdp { 257033965Sjdp rent = ((struct alpha_elf_reloc_entry *) 257133965Sjdp bfd_alloc (abfd, 257233965Sjdp sizeof (struct alpha_elf_reloc_entry))); 257333965Sjdp if (!rent) 257433965Sjdp return false; 257533965Sjdp 257633965Sjdp rent->srel = sreloc; 257733965Sjdp rent->rtype = r_type; 257833965Sjdp rent->count = 1; 257933965Sjdp 258033965Sjdp rent->next = h->reloc_entries; 258133965Sjdp h->reloc_entries = rent; 258233965Sjdp } 258333965Sjdp else 258433965Sjdp rent->count++; 258533965Sjdp } 258660510Sobrien else if (info->shared && (sec->flags & SEC_ALLOC)) 258733965Sjdp { 258860510Sobrien /* If this is a shared library, and the section is to be 258960510Sobrien loaded into memory, we need a RELATIVE reloc. */ 259033965Sjdp sreloc->_raw_size += sizeof (Elf64_External_Rela); 259133965Sjdp } 259233965Sjdp break; 259333965Sjdp } 259433965Sjdp } 259533965Sjdp 259633965Sjdp return true; 259733965Sjdp} 259833965Sjdp 259933965Sjdp/* Adjust a symbol defined by a dynamic object and referenced by a 260033965Sjdp regular object. The current definition is in some section of the 260133965Sjdp dynamic object, but we're not including those sections. We have to 260233965Sjdp change the definition to something the rest of the link can 260333965Sjdp understand. */ 260433965Sjdp 260533965Sjdpstatic boolean 260633965Sjdpelf64_alpha_adjust_dynamic_symbol (info, h) 260733965Sjdp struct bfd_link_info *info; 260833965Sjdp struct elf_link_hash_entry *h; 260933965Sjdp{ 261033965Sjdp bfd *dynobj; 261133965Sjdp asection *s; 261233965Sjdp struct alpha_elf_link_hash_entry *ah; 261333965Sjdp 261433965Sjdp dynobj = elf_hash_table(info)->dynobj; 261533965Sjdp ah = (struct alpha_elf_link_hash_entry *)h; 261633965Sjdp 261733965Sjdp /* Now that we've seen all of the input symbols, finalize our decision 261833965Sjdp about whether this symbol should get a .plt entry. */ 261933965Sjdp 262033965Sjdp if (h->root.type != bfd_link_hash_undefweak 262133965Sjdp && alpha_elf_dynamic_symbol_p (h, info) 262233965Sjdp && ((h->type == STT_FUNC 262333965Sjdp && !(ah->flags & ALPHA_ELF_LINK_HASH_LU_ADDR)) 262433965Sjdp || (h->type == STT_NOTYPE 262533965Sjdp && ah->flags == ALPHA_ELF_LINK_HASH_LU_FUNC)) 262633965Sjdp /* Don't prevent otherwise valid programs from linking by attempting 262733965Sjdp to create a new .got entry somewhere. A Correct Solution would be 262833965Sjdp to add a new .got section to a new object file and let it be merged 262933965Sjdp somewhere later. But for now don't bother. */ 263033965Sjdp && ah->got_entries) 263133965Sjdp { 263233965Sjdp h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; 263333965Sjdp 263433965Sjdp s = bfd_get_section_by_name(dynobj, ".plt"); 263533965Sjdp if (!s && !elf64_alpha_create_dynamic_sections (dynobj, info)) 263633965Sjdp return false; 263733965Sjdp 263833965Sjdp /* The first bit of the .plt is reserved. */ 263933965Sjdp if (s->_raw_size == 0) 264033965Sjdp s->_raw_size = PLT_HEADER_SIZE; 264133965Sjdp 264260510Sobrien h->plt.offset = s->_raw_size; 264333965Sjdp s->_raw_size += PLT_ENTRY_SIZE; 264433965Sjdp 264533965Sjdp /* If this symbol is not defined in a regular file, and we are not 264633965Sjdp generating a shared library, then set the symbol to the location 264733965Sjdp in the .plt. This is required to make function pointers compare 264833965Sjdp equal between the normal executable and the shared library. */ 264948850Sdfr if (! info->shared 265048850Sdfr && h->root.type != bfd_link_hash_defweak) 265133965Sjdp { 265233965Sjdp h->root.u.def.section = s; 265360510Sobrien h->root.u.def.value = h->plt.offset; 265433965Sjdp } 265533965Sjdp 265633965Sjdp /* We also need a JMP_SLOT entry in the .rela.plt section. */ 265733965Sjdp s = bfd_get_section_by_name (dynobj, ".rela.plt"); 265833965Sjdp BFD_ASSERT (s != NULL); 265933965Sjdp s->_raw_size += sizeof (Elf64_External_Rela); 266033965Sjdp 266133965Sjdp return true; 266233965Sjdp } 266333965Sjdp else 266433965Sjdp h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; 266533965Sjdp 266633965Sjdp /* If this is a weak symbol, and there is a real definition, the 266733965Sjdp processor independent code will have arranged for us to see the 266833965Sjdp real definition first, and we can just use the same value. */ 266933965Sjdp if (h->weakdef != NULL) 267033965Sjdp { 267133965Sjdp BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined 267233965Sjdp || h->weakdef->root.type == bfd_link_hash_defweak); 267333965Sjdp h->root.u.def.section = h->weakdef->root.u.def.section; 267433965Sjdp h->root.u.def.value = h->weakdef->root.u.def.value; 267533965Sjdp return true; 267633965Sjdp } 267733965Sjdp 267833965Sjdp /* This is a reference to a symbol defined by a dynamic object which 267933965Sjdp is not a function. The Alpha, since it uses .got entries for all 268033965Sjdp symbols even in regular objects, does not need the hackery of a 268133965Sjdp .dynbss section and COPY dynamic relocations. */ 268233965Sjdp 268333965Sjdp return true; 268433965Sjdp} 268533965Sjdp 268638889Sjdp/* Symbol versioning can create new symbols, and make our old symbols 268738889Sjdp indirect to the new ones. Consolidate the got and reloc information 268838889Sjdp in these situations. */ 268938889Sjdp 269038889Sjdpstatic boolean 269138889Sjdpelf64_alpha_merge_ind_symbols (hi, dummy) 269238889Sjdp struct alpha_elf_link_hash_entry *hi; 269338889Sjdp PTR dummy; 269438889Sjdp{ 269538889Sjdp struct alpha_elf_link_hash_entry *hs; 269638889Sjdp 269738889Sjdp if (hi->root.root.type != bfd_link_hash_indirect) 269838889Sjdp return true; 269938889Sjdp hs = hi; 270038889Sjdp do { 270138889Sjdp hs = (struct alpha_elf_link_hash_entry *)hs->root.root.u.i.link; 270238889Sjdp } while (hs->root.root.type == bfd_link_hash_indirect); 270338889Sjdp 270438889Sjdp /* Merge the flags. Whee. */ 270538889Sjdp 270638889Sjdp hs->flags |= hi->flags; 270738889Sjdp 270838889Sjdp /* Merge the .got entries. Cannibalize the old symbol's list in 270938889Sjdp doing so, since we don't need it anymore. */ 271038889Sjdp 271138889Sjdp if (hs->got_entries == NULL) 271238889Sjdp hs->got_entries = hi->got_entries; 271338889Sjdp else 271438889Sjdp { 271538889Sjdp struct alpha_elf_got_entry *gi, *gs, *gin, *gsh; 271638889Sjdp 271738889Sjdp gsh = hs->got_entries; 271838889Sjdp for (gi = hi->got_entries; gi ; gi = gin) 271938889Sjdp { 272038889Sjdp gin = gi->next; 272138889Sjdp for (gs = gsh; gs ; gs = gs->next) 272260510Sobrien if (gi->gotobj == gs->gotobj && gi->addend == gs->addend) 272338889Sjdp goto got_found; 272438889Sjdp gi->next = hs->got_entries; 272538889Sjdp hs->got_entries = gi; 272638889Sjdp got_found:; 272738889Sjdp } 272838889Sjdp } 272938889Sjdp hi->got_entries = NULL; 273038889Sjdp 273138889Sjdp /* And similar for the reloc entries. */ 273238889Sjdp 273338889Sjdp if (hs->reloc_entries == NULL) 273438889Sjdp hs->reloc_entries = hi->reloc_entries; 273538889Sjdp else 273638889Sjdp { 273738889Sjdp struct alpha_elf_reloc_entry *ri, *rs, *rin, *rsh; 273838889Sjdp 273938889Sjdp rsh = hs->reloc_entries; 274038889Sjdp for (ri = hi->reloc_entries; ri ; ri = rin) 274138889Sjdp { 274238889Sjdp rin = ri->next; 274338889Sjdp for (rs = rsh; rs ; rs = rs->next) 274438889Sjdp if (ri->rtype == rs->rtype) 274538889Sjdp { 274638889Sjdp rs->count += ri->count; 274738889Sjdp goto found_reloc; 274838889Sjdp } 274938889Sjdp ri->next = hs->reloc_entries; 275038889Sjdp hs->reloc_entries = ri; 275138889Sjdp found_reloc:; 275238889Sjdp } 275338889Sjdp } 275438889Sjdp hi->reloc_entries = NULL; 275538889Sjdp 275638889Sjdp return true; 275738889Sjdp} 275838889Sjdp 275933965Sjdp/* Is it possible to merge two object file's .got tables? */ 276033965Sjdp 276133965Sjdpstatic boolean 276233965Sjdpelf64_alpha_can_merge_gots (a, b) 276333965Sjdp bfd *a, *b; 276433965Sjdp{ 276533965Sjdp int total = alpha_elf_tdata (a)->total_got_entries; 276660510Sobrien bfd *bsub; 276733965Sjdp 276833965Sjdp /* Trivial quick fallout test. */ 276933965Sjdp if (total + alpha_elf_tdata (b)->total_got_entries <= MAX_GOT_ENTRIES) 277033965Sjdp return true; 277133965Sjdp 277233965Sjdp /* By their nature, local .got entries cannot be merged. */ 277333965Sjdp if ((total += alpha_elf_tdata (b)->n_local_got_entries) > MAX_GOT_ENTRIES) 277433965Sjdp return false; 277533965Sjdp 277633965Sjdp /* Failing the common trivial comparison, we must effectively 277733965Sjdp perform the merge. Not actually performing the merge means that 277833965Sjdp we don't have to store undo information in case we fail. */ 277960510Sobrien for (bsub = b; bsub ; bsub = alpha_elf_tdata (bsub)->in_got_link_next) 278060510Sobrien { 278160510Sobrien struct alpha_elf_link_hash_entry **hashes = alpha_elf_sym_hashes (bsub); 278260510Sobrien Elf_Internal_Shdr *symtab_hdr = &elf_tdata (bsub)->symtab_hdr; 278360510Sobrien int i, n; 278433965Sjdp 278560510Sobrien n = symtab_hdr->sh_size / symtab_hdr->sh_entsize - symtab_hdr->sh_info; 278660510Sobrien for (i = 0; i < n; ++i) 278760510Sobrien { 278860510Sobrien struct alpha_elf_got_entry *ae, *be; 278960510Sobrien struct alpha_elf_link_hash_entry *h; 279038889Sjdp 279160510Sobrien h = hashes[i]; 279260510Sobrien while (h->root.root.type == bfd_link_hash_indirect 279360510Sobrien || h->root.root.type == bfd_link_hash_warning) 279460510Sobrien h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link; 279538889Sjdp 279660510Sobrien for (be = h->got_entries; be ; be = be->next) 279760510Sobrien { 279860510Sobrien if (be->use_count == 0) 279960510Sobrien continue; 280060510Sobrien if (be->gotobj != b) 280160510Sobrien continue; 280233965Sjdp 280360510Sobrien for (ae = h->got_entries; ae ; ae = ae->next) 280460510Sobrien if (ae->gotobj == a && ae->addend == be->addend) 280560510Sobrien goto global_found; 280633965Sjdp 280760510Sobrien if (++total > MAX_GOT_ENTRIES) 280860510Sobrien return false; 280960510Sobrien global_found:; 281060510Sobrien } 281160510Sobrien } 281260510Sobrien } 281333965Sjdp 281433965Sjdp return true; 281533965Sjdp} 281633965Sjdp 281733965Sjdp/* Actually merge two .got tables. */ 281833965Sjdp 281933965Sjdpstatic void 282033965Sjdpelf64_alpha_merge_gots (a, b) 282133965Sjdp bfd *a, *b; 282233965Sjdp{ 282360510Sobrien int total = alpha_elf_tdata (a)->total_got_entries; 282460510Sobrien bfd *bsub; 282533965Sjdp 282633965Sjdp /* Remember local expansion. */ 282733965Sjdp { 282860510Sobrien int e = alpha_elf_tdata (b)->n_local_got_entries; 282933965Sjdp total += e; 283060510Sobrien alpha_elf_tdata (a)->n_local_got_entries += e; 283133965Sjdp } 283233965Sjdp 283360510Sobrien for (bsub = b; bsub ; bsub = alpha_elf_tdata (bsub)->in_got_link_next) 283460510Sobrien { 283560510Sobrien struct alpha_elf_got_entry **local_got_entries; 283660510Sobrien struct alpha_elf_link_hash_entry **hashes; 283760510Sobrien Elf_Internal_Shdr *symtab_hdr; 283860510Sobrien int i, n; 283933965Sjdp 284060510Sobrien /* Let the local .got entries know they are part of a new subsegment. */ 284160510Sobrien local_got_entries = alpha_elf_tdata (bsub)->local_got_entries; 284260510Sobrien if (local_got_entries) 284360510Sobrien { 284460510Sobrien n = elf_tdata (bsub)->symtab_hdr.sh_info; 284560510Sobrien for (i = 0; i < n; ++i) 284660510Sobrien { 284760510Sobrien struct alpha_elf_got_entry *ent; 284860510Sobrien for (ent = local_got_entries[i]; ent; ent = ent->next) 284960510Sobrien ent->gotobj = a; 285060510Sobrien } 285160510Sobrien } 285233965Sjdp 285360510Sobrien /* Merge the global .got entries. */ 285460510Sobrien hashes = alpha_elf_sym_hashes (bsub); 285560510Sobrien symtab_hdr = &elf_tdata (bsub)->symtab_hdr; 285633965Sjdp 285760510Sobrien n = symtab_hdr->sh_size / symtab_hdr->sh_entsize - symtab_hdr->sh_info; 285860510Sobrien for (i = 0; i < n; ++i) 285960510Sobrien { 286060510Sobrien struct alpha_elf_got_entry *ae, *be, **pbe, **start; 286160510Sobrien struct alpha_elf_link_hash_entry *h; 286238889Sjdp 286360510Sobrien h = hashes[i]; 286460510Sobrien while (h->root.root.type == bfd_link_hash_indirect 286560510Sobrien || h->root.root.type == bfd_link_hash_warning) 286660510Sobrien h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link; 286738889Sjdp 286860510Sobrien start = &h->got_entries; 286960510Sobrien for (pbe = start, be = *start; be ; pbe = &be->next, be = be->next) 287060510Sobrien { 287160510Sobrien if (be->use_count == 0) 287260510Sobrien { 287333965Sjdp *pbe = be->next; 287460510Sobrien continue; 287560510Sobrien } 287660510Sobrien if (be->gotobj != b) 287760510Sobrien continue; 287833965Sjdp 287960510Sobrien for (ae = *start; ae ; ae = ae->next) 288060510Sobrien if (ae->gotobj == a && ae->addend == be->addend) 288160510Sobrien { 288260510Sobrien ae->flags |= be->flags; 288360510Sobrien ae->use_count += be->use_count; 288460510Sobrien *pbe = be->next; 288560510Sobrien goto global_found; 288660510Sobrien } 288760510Sobrien be->gotobj = a; 288860510Sobrien total += 1; 288960510Sobrien 289060510Sobrien global_found:; 289160510Sobrien } 289260510Sobrien } 289360510Sobrien 289460510Sobrien alpha_elf_tdata (bsub)->gotobj = a; 289560510Sobrien } 289660510Sobrien alpha_elf_tdata (a)->total_got_entries = total; 289760510Sobrien 289860510Sobrien /* Merge the two in_got chains. */ 289960510Sobrien { 290060510Sobrien bfd *next; 290160510Sobrien 290260510Sobrien bsub = a; 290360510Sobrien while ((next = alpha_elf_tdata (bsub)->in_got_link_next) != NULL) 290460510Sobrien bsub = next; 290560510Sobrien 290660510Sobrien alpha_elf_tdata (bsub)->in_got_link_next = b; 290733965Sjdp } 290833965Sjdp} 290933965Sjdp 291033965Sjdp/* Calculate the offsets for the got entries. */ 291133965Sjdp 291233965Sjdpstatic boolean 291333965Sjdpelf64_alpha_calc_got_offsets_for_symbol (h, arg) 291433965Sjdp struct alpha_elf_link_hash_entry *h; 291533965Sjdp PTR arg; 291633965Sjdp{ 291733965Sjdp struct alpha_elf_got_entry *gotent; 291833965Sjdp 291933965Sjdp for (gotent = h->got_entries; gotent; gotent = gotent->next) 292060510Sobrien if (gotent->use_count > 0) 292160510Sobrien { 292260510Sobrien bfd_size_type *plge 292360510Sobrien = &alpha_elf_tdata (gotent->gotobj)->got->_raw_size; 292433965Sjdp 292560510Sobrien gotent->got_offset = *plge; 292660510Sobrien *plge += 8; 292760510Sobrien } 292860510Sobrien 292933965Sjdp return true; 293033965Sjdp} 293133965Sjdp 293233965Sjdpstatic void 293333965Sjdpelf64_alpha_calc_got_offsets (info) 293433965Sjdp struct bfd_link_info *info; 293533965Sjdp{ 293633965Sjdp bfd *i, *got_list = alpha_elf_hash_table(info)->got_list; 293733965Sjdp 293833965Sjdp /* First, zero out the .got sizes, as we may be recalculating the 293933965Sjdp .got after optimizing it. */ 294033965Sjdp for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next) 294133965Sjdp alpha_elf_tdata(i)->got->_raw_size = 0; 294233965Sjdp 294333965Sjdp /* Next, fill in the offsets for all the global entries. */ 294433965Sjdp alpha_elf_link_hash_traverse (alpha_elf_hash_table (info), 294533965Sjdp elf64_alpha_calc_got_offsets_for_symbol, 294633965Sjdp NULL); 294733965Sjdp 294833965Sjdp /* Finally, fill in the offsets for the local entries. */ 294933965Sjdp for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next) 295033965Sjdp { 295133965Sjdp bfd_size_type got_offset = alpha_elf_tdata(i)->got->_raw_size; 295233965Sjdp bfd *j; 295333965Sjdp 295433965Sjdp for (j = i; j ; j = alpha_elf_tdata(j)->in_got_link_next) 295533965Sjdp { 295633965Sjdp struct alpha_elf_got_entry **local_got_entries, *gotent; 295733965Sjdp int k, n; 295833965Sjdp 295933965Sjdp local_got_entries = alpha_elf_tdata(j)->local_got_entries; 296033965Sjdp if (!local_got_entries) 296133965Sjdp continue; 296233965Sjdp 296333965Sjdp for (k = 0, n = elf_tdata(j)->symtab_hdr.sh_info; k < n; ++k) 296433965Sjdp for (gotent = local_got_entries[k]; gotent; gotent = gotent->next) 296560510Sobrien if (gotent->use_count > 0) 296660510Sobrien { 296760510Sobrien gotent->got_offset = got_offset; 296860510Sobrien got_offset += 8; 296960510Sobrien } 297033965Sjdp } 297133965Sjdp 297233965Sjdp alpha_elf_tdata(i)->got->_raw_size = got_offset; 297360510Sobrien alpha_elf_tdata(i)->got->_cooked_size = got_offset; 297433965Sjdp } 297533965Sjdp} 297633965Sjdp 297733965Sjdp/* Constructs the gots. */ 297833965Sjdp 297933965Sjdpstatic boolean 298060510Sobrienelf64_alpha_size_got_sections (output_bfd, info) 298133965Sjdp bfd *output_bfd; 298233965Sjdp struct bfd_link_info *info; 298333965Sjdp{ 298460510Sobrien bfd *i, *got_list, *cur_got_obj; 298560510Sobrien int something_changed = 0; 298633965Sjdp 298760510Sobrien got_list = alpha_elf_hash_table (info)->got_list; 298833965Sjdp 298960510Sobrien /* On the first time through, pretend we have an existing got list 299060510Sobrien consisting of all of the input files. */ 299160510Sobrien if (got_list == NULL) 299233965Sjdp { 299360510Sobrien for (i = info->input_bfds; i ; i = i->link_next) 299460510Sobrien { 299560510Sobrien bfd *this_got = alpha_elf_tdata (i)->gotobj; 299660510Sobrien if (this_got == NULL) 299760510Sobrien continue; 299833965Sjdp 299960510Sobrien /* We are assuming no merging has yet ocurred. */ 300060510Sobrien BFD_ASSERT (this_got == i); 300133965Sjdp 300260510Sobrien if (alpha_elf_tdata (this_got)->total_got_entries > MAX_GOT_ENTRIES) 300333965Sjdp { 300460510Sobrien /* Yikes! A single object file has too many entries. */ 300560510Sobrien (*_bfd_error_handler) 300660510Sobrien (_("%s: .got subsegment exceeds 64K (size %d)"), 300760510Sobrien bfd_get_filename (i), 300860510Sobrien alpha_elf_tdata (this_got)->total_got_entries * 8); 300960510Sobrien return false; 301033965Sjdp } 301160510Sobrien 301260510Sobrien if (got_list == NULL) 301360510Sobrien got_list = this_got; 301433965Sjdp else 301560510Sobrien alpha_elf_tdata(cur_got_obj)->got_link_next = this_got; 301660510Sobrien cur_got_obj = this_got; 301733965Sjdp } 301860510Sobrien 301960510Sobrien /* Strange degenerate case of no got references. */ 302060510Sobrien if (got_list == NULL) 302160510Sobrien return true; 302260510Sobrien 302360510Sobrien alpha_elf_hash_table (info)->got_list = got_list; 302460510Sobrien 302560510Sobrien /* Force got offsets to be recalculated. */ 302660510Sobrien something_changed = 1; 302760510Sobrien } 302860510Sobrien 302960510Sobrien cur_got_obj = got_list; 303060510Sobrien i = alpha_elf_tdata(cur_got_obj)->got_link_next; 303160510Sobrien while (i != NULL) 303260510Sobrien { 303360510Sobrien if (elf64_alpha_can_merge_gots (cur_got_obj, i)) 303460510Sobrien { 303560510Sobrien elf64_alpha_merge_gots (cur_got_obj, i); 303660510Sobrien i = alpha_elf_tdata(i)->got_link_next; 303760510Sobrien alpha_elf_tdata(cur_got_obj)->got_link_next = i; 303860510Sobrien something_changed = 1; 303960510Sobrien } 304033965Sjdp else 304133965Sjdp { 304233965Sjdp cur_got_obj = i; 304360510Sobrien i = alpha_elf_tdata(i)->got_link_next; 304433965Sjdp } 304533965Sjdp } 304633965Sjdp 304760510Sobrien /* Once the gots have been merged, fill in the got offsets for 304860510Sobrien everything therein. */ 304960510Sobrien if (1 || something_changed) 305060510Sobrien elf64_alpha_calc_got_offsets (info); 305133965Sjdp 305260510Sobrien return true; 305360510Sobrien} 305433965Sjdp 305560510Sobrienstatic boolean 305660510Sobrienelf64_alpha_always_size_sections (output_bfd, info) 305760510Sobrien bfd *output_bfd; 305860510Sobrien struct bfd_link_info *info; 305960510Sobrien{ 306060510Sobrien bfd *i; 306160510Sobrien 306260510Sobrien if (info->relocateable) 306360510Sobrien return true; 306460510Sobrien 306560510Sobrien /* First, take care of the indirect symbols created by versioning. */ 306660510Sobrien alpha_elf_link_hash_traverse (alpha_elf_hash_table (info), 306760510Sobrien elf64_alpha_merge_ind_symbols, 306860510Sobrien NULL); 306960510Sobrien 307060510Sobrien if (!elf64_alpha_size_got_sections (output_bfd, info)) 307160510Sobrien return false; 307260510Sobrien 307333965Sjdp /* Allocate space for all of the .got subsections. */ 307460510Sobrien i = alpha_elf_hash_table (info)->got_list; 307560510Sobrien for ( ; i ; i = alpha_elf_tdata(i)->got_link_next) 307633965Sjdp { 307733965Sjdp asection *s = alpha_elf_tdata(i)->got; 307833965Sjdp if (s->_raw_size > 0) 307933965Sjdp { 308033965Sjdp s->contents = (bfd_byte *) bfd_zalloc (i, s->_raw_size); 308133965Sjdp if (s->contents == NULL) 308233965Sjdp return false; 308333965Sjdp } 308433965Sjdp } 308533965Sjdp 308633965Sjdp return true; 308733965Sjdp} 308833965Sjdp 308933965Sjdp/* Work out the sizes of the dynamic relocation entries. */ 309033965Sjdp 309133965Sjdpstatic boolean 309233965Sjdpelf64_alpha_calc_dynrel_sizes (h, info) 309333965Sjdp struct alpha_elf_link_hash_entry *h; 309433965Sjdp struct bfd_link_info *info; 309533965Sjdp{ 309633965Sjdp /* If the symbol was defined as a common symbol in a regular object 309733965Sjdp file, and there was no definition in any dynamic object, then the 309833965Sjdp linker will have allocated space for the symbol in a common 309933965Sjdp section but the ELF_LINK_HASH_DEF_REGULAR flag will not have been 310033965Sjdp set. This is done for dynamic symbols in 310133965Sjdp elf_adjust_dynamic_symbol but this is not done for non-dynamic 310233965Sjdp symbols, somehow. */ 310333965Sjdp if (((h->root.elf_link_hash_flags 310433965Sjdp & (ELF_LINK_HASH_DEF_REGULAR 310533965Sjdp | ELF_LINK_HASH_REF_REGULAR 310633965Sjdp | ELF_LINK_HASH_DEF_DYNAMIC)) 310733965Sjdp == ELF_LINK_HASH_REF_REGULAR) 310833965Sjdp && (h->root.root.type == bfd_link_hash_defined 310933965Sjdp || h->root.root.type == bfd_link_hash_defweak) 311033965Sjdp && !(h->root.root.u.def.section->owner->flags & DYNAMIC)) 311133965Sjdp { 311233965Sjdp h->root.elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; 311333965Sjdp } 311433965Sjdp 311533965Sjdp /* If the symbol is dynamic, we'll need all the relocations in their 311660510Sobrien natural form. If this is a shared object, and it has been forced 311760510Sobrien local, we'll need the same number of RELATIVE relocations. */ 311860510Sobrien 311960510Sobrien if (alpha_elf_dynamic_symbol_p (&h->root, info) || info->shared) 312033965Sjdp { 312133965Sjdp struct alpha_elf_reloc_entry *relent; 312248850Sdfr bfd *dynobj; 312348850Sdfr struct alpha_elf_got_entry *gotent; 312448850Sdfr bfd_size_type count; 312548850Sdfr asection *srel; 312633965Sjdp 312733965Sjdp for (relent = h->reloc_entries; relent; relent = relent->next) 312860510Sobrien if (relent->rtype == R_ALPHA_REFLONG 312960510Sobrien || relent->rtype == R_ALPHA_REFQUAD) 313060510Sobrien { 313160510Sobrien relent->srel->_raw_size += 313260510Sobrien sizeof(Elf64_External_Rela) * relent->count; 313360510Sobrien } 313433965Sjdp 313548850Sdfr dynobj = elf_hash_table(info)->dynobj; 313648850Sdfr count = 0; 313748850Sdfr 313848850Sdfr for (gotent = h->got_entries; gotent ; gotent = gotent->next) 313948850Sdfr count++; 314048850Sdfr 314148850Sdfr /* If we are using a .plt entry, subtract one, as the first 314248850Sdfr reference uses a .rela.plt entry instead. */ 314360510Sobrien if (h->root.plt.offset != MINUS_ONE) 314448850Sdfr count--; 314548850Sdfr 314648850Sdfr if (count > 0) 314733965Sjdp { 314848850Sdfr srel = bfd_get_section_by_name (dynobj, ".rela.got"); 314948850Sdfr BFD_ASSERT (srel != NULL); 315048850Sdfr srel->_raw_size += sizeof (Elf64_External_Rela) * count; 315133965Sjdp } 315233965Sjdp } 315348850Sdfr 315433965Sjdp return true; 315533965Sjdp} 315633965Sjdp 315733965Sjdp/* Set the sizes of the dynamic sections. */ 315833965Sjdp 315933965Sjdpstatic boolean 316033965Sjdpelf64_alpha_size_dynamic_sections (output_bfd, info) 316133965Sjdp bfd *output_bfd; 316233965Sjdp struct bfd_link_info *info; 316333965Sjdp{ 316433965Sjdp bfd *dynobj; 316533965Sjdp asection *s; 316633965Sjdp boolean reltext; 316733965Sjdp boolean relplt; 316833965Sjdp 316933965Sjdp dynobj = elf_hash_table(info)->dynobj; 317033965Sjdp BFD_ASSERT(dynobj != NULL); 317133965Sjdp 317233965Sjdp if (elf_hash_table (info)->dynamic_sections_created) 317333965Sjdp { 317433965Sjdp /* Set the contents of the .interp section to the interpreter. */ 317533965Sjdp if (!info->shared) 317633965Sjdp { 317733965Sjdp s = bfd_get_section_by_name (dynobj, ".interp"); 317833965Sjdp BFD_ASSERT (s != NULL); 317933965Sjdp s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; 318033965Sjdp s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; 318133965Sjdp } 318233965Sjdp 318333965Sjdp /* Now that we've seen all of the input files, we can decide which 318433965Sjdp symbols need dynamic relocation entries and which don't. We've 318533965Sjdp collected information in check_relocs that we can now apply to 318633965Sjdp size the dynamic relocation sections. */ 318733965Sjdp alpha_elf_link_hash_traverse (alpha_elf_hash_table (info), 318833965Sjdp elf64_alpha_calc_dynrel_sizes, 318933965Sjdp info); 319033965Sjdp 319133965Sjdp /* When building shared libraries, each local .got entry needs a 319233965Sjdp RELATIVE reloc. */ 319333965Sjdp if (info->shared) 319433965Sjdp { 319533965Sjdp bfd *i; 319633965Sjdp asection *srel; 319733965Sjdp bfd_size_type count; 319833965Sjdp 319933965Sjdp srel = bfd_get_section_by_name (dynobj, ".rela.got"); 320033965Sjdp BFD_ASSERT (srel != NULL); 320133965Sjdp 320233965Sjdp for (i = alpha_elf_hash_table(info)->got_list, count = 0; 320333965Sjdp i != NULL; 320433965Sjdp i = alpha_elf_tdata(i)->got_link_next) 320533965Sjdp count += alpha_elf_tdata(i)->n_local_got_entries; 320633965Sjdp 320733965Sjdp srel->_raw_size += count * sizeof(Elf64_External_Rela); 320833965Sjdp } 320933965Sjdp } 321033965Sjdp /* else we're not dynamic and by definition we don't need such things. */ 321133965Sjdp 321233965Sjdp /* The check_relocs and adjust_dynamic_symbol entry points have 321333965Sjdp determined the sizes of the various dynamic sections. Allocate 321433965Sjdp memory for them. */ 321533965Sjdp reltext = false; 321633965Sjdp relplt = false; 321733965Sjdp for (s = dynobj->sections; s != NULL; s = s->next) 321833965Sjdp { 321933965Sjdp const char *name; 322033965Sjdp boolean strip; 322133965Sjdp 322233965Sjdp if (!(s->flags & SEC_LINKER_CREATED)) 322333965Sjdp continue; 322433965Sjdp 322533965Sjdp /* It's OK to base decisions on the section name, because none 322633965Sjdp of the dynobj section names depend upon the input files. */ 322733965Sjdp name = bfd_get_section_name (dynobj, s); 322833965Sjdp 322933965Sjdp /* If we don't need this section, strip it from the output file. 323033965Sjdp This is to handle .rela.bss and .rela.plt. We must create it 323133965Sjdp in create_dynamic_sections, because it must be created before 323233965Sjdp the linker maps input sections to output sections. The 323333965Sjdp linker does that before adjust_dynamic_symbol is called, and 323433965Sjdp it is that function which decides whether anything needs to 323533965Sjdp go into these sections. */ 323633965Sjdp 323733965Sjdp strip = false; 323833965Sjdp 323933965Sjdp if (strncmp (name, ".rela", 5) == 0) 324033965Sjdp { 324133965Sjdp strip = (s->_raw_size == 0); 324233965Sjdp 324333965Sjdp if (!strip) 324433965Sjdp { 324533965Sjdp const char *outname; 324633965Sjdp asection *target; 324733965Sjdp 324833965Sjdp /* If this relocation section applies to a read only 324933965Sjdp section, then we probably need a DT_TEXTREL entry. */ 325033965Sjdp outname = bfd_get_section_name (output_bfd, 325133965Sjdp s->output_section); 325233965Sjdp target = bfd_get_section_by_name (output_bfd, outname + 5); 325333965Sjdp if (target != NULL 325438889Sjdp && (target->flags & SEC_READONLY) != 0 325538889Sjdp && (target->flags & SEC_ALLOC) != 0) 325633965Sjdp reltext = true; 325733965Sjdp 325833965Sjdp if (strcmp(name, ".rela.plt") == 0) 325933965Sjdp relplt = true; 326033965Sjdp 326133965Sjdp /* We use the reloc_count field as a counter if we need 326233965Sjdp to copy relocs into the output file. */ 326333965Sjdp s->reloc_count = 0; 326433965Sjdp } 326533965Sjdp } 326633965Sjdp else if (strcmp (name, ".plt") != 0) 326733965Sjdp { 326833965Sjdp /* It's not one of our dynamic sections, so don't allocate space. */ 326933965Sjdp continue; 327033965Sjdp } 327133965Sjdp 327233965Sjdp if (strip) 327360510Sobrien _bfd_strip_section_from_output (info, s); 327433965Sjdp else 327533965Sjdp { 327633965Sjdp /* Allocate memory for the section contents. */ 327733965Sjdp s->contents = (bfd_byte *) bfd_zalloc(dynobj, s->_raw_size); 327833965Sjdp if (s->contents == NULL && s->_raw_size != 0) 327933965Sjdp return false; 328033965Sjdp } 328133965Sjdp } 328233965Sjdp 328333965Sjdp if (elf_hash_table (info)->dynamic_sections_created) 328433965Sjdp { 328533965Sjdp /* Add some entries to the .dynamic section. We fill in the 328633965Sjdp values later, in elf64_alpha_finish_dynamic_sections, but we 328733965Sjdp must add the entries now so that we get the correct size for 328833965Sjdp the .dynamic section. The DT_DEBUG entry is filled in by the 328933965Sjdp dynamic linker and used by the debugger. */ 329033965Sjdp if (!info->shared) 329133965Sjdp { 329233965Sjdp if (!bfd_elf64_add_dynamic_entry (info, DT_DEBUG, 0)) 329333965Sjdp return false; 329433965Sjdp } 329533965Sjdp 329633965Sjdp if (! bfd_elf64_add_dynamic_entry (info, DT_PLTGOT, 0)) 329733965Sjdp return false; 329833965Sjdp 329933965Sjdp if (relplt) 330033965Sjdp { 330133965Sjdp if (! bfd_elf64_add_dynamic_entry (info, DT_PLTRELSZ, 0) 330233965Sjdp || ! bfd_elf64_add_dynamic_entry (info, DT_PLTREL, DT_RELA) 330333965Sjdp || ! bfd_elf64_add_dynamic_entry (info, DT_JMPREL, 0)) 330433965Sjdp return false; 330533965Sjdp } 330633965Sjdp 330733965Sjdp if (! bfd_elf64_add_dynamic_entry (info, DT_RELA, 0) 330833965Sjdp || ! bfd_elf64_add_dynamic_entry (info, DT_RELASZ, 0) 330933965Sjdp || ! bfd_elf64_add_dynamic_entry (info, DT_RELAENT, 331033965Sjdp sizeof(Elf64_External_Rela))) 331133965Sjdp return false; 331233965Sjdp 331333965Sjdp if (reltext) 331433965Sjdp { 331533965Sjdp if (! bfd_elf64_add_dynamic_entry (info, DT_TEXTREL, 0)) 331633965Sjdp return false; 331733965Sjdp } 331833965Sjdp } 331933965Sjdp 332033965Sjdp return true; 332133965Sjdp} 332233965Sjdp 332333965Sjdp/* Relocate an Alpha ELF section. */ 332433965Sjdp 332533965Sjdpstatic boolean 332633965Sjdpelf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section, 332733965Sjdp contents, relocs, local_syms, local_sections) 332833965Sjdp bfd *output_bfd; 332933965Sjdp struct bfd_link_info *info; 333033965Sjdp bfd *input_bfd; 333133965Sjdp asection *input_section; 333233965Sjdp bfd_byte *contents; 333333965Sjdp Elf_Internal_Rela *relocs; 333433965Sjdp Elf_Internal_Sym *local_syms; 333533965Sjdp asection **local_sections; 333633965Sjdp{ 333733965Sjdp Elf_Internal_Shdr *symtab_hdr; 333833965Sjdp Elf_Internal_Rela *rel; 333933965Sjdp Elf_Internal_Rela *relend; 334033965Sjdp asection *sec, *sgot, *srel, *srelgot; 334133965Sjdp bfd *dynobj, *gotobj; 334233965Sjdp bfd_vma gp; 334333965Sjdp 334433965Sjdp srelgot = srel = NULL; 334533965Sjdp symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 334633965Sjdp dynobj = elf_hash_table (info)->dynobj; 334733965Sjdp if (dynobj) 334833965Sjdp { 334933965Sjdp srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); 335033965Sjdp } 335133965Sjdp 335233965Sjdp /* Find the gp value for this input bfd. */ 335333965Sjdp sgot = NULL; 335433965Sjdp gp = 0; 335533965Sjdp gotobj = alpha_elf_tdata (input_bfd)->gotobj; 335633965Sjdp if (gotobj) 335733965Sjdp { 335833965Sjdp sgot = alpha_elf_tdata (gotobj)->got; 335933965Sjdp gp = _bfd_get_gp_value (gotobj); 336033965Sjdp if (gp == 0) 336133965Sjdp { 336233965Sjdp gp = (sgot->output_section->vma 336333965Sjdp + sgot->output_offset 336433965Sjdp + 0x8000); 336533965Sjdp _bfd_set_gp_value (gotobj, gp); 336633965Sjdp } 336733965Sjdp } 336833965Sjdp 336933965Sjdp rel = relocs; 337033965Sjdp relend = relocs + input_section->reloc_count; 337133965Sjdp for (; rel < relend; rel++) 337233965Sjdp { 337333965Sjdp int r_type; 337433965Sjdp reloc_howto_type *howto; 337533965Sjdp unsigned long r_symndx; 337633965Sjdp struct alpha_elf_link_hash_entry *h; 337733965Sjdp Elf_Internal_Sym *sym; 337833965Sjdp bfd_vma relocation; 337933965Sjdp bfd_vma addend; 338033965Sjdp bfd_reloc_status_type r; 338133965Sjdp 338233965Sjdp r_type = ELF64_R_TYPE(rel->r_info); 338333965Sjdp if (r_type < 0 || r_type >= (int) R_ALPHA_max) 338433965Sjdp { 338533965Sjdp bfd_set_error (bfd_error_bad_value); 338633965Sjdp return false; 338733965Sjdp } 338833965Sjdp howto = elf64_alpha_howto_table + r_type; 338933965Sjdp 339033965Sjdp r_symndx = ELF64_R_SYM(rel->r_info); 339133965Sjdp 339233965Sjdp if (info->relocateable) 339333965Sjdp { 339433965Sjdp /* This is a relocateable link. We don't have to change 339533965Sjdp anything, unless the reloc is against a section symbol, 339633965Sjdp in which case we have to adjust according to where the 339733965Sjdp section symbol winds up in the output section. */ 339860510Sobrien 339960510Sobrien /* The symbol associated with GPDISP and LITUSE is 340060510Sobrien immaterial. Only the addend is significant. */ 340160510Sobrien if (r_type == R_ALPHA_GPDISP || r_type == R_ALPHA_LITUSE) 340260510Sobrien continue; 340360510Sobrien 340433965Sjdp if (r_symndx < symtab_hdr->sh_info) 340533965Sjdp { 340633965Sjdp sym = local_syms + r_symndx; 340733965Sjdp if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) 340833965Sjdp { 340933965Sjdp sec = local_sections[r_symndx]; 341033965Sjdp rel->r_addend += sec->output_offset + sym->st_value; 341133965Sjdp } 341233965Sjdp } 341333965Sjdp 341433965Sjdp continue; 341533965Sjdp } 341633965Sjdp 341733965Sjdp /* This is a final link. */ 341833965Sjdp 341933965Sjdp h = NULL; 342033965Sjdp sym = NULL; 342133965Sjdp sec = NULL; 342233965Sjdp 342333965Sjdp if (r_symndx < symtab_hdr->sh_info) 342433965Sjdp { 342533965Sjdp sym = local_syms + r_symndx; 342633965Sjdp sec = local_sections[r_symndx]; 342733965Sjdp relocation = (sec->output_section->vma 342833965Sjdp + sec->output_offset 342933965Sjdp + sym->st_value); 343033965Sjdp } 343133965Sjdp else 343233965Sjdp { 343333965Sjdp h = alpha_elf_sym_hashes (input_bfd)[r_symndx - symtab_hdr->sh_info]; 343433965Sjdp 343533965Sjdp while (h->root.root.type == bfd_link_hash_indirect 343633965Sjdp || h->root.root.type == bfd_link_hash_warning) 343733965Sjdp h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link; 343833965Sjdp 343933965Sjdp if (h->root.root.type == bfd_link_hash_defined 344033965Sjdp || h->root.root.type == bfd_link_hash_defweak) 344133965Sjdp { 344233965Sjdp sec = h->root.root.u.def.section; 344333965Sjdp 344433965Sjdp#if rth_notdef 344533965Sjdp if ((r_type == R_ALPHA_LITERAL 344633965Sjdp && elf_hash_table(info)->dynamic_sections_created 344733965Sjdp && (!info->shared 344833965Sjdp || !info->symbolic 344933965Sjdp || !(h->root.elf_link_hash_flags 345033965Sjdp & ELF_LINK_HASH_DEF_REGULAR))) 345133965Sjdp || (info->shared 345233965Sjdp && (!info->symbolic 345333965Sjdp || !(h->root.elf_link_hash_flags 345433965Sjdp & ELF_LINK_HASH_DEF_REGULAR)) 345533965Sjdp && (input_section->flags & SEC_ALLOC) 345633965Sjdp && (r_type == R_ALPHA_REFLONG 345733965Sjdp || r_type == R_ALPHA_REFQUAD 345833965Sjdp || r_type == R_ALPHA_LITERAL))) 345933965Sjdp { 346033965Sjdp /* In these cases, we don't need the relocation value. 346133965Sjdp We check specially because in some obscure cases 346233965Sjdp sec->output_section will be NULL. */ 346333965Sjdp relocation = 0; 346433965Sjdp } 346533965Sjdp#else 346633965Sjdp /* FIXME: Are not these obscure cases simply bugs? Let's 346733965Sjdp get something working and come back to this. */ 346833965Sjdp if (sec->output_section == NULL) 346933965Sjdp relocation = 0; 347033965Sjdp#endif /* rth_notdef */ 347133965Sjdp else 347233965Sjdp { 347333965Sjdp relocation = (h->root.root.u.def.value 347433965Sjdp + sec->output_section->vma 347533965Sjdp + sec->output_offset); 347633965Sjdp } 347733965Sjdp } 347833965Sjdp else if (h->root.root.type == bfd_link_hash_undefweak) 347933965Sjdp relocation = 0; 348060510Sobrien else if (info->shared && !info->symbolic && !info->no_undefined) 348133965Sjdp relocation = 0; 348233965Sjdp else 348333965Sjdp { 348433965Sjdp if (!((*info->callbacks->undefined_symbol) 348533965Sjdp (info, h->root.root.root.string, input_bfd, 348660510Sobrien input_section, rel->r_offset, 348760510Sobrien (!info->shared || info->no_undefined)))) 348833965Sjdp return false; 348933965Sjdp relocation = 0; 349033965Sjdp } 349133965Sjdp } 349233965Sjdp addend = rel->r_addend; 349333965Sjdp 349433965Sjdp switch (r_type) 349533965Sjdp { 349633965Sjdp case R_ALPHA_GPDISP: 349733965Sjdp { 349833965Sjdp bfd_byte *p_ldah, *p_lda; 349933965Sjdp 350033965Sjdp BFD_ASSERT(gp != 0); 350133965Sjdp 350233965Sjdp relocation = (input_section->output_section->vma 350333965Sjdp + input_section->output_offset 350433965Sjdp + rel->r_offset); 350533965Sjdp 350633965Sjdp p_ldah = contents + rel->r_offset - input_section->vma; 350733965Sjdp p_lda = p_ldah + rel->r_addend; 350833965Sjdp 350933965Sjdp r = elf64_alpha_do_reloc_gpdisp (input_bfd, gp - relocation, 351033965Sjdp p_ldah, p_lda); 351133965Sjdp } 351233965Sjdp break; 351333965Sjdp 351433965Sjdp case R_ALPHA_OP_PUSH: 351533965Sjdp case R_ALPHA_OP_STORE: 351633965Sjdp case R_ALPHA_OP_PSUB: 351733965Sjdp case R_ALPHA_OP_PRSHIFT: 351833965Sjdp /* We hate these silly beasts. */ 351933965Sjdp abort(); 352033965Sjdp 352133965Sjdp case R_ALPHA_LITERAL: 352233965Sjdp { 352333965Sjdp struct alpha_elf_got_entry *gotent; 352460510Sobrien boolean dynamic_symbol; 352533965Sjdp 352633965Sjdp BFD_ASSERT(sgot != NULL); 352733965Sjdp BFD_ASSERT(gp != 0); 352833965Sjdp 352933965Sjdp if (h != NULL) 353033965Sjdp { 353133965Sjdp gotent = h->got_entries; 353260510Sobrien dynamic_symbol = alpha_elf_dynamic_symbol_p (&h->root, info); 353333965Sjdp } 353433965Sjdp else 353533965Sjdp { 353633965Sjdp gotent = (alpha_elf_tdata(input_bfd)-> 353733965Sjdp local_got_entries[r_symndx]); 353860510Sobrien dynamic_symbol = false; 353960510Sobrien } 354033965Sjdp 354160510Sobrien BFD_ASSERT(gotent != NULL); 354233965Sjdp 354360510Sobrien while (gotent->gotobj != gotobj || gotent->addend != addend) 354460510Sobrien gotent = gotent->next; 354533965Sjdp 354660510Sobrien BFD_ASSERT(gotent->use_count >= 1); 354733965Sjdp 354860510Sobrien /* Initialize the .got entry's value. */ 354960510Sobrien if (!(gotent->flags & ALPHA_ELF_GOT_ENTRY_RELOCS_DONE)) 355060510Sobrien { 355160510Sobrien bfd_put_64 (output_bfd, relocation+addend, 355260510Sobrien sgot->contents + gotent->got_offset); 355333965Sjdp 355460510Sobrien /* If the symbol has been forced local, output a 355560510Sobrien RELATIVE reloc, otherwise it will be handled in 355660510Sobrien finish_dynamic_symbol. */ 355760510Sobrien if (info->shared && !dynamic_symbol) 355860510Sobrien { 355960510Sobrien Elf_Internal_Rela outrel; 356033965Sjdp 356160510Sobrien BFD_ASSERT(srelgot != NULL); 356260510Sobrien 356360510Sobrien outrel.r_offset = (sgot->output_section->vma 356460510Sobrien + sgot->output_offset 356560510Sobrien + gotent->got_offset); 356660510Sobrien outrel.r_info = ELF64_R_INFO(0, R_ALPHA_RELATIVE); 356760510Sobrien outrel.r_addend = 0; 356860510Sobrien 356960510Sobrien bfd_elf64_swap_reloca_out (output_bfd, &outrel, 357060510Sobrien ((Elf64_External_Rela *) 357160510Sobrien srelgot->contents) 357260510Sobrien + srelgot->reloc_count++); 357360510Sobrien BFD_ASSERT (sizeof(Elf64_External_Rela) 357460510Sobrien * srelgot->reloc_count 357560510Sobrien <= srelgot->_cooked_size); 357633965Sjdp } 357760510Sobrien 357860510Sobrien gotent->flags |= ALPHA_ELF_GOT_ENTRY_RELOCS_DONE; 357933965Sjdp } 358033965Sjdp 358133965Sjdp /* Figure the gprel relocation. */ 358233965Sjdp addend = 0; 358333965Sjdp relocation = (sgot->output_section->vma 358433965Sjdp + sgot->output_offset 358533965Sjdp + gotent->got_offset); 358633965Sjdp relocation -= gp; 358733965Sjdp } 358833965Sjdp /* overflow handled by _bfd_final_link_relocate */ 358933965Sjdp goto default_reloc; 359033965Sjdp 359133965Sjdp case R_ALPHA_GPREL32: 359260510Sobrien case R_ALPHA_GPRELLOW: 359333965Sjdp BFD_ASSERT(gp != 0); 359433965Sjdp relocation -= gp; 359533965Sjdp goto default_reloc; 359633965Sjdp 359760510Sobrien case R_ALPHA_GPRELHIGH: 359860510Sobrien BFD_ASSERT(gp != 0); 359960510Sobrien relocation -= gp; 360060510Sobrien relocation += addend; 360160510Sobrien addend = 0; 360260510Sobrien relocation = (((bfd_signed_vma) relocation >> 16) 360360510Sobrien + ((relocation >> 15) & 1)); 360460510Sobrien goto default_reloc; 360560510Sobrien 360633965Sjdp case R_ALPHA_BRADDR: 360733965Sjdp case R_ALPHA_HINT: 360833965Sjdp /* The regular PC-relative stuff measures from the start of 360933965Sjdp the instruction rather than the end. */ 361033965Sjdp addend -= 4; 361133965Sjdp goto default_reloc; 361233965Sjdp 361333965Sjdp case R_ALPHA_REFLONG: 361433965Sjdp case R_ALPHA_REFQUAD: 361533965Sjdp { 361633965Sjdp Elf_Internal_Rela outrel; 361733965Sjdp boolean skip; 361833965Sjdp 361933965Sjdp /* Careful here to remember RELATIVE relocations for global 362033965Sjdp variables for symbolic shared objects. */ 362133965Sjdp 362233965Sjdp if (h && alpha_elf_dynamic_symbol_p (&h->root, info)) 362333965Sjdp { 362433965Sjdp BFD_ASSERT(h->root.dynindx != -1); 362533965Sjdp outrel.r_info = ELF64_R_INFO(h->root.dynindx, r_type); 362633965Sjdp outrel.r_addend = addend; 362733965Sjdp addend = 0, relocation = 0; 362833965Sjdp } 362960510Sobrien else if (info->shared && (input_section->flags & SEC_ALLOC)) 363033965Sjdp { 363133965Sjdp outrel.r_info = ELF64_R_INFO(0, R_ALPHA_RELATIVE); 363233965Sjdp outrel.r_addend = 0; 363333965Sjdp } 363433965Sjdp else 363533965Sjdp goto default_reloc; 363633965Sjdp 363733965Sjdp if (!srel) 363833965Sjdp { 363933965Sjdp const char *name; 364033965Sjdp 364133965Sjdp name = (bfd_elf_string_from_elf_section 364233965Sjdp (input_bfd, elf_elfheader(input_bfd)->e_shstrndx, 364333965Sjdp elf_section_data(input_section)->rel_hdr.sh_name)); 364433965Sjdp BFD_ASSERT(name != NULL); 364533965Sjdp 364633965Sjdp srel = bfd_get_section_by_name (dynobj, name); 364733965Sjdp BFD_ASSERT(srel != NULL); 364833965Sjdp } 364933965Sjdp 365033965Sjdp skip = false; 365133965Sjdp 365233965Sjdp if (elf_section_data (input_section)->stab_info == NULL) 365333965Sjdp outrel.r_offset = rel->r_offset; 365433965Sjdp else 365533965Sjdp { 365633965Sjdp bfd_vma off; 365733965Sjdp 365833965Sjdp off = (_bfd_stab_section_offset 365933965Sjdp (output_bfd, &elf_hash_table (info)->stab_info, 366033965Sjdp input_section, 366133965Sjdp &elf_section_data (input_section)->stab_info, 366233965Sjdp rel->r_offset)); 366333965Sjdp if (off == (bfd_vma) -1) 366433965Sjdp skip = true; 366533965Sjdp outrel.r_offset = off; 366633965Sjdp } 366733965Sjdp 366833965Sjdp if (! skip) 366933965Sjdp outrel.r_offset += (input_section->output_section->vma 367033965Sjdp + input_section->output_offset); 367133965Sjdp else 367233965Sjdp memset (&outrel, 0, sizeof outrel); 367333965Sjdp 367433965Sjdp bfd_elf64_swap_reloca_out (output_bfd, &outrel, 367533965Sjdp ((Elf64_External_Rela *) 367633965Sjdp srel->contents) 367733965Sjdp + srel->reloc_count++); 367848850Sdfr BFD_ASSERT (sizeof(Elf64_External_Rela) * srel->reloc_count 367948850Sdfr <= srel->_cooked_size); 368033965Sjdp } 368133965Sjdp goto default_reloc; 368233965Sjdp 368333965Sjdp default: 368433965Sjdp default_reloc: 368533965Sjdp r = _bfd_final_link_relocate (howto, input_bfd, input_section, 368633965Sjdp contents, rel->r_offset, relocation, 368733965Sjdp addend); 368833965Sjdp break; 368933965Sjdp } 369033965Sjdp 369133965Sjdp switch (r) 369233965Sjdp { 369333965Sjdp case bfd_reloc_ok: 369433965Sjdp break; 369533965Sjdp 369633965Sjdp case bfd_reloc_overflow: 369733965Sjdp { 369833965Sjdp const char *name; 369933965Sjdp 370033965Sjdp if (h != NULL) 370133965Sjdp name = h->root.root.root.string; 370233965Sjdp else 370333965Sjdp { 370433965Sjdp name = (bfd_elf_string_from_elf_section 370533965Sjdp (input_bfd, symtab_hdr->sh_link, sym->st_name)); 370633965Sjdp if (name == NULL) 370733965Sjdp return false; 370833965Sjdp if (*name == '\0') 370933965Sjdp name = bfd_section_name (input_bfd, sec); 371033965Sjdp } 371133965Sjdp if (! ((*info->callbacks->reloc_overflow) 371233965Sjdp (info, name, howto->name, (bfd_vma) 0, 371333965Sjdp input_bfd, input_section, rel->r_offset))) 371433965Sjdp return false; 371533965Sjdp } 371633965Sjdp break; 371733965Sjdp 371833965Sjdp default: 371933965Sjdp case bfd_reloc_outofrange: 372033965Sjdp abort (); 372133965Sjdp } 372233965Sjdp } 372333965Sjdp 372433965Sjdp return true; 372533965Sjdp} 372633965Sjdp 372733965Sjdp/* Finish up dynamic symbol handling. We set the contents of various 372833965Sjdp dynamic sections here. */ 372933965Sjdp 373033965Sjdpstatic boolean 373133965Sjdpelf64_alpha_finish_dynamic_symbol (output_bfd, info, h, sym) 373233965Sjdp bfd *output_bfd; 373333965Sjdp struct bfd_link_info *info; 373433965Sjdp struct elf_link_hash_entry *h; 373533965Sjdp Elf_Internal_Sym *sym; 373633965Sjdp{ 373733965Sjdp bfd *dynobj = elf_hash_table(info)->dynobj; 373833965Sjdp 373960510Sobrien if (h->plt.offset != MINUS_ONE) 374033965Sjdp { 374133965Sjdp /* Fill in the .plt entry for this symbol. */ 374233965Sjdp asection *splt, *sgot, *srel; 374333965Sjdp Elf_Internal_Rela outrel; 374433965Sjdp bfd_vma got_addr, plt_addr; 374533965Sjdp bfd_vma plt_index; 374633965Sjdp struct alpha_elf_got_entry *gotent; 374733965Sjdp 374833965Sjdp BFD_ASSERT (h->dynindx != -1); 374933965Sjdp 375033965Sjdp /* The first .got entry will be updated by the .plt with the 375133965Sjdp address of the target function. */ 375233965Sjdp gotent = ((struct alpha_elf_link_hash_entry *) h)->got_entries; 375333965Sjdp BFD_ASSERT (gotent && gotent->addend == 0); 375433965Sjdp 375533965Sjdp splt = bfd_get_section_by_name (dynobj, ".plt"); 375633965Sjdp BFD_ASSERT (splt != NULL); 375733965Sjdp srel = bfd_get_section_by_name (dynobj, ".rela.plt"); 375833965Sjdp BFD_ASSERT (srel != NULL); 375933965Sjdp sgot = alpha_elf_tdata (gotent->gotobj)->got; 376033965Sjdp BFD_ASSERT (sgot != NULL); 376133965Sjdp 376233965Sjdp got_addr = (sgot->output_section->vma 376333965Sjdp + sgot->output_offset 376433965Sjdp + gotent->got_offset); 376533965Sjdp plt_addr = (splt->output_section->vma 376633965Sjdp + splt->output_offset 376760510Sobrien + h->plt.offset); 376833965Sjdp 376960510Sobrien plt_index = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE; 377033965Sjdp 377133965Sjdp /* Fill in the entry in the procedure linkage table. */ 377233965Sjdp { 377333965Sjdp unsigned insn1, insn2, insn3; 377433965Sjdp 377560510Sobrien insn1 = PLT_ENTRY_WORD1 | ((-(h->plt.offset + 4) >> 2) & 0x1fffff); 377638889Sjdp insn2 = PLT_ENTRY_WORD2; 377738889Sjdp insn3 = PLT_ENTRY_WORD3; 377833965Sjdp 377960510Sobrien bfd_put_32 (output_bfd, insn1, splt->contents + h->plt.offset); 378060510Sobrien bfd_put_32 (output_bfd, insn2, splt->contents + h->plt.offset + 4); 378160510Sobrien bfd_put_32 (output_bfd, insn3, splt->contents + h->plt.offset + 8); 378233965Sjdp } 378333965Sjdp 378433965Sjdp /* Fill in the entry in the .rela.plt section. */ 378533965Sjdp outrel.r_offset = got_addr; 378633965Sjdp outrel.r_info = ELF64_R_INFO(h->dynindx, R_ALPHA_JMP_SLOT); 378733965Sjdp outrel.r_addend = 0; 378833965Sjdp 378933965Sjdp bfd_elf64_swap_reloca_out (output_bfd, &outrel, 379033965Sjdp ((Elf64_External_Rela *)srel->contents 379133965Sjdp + plt_index)); 379233965Sjdp 379333965Sjdp if (!(h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) 379433965Sjdp { 379533965Sjdp /* Mark the symbol as undefined, rather than as defined in the 379633965Sjdp .plt section. Leave the value alone. */ 379733965Sjdp sym->st_shndx = SHN_UNDEF; 379833965Sjdp } 379933965Sjdp 380033965Sjdp /* Fill in the entries in the .got. */ 380133965Sjdp bfd_put_64 (output_bfd, plt_addr, sgot->contents + gotent->got_offset); 380233965Sjdp 380333965Sjdp /* Subsequent .got entries will continue to bounce through the .plt. */ 380448850Sdfr if (gotent->next) 380533965Sjdp { 380648850Sdfr srel = bfd_get_section_by_name (dynobj, ".rela.got"); 380748850Sdfr BFD_ASSERT (! info->shared || srel != NULL); 380833965Sjdp 380948850Sdfr gotent = gotent->next; 381048850Sdfr do 381148850Sdfr { 381248850Sdfr sgot = alpha_elf_tdata(gotent->gotobj)->got; 381348850Sdfr BFD_ASSERT(sgot != NULL); 381448850Sdfr BFD_ASSERT(gotent->addend == 0); 381548850Sdfr 381648850Sdfr bfd_put_64 (output_bfd, plt_addr, 381748850Sdfr sgot->contents + gotent->got_offset); 381848850Sdfr 381948850Sdfr if (info->shared) 382048850Sdfr { 382148850Sdfr outrel.r_offset = (sgot->output_section->vma 382248850Sdfr + sgot->output_offset 382348850Sdfr + gotent->got_offset); 382448850Sdfr outrel.r_info = ELF64_R_INFO(0, R_ALPHA_RELATIVE); 382548850Sdfr outrel.r_addend = 0; 382648850Sdfr 382748850Sdfr bfd_elf64_swap_reloca_out (output_bfd, &outrel, 382848850Sdfr ((Elf64_External_Rela *) 382948850Sdfr srel->contents) 383048850Sdfr + srel->reloc_count++); 383148850Sdfr BFD_ASSERT (sizeof(Elf64_External_Rela) * srel->reloc_count 383248850Sdfr <= srel->_cooked_size); 383348850Sdfr } 383448850Sdfr 383548850Sdfr gotent = gotent->next; 383648850Sdfr } 383748850Sdfr while (gotent != NULL); 383833965Sjdp } 383933965Sjdp } 384033965Sjdp else if (alpha_elf_dynamic_symbol_p (h, info)) 384133965Sjdp { 384233965Sjdp /* Fill in the dynamic relocations for this symbol's .got entries. */ 384333965Sjdp asection *srel; 384433965Sjdp Elf_Internal_Rela outrel; 384533965Sjdp struct alpha_elf_got_entry *gotent; 384633965Sjdp 384733965Sjdp srel = bfd_get_section_by_name (dynobj, ".rela.got"); 384833965Sjdp BFD_ASSERT (srel != NULL); 384933965Sjdp 385033965Sjdp outrel.r_info = ELF64_R_INFO (h->dynindx, R_ALPHA_GLOB_DAT); 385133965Sjdp for (gotent = ((struct alpha_elf_link_hash_entry *) h)->got_entries; 385233965Sjdp gotent != NULL; 385333965Sjdp gotent = gotent->next) 385433965Sjdp { 385533965Sjdp asection *sgot = alpha_elf_tdata (gotent->gotobj)->got; 385633965Sjdp outrel.r_offset = (sgot->output_section->vma 385733965Sjdp + sgot->output_offset 385833965Sjdp + gotent->got_offset); 385933965Sjdp outrel.r_addend = gotent->addend; 386033965Sjdp 386133965Sjdp bfd_elf64_swap_reloca_out (output_bfd, &outrel, 386233965Sjdp ((Elf64_External_Rela *)srel->contents 386333965Sjdp + srel->reloc_count++)); 386448850Sdfr BFD_ASSERT (sizeof(Elf64_External_Rela) * srel->reloc_count 386548850Sdfr <= srel->_cooked_size); 386633965Sjdp } 386733965Sjdp } 386833965Sjdp 386933965Sjdp /* Mark some specially defined symbols as absolute. */ 387033965Sjdp if (strcmp (h->root.root.string, "_DYNAMIC") == 0 387133965Sjdp || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0 387233965Sjdp || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0) 387333965Sjdp sym->st_shndx = SHN_ABS; 387433965Sjdp 387533965Sjdp return true; 387633965Sjdp} 387733965Sjdp 387833965Sjdp/* Finish up the dynamic sections. */ 387933965Sjdp 388033965Sjdpstatic boolean 388133965Sjdpelf64_alpha_finish_dynamic_sections (output_bfd, info) 388233965Sjdp bfd *output_bfd; 388333965Sjdp struct bfd_link_info *info; 388433965Sjdp{ 388533965Sjdp bfd *dynobj; 388633965Sjdp asection *sdyn; 388733965Sjdp 388833965Sjdp dynobj = elf_hash_table (info)->dynobj; 388933965Sjdp sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); 389033965Sjdp 389133965Sjdp if (elf_hash_table (info)->dynamic_sections_created) 389233965Sjdp { 389333965Sjdp asection *splt; 389433965Sjdp Elf64_External_Dyn *dyncon, *dynconend; 389533965Sjdp 389633965Sjdp splt = bfd_get_section_by_name (dynobj, ".plt"); 389733965Sjdp BFD_ASSERT (splt != NULL && sdyn != NULL); 389833965Sjdp 389933965Sjdp dyncon = (Elf64_External_Dyn *) sdyn->contents; 390033965Sjdp dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size); 390133965Sjdp for (; dyncon < dynconend; dyncon++) 390233965Sjdp { 390333965Sjdp Elf_Internal_Dyn dyn; 390433965Sjdp const char *name; 390533965Sjdp asection *s; 390633965Sjdp 390733965Sjdp bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn); 390833965Sjdp 390933965Sjdp switch (dyn.d_tag) 391033965Sjdp { 391133965Sjdp case DT_PLTGOT: 391233965Sjdp name = ".plt"; 391333965Sjdp goto get_vma; 391433965Sjdp case DT_PLTRELSZ: 391533965Sjdp name = ".rela.plt"; 391633965Sjdp goto get_size; 391733965Sjdp case DT_JMPREL: 391833965Sjdp name = ".rela.plt"; 391933965Sjdp goto get_vma; 392033965Sjdp 392133965Sjdp case DT_RELASZ: 392233965Sjdp /* My interpretation of the TIS v1.1 ELF document indicates 392333965Sjdp that RELASZ should not include JMPREL. This is not what 392433965Sjdp the rest of the BFD does. It is, however, what the 392533965Sjdp glibc ld.so wants. Do this fixup here until we found 392633965Sjdp out who is right. */ 392733965Sjdp s = bfd_get_section_by_name (output_bfd, ".rela.plt"); 392833965Sjdp if (s) 392933965Sjdp { 393033965Sjdp dyn.d_un.d_val -= 393133965Sjdp (s->_cooked_size ? s->_cooked_size : s->_raw_size); 393233965Sjdp } 393333965Sjdp break; 393433965Sjdp 393533965Sjdp get_vma: 393633965Sjdp s = bfd_get_section_by_name (output_bfd, name); 393733965Sjdp dyn.d_un.d_ptr = (s ? s->vma : 0); 393833965Sjdp break; 393933965Sjdp 394033965Sjdp get_size: 394133965Sjdp s = bfd_get_section_by_name (output_bfd, name); 394233965Sjdp dyn.d_un.d_val = 394333965Sjdp (s->_cooked_size ? s->_cooked_size : s->_raw_size); 394433965Sjdp break; 394533965Sjdp } 394633965Sjdp 394733965Sjdp bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon); 394833965Sjdp } 394933965Sjdp 395033965Sjdp /* Initialize the PLT0 entry */ 395133965Sjdp if (splt->_raw_size > 0) 395233965Sjdp { 395333965Sjdp bfd_put_32 (output_bfd, PLT_HEADER_WORD1, splt->contents); 395433965Sjdp bfd_put_32 (output_bfd, PLT_HEADER_WORD2, splt->contents + 4); 395533965Sjdp bfd_put_32 (output_bfd, PLT_HEADER_WORD3, splt->contents + 8); 395633965Sjdp bfd_put_32 (output_bfd, PLT_HEADER_WORD4, splt->contents + 12); 395733965Sjdp 395833965Sjdp /* The next two words will be filled in by ld.so */ 395933965Sjdp bfd_put_64 (output_bfd, 0, splt->contents + 16); 396033965Sjdp bfd_put_64 (output_bfd, 0, splt->contents + 24); 396133965Sjdp 396233965Sjdp elf_section_data (splt->output_section)->this_hdr.sh_entsize = 396333965Sjdp PLT_HEADER_SIZE; 396433965Sjdp } 396533965Sjdp } 396633965Sjdp 396733965Sjdp return true; 396833965Sjdp} 396933965Sjdp 397033965Sjdp/* We need to use a special link routine to handle the .reginfo and 397133965Sjdp the .mdebug sections. We need to merge all instances of these 397233965Sjdp sections together, not write them all out sequentially. */ 397333965Sjdp 397433965Sjdpstatic boolean 397533965Sjdpelf64_alpha_final_link (abfd, info) 397633965Sjdp bfd *abfd; 397733965Sjdp struct bfd_link_info *info; 397833965Sjdp{ 397933965Sjdp asection *o; 398033965Sjdp struct bfd_link_order *p; 398133965Sjdp asection *reginfo_sec, *mdebug_sec, *gptab_data_sec, *gptab_bss_sec; 398233965Sjdp struct ecoff_debug_info debug; 398333965Sjdp const struct ecoff_debug_swap *swap 398433965Sjdp = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; 398533965Sjdp HDRR *symhdr = &debug.symbolic_header; 398633965Sjdp PTR mdebug_handle = NULL; 398733965Sjdp 398860510Sobrien#if 0 398960510Sobrien if (++ngots == 2) 399060510Sobrien { 399160510Sobrien (*info->callbacks->warning) 399260510Sobrien (info, _("using multiple gp values"), (char *) NULL, 399360510Sobrien output_bfd, (asection *) NULL, (bfd_vma) 0); 399460510Sobrien } 399560510Sobrien#endif 399660510Sobrien 399733965Sjdp /* Go through the sections and collect the .reginfo and .mdebug 399833965Sjdp information. */ 399933965Sjdp reginfo_sec = NULL; 400033965Sjdp mdebug_sec = NULL; 400133965Sjdp gptab_data_sec = NULL; 400233965Sjdp gptab_bss_sec = NULL; 400333965Sjdp for (o = abfd->sections; o != (asection *) NULL; o = o->next) 400433965Sjdp { 400533965Sjdp#ifdef ERIC_neverdef 400633965Sjdp if (strcmp (o->name, ".reginfo") == 0) 400733965Sjdp { 400833965Sjdp memset (®info, 0, sizeof reginfo); 400933965Sjdp 401033965Sjdp /* We have found the .reginfo section in the output file. 401133965Sjdp Look through all the link_orders comprising it and merge 401233965Sjdp the information together. */ 401333965Sjdp for (p = o->link_order_head; 401433965Sjdp p != (struct bfd_link_order *) NULL; 401533965Sjdp p = p->next) 401633965Sjdp { 401733965Sjdp asection *input_section; 401833965Sjdp bfd *input_bfd; 401933965Sjdp Elf64_External_RegInfo ext; 402033965Sjdp Elf64_RegInfo sub; 402133965Sjdp 402233965Sjdp if (p->type != bfd_indirect_link_order) 402333965Sjdp { 402433965Sjdp if (p->type == bfd_fill_link_order) 402533965Sjdp continue; 402633965Sjdp abort (); 402733965Sjdp } 402833965Sjdp 402933965Sjdp input_section = p->u.indirect.section; 403033965Sjdp input_bfd = input_section->owner; 403133965Sjdp 403233965Sjdp /* The linker emulation code has probably clobbered the 403333965Sjdp size to be zero bytes. */ 403433965Sjdp if (input_section->_raw_size == 0) 403533965Sjdp input_section->_raw_size = sizeof (Elf64_External_RegInfo); 403633965Sjdp 403733965Sjdp if (! bfd_get_section_contents (input_bfd, input_section, 403833965Sjdp (PTR) &ext, 403933965Sjdp (file_ptr) 0, 404033965Sjdp sizeof ext)) 404133965Sjdp return false; 404233965Sjdp 404333965Sjdp bfd_alpha_elf64_swap_reginfo_in (input_bfd, &ext, &sub); 404433965Sjdp 404533965Sjdp reginfo.ri_gprmask |= sub.ri_gprmask; 404633965Sjdp reginfo.ri_cprmask[0] |= sub.ri_cprmask[0]; 404733965Sjdp reginfo.ri_cprmask[1] |= sub.ri_cprmask[1]; 404833965Sjdp reginfo.ri_cprmask[2] |= sub.ri_cprmask[2]; 404933965Sjdp reginfo.ri_cprmask[3] |= sub.ri_cprmask[3]; 405033965Sjdp 405133965Sjdp /* ri_gp_value is set by the function 405233965Sjdp alpha_elf_section_processing when the section is 405333965Sjdp finally written out. */ 405433965Sjdp 405533965Sjdp /* Hack: reset the SEC_HAS_CONTENTS flag so that 405633965Sjdp elf_link_input_bfd ignores this section. */ 405733965Sjdp input_section->flags &=~ SEC_HAS_CONTENTS; 405833965Sjdp } 405933965Sjdp 406033965Sjdp /* Force the section size to the value we want. */ 406133965Sjdp o->_raw_size = sizeof (Elf64_External_RegInfo); 406233965Sjdp 406333965Sjdp /* Skip this section later on (I don't think this currently 406433965Sjdp matters, but someday it might). */ 406533965Sjdp o->link_order_head = (struct bfd_link_order *) NULL; 406633965Sjdp 406733965Sjdp reginfo_sec = o; 406833965Sjdp } 406933965Sjdp#endif 407033965Sjdp 407133965Sjdp if (strcmp (o->name, ".mdebug") == 0) 407233965Sjdp { 407333965Sjdp struct extsym_info einfo; 407433965Sjdp 407533965Sjdp /* We have found the .mdebug section in the output file. 407633965Sjdp Look through all the link_orders comprising it and merge 407733965Sjdp the information together. */ 407833965Sjdp symhdr->magic = swap->sym_magic; 407933965Sjdp /* FIXME: What should the version stamp be? */ 408033965Sjdp symhdr->vstamp = 0; 408133965Sjdp symhdr->ilineMax = 0; 408233965Sjdp symhdr->cbLine = 0; 408333965Sjdp symhdr->idnMax = 0; 408433965Sjdp symhdr->ipdMax = 0; 408533965Sjdp symhdr->isymMax = 0; 408633965Sjdp symhdr->ioptMax = 0; 408733965Sjdp symhdr->iauxMax = 0; 408833965Sjdp symhdr->issMax = 0; 408933965Sjdp symhdr->issExtMax = 0; 409033965Sjdp symhdr->ifdMax = 0; 409133965Sjdp symhdr->crfd = 0; 409233965Sjdp symhdr->iextMax = 0; 409333965Sjdp 409433965Sjdp /* We accumulate the debugging information itself in the 409533965Sjdp debug_info structure. */ 409633965Sjdp debug.line = NULL; 409733965Sjdp debug.external_dnr = NULL; 409833965Sjdp debug.external_pdr = NULL; 409933965Sjdp debug.external_sym = NULL; 410033965Sjdp debug.external_opt = NULL; 410133965Sjdp debug.external_aux = NULL; 410233965Sjdp debug.ss = NULL; 410333965Sjdp debug.ssext = debug.ssext_end = NULL; 410433965Sjdp debug.external_fdr = NULL; 410533965Sjdp debug.external_rfd = NULL; 410633965Sjdp debug.external_ext = debug.external_ext_end = NULL; 410733965Sjdp 410833965Sjdp mdebug_handle = bfd_ecoff_debug_init (abfd, &debug, swap, info); 410933965Sjdp if (mdebug_handle == (PTR) NULL) 411033965Sjdp return false; 411133965Sjdp 411233965Sjdp if (1) 411333965Sjdp { 411433965Sjdp asection *s; 411533965Sjdp EXTR esym; 411633965Sjdp bfd_vma last; 411733965Sjdp unsigned int i; 411833965Sjdp static const char * const name[] = 411933965Sjdp { 412033965Sjdp ".text", ".init", ".fini", ".data", 412133965Sjdp ".rodata", ".sdata", ".sbss", ".bss" 412233965Sjdp }; 412333965Sjdp static const int sc[] = { scText, scInit, scFini, scData, 412433965Sjdp scRData, scSData, scSBss, scBss }; 412533965Sjdp 412633965Sjdp esym.jmptbl = 0; 412733965Sjdp esym.cobol_main = 0; 412833965Sjdp esym.weakext = 0; 412933965Sjdp esym.reserved = 0; 413033965Sjdp esym.ifd = ifdNil; 413133965Sjdp esym.asym.iss = issNil; 413233965Sjdp esym.asym.st = stLocal; 413333965Sjdp esym.asym.reserved = 0; 413433965Sjdp esym.asym.index = indexNil; 413533965Sjdp for (i = 0; i < 8; i++) 413633965Sjdp { 413733965Sjdp esym.asym.sc = sc[i]; 413833965Sjdp s = bfd_get_section_by_name (abfd, name[i]); 413933965Sjdp if (s != NULL) 414033965Sjdp { 414133965Sjdp esym.asym.value = s->vma; 414233965Sjdp last = s->vma + s->_raw_size; 414333965Sjdp } 414433965Sjdp else 414533965Sjdp esym.asym.value = last; 414633965Sjdp 414733965Sjdp if (! bfd_ecoff_debug_one_external (abfd, &debug, swap, 414833965Sjdp name[i], &esym)) 414933965Sjdp return false; 415033965Sjdp } 415133965Sjdp } 415233965Sjdp 415333965Sjdp for (p = o->link_order_head; 415433965Sjdp p != (struct bfd_link_order *) NULL; 415533965Sjdp p = p->next) 415633965Sjdp { 415733965Sjdp asection *input_section; 415833965Sjdp bfd *input_bfd; 415933965Sjdp const struct ecoff_debug_swap *input_swap; 416033965Sjdp struct ecoff_debug_info input_debug; 416133965Sjdp char *eraw_src; 416233965Sjdp char *eraw_end; 416333965Sjdp 416433965Sjdp if (p->type != bfd_indirect_link_order) 416533965Sjdp { 416633965Sjdp if (p->type == bfd_fill_link_order) 416733965Sjdp continue; 416833965Sjdp abort (); 416933965Sjdp } 417033965Sjdp 417133965Sjdp input_section = p->u.indirect.section; 417233965Sjdp input_bfd = input_section->owner; 417333965Sjdp 417433965Sjdp if (bfd_get_flavour (input_bfd) != bfd_target_elf_flavour 417533965Sjdp || (get_elf_backend_data (input_bfd) 417633965Sjdp ->elf_backend_ecoff_debug_swap) == NULL) 417733965Sjdp { 417833965Sjdp /* I don't know what a non ALPHA ELF bfd would be 417933965Sjdp doing with a .mdebug section, but I don't really 418033965Sjdp want to deal with it. */ 418133965Sjdp continue; 418233965Sjdp } 418333965Sjdp 418433965Sjdp input_swap = (get_elf_backend_data (input_bfd) 418533965Sjdp ->elf_backend_ecoff_debug_swap); 418633965Sjdp 418733965Sjdp BFD_ASSERT (p->size == input_section->_raw_size); 418833965Sjdp 418933965Sjdp /* The ECOFF linking code expects that we have already 419033965Sjdp read in the debugging information and set up an 419133965Sjdp ecoff_debug_info structure, so we do that now. */ 419233965Sjdp if (!elf64_alpha_read_ecoff_info (input_bfd, input_section, 419333965Sjdp &input_debug)) 419433965Sjdp return false; 419533965Sjdp 419633965Sjdp if (! (bfd_ecoff_debug_accumulate 419733965Sjdp (mdebug_handle, abfd, &debug, swap, input_bfd, 419833965Sjdp &input_debug, input_swap, info))) 419933965Sjdp return false; 420033965Sjdp 420133965Sjdp /* Loop through the external symbols. For each one with 420233965Sjdp interesting information, try to find the symbol in 420333965Sjdp the linker global hash table and save the information 420433965Sjdp for the output external symbols. */ 420533965Sjdp eraw_src = input_debug.external_ext; 420633965Sjdp eraw_end = (eraw_src 420733965Sjdp + (input_debug.symbolic_header.iextMax 420833965Sjdp * input_swap->external_ext_size)); 420933965Sjdp for (; 421033965Sjdp eraw_src < eraw_end; 421133965Sjdp eraw_src += input_swap->external_ext_size) 421233965Sjdp { 421333965Sjdp EXTR ext; 421433965Sjdp const char *name; 421533965Sjdp struct alpha_elf_link_hash_entry *h; 421633965Sjdp 421733965Sjdp (*input_swap->swap_ext_in) (input_bfd, (PTR) eraw_src, &ext); 421833965Sjdp if (ext.asym.sc == scNil 421933965Sjdp || ext.asym.sc == scUndefined 422033965Sjdp || ext.asym.sc == scSUndefined) 422133965Sjdp continue; 422233965Sjdp 422333965Sjdp name = input_debug.ssext + ext.asym.iss; 422433965Sjdp h = alpha_elf_link_hash_lookup (alpha_elf_hash_table (info), 422533965Sjdp name, false, false, true); 422633965Sjdp if (h == NULL || h->esym.ifd != -2) 422733965Sjdp continue; 422833965Sjdp 422933965Sjdp if (ext.ifd != -1) 423033965Sjdp { 423133965Sjdp BFD_ASSERT (ext.ifd 423233965Sjdp < input_debug.symbolic_header.ifdMax); 423333965Sjdp ext.ifd = input_debug.ifdmap[ext.ifd]; 423433965Sjdp } 423533965Sjdp 423633965Sjdp h->esym = ext; 423733965Sjdp } 423833965Sjdp 423933965Sjdp /* Free up the information we just read. */ 424033965Sjdp free (input_debug.line); 424133965Sjdp free (input_debug.external_dnr); 424233965Sjdp free (input_debug.external_pdr); 424333965Sjdp free (input_debug.external_sym); 424433965Sjdp free (input_debug.external_opt); 424533965Sjdp free (input_debug.external_aux); 424633965Sjdp free (input_debug.ss); 424733965Sjdp free (input_debug.ssext); 424833965Sjdp free (input_debug.external_fdr); 424933965Sjdp free (input_debug.external_rfd); 425033965Sjdp free (input_debug.external_ext); 425133965Sjdp 425233965Sjdp /* Hack: reset the SEC_HAS_CONTENTS flag so that 425333965Sjdp elf_link_input_bfd ignores this section. */ 425433965Sjdp input_section->flags &=~ SEC_HAS_CONTENTS; 425533965Sjdp } 425633965Sjdp 425733965Sjdp#ifdef ERIC_neverdef 425833965Sjdp if (info->shared) 425933965Sjdp { 426033965Sjdp /* Create .rtproc section. */ 426133965Sjdp rtproc_sec = bfd_get_section_by_name (abfd, ".rtproc"); 426233965Sjdp if (rtproc_sec == NULL) 426333965Sjdp { 426433965Sjdp flagword flags = (SEC_HAS_CONTENTS 426533965Sjdp | SEC_IN_MEMORY 426633965Sjdp | SEC_LINKER_CREATED 426733965Sjdp | SEC_READONLY); 426833965Sjdp 426933965Sjdp rtproc_sec = bfd_make_section (abfd, ".rtproc"); 427033965Sjdp if (rtproc_sec == NULL 427133965Sjdp || ! bfd_set_section_flags (abfd, rtproc_sec, flags) 427233965Sjdp || ! bfd_set_section_alignment (abfd, rtproc_sec, 12)) 427333965Sjdp return false; 427433965Sjdp } 427533965Sjdp 427633965Sjdp if (! alpha_elf_create_procedure_table (mdebug_handle, abfd, 427733965Sjdp info, rtproc_sec, &debug)) 427833965Sjdp return false; 427933965Sjdp } 428033965Sjdp#endif 428133965Sjdp 428233965Sjdp 428333965Sjdp /* Build the external symbol information. */ 428433965Sjdp einfo.abfd = abfd; 428533965Sjdp einfo.info = info; 428633965Sjdp einfo.debug = &debug; 428733965Sjdp einfo.swap = swap; 428833965Sjdp einfo.failed = false; 428933965Sjdp elf_link_hash_traverse (elf_hash_table (info), 429033965Sjdp elf64_alpha_output_extsym, 429133965Sjdp (PTR) &einfo); 429233965Sjdp if (einfo.failed) 429333965Sjdp return false; 429433965Sjdp 429533965Sjdp /* Set the size of the .mdebug section. */ 429633965Sjdp o->_raw_size = bfd_ecoff_debug_size (abfd, &debug, swap); 429733965Sjdp 429833965Sjdp /* Skip this section later on (I don't think this currently 429933965Sjdp matters, but someday it might). */ 430033965Sjdp o->link_order_head = (struct bfd_link_order *) NULL; 430133965Sjdp 430233965Sjdp mdebug_sec = o; 430333965Sjdp } 430433965Sjdp 430533965Sjdp#ifdef ERIC_neverdef 430633965Sjdp if (strncmp (o->name, ".gptab.", sizeof ".gptab." - 1) == 0) 430733965Sjdp { 430833965Sjdp const char *subname; 430933965Sjdp unsigned int c; 431033965Sjdp Elf64_gptab *tab; 431133965Sjdp Elf64_External_gptab *ext_tab; 431233965Sjdp unsigned int i; 431333965Sjdp 431433965Sjdp /* The .gptab.sdata and .gptab.sbss sections hold 431533965Sjdp information describing how the small data area would 431633965Sjdp change depending upon the -G switch. These sections 431733965Sjdp not used in executables files. */ 431833965Sjdp if (! info->relocateable) 431933965Sjdp { 432033965Sjdp asection **secpp; 432133965Sjdp 432233965Sjdp for (p = o->link_order_head; 432333965Sjdp p != (struct bfd_link_order *) NULL; 432433965Sjdp p = p->next) 432533965Sjdp { 432633965Sjdp asection *input_section; 432733965Sjdp 432833965Sjdp if (p->type != bfd_indirect_link_order) 432933965Sjdp { 433033965Sjdp if (p->type == bfd_fill_link_order) 433133965Sjdp continue; 433233965Sjdp abort (); 433333965Sjdp } 433433965Sjdp 433533965Sjdp input_section = p->u.indirect.section; 433633965Sjdp 433733965Sjdp /* Hack: reset the SEC_HAS_CONTENTS flag so that 433833965Sjdp elf_link_input_bfd ignores this section. */ 433933965Sjdp input_section->flags &=~ SEC_HAS_CONTENTS; 434033965Sjdp } 434133965Sjdp 434233965Sjdp /* Skip this section later on (I don't think this 434333965Sjdp currently matters, but someday it might). */ 434433965Sjdp o->link_order_head = (struct bfd_link_order *) NULL; 434533965Sjdp 434633965Sjdp /* Really remove the section. */ 434733965Sjdp for (secpp = &abfd->sections; 434833965Sjdp *secpp != o; 434933965Sjdp secpp = &(*secpp)->next) 435033965Sjdp ; 435133965Sjdp *secpp = (*secpp)->next; 435233965Sjdp --abfd->section_count; 435333965Sjdp 435433965Sjdp continue; 435533965Sjdp } 435633965Sjdp 435733965Sjdp /* There is one gptab for initialized data, and one for 435833965Sjdp uninitialized data. */ 435933965Sjdp if (strcmp (o->name, ".gptab.sdata") == 0) 436033965Sjdp gptab_data_sec = o; 436133965Sjdp else if (strcmp (o->name, ".gptab.sbss") == 0) 436233965Sjdp gptab_bss_sec = o; 436333965Sjdp else 436433965Sjdp { 436533965Sjdp (*_bfd_error_handler) 436660510Sobrien (_("%s: illegal section name `%s'"), 436733965Sjdp bfd_get_filename (abfd), o->name); 436833965Sjdp bfd_set_error (bfd_error_nonrepresentable_section); 436933965Sjdp return false; 437033965Sjdp } 437133965Sjdp 437233965Sjdp /* The linker script always combines .gptab.data and 437333965Sjdp .gptab.sdata into .gptab.sdata, and likewise for 437433965Sjdp .gptab.bss and .gptab.sbss. It is possible that there is 437533965Sjdp no .sdata or .sbss section in the output file, in which 437633965Sjdp case we must change the name of the output section. */ 437733965Sjdp subname = o->name + sizeof ".gptab" - 1; 437833965Sjdp if (bfd_get_section_by_name (abfd, subname) == NULL) 437933965Sjdp { 438033965Sjdp if (o == gptab_data_sec) 438133965Sjdp o->name = ".gptab.data"; 438233965Sjdp else 438333965Sjdp o->name = ".gptab.bss"; 438433965Sjdp subname = o->name + sizeof ".gptab" - 1; 438533965Sjdp BFD_ASSERT (bfd_get_section_by_name (abfd, subname) != NULL); 438633965Sjdp } 438733965Sjdp 438833965Sjdp /* Set up the first entry. */ 438933965Sjdp c = 1; 439033965Sjdp tab = (Elf64_gptab *) bfd_malloc (c * sizeof (Elf64_gptab)); 439133965Sjdp if (tab == NULL) 439233965Sjdp return false; 439333965Sjdp tab[0].gt_header.gt_current_g_value = elf_gp_size (abfd); 439433965Sjdp tab[0].gt_header.gt_unused = 0; 439533965Sjdp 439633965Sjdp /* Combine the input sections. */ 439733965Sjdp for (p = o->link_order_head; 439833965Sjdp p != (struct bfd_link_order *) NULL; 439933965Sjdp p = p->next) 440033965Sjdp { 440133965Sjdp asection *input_section; 440233965Sjdp bfd *input_bfd; 440333965Sjdp bfd_size_type size; 440433965Sjdp unsigned long last; 440533965Sjdp bfd_size_type gpentry; 440633965Sjdp 440733965Sjdp if (p->type != bfd_indirect_link_order) 440833965Sjdp { 440933965Sjdp if (p->type == bfd_fill_link_order) 441033965Sjdp continue; 441133965Sjdp abort (); 441233965Sjdp } 441333965Sjdp 441433965Sjdp input_section = p->u.indirect.section; 441533965Sjdp input_bfd = input_section->owner; 441633965Sjdp 441733965Sjdp /* Combine the gptab entries for this input section one 441833965Sjdp by one. We know that the input gptab entries are 441933965Sjdp sorted by ascending -G value. */ 442033965Sjdp size = bfd_section_size (input_bfd, input_section); 442133965Sjdp last = 0; 442233965Sjdp for (gpentry = sizeof (Elf64_External_gptab); 442333965Sjdp gpentry < size; 442433965Sjdp gpentry += sizeof (Elf64_External_gptab)) 442533965Sjdp { 442633965Sjdp Elf64_External_gptab ext_gptab; 442733965Sjdp Elf64_gptab int_gptab; 442833965Sjdp unsigned long val; 442933965Sjdp unsigned long add; 443033965Sjdp boolean exact; 443133965Sjdp unsigned int look; 443233965Sjdp 443333965Sjdp if (! (bfd_get_section_contents 443433965Sjdp (input_bfd, input_section, (PTR) &ext_gptab, 443533965Sjdp gpentry, sizeof (Elf64_External_gptab)))) 443633965Sjdp { 443733965Sjdp free (tab); 443833965Sjdp return false; 443933965Sjdp } 444033965Sjdp 444133965Sjdp bfd_alpha_elf64_swap_gptab_in (input_bfd, &ext_gptab, 444233965Sjdp &int_gptab); 444333965Sjdp val = int_gptab.gt_entry.gt_g_value; 444433965Sjdp add = int_gptab.gt_entry.gt_bytes - last; 444533965Sjdp 444633965Sjdp exact = false; 444733965Sjdp for (look = 1; look < c; look++) 444833965Sjdp { 444933965Sjdp if (tab[look].gt_entry.gt_g_value >= val) 445033965Sjdp tab[look].gt_entry.gt_bytes += add; 445133965Sjdp 445233965Sjdp if (tab[look].gt_entry.gt_g_value == val) 445333965Sjdp exact = true; 445433965Sjdp } 445533965Sjdp 445633965Sjdp if (! exact) 445733965Sjdp { 445833965Sjdp Elf64_gptab *new_tab; 445933965Sjdp unsigned int max; 446033965Sjdp 446133965Sjdp /* We need a new table entry. */ 446233965Sjdp new_tab = ((Elf64_gptab *) 446333965Sjdp bfd_realloc ((PTR) tab, 446433965Sjdp (c + 1) * sizeof (Elf64_gptab))); 446533965Sjdp if (new_tab == NULL) 446633965Sjdp { 446733965Sjdp free (tab); 446833965Sjdp return false; 446933965Sjdp } 447033965Sjdp tab = new_tab; 447133965Sjdp tab[c].gt_entry.gt_g_value = val; 447233965Sjdp tab[c].gt_entry.gt_bytes = add; 447333965Sjdp 447433965Sjdp /* Merge in the size for the next smallest -G 447533965Sjdp value, since that will be implied by this new 447633965Sjdp value. */ 447733965Sjdp max = 0; 447833965Sjdp for (look = 1; look < c; look++) 447933965Sjdp { 448033965Sjdp if (tab[look].gt_entry.gt_g_value < val 448133965Sjdp && (max == 0 448233965Sjdp || (tab[look].gt_entry.gt_g_value 448333965Sjdp > tab[max].gt_entry.gt_g_value))) 448433965Sjdp max = look; 448533965Sjdp } 448633965Sjdp if (max != 0) 448733965Sjdp tab[c].gt_entry.gt_bytes += 448833965Sjdp tab[max].gt_entry.gt_bytes; 448933965Sjdp 449033965Sjdp ++c; 449133965Sjdp } 449233965Sjdp 449333965Sjdp last = int_gptab.gt_entry.gt_bytes; 449433965Sjdp } 449533965Sjdp 449633965Sjdp /* Hack: reset the SEC_HAS_CONTENTS flag so that 449733965Sjdp elf_link_input_bfd ignores this section. */ 449833965Sjdp input_section->flags &=~ SEC_HAS_CONTENTS; 449933965Sjdp } 450033965Sjdp 450133965Sjdp /* The table must be sorted by -G value. */ 450233965Sjdp if (c > 2) 450333965Sjdp qsort (tab + 1, c - 1, sizeof (tab[0]), gptab_compare); 450433965Sjdp 450533965Sjdp /* Swap out the table. */ 450633965Sjdp ext_tab = ((Elf64_External_gptab *) 450733965Sjdp bfd_alloc (abfd, c * sizeof (Elf64_External_gptab))); 450833965Sjdp if (ext_tab == NULL) 450933965Sjdp { 451033965Sjdp free (tab); 451133965Sjdp return false; 451233965Sjdp } 451333965Sjdp 451433965Sjdp for (i = 0; i < c; i++) 451533965Sjdp bfd_alpha_elf64_swap_gptab_out (abfd, tab + i, ext_tab + i); 451633965Sjdp free (tab); 451733965Sjdp 451833965Sjdp o->_raw_size = c * sizeof (Elf64_External_gptab); 451933965Sjdp o->contents = (bfd_byte *) ext_tab; 452033965Sjdp 452133965Sjdp /* Skip this section later on (I don't think this currently 452233965Sjdp matters, but someday it might). */ 452333965Sjdp o->link_order_head = (struct bfd_link_order *) NULL; 452433965Sjdp } 452533965Sjdp#endif 452633965Sjdp 452733965Sjdp } 452833965Sjdp 452933965Sjdp /* Invoke the regular ELF backend linker to do all the work. */ 453033965Sjdp if (! bfd_elf64_bfd_final_link (abfd, info)) 453133965Sjdp return false; 453233965Sjdp 453333965Sjdp /* Now write out the computed sections. */ 453433965Sjdp 453533965Sjdp /* The .got subsections... */ 453633965Sjdp { 453733965Sjdp bfd *i, *dynobj = elf_hash_table(info)->dynobj; 453833965Sjdp for (i = alpha_elf_hash_table(info)->got_list; 453933965Sjdp i != NULL; 454033965Sjdp i = alpha_elf_tdata(i)->got_link_next) 454133965Sjdp { 454233965Sjdp asection *sgot; 454333965Sjdp 454433965Sjdp /* elf_bfd_final_link already did everything in dynobj. */ 454533965Sjdp if (i == dynobj) 454633965Sjdp continue; 454733965Sjdp 454833965Sjdp sgot = alpha_elf_tdata(i)->got; 454933965Sjdp if (! bfd_set_section_contents (abfd, sgot->output_section, 455033965Sjdp sgot->contents, sgot->output_offset, 455133965Sjdp sgot->_raw_size)) 455233965Sjdp return false; 455333965Sjdp } 455433965Sjdp } 455533965Sjdp 455633965Sjdp#ifdef ERIC_neverdef 455733965Sjdp if (reginfo_sec != (asection *) NULL) 455833965Sjdp { 455933965Sjdp Elf64_External_RegInfo ext; 456033965Sjdp 456133965Sjdp bfd_alpha_elf64_swap_reginfo_out (abfd, ®info, &ext); 456233965Sjdp if (! bfd_set_section_contents (abfd, reginfo_sec, (PTR) &ext, 456333965Sjdp (file_ptr) 0, sizeof ext)) 456433965Sjdp return false; 456533965Sjdp } 456633965Sjdp#endif 456733965Sjdp 456833965Sjdp if (mdebug_sec != (asection *) NULL) 456933965Sjdp { 457033965Sjdp BFD_ASSERT (abfd->output_has_begun); 457133965Sjdp if (! bfd_ecoff_write_accumulated_debug (mdebug_handle, abfd, &debug, 457233965Sjdp swap, info, 457333965Sjdp mdebug_sec->filepos)) 457433965Sjdp return false; 457533965Sjdp 457633965Sjdp bfd_ecoff_debug_free (mdebug_handle, abfd, &debug, swap, info); 457733965Sjdp } 457833965Sjdp 457933965Sjdp if (gptab_data_sec != (asection *) NULL) 458033965Sjdp { 458133965Sjdp if (! bfd_set_section_contents (abfd, gptab_data_sec, 458233965Sjdp gptab_data_sec->contents, 458333965Sjdp (file_ptr) 0, 458433965Sjdp gptab_data_sec->_raw_size)) 458533965Sjdp return false; 458633965Sjdp } 458733965Sjdp 458833965Sjdp if (gptab_bss_sec != (asection *) NULL) 458933965Sjdp { 459033965Sjdp if (! bfd_set_section_contents (abfd, gptab_bss_sec, 459133965Sjdp gptab_bss_sec->contents, 459233965Sjdp (file_ptr) 0, 459333965Sjdp gptab_bss_sec->_raw_size)) 459433965Sjdp return false; 459533965Sjdp } 459633965Sjdp 459733965Sjdp return true; 459833965Sjdp} 459933965Sjdp 460033965Sjdp/* ECOFF swapping routines. These are used when dealing with the 460133965Sjdp .mdebug section, which is in the ECOFF debugging format. Copied 460233965Sjdp from elf32-mips.c. */ 460333965Sjdpstatic const struct ecoff_debug_swap 460433965Sjdpelf64_alpha_ecoff_debug_swap = 460533965Sjdp{ 460633965Sjdp /* Symbol table magic number. */ 460733965Sjdp magicSym2, 460833965Sjdp /* Alignment of debugging information. E.g., 4. */ 460933965Sjdp 8, 461033965Sjdp /* Sizes of external symbolic information. */ 461133965Sjdp sizeof (struct hdr_ext), 461233965Sjdp sizeof (struct dnr_ext), 461333965Sjdp sizeof (struct pdr_ext), 461433965Sjdp sizeof (struct sym_ext), 461533965Sjdp sizeof (struct opt_ext), 461633965Sjdp sizeof (struct fdr_ext), 461733965Sjdp sizeof (struct rfd_ext), 461833965Sjdp sizeof (struct ext_ext), 461933965Sjdp /* Functions to swap in external symbolic data. */ 462033965Sjdp ecoff_swap_hdr_in, 462133965Sjdp ecoff_swap_dnr_in, 462233965Sjdp ecoff_swap_pdr_in, 462333965Sjdp ecoff_swap_sym_in, 462433965Sjdp ecoff_swap_opt_in, 462533965Sjdp ecoff_swap_fdr_in, 462633965Sjdp ecoff_swap_rfd_in, 462733965Sjdp ecoff_swap_ext_in, 462833965Sjdp _bfd_ecoff_swap_tir_in, 462933965Sjdp _bfd_ecoff_swap_rndx_in, 463033965Sjdp /* Functions to swap out external symbolic data. */ 463133965Sjdp ecoff_swap_hdr_out, 463233965Sjdp ecoff_swap_dnr_out, 463333965Sjdp ecoff_swap_pdr_out, 463433965Sjdp ecoff_swap_sym_out, 463533965Sjdp ecoff_swap_opt_out, 463633965Sjdp ecoff_swap_fdr_out, 463733965Sjdp ecoff_swap_rfd_out, 463833965Sjdp ecoff_swap_ext_out, 463933965Sjdp _bfd_ecoff_swap_tir_out, 464033965Sjdp _bfd_ecoff_swap_rndx_out, 464133965Sjdp /* Function to read in symbolic data. */ 464233965Sjdp elf64_alpha_read_ecoff_info 464333965Sjdp}; 464433965Sjdp 464533965Sjdp#define TARGET_LITTLE_SYM bfd_elf64_alpha_vec 464633965Sjdp#define TARGET_LITTLE_NAME "elf64-alpha" 464733965Sjdp#define ELF_ARCH bfd_arch_alpha 464833965Sjdp#define ELF_MACHINE_CODE EM_ALPHA 464938889Sjdp#define ELF_MAXPAGESIZE 0x10000 465033965Sjdp 465133965Sjdp#define bfd_elf64_bfd_link_hash_table_create \ 465233965Sjdp elf64_alpha_bfd_link_hash_table_create 465333965Sjdp 465433965Sjdp#define bfd_elf64_bfd_reloc_type_lookup \ 465533965Sjdp elf64_alpha_bfd_reloc_type_lookup 465633965Sjdp#define elf_info_to_howto \ 465733965Sjdp elf64_alpha_info_to_howto 465833965Sjdp 465933965Sjdp#define bfd_elf64_mkobject \ 466033965Sjdp elf64_alpha_mkobject 466133965Sjdp#define elf_backend_object_p \ 466233965Sjdp elf64_alpha_object_p 466333965Sjdp 466433965Sjdp#define elf_backend_section_from_shdr \ 466533965Sjdp elf64_alpha_section_from_shdr 466633965Sjdp#define elf_backend_fake_sections \ 466733965Sjdp elf64_alpha_fake_sections 466833965Sjdp 466933965Sjdp#define bfd_elf64_bfd_is_local_label_name \ 467033965Sjdp elf64_alpha_is_local_label_name 467133965Sjdp#define bfd_elf64_find_nearest_line \ 467233965Sjdp elf64_alpha_find_nearest_line 467360510Sobrien#define bfd_elf64_bfd_relax_section \ 467460510Sobrien elf64_alpha_relax_section 467533965Sjdp 467660510Sobrien#define elf_backend_add_symbol_hook \ 467760510Sobrien elf64_alpha_add_symbol_hook 467833965Sjdp#define elf_backend_check_relocs \ 467933965Sjdp elf64_alpha_check_relocs 468033965Sjdp#define elf_backend_create_dynamic_sections \ 468133965Sjdp elf64_alpha_create_dynamic_sections 468233965Sjdp#define elf_backend_adjust_dynamic_symbol \ 468333965Sjdp elf64_alpha_adjust_dynamic_symbol 468433965Sjdp#define elf_backend_always_size_sections \ 468533965Sjdp elf64_alpha_always_size_sections 468633965Sjdp#define elf_backend_size_dynamic_sections \ 468733965Sjdp elf64_alpha_size_dynamic_sections 468833965Sjdp#define elf_backend_relocate_section \ 468933965Sjdp elf64_alpha_relocate_section 469033965Sjdp#define elf_backend_finish_dynamic_symbol \ 469133965Sjdp elf64_alpha_finish_dynamic_symbol 469233965Sjdp#define elf_backend_finish_dynamic_sections \ 469333965Sjdp elf64_alpha_finish_dynamic_sections 469433965Sjdp#define bfd_elf64_bfd_final_link \ 469533965Sjdp elf64_alpha_final_link 469633965Sjdp 469733965Sjdp#define elf_backend_ecoff_debug_swap \ 469833965Sjdp &elf64_alpha_ecoff_debug_swap 469933965Sjdp 470033965Sjdp/* 470133965Sjdp * A few constants that determine how the .plt section is set up. 470233965Sjdp */ 470333965Sjdp#define elf_backend_want_got_plt 0 470433965Sjdp#define elf_backend_plt_readonly 0 470533965Sjdp#define elf_backend_want_plt_sym 1 470660510Sobrien#define elf_backend_got_header_size 0 470760510Sobrien#define elf_backend_plt_header_size PLT_HEADER_SIZE 470833965Sjdp 470933965Sjdp#include "elf64-target.h" 4710