Back to index

cell-binutils  2.17cvs20070401
elf64-alpha.c
Go to the documentation of this file.
00001 /* Alpha specific support for 64-bit ELF
00002    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
00003    2006, 2007 Free Software Foundation, Inc.
00004    Contributed by Richard Henderson <rth@tamu.edu>.
00005 
00006    This file is part of BFD, the Binary File Descriptor library.
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00021 
00022 /* We need a published ABI spec for this.  Until one comes out, don't
00023    assume this'll remain unchanged forever.  */
00024 
00025 #include "bfd.h"
00026 #include "sysdep.h"
00027 #include "libbfd.h"
00028 #include "elf-bfd.h"
00029 
00030 #include "elf/alpha.h"
00031 
00032 #define ALPHAECOFF
00033 
00034 #define NO_COFF_RELOCS
00035 #define NO_COFF_SYMBOLS
00036 #define NO_COFF_LINENOS
00037 
00038 /* Get the ECOFF swapping routines.  Needed for the debug information.  */
00039 #include "coff/internal.h"
00040 #include "coff/sym.h"
00041 #include "coff/symconst.h"
00042 #include "coff/ecoff.h"
00043 #include "coff/alpha.h"
00044 #include "aout/ar.h"
00045 #include "libcoff.h"
00046 #include "libecoff.h"
00047 #define ECOFF_64
00048 #include "ecoffswap.h"
00049 
00050 
00051 /* Instruction data for plt generation and relaxation.  */
00052 
00053 #define OP_LDA              0x08
00054 #define OP_LDAH             0x09
00055 #define OP_LDQ              0x29
00056 #define OP_BR        0x30
00057 #define OP_BSR              0x34
00058 
00059 #define INSN_LDA     (OP_LDA << 26)
00060 #define INSN_LDAH    (OP_LDAH << 26)
00061 #define INSN_LDQ     (OP_LDQ << 26)
00062 #define INSN_BR             (OP_BR << 26)
00063 
00064 #define INSN_ADDQ    0x40000400
00065 #define INSN_RDUNIQ  0x0000009e
00066 #define INSN_SUBQ    0x40000520
00067 #define INSN_S4SUBQ  0x40000560
00068 #define INSN_UNOP    0x2ffe0000
00069 
00070 #define INSN_JSR     0x68004000
00071 #define INSN_JMP     0x68000000
00072 #define INSN_JSR_MASK       0xfc00c000
00073 
00074 #define INSN_A(I,A)         (I | (A << 21))
00075 #define INSN_AB(I,A,B)             (I | (A << 21) | (B << 16))
00076 #define INSN_ABC(I,A,B,C)   (I | (A << 21) | (B << 16) | C)
00077 #define INSN_ABO(I,A,B,O)   (I | (A << 21) | (B << 16) | ((O) & 0xffff))
00078 #define INSN_AD(I,A,D)             (I | (A << 21) | (((D) >> 2) & 0x1fffff))
00079 
00080 /* PLT/GOT Stuff */
00081 
00082 /* Set by ld emulation.  Putting this into the link_info or hash structure
00083    is simply working too hard.  */
00084 #ifdef USE_SECUREPLT
00085 bfd_boolean elf64_alpha_use_secureplt = TRUE;
00086 #else
00087 bfd_boolean elf64_alpha_use_secureplt = FALSE;
00088 #endif
00089 
00090 #define OLD_PLT_HEADER_SIZE 32
00091 #define OLD_PLT_ENTRY_SIZE  12
00092 #define NEW_PLT_HEADER_SIZE 36
00093 #define NEW_PLT_ENTRY_SIZE  4
00094 
00095 #define PLT_HEADER_SIZE \
00096   (elf64_alpha_use_secureplt ? NEW_PLT_HEADER_SIZE : OLD_PLT_HEADER_SIZE)
00097 #define PLT_ENTRY_SIZE \
00098   (elf64_alpha_use_secureplt ? NEW_PLT_ENTRY_SIZE : OLD_PLT_ENTRY_SIZE)
00099 
00100 #define MAX_GOT_SIZE        (64*1024)
00101 
00102 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so"
00103 
00104 struct alpha_elf_link_hash_entry
00105 {
00106   struct elf_link_hash_entry root;
00107 
00108   /* External symbol information.  */
00109   EXTR esym;
00110 
00111   /* Cumulative flags for all the .got entries.  */
00112   int flags;
00113 
00114   /* Contexts in which a literal was referenced.  */
00115 #define ALPHA_ELF_LINK_HASH_LU_ADDR        0x01
00116 #define ALPHA_ELF_LINK_HASH_LU_MEM  0x02
00117 #define ALPHA_ELF_LINK_HASH_LU_BYTE        0x04
00118 #define ALPHA_ELF_LINK_HASH_LU_JSR  0x08
00119 #define ALPHA_ELF_LINK_HASH_LU_TLSGD       0x10
00120 #define ALPHA_ELF_LINK_HASH_LU_TLSLDM      0x20
00121 #define ALPHA_ELF_LINK_HASH_LU_JSRDIRECT 0x40
00122 #define ALPHA_ELF_LINK_HASH_LU_PLT  0x38
00123 #define ALPHA_ELF_LINK_HASH_TLS_IE  0x80
00124 
00125   /* Used to implement multiple .got subsections.  */
00126   struct alpha_elf_got_entry
00127   {
00128     struct alpha_elf_got_entry *next;
00129 
00130     /* Which .got subsection?  */
00131     bfd *gotobj;
00132 
00133     /* The addend in effect for this entry.  */
00134     bfd_vma addend;
00135 
00136     /* The .got offset for this entry.  */
00137     int got_offset;
00138 
00139     /* The .plt offset for this entry.  */
00140     int plt_offset;
00141 
00142     /* How many references to this entry?  */
00143     int use_count;
00144 
00145     /* The relocation type of this entry.  */
00146     unsigned char reloc_type;
00147 
00148     /* How a LITERAL is used.  */
00149     unsigned char flags;
00150 
00151     /* Have we initialized the dynamic relocation for this entry?  */
00152     unsigned char reloc_done;
00153 
00154     /* Have we adjusted this entry for SEC_MERGE?  */
00155     unsigned char reloc_xlated;
00156   } *got_entries;
00157 
00158   /* Used to count non-got, non-plt relocations for delayed sizing
00159      of relocation sections.  */
00160   struct alpha_elf_reloc_entry
00161   {
00162     struct alpha_elf_reloc_entry *next;
00163 
00164     /* Which .reloc section? */
00165     asection *srel;
00166 
00167     /* What kind of relocation? */
00168     unsigned int rtype;
00169 
00170     /* Is this against read-only section? */
00171     unsigned int reltext : 1;
00172 
00173     /* How many did we find?  */
00174     unsigned long count;
00175   } *reloc_entries;
00176 };
00177 
00178 /* Alpha ELF linker hash table.  */
00179 
00180 struct alpha_elf_link_hash_table
00181 {
00182   struct elf_link_hash_table root;
00183 
00184   /* The head of a list of .got subsections linked through
00185      alpha_elf_tdata(abfd)->got_link_next.  */
00186   bfd *got_list;
00187 };
00188 
00189 /* Look up an entry in a Alpha ELF linker hash table.  */
00190 
00191 #define alpha_elf_link_hash_lookup(table, string, create, copy, follow)      \
00192   ((struct alpha_elf_link_hash_entry *)                               \
00193    elf_link_hash_lookup (&(table)->root, (string), (create),          \
00194                       (copy), (follow)))
00195 
00196 /* Traverse a Alpha ELF linker hash table.  */
00197 
00198 #define alpha_elf_link_hash_traverse(table, func, info)               \
00199   (elf_link_hash_traverse                                      \
00200    (&(table)->root,                                            \
00201     (bfd_boolean (*) (struct elf_link_hash_entry *, PTR)) (func),     \
00202     (info)))
00203 
00204 /* Get the Alpha ELF linker hash table from a link_info structure.  */
00205 
00206 #define alpha_elf_hash_table(p) \
00207   ((struct alpha_elf_link_hash_table *) ((p)->hash))
00208 
00209 /* Get the object's symbols as our own entry type.  */
00210 
00211 #define alpha_elf_sym_hashes(abfd) \
00212   ((struct alpha_elf_link_hash_entry **)elf_sym_hashes(abfd))
00213 
00214 /* Should we do dynamic things to this symbol?  This differs from the 
00215    generic version in that we never need to consider function pointer
00216    equality wrt PLT entries -- we don't create a PLT entry if a symbol's
00217    address is ever taken.  */
00218 
00219 static inline bfd_boolean
00220 alpha_elf_dynamic_symbol_p (struct elf_link_hash_entry *h,
00221                          struct bfd_link_info *info)
00222 {
00223   return _bfd_elf_dynamic_symbol_p (h, info, 0);
00224 }
00225 
00226 /* Create an entry in a Alpha ELF linker hash table.  */
00227 
00228 static struct bfd_hash_entry *
00229 elf64_alpha_link_hash_newfunc (struct bfd_hash_entry *entry,
00230                             struct bfd_hash_table *table,
00231                             const char *string)
00232 {
00233   struct alpha_elf_link_hash_entry *ret =
00234     (struct alpha_elf_link_hash_entry *) entry;
00235 
00236   /* Allocate the structure if it has not already been allocated by a
00237      subclass.  */
00238   if (ret == (struct alpha_elf_link_hash_entry *) NULL)
00239     ret = ((struct alpha_elf_link_hash_entry *)
00240           bfd_hash_allocate (table,
00241                            sizeof (struct alpha_elf_link_hash_entry)));
00242   if (ret == (struct alpha_elf_link_hash_entry *) NULL)
00243     return (struct bfd_hash_entry *) ret;
00244 
00245   /* Call the allocation method of the superclass.  */
00246   ret = ((struct alpha_elf_link_hash_entry *)
00247         _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
00248                                  table, string));
00249   if (ret != (struct alpha_elf_link_hash_entry *) NULL)
00250     {
00251       /* Set local fields.  */
00252       memset (&ret->esym, 0, sizeof (EXTR));
00253       /* We use -2 as a marker to indicate that the information has
00254         not been set.  -1 means there is no associated ifd.  */
00255       ret->esym.ifd = -2;
00256       ret->flags = 0;
00257       ret->got_entries = NULL;
00258       ret->reloc_entries = NULL;
00259     }
00260 
00261   return (struct bfd_hash_entry *) ret;
00262 }
00263 
00264 /* Create a Alpha ELF linker hash table.  */
00265 
00266 static struct bfd_link_hash_table *
00267 elf64_alpha_bfd_link_hash_table_create (bfd *abfd)
00268 {
00269   struct alpha_elf_link_hash_table *ret;
00270   bfd_size_type amt = sizeof (struct alpha_elf_link_hash_table);
00271 
00272   ret = (struct alpha_elf_link_hash_table *) bfd_zmalloc (amt);
00273   if (ret == (struct alpha_elf_link_hash_table *) NULL)
00274     return NULL;
00275 
00276   if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
00277                                   elf64_alpha_link_hash_newfunc,
00278                                   sizeof (struct alpha_elf_link_hash_entry)))
00279     {
00280       free (ret);
00281       return NULL;
00282     }
00283 
00284   return &ret->root.root;
00285 }
00286 
00287 /* We have some private fields hanging off of the elf_tdata structure.  */
00288 
00289 struct alpha_elf_obj_tdata
00290 {
00291   struct elf_obj_tdata root;
00292 
00293   /* For every input file, these are the got entries for that object's
00294      local symbols.  */
00295   struct alpha_elf_got_entry ** local_got_entries;
00296 
00297   /* For every input file, this is the object that owns the got that
00298      this input file uses.  */
00299   bfd *gotobj;
00300 
00301   /* For every got, this is a linked list through the objects using this got */
00302   bfd *in_got_link_next;
00303 
00304   /* For every got, this is a link to the next got subsegment.  */
00305   bfd *got_link_next;
00306 
00307   /* For every got, this is the section.  */
00308   asection *got;
00309 
00310   /* For every got, this is it's total number of words.  */
00311   int total_got_size;
00312 
00313   /* For every got, this is the sum of the number of words required
00314      to hold all of the member object's local got.  */
00315   int local_got_size;
00316 };
00317 
00318 #define alpha_elf_tdata(abfd) \
00319   ((struct alpha_elf_obj_tdata *) (abfd)->tdata.any)
00320 
00321 static bfd_boolean
00322 elf64_alpha_mkobject (bfd *abfd)
00323 {
00324   if (abfd->tdata.any == NULL)
00325     {
00326       bfd_size_type amt = sizeof (struct alpha_elf_obj_tdata);
00327       abfd->tdata.any = bfd_zalloc (abfd, amt);
00328       if (abfd->tdata.any == NULL)
00329        return FALSE;
00330     }
00331   return bfd_elf_mkobject (abfd);
00332 }
00333 
00334 static bfd_boolean
00335 elf64_alpha_object_p (bfd *abfd)
00336 {
00337   /* Set the right machine number for an Alpha ELF file.  */
00338   return bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0);
00339 }
00340 
00341 /* A relocation function which doesn't do anything.  */
00342 
00343 static bfd_reloc_status_type
00344 elf64_alpha_reloc_nil (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc,
00345                      asymbol *sym ATTRIBUTE_UNUSED,
00346                      PTR data ATTRIBUTE_UNUSED, asection *sec,
00347                      bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
00348 {
00349   if (output_bfd)
00350     reloc->address += sec->output_offset;
00351   return bfd_reloc_ok;
00352 }
00353 
00354 /* A relocation function used for an unsupported reloc.  */
00355 
00356 static bfd_reloc_status_type
00357 elf64_alpha_reloc_bad (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc,
00358                      asymbol *sym ATTRIBUTE_UNUSED,
00359                      PTR data ATTRIBUTE_UNUSED, asection *sec,
00360                      bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
00361 {
00362   if (output_bfd)
00363     reloc->address += sec->output_offset;
00364   return bfd_reloc_notsupported;
00365 }
00366 
00367 /* Do the work of the GPDISP relocation.  */
00368 
00369 static bfd_reloc_status_type
00370 elf64_alpha_do_reloc_gpdisp (bfd *abfd, bfd_vma gpdisp, bfd_byte *p_ldah,
00371                           bfd_byte *p_lda)
00372 {
00373   bfd_reloc_status_type ret = bfd_reloc_ok;
00374   bfd_vma addend;
00375   unsigned long i_ldah, i_lda;
00376 
00377   i_ldah = bfd_get_32 (abfd, p_ldah);
00378   i_lda = bfd_get_32 (abfd, p_lda);
00379 
00380   /* Complain if the instructions are not correct.  */
00381   if (((i_ldah >> 26) & 0x3f) != 0x09
00382       || ((i_lda >> 26) & 0x3f) != 0x08)
00383     ret = bfd_reloc_dangerous;
00384 
00385   /* Extract the user-supplied offset, mirroring the sign extensions
00386      that the instructions perform.  */
00387   addend = ((i_ldah & 0xffff) << 16) | (i_lda & 0xffff);
00388   addend = (addend ^ 0x80008000) - 0x80008000;
00389 
00390   gpdisp += addend;
00391 
00392   if ((bfd_signed_vma) gpdisp < -(bfd_signed_vma) 0x80000000
00393       || (bfd_signed_vma) gpdisp >= (bfd_signed_vma) 0x7fff8000)
00394     ret = bfd_reloc_overflow;
00395 
00396   /* compensate for the sign extension again.  */
00397   i_ldah = ((i_ldah & 0xffff0000)
00398            | (((gpdisp >> 16) + ((gpdisp >> 15) & 1)) & 0xffff));
00399   i_lda = (i_lda & 0xffff0000) | (gpdisp & 0xffff);
00400 
00401   bfd_put_32 (abfd, (bfd_vma) i_ldah, p_ldah);
00402   bfd_put_32 (abfd, (bfd_vma) i_lda, p_lda);
00403 
00404   return ret;
00405 }
00406 
00407 /* The special function for the GPDISP reloc.  */
00408 
00409 static bfd_reloc_status_type
00410 elf64_alpha_reloc_gpdisp (bfd *abfd, arelent *reloc_entry,
00411                        asymbol *sym ATTRIBUTE_UNUSED, PTR data,
00412                        asection *input_section, bfd *output_bfd,
00413                        char **err_msg)
00414 {
00415   bfd_reloc_status_type ret;
00416   bfd_vma gp, relocation;
00417   bfd_vma high_address;
00418   bfd_byte *p_ldah, *p_lda;
00419 
00420   /* Don't do anything if we're not doing a final link.  */
00421   if (output_bfd)
00422     {
00423       reloc_entry->address += input_section->output_offset;
00424       return bfd_reloc_ok;
00425     }
00426 
00427   high_address = bfd_get_section_limit (abfd, input_section);
00428   if (reloc_entry->address > high_address
00429       || reloc_entry->address + reloc_entry->addend > high_address)
00430     return bfd_reloc_outofrange;
00431 
00432   /* The gp used in the portion of the output object to which this
00433      input object belongs is cached on the input bfd.  */
00434   gp = _bfd_get_gp_value (abfd);
00435 
00436   relocation = (input_section->output_section->vma
00437               + input_section->output_offset
00438               + reloc_entry->address);
00439 
00440   p_ldah = (bfd_byte *) data + reloc_entry->address;
00441   p_lda = p_ldah + reloc_entry->addend;
00442 
00443   ret = elf64_alpha_do_reloc_gpdisp (abfd, gp - relocation, p_ldah, p_lda);
00444 
00445   /* Complain if the instructions are not correct.  */
00446   if (ret == bfd_reloc_dangerous)
00447     *err_msg = _("GPDISP relocation did not find ldah and lda instructions");
00448 
00449   return ret;
00450 }
00451 
00452 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
00453    from smaller values.  Start with zero, widen, *then* decrement.  */
00454 #define MINUS_ONE    (((bfd_vma)0) - 1)
00455 
00456 #define SKIP_HOWTO(N) \
00457   HOWTO(N, 0, 0, 0, 0, 0, 0, elf64_alpha_reloc_bad, 0, 0, 0, 0, 0)
00458 
00459 static reloc_howto_type elf64_alpha_howto_table[] =
00460 {
00461   HOWTO (R_ALPHA_NONE,             /* type */
00462         0,                  /* rightshift */
00463         0,                  /* size (0 = byte, 1 = short, 2 = long) */
00464         8,                  /* bitsize */
00465         TRUE,               /* pc_relative */
00466         0,                  /* bitpos */
00467         complain_overflow_dont, /* complain_on_overflow */
00468         elf64_alpha_reloc_nil,     /* special_function */
00469         "NONE",             /* name */
00470         FALSE,                     /* partial_inplace */
00471         0,                  /* src_mask */
00472         0,                  /* dst_mask */
00473         TRUE),                     /* pcrel_offset */
00474 
00475   /* A 32 bit reference to a symbol.  */
00476   HOWTO (R_ALPHA_REFLONG,   /* type */
00477         0,                  /* rightshift */
00478         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00479         32,                 /* bitsize */
00480         FALSE,                     /* pc_relative */
00481         0,                  /* bitpos */
00482         complain_overflow_bitfield, /* complain_on_overflow */
00483         0,                  /* special_function */
00484         "REFLONG",          /* name */
00485         FALSE,                     /* partial_inplace */
00486         0xffffffff,         /* src_mask */
00487         0xffffffff,         /* dst_mask */
00488         FALSE),             /* pcrel_offset */
00489 
00490   /* A 64 bit reference to a symbol.  */
00491   HOWTO (R_ALPHA_REFQUAD,   /* type */
00492         0,                  /* rightshift */
00493         4,                  /* size (0 = byte, 1 = short, 2 = long) */
00494         64,                 /* bitsize */
00495         FALSE,                     /* pc_relative */
00496         0,                  /* bitpos */
00497         complain_overflow_bitfield, /* complain_on_overflow */
00498         0,                  /* special_function */
00499         "REFQUAD",          /* name */
00500         FALSE,                     /* partial_inplace */
00501         MINUS_ONE,          /* src_mask */
00502         MINUS_ONE,          /* dst_mask */
00503         FALSE),             /* pcrel_offset */
00504 
00505   /* A 32 bit GP relative offset.  This is just like REFLONG except
00506      that when the value is used the value of the gp register will be
00507      added in.  */
00508   HOWTO (R_ALPHA_GPREL32,   /* type */
00509         0,                  /* rightshift */
00510         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00511         32,                 /* bitsize */
00512         FALSE,                     /* pc_relative */
00513         0,                  /* bitpos */
00514         complain_overflow_bitfield, /* complain_on_overflow */
00515         0,                  /* special_function */
00516         "GPREL32",          /* name */
00517         FALSE,                     /* partial_inplace */
00518         0xffffffff,         /* src_mask */
00519         0xffffffff,         /* dst_mask */
00520         FALSE),             /* pcrel_offset */
00521 
00522   /* Used for an instruction that refers to memory off the GP register.  */
00523   HOWTO (R_ALPHA_LITERAL,   /* type */
00524         0,                  /* rightshift */
00525         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00526         16,                 /* bitsize */
00527         FALSE,                     /* pc_relative */
00528         0,                  /* bitpos */
00529         complain_overflow_signed, /* complain_on_overflow */
00530         0,                  /* special_function */
00531         "ELF_LITERAL",             /* name */
00532         FALSE,                     /* partial_inplace */
00533         0xffff,             /* src_mask */
00534         0xffff,             /* dst_mask */
00535         FALSE),             /* pcrel_offset */
00536 
00537   /* This reloc only appears immediately following an ELF_LITERAL reloc.
00538      It identifies a use of the literal.  The symbol index is special:
00539      1 means the literal address is in the base register of a memory
00540      format instruction; 2 means the literal address is in the byte
00541      offset register of a byte-manipulation instruction; 3 means the
00542      literal address is in the target register of a jsr instruction.
00543      This does not actually do any relocation.  */
00544   HOWTO (R_ALPHA_LITUSE,    /* type */
00545         0,                  /* rightshift */
00546         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00547         32,                 /* bitsize */
00548         FALSE,                     /* pc_relative */
00549         0,                  /* bitpos */
00550         complain_overflow_dont, /* complain_on_overflow */
00551         elf64_alpha_reloc_nil,     /* special_function */
00552         "LITUSE",           /* name */
00553         FALSE,                     /* partial_inplace */
00554         0,                  /* src_mask */
00555         0,                  /* dst_mask */
00556         FALSE),             /* pcrel_offset */
00557 
00558   /* Load the gp register.  This is always used for a ldah instruction
00559      which loads the upper 16 bits of the gp register.  The symbol
00560      index of the GPDISP instruction is an offset in bytes to the lda
00561      instruction that loads the lower 16 bits.  The value to use for
00562      the relocation is the difference between the GP value and the
00563      current location; the load will always be done against a register
00564      holding the current address.
00565 
00566      NOTE: Unlike ECOFF, partial in-place relocation is not done.  If
00567      any offset is present in the instructions, it is an offset from
00568      the register to the ldah instruction.  This lets us avoid any
00569      stupid hackery like inventing a gp value to do partial relocation
00570      against.  Also unlike ECOFF, we do the whole relocation off of
00571      the GPDISP rather than a GPDISP_HI16/GPDISP_LO16 pair.  An odd,
00572      space consuming bit, that, since all the information was present
00573      in the GPDISP_HI16 reloc.  */
00574   HOWTO (R_ALPHA_GPDISP,    /* type */
00575         16,                 /* rightshift */
00576         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00577         16,                 /* bitsize */
00578         FALSE,                     /* pc_relative */
00579         0,                  /* bitpos */
00580         complain_overflow_dont, /* complain_on_overflow */
00581         elf64_alpha_reloc_gpdisp, /* special_function */
00582         "GPDISP",           /* name */
00583         FALSE,                     /* partial_inplace */
00584         0xffff,             /* src_mask */
00585         0xffff,             /* dst_mask */
00586         TRUE),                     /* pcrel_offset */
00587 
00588   /* A 21 bit branch.  */
00589   HOWTO (R_ALPHA_BRADDR,    /* type */
00590         2,                  /* rightshift */
00591         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00592         21,                 /* bitsize */
00593         TRUE,               /* pc_relative */
00594         0,                  /* bitpos */
00595         complain_overflow_signed, /* complain_on_overflow */
00596         0,                  /* special_function */
00597         "BRADDR",           /* name */
00598         FALSE,                     /* partial_inplace */
00599         0x1fffff,           /* src_mask */
00600         0x1fffff,           /* dst_mask */
00601         TRUE),                     /* pcrel_offset */
00602 
00603   /* A hint for a jump to a register.  */
00604   HOWTO (R_ALPHA_HINT,             /* type */
00605         2,                  /* rightshift */
00606         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00607         14,                 /* bitsize */
00608         TRUE,               /* pc_relative */
00609         0,                  /* bitpos */
00610         complain_overflow_dont, /* complain_on_overflow */
00611         0,                  /* special_function */
00612         "HINT",             /* name */
00613         FALSE,                     /* partial_inplace */
00614         0x3fff,             /* src_mask */
00615         0x3fff,             /* dst_mask */
00616         TRUE),                     /* pcrel_offset */
00617 
00618   /* 16 bit PC relative offset.  */
00619   HOWTO (R_ALPHA_SREL16,    /* type */
00620         0,                  /* rightshift */
00621         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00622         16,                 /* bitsize */
00623         TRUE,               /* pc_relative */
00624         0,                  /* bitpos */
00625         complain_overflow_signed, /* complain_on_overflow */
00626         0,                  /* special_function */
00627         "SREL16",           /* name */
00628         FALSE,                     /* partial_inplace */
00629         0xffff,             /* src_mask */
00630         0xffff,             /* dst_mask */
00631         TRUE),                     /* pcrel_offset */
00632 
00633   /* 32 bit PC relative offset.  */
00634   HOWTO (R_ALPHA_SREL32,    /* type */
00635         0,                  /* rightshift */
00636         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00637         32,                 /* bitsize */
00638         TRUE,               /* pc_relative */
00639         0,                  /* bitpos */
00640         complain_overflow_signed, /* complain_on_overflow */
00641         0,                  /* special_function */
00642         "SREL32",           /* name */
00643         FALSE,                     /* partial_inplace */
00644         0xffffffff,         /* src_mask */
00645         0xffffffff,         /* dst_mask */
00646         TRUE),                     /* pcrel_offset */
00647 
00648   /* A 64 bit PC relative offset.  */
00649   HOWTO (R_ALPHA_SREL64,    /* type */
00650         0,                  /* rightshift */
00651         4,                  /* size (0 = byte, 1 = short, 2 = long) */
00652         64,                 /* bitsize */
00653         TRUE,               /* pc_relative */
00654         0,                  /* bitpos */
00655         complain_overflow_signed, /* complain_on_overflow */
00656         0,                  /* special_function */
00657         "SREL64",           /* name */
00658         FALSE,                     /* partial_inplace */
00659         MINUS_ONE,          /* src_mask */
00660         MINUS_ONE,          /* dst_mask */
00661         TRUE),                     /* pcrel_offset */
00662 
00663   /* Skip 12 - 16; deprecated ECOFF relocs.  */
00664   SKIP_HOWTO (12),
00665   SKIP_HOWTO (13),
00666   SKIP_HOWTO (14),
00667   SKIP_HOWTO (15),
00668   SKIP_HOWTO (16),
00669 
00670   /* The high 16 bits of the displacement from GP to the target.  */
00671   HOWTO (R_ALPHA_GPRELHIGH,
00672         0,                  /* rightshift */
00673         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00674         16,                 /* bitsize */
00675         FALSE,                     /* pc_relative */
00676         0,                  /* bitpos */
00677         complain_overflow_signed, /* complain_on_overflow */
00678         0,                  /* special_function */
00679         "GPRELHIGH",        /* name */
00680         FALSE,                     /* partial_inplace */
00681         0xffff,             /* src_mask */
00682         0xffff,             /* dst_mask */
00683         FALSE),             /* pcrel_offset */
00684 
00685   /* The low 16 bits of the displacement from GP to the target.  */
00686   HOWTO (R_ALPHA_GPRELLOW,
00687         0,                  /* rightshift */
00688         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00689         16,                 /* bitsize */
00690         FALSE,                     /* pc_relative */
00691         0,                  /* bitpos */
00692         complain_overflow_dont, /* complain_on_overflow */
00693         0,                  /* special_function */
00694         "GPRELLOW",         /* name */
00695         FALSE,                     /* partial_inplace */
00696         0xffff,             /* src_mask */
00697         0xffff,             /* dst_mask */
00698         FALSE),             /* pcrel_offset */
00699 
00700   /* A 16-bit displacement from the GP to the target.  */
00701   HOWTO (R_ALPHA_GPREL16,
00702         0,                  /* rightshift */
00703         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00704         16,                 /* bitsize */
00705         FALSE,                     /* pc_relative */
00706         0,                  /* bitpos */
00707         complain_overflow_signed, /* complain_on_overflow */
00708         0,                  /* special_function */
00709         "GPREL16",          /* name */
00710         FALSE,                     /* partial_inplace */
00711         0xffff,             /* src_mask */
00712         0xffff,             /* dst_mask */
00713         FALSE),             /* pcrel_offset */
00714 
00715   /* Skip 20 - 23; deprecated ECOFF relocs.  */
00716   SKIP_HOWTO (20),
00717   SKIP_HOWTO (21),
00718   SKIP_HOWTO (22),
00719   SKIP_HOWTO (23),
00720 
00721   /* Misc ELF relocations.  */
00722 
00723   /* A dynamic relocation to copy the target into our .dynbss section.  */
00724   /* Not generated, as all Alpha objects use PIC, so it is not needed.  It
00725      is present because every other ELF has one, but should not be used
00726      because .dynbss is an ugly thing.  */
00727   HOWTO (R_ALPHA_COPY,
00728         0,
00729         0,
00730         0,
00731         FALSE,
00732         0,
00733         complain_overflow_dont,
00734         bfd_elf_generic_reloc,
00735         "COPY",
00736         FALSE,
00737         0,
00738         0,
00739         TRUE),
00740 
00741   /* A dynamic relocation for a .got entry.  */
00742   HOWTO (R_ALPHA_GLOB_DAT,
00743         0,
00744         0,
00745         0,
00746         FALSE,
00747         0,
00748         complain_overflow_dont,
00749         bfd_elf_generic_reloc,
00750         "GLOB_DAT",
00751         FALSE,
00752         0,
00753         0,
00754         TRUE),
00755 
00756   /* A dynamic relocation for a .plt entry.  */
00757   HOWTO (R_ALPHA_JMP_SLOT,
00758         0,
00759         0,
00760         0,
00761         FALSE,
00762         0,
00763         complain_overflow_dont,
00764         bfd_elf_generic_reloc,
00765         "JMP_SLOT",
00766         FALSE,
00767         0,
00768         0,
00769         TRUE),
00770 
00771   /* A dynamic relocation to add the base of the DSO to a 64-bit field.  */
00772   HOWTO (R_ALPHA_RELATIVE,
00773         0,
00774         0,
00775         0,
00776         FALSE,
00777         0,
00778         complain_overflow_dont,
00779         bfd_elf_generic_reloc,
00780         "RELATIVE",
00781         FALSE,
00782         0,
00783         0,
00784         TRUE),
00785 
00786   /* A 21 bit branch that adjusts for gp loads.  */
00787   HOWTO (R_ALPHA_BRSGP,            /* type */
00788         2,                  /* rightshift */
00789         2,                  /* size (0 = byte, 1 = short, 2 = long) */
00790         21,                 /* bitsize */
00791         TRUE,               /* pc_relative */
00792         0,                  /* bitpos */
00793         complain_overflow_signed, /* complain_on_overflow */
00794         0,                  /* special_function */
00795         "BRSGP",            /* name */
00796         FALSE,                     /* partial_inplace */
00797         0x1fffff,           /* src_mask */
00798         0x1fffff,           /* dst_mask */
00799         TRUE),                     /* pcrel_offset */
00800 
00801   /* Creates a tls_index for the symbol in the got.  */
00802   HOWTO (R_ALPHA_TLSGD,            /* type */
00803         0,                  /* rightshift */
00804         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00805         16,                 /* bitsize */
00806         FALSE,                     /* pc_relative */
00807         0,                  /* bitpos */
00808         complain_overflow_signed, /* complain_on_overflow */
00809         0,                  /* special_function */
00810         "TLSGD",            /* name */
00811         FALSE,                     /* partial_inplace */
00812         0xffff,             /* src_mask */
00813         0xffff,             /* dst_mask */
00814         FALSE),             /* pcrel_offset */
00815 
00816   /* Creates a tls_index for the (current) module in the got.  */
00817   HOWTO (R_ALPHA_TLSLDM,    /* type */
00818         0,                  /* rightshift */
00819         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00820         16,                 /* bitsize */
00821         FALSE,                     /* pc_relative */
00822         0,                  /* bitpos */
00823         complain_overflow_signed, /* complain_on_overflow */
00824         0,                  /* special_function */
00825         "TLSLDM",           /* name */
00826         FALSE,                     /* partial_inplace */
00827         0xffff,             /* src_mask */
00828         0xffff,             /* dst_mask */
00829         FALSE),             /* pcrel_offset */
00830 
00831   /* A dynamic relocation for a DTP module entry.  */
00832   HOWTO (R_ALPHA_DTPMOD64,  /* type */
00833         0,                  /* rightshift */
00834         4,                  /* size (0 = byte, 1 = short, 2 = long) */
00835         64,                 /* bitsize */
00836         FALSE,                     /* pc_relative */
00837         0,                  /* bitpos */
00838         complain_overflow_bitfield, /* complain_on_overflow */
00839         0,                  /* special_function */
00840         "DTPMOD64",         /* name */
00841         FALSE,                     /* partial_inplace */
00842         MINUS_ONE,          /* src_mask */
00843         MINUS_ONE,          /* dst_mask */
00844         FALSE),             /* pcrel_offset */
00845 
00846   /* Creates a 64-bit offset in the got for the displacement
00847      from DTP to the target.  */
00848   HOWTO (R_ALPHA_GOTDTPREL, /* type */
00849         0,                  /* rightshift */
00850         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00851         16,                 /* bitsize */
00852         FALSE,                     /* pc_relative */
00853         0,                  /* bitpos */
00854         complain_overflow_signed, /* complain_on_overflow */
00855         0,                  /* special_function */
00856         "GOTDTPREL",        /* name */
00857         FALSE,                     /* partial_inplace */
00858         0xffff,             /* src_mask */
00859         0xffff,             /* dst_mask */
00860         FALSE),             /* pcrel_offset */
00861 
00862   /* A dynamic relocation for a displacement from DTP to the target.  */
00863   HOWTO (R_ALPHA_DTPREL64,  /* type */
00864         0,                  /* rightshift */
00865         4,                  /* size (0 = byte, 1 = short, 2 = long) */
00866         64,                 /* bitsize */
00867         FALSE,                     /* pc_relative */
00868         0,                  /* bitpos */
00869         complain_overflow_bitfield, /* complain_on_overflow */
00870         0,                  /* special_function */
00871         "DTPREL64",         /* name */
00872         FALSE,                     /* partial_inplace */
00873         MINUS_ONE,          /* src_mask */
00874         MINUS_ONE,          /* dst_mask */
00875         FALSE),             /* pcrel_offset */
00876 
00877   /* The high 16 bits of the displacement from DTP to the target.  */
00878   HOWTO (R_ALPHA_DTPRELHI,  /* type */
00879         0,                  /* rightshift */
00880         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00881         16,                 /* bitsize */
00882         FALSE,                     /* pc_relative */
00883         0,                  /* bitpos */
00884         complain_overflow_signed, /* complain_on_overflow */
00885         0,                  /* special_function */
00886         "DTPRELHI",         /* name */
00887         FALSE,                     /* partial_inplace */
00888         0xffff,             /* src_mask */
00889         0xffff,             /* dst_mask */
00890         FALSE),             /* pcrel_offset */
00891 
00892   /* The low 16 bits of the displacement from DTP to the target.  */
00893   HOWTO (R_ALPHA_DTPRELLO,  /* type */
00894         0,                  /* rightshift */
00895         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00896         16,                 /* bitsize */
00897         FALSE,                     /* pc_relative */
00898         0,                  /* bitpos */
00899         complain_overflow_dont, /* complain_on_overflow */
00900         0,                  /* special_function */
00901         "DTPRELLO",         /* name */
00902         FALSE,                     /* partial_inplace */
00903         0xffff,             /* src_mask */
00904         0xffff,             /* dst_mask */
00905         FALSE),             /* pcrel_offset */
00906 
00907   /* A 16-bit displacement from DTP to the target.  */
00908   HOWTO (R_ALPHA_DTPREL16,  /* type */
00909         0,                  /* rightshift */
00910         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00911         16,                 /* bitsize */
00912         FALSE,                     /* pc_relative */
00913         0,                  /* bitpos */
00914         complain_overflow_signed, /* complain_on_overflow */
00915         0,                  /* special_function */
00916         "DTPREL16",         /* name */
00917         FALSE,                     /* partial_inplace */
00918         0xffff,             /* src_mask */
00919         0xffff,             /* dst_mask */
00920         FALSE),             /* pcrel_offset */
00921 
00922   /* Creates a 64-bit offset in the got for the displacement
00923      from TP to the target.  */
00924   HOWTO (R_ALPHA_GOTTPREL,  /* type */
00925         0,                  /* rightshift */
00926         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00927         16,                 /* bitsize */
00928         FALSE,                     /* pc_relative */
00929         0,                  /* bitpos */
00930         complain_overflow_signed, /* complain_on_overflow */
00931         0,                  /* special_function */
00932         "GOTTPREL",         /* name */
00933         FALSE,                     /* partial_inplace */
00934         0xffff,             /* src_mask */
00935         0xffff,             /* dst_mask */
00936         FALSE),             /* pcrel_offset */
00937 
00938   /* A dynamic relocation for a displacement from TP to the target.  */
00939   HOWTO (R_ALPHA_TPREL64,   /* type */
00940         0,                  /* rightshift */
00941         4,                  /* size (0 = byte, 1 = short, 2 = long) */
00942         64,                 /* bitsize */
00943         FALSE,                     /* pc_relative */
00944         0,                  /* bitpos */
00945         complain_overflow_bitfield, /* complain_on_overflow */
00946         0,                  /* special_function */
00947         "TPREL64",          /* name */
00948         FALSE,                     /* partial_inplace */
00949         MINUS_ONE,          /* src_mask */
00950         MINUS_ONE,          /* dst_mask */
00951         FALSE),             /* pcrel_offset */
00952 
00953   /* The high 16 bits of the displacement from TP to the target.  */
00954   HOWTO (R_ALPHA_TPRELHI,   /* type */
00955         0,                  /* rightshift */
00956         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00957         16,                 /* bitsize */
00958         FALSE,                     /* pc_relative */
00959         0,                  /* bitpos */
00960         complain_overflow_signed, /* complain_on_overflow */
00961         0,                  /* special_function */
00962         "TPRELHI",          /* name */
00963         FALSE,                     /* partial_inplace */
00964         0xffff,             /* src_mask */
00965         0xffff,             /* dst_mask */
00966         FALSE),             /* pcrel_offset */
00967 
00968   /* The low 16 bits of the displacement from TP to the target.  */
00969   HOWTO (R_ALPHA_TPRELLO,   /* type */
00970         0,                  /* rightshift */
00971         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00972         16,                 /* bitsize */
00973         FALSE,                     /* pc_relative */
00974         0,                  /* bitpos */
00975         complain_overflow_dont, /* complain_on_overflow */
00976         0,                  /* special_function */
00977         "TPRELLO",          /* name */
00978         FALSE,                     /* partial_inplace */
00979         0xffff,             /* src_mask */
00980         0xffff,             /* dst_mask */
00981         FALSE),             /* pcrel_offset */
00982 
00983   /* A 16-bit displacement from TP to the target.  */
00984   HOWTO (R_ALPHA_TPREL16,   /* type */
00985         0,                  /* rightshift */
00986         1,                  /* size (0 = byte, 1 = short, 2 = long) */
00987         16,                 /* bitsize */
00988         FALSE,                     /* pc_relative */
00989         0,                  /* bitpos */
00990         complain_overflow_signed, /* complain_on_overflow */
00991         0,                  /* special_function */
00992         "TPREL16",          /* name */
00993         FALSE,                     /* partial_inplace */
00994         0xffff,             /* src_mask */
00995         0xffff,             /* dst_mask */
00996         FALSE),             /* pcrel_offset */
00997 };
00998 
00999 /* A mapping from BFD reloc types to Alpha ELF reloc types.  */
01000 
01001 struct elf_reloc_map
01002 {
01003   bfd_reloc_code_real_type bfd_reloc_val;
01004   int elf_reloc_val;
01005 };
01006 
01007 static const struct elf_reloc_map elf64_alpha_reloc_map[] =
01008 {
01009   {BFD_RELOC_NONE,                 R_ALPHA_NONE},
01010   {BFD_RELOC_32,                   R_ALPHA_REFLONG},
01011   {BFD_RELOC_64,                   R_ALPHA_REFQUAD},
01012   {BFD_RELOC_CTOR,                 R_ALPHA_REFQUAD},
01013   {BFD_RELOC_GPREL32,                     R_ALPHA_GPREL32},
01014   {BFD_RELOC_ALPHA_ELF_LITERAL,           R_ALPHA_LITERAL},
01015   {BFD_RELOC_ALPHA_LITUSE,         R_ALPHA_LITUSE},
01016   {BFD_RELOC_ALPHA_GPDISP,         R_ALPHA_GPDISP},
01017   {BFD_RELOC_23_PCREL_S2,          R_ALPHA_BRADDR},
01018   {BFD_RELOC_ALPHA_HINT,           R_ALPHA_HINT},
01019   {BFD_RELOC_16_PCREL,                    R_ALPHA_SREL16},
01020   {BFD_RELOC_32_PCREL,                    R_ALPHA_SREL32},
01021   {BFD_RELOC_64_PCREL,                    R_ALPHA_SREL64},
01022   {BFD_RELOC_ALPHA_GPREL_HI16,            R_ALPHA_GPRELHIGH},
01023   {BFD_RELOC_ALPHA_GPREL_LO16,            R_ALPHA_GPRELLOW},
01024   {BFD_RELOC_GPREL16,                     R_ALPHA_GPREL16},
01025   {BFD_RELOC_ALPHA_BRSGP,          R_ALPHA_BRSGP},
01026   {BFD_RELOC_ALPHA_TLSGD,          R_ALPHA_TLSGD},
01027   {BFD_RELOC_ALPHA_TLSLDM,         R_ALPHA_TLSLDM},
01028   {BFD_RELOC_ALPHA_DTPMOD64,              R_ALPHA_DTPMOD64},
01029   {BFD_RELOC_ALPHA_GOTDTPREL16,           R_ALPHA_GOTDTPREL},
01030   {BFD_RELOC_ALPHA_DTPREL64,              R_ALPHA_DTPREL64},
01031   {BFD_RELOC_ALPHA_DTPREL_HI16,           R_ALPHA_DTPRELHI},
01032   {BFD_RELOC_ALPHA_DTPREL_LO16,           R_ALPHA_DTPRELLO},
01033   {BFD_RELOC_ALPHA_DTPREL16,              R_ALPHA_DTPREL16},
01034   {BFD_RELOC_ALPHA_GOTTPREL16,            R_ALPHA_GOTTPREL},
01035   {BFD_RELOC_ALPHA_TPREL64,        R_ALPHA_TPREL64},
01036   {BFD_RELOC_ALPHA_TPREL_HI16,            R_ALPHA_TPRELHI},
01037   {BFD_RELOC_ALPHA_TPREL_LO16,            R_ALPHA_TPRELLO},
01038   {BFD_RELOC_ALPHA_TPREL16,        R_ALPHA_TPREL16},
01039 };
01040 
01041 /* Given a BFD reloc type, return a HOWTO structure.  */
01042 
01043 static reloc_howto_type *
01044 elf64_alpha_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
01045                                bfd_reloc_code_real_type code)
01046 {
01047   const struct elf_reloc_map *i, *e;
01048   i = e = elf64_alpha_reloc_map;
01049   e += sizeof (elf64_alpha_reloc_map) / sizeof (struct elf_reloc_map);
01050   for (; i != e; ++i)
01051     {
01052       if (i->bfd_reloc_val == code)
01053        return &elf64_alpha_howto_table[i->elf_reloc_val];
01054     }
01055   return 0;
01056 }
01057 
01058 static reloc_howto_type *
01059 elf64_alpha_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
01060                                const char *r_name)
01061 {
01062   unsigned int i;
01063 
01064   for (i = 0;
01065        i < (sizeof (elf64_alpha_howto_table)
01066            / sizeof (elf64_alpha_howto_table[0]));
01067        i++)
01068     if (elf64_alpha_howto_table[i].name != NULL
01069        && strcasecmp (elf64_alpha_howto_table[i].name, r_name) == 0)
01070       return &elf64_alpha_howto_table[i];
01071 
01072   return NULL;
01073 }
01074 
01075 /* Given an Alpha ELF reloc type, fill in an arelent structure.  */
01076 
01077 static void
01078 elf64_alpha_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
01079                         Elf_Internal_Rela *dst)
01080 {
01081   unsigned r_type = ELF64_R_TYPE(dst->r_info);
01082   BFD_ASSERT (r_type < (unsigned int) R_ALPHA_max);
01083   cache_ptr->howto = &elf64_alpha_howto_table[r_type];
01084 }
01085 
01086 /* These two relocations create a two-word entry in the got.  */
01087 #define alpha_got_entry_size(r_type) \
01088   (r_type == R_ALPHA_TLSGD || r_type == R_ALPHA_TLSLDM ? 16 : 8)
01089 
01090 /* This is PT_TLS segment p_vaddr.  */
01091 #define alpha_get_dtprel_base(info) \
01092   (elf_hash_table (info)->tls_sec->vma)
01093 
01094 /* Main program TLS (whose template starts at PT_TLS p_vaddr)
01095    is assigned offset round(16, PT_TLS p_align).  */
01096 #define alpha_get_tprel_base(info) \
01097   (elf_hash_table (info)->tls_sec->vma                                \
01098    - align_power ((bfd_vma) 16,                                       \
01099                 elf_hash_table (info)->tls_sec->alignment_power))
01100 
01101 /* Handle an Alpha specific section when reading an object file.  This
01102    is called when bfd_section_from_shdr finds a section with an unknown
01103    type.
01104    FIXME: We need to handle the SHF_ALPHA_GPREL flag, but I'm not sure
01105    how to.  */
01106 
01107 static bfd_boolean
01108 elf64_alpha_section_from_shdr (bfd *abfd,
01109                             Elf_Internal_Shdr *hdr,
01110                             const char *name,
01111                             int shindex)
01112 {
01113   asection *newsect;
01114 
01115   /* There ought to be a place to keep ELF backend specific flags, but
01116      at the moment there isn't one.  We just keep track of the
01117      sections by their name, instead.  Fortunately, the ABI gives
01118      suggested names for all the MIPS specific sections, so we will
01119      probably get away with this.  */
01120   switch (hdr->sh_type)
01121     {
01122     case SHT_ALPHA_DEBUG:
01123       if (strcmp (name, ".mdebug") != 0)
01124        return FALSE;
01125       break;
01126     default:
01127       return FALSE;
01128     }
01129 
01130   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
01131     return FALSE;
01132   newsect = hdr->bfd_section;
01133 
01134   if (hdr->sh_type == SHT_ALPHA_DEBUG)
01135     {
01136       if (! bfd_set_section_flags (abfd, newsect,
01137                                (bfd_get_section_flags (abfd, newsect)
01138                                 | SEC_DEBUGGING)))
01139        return FALSE;
01140     }
01141 
01142   return TRUE;
01143 }
01144 
01145 /* Convert Alpha specific section flags to bfd internal section flags.  */
01146 
01147 static bfd_boolean
01148 elf64_alpha_section_flags (flagword *flags, const Elf_Internal_Shdr *hdr)
01149 {
01150   if (hdr->sh_flags & SHF_ALPHA_GPREL)
01151     *flags |= SEC_SMALL_DATA;
01152 
01153   return TRUE;
01154 }
01155 
01156 /* Set the correct type for an Alpha ELF section.  We do this by the
01157    section name, which is a hack, but ought to work.  */
01158 
01159 static bfd_boolean
01160 elf64_alpha_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec)
01161 {
01162   register const char *name;
01163 
01164   name = bfd_get_section_name (abfd, sec);
01165 
01166   if (strcmp (name, ".mdebug") == 0)
01167     {
01168       hdr->sh_type = SHT_ALPHA_DEBUG;
01169       /* In a shared object on Irix 5.3, the .mdebug section has an
01170          entsize of 0.  FIXME: Does this matter?  */
01171       if ((abfd->flags & DYNAMIC) != 0 )
01172        hdr->sh_entsize = 0;
01173       else
01174        hdr->sh_entsize = 1;
01175     }
01176   else if ((sec->flags & SEC_SMALL_DATA)
01177           || strcmp (name, ".sdata") == 0
01178           || strcmp (name, ".sbss") == 0
01179           || strcmp (name, ".lit4") == 0
01180           || strcmp (name, ".lit8") == 0)
01181     hdr->sh_flags |= SHF_ALPHA_GPREL;
01182 
01183   return TRUE;
01184 }
01185 
01186 /* Hook called by the linker routine which adds symbols from an object
01187    file.  We use it to put .comm items in .sbss, and not .bss.  */
01188 
01189 static bfd_boolean
01190 elf64_alpha_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
01191                           Elf_Internal_Sym *sym,
01192                           const char **namep ATTRIBUTE_UNUSED,
01193                           flagword *flagsp ATTRIBUTE_UNUSED,
01194                           asection **secp, bfd_vma *valp)
01195 {
01196   if (sym->st_shndx == SHN_COMMON
01197       && !info->relocatable
01198       && sym->st_size <= elf_gp_size (abfd))
01199     {
01200       /* Common symbols less than or equal to -G nn bytes are
01201         automatically put into .sbss.  */
01202 
01203       asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
01204 
01205       if (scomm == NULL)
01206        {
01207          scomm = bfd_make_section_with_flags (abfd, ".scommon",
01208                                           (SEC_ALLOC
01209                                           | SEC_IS_COMMON
01210                                           | SEC_LINKER_CREATED));
01211          if (scomm == NULL)
01212            return FALSE;
01213        }
01214 
01215       *secp = scomm;
01216       *valp = sym->st_size;
01217     }
01218 
01219   return TRUE;
01220 }
01221 
01222 /* Create the .got section.  */
01223 
01224 static bfd_boolean
01225 elf64_alpha_create_got_section (bfd *abfd,
01226                             struct bfd_link_info *info ATTRIBUTE_UNUSED)
01227 {
01228   flagword flags;
01229   asection *s;
01230 
01231   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
01232           | SEC_LINKER_CREATED);
01233   s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
01234   if (s == NULL
01235       || !bfd_set_section_alignment (abfd, s, 3))
01236     return FALSE;
01237 
01238   alpha_elf_tdata (abfd)->got = s;
01239 
01240   /* Make sure the object's gotobj is set to itself so that we default
01241      to every object with its own .got.  We'll merge .gots later once
01242      we've collected each object's info.  */
01243   alpha_elf_tdata (abfd)->gotobj = abfd;
01244 
01245   return TRUE;
01246 }
01247 
01248 /* Create all the dynamic sections.  */
01249 
01250 static bfd_boolean
01251 elf64_alpha_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
01252 {
01253   asection *s;
01254   flagword flags;
01255   struct elf_link_hash_entry *h;
01256 
01257   /* We need to create .plt, .rela.plt, .got, and .rela.got sections.  */
01258 
01259   flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_IN_MEMORY
01260           | SEC_LINKER_CREATED
01261           | (elf64_alpha_use_secureplt ? SEC_READONLY : 0));
01262   s = bfd_make_section_anyway_with_flags (abfd, ".plt", flags);
01263   if (s == NULL || ! bfd_set_section_alignment (abfd, s, 4))
01264     return FALSE;
01265 
01266   /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
01267      .plt section.  */
01268   h = _bfd_elf_define_linkage_sym (abfd, info, s,
01269                                "_PROCEDURE_LINKAGE_TABLE_");
01270   elf_hash_table (info)->hplt = h;
01271   if (h == NULL)
01272     return FALSE;
01273 
01274   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
01275           | SEC_LINKER_CREATED | SEC_READONLY);
01276   s = bfd_make_section_anyway_with_flags (abfd, ".rela.plt", flags);
01277   if (s == NULL || ! bfd_set_section_alignment (abfd, s, 3))
01278     return FALSE;
01279 
01280   if (elf64_alpha_use_secureplt)
01281     {
01282       flags = SEC_ALLOC | SEC_LINKER_CREATED;
01283       s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
01284       if (s == NULL || ! bfd_set_section_alignment (abfd, s, 3))
01285        return FALSE;
01286     }
01287 
01288   /* We may or may not have created a .got section for this object, but
01289      we definitely havn't done the rest of the work.  */
01290 
01291   if (alpha_elf_tdata(abfd)->gotobj == NULL)
01292     {
01293       if (!elf64_alpha_create_got_section (abfd, info))
01294        return FALSE;
01295     }
01296 
01297   flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
01298           | SEC_LINKER_CREATED | SEC_READONLY);
01299   s = bfd_make_section_anyway_with_flags (abfd, ".rela.got", flags);
01300   if (s == NULL
01301       || !bfd_set_section_alignment (abfd, s, 3))
01302     return FALSE;
01303 
01304   /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the
01305      dynobj's .got section.  We don't do this in the linker script
01306      because we don't want to define the symbol if we are not creating
01307      a global offset table.  */
01308   h = _bfd_elf_define_linkage_sym (abfd, info, alpha_elf_tdata(abfd)->got,
01309                                "_GLOBAL_OFFSET_TABLE_");
01310   elf_hash_table (info)->hgot = h;
01311   if (h == NULL)
01312     return FALSE;
01313 
01314   return TRUE;
01315 }
01316 
01317 /* Read ECOFF debugging information from a .mdebug section into a
01318    ecoff_debug_info structure.  */
01319 
01320 static bfd_boolean
01321 elf64_alpha_read_ecoff_info (bfd *abfd, asection *section,
01322                           struct ecoff_debug_info *debug)
01323 {
01324   HDRR *symhdr;
01325   const struct ecoff_debug_swap *swap;
01326   char *ext_hdr = NULL;
01327 
01328   swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
01329   memset (debug, 0, sizeof (*debug));
01330 
01331   ext_hdr = (char *) bfd_malloc (swap->external_hdr_size);
01332   if (ext_hdr == NULL && swap->external_hdr_size != 0)
01333     goto error_return;
01334 
01335   if (! bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0,
01336                               swap->external_hdr_size))
01337     goto error_return;
01338 
01339   symhdr = &debug->symbolic_header;
01340   (*swap->swap_hdr_in) (abfd, ext_hdr, symhdr);
01341 
01342   /* The symbolic header contains absolute file offsets and sizes to
01343      read.  */
01344 #define READ(ptr, offset, count, size, type)                          \
01345   if (symhdr->count == 0)                                      \
01346     debug->ptr = NULL;                                                \
01347   else                                                         \
01348     {                                                          \
01349       bfd_size_type amt = (bfd_size_type) size * symhdr->count;              \
01350       debug->ptr = (type) bfd_malloc (amt);                           \
01351       if (debug->ptr == NULL)                                         \
01352        goto error_return;                                      \
01353       if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0   \
01354          || bfd_bread (debug->ptr, amt, abfd) != amt)                 \
01355        goto error_return;                                      \
01356     }
01357 
01358   READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *);
01359   READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR);
01360   READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR);
01361   READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR);
01362   READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR);
01363   READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext),
01364        union aux_ext *);
01365   READ (ss, cbSsOffset, issMax, sizeof (char), char *);
01366   READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *);
01367   READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR);
01368   READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR);
01369   READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, PTR);
01370 #undef READ
01371 
01372   debug->fdr = NULL;
01373 
01374   return TRUE;
01375 
01376  error_return:
01377   if (ext_hdr != NULL)
01378     free (ext_hdr);
01379   if (debug->line != NULL)
01380     free (debug->line);
01381   if (debug->external_dnr != NULL)
01382     free (debug->external_dnr);
01383   if (debug->external_pdr != NULL)
01384     free (debug->external_pdr);
01385   if (debug->external_sym != NULL)
01386     free (debug->external_sym);
01387   if (debug->external_opt != NULL)
01388     free (debug->external_opt);
01389   if (debug->external_aux != NULL)
01390     free (debug->external_aux);
01391   if (debug->ss != NULL)
01392     free (debug->ss);
01393   if (debug->ssext != NULL)
01394     free (debug->ssext);
01395   if (debug->external_fdr != NULL)
01396     free (debug->external_fdr);
01397   if (debug->external_rfd != NULL)
01398     free (debug->external_rfd);
01399   if (debug->external_ext != NULL)
01400     free (debug->external_ext);
01401   return FALSE;
01402 }
01403 
01404 /* Alpha ELF local labels start with '$'.  */
01405 
01406 static bfd_boolean
01407 elf64_alpha_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED, const char *name)
01408 {
01409   return name[0] == '$';
01410 }
01411 
01412 /* Alpha ELF follows MIPS ELF in using a special find_nearest_line
01413    routine in order to handle the ECOFF debugging information.  We
01414    still call this mips_elf_find_line because of the slot
01415    find_line_info in elf_obj_tdata is declared that way.  */
01416 
01417 struct mips_elf_find_line
01418 {
01419   struct ecoff_debug_info d;
01420   struct ecoff_find_line i;
01421 };
01422 
01423 static bfd_boolean
01424 elf64_alpha_find_nearest_line (bfd *abfd, asection *section, asymbol **symbols,
01425                             bfd_vma offset, const char **filename_ptr,
01426                             const char **functionname_ptr,
01427                             unsigned int *line_ptr)
01428 {
01429   asection *msec;
01430 
01431   if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
01432                                  filename_ptr, functionname_ptr,
01433                                  line_ptr, 0,
01434                                  &elf_tdata (abfd)->dwarf2_find_line_info))
01435     return TRUE;
01436 
01437   msec = bfd_get_section_by_name (abfd, ".mdebug");
01438   if (msec != NULL)
01439     {
01440       flagword origflags;
01441       struct mips_elf_find_line *fi;
01442       const struct ecoff_debug_swap * const swap =
01443        get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
01444 
01445       /* If we are called during a link, alpha_elf_final_link may have
01446         cleared the SEC_HAS_CONTENTS field.  We force it back on here
01447         if appropriate (which it normally will be).  */
01448       origflags = msec->flags;
01449       if (elf_section_data (msec)->this_hdr.sh_type != SHT_NOBITS)
01450        msec->flags |= SEC_HAS_CONTENTS;
01451 
01452       fi = elf_tdata (abfd)->find_line_info;
01453       if (fi == NULL)
01454        {
01455          bfd_size_type external_fdr_size;
01456          char *fraw_src;
01457          char *fraw_end;
01458          struct fdr *fdr_ptr;
01459          bfd_size_type amt = sizeof (struct mips_elf_find_line);
01460 
01461          fi = (struct mips_elf_find_line *) bfd_zalloc (abfd, amt);
01462          if (fi == NULL)
01463            {
01464              msec->flags = origflags;
01465              return FALSE;
01466            }
01467 
01468          if (!elf64_alpha_read_ecoff_info (abfd, msec, &fi->d))
01469            {
01470              msec->flags = origflags;
01471              return FALSE;
01472            }
01473 
01474          /* Swap in the FDR information.  */
01475          amt = fi->d.symbolic_header.ifdMax * sizeof (struct fdr);
01476          fi->d.fdr = (struct fdr *) bfd_alloc (abfd, amt);
01477          if (fi->d.fdr == NULL)
01478            {
01479              msec->flags = origflags;
01480              return FALSE;
01481            }
01482          external_fdr_size = swap->external_fdr_size;
01483          fdr_ptr = fi->d.fdr;
01484          fraw_src = (char *) fi->d.external_fdr;
01485          fraw_end = (fraw_src
01486                     + fi->d.symbolic_header.ifdMax * external_fdr_size);
01487          for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++)
01488            (*swap->swap_fdr_in) (abfd, (PTR) fraw_src, fdr_ptr);
01489 
01490          elf_tdata (abfd)->find_line_info = fi;
01491 
01492          /* Note that we don't bother to ever free this information.
01493              find_nearest_line is either called all the time, as in
01494              objdump -l, so the information should be saved, or it is
01495              rarely called, as in ld error messages, so the memory
01496              wasted is unimportant.  Still, it would probably be a
01497              good idea for free_cached_info to throw it away.  */
01498        }
01499 
01500       if (_bfd_ecoff_locate_line (abfd, section, offset, &fi->d, swap,
01501                               &fi->i, filename_ptr, functionname_ptr,
01502                               line_ptr))
01503        {
01504          msec->flags = origflags;
01505          return TRUE;
01506        }
01507 
01508       msec->flags = origflags;
01509     }
01510 
01511   /* Fall back on the generic ELF find_nearest_line routine.  */
01512 
01513   return _bfd_elf_find_nearest_line (abfd, section, symbols, offset,
01514                                  filename_ptr, functionname_ptr,
01515                                  line_ptr);
01516 }
01517 
01518 /* Structure used to pass information to alpha_elf_output_extsym.  */
01519 
01520 struct extsym_info
01521 {
01522   bfd *abfd;
01523   struct bfd_link_info *info;
01524   struct ecoff_debug_info *debug;
01525   const struct ecoff_debug_swap *swap;
01526   bfd_boolean failed;
01527 };
01528 
01529 static bfd_boolean
01530 elf64_alpha_output_extsym (struct alpha_elf_link_hash_entry *h, PTR data)
01531 {
01532   struct extsym_info *einfo = (struct extsym_info *) data;
01533   bfd_boolean strip;
01534   asection *sec, *output_section;
01535 
01536   if (h->root.root.type == bfd_link_hash_warning)
01537     h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
01538 
01539   if (h->root.indx == -2)
01540     strip = FALSE;
01541   else if ((h->root.def_dynamic
01542            || h->root.ref_dynamic
01543            || h->root.root.type == bfd_link_hash_new)
01544           && !h->root.def_regular
01545           && !h->root.ref_regular)
01546     strip = TRUE;
01547   else if (einfo->info->strip == strip_all
01548           || (einfo->info->strip == strip_some
01549               && bfd_hash_lookup (einfo->info->keep_hash,
01550                                h->root.root.root.string,
01551                                FALSE, FALSE) == NULL))
01552     strip = TRUE;
01553   else
01554     strip = FALSE;
01555 
01556   if (strip)
01557     return TRUE;
01558 
01559   if (h->esym.ifd == -2)
01560     {
01561       h->esym.jmptbl = 0;
01562       h->esym.cobol_main = 0;
01563       h->esym.weakext = 0;
01564       h->esym.reserved = 0;
01565       h->esym.ifd = ifdNil;
01566       h->esym.asym.value = 0;
01567       h->esym.asym.st = stGlobal;
01568 
01569       if (h->root.root.type != bfd_link_hash_defined
01570          && h->root.root.type != bfd_link_hash_defweak)
01571        h->esym.asym.sc = scAbs;
01572       else
01573        {
01574          const char *name;
01575 
01576          sec = h->root.root.u.def.section;
01577          output_section = sec->output_section;
01578 
01579          /* When making a shared library and symbol h is the one from
01580             the another shared library, OUTPUT_SECTION may be null.  */
01581          if (output_section == NULL)
01582            h->esym.asym.sc = scUndefined;
01583          else
01584            {
01585              name = bfd_section_name (output_section->owner, output_section);
01586 
01587              if (strcmp (name, ".text") == 0)
01588               h->esym.asym.sc = scText;
01589              else if (strcmp (name, ".data") == 0)
01590               h->esym.asym.sc = scData;
01591              else if (strcmp (name, ".sdata") == 0)
01592               h->esym.asym.sc = scSData;
01593              else if (strcmp (name, ".rodata") == 0
01594                      || strcmp (name, ".rdata") == 0)
01595               h->esym.asym.sc = scRData;
01596              else if (strcmp (name, ".bss") == 0)
01597               h->esym.asym.sc = scBss;
01598              else if (strcmp (name, ".sbss") == 0)
01599               h->esym.asym.sc = scSBss;
01600              else if (strcmp (name, ".init") == 0)
01601               h->esym.asym.sc = scInit;
01602              else if (strcmp (name, ".fini") == 0)
01603               h->esym.asym.sc = scFini;
01604              else
01605               h->esym.asym.sc = scAbs;
01606            }
01607        }
01608 
01609       h->esym.asym.reserved = 0;
01610       h->esym.asym.index = indexNil;
01611     }
01612 
01613   if (h->root.root.type == bfd_link_hash_common)
01614     h->esym.asym.value = h->root.root.u.c.size;
01615   else if (h->root.root.type == bfd_link_hash_defined
01616           || h->root.root.type == bfd_link_hash_defweak)
01617     {
01618       if (h->esym.asym.sc == scCommon)
01619        h->esym.asym.sc = scBss;
01620       else if (h->esym.asym.sc == scSCommon)
01621        h->esym.asym.sc = scSBss;
01622 
01623       sec = h->root.root.u.def.section;
01624       output_section = sec->output_section;
01625       if (output_section != NULL)
01626        h->esym.asym.value = (h->root.root.u.def.value
01627                            + sec->output_offset
01628                            + output_section->vma);
01629       else
01630        h->esym.asym.value = 0;
01631     }
01632 
01633   if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap,
01634                                   h->root.root.root.string,
01635                                   &h->esym))
01636     {
01637       einfo->failed = TRUE;
01638       return FALSE;
01639     }
01640 
01641   return TRUE;
01642 }
01643 
01644 /* Search for and possibly create a got entry.  */
01645 
01646 static struct alpha_elf_got_entry *
01647 get_got_entry (bfd *abfd, struct alpha_elf_link_hash_entry *h,
01648               unsigned long r_type, unsigned long r_symndx,
01649               bfd_vma r_addend)
01650 {
01651   struct alpha_elf_got_entry *gotent;
01652   struct alpha_elf_got_entry **slot;
01653 
01654   if (h)
01655     slot = &h->got_entries;
01656   else
01657     {
01658       /* This is a local .got entry -- record for merge.  */
01659 
01660       struct alpha_elf_got_entry **local_got_entries;
01661 
01662       local_got_entries = alpha_elf_tdata(abfd)->local_got_entries;
01663       if (!local_got_entries)
01664        {
01665          bfd_size_type size;
01666          Elf_Internal_Shdr *symtab_hdr;
01667 
01668          symtab_hdr = &elf_tdata(abfd)->symtab_hdr;
01669          size = symtab_hdr->sh_info;
01670          size *= sizeof (struct alpha_elf_got_entry *);
01671 
01672          local_got_entries
01673            = (struct alpha_elf_got_entry **) bfd_zalloc (abfd, size);
01674          if (!local_got_entries)
01675            return NULL;
01676 
01677          alpha_elf_tdata (abfd)->local_got_entries = local_got_entries;
01678        }
01679 
01680       slot = &local_got_entries[r_symndx];
01681     }
01682 
01683   for (gotent = *slot; gotent ; gotent = gotent->next)
01684     if (gotent->gotobj == abfd
01685        && gotent->reloc_type == r_type
01686        && gotent->addend == r_addend)
01687       break;
01688 
01689   if (!gotent)
01690     {
01691       int entry_size;
01692       bfd_size_type amt;
01693 
01694       amt = sizeof (struct alpha_elf_got_entry);
01695       gotent = (struct alpha_elf_got_entry *) bfd_alloc (abfd, amt);
01696       if (!gotent)
01697        return NULL;
01698 
01699       gotent->gotobj = abfd;
01700       gotent->addend = r_addend;
01701       gotent->got_offset = -1;
01702       gotent->plt_offset = -1;
01703       gotent->use_count = 1;
01704       gotent->reloc_type = r_type;
01705       gotent->reloc_done = 0;
01706       gotent->reloc_xlated = 0;
01707 
01708       gotent->next = *slot;
01709       *slot = gotent;
01710 
01711       entry_size = alpha_got_entry_size (r_type);
01712       alpha_elf_tdata (abfd)->total_got_size += entry_size;
01713       if (!h)
01714        alpha_elf_tdata(abfd)->local_got_size += entry_size;
01715     }
01716   else
01717     gotent->use_count += 1;
01718 
01719   return gotent;
01720 }
01721 
01722 static bfd_boolean
01723 elf64_alpha_want_plt (struct alpha_elf_link_hash_entry *ah)
01724 {
01725   return ((ah->root.type == STT_FUNC
01726          || ah->root.root.type == bfd_link_hash_undefweak
01727          || ah->root.root.type == bfd_link_hash_undefined)
01728          && (ah->flags & ALPHA_ELF_LINK_HASH_LU_PLT) != 0
01729          && (ah->flags & ~ALPHA_ELF_LINK_HASH_LU_PLT) == 0);
01730 }
01731 
01732 /* Handle dynamic relocations when doing an Alpha ELF link.  */
01733 
01734 static bfd_boolean
01735 elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info,
01736                        asection *sec, const Elf_Internal_Rela *relocs)
01737 {
01738   bfd *dynobj;
01739   asection *sreloc;
01740   const char *rel_sec_name;
01741   Elf_Internal_Shdr *symtab_hdr;
01742   struct alpha_elf_link_hash_entry **sym_hashes;
01743   const Elf_Internal_Rela *rel, *relend;
01744   bfd_size_type amt;
01745 
01746   if (info->relocatable)
01747     return TRUE;
01748 
01749   /* Don't do anything special with non-loaded, non-alloced sections.
01750      In particular, any relocs in such sections should not affect GOT
01751      and PLT reference counting (ie. we don't allow them to create GOT
01752      or PLT entries), there's no possibility or desire to optimize TLS
01753      relocs, and there's not much point in propagating relocs to shared
01754      libs that the dynamic linker won't relocate.  */
01755   if ((sec->flags & SEC_ALLOC) == 0)
01756     return TRUE;
01757 
01758   dynobj = elf_hash_table(info)->dynobj;
01759   if (dynobj == NULL)
01760     elf_hash_table(info)->dynobj = dynobj = abfd;
01761 
01762   sreloc = NULL;
01763   rel_sec_name = NULL;
01764   symtab_hdr = &elf_tdata(abfd)->symtab_hdr;
01765   sym_hashes = alpha_elf_sym_hashes(abfd);
01766 
01767   relend = relocs + sec->reloc_count;
01768   for (rel = relocs; rel < relend; ++rel)
01769     {
01770       enum {
01771        NEED_GOT = 1,
01772        NEED_GOT_ENTRY = 2,
01773        NEED_DYNREL = 4
01774       };
01775 
01776       unsigned long r_symndx, r_type;
01777       struct alpha_elf_link_hash_entry *h;
01778       unsigned int gotent_flags;
01779       bfd_boolean maybe_dynamic;
01780       unsigned int need;
01781       bfd_vma addend;
01782 
01783       r_symndx = ELF64_R_SYM (rel->r_info);
01784       if (r_symndx < symtab_hdr->sh_info)
01785        h = NULL;
01786       else
01787        {
01788          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
01789 
01790          while (h->root.root.type == bfd_link_hash_indirect
01791                || h->root.root.type == bfd_link_hash_warning)
01792            h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
01793 
01794          h->root.ref_regular = 1;
01795        }
01796 
01797       /* We can only get preliminary data on whether a symbol is
01798          locally or externally defined, as not all of the input files
01799          have yet been processed.  Do something with what we know, as
01800          this may help reduce memory usage and processing time later.  */
01801       maybe_dynamic = FALSE;
01802       if (h && ((info->shared
01803                && (!info->symbolic
01804                    || info->unresolved_syms_in_shared_libs == RM_IGNORE))
01805               || !h->root.def_regular
01806               || h->root.root.type == bfd_link_hash_defweak))
01807         maybe_dynamic = TRUE;
01808 
01809       need = 0;
01810       gotent_flags = 0;
01811       r_type = ELF64_R_TYPE (rel->r_info);
01812       addend = rel->r_addend;
01813 
01814       switch (r_type)
01815        {
01816        case R_ALPHA_LITERAL:
01817          need = NEED_GOT | NEED_GOT_ENTRY;
01818 
01819          /* Remember how this literal is used from its LITUSEs.
01820             This will be important when it comes to decide if we can
01821             create a .plt entry for a function symbol.  */
01822          while (++rel < relend && ELF64_R_TYPE (rel->r_info) == R_ALPHA_LITUSE)
01823            if (rel->r_addend >= 1 && rel->r_addend <= 6)
01824              gotent_flags |= 1 << rel->r_addend;
01825          --rel;
01826 
01827          /* No LITUSEs -- presumably the address is used somehow.  */
01828          if (gotent_flags == 0)
01829            gotent_flags = ALPHA_ELF_LINK_HASH_LU_ADDR;
01830          break;
01831 
01832        case R_ALPHA_GPDISP:
01833        case R_ALPHA_GPREL16:
01834        case R_ALPHA_GPREL32:
01835        case R_ALPHA_GPRELHIGH:
01836        case R_ALPHA_GPRELLOW:
01837        case R_ALPHA_BRSGP:
01838          need = NEED_GOT;
01839          break;
01840 
01841        case R_ALPHA_REFLONG:
01842        case R_ALPHA_REFQUAD:
01843          if (info->shared || maybe_dynamic)
01844            need = NEED_DYNREL;
01845          break;
01846 
01847        case R_ALPHA_TLSLDM:
01848          /* The symbol for a TLSLDM reloc is ignored.  Collapse the
01849             reloc to the 0 symbol so that they all match.  */
01850          r_symndx = 0;
01851          h = 0;
01852          maybe_dynamic = FALSE;
01853          /* FALLTHRU */
01854 
01855        case R_ALPHA_TLSGD:
01856        case R_ALPHA_GOTDTPREL:
01857          need = NEED_GOT | NEED_GOT_ENTRY;
01858          break;
01859 
01860        case R_ALPHA_GOTTPREL:
01861          need = NEED_GOT | NEED_GOT_ENTRY;
01862          gotent_flags = ALPHA_ELF_LINK_HASH_TLS_IE;
01863          if (info->shared)
01864            info->flags |= DF_STATIC_TLS;
01865          break;
01866 
01867        case R_ALPHA_TPREL64:
01868          if (info->shared || maybe_dynamic)
01869            need = NEED_DYNREL;
01870          if (info->shared)
01871            info->flags |= DF_STATIC_TLS;
01872          break;
01873        }
01874 
01875       if (need & NEED_GOT)
01876        {
01877          if (alpha_elf_tdata(abfd)->gotobj == NULL)
01878            {
01879              if (!elf64_alpha_create_got_section (abfd, info))
01880               return FALSE;
01881            }
01882        }
01883 
01884       if (need & NEED_GOT_ENTRY)
01885        {
01886          struct alpha_elf_got_entry *gotent;
01887 
01888          gotent = get_got_entry (abfd, h, r_type, r_symndx, addend);
01889          if (!gotent)
01890            return FALSE;
01891 
01892          if (gotent_flags)
01893            {
01894              gotent->flags |= gotent_flags;
01895              if (h)
01896               {
01897                 gotent_flags |= h->flags;
01898                 h->flags = gotent_flags;
01899 
01900                 /* Make a guess as to whether a .plt entry is needed.  */
01901                 /* ??? It appears that we won't make it into
01902                    adjust_dynamic_symbol for symbols that remain
01903                    totally undefined.  Copying this check here means
01904                    we can create a plt entry for them too.  */
01905                 h->root.needs_plt
01906                   = (maybe_dynamic && elf64_alpha_want_plt (h));
01907               }
01908            }
01909        }
01910 
01911       if (need & NEED_DYNREL)
01912        {
01913          if (rel_sec_name == NULL)
01914            {
01915              rel_sec_name = (bfd_elf_string_from_elf_section
01916                            (abfd, elf_elfheader(abfd)->e_shstrndx,
01917                             elf_section_data(sec)->rel_hdr.sh_name));
01918              if (rel_sec_name == NULL)
01919               return FALSE;
01920 
01921              BFD_ASSERT (CONST_STRNEQ (rel_sec_name, ".rela")
01922                        && strcmp (bfd_get_section_name (abfd, sec),
01923                                  rel_sec_name+5) == 0);
01924            }
01925 
01926          /* We need to create the section here now whether we eventually
01927             use it or not so that it gets mapped to an output section by
01928             the linker.  If not used, we'll kill it in
01929             size_dynamic_sections.  */
01930          if (sreloc == NULL)
01931            {
01932              sreloc = bfd_get_section_by_name (dynobj, rel_sec_name);
01933              if (sreloc == NULL)
01934               {
01935                 flagword flags;
01936 
01937                 flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY
01938                         | SEC_LINKER_CREATED | SEC_READONLY);
01939                 if (sec->flags & SEC_ALLOC)
01940                   flags |= SEC_ALLOC | SEC_LOAD;
01941                 sreloc = bfd_make_section_with_flags (dynobj,
01942                                                  rel_sec_name,
01943                                                  flags);
01944                 if (sreloc == NULL
01945                     || !bfd_set_section_alignment (dynobj, sreloc, 3))
01946                   return FALSE;
01947               }
01948            }
01949 
01950          if (h)
01951            {
01952              /* Since we havn't seen all of the input symbols yet, we
01953                don't know whether we'll actually need a dynamic relocation
01954                entry for this reloc.  So make a record of it.  Once we
01955                find out if this thing needs dynamic relocation we'll
01956                expand the relocation sections by the appropriate amount.  */
01957 
01958              struct alpha_elf_reloc_entry *rent;
01959 
01960              for (rent = h->reloc_entries; rent; rent = rent->next)
01961               if (rent->rtype == r_type && rent->srel == sreloc)
01962                 break;
01963 
01964              if (!rent)
01965               {
01966                 amt = sizeof (struct alpha_elf_reloc_entry);
01967                 rent = (struct alpha_elf_reloc_entry *) bfd_alloc (abfd, amt);
01968                 if (!rent)
01969                   return FALSE;
01970 
01971                 rent->srel = sreloc;
01972                 rent->rtype = r_type;
01973                 rent->count = 1;
01974                 rent->reltext = (sec->flags & SEC_READONLY) != 0;
01975 
01976                 rent->next = h->reloc_entries;
01977                 h->reloc_entries = rent;
01978               }
01979              else
01980               rent->count++;
01981            }
01982          else if (info->shared)
01983            {
01984              /* If this is a shared library, and the section is to be
01985                loaded into memory, we need a RELATIVE reloc.  */
01986              sreloc->size += sizeof (Elf64_External_Rela);
01987              if (sec->flags & SEC_READONLY)
01988               info->flags |= DF_TEXTREL;
01989            }
01990        }
01991     }
01992 
01993   return TRUE;
01994 }
01995 
01996 /* Adjust a symbol defined by a dynamic object and referenced by a
01997    regular object.  The current definition is in some section of the
01998    dynamic object, but we're not including those sections.  We have to
01999    change the definition to something the rest of the link can
02000    understand.  */
02001 
02002 static bfd_boolean
02003 elf64_alpha_adjust_dynamic_symbol (struct bfd_link_info *info,
02004                                struct elf_link_hash_entry *h)
02005 {
02006   bfd *dynobj;
02007   asection *s;
02008   struct alpha_elf_link_hash_entry *ah;
02009 
02010   dynobj = elf_hash_table(info)->dynobj;
02011   ah = (struct alpha_elf_link_hash_entry *)h;
02012 
02013   /* Now that we've seen all of the input symbols, finalize our decision
02014      about whether this symbol should get a .plt entry.  Irritatingly, it
02015      is common for folk to leave undefined symbols in shared libraries,
02016      and they still expect lazy binding; accept undefined symbols in lieu
02017      of STT_FUNC.  */
02018   if (alpha_elf_dynamic_symbol_p (h, info) && elf64_alpha_want_plt (ah))
02019     {
02020       h->needs_plt = TRUE;
02021 
02022       s = bfd_get_section_by_name(dynobj, ".plt");
02023       if (!s && !elf64_alpha_create_dynamic_sections (dynobj, info))
02024        return FALSE;
02025 
02026       /* We need one plt entry per got subsection.  Delay allocation of
02027         the actual plt entries until size_plt_section, called from
02028         size_dynamic_sections or during relaxation.  */
02029 
02030       return TRUE;
02031     }
02032   else
02033     h->needs_plt = FALSE;
02034 
02035   /* If this is a weak symbol, and there is a real definition, the
02036      processor independent code will have arranged for us to see the
02037      real definition first, and we can just use the same value.  */
02038   if (h->u.weakdef != NULL)
02039     {
02040       BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
02041                 || h->u.weakdef->root.type == bfd_link_hash_defweak);
02042       h->root.u.def.section = h->u.weakdef->root.u.def.section;
02043       h->root.u.def.value = h->u.weakdef->root.u.def.value;
02044       return TRUE;
02045     }
02046 
02047   /* This is a reference to a symbol defined by a dynamic object which
02048      is not a function.  The Alpha, since it uses .got entries for all
02049      symbols even in regular objects, does not need the hackery of a
02050      .dynbss section and COPY dynamic relocations.  */
02051 
02052   return TRUE;
02053 }
02054 
02055 /* Record STO_ALPHA_NOPV and STO_ALPHA_STD_GPLOAD.  */
02056 
02057 static void
02058 elf64_alpha_merge_symbol_attribute (struct elf_link_hash_entry *h,
02059                                 const Elf_Internal_Sym *isym,
02060                                 bfd_boolean definition,
02061                                 bfd_boolean dynamic)
02062 {
02063   if (!dynamic && definition)
02064     h->other = ((h->other & ELF_ST_VISIBILITY (-1))
02065               | (isym->st_other & ~ELF_ST_VISIBILITY (-1)));
02066 }
02067 
02068 /* Symbol versioning can create new symbols, and make our old symbols
02069    indirect to the new ones.  Consolidate the got and reloc information
02070    in these situations.  */
02071 
02072 static bfd_boolean
02073 elf64_alpha_merge_ind_symbols (struct alpha_elf_link_hash_entry *hi,
02074                             PTR dummy ATTRIBUTE_UNUSED)
02075 {
02076   struct alpha_elf_link_hash_entry *hs;
02077 
02078   if (hi->root.root.type != bfd_link_hash_indirect)
02079     return TRUE;
02080   hs = hi;
02081   do {
02082     hs = (struct alpha_elf_link_hash_entry *)hs->root.root.u.i.link;
02083   } while (hs->root.root.type == bfd_link_hash_indirect);
02084 
02085   /* Merge the flags.  Whee.  */
02086 
02087   hs->flags |= hi->flags;
02088 
02089   /* Merge the .got entries.  Cannibalize the old symbol's list in
02090      doing so, since we don't need it anymore.  */
02091 
02092   if (hs->got_entries == NULL)
02093     hs->got_entries = hi->got_entries;
02094   else
02095     {
02096       struct alpha_elf_got_entry *gi, *gs, *gin, *gsh;
02097 
02098       gsh = hs->got_entries;
02099       for (gi = hi->got_entries; gi ; gi = gin)
02100        {
02101          gin = gi->next;
02102          for (gs = gsh; gs ; gs = gs->next)
02103            if (gi->gotobj == gs->gotobj
02104               && gi->reloc_type == gs->reloc_type
02105               && gi->addend == gs->addend)
02106              {
02107               gi->use_count += gs->use_count;
02108                goto got_found;
02109              }
02110          gi->next = hs->got_entries;
02111          hs->got_entries = gi;
02112        got_found:;
02113        }
02114     }
02115   hi->got_entries = NULL;
02116 
02117   /* And similar for the reloc entries.  */
02118 
02119   if (hs->reloc_entries == NULL)
02120     hs->reloc_entries = hi->reloc_entries;
02121   else
02122     {
02123       struct alpha_elf_reloc_entry *ri, *rs, *rin, *rsh;
02124 
02125       rsh = hs->reloc_entries;
02126       for (ri = hi->reloc_entries; ri ; ri = rin)
02127        {
02128          rin = ri->next;
02129          for (rs = rsh; rs ; rs = rs->next)
02130            if (ri->rtype == rs->rtype && ri->srel == rs->srel)
02131              {
02132               rs->count += ri->count;
02133               goto found_reloc;
02134              }
02135          ri->next = hs->reloc_entries;
02136          hs->reloc_entries = ri;
02137        found_reloc:;
02138        }
02139     }
02140   hi->reloc_entries = NULL;
02141 
02142   return TRUE;
02143 }
02144 
02145 /* Is it possible to merge two object file's .got tables?  */
02146 
02147 static bfd_boolean
02148 elf64_alpha_can_merge_gots (bfd *a, bfd *b)
02149 {
02150   int total = alpha_elf_tdata (a)->total_got_size;
02151   bfd *bsub;
02152 
02153   /* Trivial quick fallout test.  */
02154   if (total + alpha_elf_tdata (b)->total_got_size <= MAX_GOT_SIZE)
02155     return TRUE;
02156 
02157   /* By their nature, local .got entries cannot be merged.  */
02158   if ((total += alpha_elf_tdata (b)->local_got_size) > MAX_GOT_SIZE)
02159     return FALSE;
02160 
02161   /* Failing the common trivial comparison, we must effectively
02162      perform the merge.  Not actually performing the merge means that
02163      we don't have to store undo information in case we fail.  */
02164   for (bsub = b; bsub ; bsub = alpha_elf_tdata (bsub)->in_got_link_next)
02165     {
02166       struct alpha_elf_link_hash_entry **hashes = alpha_elf_sym_hashes (bsub);
02167       Elf_Internal_Shdr *symtab_hdr = &elf_tdata (bsub)->symtab_hdr;
02168       int i, n;
02169 
02170       n = NUM_SHDR_ENTRIES (symtab_hdr) - symtab_hdr->sh_info;
02171       for (i = 0; i < n; ++i)
02172        {
02173          struct alpha_elf_got_entry *ae, *be;
02174          struct alpha_elf_link_hash_entry *h;
02175 
02176          h = hashes[i];
02177          while (h->root.root.type == bfd_link_hash_indirect
02178                 || h->root.root.type == bfd_link_hash_warning)
02179            h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
02180 
02181          for (be = h->got_entries; be ; be = be->next)
02182            {
02183              if (be->use_count == 0)
02184                continue;
02185              if (be->gotobj != b)
02186                continue;
02187 
02188              for (ae = h->got_entries; ae ; ae = ae->next)
02189                if (ae->gotobj == a
02190                   && ae->reloc_type == be->reloc_type
02191                   && ae->addend == be->addend)
02192                 goto global_found;
02193 
02194              total += alpha_got_entry_size (be->reloc_type);
02195              if (total > MAX_GOT_SIZE)
02196                return FALSE;
02197            global_found:;
02198            }
02199        }
02200     }
02201 
02202   return TRUE;
02203 }
02204 
02205 /* Actually merge two .got tables.  */
02206 
02207 static void
02208 elf64_alpha_merge_gots (bfd *a, bfd *b)
02209 {
02210   int total = alpha_elf_tdata (a)->total_got_size;
02211   bfd *bsub;
02212 
02213   /* Remember local expansion.  */
02214   {
02215     int e = alpha_elf_tdata (b)->local_got_size;
02216     total += e;
02217     alpha_elf_tdata (a)->local_got_size += e;
02218   }
02219 
02220   for (bsub = b; bsub ; bsub = alpha_elf_tdata (bsub)->in_got_link_next)
02221     {
02222       struct alpha_elf_got_entry **local_got_entries;
02223       struct alpha_elf_link_hash_entry **hashes;
02224       Elf_Internal_Shdr *symtab_hdr;
02225       int i, n;
02226 
02227       /* Let the local .got entries know they are part of a new subsegment.  */
02228       local_got_entries = alpha_elf_tdata (bsub)->local_got_entries;
02229       if (local_got_entries)
02230         {
02231          n = elf_tdata (bsub)->symtab_hdr.sh_info;
02232          for (i = 0; i < n; ++i)
02233            {
02234              struct alpha_elf_got_entry *ent;
02235              for (ent = local_got_entries[i]; ent; ent = ent->next)
02236                ent->gotobj = a;
02237            }
02238         }
02239 
02240       /* Merge the global .got entries.  */
02241       hashes = alpha_elf_sym_hashes (bsub);
02242       symtab_hdr = &elf_tdata (bsub)->symtab_hdr;
02243 
02244       n = NUM_SHDR_ENTRIES (symtab_hdr) - symtab_hdr->sh_info;
02245       for (i = 0; i < n; ++i)
02246         {
02247          struct alpha_elf_got_entry *ae, *be, **pbe, **start;
02248          struct alpha_elf_link_hash_entry *h;
02249 
02250          h = hashes[i];
02251          while (h->root.root.type == bfd_link_hash_indirect
02252                 || h->root.root.type == bfd_link_hash_warning)
02253            h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
02254 
02255          pbe = start = &h->got_entries;
02256          while ((be = *pbe) != NULL)
02257            {
02258              if (be->use_count == 0)
02259                {
02260                 *pbe = be->next;
02261                 memset (be, 0xa5, sizeof (*be));
02262                 goto kill;
02263                }
02264              if (be->gotobj != b)
02265                goto next;
02266 
02267              for (ae = *start; ae ; ae = ae->next)
02268                if (ae->gotobj == a
02269                   && ae->reloc_type == be->reloc_type
02270                   && ae->addend == be->addend)
02271                 {
02272                   ae->flags |= be->flags;
02273                   ae->use_count += be->use_count;
02274                   *pbe = be->next;
02275                   memset (be, 0xa5, sizeof (*be));
02276                   goto kill;
02277                 }
02278              be->gotobj = a;
02279              total += alpha_got_entry_size (be->reloc_type);
02280 
02281            next:;
02282              pbe = &be->next;
02283            kill:;
02284            }
02285         }
02286 
02287       alpha_elf_tdata (bsub)->gotobj = a;
02288     }
02289   alpha_elf_tdata (a)->total_got_size = total;
02290 
02291   /* Merge the two in_got chains.  */
02292   {
02293     bfd *next;
02294 
02295     bsub = a;
02296     while ((next = alpha_elf_tdata (bsub)->in_got_link_next) != NULL)
02297       bsub = next;
02298 
02299     alpha_elf_tdata (bsub)->in_got_link_next = b;
02300   }
02301 }
02302 
02303 /* Calculate the offsets for the got entries.  */
02304 
02305 static bfd_boolean
02306 elf64_alpha_calc_got_offsets_for_symbol (struct alpha_elf_link_hash_entry *h,
02307                                     PTR arg ATTRIBUTE_UNUSED)
02308 {
02309   struct alpha_elf_got_entry *gotent;
02310 
02311   if (h->root.root.type == bfd_link_hash_warning)
02312     h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
02313 
02314   for (gotent = h->got_entries; gotent; gotent = gotent->next)
02315     if (gotent->use_count > 0)
02316       {
02317        struct alpha_elf_obj_tdata *td;
02318        bfd_size_type *plge;
02319 
02320        td = alpha_elf_tdata (gotent->gotobj);
02321        plge = &td->got->size;
02322        gotent->got_offset = *plge;
02323        *plge += alpha_got_entry_size (gotent->reloc_type);
02324       }
02325 
02326   return TRUE;
02327 }
02328 
02329 static void
02330 elf64_alpha_calc_got_offsets (struct bfd_link_info *info)
02331 {
02332   bfd *i, *got_list = alpha_elf_hash_table(info)->got_list;
02333 
02334   /* First, zero out the .got sizes, as we may be recalculating the
02335      .got after optimizing it.  */
02336   for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next)
02337     alpha_elf_tdata(i)->got->size = 0;
02338 
02339   /* Next, fill in the offsets for all the global entries.  */
02340   alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
02341                             elf64_alpha_calc_got_offsets_for_symbol,
02342                             NULL);
02343 
02344   /* Finally, fill in the offsets for the local entries.  */
02345   for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next)
02346     {
02347       bfd_size_type got_offset = alpha_elf_tdata(i)->got->size;
02348       bfd *j;
02349 
02350       for (j = i; j ; j = alpha_elf_tdata(j)->in_got_link_next)
02351        {
02352          struct alpha_elf_got_entry **local_got_entries, *gotent;
02353          int k, n;
02354 
02355          local_got_entries = alpha_elf_tdata(j)->local_got_entries;
02356          if (!local_got_entries)
02357            continue;
02358 
02359          for (k = 0, n = elf_tdata(j)->symtab_hdr.sh_info; k < n; ++k)
02360            for (gotent = local_got_entries[k]; gotent; gotent = gotent->next)
02361              if (gotent->use_count > 0)
02362                {
02363                 gotent->got_offset = got_offset;
02364                 got_offset += alpha_got_entry_size (gotent->reloc_type);
02365                }
02366        }
02367 
02368       alpha_elf_tdata(i)->got->size = got_offset;
02369     }
02370 }
02371 
02372 /* Constructs the gots.  */
02373 
02374 static bfd_boolean
02375 elf64_alpha_size_got_sections (struct bfd_link_info *info)
02376 {
02377   bfd *i, *got_list, *cur_got_obj = NULL;
02378   int something_changed = 0;
02379 
02380   got_list = alpha_elf_hash_table (info)->got_list;
02381 
02382   /* On the first time through, pretend we have an existing got list
02383      consisting of all of the input files.  */
02384   if (got_list == NULL)
02385     {
02386       for (i = info->input_bfds; i ; i = i->link_next)
02387        {
02388          bfd *this_got = alpha_elf_tdata (i)->gotobj;
02389          if (this_got == NULL)
02390            continue;
02391 
02392          /* We are assuming no merging has yet occurred.  */
02393          BFD_ASSERT (this_got == i);
02394 
02395           if (alpha_elf_tdata (this_got)->total_got_size > MAX_GOT_SIZE)
02396            {
02397              /* Yikes! A single object file has too many entries.  */
02398              (*_bfd_error_handler)
02399                (_("%B: .got subsegment exceeds 64K (size %d)"),
02400                 i, alpha_elf_tdata (this_got)->total_got_size);
02401              return FALSE;
02402            }
02403 
02404          if (got_list == NULL)
02405            got_list = this_got;
02406          else
02407            alpha_elf_tdata(cur_got_obj)->got_link_next = this_got;
02408          cur_got_obj = this_got;
02409        }
02410 
02411       /* Strange degenerate case of no got references.  */
02412       if (got_list == NULL)
02413        return TRUE;
02414 
02415       alpha_elf_hash_table (info)->got_list = got_list;
02416 
02417       /* Force got offsets to be recalculated.  */
02418       something_changed = 1;
02419     }
02420 
02421   cur_got_obj = got_list;
02422   i = alpha_elf_tdata(cur_got_obj)->got_link_next;
02423   while (i != NULL)
02424     {
02425       if (elf64_alpha_can_merge_gots (cur_got_obj, i))
02426        {
02427          elf64_alpha_merge_gots (cur_got_obj, i);
02428 
02429          alpha_elf_tdata(i)->got->size = 0;
02430          i = alpha_elf_tdata(i)->got_link_next;
02431          alpha_elf_tdata(cur_got_obj)->got_link_next = i;
02432          
02433          something_changed = 1;
02434        }
02435       else
02436        {
02437          cur_got_obj = i;
02438          i = alpha_elf_tdata(i)->got_link_next;
02439        }
02440     }
02441 
02442   /* Once the gots have been merged, fill in the got offsets for
02443      everything therein.  */
02444   if (1 || something_changed)
02445     elf64_alpha_calc_got_offsets (info);
02446 
02447   return TRUE;
02448 }
02449 
02450 static bfd_boolean
02451 elf64_alpha_size_plt_section_1 (struct alpha_elf_link_hash_entry *h, PTR data)
02452 {
02453   asection *splt = (asection *) data;
02454   struct alpha_elf_got_entry *gotent;
02455   bfd_boolean saw_one = FALSE;
02456 
02457   /* If we didn't need an entry before, we still don't.  */
02458   if (!h->root.needs_plt)
02459     return TRUE;
02460 
02461   /* For each LITERAL got entry still in use, allocate a plt entry.  */
02462   for (gotent = h->got_entries; gotent ; gotent = gotent->next)
02463     if (gotent->reloc_type == R_ALPHA_LITERAL
02464        && gotent->use_count > 0)
02465       {
02466        if (splt->size == 0)
02467          splt->size = PLT_HEADER_SIZE;
02468        gotent->plt_offset = splt->size;
02469        splt->size += PLT_ENTRY_SIZE;
02470        saw_one = TRUE;
02471       }
02472 
02473   /* If there weren't any, there's no longer a need for the PLT entry.  */
02474   if (!saw_one)
02475     h->root.needs_plt = FALSE;
02476 
02477   return TRUE;
02478 }
02479 
02480 /* Called from relax_section to rebuild the PLT in light of
02481    potential changes in the function's status.  */
02482 
02483 static bfd_boolean
02484 elf64_alpha_size_plt_section (struct bfd_link_info *info)
02485 {
02486   asection *splt, *spltrel, *sgotplt;
02487   unsigned long entries;
02488   bfd *dynobj;
02489 
02490   dynobj = elf_hash_table(info)->dynobj;
02491   splt = bfd_get_section_by_name (dynobj, ".plt");
02492   if (splt == NULL)
02493     return TRUE;
02494 
02495   splt->size = 0;
02496 
02497   alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
02498                             elf64_alpha_size_plt_section_1, splt);
02499 
02500   /* Every plt entry requires a JMP_SLOT relocation.  */
02501   spltrel = bfd_get_section_by_name (dynobj, ".rela.plt");
02502   if (splt->size)
02503     {
02504       if (elf64_alpha_use_secureplt)
02505        entries = (splt->size - NEW_PLT_HEADER_SIZE) / NEW_PLT_ENTRY_SIZE;
02506       else
02507        entries = (splt->size - OLD_PLT_HEADER_SIZE) / OLD_PLT_ENTRY_SIZE;
02508     }
02509   else
02510     entries = 0;
02511   spltrel->size = entries * sizeof (Elf64_External_Rela);
02512 
02513   /* When using the secureplt, we need two words somewhere in the data
02514      segment for the dynamic linker to tell us where to go.  This is the
02515      entire contents of the .got.plt section.  */
02516   if (elf64_alpha_use_secureplt)
02517     {
02518       sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
02519       sgotplt->size = entries ? 16 : 0;
02520     }
02521 
02522   return TRUE;
02523 }
02524 
02525 static bfd_boolean
02526 elf64_alpha_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
02527                               struct bfd_link_info *info)
02528 {
02529   bfd *i;
02530 
02531   if (info->relocatable)
02532     return TRUE;
02533 
02534   /* First, take care of the indirect symbols created by versioning.  */
02535   alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
02536                             elf64_alpha_merge_ind_symbols,
02537                             NULL);
02538 
02539   if (!elf64_alpha_size_got_sections (info))
02540     return FALSE;
02541 
02542   /* Allocate space for all of the .got subsections.  */
02543   i = alpha_elf_hash_table (info)->got_list;
02544   for ( ; i ; i = alpha_elf_tdata(i)->got_link_next)
02545     {
02546       asection *s = alpha_elf_tdata(i)->got;
02547       if (s->size > 0)
02548        {
02549          s->contents = (bfd_byte *) bfd_zalloc (i, s->size);
02550          if (s->contents == NULL)
02551            return FALSE;
02552        }
02553     }
02554 
02555   return TRUE;
02556 }
02557 
02558 /* The number of dynamic relocations required by a static relocation.  */
02559 
02560 static int
02561 alpha_dynamic_entries_for_reloc (int r_type, int dynamic, int shared)
02562 {
02563   switch (r_type)
02564     {
02565     /* May appear in GOT entries.  */
02566     case R_ALPHA_TLSGD:
02567       return (dynamic ? 2 : shared ? 1 : 0);
02568     case R_ALPHA_TLSLDM:
02569       return shared;
02570     case R_ALPHA_LITERAL:
02571     case R_ALPHA_GOTTPREL:
02572       return dynamic || shared;
02573     case R_ALPHA_GOTDTPREL:
02574       return dynamic;
02575 
02576     /* May appear in data sections.  */
02577     case R_ALPHA_REFLONG:
02578     case R_ALPHA_REFQUAD:
02579     case R_ALPHA_TPREL64:
02580       return dynamic || shared;
02581 
02582     /* Everything else is illegal.  We'll issue an error during
02583        relocate_section.  */
02584     default:
02585       return 0;
02586     }
02587 }
02588 
02589 /* Work out the sizes of the dynamic relocation entries.  */
02590 
02591 static bfd_boolean
02592 elf64_alpha_calc_dynrel_sizes (struct alpha_elf_link_hash_entry *h,
02593                             struct bfd_link_info *info)
02594 {
02595   bfd_boolean dynamic;
02596   struct alpha_elf_reloc_entry *relent;
02597   unsigned long entries;
02598 
02599   if (h->root.root.type == bfd_link_hash_warning)
02600     h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
02601 
02602   /* If the symbol was defined as a common symbol in a regular object
02603      file, and there was no definition in any dynamic object, then the
02604      linker will have allocated space for the symbol in a common
02605      section but the ELF_LINK_HASH_DEF_REGULAR flag will not have been
02606      set.  This is done for dynamic symbols in
02607      elf_adjust_dynamic_symbol but this is not done for non-dynamic
02608      symbols, somehow.  */
02609   if (!h->root.def_regular
02610       && h->root.ref_regular
02611       && !h->root.def_dynamic
02612       && (h->root.root.type == bfd_link_hash_defined
02613          || h->root.root.type == bfd_link_hash_defweak)
02614       && !(h->root.root.u.def.section->owner->flags & DYNAMIC))
02615     h->root.def_regular = 1;
02616 
02617   /* If the symbol is dynamic, we'll need all the relocations in their
02618      natural form.  If this is a shared object, and it has been forced
02619      local, we'll need the same number of RELATIVE relocations.  */
02620   dynamic = alpha_elf_dynamic_symbol_p (&h->root, info);
02621 
02622   /* If the symbol is a hidden undefined weak, then we never have any
02623      relocations.  Avoid the loop which may want to add RELATIVE relocs
02624      based on info->shared.  */
02625   if (h->root.root.type == bfd_link_hash_undefweak && !dynamic)
02626     return TRUE;
02627 
02628   for (relent = h->reloc_entries; relent; relent = relent->next)
02629     {
02630       entries = alpha_dynamic_entries_for_reloc (relent->rtype, dynamic,
02631                                            info->shared);
02632       if (entries)
02633        {
02634          relent->srel->size +=
02635            entries * sizeof (Elf64_External_Rela) * relent->count;
02636          if (relent->reltext)
02637            info->flags |= DT_TEXTREL;
02638        }
02639     }
02640 
02641   return TRUE;
02642 }
02643 
02644 /* Subroutine of elf64_alpha_size_rela_got_section for doing the
02645    global symbols.  */
02646 
02647 static bfd_boolean
02648 elf64_alpha_size_rela_got_1 (struct alpha_elf_link_hash_entry *h,
02649                           struct bfd_link_info *info)
02650 {
02651   bfd_boolean dynamic;
02652   struct alpha_elf_got_entry *gotent;
02653   unsigned long entries;
02654 
02655   if (h->root.root.type == bfd_link_hash_warning)
02656     h = (struct alpha_elf_link_hash_entry *) h->root.root.u.i.link;
02657 
02658   /* If we're using a plt for this symbol, then all of its relocations
02659      for its got entries go into .rela.plt.  */
02660   if (h->root.needs_plt)
02661     return TRUE;
02662 
02663   /* If the symbol is dynamic, we'll need all the relocations in their
02664      natural form.  If this is a shared object, and it has been forced
02665      local, we'll need the same number of RELATIVE relocations.  */
02666   dynamic = alpha_elf_dynamic_symbol_p (&h->root, info);
02667 
02668   /* If the symbol is a hidden undefined weak, then we never have any
02669      relocations.  Avoid the loop which may want to add RELATIVE relocs
02670      based on info->shared.  */
02671   if (h->root.root.type == bfd_link_hash_undefweak && !dynamic)
02672     return TRUE;
02673 
02674   entries = 0;
02675   for (gotent = h->got_entries; gotent ; gotent = gotent->next)
02676     if (gotent->use_count > 0)
02677       entries += alpha_dynamic_entries_for_reloc (gotent->reloc_type,
02678                                             dynamic, info->shared);
02679 
02680   if (entries > 0)
02681     {
02682       bfd *dynobj = elf_hash_table(info)->dynobj;
02683       asection *srel = bfd_get_section_by_name (dynobj, ".rela.got");
02684       BFD_ASSERT (srel != NULL);
02685       srel->size += sizeof (Elf64_External_Rela) * entries;
02686     }
02687 
02688   return TRUE;
02689 }
02690 
02691 /* Set the sizes of the dynamic relocation sections.  */
02692 
02693 static bfd_boolean
02694 elf64_alpha_size_rela_got_section (struct bfd_link_info *info)
02695 {
02696   unsigned long entries;
02697   bfd *i, *dynobj;
02698   asection *srel;
02699 
02700   /* Shared libraries often require RELATIVE relocs, and some relocs
02701      require attention for the main application as well.  */
02702 
02703   entries = 0;
02704   for (i = alpha_elf_hash_table(info)->got_list;
02705        i ; i = alpha_elf_tdata(i)->got_link_next)
02706     {
02707       bfd *j;
02708 
02709       for (j = i; j ; j = alpha_elf_tdata(j)->in_got_link_next)
02710        {
02711          struct alpha_elf_got_entry **local_got_entries, *gotent;
02712          int k, n;
02713 
02714          local_got_entries = alpha_elf_tdata(j)->local_got_entries;
02715          if (!local_got_entries)
02716            continue;
02717 
02718          for (k = 0, n = elf_tdata(j)->symtab_hdr.sh_info; k < n; ++k)
02719            for (gotent = local_got_entries[k];
02720                gotent ; gotent = gotent->next)
02721              if (gotent->use_count > 0)
02722               entries += (alpha_dynamic_entries_for_reloc
02723                          (gotent->reloc_type, 0, info->shared));
02724        }
02725     }
02726 
02727   dynobj = elf_hash_table(info)->dynobj;
02728   srel = bfd_get_section_by_name (dynobj, ".rela.got");
02729   if (!srel)
02730     {
02731       BFD_ASSERT (entries == 0);
02732       return TRUE;
02733     }
02734   srel->size = sizeof (Elf64_External_Rela) * entries;
02735 
02736   /* Now do the non-local symbols.  */
02737   alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
02738                             elf64_alpha_size_rela_got_1, info);
02739 
02740   return TRUE;
02741 }
02742 
02743 /* Set the sizes of the dynamic sections.  */
02744 
02745 static bfd_boolean
02746 elf64_alpha_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
02747                                struct bfd_link_info *info)
02748 {
02749   bfd *dynobj;
02750   asection *s;
02751   bfd_boolean relplt;
02752 
02753   dynobj = elf_hash_table(info)->dynobj;
02754   BFD_ASSERT(dynobj != NULL);
02755 
02756   if (elf_hash_table (info)->dynamic_sections_created)
02757     {
02758       /* Set the contents of the .interp section to the interpreter.  */
02759       if (info->executable)
02760        {
02761          s = bfd_get_section_by_name (dynobj, ".interp");
02762          BFD_ASSERT (s != NULL);
02763          s->size = sizeof ELF_DYNAMIC_INTERPRETER;
02764          s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
02765        }
02766 
02767       /* Now that we've seen all of the input files, we can decide which
02768         symbols need dynamic relocation entries and which don't.  We've
02769         collected information in check_relocs that we can now apply to
02770         size the dynamic relocation sections.  */
02771       alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
02772                                 elf64_alpha_calc_dynrel_sizes, info);
02773 
02774       elf64_alpha_size_rela_got_section (info);
02775       elf64_alpha_size_plt_section (info);
02776     }
02777   /* else we're not dynamic and by definition we don't need such things.  */
02778 
02779   /* The check_relocs and adjust_dynamic_symbol entry points have
02780      determined the sizes of the various dynamic sections.  Allocate
02781      memory for them.  */
02782   relplt = FALSE;
02783   for (s = dynobj->sections; s != NULL; s = s->next)
02784     {
02785       const char *name;
02786 
02787       if (!(s->flags & SEC_LINKER_CREATED))
02788        continue;
02789 
02790       /* It's OK to base decisions on the section name, because none
02791         of the dynobj section names depend upon the input files.  */
02792       name = bfd_get_section_name (dynobj, s);
02793 
02794       if (CONST_STRNEQ (name, ".rela"))
02795        {
02796          if (s->size != 0)
02797            {
02798              if (strcmp (name, ".rela.plt") == 0)
02799               relplt = TRUE;
02800 
02801              /* We use the reloc_count field as a counter if we need
02802                to copy relocs into the output file.  */
02803              s->reloc_count = 0;
02804            }
02805        }
02806       else if (! CONST_STRNEQ (name, ".got")
02807               && strcmp (name, ".plt") != 0
02808               && strcmp (name, ".dynbss") != 0)
02809        {
02810          /* It's not one of our dynamic sections, so don't allocate space.  */
02811          continue;
02812        }
02813 
02814       if (s->size == 0)
02815        {
02816          /* If we don't need this section, strip it from the output file.
02817             This is to handle .rela.bss and .rela.plt.  We must create it
02818             in create_dynamic_sections, because it must be created before
02819             the linker maps input sections to output sections.  The
02820             linker does that before adjust_dynamic_symbol is called, and
02821             it is that function which decides whether anything needs to
02822             go into these sections.  */
02823          s->flags |= SEC_EXCLUDE;
02824        }
02825       else if ((s->flags & SEC_HAS_CONTENTS) != 0)
02826        {
02827          /* Allocate memory for the section contents.  */
02828          s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
02829          if (s->contents == NULL)
02830            return FALSE;
02831        }
02832     }
02833 
02834   if (elf_hash_table (info)->dynamic_sections_created)
02835     {
02836       /* Add some entries to the .dynamic section.  We fill in the
02837         values later, in elf64_alpha_finish_dynamic_sections, but we
02838         must add the entries now so that we get the correct size for
02839         the .dynamic section.  The DT_DEBUG entry is filled in by the
02840         dynamic linker and used by the debugger.  */
02841 #define add_dynamic_entry(TAG, VAL) \
02842   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
02843 
02844       if (info->executable)
02845        {
02846          if (!add_dynamic_entry (DT_DEBUG, 0))
02847            return FALSE;
02848        }
02849 
02850       if (relplt)
02851        {
02852          if (!add_dynamic_entry (DT_PLTGOT, 0)
02853              || !add_dynamic_entry (DT_PLTRELSZ, 0)
02854              || !add_dynamic_entry (DT_PLTREL, DT_RELA)
02855              || !add_dynamic_entry (DT_JMPREL, 0))
02856            return FALSE;
02857 
02858          if (elf64_alpha_use_secureplt
02859              && !add_dynamic_entry (DT_ALPHA_PLTRO, 1))
02860            return FALSE;
02861        }
02862 
02863       if (!add_dynamic_entry (DT_RELA, 0)
02864          || !add_dynamic_entry (DT_RELASZ, 0)
02865          || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
02866        return FALSE;
02867 
02868       if (info->flags & DF_TEXTREL)
02869        {
02870          if (!add_dynamic_entry (DT_TEXTREL, 0))
02871            return FALSE;
02872        }
02873     }
02874 #undef add_dynamic_entry
02875 
02876   return TRUE;
02877 }
02878 
02879 /* These functions do relaxation for Alpha ELF.
02880 
02881    Currently I'm only handling what I can do with existing compiler
02882    and assembler support, which means no instructions are removed,
02883    though some may be nopped.  At this time GCC does not emit enough
02884    information to do all of the relaxing that is possible.  It will
02885    take some not small amount of work for that to happen.
02886 
02887    There are a couple of interesting papers that I once read on this
02888    subject, that I cannot find references to at the moment, that
02889    related to Alpha in particular.  They are by David Wall, then of
02890    DEC WRL.  */
02891 
02892 struct alpha_relax_info
02893 {
02894   bfd *abfd;
02895   asection *sec;
02896   bfd_byte *contents;
02897   Elf_Internal_Shdr *symtab_hdr;
02898   Elf_Internal_Rela *relocs, *relend;
02899   struct bfd_link_info *link_info;
02900   bfd_vma gp;
02901   bfd *gotobj;
02902   asection *tsec;
02903   struct alpha_elf_link_hash_entry *h;
02904   struct alpha_elf_got_entry **first_gotent;
02905   struct alpha_elf_got_entry *gotent;
02906   bfd_boolean changed_contents;
02907   bfd_boolean changed_relocs;
02908   unsigned char other;
02909 };
02910 
02911 static Elf_Internal_Rela *
02912 elf64_alpha_find_reloc_at_ofs (Elf_Internal_Rela *rel,
02913                             Elf_Internal_Rela *relend,
02914                             bfd_vma offset, int type)
02915 {
02916   while (rel < relend)
02917     {
02918       if (rel->r_offset == offset
02919          && ELF64_R_TYPE (rel->r_info) == (unsigned int) type)
02920        return rel;
02921       ++rel;
02922     }
02923   return NULL;
02924 }
02925 
02926 static bfd_boolean
02927 elf64_alpha_relax_got_load (struct alpha_relax_info *info, bfd_vma symval,
02928                          Elf_Internal_Rela *irel, unsigned long r_type)
02929 {
02930   unsigned int insn;
02931   bfd_signed_vma disp;
02932 
02933   /* Get the instruction.  */
02934   insn = bfd_get_32 (info->abfd, info->contents + irel->r_offset);
02935 
02936   if (insn >> 26 != OP_LDQ)
02937     {
02938       reloc_howto_type *howto = elf64_alpha_howto_table + r_type;
02939       ((*_bfd_error_handler)
02940        ("%B: %A+0x%lx: warning: %s relocation against unexpected insn",
02941        info->abfd, info->sec,
02942        (unsigned long) irel->r_offset, howto->name));
02943       return TRUE;
02944     }
02945 
02946   /* Can't relax dynamic symbols.  */
02947   if (alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info))
02948     return TRUE;
02949 
02950   /* Can't use local-exec relocations in shared libraries.  */
02951   if (r_type == R_ALPHA_GOTTPREL && info->link_info->shared)
02952     return TRUE;
02953 
02954   if (r_type == R_ALPHA_LITERAL)
02955     {
02956       /* Look for nice constant addresses.  This includes the not-uncommon
02957         special case of 0 for undefweak symbols.  */
02958       if ((info->h && info->h->root.root.type == bfd_link_hash_undefweak)
02959          || (!info->link_info->shared
02960              && (symval >= (bfd_vma)-0x8000 || symval < 0x8000)))
02961        {
02962          disp = 0;
02963          insn = (OP_LDA << 26) | (insn & (31 << 21)) | (31 << 16);
02964          insn |= (symval & 0xffff);
02965          r_type = R_ALPHA_NONE;
02966        }
02967       else
02968        {
02969          disp = symval - info->gp;
02970          insn = (OP_LDA << 26) | (insn & 0x03ff0000);
02971          r_type = R_ALPHA_GPREL16;
02972        }
02973     }
02974   else
02975     {
02976       bfd_vma dtp_base, tp_base;
02977 
02978       BFD_ASSERT (elf_hash_table (info->link_info)->tls_sec != NULL);
02979       dtp_base = alpha_get_dtprel_base (info->link_info);
02980       tp_base = alpha_get_tprel_base (info->link_info);
02981       disp = symval - (r_type == R_ALPHA_GOTDTPREL ? dtp_base : tp_base);
02982 
02983       insn = (OP_LDA << 26) | (insn & (31 << 21)) | (31 << 16);
02984 
02985       switch (r_type)
02986        {
02987        case R_ALPHA_GOTDTPREL:
02988          r_type = R_ALPHA_DTPREL16;
02989          break;
02990        case R_ALPHA_GOTTPREL:
02991          r_type = R_ALPHA_TPREL16;
02992          break;
02993        default:
02994          BFD_ASSERT (0);
02995          return FALSE;
02996        }
02997     }
02998 
02999   if (disp < -0x8000 || disp >= 0x8000)
03000     return TRUE;
03001 
03002   bfd_put_32 (info->abfd, (bfd_vma) insn, info->contents + irel->r_offset);
03003   info->changed_contents = TRUE;
03004 
03005   /* Reduce the use count on this got entry by one, possibly
03006      eliminating it.  */
03007   if (--info->gotent->use_count == 0)
03008     {
03009       int sz = alpha_got_entry_size (r_type);
03010       alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
03011       if (!info->h)
03012        alpha_elf_tdata (info->gotobj)->local_got_size -= sz;
03013     }
03014 
03015   /* Smash the existing GOT relocation for its 16-bit immediate pair.  */
03016   irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), r_type);
03017   info->changed_relocs = TRUE;
03018 
03019   /* ??? Search forward through this basic block looking for insns
03020      that use the target register.  Stop after an insn modifying the
03021      register is seen, or after a branch or call.
03022 
03023      Any such memory load insn may be substituted by a load directly
03024      off the GP.  This allows the memory load insn to be issued before
03025      the calculated GP register would otherwise be ready.
03026 
03027      Any such jsr insn can be replaced by a bsr if it is in range.
03028 
03029      This would mean that we'd have to _add_ relocations, the pain of
03030      which gives one pause.  */
03031 
03032   return TRUE;
03033 }
03034 
03035 static bfd_vma
03036 elf64_alpha_relax_opt_call (struct alpha_relax_info *info, bfd_vma symval)
03037 {
03038   /* If the function has the same gp, and we can identify that the
03039      function does not use its function pointer, we can eliminate the
03040      address load.  */
03041 
03042   /* If the symbol is marked NOPV, we are being told the function never
03043      needs its procedure value.  */
03044   if ((info->other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_NOPV)
03045     return symval;
03046 
03047   /* If the symbol is marked STD_GP, we are being told the function does
03048      a normal ldgp in the first two words.  */
03049   else if ((info->other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_STD_GPLOAD)
03050     ;
03051 
03052   /* Otherwise, we may be able to identify a GP load in the first two
03053      words, which we can then skip.  */
03054   else
03055     {
03056       Elf_Internal_Rela *tsec_relocs, *tsec_relend, *tsec_free, *gpdisp;
03057       bfd_vma ofs;
03058 
03059       /* Load the relocations from the section that the target symbol is in.  */
03060       if (info->sec == info->tsec)
03061        {
03062          tsec_relocs = info->relocs;
03063          tsec_relend = info->relend;
03064          tsec_free = NULL;
03065        }
03066       else
03067        {
03068          tsec_relocs = (_bfd_elf_link_read_relocs
03069                        (info->abfd, info->tsec, (PTR) NULL,
03070                       (Elf_Internal_Rela *) NULL,
03071                       info->link_info->keep_memory));
03072          if (tsec_relocs == NULL)
03073            return 0;
03074          tsec_relend = tsec_relocs + info->tsec->reloc_count;
03075          tsec_free = (info->link_info->keep_memory ? NULL : tsec_relocs);
03076        }
03077 
03078       /* Recover the symbol's offset within the section.  */
03079       ofs = (symval - info->tsec->output_section->vma
03080             - info->tsec->output_offset);
03081 
03082       /* Look for a GPDISP reloc.  */
03083       gpdisp = (elf64_alpha_find_reloc_at_ofs
03084               (tsec_relocs, tsec_relend, ofs, R_ALPHA_GPDISP));
03085 
03086       if (!gpdisp || gpdisp->r_addend != 4)
03087        {
03088          if (tsec_free)
03089            free (tsec_free);
03090          return 0;
03091        }
03092       if (tsec_free)
03093         free (tsec_free);
03094     }
03095 
03096   /* We've now determined that we can skip an initial gp load.  Verify
03097      that the call and the target use the same gp.   */
03098   if (info->link_info->hash->creator != info->tsec->owner->xvec
03099       || info->gotobj != alpha_elf_tdata (info->tsec->owner)->gotobj)
03100     return 0;
03101 
03102   return symval + 8;
03103 }
03104 
03105 static bfd_boolean
03106 elf64_alpha_relax_with_lituse (struct alpha_relax_info *info,
03107                             bfd_vma symval, Elf_Internal_Rela *irel)
03108 {
03109   Elf_Internal_Rela *urel, *irelend = info->relend;
03110   int flags, count, i;
03111   bfd_signed_vma disp;
03112   bfd_boolean fits16;
03113   bfd_boolean fits32;
03114   bfd_boolean lit_reused = FALSE;
03115   bfd_boolean all_optimized = TRUE;
03116   unsigned int lit_insn;
03117 
03118   lit_insn = bfd_get_32 (info->abfd, info->contents + irel->r_offset);
03119   if (lit_insn >> 26 != OP_LDQ)
03120     {
03121       ((*_bfd_error_handler)
03122        ("%B: %A+0x%lx: warning: LITERAL relocation against unexpected insn",
03123        info->abfd, info->sec,
03124        (unsigned long) irel->r_offset));
03125       return TRUE;
03126     }
03127 
03128   /* Can't relax dynamic symbols.  */
03129   if (alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info))
03130     return TRUE;
03131 
03132   /* Summarize how this particular LITERAL is used.  */
03133   for (urel = irel+1, flags = count = 0; urel < irelend; ++urel, ++count)
03134     {
03135       if (ELF64_R_TYPE (urel->r_info) != R_ALPHA_LITUSE)
03136        break;
03137       if (urel->r_addend <= 6)
03138        flags |= 1 << urel->r_addend;
03139     }
03140 
03141   /* A little preparation for the loop...  */
03142   disp = symval - info->gp;
03143 
03144   for (urel = irel+1, i = 0; i < count; ++i, ++urel)
03145     {
03146       unsigned int insn;
03147       int insn_disp;
03148       bfd_signed_vma xdisp;
03149 
03150       insn = bfd_get_32 (info->abfd, info->contents + urel->r_offset);
03151 
03152       switch (urel->r_addend)
03153        {
03154        case LITUSE_ALPHA_ADDR:
03155        default:
03156          /* This type is really just a placeholder to note that all
03157             uses cannot be optimized, but to still allow some.  */
03158          all_optimized = FALSE;
03159          break;
03160 
03161        case LITUSE_ALPHA_BASE:
03162          /* We can always optimize 16-bit displacements.  */
03163 
03164          /* Extract the displacement from the instruction, sign-extending
03165             it if necessary, then test whether it is within 16 or 32 bits
03166             displacement from GP.  */
03167          insn_disp = ((insn & 0xffff) ^ 0x8000) - 0x8000;
03168 
03169          xdisp = disp + insn_disp;
03170          fits16 = (xdisp >= - (bfd_signed_vma) 0x8000 && xdisp < 0x8000);
03171          fits32 = (xdisp >= - (bfd_signed_vma) 0x80000000
03172                   && xdisp < 0x7fff8000);
03173 
03174          if (fits16)
03175            {
03176              /* Take the op code and dest from this insn, take the base
03177                register from the literal insn.  Leave the offset alone.  */
03178              insn = (insn & 0xffe0ffff) | (lit_insn & 0x001f0000);
03179              urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
03180                                       R_ALPHA_GPREL16);
03181              urel->r_addend = irel->r_addend;
03182              info->changed_relocs = TRUE;
03183 
03184              bfd_put_32 (info->abfd, (bfd_vma) insn,
03185                        info->contents + urel->r_offset);
03186              info->changed_contents = TRUE;
03187            }
03188 
03189          /* If all mem+byte, we can optimize 32-bit mem displacements.  */
03190          else if (fits32 && !(flags & ~6))
03191            {
03192              /* FIXME: sanity check that lit insn Ra is mem insn Rb.  */
03193 
03194              irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
03195                                       R_ALPHA_GPRELHIGH);
03196              lit_insn = (OP_LDAH << 26) | (lit_insn & 0x03ff0000);
03197              bfd_put_32 (info->abfd, (bfd_vma) lit_insn,
03198                        info->contents + irel->r_offset);
03199              lit_reused = TRUE;
03200              info->changed_contents = TRUE;
03201 
03202              urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
03203                                       R_ALPHA_GPRELLOW);
03204              urel->r_addend = irel->r_addend;
03205              info->changed_relocs = TRUE;
03206            }
03207          else
03208            all_optimized = FALSE;
03209          break;
03210 
03211        case LITUSE_ALPHA_BYTOFF:
03212          /* We can always optimize byte instructions.  */
03213 
03214          /* FIXME: sanity check the insn for byte op.  Check that the
03215             literal dest reg is indeed Rb in the byte insn.  */
03216 
03217          insn &= ~ (unsigned) 0x001ff000;
03218          insn |= ((symval & 7) << 13) | 0x1000;
03219 
03220          urel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
03221          urel->r_addend = 0;
03222          info->changed_relocs = TRUE;
03223 
03224          bfd_put_32 (info->abfd, (bfd_vma) insn,
03225                     info->contents + urel->r_offset);
03226          info->changed_contents = TRUE;
03227          break;
03228 
03229        case LITUSE_ALPHA_JSR:
03230        case LITUSE_ALPHA_TLSGD:
03231        case LITUSE_ALPHA_TLSLDM:
03232        case LITUSE_ALPHA_JSRDIRECT:
03233          {
03234            bfd_vma optdest, org;
03235            bfd_signed_vma odisp;
03236 
03237            /* For undefined weak symbols, we're mostly interested in getting
03238               rid of the got entry whenever possible, so optimize this to a
03239               use of the zero register.  */
03240            if (info->h && info->h->root.root.type == bfd_link_hash_undefweak)
03241              {
03242               insn |= 31 << 16;
03243               bfd_put_32 (info->abfd, (bfd_vma) insn,
03244                          info->contents + urel->r_offset);
03245 
03246               info->changed_contents = TRUE;
03247               break;
03248              }
03249 
03250            /* If not zero, place to jump without needing pv.  */
03251            optdest = elf64_alpha_relax_opt_call (info, symval);
03252            org = (info->sec->output_section->vma
03253                  + info->sec->output_offset
03254                  + urel->r_offset + 4);
03255            odisp = (optdest ? optdest : symval) - org;
03256 
03257            if (odisp >= -0x400000 && odisp < 0x400000)
03258              {
03259               Elf_Internal_Rela *xrel;
03260 
03261               /* Preserve branch prediction call stack when possible.  */
03262               if ((insn & INSN_JSR_MASK) == INSN_JSR)
03263                 insn = (OP_BSR << 26) | (insn & 0x03e00000);
03264               else
03265                 insn = (OP_BR << 26) | (insn & 0x03e00000);
03266 
03267               urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
03268                                         R_ALPHA_BRADDR);
03269               urel->r_addend = irel->r_addend;
03270 
03271               if (optdest)
03272                 urel->r_addend += optdest - symval;
03273               else
03274                 all_optimized = FALSE;
03275 
03276               bfd_put_32 (info->abfd, (bfd_vma) insn,
03277                          info->contents + urel->r_offset);
03278 
03279               /* Kill any HINT reloc that might exist for this insn.  */
03280               xrel = (elf64_alpha_find_reloc_at_ofs
03281                      (info->relocs, info->relend, urel->r_offset,
03282                       R_ALPHA_HINT));
03283               if (xrel)
03284                 xrel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
03285 
03286               info->changed_contents = TRUE;
03287               info->changed_relocs = TRUE;
03288              }
03289            else
03290              all_optimized = FALSE;
03291 
03292            /* Even if the target is not in range for a direct branch,
03293               if we share a GP, we can eliminate the gp reload.  */
03294            if (optdest)
03295              {
03296               Elf_Internal_Rela *gpdisp
03297                 = (elf64_alpha_find_reloc_at_ofs
03298                    (info->relocs, irelend, urel->r_offset + 4,
03299                     R_ALPHA_GPDISP));
03300               if (gpdisp)
03301                 {
03302                   bfd_byte *p_ldah = info->contents + gpdisp->r_offset;
03303                   bfd_byte *p_lda = p_ldah + gpdisp->r_addend;
03304                   unsigned int ldah = bfd_get_32 (info->abfd, p_ldah);
03305                   unsigned int lda = bfd_get_32 (info->abfd, p_lda);
03306 
03307                   /* Verify that the instruction is "ldah $29,0($26)".
03308                      Consider a function that ends in a noreturn call,
03309                      and that the next function begins with an ldgp,
03310                      and that by accident there is no padding between.
03311                      In that case the insn would use $27 as the base.  */
03312                   if (ldah == 0x27ba0000 && lda == 0x23bd0000)
03313                     {
03314                      bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, p_ldah);
03315                      bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, p_lda);
03316 
03317                      gpdisp->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
03318                      info->changed_contents = TRUE;
03319                      info->changed_relocs = TRUE;
03320                     }
03321                 }
03322              }
03323          }
03324          break;
03325        }
03326     }
03327 
03328   /* If all cases were optimized, we can reduce the use count on this
03329      got entry by one, possibly eliminating it.  */
03330   if (all_optimized)
03331     {
03332       if (--info->gotent->use_count == 0)
03333        {
03334          int sz = alpha_got_entry_size (R_ALPHA_LITERAL);
03335          alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
03336          if (!info->h)
03337            alpha_elf_tdata (info->gotobj)->local_got_size -= sz;
03338        }
03339 
03340       /* If the literal instruction is no longer needed (it may have been
03341         reused.  We can eliminate it.  */
03342       /* ??? For now, I don't want to deal with compacting the section,
03343         so just nop it out.  */
03344       if (!lit_reused)
03345        {
03346          irel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
03347          info->changed_relocs = TRUE;
03348 
03349          bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP,
03350                     info->contents + irel->r_offset);
03351          info->changed_contents = TRUE;
03352        }
03353 
03354       return TRUE;
03355     }
03356   else
03357     return elf64_alpha_relax_got_load (info, symval, irel, R_ALPHA_LITERAL);
03358 }
03359 
03360 static bfd_boolean
03361 elf64_alpha_relax_tls_get_addr (struct alpha_relax_info *info, bfd_vma symval,
03362                             Elf_Internal_Rela *irel, bfd_boolean is_gd)
03363 {
03364   bfd_byte *pos[5];
03365   unsigned int insn;
03366   Elf_Internal_Rela *gpdisp, *hint;
03367   bfd_boolean dynamic, use_gottprel, pos1_unusable;
03368   unsigned long new_symndx;
03369 
03370   dynamic = alpha_elf_dynamic_symbol_p (&info->h->root, info->link_info);
03371 
03372   /* If a TLS symbol is accessed using IE at least once, there is no point
03373      to use dynamic model for it.  */
03374   if (is_gd && info->h && (info->h->flags & ALPHA_ELF_LINK_HASH_TLS_IE))
03375     ;
03376 
03377   /* If the symbol is local, and we've already committed to DF_STATIC_TLS,
03378      then we might as well relax to IE.  */
03379   else if (info->link_info->shared && !dynamic
03380           && (info->link_info->flags & DF_STATIC_TLS))
03381     ;
03382 
03383   /* Otherwise we must be building an executable to do anything.  */
03384   else if (info->link_info->shared)
03385     return TRUE;
03386 
03387   /* The TLSGD/TLSLDM relocation must be followed by a LITERAL and
03388      the matching LITUSE_TLS relocations.  */
03389   if (irel + 2 >= info->relend)
03390     return TRUE;
03391   if (ELF64_R_TYPE (irel[1].r_info) != R_ALPHA_LITERAL
03392       || ELF64_R_TYPE (irel[2].r_info) != R_ALPHA_LITUSE
03393       || irel[2].r_addend != (is_gd ? LITUSE_ALPHA_TLSGD : LITUSE_ALPHA_TLSLDM))
03394     return TRUE;
03395 
03396   /* There must be a GPDISP relocation positioned immediately after the
03397      LITUSE relocation.  */
03398   gpdisp = elf64_alpha_find_reloc_at_ofs (info->relocs, info->relend,
03399                                      irel[2].r_offset + 4, R_ALPHA_GPDISP);
03400   if (!gpdisp)
03401     return TRUE;
03402 
03403   pos[0] = info->contents + irel[0].r_offset;
03404   pos[1] = info->contents + irel[1].r_offset;
03405   pos[2] = info->contents + irel[2].r_offset;
03406   pos[3] = info->contents + gpdisp->r_offset;
03407   pos[4] = pos[3] + gpdisp->r_addend;
03408   pos1_unusable = FALSE;
03409 
03410   /* Generally, the positions are not allowed to be out of order, lest the
03411      modified insn sequence have different register lifetimes.  We can make
03412      an exception when pos 1 is adjacent to pos 0.  */
03413   if (pos[1] + 4 == pos[0])
03414     {
03415       bfd_byte *tmp = pos[0];
03416       pos[0] = pos[1];
03417       pos[1] = tmp;
03418     }
03419   else if (pos[1] < pos[0])
03420     pos1_unusable = TRUE;
03421   if (pos[1] >= pos[2] || pos[2] >= pos[3])
03422     return TRUE;
03423 
03424   /* Reduce the use count on the LITERAL relocation.  Do this before we
03425      smash the symndx when we adjust the relocations below.  */
03426   {
03427     struct alpha_elf_got_entry *lit_gotent;
03428     struct alpha_elf_link_hash_entry *lit_h;
03429     unsigned long indx;
03430 
03431     BFD_ASSERT (ELF64_R_SYM (irel[1].r_info) >= info->symtab_hdr->sh_info);
03432     indx = ELF64_R_SYM (irel[1].r_info) - info->symtab_hdr->sh_info;
03433     lit_h = alpha_elf_sym_hashes (info->abfd)[indx];
03434 
03435     while (lit_h->root.root.type == bfd_link_hash_indirect
03436           || lit_h->root.root.type == bfd_link_hash_warning)
03437       lit_h = (struct alpha_elf_link_hash_entry *) lit_h->root.root.u.i.link;
03438 
03439     for (lit_gotent = lit_h->got_entries; lit_gotent ;
03440         lit_gotent = lit_gotent->next)
03441       if (lit_gotent->gotobj == info->gotobj
03442          && lit_gotent->reloc_type == R_ALPHA_LITERAL
03443          && lit_gotent->addend == irel[1].r_addend)
03444        break;
03445     BFD_ASSERT (lit_gotent);
03446 
03447     if (--lit_gotent->use_count == 0)
03448       {
03449        int sz = alpha_got_entry_size (R_ALPHA_LITERAL);
03450        alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
03451       }
03452   }
03453 
03454   /* Change
03455 
03456        lda    $16,x($gp)                  !tlsgd!1
03457        ldq    $27,__tls_get_addr($gp)            !literal!1
03458        jsr    $26,($27),__tls_get_addr    !lituse_tlsgd!1
03459        ldah   $29,0($26)                  !gpdisp!2
03460        lda    $29,0($29)                  !gpdisp!2
03461      to
03462        ldq    $16,x($gp)                  !gottprel
03463        unop
03464        call_pal rduniq
03465        addq   $16,$0,$0
03466        unop
03467      or the first pair to
03468        lda    $16,x($gp)                  !tprel
03469        unop
03470      or
03471        ldah   $16,x($gp)                  !tprelhi
03472        lda    $16,x($16)                  !tprello
03473 
03474      as appropriate.  */
03475 
03476   use_gottprel = FALSE;
03477   new_symndx = is_gd ? ELF64_R_SYM (irel->r_info) : 0;
03478   switch (!dynamic && !info->link_info->shared)
03479     {
03480     case 1:
03481       {
03482        bfd_vma tp_base;
03483        bfd_signed_vma disp;
03484 
03485        BFD_ASSERT (elf_hash_table (info->link_info)->tls_sec != NULL);
03486        tp_base = alpha_get_tprel_base (info->link_info);
03487        disp = symval - tp_base;
03488 
03489        if (disp >= -0x8000 && disp < 0x8000)
03490          {
03491            insn = (OP_LDA << 26) | (16 << 21) | (31 << 16);
03492            bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
03493            bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[1]);
03494 
03495            irel[0].r_offset = pos[0] - info->contents;
03496            irel[0].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_TPREL16);
03497            irel[1].r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
03498            break;
03499          }
03500        else if (disp >= -(bfd_signed_vma) 0x80000000
03501                && disp < (bfd_signed_vma) 0x7fff8000
03502                && !pos1_unusable)
03503          {
03504            insn = (OP_LDAH << 26) | (16 << 21) | (31 << 16);
03505            bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
03506            insn = (OP_LDA << 26) | (16 << 21) | (16 << 16);
03507            bfd_put_32 (info->abfd, (bfd_vma) insn, pos[1]);
03508 
03509            irel[0].r_offset = pos[0] - info->contents;
03510            irel[0].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_TPRELHI);
03511            irel[1].r_offset = pos[1] - info->contents;
03512            irel[1].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_TPRELLO);
03513            break;
03514          }
03515       }
03516       /* FALLTHRU */
03517 
03518     default:
03519       use_gottprel = TRUE;
03520 
03521       insn = (OP_LDQ << 26) | (16 << 21) | (29 << 16);
03522       bfd_put_32 (info->abfd, (bfd_vma) insn, pos[0]);
03523       bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[1]);
03524 
03525       irel[0].r_offset = pos[0] - info->contents;
03526       irel[0].r_info = ELF64_R_INFO (new_symndx, R_ALPHA_GOTTPREL);
03527       irel[1].r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
03528       break;
03529     }
03530 
03531   bfd_put_32 (info->abfd, (bfd_vma) INSN_RDUNIQ, pos[2]);
03532 
03533   insn = INSN_ADDQ | (16 << 21) | (0 << 16) | (0 << 0);
03534   bfd_put_32 (info->abfd, (bfd_vma) insn, pos[3]);
03535 
03536   bfd_put_32 (info->abfd, (bfd_vma) INSN_UNOP, pos[4]);
03537 
03538   irel[2].r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
03539   gpdisp->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
03540 
03541   hint = elf64_alpha_find_reloc_at_ofs (info->relocs, info->relend,
03542                                    irel[2].r_offset, R_ALPHA_HINT);
03543   if (hint)
03544     hint->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
03545 
03546   info->changed_contents = TRUE;
03547   info->changed_relocs = TRUE;
03548 
03549   /* Reduce the use count on the TLSGD/TLSLDM relocation.  */
03550   if (--info->gotent->use_count == 0)
03551     {
03552       int sz = alpha_got_entry_size (info->gotent->reloc_type);
03553       alpha_elf_tdata (info->gotobj)->total_got_size -= sz;
03554       if (!info->h)
03555        alpha_elf_tdata (info->gotobj)->local_got_size -= sz;
03556     }
03557 
03558   /* If we've switched to a GOTTPREL relocation, increment the reference
03559      count on that got entry.  */
03560   if (use_gottprel)
03561     {
03562       struct alpha_elf_got_entry *tprel_gotent;
03563 
03564       for (tprel_gotent = *info->first_gotent; tprel_gotent ;
03565           tprel_gotent = tprel_gotent->next)
03566        if (tprel_gotent->gotobj == info->gotobj
03567            && tprel_gotent->reloc_type == R_ALPHA_GOTTPREL
03568            && tprel_gotent->addend == irel->r_addend)
03569          break;
03570       if (tprel_gotent)
03571        tprel_gotent->use_count++;
03572       else
03573        {
03574          if (info->gotent->use_count == 0)
03575            tprel_gotent = info->gotent;
03576          else
03577            {
03578              tprel_gotent = (struct alpha_elf_got_entry *)
03579               bfd_alloc (info->abfd, sizeof (struct alpha_elf_got_entry));
03580              if (!tprel_gotent)
03581               return FALSE;
03582 
03583              tprel_gotent->next = *info->first_gotent;
03584              *info->first_gotent = tprel_gotent;
03585 
03586              tprel_gotent->gotobj = info->gotobj;
03587              tprel_gotent->addend = irel->r_addend;
03588              tprel_gotent->got_offset = -1;
03589              tprel_gotent->reloc_done = 0;
03590              tprel_gotent->reloc_xlated = 0;
03591            }
03592 
03593          tprel_gotent->use_count = 1;
03594          tprel_gotent->reloc_type = R_ALPHA_GOTTPREL;
03595        }
03596     }
03597 
03598   return TRUE;
03599 }
03600 
03601 static bfd_boolean
03602 elf64_alpha_relax_section (bfd *abfd, asection *sec,
03603                         struct bfd_link_info *link_info, bfd_boolean *again)
03604 {
03605   Elf_Internal_Shdr *symtab_hdr;
03606   Elf_Internal_Rela *internal_relocs;
03607   Elf_Internal_Rela *irel, *irelend;
03608   Elf_Internal_Sym *isymbuf = NULL;
03609   struct alpha_elf_got_entry **local_got_entries;
03610   struct alpha_relax_info info;
03611 
03612   /* We are not currently changing any sizes, so only one pass.  */
03613   *again = FALSE;
03614 
03615   if (link_info->relocatable
03616       || ((sec->flags & (SEC_CODE | SEC_RELOC | SEC_ALLOC))
03617          != (SEC_CODE | SEC_RELOC | SEC_ALLOC))
03618       || sec->reloc_count == 0)
03619     return TRUE;
03620 
03621   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
03622   local_got_entries = alpha_elf_tdata(abfd)->local_got_entries;
03623 
03624   /* Load the relocations for this section.  */
03625   internal_relocs = (_bfd_elf_link_read_relocs
03626                    (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
03627                     link_info->keep_memory));
03628   if (internal_relocs == NULL)
03629     return FALSE;
03630 
03631   memset(&info, 0, sizeof (info));
03632   info.abfd = abfd;
03633   info.sec = sec;
03634   info.link_info = link_info;
03635   info.symtab_hdr = symtab_hdr;
03636   info.relocs = internal_relocs;
03637   info.relend = irelend = internal_relocs + sec->reloc_count;
03638 
03639   /* Find the GP for this object.  Do not store the result back via
03640      _bfd_set_gp_value, since this could change again before final.  */
03641   info.gotobj = alpha_elf_tdata (abfd)->gotobj;
03642   if (info.gotobj)
03643     {
03644       asection *sgot = alpha_elf_tdata (info.gotobj)->got;
03645       info.gp = (sgot->output_section->vma
03646                + sgot->output_offset
03647                + 0x8000);
03648     }
03649 
03650   /* Get the section contents.  */
03651   if (elf_section_data (sec)->this_hdr.contents != NULL)
03652     info.contents = elf_section_data (sec)->this_hdr.contents;
03653   else
03654     {
03655       if (!bfd_malloc_and_get_section (abfd, sec, &info.contents))
03656        goto error_return;
03657     }
03658 
03659   for (irel = internal_relocs; irel < irelend; irel++)
03660     {
03661       bfd_vma symval;
03662       struct alpha_elf_got_entry *gotent;
03663       unsigned long r_type = ELF64_R_TYPE (irel->r_info);
03664       unsigned long r_symndx = ELF64_R_SYM (irel->r_info);
03665 
03666       /* Early exit for unhandled or unrelaxable relocations.  */
03667       switch (r_type)
03668        {
03669        case R_ALPHA_LITERAL:
03670        case R_ALPHA_GPRELHIGH:
03671        case R_ALPHA_GPRELLOW:
03672        case R_ALPHA_GOTDTPREL:
03673        case R_ALPHA_GOTTPREL:
03674        case R_ALPHA_TLSGD:
03675          break;
03676 
03677        case R_ALPHA_TLSLDM:
03678          /* The symbol for a TLSLDM reloc is ignored.  Collapse the
03679              reloc to the 0 symbol so that they all match.  */
03680          r_symndx = 0;
03681          break;
03682 
03683        default:
03684          continue;
03685        }
03686 
03687       /* Get the value of the symbol referred to by the reloc.  */
03688       if (r_symndx < symtab_hdr->sh_info)
03689        {
03690          /* A local symbol.  */
03691          Elf_Internal_Sym *isym;
03692 
03693          /* Read this BFD's local symbols.  */
03694          if (isymbuf == NULL)
03695            {
03696              isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
03697              if (isymbuf == NULL)
03698               isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
03699                                           symtab_hdr->sh_info, 0,
03700                                           NULL, NULL, NULL);
03701              if (isymbuf == NULL)
03702               goto error_return;
03703            }
03704 
03705          isym = isymbuf + r_symndx;
03706 
03707          /* Given the symbol for a TLSLDM reloc is ignored, this also
03708             means forcing the symbol value to the tp base.  */
03709          if (r_type == R_ALPHA_TLSLDM)
03710            {
03711              info.tsec = bfd_abs_section_ptr;
03712              symval = alpha_get_tprel_base (info.link_info);
03713            }
03714          else
03715            {
03716              symval = isym->st_value;
03717              if (isym->st_shndx == SHN_UNDEF)
03718                continue;
03719              else if (isym->st_shndx == SHN_ABS)
03720                info.tsec = bfd_abs_section_ptr;
03721              else if (isym->st_shndx == SHN_COMMON)
03722                info.tsec = bfd_com_section_ptr;
03723              else
03724                info.tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
03725            }
03726 
03727          info.h = NULL;
03728          info.other = isym->st_other;
03729          if (local_got_entries)
03730            info.first_gotent = &local_got_entries[r_symndx];
03731          else
03732            {
03733              info.first_gotent = &info.gotent;
03734              info.gotent = NULL;
03735            }
03736        }
03737       else
03738        {
03739          unsigned long indx;
03740          struct alpha_elf_link_hash_entry *h;
03741 
03742          indx = r_symndx - symtab_hdr->sh_info;
03743          h = alpha_elf_sym_hashes (abfd)[indx];
03744          BFD_ASSERT (h != NULL);
03745 
03746          while (h->root.root.type == bfd_link_hash_indirect
03747                || h->root.root.type == bfd_link_hash_warning)
03748            h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
03749 
03750          /* If the symbol is undefined, we can't do anything with it.  */
03751          if (h->root.root.type == bfd_link_hash_undefined)
03752            continue;
03753 
03754          /* If the symbol isn't defined in the current module,
03755             again we can't do anything.  */
03756          if (h->root.root.type == bfd_link_hash_undefweak)
03757            {
03758              info.tsec = bfd_abs_section_ptr;
03759              symval = 0;
03760            }
03761          else if (!h->root.def_regular)
03762            {
03763              /* Except for TLSGD relocs, which can sometimes be
03764                relaxed to GOTTPREL relocs.  */
03765              if (r_type != R_ALPHA_TLSGD)
03766               continue;
03767              info.tsec = bfd_abs_section_ptr;
03768              symval = 0;
03769            }
03770          else
03771            {
03772              info.tsec = h->root.root.u.def.section;
03773              symval = h->root.root.u.def.value;
03774            }
03775 
03776          info.h = h;
03777          info.other = h->root.other;
03778          info.first_gotent = &h->got_entries;
03779        }
03780 
03781       /* Search for the got entry to be used by this relocation.  */
03782       for (gotent = *info.first_gotent; gotent ; gotent = gotent->next)
03783        if (gotent->gotobj == info.gotobj
03784            && gotent->reloc_type == r_type
03785            && gotent->addend == irel->r_addend)
03786          break;
03787       info.gotent = gotent;
03788 
03789       symval += info.tsec->output_section->vma + info.tsec->output_offset;
03790       symval += irel->r_addend;
03791 
03792       switch (r_type)
03793        {
03794        case R_ALPHA_LITERAL:
03795          BFD_ASSERT(info.gotent != NULL);
03796 
03797          /* If there exist LITUSE relocations immediately following, this
03798             opens up all sorts of interesting optimizations, because we
03799             now know every location that this address load is used.  */
03800          if (irel+1 < irelend
03801              && ELF64_R_TYPE (irel[1].r_info) == R_ALPHA_LITUSE)
03802            {
03803              if (!elf64_alpha_relax_with_lituse (&info, symval, irel))
03804               goto error_return;
03805            }
03806          else
03807            {
03808              if (!elf64_alpha_relax_got_load (&info, symval, irel, r_type))
03809               goto error_return;
03810            }
03811          break;
03812 
03813        case R_ALPHA_GOTDTPREL:
03814        case R_ALPHA_GOTTPREL:
03815          BFD_ASSERT(info.gotent != NULL);
03816          if (!elf64_alpha_relax_got_load (&info, symval, irel, r_type))
03817            goto error_return;
03818          break;
03819 
03820        case R_ALPHA_TLSGD:
03821        case R_ALPHA_TLSLDM:
03822          BFD_ASSERT(info.gotent != NULL);
03823          if (!elf64_alpha_relax_tls_get_addr (&info, symval, irel,
03824                                           r_type == R_ALPHA_TLSGD))
03825            goto error_return;
03826          break;
03827        }
03828     }
03829 
03830   if (!elf64_alpha_size_plt_section (link_info))
03831     return FALSE;
03832   if (!elf64_alpha_size_got_sections (link_info))
03833     return FALSE;
03834   if (!elf64_alpha_size_rela_got_section (link_info))
03835     return FALSE;
03836 
03837   if (isymbuf != NULL
03838       && symtab_hdr->contents != (unsigned char *) isymbuf)
03839     {
03840       if (!link_info->keep_memory)
03841        free (isymbuf);
03842       else
03843        {
03844          /* Cache the symbols for elf_link_input_bfd.  */
03845          symtab_hdr->contents = (unsigned char *) isymbuf;
03846        }
03847     }
03848 
03849   if (info.contents != NULL
03850       && elf_section_data (sec)->this_hdr.contents != info.contents)
03851     {
03852       if (!info.changed_contents && !link_info->keep_memory)
03853        free (info.contents);
03854       else
03855        {
03856          /* Cache the section contents for elf_link_input_bfd.  */
03857          elf_section_data (sec)->this_hdr.contents = info.contents;
03858        }
03859     }
03860 
03861   if (elf_section_data (sec)->relocs != internal_relocs)
03862     {
03863       if (!info.changed_relocs)
03864        free (internal_relocs);
03865       else
03866        elf_section_data (sec)->relocs = internal_relocs;
03867     }
03868 
03869   *again = info.changed_contents || info.changed_relocs;
03870 
03871   return TRUE;
03872 
03873  error_return:
03874   if (isymbuf != NULL
03875       && symtab_hdr->contents != (unsigned char *) isymbuf)
03876     free (isymbuf);
03877   if (info.contents != NULL
03878       && elf_section_data (sec)->this_hdr.contents != info.contents)
03879     free (info.contents);
03880   if (internal_relocs != NULL
03881       && elf_section_data (sec)->relocs != internal_relocs)
03882     free (internal_relocs);
03883   return FALSE;
03884 }
03885 
03886 /* Emit a dynamic relocation for (DYNINDX, RTYPE, ADDEND) at (SEC, OFFSET)
03887    into the next available slot in SREL.  */
03888 
03889 static void
03890 elf64_alpha_emit_dynrel (bfd *abfd, struct bfd_link_info *info,
03891                       asection *sec, asection *srel, bfd_vma offset,
03892                       long dynindx, long rtype, bfd_vma addend)
03893 {
03894   Elf_Internal_Rela outrel;
03895   bfd_byte *loc;
03896 
03897   BFD_ASSERT (srel != NULL);
03898 
03899   outrel.r_info = ELF64_R_INFO (dynindx, rtype);
03900   outrel.r_addend = addend;
03901 
03902   offset = _bfd_elf_section_offset (abfd, info, sec, offset);
03903   if ((offset | 1) != (bfd_vma) -1)
03904     outrel.r_offset = sec->output_section->vma + sec->output_offset + offset;
03905   else
03906     memset (&outrel, 0, sizeof (outrel));
03907 
03908   loc = srel->contents;
03909   loc += srel->reloc_count++ * sizeof (Elf64_External_Rela);
03910   bfd_elf64_swap_reloca_out (abfd, &outrel, loc);
03911   BFD_ASSERT (sizeof (Elf64_External_Rela) * srel->reloc_count <= srel->size);
03912 }
03913 
03914 /* Relocate an Alpha ELF section for a relocatable link.
03915 
03916    We don't have to change anything unless the reloc is against a section
03917    symbol, in which case we have to adjust according to where the section
03918    symbol winds up in the output section.  */
03919 
03920 static bfd_boolean
03921 elf64_alpha_relocate_section_r (bfd *output_bfd ATTRIBUTE_UNUSED,
03922                             struct bfd_link_info *info ATTRIBUTE_UNUSED,
03923                             bfd *input_bfd, asection *input_section,
03924                             bfd_byte *contents ATTRIBUTE_UNUSED,
03925                             Elf_Internal_Rela *relocs,
03926                             Elf_Internal_Sym *local_syms,
03927                             asection **local_sections)
03928 {
03929   unsigned long symtab_hdr_sh_info;
03930   Elf_Internal_Rela *rel;
03931   Elf_Internal_Rela *relend;
03932   struct elf_link_hash_entry **sym_hashes;
03933   bfd_boolean ret_val = TRUE;
03934 
03935   symtab_hdr_sh_info = elf_tdata (input_bfd)->symtab_hdr.sh_info;
03936   sym_hashes = elf_sym_hashes (input_bfd);
03937 
03938   relend = relocs + input_section->reloc_count;
03939   for (rel = relocs; rel < relend; rel++)
03940     {
03941       unsigned long r_symndx;
03942       Elf_Internal_Sym *sym;
03943       asection *sec;
03944       unsigned long r_type;
03945 
03946       r_type = ELF64_R_TYPE (rel->r_info);
03947       if (r_type >= R_ALPHA_max)
03948        {
03949          (*_bfd_error_handler)
03950            (_("%B: unknown relocation type %d"),
03951             input_bfd, (int) r_type);
03952          bfd_set_error (bfd_error_bad_value);
03953          ret_val = FALSE;
03954          continue;
03955        }
03956 
03957       /* The symbol associated with GPDISP and LITUSE is
03958         immaterial.  Only the addend is significant.  */
03959       if (r_type == R_ALPHA_GPDISP || r_type == R_ALPHA_LITUSE)
03960        continue;
03961 
03962       r_symndx = ELF64_R_SYM (rel->r_info);
03963       if (r_symndx < symtab_hdr_sh_info)
03964        {
03965          sym = local_syms + r_symndx;
03966          sec = local_sections[r_symndx];
03967        }
03968       else
03969        {
03970          struct elf_link_hash_entry *h;
03971 
03972          h = sym_hashes[r_symndx - symtab_hdr_sh_info];
03973 
03974          while (h->root.type == bfd_link_hash_indirect
03975                || h->root.type == bfd_link_hash_warning)
03976            h = (struct elf_link_hash_entry *) h->root.u.i.link;
03977 
03978          if (h->root.type != bfd_link_hash_defined
03979              && h->root.type != bfd_link_hash_defweak)
03980            continue;
03981 
03982          sym = NULL;
03983          sec = h->root.u.def.section;
03984        }
03985 
03986       if (sec != NULL && elf_discarded_section (sec))
03987        {
03988          /* For relocs against symbols from removed linkonce sections,
03989             or sections discarded by a linker script, we just want the
03990             section contents zeroed.  */
03991          _bfd_clear_contents (elf64_alpha_howto_table + r_type,
03992                             input_bfd, contents + rel->r_offset);
03993          rel->r_info = 0;
03994          rel->r_addend = 0;
03995          continue;
03996        }
03997 
03998       if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
03999        rel->r_addend += sec->output_offset;
04000     }
04001 
04002   return ret_val;
04003 }
04004 
04005 /* Relocate an Alpha ELF section.  */
04006 
04007 static bfd_boolean
04008 elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
04009                            bfd *input_bfd, asection *input_section,
04010                            bfd_byte *contents, Elf_Internal_Rela *relocs,
04011                            Elf_Internal_Sym *local_syms,
04012                            asection **local_sections)
04013 {
04014   Elf_Internal_Shdr *symtab_hdr;
04015   Elf_Internal_Rela *rel;
04016   Elf_Internal_Rela *relend;
04017   asection *sgot, *srel, *srelgot;
04018   bfd *dynobj, *gotobj;
04019   bfd_vma gp, tp_base, dtp_base;
04020   struct alpha_elf_got_entry **local_got_entries;
04021   bfd_boolean ret_val;
04022 
04023   /* Handle relocatable links with a smaller loop.  */
04024   if (info->relocatable)
04025     return elf64_alpha_relocate_section_r (output_bfd, info, input_bfd,
04026                                       input_section, contents, relocs,
04027                                       local_syms, local_sections);
04028 
04029   /* This is a final link.  */
04030 
04031   ret_val = TRUE;
04032 
04033   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
04034 
04035   dynobj = elf_hash_table (info)->dynobj;
04036   if (dynobj)
04037     srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
04038   else
04039     srelgot = NULL;
04040 
04041   if (input_section->flags & SEC_ALLOC)
04042     {
04043       const char *section_name;
04044       section_name = (bfd_elf_string_from_elf_section
04045                     (input_bfd, elf_elfheader(input_bfd)->e_shstrndx,
04046                      elf_section_data(input_section)->rel_hdr.sh_name));
04047       BFD_ASSERT(section_name != NULL);
04048       srel = bfd_get_section_by_name (dynobj, section_name);
04049     }
04050   else
04051     srel = NULL;
04052 
04053   /* Find the gp value for this input bfd.  */
04054   gotobj = alpha_elf_tdata (input_bfd)->gotobj;
04055   if (gotobj)
04056     {
04057       sgot = alpha_elf_tdata (gotobj)->got;
04058       gp = _bfd_get_gp_value (gotobj);
04059       if (gp == 0)
04060        {
04061          gp = (sgot->output_section->vma
04062               + sgot->output_offset
04063               + 0x8000);
04064          _bfd_set_gp_value (gotobj, gp);
04065        }
04066     }
04067   else
04068     {
04069       sgot = NULL;
04070       gp = 0;
04071     }
04072 
04073   local_got_entries = alpha_elf_tdata(input_bfd)->local_got_entries;
04074 
04075   if (elf_hash_table (info)->tls_sec != NULL)
04076     {
04077       dtp_base = alpha_get_dtprel_base (info);
04078       tp_base = alpha_get_tprel_base (info);
04079     }
04080   else
04081     dtp_base = tp_base = 0;
04082 
04083   relend = relocs + input_section->reloc_count;
04084   for (rel = relocs; rel < relend; rel++)
04085     {
04086       struct alpha_elf_link_hash_entry *h = NULL;
04087       struct alpha_elf_got_entry *gotent;
04088       bfd_reloc_status_type r;
04089       reloc_howto_type *howto;
04090       unsigned long r_symndx;
04091       Elf_Internal_Sym *sym = NULL;
04092       asection *sec = NULL;
04093       bfd_vma value;
04094       bfd_vma addend;
04095       bfd_boolean dynamic_symbol_p;
04096       bfd_boolean undef_weak_ref = FALSE;
04097       unsigned long r_type;
04098 
04099       r_type = ELF64_R_TYPE(rel->r_info);
04100       if (r_type >= R_ALPHA_max)
04101        {
04102          (*_bfd_error_handler)
04103            (_("%B: unknown relocation type %d"),
04104             input_bfd, (int) r_type);
04105          bfd_set_error (bfd_error_bad_value);
04106          ret_val = FALSE;
04107          continue;
04108        }
04109 
04110       howto = elf64_alpha_howto_table + r_type;
04111       r_symndx = ELF64_R_SYM(rel->r_info);
04112 
04113       /* The symbol for a TLSLDM reloc is ignored.  Collapse the
04114         reloc to the 0 symbol so that they all match.  */
04115       if (r_type == R_ALPHA_TLSLDM)
04116        r_symndx = 0;
04117 
04118       if (r_symndx < symtab_hdr->sh_info)
04119        {
04120          asection *msec;
04121          sym = local_syms + r_symndx;
04122          sec = local_sections[r_symndx];
04123          msec = sec;
04124          value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
04125 
04126          /* If this is a tp-relative relocation against sym 0,
04127             this is hackery from relax_section.  Force the value to
04128             be the tls module base.  */
04129          if (r_symndx == 0
04130              && (r_type == R_ALPHA_TLSLDM
04131                 || r_type == R_ALPHA_GOTTPREL
04132                 || r_type == R_ALPHA_TPREL64
04133                 || r_type == R_ALPHA_TPRELHI
04134                 || r_type == R_ALPHA_TPRELLO
04135                 || r_type == R_ALPHA_TPREL16))
04136            value = dtp_base;
04137 
04138          if (local_got_entries)
04139            gotent = local_got_entries[r_symndx];
04140          else
04141            gotent = NULL;
04142 
04143          /* Need to adjust local GOT entries' addends for SEC_MERGE
04144             unless it has been done already.  */
04145          if ((sec->flags & SEC_MERGE)
04146              && ELF_ST_TYPE (sym->st_info) == STT_SECTION
04147              && sec->sec_info_type == ELF_INFO_TYPE_MERGE
04148              && gotent
04149              && !gotent->reloc_xlated)
04150            {
04151              struct alpha_elf_got_entry *ent;
04152 
04153              for (ent = gotent; ent; ent = ent->next)
04154               {
04155                 ent->reloc_xlated = 1;
04156                 if (ent->use_count == 0)
04157                   continue;
04158                 msec = sec;
04159                 ent->addend =
04160                   _bfd_merged_section_offset (output_bfd, &msec,
04161                                           elf_section_data (sec)->
04162                                             sec_info,
04163                                           sym->st_value + ent->addend);
04164                 ent->addend -= sym->st_value;
04165                 ent->addend += msec->output_section->vma
04166                              + msec->output_offset
04167                              - sec->output_section->vma
04168                              - sec->output_offset;
04169               }
04170            }
04171 
04172          dynamic_symbol_p = FALSE;
04173        }
04174       else
04175        {
04176          bfd_boolean warned;
04177          bfd_boolean unresolved_reloc;
04178          struct elf_link_hash_entry *hh;
04179          struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
04180 
04181          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
04182                                r_symndx, symtab_hdr, sym_hashes,
04183                                hh, sec, value,
04184                                unresolved_reloc, warned);
04185 
04186          if (warned)
04187            continue;
04188 
04189          if (value == 0
04190              && ! unresolved_reloc
04191              && hh->root.type == bfd_link_hash_undefweak)
04192            undef_weak_ref = TRUE;
04193 
04194          h = (struct alpha_elf_link_hash_entry *) hh;
04195           dynamic_symbol_p = alpha_elf_dynamic_symbol_p (&h->root, info);
04196          gotent = h->got_entries;
04197        }
04198 
04199       if (sec != NULL && elf_discarded_section (sec))
04200        {
04201          /* For relocs against symbols from removed linkonce sections,
04202             or sections discarded by a linker script, we just want the
04203             section contents zeroed.  Avoid any special processing.  */
04204          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
04205          rel->r_info = 0;
04206          rel->r_addend = 0;
04207          continue;
04208        }
04209 
04210       addend = rel->r_addend;
04211       value += addend;
04212 
04213       /* Search for the proper got entry.  */
04214       for (; gotent ; gotent = gotent->next)
04215        if (gotent->gotobj == gotobj
04216            && gotent->reloc_type == r_type
04217            && gotent->addend == addend)
04218          break;
04219 
04220       switch (r_type)
04221        {
04222        case R_ALPHA_GPDISP:
04223          {
04224            bfd_byte *p_ldah, *p_lda;
04225 
04226            BFD_ASSERT(gp != 0);
04227 
04228            value = (input_section->output_section->vma
04229                    + input_section->output_offset
04230                    + rel->r_offset);
04231 
04232            p_ldah = contents + rel->r_offset;
04233            p_lda = p_ldah + rel->r_addend;
04234 
04235            r = elf64_alpha_do_reloc_gpdisp (input_bfd, gp - value,
04236                                         p_ldah, p_lda);
04237          }
04238          break;
04239 
04240        case R_ALPHA_LITERAL:
04241          BFD_ASSERT(sgot != NULL);
04242          BFD_ASSERT(gp != 0);
04243          BFD_ASSERT(gotent != NULL);
04244          BFD_ASSERT(gotent->use_count >= 1);
04245 
04246          if (!gotent->reloc_done)
04247            {
04248              gotent->reloc_done = 1;
04249 
04250              bfd_put_64 (output_bfd, value,
04251                        sgot->contents + gotent->got_offset);
04252 
04253              /* If the symbol has been forced local, output a
04254                RELATIVE reloc, otherwise it will be handled in
04255                finish_dynamic_symbol.  */
04256              if (info->shared && !dynamic_symbol_p && !undef_weak_ref)
04257               elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
04258                                     gotent->got_offset, 0,
04259                                     R_ALPHA_RELATIVE, value);
04260            }
04261 
04262          value = (sgot->output_section->vma
04263                  + sgot->output_offset
04264                  + gotent->got_offset);
04265          value -= gp;
04266          goto default_reloc;
04267 
04268        case R_ALPHA_GPREL32:
04269        case R_ALPHA_GPREL16:
04270        case R_ALPHA_GPRELLOW:
04271          if (dynamic_symbol_p)
04272             {
04273               (*_bfd_error_handler)
04274                 (_("%B: gp-relative relocation against dynamic symbol %s"),
04275                  input_bfd, h->root.root.root.string);
04276               ret_val = FALSE;
04277             }
04278          BFD_ASSERT(gp != 0);
04279          value -= gp;
04280          goto default_reloc;
04281 
04282        case R_ALPHA_GPRELHIGH:
04283          if (dynamic_symbol_p)
04284             {
04285               (*_bfd_error_handler)
04286                 (_("%B: gp-relative relocation against dynamic symbol %s"),
04287                  input_bfd, h->root.root.root.string);
04288               ret_val = FALSE;
04289             }
04290          BFD_ASSERT(gp != 0);
04291          value -= gp;
04292          value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1);
04293          goto default_reloc;
04294 
04295        case R_ALPHA_HINT:
04296          /* A call to a dynamic symbol is definitely out of range of
04297             the 16-bit displacement.  Don't bother writing anything.  */
04298          if (dynamic_symbol_p)
04299            {
04300              r = bfd_reloc_ok;
04301              break;
04302            }
04303          /* The regular PC-relative stuff measures from the start of
04304             the instruction rather than the end.  */
04305          value -= 4;
04306          goto default_reloc;
04307 
04308        case R_ALPHA_BRADDR:
04309          if (dynamic_symbol_p)
04310             {
04311               (*_bfd_error_handler)
04312                 (_("%B: pc-relative relocation against dynamic symbol %s"),
04313                  input_bfd, h->root.root.root.string);
04314               ret_val = FALSE;
04315             }
04316          /* The regular PC-relative stuff measures from the start of
04317             the instruction rather than the end.  */
04318          value -= 4;
04319          goto default_reloc;
04320 
04321        case R_ALPHA_BRSGP:
04322          {
04323            int other;
04324            const char *name;
04325 
04326            /* The regular PC-relative stuff measures from the start of
04327               the instruction rather than the end.  */
04328            value -= 4;
04329 
04330            /* The source and destination gp must be the same.  Note that
04331               the source will always have an assigned gp, since we forced
04332               one in check_relocs, but that the destination may not, as
04333               it might not have had any relocations at all.  Also take
04334               care not to crash if H is an undefined symbol.  */
04335            if (h != NULL && sec != NULL
04336               && alpha_elf_tdata (sec->owner)->gotobj
04337               && gotobj != alpha_elf_tdata (sec->owner)->gotobj)
04338              {
04339               (*_bfd_error_handler)
04340                 (_("%B: change in gp: BRSGP %s"),
04341                  input_bfd, h->root.root.root.string);
04342               ret_val = FALSE;
04343              }
04344 
04345            /* The symbol should be marked either NOPV or STD_GPLOAD.  */
04346            if (h != NULL)
04347              other = h->root.other;
04348            else
04349              other = sym->st_other;
04350            switch (other & STO_ALPHA_STD_GPLOAD)
04351              {
04352              case STO_ALPHA_NOPV:
04353                break;
04354              case STO_ALPHA_STD_GPLOAD:
04355               value += 8;
04356               break;
04357              default:
04358               if (h != NULL)
04359                 name = h->root.root.root.string;
04360               else
04361                 {
04362                   name = (bfd_elf_string_from_elf_section
04363                          (input_bfd, symtab_hdr->sh_link, sym->st_name));
04364                   if (name == NULL)
04365                     name = _("<unknown>");
04366                   else if (name[0] == 0)
04367                     name = bfd_section_name (input_bfd, sec);
04368                 }
04369               (*_bfd_error_handler)
04370                 (_("%B: !samegp reloc against symbol without .prologue: %s"),
04371                  input_bfd, name);
04372               ret_val = FALSE;
04373               break;
04374              }
04375 
04376            goto default_reloc;
04377          }
04378 
04379        case R_ALPHA_REFLONG:
04380        case R_ALPHA_REFQUAD:
04381        case R_ALPHA_DTPREL64:
04382        case R_ALPHA_TPREL64:
04383          {
04384            long dynindx, dyntype = r_type;
04385            bfd_vma dynaddend;
04386 
04387            /* Careful here to remember RELATIVE relocations for global
04388               variables for symbolic shared objects.  */
04389 
04390            if (dynamic_symbol_p)
04391              {
04392               BFD_ASSERT(h->root.dynindx != -1);
04393               dynindx = h->root.dynindx;
04394               dynaddend = addend;
04395               addend = 0, value = 0;
04396              }
04397            else if (r_type == R_ALPHA_DTPREL64)
04398              {
04399               BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
04400               value -= dtp_base;
04401               goto default_reloc;
04402              }
04403            else if (r_type == R_ALPHA_TPREL64)
04404              {
04405               BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
04406               if (!info->shared)
04407                 {
04408                   value -= tp_base;
04409                   goto default_reloc;
04410                 }
04411               dynindx = 0;
04412               dynaddend = value - dtp_base;
04413              }
04414            else if (info->shared
04415                    && r_symndx != 0
04416                    && (input_section->flags & SEC_ALLOC)
04417                    && !undef_weak_ref)
04418              {
04419               if (r_type == R_ALPHA_REFLONG)
04420                 {
04421                   (*_bfd_error_handler)
04422                     (_("%B: unhandled dynamic relocation against %s"),
04423                      input_bfd,
04424                      h->root.root.root.string);
04425                   ret_val = FALSE;
04426                 }
04427               dynindx = 0;
04428               dyntype = R_ALPHA_RELATIVE;
04429               dynaddend = value;
04430              }
04431            else
04432              goto default_reloc;
04433 
04434            if (input_section->flags & SEC_ALLOC)
04435              elf64_alpha_emit_dynrel (output_bfd, info, input_section,
04436                                    srel, rel->r_offset, dynindx,
04437                                    dyntype, dynaddend);
04438          }
04439          goto default_reloc;
04440 
04441        case R_ALPHA_SREL16:
04442        case R_ALPHA_SREL32:
04443        case R_ALPHA_SREL64:
04444          if (dynamic_symbol_p)
04445             {
04446               (*_bfd_error_handler)
04447                 (_("%B: pc-relative relocation against dynamic symbol %s"),
04448                  input_bfd, h->root.root.root.string);
04449               ret_val = FALSE;
04450             }
04451          else if ((info->shared || info->pie) && undef_weak_ref)
04452             {
04453               (*_bfd_error_handler)
04454                 (_("%B: pc-relative relocation against undefined weak symbol %s"),
04455                  input_bfd, h->root.root.root.string);
04456               ret_val = FALSE;
04457             }
04458 
04459 
04460          /* ??? .eh_frame references to discarded sections will be smashed
04461             to relocations against SHN_UNDEF.  The .eh_frame format allows
04462             NULL to be encoded as 0 in any format, so this works here.  */
04463          if (r_symndx == 0)
04464            howto = (elf64_alpha_howto_table
04465                    + (r_type - R_ALPHA_SREL32 + R_ALPHA_REFLONG));
04466          goto default_reloc;
04467 
04468        case R_ALPHA_TLSLDM:
04469          /* Ignore the symbol for the relocation.  The result is always
04470             the current module.  */
04471          dynamic_symbol_p = 0;
04472          /* FALLTHRU */
04473 
04474        case R_ALPHA_TLSGD:
04475          if (!gotent->reloc_done)
04476            {
04477              gotent->reloc_done = 1;
04478 
04479              /* Note that the module index for the main program is 1.  */
04480              bfd_put_64 (output_bfd, !info->shared && !dynamic_symbol_p,
04481                        sgot->contents + gotent->got_offset);
04482 
04483              /* If the symbol has been forced local, output a
04484                DTPMOD64 reloc, otherwise it will be handled in
04485                finish_dynamic_symbol.  */
04486              if (info->shared && !dynamic_symbol_p)
04487               elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
04488                                     gotent->got_offset, 0,
04489                                     R_ALPHA_DTPMOD64, 0);
04490 
04491              if (dynamic_symbol_p || r_type == R_ALPHA_TLSLDM)
04492               value = 0;
04493              else
04494               {
04495                 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
04496                  value -= dtp_base;
04497               }
04498              bfd_put_64 (output_bfd, value,
04499                        sgot->contents + gotent->got_offset + 8);
04500            }
04501 
04502          value = (sgot->output_section->vma
04503                  + sgot->output_offset
04504                  + gotent->got_offset);
04505          value -= gp;
04506          goto default_reloc;
04507 
04508        case R_ALPHA_DTPRELHI:
04509        case R_ALPHA_DTPRELLO:
04510        case R_ALPHA_DTPREL16:
04511          if (dynamic_symbol_p)
04512             {
04513               (*_bfd_error_handler)
04514                 (_("%B: dtp-relative relocation against dynamic symbol %s"),
04515                  input_bfd, h->root.root.root.string);
04516               ret_val = FALSE;
04517             }
04518          BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
04519          value -= dtp_base;
04520          if (r_type == R_ALPHA_DTPRELHI)
04521            value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1);
04522          goto default_reloc;
04523 
04524        case R_ALPHA_TPRELHI:
04525        case R_ALPHA_TPRELLO:
04526        case R_ALPHA_TPREL16:
04527          if (info->shared)
04528            {
04529              (*_bfd_error_handler)
04530               (_("%B: TLS local exec code cannot be linked into shared objects"),
04531               input_bfd);
04532               ret_val = FALSE;
04533            }
04534          else if (dynamic_symbol_p)
04535             {
04536               (*_bfd_error_handler)
04537                 (_("%B: tp-relative relocation against dynamic symbol %s"),
04538                  input_bfd, h->root.root.root.string);
04539               ret_val = FALSE;
04540             }
04541          BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
04542          value -= tp_base;
04543          if (r_type == R_ALPHA_TPRELHI)
04544            value = ((bfd_signed_vma) value >> 16) + ((value >> 15) & 1);
04545          goto default_reloc;
04546 
04547        case R_ALPHA_GOTDTPREL:
04548        case R_ALPHA_GOTTPREL:
04549          BFD_ASSERT(sgot != NULL);
04550          BFD_ASSERT(gp != 0);
04551          BFD_ASSERT(gotent != NULL);
04552          BFD_ASSERT(gotent->use_count >= 1);
04553 
04554          if (!gotent->reloc_done)
04555            {
04556              gotent->reloc_done = 1;
04557 
04558              if (dynamic_symbol_p)
04559               value = 0;
04560              else
04561               {
04562                 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
04563                 if (r_type == R_ALPHA_GOTDTPREL)
04564                   value -= dtp_base;
04565                 else if (!info->shared)
04566                   value -= tp_base;
04567                 else
04568                   {
04569                     elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
04570                                           gotent->got_offset, 0,
04571                                           R_ALPHA_TPREL64,
04572                                           value - dtp_base);
04573                     value = 0;
04574                   }
04575               }
04576              bfd_put_64 (output_bfd, value,
04577                        sgot->contents + gotent->got_offset);
04578            }
04579 
04580          value = (sgot->output_section->vma
04581                  + sgot->output_offset
04582                  + gotent->got_offset);
04583          value -= gp;
04584          goto default_reloc;
04585 
04586        default:
04587        default_reloc:
04588          r = _bfd_final_link_relocate (howto, input_bfd, input_section,
04589                                    contents, rel->r_offset, value, 0);
04590          break;
04591        }
04592 
04593       switch (r)
04594        {
04595        case bfd_reloc_ok:
04596          break;
04597 
04598        case bfd_reloc_overflow:
04599          {
04600            const char *name;
04601 
04602            /* Don't warn if the overflow is due to pc relative reloc
04603               against discarded section.  Section optimization code should
04604               handle it.  */
04605 
04606            if (r_symndx < symtab_hdr->sh_info
04607               && sec != NULL && howto->pc_relative
04608               && elf_discarded_section (sec))
04609              break;
04610 
04611            if (h != NULL)
04612              name = NULL;
04613            else
04614              {
04615               name = (bfd_elf_string_from_elf_section
04616                      (input_bfd, symtab_hdr->sh_link, sym->st_name));
04617               if (name == NULL)
04618                 return FALSE;
04619               if (*name == '\0')
04620                 name = bfd_section_name (input_bfd, sec);
04621              }
04622            if (! ((*info->callbacks->reloc_overflow)
04623                  (info, (h ? &h->root.root : NULL), name, howto->name,
04624                   (bfd_vma) 0, input_bfd, input_section,
04625                   rel->r_offset)))
04626              ret_val = FALSE;
04627          }
04628          break;
04629 
04630        default:
04631        case bfd_reloc_outofrange:
04632          abort ();
04633        }
04634     }
04635 
04636   return ret_val;
04637 }
04638 
04639 /* Finish up dynamic symbol handling.  We set the contents of various
04640    dynamic sections here.  */
04641 
04642 static bfd_boolean
04643 elf64_alpha_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info,
04644                                struct elf_link_hash_entry *h,
04645                                Elf_Internal_Sym *sym)
04646 {
04647   struct alpha_elf_link_hash_entry *ah = (struct alpha_elf_link_hash_entry *)h;
04648   bfd *dynobj = elf_hash_table(info)->dynobj;
04649 
04650   if (h->needs_plt)
04651     {
04652       /* Fill in the .plt entry for this symbol.  */
04653       asection *splt, *sgot, *srel;
04654       Elf_Internal_Rela outrel;
04655       bfd_byte *loc;
04656       bfd_vma got_addr, plt_addr;
04657       bfd_vma plt_index;
04658       struct alpha_elf_got_entry *gotent;
04659 
04660       BFD_ASSERT (h->dynindx != -1);
04661 
04662       splt = bfd_get_section_by_name (dynobj, ".plt");
04663       BFD_ASSERT (splt != NULL);
04664       srel = bfd_get_section_by_name (dynobj, ".rela.plt");
04665       BFD_ASSERT (srel != NULL);
04666 
04667       for (gotent = ah->got_entries; gotent ; gotent = gotent->next)
04668        if (gotent->reloc_type == R_ALPHA_LITERAL
04669            && gotent->use_count > 0)
04670          {
04671            unsigned int insn;
04672            int disp;
04673 
04674            sgot = alpha_elf_tdata (gotent->gotobj)->got;
04675            BFD_ASSERT (sgot != NULL);
04676 
04677            BFD_ASSERT (gotent->got_offset != -1);
04678            BFD_ASSERT (gotent->plt_offset != -1);
04679 
04680            got_addr = (sgot->output_section->vma
04681                      + sgot->output_offset
04682                      + gotent->got_offset);
04683            plt_addr = (splt->output_section->vma
04684                      + splt->output_offset
04685                      + gotent->plt_offset);
04686 
04687            plt_index = (gotent->plt_offset-PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
04688 
04689            /* Fill in the entry in the procedure linkage table.  */
04690            if (elf64_alpha_use_secureplt)
04691              {
04692               disp = (PLT_HEADER_SIZE - 4) - (gotent->plt_offset + 4);
04693               insn = INSN_AD (INSN_BR, 31, disp);
04694               bfd_put_32 (output_bfd, insn,
04695                          splt->contents + gotent->plt_offset);
04696 
04697               plt_index = ((gotent->plt_offset - NEW_PLT_HEADER_SIZE)
04698                           / NEW_PLT_ENTRY_SIZE);
04699              }
04700            else
04701              {
04702               disp = -(gotent->plt_offset + 4);
04703               insn = INSN_AD (INSN_BR, 28, disp);
04704               bfd_put_32 (output_bfd, insn,
04705                          splt->contents + gotent->plt_offset);
04706               bfd_put_32 (output_bfd, INSN_UNOP,
04707                          splt->contents + gotent->plt_offset + 4);
04708               bfd_put_32 (output_bfd, INSN_UNOP,
04709                          splt->contents + gotent->plt_offset + 8);
04710 
04711               plt_index = ((gotent->plt_offset - OLD_PLT_HEADER_SIZE)
04712                           / OLD_PLT_ENTRY_SIZE);
04713              }
04714 
04715            /* Fill in the entry in the .rela.plt section.  */
04716            outrel.r_offset = got_addr;
04717            outrel.r_info = ELF64_R_INFO(h->dynindx, R_ALPHA_JMP_SLOT);
04718            outrel.r_addend = 0;
04719 
04720            loc = srel->contents + plt_index * sizeof (Elf64_External_Rela);
04721            bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
04722 
04723            /* Fill in the entry in the .got.  */
04724            bfd_put_64 (output_bfd, plt_addr,
04725                      sgot->contents + gotent->got_offset);
04726          }
04727     }
04728   else if (alpha_elf_dynamic_symbol_p (h, info))
04729     {
04730       /* Fill in the dynamic relocations for this symbol's .got entries.  */
04731       asection *srel;
04732       struct alpha_elf_got_entry *gotent;
04733 
04734       srel = bfd_get_section_by_name (dynobj, ".rela.got");
04735       BFD_ASSERT (srel != NULL);
04736 
04737       for (gotent = ((struct alpha_elf_link_hash_entry *) h)->got_entries;
04738           gotent != NULL;
04739           gotent = gotent->next)
04740        {
04741          asection *sgot;
04742          long r_type;
04743 
04744          if (gotent->use_count == 0)
04745            continue;
04746 
04747          sgot = alpha_elf_tdata (gotent->gotobj)->got;
04748 
04749          r_type = gotent->reloc_type;
04750          switch (r_type)
04751            {
04752            case R_ALPHA_LITERAL:
04753              r_type = R_ALPHA_GLOB_DAT;
04754              break;
04755            case R_ALPHA_TLSGD:
04756              r_type = R_ALPHA_DTPMOD64;
04757              break;
04758            case R_ALPHA_GOTDTPREL:
04759              r_type = R_ALPHA_DTPREL64;
04760              break;
04761            case R_ALPHA_GOTTPREL:
04762              r_type = R_ALPHA_TPREL64;
04763              break;
04764            case R_ALPHA_TLSLDM:
04765            default:
04766              abort ();
04767            }
04768 
04769          elf64_alpha_emit_dynrel (output_bfd, info, sgot, srel, 
04770                                gotent->got_offset, h->dynindx,
04771                                r_type, gotent->addend);
04772 
04773          if (gotent->reloc_type == R_ALPHA_TLSGD)
04774            elf64_alpha_emit_dynrel (output_bfd, info, sgot, srel, 
04775                                  gotent->got_offset + 8, h->dynindx,
04776                                  R_ALPHA_DTPREL64, gotent->addend);
04777        }
04778     }
04779 
04780   /* Mark some specially defined symbols as absolute.  */
04781   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
04782       || h == elf_hash_table (info)->hgot
04783       || h == elf_hash_table (info)->hplt)
04784     sym->st_shndx = SHN_ABS;
04785 
04786   return TRUE;
04787 }
04788 
04789 /* Finish up the dynamic sections.  */
04790 
04791 static bfd_boolean
04792 elf64_alpha_finish_dynamic_sections (bfd *output_bfd,
04793                                  struct bfd_link_info *info)
04794 {
04795   bfd *dynobj;
04796   asection *sdyn;
04797 
04798   dynobj = elf_hash_table (info)->dynobj;
04799   sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
04800 
04801   if (elf_hash_table (info)->dynamic_sections_created)
04802     {
04803       asection *splt, *sgotplt, *srelaplt;
04804       Elf64_External_Dyn *dyncon, *dynconend;
04805       bfd_vma plt_vma, gotplt_vma;
04806 
04807       splt = bfd_get_section_by_name (dynobj, ".plt");
04808       srelaplt = bfd_get_section_by_name (output_bfd, ".rela.plt");
04809       BFD_ASSERT (splt != NULL && sdyn != NULL);
04810 
04811       plt_vma = splt->output_section->vma + splt->output_offset;
04812 
04813       gotplt_vma = 0;
04814       if (elf64_alpha_use_secureplt)
04815        {
04816          sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
04817          BFD_ASSERT (sgotplt != NULL);
04818          if (sgotplt->size > 0)
04819            gotplt_vma = sgotplt->output_section->vma + sgotplt->output_offset;
04820        }
04821 
04822       dyncon = (Elf64_External_Dyn *) sdyn->contents;
04823       dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
04824       for (; dyncon < dynconend; dyncon++)
04825        {
04826          Elf_Internal_Dyn dyn;
04827 
04828          bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
04829 
04830          switch (dyn.d_tag)
04831            {
04832            case DT_PLTGOT:
04833              dyn.d_un.d_ptr
04834               = elf64_alpha_use_secureplt ? gotplt_vma : plt_vma;
04835              break;
04836            case DT_PLTRELSZ:
04837              dyn.d_un.d_val = srelaplt ? srelaplt->size : 0;
04838              break;
04839            case DT_JMPREL:
04840              dyn.d_un.d_ptr = srelaplt ? srelaplt->vma : 0;
04841              break;
04842 
04843            case DT_RELASZ:
04844              /* My interpretation of the TIS v1.1 ELF document indicates
04845                that RELASZ should not include JMPREL.  This is not what
04846                the rest of the BFD does.  It is, however, what the
04847                glibc ld.so wants.  Do this fixup here until we found
04848                out who is right.  */
04849              if (srelaplt)
04850               dyn.d_un.d_val -= srelaplt->size;
04851              break;
04852            }
04853 
04854          bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
04855        }
04856 
04857       /* Initialize the plt header.  */
04858       if (splt->size > 0)
04859        {
04860          unsigned int insn;
04861          int ofs;
04862 
04863          if (elf64_alpha_use_secureplt)
04864            {
04865              ofs = gotplt_vma - (plt_vma + PLT_HEADER_SIZE);
04866 
04867              insn = INSN_ABC (INSN_SUBQ, 27, 28, 25);
04868              bfd_put_32 (output_bfd, insn, splt->contents);
04869 
04870              insn = INSN_ABO (INSN_LDAH, 28, 28, (ofs + 0x8000) >> 16);
04871              bfd_put_32 (output_bfd, insn, splt->contents + 4);
04872 
04873              insn = INSN_ABC (INSN_S4SUBQ, 25, 25, 25);
04874              bfd_put_32 (output_bfd, insn, splt->contents + 8);
04875 
04876              insn = INSN_ABO (INSN_LDA, 28, 28, ofs);
04877              bfd_put_32 (output_bfd, insn, splt->contents + 12);
04878 
04879              insn = INSN_ABO (INSN_LDQ, 27, 28, 0);
04880              bfd_put_32 (output_bfd, insn, splt->contents + 16);
04881 
04882              insn = INSN_ABC (INSN_ADDQ, 25, 25, 25);
04883              bfd_put_32 (output_bfd, insn, splt->contents + 20);
04884 
04885              insn = INSN_ABO (INSN_LDQ, 28, 28, 8);
04886              bfd_put_32 (output_bfd, insn, splt->contents + 24);
04887 
04888              insn = INSN_AB (INSN_JMP, 31, 27);
04889              bfd_put_32 (output_bfd, insn, splt->contents + 28);
04890 
04891              insn = INSN_AD (INSN_BR, 28, -PLT_HEADER_SIZE);
04892              bfd_put_32 (output_bfd, insn, splt->contents + 32);
04893            }
04894          else
04895            {
04896              insn = INSN_AD (INSN_BR, 27, 0);    /* br $27, .+4 */
04897              bfd_put_32 (output_bfd, insn, splt->contents);
04898 
04899              insn = INSN_ABO (INSN_LDQ, 27, 27, 12);
04900              bfd_put_32 (output_bfd, insn, splt->contents + 4);
04901 
04902              insn = INSN_UNOP;
04903              bfd_put_32 (output_bfd, insn, splt->contents + 8);
04904 
04905              insn = INSN_AB (INSN_JMP, 27, 27);
04906              bfd_put_32 (output_bfd, insn, splt->contents + 12);
04907 
04908              /* The next two words will be filled in by ld.so.  */
04909              bfd_put_64 (output_bfd, 0, splt->contents + 16);
04910              bfd_put_64 (output_bfd, 0, splt->contents + 24);
04911            }
04912 
04913          elf_section_data (splt->output_section)->this_hdr.sh_entsize = 0;
04914        }
04915     }
04916 
04917   return TRUE;
04918 }
04919 
04920 /* We need to use a special link routine to handle the .mdebug section.
04921    We need to merge all instances of these sections together, not write
04922    them all out sequentially.  */
04923 
04924 static bfd_boolean
04925 elf64_alpha_final_link (bfd *abfd, struct bfd_link_info *info)
04926 {
04927   asection *o;
04928   struct bfd_link_order *p;
04929   asection *mdebug_sec;
04930   struct ecoff_debug_info debug;
04931   const struct ecoff_debug_swap *swap
04932     = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
04933   HDRR *symhdr = &debug.symbolic_header;
04934   PTR mdebug_handle = NULL;
04935 
04936   /* Go through the sections and collect the mdebug information.  */
04937   mdebug_sec = NULL;
04938   for (o = abfd->sections; o != (asection *) NULL; o = o->next)
04939     {
04940       if (strcmp (o->name, ".mdebug") == 0)
04941        {
04942          struct extsym_info einfo;
04943 
04944          /* We have found the .mdebug section in the output file.
04945             Look through all the link_orders comprising it and merge
04946             the information together.  */
04947          symhdr->magic = swap->sym_magic;
04948          /* FIXME: What should the version stamp be?  */
04949          symhdr->vstamp = 0;
04950          symhdr->ilineMax = 0;
04951          symhdr->cbLine = 0;
04952          symhdr->idnMax = 0;
04953          symhdr->ipdMax = 0;
04954          symhdr->isymMax = 0;
04955          symhdr->ioptMax = 0;
04956          symhdr->iauxMax = 0;
04957          symhdr->issMax = 0;
04958          symhdr->issExtMax = 0;
04959          symhdr->ifdMax = 0;
04960          symhdr->crfd = 0;
04961          symhdr->iextMax = 0;
04962 
04963          /* We accumulate the debugging information itself in the
04964             debug_info structure.  */
04965          debug.line = NULL;
04966          debug.external_dnr = NULL;
04967          debug.external_pdr = NULL;
04968          debug.external_sym = NULL;
04969          debug.external_opt = NULL;
04970          debug.external_aux = NULL;
04971          debug.ss = NULL;
04972          debug.ssext = debug.ssext_end = NULL;
04973          debug.external_fdr = NULL;
04974          debug.external_rfd = NULL;
04975          debug.external_ext = debug.external_ext_end = NULL;
04976 
04977          mdebug_handle = bfd_ecoff_debug_init (abfd, &debug, swap, info);
04978          if (mdebug_handle == (PTR) NULL)
04979            return FALSE;
04980 
04981          if (1)
04982            {
04983              asection *s;
04984              EXTR esym;
04985              bfd_vma last = 0;
04986              unsigned int i;
04987              static const char * const name[] =
04988               {
04989                 ".text", ".init", ".fini", ".data",
04990                 ".rodata", ".sdata", ".sbss", ".bss"
04991               };
04992              static const int sc[] = { scText, scInit, scFini, scData,
04993                                      scRData, scSData, scSBss, scBss };
04994 
04995              esym.jmptbl = 0;
04996              esym.cobol_main = 0;
04997              esym.weakext = 0;
04998              esym.reserved = 0;
04999              esym.ifd = ifdNil;
05000              esym.asym.iss = issNil;
05001              esym.asym.st = stLocal;
05002              esym.asym.reserved = 0;
05003              esym.asym.index = indexNil;
05004              for (i = 0; i < 8; i++)
05005               {
05006                 esym.asym.sc = sc[i];
05007                 s = bfd_get_section_by_name (abfd, name[i]);
05008                 if (s != NULL)
05009                   {
05010                     esym.asym.value = s->vma;
05011                     last = s->vma + s->size;
05012                   }
05013                 else
05014                   esym.asym.value = last;
05015 
05016                 if (! bfd_ecoff_debug_one_external (abfd, &debug, swap,
05017                                                 name[i], &esym))
05018                   return FALSE;
05019               }
05020            }
05021 
05022          for (p = o->map_head.link_order;
05023               p != (struct bfd_link_order *) NULL;
05024               p = p->next)
05025            {
05026              asection *input_section;
05027              bfd *input_bfd;
05028              const struct ecoff_debug_swap *input_swap;
05029              struct ecoff_debug_info input_debug;
05030              char *eraw_src;
05031              char *eraw_end;
05032 
05033              if (p->type != bfd_indirect_link_order)
05034               {
05035                 if (p->type == bfd_data_link_order)
05036                   continue;
05037                 abort ();
05038               }
05039 
05040              input_section = p->u.indirect.section;
05041              input_bfd = input_section->owner;
05042 
05043              if (bfd_get_flavour (input_bfd) != bfd_target_elf_flavour
05044                 || (get_elf_backend_data (input_bfd)
05045                     ->elf_backend_ecoff_debug_swap) == NULL)
05046               {
05047                 /* I don't know what a non ALPHA ELF bfd would be
05048                    doing with a .mdebug section, but I don't really
05049                    want to deal with it.  */
05050                 continue;
05051               }
05052 
05053              input_swap = (get_elf_backend_data (input_bfd)
05054                          ->elf_backend_ecoff_debug_swap);
05055 
05056              BFD_ASSERT (p->size == input_section->size);
05057 
05058              /* The ECOFF linking code expects that we have already
05059                read in the debugging information and set up an
05060                ecoff_debug_info structure, so we do that now.  */
05061              if (!elf64_alpha_read_ecoff_info (input_bfd, input_section,
05062                                           &input_debug))
05063               return FALSE;
05064 
05065              if (! (bfd_ecoff_debug_accumulate
05066                    (mdebug_handle, abfd, &debug, swap, input_bfd,
05067                     &input_debug, input_swap, info)))
05068               return FALSE;
05069 
05070              /* Loop through the external symbols.  For each one with
05071                interesting information, try to find the symbol in
05072                the linker global hash table and save the information
05073                for the output external symbols.  */
05074              eraw_src = input_debug.external_ext;
05075              eraw_end = (eraw_src
05076                        + (input_debug.symbolic_header.iextMax
05077                           * input_swap->external_ext_size));
05078              for (;
05079                  eraw_src < eraw_end;
05080                  eraw_src += input_swap->external_ext_size)
05081               {
05082                 EXTR ext;
05083                 const char *name;
05084                 struct alpha_elf_link_hash_entry *h;
05085 
05086                 (*input_swap->swap_ext_in) (input_bfd, (PTR) eraw_src, &ext);
05087                 if (ext.asym.sc == scNil
05088                     || ext.asym.sc == scUndefined
05089                     || ext.asym.sc == scSUndefined)
05090                   continue;
05091 
05092                 name = input_debug.ssext + ext.asym.iss;
05093                 h = alpha_elf_link_hash_lookup (alpha_elf_hash_table (info),
05094                                             name, FALSE, FALSE, TRUE);
05095                 if (h == NULL || h->esym.ifd != -2)
05096                   continue;
05097 
05098                 if (ext.ifd != -1)
05099                   {
05100                     BFD_ASSERT (ext.ifd
05101                               < input_debug.symbolic_header.ifdMax);
05102                     ext.ifd = input_debug.ifdmap[ext.ifd];
05103                   }
05104 
05105                 h->esym = ext;
05106               }
05107 
05108              /* Free up the information we just read.  */
05109              free (input_debug.line);
05110              free (input_debug.external_dnr);
05111              free (input_debug.external_pdr);
05112              free (input_debug.external_sym);
05113              free (input_debug.external_opt);
05114              free (input_debug.external_aux);
05115              free (input_debug.ss);
05116              free (input_debug.ssext);
05117              free (input_debug.external_fdr);
05118              free (input_debug.external_rfd);
05119              free (input_debug.external_ext);
05120 
05121              /* Hack: reset the SEC_HAS_CONTENTS flag so that
05122                elf_link_input_bfd ignores this section.  */
05123              input_section->flags &=~ SEC_HAS_CONTENTS;
05124            }
05125 
05126          /* Build the external symbol information.  */
05127          einfo.abfd = abfd;
05128          einfo.info = info;
05129          einfo.debug = &debug;
05130          einfo.swap = swap;
05131          einfo.failed = FALSE;
05132          elf_link_hash_traverse (elf_hash_table (info),
05133                               elf64_alpha_output_extsym,
05134                               (PTR) &einfo);
05135          if (einfo.failed)
05136            return FALSE;
05137 
05138          /* Set the size of the .mdebug section.  */
05139          o->size = bfd_ecoff_debug_size (abfd, &debug, swap);
05140 
05141          /* Skip this section later on (I don't think this currently
05142             matters, but someday it might).  */
05143          o->map_head.link_order = (struct bfd_link_order *) NULL;
05144 
05145          mdebug_sec = o;
05146        }
05147     }
05148 
05149   /* Invoke the regular ELF backend linker to do all the work.  */
05150   if (! bfd_elf_final_link (abfd, info))
05151     return FALSE;
05152 
05153   /* Now write out the computed sections.  */
05154 
05155   /* The .got subsections...  */
05156   {
05157     bfd *i, *dynobj = elf_hash_table(info)->dynobj;
05158     for (i = alpha_elf_hash_table(info)->got_list;
05159         i != NULL;
05160         i = alpha_elf_tdata(i)->got_link_next)
05161       {
05162        asection *sgot;
05163 
05164        /* elf_bfd_final_link already did everything in dynobj.  */
05165        if (i == dynobj)
05166          continue;
05167 
05168        sgot = alpha_elf_tdata(i)->got;
05169        if (! bfd_set_section_contents (abfd, sgot->output_section,
05170                                    sgot->contents,
05171                                    (file_ptr) sgot->output_offset,
05172                                    sgot->size))
05173          return FALSE;
05174       }
05175   }
05176 
05177   if (mdebug_sec != (asection *) NULL)
05178     {
05179       BFD_ASSERT (abfd->output_has_begun);
05180       if (! bfd_ecoff_write_accumulated_debug (mdebug_handle, abfd, &debug,
05181                                           swap, info,
05182                                           mdebug_sec->filepos))
05183        return FALSE;
05184 
05185       bfd_ecoff_debug_free (mdebug_handle, abfd, &debug, swap, info);
05186     }
05187 
05188   return TRUE;
05189 }
05190 
05191 static enum elf_reloc_type_class
05192 elf64_alpha_reloc_type_class (const Elf_Internal_Rela *rela)
05193 {
05194   switch ((int) ELF64_R_TYPE (rela->r_info))
05195     {
05196     case R_ALPHA_RELATIVE:
05197       return reloc_class_relative;
05198     case R_ALPHA_JMP_SLOT:
05199       return reloc_class_plt;
05200     case R_ALPHA_COPY:
05201       return reloc_class_copy;
05202     default:
05203       return reloc_class_normal;
05204     }
05205 }
05206 
05207 static const struct bfd_elf_special_section elf64_alpha_special_sections[] =
05208 {
05209   { STRING_COMMA_LEN (".sbss"),  -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_ALPHA_GPREL },
05210   { STRING_COMMA_LEN (".sdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_ALPHA_GPREL },
05211   { NULL,                     0,  0, 0,            0 }
05212 };
05213 
05214 /* ECOFF swapping routines.  These are used when dealing with the
05215    .mdebug section, which is in the ECOFF debugging format.  Copied
05216    from elf32-mips.c.  */
05217 static const struct ecoff_debug_swap
05218 elf64_alpha_ecoff_debug_swap =
05219 {
05220   /* Symbol table magic number.  */
05221   magicSym2,
05222   /* Alignment of debugging information.  E.g., 4.  */
05223   8,
05224   /* Sizes of external symbolic information.  */
05225   sizeof (struct hdr_ext),
05226   sizeof (struct dnr_ext),
05227   sizeof (struct pdr_ext),
05228   sizeof (struct sym_ext),
05229   sizeof (struct opt_ext),
05230   sizeof (struct fdr_ext),
05231   sizeof (struct rfd_ext),
05232   sizeof (struct ext_ext),
05233   /* Functions to swap in external symbolic data.  */
05234   ecoff_swap_hdr_in,
05235   ecoff_swap_dnr_in,
05236   ecoff_swap_pdr_in,
05237   ecoff_swap_sym_in,
05238   ecoff_swap_opt_in,
05239   ecoff_swap_fdr_in,
05240   ecoff_swap_rfd_in,
05241   ecoff_swap_ext_in,
05242   _bfd_ecoff_swap_tir_in,
05243   _bfd_ecoff_swap_rndx_in,
05244   /* Functions to swap out external symbolic data.  */
05245   ecoff_swap_hdr_out,
05246   ecoff_swap_dnr_out,
05247   ecoff_swap_pdr_out,
05248   ecoff_swap_sym_out,
05249   ecoff_swap_opt_out,
05250   ecoff_swap_fdr_out,
05251   ecoff_swap_rfd_out,
05252   ecoff_swap_ext_out,
05253   _bfd_ecoff_swap_tir_out,
05254   _bfd_ecoff_swap_rndx_out,
05255   /* Function to read in symbolic data.  */
05256   elf64_alpha_read_ecoff_info
05257 };
05258 
05259 /* Use a non-standard hash bucket size of 8.  */
05260 
05261 static const struct elf_size_info alpha_elf_size_info =
05262 {
05263   sizeof (Elf64_External_Ehdr),
05264   sizeof (Elf64_External_Phdr),
05265   sizeof (Elf64_External_Shdr),
05266   sizeof (Elf64_External_Rel),
05267   sizeof (Elf64_External_Rela),
05268   sizeof (Elf64_External_Sym),
05269   sizeof (Elf64_External_Dyn),
05270   sizeof (Elf_External_Note),
05271   8,
05272   1,
05273   64, 3,
05274   ELFCLASS64, EV_CURRENT,
05275   bfd_elf64_write_out_phdrs,
05276   bfd_elf64_write_shdrs_and_ehdr,
05277   bfd_elf64_write_relocs,
05278   bfd_elf64_swap_symbol_in,
05279   bfd_elf64_swap_symbol_out,
05280   bfd_elf64_slurp_reloc_table,
05281   bfd_elf64_slurp_symbol_table,
05282   bfd_elf64_swap_dyn_in,
05283   bfd_elf64_swap_dyn_out,
05284   bfd_elf64_swap_reloc_in,
05285   bfd_elf64_swap_reloc_out,
05286   bfd_elf64_swap_reloca_in,
05287   bfd_elf64_swap_reloca_out
05288 };
05289 
05290 #define TARGET_LITTLE_SYM   bfd_elf64_alpha_vec
05291 #define TARGET_LITTLE_NAME  "elf64-alpha"
05292 #define ELF_ARCH            bfd_arch_alpha
05293 #define ELF_MACHINE_CODE    EM_ALPHA
05294 #define ELF_MAXPAGESIZE     0x10000
05295 #define ELF_COMMONPAGESIZE  0x2000
05296 
05297 #define bfd_elf64_bfd_link_hash_table_create \
05298   elf64_alpha_bfd_link_hash_table_create
05299 
05300 #define bfd_elf64_bfd_reloc_type_lookup \
05301   elf64_alpha_bfd_reloc_type_lookup
05302 #define bfd_elf64_bfd_reloc_name_lookup \
05303   elf64_alpha_bfd_reloc_name_lookup
05304 #define elf_info_to_howto \
05305   elf64_alpha_info_to_howto
05306 
05307 #define bfd_elf64_mkobject \
05308   elf64_alpha_mkobject
05309 #define elf_backend_object_p \
05310   elf64_alpha_object_p
05311 
05312 #define elf_backend_section_from_shdr \
05313   elf64_alpha_section_from_shdr
05314 #define elf_backend_section_flags \
05315   elf64_alpha_section_flags
05316 #define elf_backend_fake_sections \
05317   elf64_alpha_fake_sections
05318 
05319 #define bfd_elf64_bfd_is_local_label_name \
05320   elf64_alpha_is_local_label_name
05321 #define bfd_elf64_find_nearest_line \
05322   elf64_alpha_find_nearest_line
05323 #define bfd_elf64_bfd_relax_section \
05324   elf64_alpha_relax_section
05325 
05326 #define elf_backend_add_symbol_hook \
05327   elf64_alpha_add_symbol_hook
05328 #define elf_backend_check_relocs \
05329   elf64_alpha_check_relocs
05330 #define elf_backend_create_dynamic_sections \
05331   elf64_alpha_create_dynamic_sections
05332 #define elf_backend_adjust_dynamic_symbol \
05333   elf64_alpha_adjust_dynamic_symbol
05334 #define elf_backend_merge_symbol_attribute \
05335   elf64_alpha_merge_symbol_attribute
05336 #define elf_backend_always_size_sections \
05337   elf64_alpha_always_size_sections
05338 #define elf_backend_size_dynamic_sections \
05339   elf64_alpha_size_dynamic_sections
05340 #define elf_backend_omit_section_dynsym \
05341   ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
05342 #define elf_backend_relocate_section \
05343   elf64_alpha_relocate_section
05344 #define elf_backend_finish_dynamic_symbol \
05345   elf64_alpha_finish_dynamic_symbol
05346 #define elf_backend_finish_dynamic_sections \
05347   elf64_alpha_finish_dynamic_sections
05348 #define bfd_elf64_bfd_final_link \
05349   elf64_alpha_final_link
05350 #define elf_backend_reloc_type_class \
05351   elf64_alpha_reloc_type_class
05352 
05353 #define elf_backend_ecoff_debug_swap \
05354   &elf64_alpha_ecoff_debug_swap
05355 
05356 #define elf_backend_size_info \
05357   alpha_elf_size_info
05358 
05359 #define elf_backend_special_sections \
05360   elf64_alpha_special_sections
05361 
05362 /* A few constants that determine how the .plt section is set up.  */
05363 #define elf_backend_want_got_plt 0
05364 #define elf_backend_plt_readonly 0
05365 #define elf_backend_want_plt_sym 1
05366 #define elf_backend_got_header_size 0
05367 
05368 #include "elf64-target.h"
05369 
05370 /* FreeBSD support.  */
05371 
05372 #undef TARGET_LITTLE_SYM
05373 #define TARGET_LITTLE_SYM   bfd_elf64_alpha_freebsd_vec
05374 #undef TARGET_LITTLE_NAME
05375 #define TARGET_LITTLE_NAME  "elf64-alpha-freebsd"
05376 #undef ELF_OSABI
05377 #define       ELF_OSABI            ELFOSABI_FREEBSD
05378 
05379 /* The kernel recognizes executables as valid only if they carry a
05380    "FreeBSD" label in the ELF header.  So we put this label on all
05381    executables and (for simplicity) also all other object files.  */
05382 
05383 static void
05384 elf64_alpha_fbsd_post_process_headers (bfd * abfd,
05385        struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
05386 {
05387   Elf_Internal_Ehdr * i_ehdrp;     /* ELF file header, internal form.  */
05388 
05389   i_ehdrp = elf_elfheader (abfd);
05390 
05391   /* Put an ABI label supported by FreeBSD >= 4.1.  */
05392   i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
05393 #ifdef OLD_FREEBSD_ABI_LABEL
05394   /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard.  */
05395   memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8);
05396 #endif
05397 }
05398 
05399 #undef elf_backend_post_process_headers
05400 #define elf_backend_post_process_headers \
05401   elf64_alpha_fbsd_post_process_headers
05402 
05403 #undef  elf64_bed
05404 #define elf64_bed elf64_alpha_fbsd_bed
05405 
05406 #include "elf64-target.h"