elf64-alpha.c revision 77303
133965Sjdp/* Alpha specific support for 64-bit ELF
260510Sobrien   Copyright 1996, 97, 98, 1999 Free Software Foundation, Inc.
333965Sjdp   Contributed by Richard Henderson <rth@tamu.edu>.
433965Sjdp
533965SjdpThis file is part of BFD, the Binary File Descriptor library.
633965Sjdp
733965SjdpThis program is free software; you can redistribute it and/or modify
833965Sjdpit under the terms of the GNU General Public License as published by
933965Sjdpthe Free Software Foundation; either version 2 of the License, or
1033965Sjdp(at your option) any later version.
1133965Sjdp
1233965SjdpThis program is distributed in the hope that it will be useful,
1333965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of
1433965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1533965SjdpGNU General Public License for more details.
1633965Sjdp
1733965SjdpYou should have received a copy of the GNU General Public License
1833965Sjdpalong with this program; if not, write to the Free Software
1933965SjdpFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
2033965Sjdp
2157406Sjdp/* $FreeBSD: head/contrib/binutils/bfd/elf64-alpha.c 77303 2001-05-28 05:53:00Z obrien $ */
2257406Sjdp
2333965Sjdp/* We need a published ABI spec for this.  Until one comes out, don't
2433965Sjdp   assume this'll remain unchanged forever.  */
2533965Sjdp
2633965Sjdp#include "bfd.h"
2733965Sjdp#include "sysdep.h"
2833965Sjdp#include "libbfd.h"
2933965Sjdp#include "elf-bfd.h"
3033965Sjdp
3133965Sjdp#include "elf/alpha.h"
3233965Sjdp
3333965Sjdp#define ALPHAECOFF
3433965Sjdp
3533965Sjdp#define NO_COFF_RELOCS
3633965Sjdp#define NO_COFF_SYMBOLS
3733965Sjdp#define NO_COFF_LINENOS
3833965Sjdp
3977303Sobrien/* Get the ECOFF swapping routines.  Needed for the debug information.  */
4033965Sjdp#include "coff/internal.h"
4133965Sjdp#include "coff/sym.h"
4233965Sjdp#include "coff/symconst.h"
4333965Sjdp#include "coff/ecoff.h"
4433965Sjdp#include "coff/alpha.h"
4533965Sjdp#include "aout/ar.h"
4633965Sjdp#include "libcoff.h"
4733965Sjdp#include "libecoff.h"
4833965Sjdp#define ECOFF_64
4933965Sjdp#include "ecoffswap.h"
5033965Sjdp
5177303Sobrienstatic int alpha_elf_dynamic_symbol_p
5277303Sobrien  PARAMS((struct elf_link_hash_entry *, struct bfd_link_info *));
5333965Sjdpstatic struct bfd_hash_entry * elf64_alpha_link_hash_newfunc
5433965Sjdp  PARAMS((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
5533965Sjdpstatic struct bfd_link_hash_table * elf64_alpha_bfd_link_hash_table_create
5633965Sjdp  PARAMS((bfd *));
5733965Sjdp
5833965Sjdpstatic bfd_reloc_status_type elf64_alpha_reloc_nil
5933965Sjdp  PARAMS((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
6033965Sjdpstatic bfd_reloc_status_type elf64_alpha_reloc_bad
6133965Sjdp  PARAMS((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
6233965Sjdpstatic bfd_reloc_status_type elf64_alpha_do_reloc_gpdisp
6333965Sjdp  PARAMS((bfd *, bfd_vma, bfd_byte *, bfd_byte *));
6433965Sjdpstatic bfd_reloc_status_type elf64_alpha_reloc_gpdisp
6533965Sjdp  PARAMS((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
6633965Sjdp
6733965Sjdpstatic reloc_howto_type * elf64_alpha_bfd_reloc_type_lookup
6833965Sjdp  PARAMS((bfd *, bfd_reloc_code_real_type));
6933965Sjdpstatic void elf64_alpha_info_to_howto
7033965Sjdp  PARAMS((bfd *, arelent *, Elf64_Internal_Rela *));
7133965Sjdp
7277303Sobrienstatic boolean elf64_alpha_mkobject
7377303Sobrien  PARAMS((bfd *));
7433965Sjdpstatic boolean elf64_alpha_object_p
7533965Sjdp  PARAMS((bfd *));
7633965Sjdpstatic boolean elf64_alpha_section_from_shdr
7733965Sjdp  PARAMS((bfd *, Elf64_Internal_Shdr *, char *));
7833965Sjdpstatic boolean elf64_alpha_fake_sections
7933965Sjdp  PARAMS((bfd *, Elf64_Internal_Shdr *, asection *));
8033965Sjdpstatic boolean elf64_alpha_create_got_section
8133965Sjdp  PARAMS((bfd *, struct bfd_link_info *));
8233965Sjdpstatic boolean elf64_alpha_create_dynamic_sections
8333965Sjdp  PARAMS((bfd *, struct bfd_link_info *));
8433965Sjdp
8533965Sjdpstatic boolean elf64_alpha_read_ecoff_info
8633965Sjdp  PARAMS((bfd *, asection *, struct ecoff_debug_info *));
8733965Sjdpstatic boolean elf64_alpha_is_local_label_name
8833965Sjdp  PARAMS((bfd *, const char *));
8933965Sjdpstatic boolean elf64_alpha_find_nearest_line
9033965Sjdp  PARAMS((bfd *, asection *, asymbol **, bfd_vma, const char **,
9133965Sjdp	  const char **, unsigned int *));
9233965Sjdp
9333965Sjdp#if defined(__STDC__) || defined(ALMOST_STDC)
9433965Sjdpstruct alpha_elf_link_hash_entry;
9533965Sjdp#endif
9633965Sjdp
9733965Sjdpstatic boolean elf64_alpha_output_extsym
9833965Sjdp  PARAMS((struct alpha_elf_link_hash_entry *, PTR));
9933965Sjdp
10033965Sjdpstatic boolean elf64_alpha_can_merge_gots
10133965Sjdp  PARAMS((bfd *, bfd *));
10233965Sjdpstatic void elf64_alpha_merge_gots
10333965Sjdp  PARAMS((bfd *, bfd *));
10433965Sjdpstatic boolean elf64_alpha_calc_got_offsets_for_symbol
10533965Sjdp  PARAMS ((struct alpha_elf_link_hash_entry *, PTR));
10633965Sjdpstatic void elf64_alpha_calc_got_offsets PARAMS ((struct bfd_link_info *));
10760510Sobrienstatic boolean elf64_alpha_size_got_sections
10860510Sobrien  PARAMS ((bfd *, struct bfd_link_info *));
10933965Sjdpstatic boolean elf64_alpha_always_size_sections
11033965Sjdp  PARAMS ((bfd *, struct bfd_link_info *));
11133965Sjdpstatic boolean elf64_alpha_calc_dynrel_sizes
11233965Sjdp  PARAMS ((struct alpha_elf_link_hash_entry *, struct bfd_link_info *));
11360510Sobrienstatic boolean elf64_alpha_add_symbol_hook
11460510Sobrien  PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
11560510Sobrien	   const char **, flagword *, asection **, bfd_vma *));
11633965Sjdpstatic boolean elf64_alpha_check_relocs
11733965Sjdp  PARAMS((bfd *, struct bfd_link_info *, asection *sec,
11833965Sjdp	  const Elf_Internal_Rela *));
11933965Sjdpstatic boolean elf64_alpha_adjust_dynamic_symbol
12033965Sjdp  PARAMS((struct bfd_link_info *, struct elf_link_hash_entry *));
12133965Sjdpstatic boolean elf64_alpha_size_dynamic_sections
12233965Sjdp  PARAMS((bfd *, struct bfd_link_info *));
12333965Sjdpstatic boolean elf64_alpha_relocate_section
12433965Sjdp  PARAMS((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
12533965Sjdp	  Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
12633965Sjdpstatic boolean elf64_alpha_finish_dynamic_symbol
12733965Sjdp  PARAMS((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
12833965Sjdp	  Elf_Internal_Sym *));
12933965Sjdpstatic boolean elf64_alpha_finish_dynamic_sections
13033965Sjdp  PARAMS((bfd *, struct bfd_link_info *));
13133965Sjdpstatic boolean elf64_alpha_final_link
13233965Sjdp  PARAMS((bfd *, struct bfd_link_info *));
13348850Sdfrstatic boolean elf64_alpha_merge_ind_symbols
13448850Sdfr  PARAMS((struct alpha_elf_link_hash_entry *, PTR));
13560510Sobrienstatic Elf_Internal_Rela * elf64_alpha_find_reloc_at_ofs
13660510Sobrien  PARAMS ((Elf_Internal_Rela *, Elf_Internal_Rela *, bfd_vma, int));
13733965Sjdp
13833965Sjdpstruct alpha_elf_link_hash_entry
13933965Sjdp{
14033965Sjdp  struct elf_link_hash_entry root;
14133965Sjdp
14233965Sjdp  /* External symbol information.  */
14333965Sjdp  EXTR esym;
14433965Sjdp
14533965Sjdp  /* Cumulative flags for all the .got entries.  */
14633965Sjdp  int flags;
14733965Sjdp
14833965Sjdp  /* Contexts (LITUSE) in which a literal was referenced.  */
14933965Sjdp#define ALPHA_ELF_LINK_HASH_LU_ADDR 0x01
15033965Sjdp#define ALPHA_ELF_LINK_HASH_LU_MEM  0x02
15133965Sjdp#define ALPHA_ELF_LINK_HASH_LU_BYTE 0x04
15233965Sjdp#define ALPHA_ELF_LINK_HASH_LU_FUNC 0x08
15333965Sjdp
15433965Sjdp  /* Used to implement multiple .got subsections.  */
15533965Sjdp  struct alpha_elf_got_entry
15633965Sjdp  {
15733965Sjdp    struct alpha_elf_got_entry *next;
15833965Sjdp
15933965Sjdp    /* which .got subsection?  */
16033965Sjdp    bfd *gotobj;
16133965Sjdp
16233965Sjdp    /* the addend in effect for this entry.  */
16333965Sjdp    bfd_vma addend;
16433965Sjdp
16533965Sjdp    /* the .got offset for this entry.  */
16633965Sjdp    int got_offset;
16733965Sjdp
16833965Sjdp    int flags;
16933965Sjdp
17033965Sjdp    /* An additional flag.  */
17133965Sjdp#define ALPHA_ELF_GOT_ENTRY_RELOCS_DONE 0x10
17260510Sobrien
17360510Sobrien    int use_count;
17433965Sjdp  } *got_entries;
17533965Sjdp
17633965Sjdp  /* used to count non-got, non-plt relocations for delayed sizing
17733965Sjdp     of relocation sections.  */
17833965Sjdp  struct alpha_elf_reloc_entry
17933965Sjdp  {
18033965Sjdp    struct alpha_elf_reloc_entry *next;
18133965Sjdp
18233965Sjdp    /* which .reloc section? */
18333965Sjdp    asection *srel;
18433965Sjdp
18533965Sjdp    /* what kind of relocation? */
18633965Sjdp    unsigned long rtype;
18733965Sjdp
18833965Sjdp    /* how many did we find?  */
18933965Sjdp    unsigned long count;
19033965Sjdp  } *reloc_entries;
19133965Sjdp};
19233965Sjdp
19333965Sjdp/* Alpha ELF linker hash table.  */
19433965Sjdp
19533965Sjdpstruct alpha_elf_link_hash_table
19633965Sjdp{
19733965Sjdp  struct elf_link_hash_table root;
19833965Sjdp
19933965Sjdp  /* The head of a list of .got subsections linked through
20033965Sjdp     alpha_elf_tdata(abfd)->got_link_next.  */
20133965Sjdp  bfd *got_list;
20233965Sjdp};
20333965Sjdp
20433965Sjdp/* Look up an entry in a Alpha ELF linker hash table.  */
20533965Sjdp
20633965Sjdp#define alpha_elf_link_hash_lookup(table, string, create, copy, follow)	\
20733965Sjdp  ((struct alpha_elf_link_hash_entry *)					\
20833965Sjdp   elf_link_hash_lookup (&(table)->root, (string), (create),		\
20933965Sjdp			 (copy), (follow)))
21033965Sjdp
21133965Sjdp/* Traverse a Alpha ELF linker hash table.  */
21233965Sjdp
21333965Sjdp#define alpha_elf_link_hash_traverse(table, func, info)			\
21433965Sjdp  (elf_link_hash_traverse						\
21533965Sjdp   (&(table)->root,							\
21633965Sjdp    (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func),	\
21733965Sjdp    (info)))
21833965Sjdp
21933965Sjdp/* Get the Alpha ELF linker hash table from a link_info structure.  */
22033965Sjdp
22133965Sjdp#define alpha_elf_hash_table(p) \
22233965Sjdp  ((struct alpha_elf_link_hash_table *) ((p)->hash))
22333965Sjdp
22433965Sjdp/* Get the object's symbols as our own entry type.  */
22533965Sjdp
22633965Sjdp#define alpha_elf_sym_hashes(abfd) \
22733965Sjdp  ((struct alpha_elf_link_hash_entry **)elf_sym_hashes(abfd))
22833965Sjdp
22933965Sjdp/* Should we do dynamic things to this symbol?  */
23033965Sjdp
23177303Sobrienstatic int
23277303Sobrienalpha_elf_dynamic_symbol_p (h, info)
23377303Sobrien     struct elf_link_hash_entry *h;
23477303Sobrien     struct bfd_link_info *info;
23577303Sobrien{
23677303Sobrien  if (h == NULL)
23777303Sobrien    return false;
23833965Sjdp
23977303Sobrien  while (h->root.type == bfd_link_hash_indirect
24077303Sobrien	 || h->root.type == bfd_link_hash_warning)
24177303Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
24277303Sobrien
24377303Sobrien  if (h->dynindx == -1)
24477303Sobrien    return false;
24577303Sobrien  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
24677303Sobrien    return false;
24777303Sobrien
24877303Sobrien  if (h->root.type == bfd_link_hash_undefweak
24977303Sobrien      || h->root.type == bfd_link_hash_defweak)
25077303Sobrien    return true;
25177303Sobrien
25277303Sobrien  if ((info->shared && !info->symbolic)
25377303Sobrien      || ((h->elf_link_hash_flags
25477303Sobrien	   & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR))
25577303Sobrien	  == (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)))
25677303Sobrien    return true;
25777303Sobrien
25877303Sobrien  return false;
25977303Sobrien}
26077303Sobrien
26133965Sjdp/* Create an entry in a Alpha ELF linker hash table.  */
26233965Sjdp
26333965Sjdpstatic struct bfd_hash_entry *
26433965Sjdpelf64_alpha_link_hash_newfunc (entry, table, string)
26533965Sjdp     struct bfd_hash_entry *entry;
26633965Sjdp     struct bfd_hash_table *table;
26733965Sjdp     const char *string;
26833965Sjdp{
26933965Sjdp  struct alpha_elf_link_hash_entry *ret =
27033965Sjdp    (struct alpha_elf_link_hash_entry *) entry;
27133965Sjdp
27233965Sjdp  /* Allocate the structure if it has not already been allocated by a
27333965Sjdp     subclass.  */
27433965Sjdp  if (ret == (struct alpha_elf_link_hash_entry *) NULL)
27533965Sjdp    ret = ((struct alpha_elf_link_hash_entry *)
27633965Sjdp	   bfd_hash_allocate (table,
27733965Sjdp			      sizeof (struct alpha_elf_link_hash_entry)));
27833965Sjdp  if (ret == (struct alpha_elf_link_hash_entry *) NULL)
27933965Sjdp    return (struct bfd_hash_entry *) ret;
28033965Sjdp
28133965Sjdp  /* Call the allocation method of the superclass.  */
28233965Sjdp  ret = ((struct alpha_elf_link_hash_entry *)
28333965Sjdp	 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
28433965Sjdp				     table, string));
28533965Sjdp  if (ret != (struct alpha_elf_link_hash_entry *) NULL)
28633965Sjdp    {
28733965Sjdp      /* Set local fields.  */
28833965Sjdp      memset (&ret->esym, 0, sizeof (EXTR));
28933965Sjdp      /* We use -2 as a marker to indicate that the information has
29033965Sjdp	 not been set.  -1 means there is no associated ifd.  */
29133965Sjdp      ret->esym.ifd = -2;
29233965Sjdp      ret->flags = 0;
29333965Sjdp      ret->got_entries = NULL;
29433965Sjdp      ret->reloc_entries = NULL;
29533965Sjdp    }
29633965Sjdp
29733965Sjdp  return (struct bfd_hash_entry *) ret;
29833965Sjdp}
29933965Sjdp
30033965Sjdp/* Create a Alpha ELF linker hash table.  */
30133965Sjdp
30233965Sjdpstatic struct bfd_link_hash_table *
30333965Sjdpelf64_alpha_bfd_link_hash_table_create (abfd)
30433965Sjdp     bfd *abfd;
30533965Sjdp{
30633965Sjdp  struct alpha_elf_link_hash_table *ret;
30733965Sjdp
30833965Sjdp  ret = ((struct alpha_elf_link_hash_table *)
30933965Sjdp	 bfd_zalloc (abfd, sizeof (struct alpha_elf_link_hash_table)));
31033965Sjdp  if (ret == (struct alpha_elf_link_hash_table *) NULL)
31133965Sjdp    return NULL;
31233965Sjdp
31333965Sjdp  if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
31433965Sjdp				       elf64_alpha_link_hash_newfunc))
31533965Sjdp    {
31633965Sjdp      bfd_release (abfd, ret);
31733965Sjdp      return NULL;
31833965Sjdp    }
31933965Sjdp
32033965Sjdp  return &ret->root.root;
32133965Sjdp}
32233965Sjdp
32333965Sjdp/* We have some private fields hanging off of the elf_tdata structure.  */
32433965Sjdp
32533965Sjdpstruct alpha_elf_obj_tdata
32633965Sjdp{
32733965Sjdp  struct elf_obj_tdata root;
32833965Sjdp
32933965Sjdp  /* For every input file, these are the got entries for that object's
33033965Sjdp     local symbols.  */
33133965Sjdp  struct alpha_elf_got_entry ** local_got_entries;
33233965Sjdp
33333965Sjdp  /* For every input file, this is the object that owns the got that
33433965Sjdp     this input file uses.  */
33533965Sjdp  bfd *gotobj;
33633965Sjdp
33733965Sjdp  /* For every got, this is a linked list through the objects using this got */
33833965Sjdp  bfd *in_got_link_next;
33933965Sjdp
34033965Sjdp  /* For every got, this is a link to the next got subsegment.  */
34133965Sjdp  bfd *got_link_next;
34233965Sjdp
34333965Sjdp  /* For every got, this is the section.  */
34433965Sjdp  asection *got;
34533965Sjdp
34633965Sjdp  /* For every got, this is it's total number of *entries*.  */
34733965Sjdp  int total_got_entries;
34833965Sjdp
34933965Sjdp  /* For every got, this is the sum of the number of *entries* required
35033965Sjdp     to hold all of the member object's local got.  */
35133965Sjdp  int n_local_got_entries;
35233965Sjdp};
35333965Sjdp
35433965Sjdp#define alpha_elf_tdata(abfd) \
35533965Sjdp  ((struct alpha_elf_obj_tdata *) (abfd)->tdata.any)
35633965Sjdp
35733965Sjdpstatic boolean
35833965Sjdpelf64_alpha_mkobject (abfd)
35933965Sjdp     bfd *abfd;
36033965Sjdp{
36133965Sjdp  abfd->tdata.any = bfd_zalloc (abfd, sizeof (struct alpha_elf_obj_tdata));
36233965Sjdp  if (abfd->tdata.any == NULL)
36333965Sjdp    return false;
36433965Sjdp  return true;
36533965Sjdp}
36633965Sjdp
36733965Sjdpstatic boolean
36833965Sjdpelf64_alpha_object_p (abfd)
36933965Sjdp     bfd *abfd;
37033965Sjdp{
37133965Sjdp  /* Allocate our special target data.  */
37233965Sjdp  struct alpha_elf_obj_tdata *new_tdata;
37333965Sjdp  new_tdata = bfd_zalloc (abfd, sizeof (struct alpha_elf_obj_tdata));
37433965Sjdp  if (new_tdata == NULL)
37533965Sjdp    return false;
37633965Sjdp  new_tdata->root = *abfd->tdata.elf_obj_data;
37733965Sjdp  abfd->tdata.any = new_tdata;
37833965Sjdp
37933965Sjdp  /* Set the right machine number for an Alpha ELF file.  */
38033965Sjdp  return bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0);
38133965Sjdp}
38233965Sjdp
38333965Sjdp/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
38433965Sjdp   from smaller values.  Start with zero, widen, *then* decrement.  */
38533965Sjdp#define MINUS_ONE	(((bfd_vma)0) - 1)
38633965Sjdp
38733965Sjdpstatic reloc_howto_type elf64_alpha_howto_table[] =
38833965Sjdp{
38933965Sjdp  HOWTO (R_ALPHA_NONE,		/* type */
39033965Sjdp	 0,			/* rightshift */
39133965Sjdp	 0,			/* size (0 = byte, 1 = short, 2 = long) */
39233965Sjdp	 8,			/* bitsize */
39333965Sjdp	 true,			/* pc_relative */
39433965Sjdp	 0,			/* bitpos */
39533965Sjdp	 complain_overflow_dont, /* complain_on_overflow */
39633965Sjdp	 elf64_alpha_reloc_nil,	/* special_function */
39733965Sjdp	 "NONE",		/* name */
39833965Sjdp	 false,			/* partial_inplace */
39933965Sjdp	 0,			/* src_mask */
40033965Sjdp	 0,			/* dst_mask */
40133965Sjdp	 true),			/* pcrel_offset */
40233965Sjdp
40333965Sjdp  /* A 32 bit reference to a symbol.  */
40433965Sjdp  HOWTO (R_ALPHA_REFLONG,	/* type */
40533965Sjdp	 0,			/* rightshift */
40633965Sjdp	 2,			/* size (0 = byte, 1 = short, 2 = long) */
40733965Sjdp	 32,			/* bitsize */
40833965Sjdp	 false,			/* pc_relative */
40933965Sjdp	 0,			/* bitpos */
41033965Sjdp	 complain_overflow_bitfield, /* complain_on_overflow */
41133965Sjdp	 0,			/* special_function */
41233965Sjdp	 "REFLONG",		/* name */
41333965Sjdp	 false,			/* partial_inplace */
41433965Sjdp	 0xffffffff,		/* src_mask */
41533965Sjdp	 0xffffffff,		/* dst_mask */
41633965Sjdp	 false),		/* pcrel_offset */
41733965Sjdp
41833965Sjdp  /* A 64 bit reference to a symbol.  */
41933965Sjdp  HOWTO (R_ALPHA_REFQUAD,	/* type */
42033965Sjdp	 0,			/* rightshift */
42133965Sjdp	 4,			/* size (0 = byte, 1 = short, 2 = long) */
42233965Sjdp	 64,			/* bitsize */
42333965Sjdp	 false,			/* pc_relative */
42433965Sjdp	 0,			/* bitpos */
42533965Sjdp	 complain_overflow_bitfield, /* complain_on_overflow */
42633965Sjdp	 0,			/* special_function */
42733965Sjdp	 "REFQUAD",		/* name */
42833965Sjdp	 false,			/* partial_inplace */
42933965Sjdp	 MINUS_ONE,		/* src_mask */
43033965Sjdp	 MINUS_ONE,		/* dst_mask */
43133965Sjdp	 false),		/* pcrel_offset */
43233965Sjdp
43333965Sjdp  /* A 32 bit GP relative offset.  This is just like REFLONG except
43433965Sjdp     that when the value is used the value of the gp register will be
43533965Sjdp     added in.  */
43633965Sjdp  HOWTO (R_ALPHA_GPREL32,	/* type */
43733965Sjdp	 0,			/* rightshift */
43833965Sjdp	 2,			/* size (0 = byte, 1 = short, 2 = long) */
43933965Sjdp	 32,			/* bitsize */
44033965Sjdp	 false,			/* pc_relative */
44133965Sjdp	 0,			/* bitpos */
44233965Sjdp	 complain_overflow_bitfield, /* complain_on_overflow */
44333965Sjdp	 0,			/* special_function */
44433965Sjdp	 "GPREL32",		/* name */
44533965Sjdp	 false,			/* partial_inplace */
44633965Sjdp	 0xffffffff,		/* src_mask */
44733965Sjdp	 0xffffffff,		/* dst_mask */
44833965Sjdp	 false),		/* pcrel_offset */
44933965Sjdp
45033965Sjdp  /* Used for an instruction that refers to memory off the GP register.  */
45133965Sjdp  HOWTO (R_ALPHA_LITERAL,	/* type */
45233965Sjdp	 0,			/* rightshift */
45333965Sjdp	 2,			/* size (0 = byte, 1 = short, 2 = long) */
45433965Sjdp	 16,			/* bitsize */
45533965Sjdp	 false,			/* pc_relative */
45633965Sjdp	 0,			/* bitpos */
45733965Sjdp	 complain_overflow_signed, /* complain_on_overflow */
45833965Sjdp	 0,			/* special_function */
45933965Sjdp	 "ELF_LITERAL",		/* name */
46033965Sjdp	 false,			/* partial_inplace */
46133965Sjdp	 0xffff,		/* src_mask */
46233965Sjdp	 0xffff,		/* dst_mask */
46333965Sjdp	 false),		/* pcrel_offset */
46433965Sjdp
46533965Sjdp  /* This reloc only appears immediately following an ELF_LITERAL reloc.
46633965Sjdp     It identifies a use of the literal.  The symbol index is special:
46733965Sjdp     1 means the literal address is in the base register of a memory
46833965Sjdp     format instruction; 2 means the literal address is in the byte
46933965Sjdp     offset register of a byte-manipulation instruction; 3 means the
47033965Sjdp     literal address is in the target register of a jsr instruction.
47133965Sjdp     This does not actually do any relocation.  */
47233965Sjdp  HOWTO (R_ALPHA_LITUSE,	/* type */
47333965Sjdp	 0,			/* rightshift */
47433965Sjdp	 2,			/* size (0 = byte, 1 = short, 2 = long) */
47533965Sjdp	 32,			/* bitsize */
47633965Sjdp	 false,			/* pc_relative */
47733965Sjdp	 0,			/* bitpos */
47833965Sjdp	 complain_overflow_dont, /* complain_on_overflow */
47933965Sjdp	 elf64_alpha_reloc_nil,	/* special_function */
48033965Sjdp	 "LITUSE",		/* name */
48133965Sjdp	 false,			/* partial_inplace */
48233965Sjdp	 0,			/* src_mask */
48333965Sjdp	 0,			/* dst_mask */
48433965Sjdp	 false),		/* pcrel_offset */
48533965Sjdp
48633965Sjdp  /* Load the gp register.  This is always used for a ldah instruction
48733965Sjdp     which loads the upper 16 bits of the gp register.  The symbol
48833965Sjdp     index of the GPDISP instruction is an offset in bytes to the lda
48933965Sjdp     instruction that loads the lower 16 bits.  The value to use for
49033965Sjdp     the relocation is the difference between the GP value and the
49133965Sjdp     current location; the load will always be done against a register
49233965Sjdp     holding the current address.
49333965Sjdp
49433965Sjdp     NOTE: Unlike ECOFF, partial in-place relocation is not done.  If
49533965Sjdp     any offset is present in the instructions, it is an offset from
49633965Sjdp     the register to the ldah instruction.  This lets us avoid any
49733965Sjdp     stupid hackery like inventing a gp value to do partial relocation
49833965Sjdp     against.  Also unlike ECOFF, we do the whole relocation off of
49933965Sjdp     the GPDISP rather than a GPDISP_HI16/GPDISP_LO16 pair.  An odd,
50033965Sjdp     space consuming bit, that, since all the information was present
50133965Sjdp     in the GPDISP_HI16 reloc.  */
50233965Sjdp  HOWTO (R_ALPHA_GPDISP,	/* type */
50333965Sjdp	 16,			/* rightshift */
50433965Sjdp	 2,			/* size (0 = byte, 1 = short, 2 = long) */
50533965Sjdp	 16,			/* bitsize */
50633965Sjdp	 false,			/* pc_relative */
50733965Sjdp	 0,			/* bitpos */
50833965Sjdp	 complain_overflow_dont, /* complain_on_overflow */
50933965Sjdp	 elf64_alpha_reloc_gpdisp, /* special_function */
51033965Sjdp	 "GPDISP",		/* name */
51133965Sjdp	 false,			/* partial_inplace */
51233965Sjdp	 0xffff,		/* src_mask */
51333965Sjdp	 0xffff,		/* dst_mask */
51433965Sjdp	 true),			/* pcrel_offset */
51533965Sjdp
51633965Sjdp  /* A 21 bit branch.  */
51733965Sjdp  HOWTO (R_ALPHA_BRADDR,	/* type */
51833965Sjdp	 2,			/* rightshift */
51933965Sjdp	 2,			/* size (0 = byte, 1 = short, 2 = long) */
52033965Sjdp	 21,			/* bitsize */
52133965Sjdp	 true,			/* pc_relative */
52233965Sjdp	 0,			/* bitpos */
52333965Sjdp	 complain_overflow_signed, /* complain_on_overflow */
52433965Sjdp	 0,			/* special_function */
52533965Sjdp	 "BRADDR",		/* name */
52633965Sjdp	 false,			/* partial_inplace */
52733965Sjdp	 0x1fffff,		/* src_mask */
52833965Sjdp	 0x1fffff,		/* dst_mask */
52933965Sjdp	 true),			/* pcrel_offset */
53033965Sjdp
53133965Sjdp  /* A hint for a jump to a register.  */
53233965Sjdp  HOWTO (R_ALPHA_HINT,		/* type */
53333965Sjdp	 2,			/* rightshift */
53433965Sjdp	 2,			/* size (0 = byte, 1 = short, 2 = long) */
53533965Sjdp	 14,			/* bitsize */
53633965Sjdp	 true,			/* pc_relative */
53733965Sjdp	 0,			/* bitpos */
53833965Sjdp	 complain_overflow_dont, /* complain_on_overflow */
53933965Sjdp	 0,			/* special_function */
54033965Sjdp	 "HINT",		/* name */
54133965Sjdp	 false,			/* partial_inplace */
54233965Sjdp	 0x3fff,		/* src_mask */
54333965Sjdp	 0x3fff,		/* dst_mask */
54433965Sjdp	 true),			/* pcrel_offset */
54533965Sjdp
54633965Sjdp  /* 16 bit PC relative offset.  */
54733965Sjdp  HOWTO (R_ALPHA_SREL16,	/* type */
54833965Sjdp	 0,			/* rightshift */
54933965Sjdp	 1,			/* size (0 = byte, 1 = short, 2 = long) */
55033965Sjdp	 16,			/* bitsize */
55133965Sjdp	 true,			/* pc_relative */
55233965Sjdp	 0,			/* bitpos */
55333965Sjdp	 complain_overflow_signed, /* complain_on_overflow */
55433965Sjdp	 0,			/* special_function */
55533965Sjdp	 "SREL16",		/* name */
55633965Sjdp	 false,			/* partial_inplace */
55733965Sjdp	 0xffff,		/* src_mask */
55833965Sjdp	 0xffff,		/* dst_mask */
55933965Sjdp	 false),		/* pcrel_offset */
56033965Sjdp
56133965Sjdp  /* 32 bit PC relative offset.  */
56233965Sjdp  HOWTO (R_ALPHA_SREL32,	/* type */
56333965Sjdp	 0,			/* rightshift */
56433965Sjdp	 2,			/* size (0 = byte, 1 = short, 2 = long) */
56533965Sjdp	 32,			/* bitsize */
56633965Sjdp	 true,			/* pc_relative */
56733965Sjdp	 0,			/* bitpos */
56833965Sjdp	 complain_overflow_signed, /* complain_on_overflow */
56933965Sjdp	 0,			/* special_function */
57033965Sjdp	 "SREL32",		/* name */
57133965Sjdp	 false,			/* partial_inplace */
57233965Sjdp	 0xffffffff,		/* src_mask */
57333965Sjdp	 0xffffffff,		/* dst_mask */
57433965Sjdp	 false),		/* pcrel_offset */
57533965Sjdp
57633965Sjdp  /* A 64 bit PC relative offset.  */
57733965Sjdp  HOWTO (R_ALPHA_SREL64,	/* type */
57833965Sjdp	 0,			/* rightshift */
57933965Sjdp	 4,			/* size (0 = byte, 1 = short, 2 = long) */
58033965Sjdp	 64,			/* bitsize */
58133965Sjdp	 true,			/* pc_relative */
58233965Sjdp	 0,			/* bitpos */
58333965Sjdp	 complain_overflow_signed, /* complain_on_overflow */
58433965Sjdp	 0,			/* special_function */
58533965Sjdp	 "SREL64",		/* name */
58633965Sjdp	 false,			/* partial_inplace */
58733965Sjdp	 MINUS_ONE,		/* src_mask */
58833965Sjdp	 MINUS_ONE,		/* dst_mask */
58933965Sjdp	 false),		/* pcrel_offset */
59033965Sjdp
59133965Sjdp  /* Push a value on the reloc evaluation stack.  */
59238889Sjdp  /* Not implemented -- it's dumb.  */
59338889Sjdp  HOWTO (R_ALPHA_OP_PUSH,	/* type */
59433965Sjdp	 0,			/* rightshift */
59533965Sjdp	 0,			/* size (0 = byte, 1 = short, 2 = long) */
59633965Sjdp	 0,			/* bitsize */
59733965Sjdp	 false,			/* pc_relative */
59833965Sjdp	 0,			/* bitpos */
59933965Sjdp	 complain_overflow_dont, /* complain_on_overflow */
60033965Sjdp	 elf64_alpha_reloc_bad, /* special_function */
60133965Sjdp	 "OP_PUSH",		/* name */
60233965Sjdp	 false,			/* partial_inplace */
60333965Sjdp	 0,			/* src_mask */
60433965Sjdp	 0,			/* dst_mask */
60533965Sjdp	 false),		/* pcrel_offset */
60633965Sjdp
60733965Sjdp  /* Store the value from the stack at the given address.  Store it in
60833965Sjdp     a bitfield of size r_size starting at bit position r_offset.  */
60938889Sjdp  /* Not implemented -- it's dumb.  */
61038889Sjdp  HOWTO (R_ALPHA_OP_STORE,	/* type */
61133965Sjdp	 0,			/* rightshift */
61233965Sjdp	 4,			/* size (0 = byte, 1 = short, 2 = long) */
61333965Sjdp	 64,			/* bitsize */
61433965Sjdp	 false,			/* pc_relative */
61533965Sjdp	 0,			/* bitpos */
61633965Sjdp	 complain_overflow_dont, /* complain_on_overflow */
61733965Sjdp	 elf64_alpha_reloc_bad, /* special_function */
61833965Sjdp	 "OP_STORE",		/* name */
61933965Sjdp	 false,			/* partial_inplace */
62033965Sjdp	 0,			/* src_mask */
62133965Sjdp	 MINUS_ONE,		/* dst_mask */
62233965Sjdp	 false),		/* pcrel_offset */
62333965Sjdp
62433965Sjdp  /* Subtract the reloc address from the value on the top of the
62533965Sjdp     relocation stack.  */
62638889Sjdp  /* Not implemented -- it's dumb.  */
62738889Sjdp  HOWTO (R_ALPHA_OP_PSUB,	/* type */
62833965Sjdp	 0,			/* rightshift */
62933965Sjdp	 0,			/* size (0 = byte, 1 = short, 2 = long) */
63033965Sjdp	 0,			/* bitsize */
63133965Sjdp	 false,			/* pc_relative */
63233965Sjdp	 0,			/* bitpos */
63333965Sjdp	 complain_overflow_dont, /* complain_on_overflow */
63433965Sjdp	 elf64_alpha_reloc_bad, /* special_function */
63533965Sjdp	 "OP_PSUB",		/* name */
63633965Sjdp	 false,			/* partial_inplace */
63733965Sjdp	 0,			/* src_mask */
63833965Sjdp	 0,			/* dst_mask */
63933965Sjdp	 false),		/* pcrel_offset */
64033965Sjdp
64133965Sjdp  /* Shift the value on the top of the relocation stack right by the
64233965Sjdp     given value.  */
64338889Sjdp  /* Not implemented -- it's dumb.  */
64438889Sjdp  HOWTO (R_ALPHA_OP_PRSHIFT,	/* type */
64533965Sjdp	 0,			/* rightshift */
64633965Sjdp	 0,			/* size (0 = byte, 1 = short, 2 = long) */
64733965Sjdp	 0,			/* bitsize */
64833965Sjdp	 false,			/* pc_relative */
64933965Sjdp	 0,			/* bitpos */
65033965Sjdp	 complain_overflow_dont, /* complain_on_overflow */
65133965Sjdp	 elf64_alpha_reloc_bad, /* special_function */
65233965Sjdp	 "OP_PRSHIFT",		/* name */
65333965Sjdp	 false,			/* partial_inplace */
65433965Sjdp	 0,			/* src_mask */
65533965Sjdp	 0,			/* dst_mask */
65633965Sjdp	 false),		/* pcrel_offset */
65733965Sjdp
65838889Sjdp  /* Change the value of GP used by +r_addend until the next GPVALUE or the
65938889Sjdp     end of the input bfd.  */
66038889Sjdp  /* Not implemented -- it's dumb.  */
66138889Sjdp  HOWTO (R_ALPHA_GPVALUE,
66238889Sjdp	 0,			/* rightshift */
66338889Sjdp	 0,			/* size (0 = byte, 1 = short, 2 = long) */
66438889Sjdp	 0,			/* bitsize */
66538889Sjdp	 false,			/* pc_relative */
66638889Sjdp	 0,			/* bitpos */
66738889Sjdp	 complain_overflow_dont, /* complain_on_overflow */
66838889Sjdp	 elf64_alpha_reloc_bad, /* special_function */
66938889Sjdp	 "GPVALUE",		/* name */
67038889Sjdp	 false,			/* partial_inplace */
67138889Sjdp	 0,			/* src_mask */
67238889Sjdp	 0,			/* dst_mask */
67338889Sjdp	 false),		/* pcrel_offset */
67438889Sjdp
67538889Sjdp  /* The high 16 bits of the displacement from GP to the target.  */
67638889Sjdp  HOWTO (R_ALPHA_GPRELHIGH,
67738889Sjdp	 0,			/* rightshift */
67860510Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
67960510Sobrien	 16,			/* bitsize */
68038889Sjdp	 false,			/* pc_relative */
68138889Sjdp	 0,			/* bitpos */
68260510Sobrien	 complain_overflow_signed, /* complain_on_overflow */
68338889Sjdp	 elf64_alpha_reloc_bad, /* special_function */
68438889Sjdp	 "GPRELHIGH",		/* name */
68538889Sjdp	 false,			/* partial_inplace */
68660510Sobrien	 0xffff,		/* src_mask */
68760510Sobrien	 0xffff,		/* dst_mask */
68838889Sjdp	 false),		/* pcrel_offset */
68938889Sjdp
69038889Sjdp  /* The low 16 bits of the displacement from GP to the target.  */
69138889Sjdp  HOWTO (R_ALPHA_GPRELLOW,
69238889Sjdp	 0,			/* rightshift */
69360510Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
69460510Sobrien	 16,			/* bitsize */
69538889Sjdp	 false,			/* pc_relative */
69638889Sjdp	 0,			/* bitpos */
69738889Sjdp	 complain_overflow_dont, /* complain_on_overflow */
69838889Sjdp	 elf64_alpha_reloc_bad, /* special_function */
69938889Sjdp	 "GPRELLOW",		/* name */
70038889Sjdp	 false,			/* partial_inplace */
70160510Sobrien	 0xffff,		/* src_mask */
70260510Sobrien	 0xffff,		/* dst_mask */
70338889Sjdp	 false),		/* pcrel_offset */
70438889Sjdp
70538889Sjdp  /* A 16-bit displacement from the GP to the target.  */
70638889Sjdp  /* XXX: Not implemented.  */
70738889Sjdp  HOWTO (R_ALPHA_IMMED_GP_16,
70838889Sjdp	 0,			/* rightshift */
70960510Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
71060510Sobrien	 16,			/* bitsize */
71138889Sjdp	 false,			/* pc_relative */
71238889Sjdp	 0,			/* bitpos */
71360510Sobrien	 complain_overflow_signed, /* complain_on_overflow */
71460510Sobrien	 0,			/* special_function */
71538889Sjdp	 "IMMED_GP_16",		/* name */
71638889Sjdp	 false,			/* partial_inplace */
71760510Sobrien	 0xffff,		/* src_mask */
71860510Sobrien	 0xffff,		/* dst_mask */
71938889Sjdp	 false),		/* pcrel_offset */
72038889Sjdp
72138889Sjdp  /* The high bits of a 32-bit displacement from the GP to the target; the
72238889Sjdp     low bits are supplied in the subsequent R_ALPHA_IMMED_LO32 relocs.  */
72338889Sjdp  /* XXX: Not implemented.  */
72438889Sjdp  HOWTO (R_ALPHA_IMMED_GP_HI32,
72538889Sjdp	 0,			/* rightshift */
72638889Sjdp	 0,			/* size (0 = byte, 1 = short, 2 = long) */
72738889Sjdp	 0,			/* bitsize */
72838889Sjdp	 false,			/* pc_relative */
72938889Sjdp	 0,			/* bitpos */
73038889Sjdp	 complain_overflow_dont, /* complain_on_overflow */
73138889Sjdp	 elf64_alpha_reloc_bad, /* special_function */
73238889Sjdp	 "IMMED_GP_HI32",		/* name */
73338889Sjdp	 false,			/* partial_inplace */
73438889Sjdp	 0,			/* src_mask */
73538889Sjdp	 0,			/* dst_mask */
73638889Sjdp	 false),		/* pcrel_offset */
73738889Sjdp
73838889Sjdp  /* The high bits of a 32-bit displacement to the starting address of the
73977303Sobrien     current section (the relocation target is ignored); the low bits are
74038889Sjdp     supplied in the subsequent R_ALPHA_IMMED_LO32 relocs.  */
74138889Sjdp  /* XXX: Not implemented.  */
74238889Sjdp  HOWTO (R_ALPHA_IMMED_SCN_HI32,
74338889Sjdp	 0,			/* rightshift */
74438889Sjdp	 0,			/* size (0 = byte, 1 = short, 2 = long) */
74538889Sjdp	 0,			/* bitsize */
74638889Sjdp	 false,			/* pc_relative */
74738889Sjdp	 0,			/* bitpos */
74838889Sjdp	 complain_overflow_dont, /* complain_on_overflow */
74938889Sjdp	 elf64_alpha_reloc_bad, /* special_function */
75038889Sjdp	 "IMMED_SCN_HI32",		/* name */
75138889Sjdp	 false,			/* partial_inplace */
75238889Sjdp	 0,			/* src_mask */
75338889Sjdp	 0,			/* dst_mask */
75438889Sjdp	 false),		/* pcrel_offset */
75538889Sjdp
75638889Sjdp  /* The high bits of a 32-bit displacement from the previous br, bsr, jsr
75738889Sjdp     or jmp insn (as tagged by a BRADDR or HINT reloc) to the target; the
75838889Sjdp     low bits are supplied by subsequent R_ALPHA_IMMED_LO32 relocs.  */
75938889Sjdp  /* XXX: Not implemented.  */
76038889Sjdp  HOWTO (R_ALPHA_IMMED_BR_HI32,
76138889Sjdp	 0,			/* rightshift */
76238889Sjdp	 0,			/* size (0 = byte, 1 = short, 2 = long) */
76338889Sjdp	 0,			/* bitsize */
76438889Sjdp	 false,			/* pc_relative */
76538889Sjdp	 0,			/* bitpos */
76638889Sjdp	 complain_overflow_dont, /* complain_on_overflow */
76738889Sjdp	 elf64_alpha_reloc_bad, /* special_function */
76838889Sjdp	 "IMMED_BR_HI32",		/* name */
76938889Sjdp	 false,			/* partial_inplace */
77038889Sjdp	 0,			/* src_mask */
77138889Sjdp	 0,			/* dst_mask */
77238889Sjdp	 false),		/* pcrel_offset */
77338889Sjdp
77438889Sjdp  /* The low 16 bits of a displacement calculated in a previous HI32 reloc.  */
77538889Sjdp  /* XXX: Not implemented.  */
77638889Sjdp  HOWTO (R_ALPHA_IMMED_LO32,
77738889Sjdp	 0,			/* rightshift */
77838889Sjdp	 0,			/* size (0 = byte, 1 = short, 2 = long) */
77938889Sjdp	 0,			/* bitsize */
78038889Sjdp	 false,			/* pc_relative */
78138889Sjdp	 0,			/* bitpos */
78238889Sjdp	 complain_overflow_dont, /* complain_on_overflow */
78338889Sjdp	 elf64_alpha_reloc_bad, /* special_function */
78438889Sjdp	 "IMMED_LO32",		/* name */
78538889Sjdp	 false,			/* partial_inplace */
78638889Sjdp	 0,			/* src_mask */
78738889Sjdp	 0,			/* dst_mask */
78838889Sjdp	 false),		/* pcrel_offset */
78938889Sjdp
79077303Sobrien  /* Misc ELF relocations.  */
79138889Sjdp
79238889Sjdp  /* A dynamic relocation to copy the target into our .dynbss section.  */
79338889Sjdp  /* Not generated, as all Alpha objects use PIC, so it is not needed.  It
79438889Sjdp     is present because every other ELF has one, but should not be used
79538889Sjdp     because .dynbss is an ugly thing.  */
79633965Sjdp  HOWTO (R_ALPHA_COPY,
79733965Sjdp	 0,
79833965Sjdp	 0,
79933965Sjdp	 0,
80033965Sjdp	 false,
80133965Sjdp	 0,
80233965Sjdp	 complain_overflow_dont,
80333965Sjdp	 bfd_elf_generic_reloc,
80433965Sjdp	 "COPY",
80533965Sjdp	 false,
80633965Sjdp	 0,
80733965Sjdp	 0,
80833965Sjdp	 true),
80933965Sjdp
81038889Sjdp  /* A dynamic relocation for a .got entry.  */
81133965Sjdp  HOWTO (R_ALPHA_GLOB_DAT,
81233965Sjdp	 0,
81333965Sjdp	 0,
81433965Sjdp	 0,
81533965Sjdp	 false,
81633965Sjdp	 0,
81733965Sjdp	 complain_overflow_dont,
81833965Sjdp	 bfd_elf_generic_reloc,
81933965Sjdp	 "GLOB_DAT",
82033965Sjdp	 false,
82133965Sjdp	 0,
82233965Sjdp	 0,
82333965Sjdp	 true),
82433965Sjdp
82538889Sjdp  /* A dynamic relocation for a .plt entry.  */
82633965Sjdp  HOWTO (R_ALPHA_JMP_SLOT,
82733965Sjdp	 0,
82833965Sjdp	 0,
82933965Sjdp	 0,
83033965Sjdp	 false,
83133965Sjdp	 0,
83233965Sjdp	 complain_overflow_dont,
83333965Sjdp	 bfd_elf_generic_reloc,
83433965Sjdp	 "JMP_SLOT",
83533965Sjdp	 false,
83633965Sjdp	 0,
83733965Sjdp	 0,
83833965Sjdp	 true),
83933965Sjdp
84038889Sjdp  /* A dynamic relocation to add the base of the DSO to a 64-bit field.  */
84133965Sjdp  HOWTO (R_ALPHA_RELATIVE,
84233965Sjdp	 0,
84333965Sjdp	 0,
84433965Sjdp	 0,
84533965Sjdp	 false,
84633965Sjdp	 0,
84733965Sjdp	 complain_overflow_dont,
84833965Sjdp	 bfd_elf_generic_reloc,
84933965Sjdp	 "RELATIVE",
85033965Sjdp	 false,
85133965Sjdp	 0,
85233965Sjdp	 0,
85333965Sjdp	 true)
85433965Sjdp};
85533965Sjdp
85633965Sjdp/* A relocation function which doesn't do anything.  */
85733965Sjdp
85833965Sjdpstatic bfd_reloc_status_type
85933965Sjdpelf64_alpha_reloc_nil (abfd, reloc, sym, data, sec, output_bfd, error_message)
86033965Sjdp     bfd *abfd;
86133965Sjdp     arelent *reloc;
86233965Sjdp     asymbol *sym;
86333965Sjdp     PTR data;
86433965Sjdp     asection *sec;
86533965Sjdp     bfd *output_bfd;
86633965Sjdp     char **error_message;
86733965Sjdp{
86833965Sjdp  if (output_bfd)
86933965Sjdp    reloc->address += sec->output_offset;
87033965Sjdp  return bfd_reloc_ok;
87133965Sjdp}
87233965Sjdp
87333965Sjdp/* A relocation function used for an unsupported reloc.  */
87433965Sjdp
87533965Sjdpstatic bfd_reloc_status_type
87633965Sjdpelf64_alpha_reloc_bad (abfd, reloc, sym, data, sec, output_bfd, error_message)
87733965Sjdp     bfd *abfd;
87833965Sjdp     arelent *reloc;
87933965Sjdp     asymbol *sym;
88033965Sjdp     PTR data;
88133965Sjdp     asection *sec;
88233965Sjdp     bfd *output_bfd;
88333965Sjdp     char **error_message;
88433965Sjdp{
88533965Sjdp  if (output_bfd)
88633965Sjdp    reloc->address += sec->output_offset;
88733965Sjdp  return bfd_reloc_notsupported;
88833965Sjdp}
88933965Sjdp
89033965Sjdp/* Do the work of the GPDISP relocation.  */
89133965Sjdp
89233965Sjdpstatic bfd_reloc_status_type
89333965Sjdpelf64_alpha_do_reloc_gpdisp (abfd, gpdisp, p_ldah, p_lda)
89433965Sjdp     bfd *abfd;
89533965Sjdp     bfd_vma gpdisp;
89633965Sjdp     bfd_byte *p_ldah;
89733965Sjdp     bfd_byte *p_lda;
89833965Sjdp{
89933965Sjdp  bfd_reloc_status_type ret = bfd_reloc_ok;
90033965Sjdp  bfd_vma addend;
90133965Sjdp  unsigned long i_ldah, i_lda;
90233965Sjdp
90333965Sjdp  i_ldah = bfd_get_32 (abfd, p_ldah);
90433965Sjdp  i_lda = bfd_get_32 (abfd, p_lda);
90533965Sjdp
90633965Sjdp  /* Complain if the instructions are not correct.  */
90733965Sjdp  if (((i_ldah >> 26) & 0x3f) != 0x09
90833965Sjdp      || ((i_lda >> 26) & 0x3f) != 0x08)
90933965Sjdp    ret = bfd_reloc_dangerous;
91033965Sjdp
91133965Sjdp  /* Extract the user-supplied offset, mirroring the sign extensions
91233965Sjdp     that the instructions perform.  */
91333965Sjdp  addend = ((i_ldah & 0xffff) << 16) | (i_lda & 0xffff);
91433965Sjdp  addend = (addend ^ 0x80008000) - 0x80008000;
91533965Sjdp
91633965Sjdp  gpdisp += addend;
91733965Sjdp
91848850Sdfr  if ((bfd_signed_vma) gpdisp < -(bfd_signed_vma) 0x80000000
91948850Sdfr      || (bfd_signed_vma) gpdisp >= (bfd_signed_vma) 0x7fff8000)
92033965Sjdp    ret = bfd_reloc_overflow;
92133965Sjdp
92233965Sjdp  /* compensate for the sign extension again.  */
92333965Sjdp  i_ldah = ((i_ldah & 0xffff0000)
92433965Sjdp	    | (((gpdisp >> 16) + ((gpdisp >> 15) & 1)) & 0xffff));
92533965Sjdp  i_lda = (i_lda & 0xffff0000) | (gpdisp & 0xffff);
92633965Sjdp
92733965Sjdp  bfd_put_32 (abfd, i_ldah, p_ldah);
92833965Sjdp  bfd_put_32 (abfd, i_lda, p_lda);
92933965Sjdp
93033965Sjdp  return ret;
93133965Sjdp}
93233965Sjdp
93333965Sjdp/* The special function for the GPDISP reloc.  */
93433965Sjdp
93533965Sjdpstatic bfd_reloc_status_type
93633965Sjdpelf64_alpha_reloc_gpdisp (abfd, reloc_entry, sym, data, input_section,
93733965Sjdp			  output_bfd, err_msg)
93833965Sjdp     bfd *abfd;
93933965Sjdp     arelent *reloc_entry;
94033965Sjdp     asymbol *sym;
94133965Sjdp     PTR data;
94233965Sjdp     asection *input_section;
94333965Sjdp     bfd *output_bfd;
94433965Sjdp     char **err_msg;
94533965Sjdp{
94633965Sjdp  bfd_reloc_status_type ret;
94733965Sjdp  bfd_vma gp, relocation;
94833965Sjdp  bfd_byte *p_ldah, *p_lda;
94933965Sjdp
95033965Sjdp  /* Don't do anything if we're not doing a final link.  */
95133965Sjdp  if (output_bfd)
95233965Sjdp    {
95333965Sjdp      reloc_entry->address += input_section->output_offset;
95433965Sjdp      return bfd_reloc_ok;
95533965Sjdp    }
95633965Sjdp
95733965Sjdp  if (reloc_entry->address > input_section->_cooked_size ||
95833965Sjdp      reloc_entry->address + reloc_entry->addend > input_section->_cooked_size)
95933965Sjdp    return bfd_reloc_outofrange;
96033965Sjdp
96133965Sjdp  /* The gp used in the portion of the output object to which this
96233965Sjdp     input object belongs is cached on the input bfd.  */
96333965Sjdp  gp = _bfd_get_gp_value (abfd);
96433965Sjdp
96533965Sjdp  relocation = (input_section->output_section->vma
96633965Sjdp		+ input_section->output_offset
96733965Sjdp		+ reloc_entry->address);
96833965Sjdp
96933965Sjdp  p_ldah = (bfd_byte *) data + reloc_entry->address;
97033965Sjdp  p_lda = p_ldah + reloc_entry->addend;
97133965Sjdp
97233965Sjdp  ret = elf64_alpha_do_reloc_gpdisp (abfd, gp - relocation, p_ldah, p_lda);
97333965Sjdp
97433965Sjdp  /* Complain if the instructions are not correct.  */
97533965Sjdp  if (ret == bfd_reloc_dangerous)
97660510Sobrien    *err_msg = _("GPDISP relocation did not find ldah and lda instructions");
97733965Sjdp
97833965Sjdp  return ret;
97933965Sjdp}
98033965Sjdp
98133965Sjdp/* A mapping from BFD reloc types to Alpha ELF reloc types.  */
98233965Sjdp
98333965Sjdpstruct elf_reloc_map
98433965Sjdp{
98533965Sjdp  bfd_reloc_code_real_type bfd_reloc_val;
98633965Sjdp  int elf_reloc_val;
98733965Sjdp};
98833965Sjdp
98933965Sjdpstatic const struct elf_reloc_map elf64_alpha_reloc_map[] =
99033965Sjdp{
99133965Sjdp  {BFD_RELOC_NONE,		R_ALPHA_NONE},
99233965Sjdp  {BFD_RELOC_32,		R_ALPHA_REFLONG},
99333965Sjdp  {BFD_RELOC_64,		R_ALPHA_REFQUAD},
99433965Sjdp  {BFD_RELOC_CTOR,		R_ALPHA_REFQUAD},
99533965Sjdp  {BFD_RELOC_GPREL32,		R_ALPHA_GPREL32},
99633965Sjdp  {BFD_RELOC_ALPHA_ELF_LITERAL,	R_ALPHA_LITERAL},
99733965Sjdp  {BFD_RELOC_ALPHA_LITUSE,	R_ALPHA_LITUSE},
99833965Sjdp  {BFD_RELOC_ALPHA_GPDISP,	R_ALPHA_GPDISP},
99933965Sjdp  {BFD_RELOC_23_PCREL_S2,	R_ALPHA_BRADDR},
100033965Sjdp  {BFD_RELOC_ALPHA_HINT,	R_ALPHA_HINT},
100133965Sjdp  {BFD_RELOC_16_PCREL,		R_ALPHA_SREL16},
100233965Sjdp  {BFD_RELOC_32_PCREL,		R_ALPHA_SREL32},
100333965Sjdp  {BFD_RELOC_64_PCREL,		R_ALPHA_SREL64},
100460510Sobrien
100560510Sobrien/* The BFD_RELOC_ALPHA_USER_* relocations are used by the assembler to process
100660510Sobrien   the explicit !<reloc>!sequence relocations, and are mapped into the normal
100777303Sobrien   relocations at the end of processing.  */
100860510Sobrien  {BFD_RELOC_ALPHA_USER_LITERAL,	R_ALPHA_LITERAL},
100960510Sobrien  {BFD_RELOC_ALPHA_USER_LITUSE_BASE,	R_ALPHA_LITUSE},
101060510Sobrien  {BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF,	R_ALPHA_LITUSE},
101160510Sobrien  {BFD_RELOC_ALPHA_USER_LITUSE_JSR,	R_ALPHA_LITUSE},
101260510Sobrien  {BFD_RELOC_ALPHA_USER_GPDISP,		R_ALPHA_GPDISP},
101360510Sobrien  {BFD_RELOC_ALPHA_USER_GPRELHIGH,	R_ALPHA_GPRELHIGH},
101460510Sobrien  {BFD_RELOC_ALPHA_USER_GPRELLOW,	R_ALPHA_GPRELLOW},
101533965Sjdp};
101633965Sjdp
101733965Sjdp/* Given a BFD reloc type, return a HOWTO structure.  */
101833965Sjdp
101933965Sjdpstatic reloc_howto_type *
102033965Sjdpelf64_alpha_bfd_reloc_type_lookup (abfd, code)
102133965Sjdp     bfd *abfd;
102233965Sjdp     bfd_reloc_code_real_type code;
102333965Sjdp{
102433965Sjdp  const struct elf_reloc_map *i, *e;
102533965Sjdp  i = e = elf64_alpha_reloc_map;
102633965Sjdp  e += sizeof (elf64_alpha_reloc_map) / sizeof (struct elf_reloc_map);
102733965Sjdp  for (; i != e; ++i)
102833965Sjdp    {
102933965Sjdp      if (i->bfd_reloc_val == code)
103033965Sjdp	return &elf64_alpha_howto_table[i->elf_reloc_val];
103133965Sjdp    }
103233965Sjdp  return 0;
103333965Sjdp}
103433965Sjdp
103533965Sjdp/* Given an Alpha ELF reloc type, fill in an arelent structure.  */
103633965Sjdp
103733965Sjdpstatic void
103833965Sjdpelf64_alpha_info_to_howto (abfd, cache_ptr, dst)
103933965Sjdp     bfd *abfd;
104033965Sjdp     arelent *cache_ptr;
104133965Sjdp     Elf64_Internal_Rela *dst;
104233965Sjdp{
104333965Sjdp  unsigned r_type;
104433965Sjdp
104533965Sjdp  r_type = ELF64_R_TYPE(dst->r_info);
104633965Sjdp  BFD_ASSERT (r_type < (unsigned int) R_ALPHA_max);
104733965Sjdp  cache_ptr->howto = &elf64_alpha_howto_table[r_type];
104833965Sjdp}
104933965Sjdp
105077303Sobrien/* These functions do relaxation for Alpha ELF.
105160510Sobrien
105260510Sobrien   Currently I'm only handling what I can do with existing compiler
105360510Sobrien   and assembler support, which means no instructions are removed,
105460510Sobrien   though some may be nopped.  At this time GCC does not emit enough
105560510Sobrien   information to do all of the relaxing that is possible.  It will
105660510Sobrien   take some not small amount of work for that to happen.
105760510Sobrien
105860510Sobrien   There are a couple of interesting papers that I once read on this
105960510Sobrien   subject, that I cannot find references to at the moment, that
106060510Sobrien   related to Alpha in particular.  They are by David Wall, then of
106160510Sobrien   DEC WRL.  */
106260510Sobrien
106360510Sobrien#define OP_LDA		0x08
106460510Sobrien#define OP_LDAH		0x09
106560510Sobrien#define INSN_JSR	0x68004000
106660510Sobrien#define INSN_JSR_MASK	0xfc00c000
106760510Sobrien#define OP_LDQ		0x29
106860510Sobrien#define OP_BR		0x30
106960510Sobrien#define OP_BSR		0x34
107060510Sobrien#define INSN_UNOP	0x2fe00000
107160510Sobrien
107260510Sobrienstruct alpha_relax_info
107360510Sobrien{
107460510Sobrien  bfd *abfd;
107560510Sobrien  asection *sec;
107660510Sobrien  bfd_byte *contents;
107760510Sobrien  Elf_Internal_Rela *relocs, *relend;
107860510Sobrien  struct bfd_link_info *link_info;
107960510Sobrien  boolean changed_contents;
108060510Sobrien  boolean changed_relocs;
108160510Sobrien  bfd_vma gp;
108260510Sobrien  bfd *gotobj;
108360510Sobrien  asection *tsec;
108460510Sobrien  struct alpha_elf_link_hash_entry *h;
108560510Sobrien  struct alpha_elf_got_entry *gotent;
108660510Sobrien  unsigned char other;
108760510Sobrien};
108860510Sobrien
108960510Sobrienstatic Elf_Internal_Rela * elf64_alpha_relax_with_lituse
109077303Sobrien  PARAMS((struct alpha_relax_info *info, bfd_vma symval,
109160510Sobrien          Elf_Internal_Rela *irel, Elf_Internal_Rela *irelend));
109260510Sobrien
109360510Sobrienstatic boolean elf64_alpha_relax_without_lituse
109477303Sobrien  PARAMS((struct alpha_relax_info *info, bfd_vma symval,
109560510Sobrien          Elf_Internal_Rela *irel));
109660510Sobrien
109760510Sobrienstatic bfd_vma elf64_alpha_relax_opt_call
109860510Sobrien  PARAMS((struct alpha_relax_info *info, bfd_vma symval));
109960510Sobrien
110060510Sobrienstatic boolean elf64_alpha_relax_section
110160510Sobrien  PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
110260510Sobrien	  boolean *again));
110360510Sobrien
110460510Sobrienstatic Elf_Internal_Rela *
110560510Sobrienelf64_alpha_find_reloc_at_ofs (rel, relend, offset, type)
110660510Sobrien     Elf_Internal_Rela *rel, *relend;
110760510Sobrien     bfd_vma offset;
110860510Sobrien     int type;
110960510Sobrien{
111060510Sobrien  while (rel < relend)
111160510Sobrien    {
111260510Sobrien      if (rel->r_offset == offset && ELF64_R_TYPE (rel->r_info) == type)
111360510Sobrien	return rel;
111460510Sobrien      ++rel;
111560510Sobrien    }
111660510Sobrien  return NULL;
111760510Sobrien}
111860510Sobrien
111960510Sobrienstatic Elf_Internal_Rela *
112060510Sobrienelf64_alpha_relax_with_lituse (info, symval, irel, irelend)
112160510Sobrien     struct alpha_relax_info *info;
112260510Sobrien     bfd_vma symval;
112360510Sobrien     Elf_Internal_Rela *irel, *irelend;
112460510Sobrien{
112560510Sobrien  Elf_Internal_Rela *urel;
112660510Sobrien  int flags, count, i;
112760510Sobrien  bfd_signed_vma disp;
112860510Sobrien  boolean fits16;
112960510Sobrien  boolean fits32;
113060510Sobrien  boolean lit_reused = false;
113160510Sobrien  boolean all_optimized = true;
113260510Sobrien  unsigned int lit_insn;
113360510Sobrien
113460510Sobrien  lit_insn = bfd_get_32 (info->abfd, info->contents + irel->r_offset);
113560510Sobrien  if (lit_insn >> 26 != OP_LDQ)
113660510Sobrien    {
113760510Sobrien      ((*_bfd_error_handler)
113860510Sobrien       ("%s: %s+0x%lx: warning: LITERAL relocation against unexpected insn",
113960510Sobrien	bfd_get_filename (info->abfd), info->sec->name,
114060510Sobrien	(unsigned long)irel->r_offset));
114160510Sobrien      return irel;
114260510Sobrien    }
114360510Sobrien
114460510Sobrien  /* Summarize how this particular LITERAL is used.  */
114560510Sobrien  for (urel = irel+1, flags = count = 0; urel < irelend; ++urel, ++count)
114660510Sobrien    {
114760510Sobrien      if (ELF64_R_TYPE (urel->r_info) != R_ALPHA_LITUSE)
114860510Sobrien	break;
114960510Sobrien      if (urel->r_addend >= 0 && urel->r_addend <= 3)
115060510Sobrien	flags |= 1 << urel->r_addend;
115160510Sobrien    }
115260510Sobrien
115377303Sobrien  /* A little preparation for the loop...  */
115460510Sobrien  disp = symval - info->gp;
115560510Sobrien
115660510Sobrien  for (urel = irel+1, i = 0; i < count; ++i, ++urel)
115760510Sobrien    {
115860510Sobrien      unsigned int insn;
115977303Sobrien      int insn_disp;
116077303Sobrien      bfd_signed_vma xdisp;
116177303Sobrien
116260510Sobrien      insn = bfd_get_32 (info->abfd, info->contents + urel->r_offset);
116360510Sobrien
116460510Sobrien      switch (urel->r_addend)
116560510Sobrien	{
116660510Sobrien	default: /* 0 = ADDRESS FORMAT */
116760510Sobrien	  /* This type is really just a placeholder to note that all
116860510Sobrien	     uses cannot be optimized, but to still allow some.  */
116960510Sobrien	  all_optimized = false;
117060510Sobrien	  break;
117160510Sobrien
117260510Sobrien	case 1: /* MEM FORMAT */
117360510Sobrien	  /* We can always optimize 16-bit displacements.  */
117477303Sobrien
117577303Sobrien	  /* Extract the displacement from the instruction, sign-extending
117677303Sobrien	     it if necessary, then test whether it is within 16 or 32 bits
117777303Sobrien	     displacement from GP.  */
117877303Sobrien	  insn_disp = insn & 0x0000ffff;
117977303Sobrien	  if (insn_disp & 0x00008000)
118077303Sobrien	    insn_disp |= 0xffff0000;  /* Negative: sign-extend.  */
118177303Sobrien
118277303Sobrien	  xdisp = disp + insn_disp;
118377303Sobrien	  fits16 = (xdisp >= - (bfd_signed_vma) 0x00008000 && xdisp < 0x00008000);
118477303Sobrien	  fits32 = (xdisp >= - (bfd_signed_vma) 0x80000000 && xdisp < 0x7fff8000);
118577303Sobrien
118660510Sobrien	  if (fits16)
118760510Sobrien	    {
118877303Sobrien	      /* Take the op code and dest from this insn, take the base
118960510Sobrien		 register from the literal insn.  Leave the offset alone.  */
119077303Sobrien	      insn = (insn & 0xffe0ffff) | (lit_insn & 0x001f0000);
119160510Sobrien	      urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
119260510Sobrien					   R_ALPHA_GPRELLOW);
119360510Sobrien	      urel->r_addend = irel->r_addend;
119460510Sobrien	      info->changed_relocs = true;
119560510Sobrien
119660510Sobrien	      bfd_put_32 (info->abfd, insn, info->contents + urel->r_offset);
119760510Sobrien	      info->changed_contents = true;
119860510Sobrien	    }
119960510Sobrien
120060510Sobrien	  /* If all mem+byte, we can optimize 32-bit mem displacements.  */
120160510Sobrien	  else if (fits32 && !(flags & ~6))
120260510Sobrien	    {
120377303Sobrien	      /* FIXME: sanity check that lit insn Ra is mem insn Rb.  */
120460510Sobrien
120560510Sobrien	      irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
120660510Sobrien					   R_ALPHA_GPRELHIGH);
120760510Sobrien	      lit_insn = (OP_LDAH << 26) | (lit_insn & 0x03ff0000);
120860510Sobrien	      bfd_put_32 (info->abfd, lit_insn,
120960510Sobrien			  info->contents + irel->r_offset);
121060510Sobrien	      lit_reused = true;
121160510Sobrien	      info->changed_contents = true;
121260510Sobrien
121360510Sobrien	      urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
121460510Sobrien					   R_ALPHA_GPRELLOW);
121560510Sobrien	      urel->r_addend = irel->r_addend;
121660510Sobrien	      info->changed_relocs = true;
121760510Sobrien	    }
121860510Sobrien	  else
121960510Sobrien	    all_optimized = false;
122060510Sobrien	  break;
122160510Sobrien
122260510Sobrien	case 2: /* BYTE OFFSET FORMAT */
122360510Sobrien	  /* We can always optimize byte instructions.  */
122460510Sobrien
122560510Sobrien	  /* FIXME: sanity check the insn for byte op.  Check that the
122660510Sobrien	     literal dest reg is indeed Rb in the byte insn.  */
122760510Sobrien
122860510Sobrien	  insn = (insn & ~0x001ff000) | ((symval & 7) << 13) | 0x1000;
122960510Sobrien
123060510Sobrien	  urel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
123160510Sobrien	  urel->r_addend = 0;
123260510Sobrien	  info->changed_relocs = true;
123360510Sobrien
123460510Sobrien	  bfd_put_32 (info->abfd, insn, info->contents + urel->r_offset);
123560510Sobrien	  info->changed_contents = true;
123660510Sobrien	  break;
123760510Sobrien
123860510Sobrien	case 3: /* CALL FORMAT */
123960510Sobrien	  {
124060510Sobrien	    /* If not zero, place to jump without needing pv.  */
124160510Sobrien	    bfd_vma optdest = elf64_alpha_relax_opt_call (info, symval);
124260510Sobrien	    bfd_vma org = (info->sec->output_section->vma
124360510Sobrien			   + info->sec->output_offset
124460510Sobrien			   + urel->r_offset + 4);
124560510Sobrien	    bfd_signed_vma odisp;
124660510Sobrien
124760510Sobrien	    odisp = (optdest ? optdest : symval) - org;
124860510Sobrien	    if (odisp >= -0x400000 && odisp < 0x400000)
124960510Sobrien	      {
125060510Sobrien		Elf_Internal_Rela *xrel;
125160510Sobrien
125277303Sobrien		/* Preserve branch prediction call stack when possible.  */
125360510Sobrien		if ((insn & INSN_JSR_MASK) == INSN_JSR)
125460510Sobrien		  insn = (OP_BSR << 26) | (insn & 0x03e00000);
125560510Sobrien		else
125660510Sobrien		  insn = (OP_BR << 26) | (insn & 0x03e00000);
125777303Sobrien
125860510Sobrien		urel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
125960510Sobrien					     R_ALPHA_BRADDR);
126060510Sobrien		urel->r_addend = irel->r_addend;
126160510Sobrien
126260510Sobrien		if (optdest)
126360510Sobrien		  urel->r_addend += optdest - symval;
126460510Sobrien		else
126560510Sobrien		  all_optimized = false;
126660510Sobrien
126760510Sobrien		bfd_put_32 (info->abfd, insn, info->contents + urel->r_offset);
126860510Sobrien
126960510Sobrien		/* Kill any HINT reloc that might exist for this insn.  */
127060510Sobrien		xrel = (elf64_alpha_find_reloc_at_ofs
127177303Sobrien			(info->relocs, info->relend, urel->r_offset,
127260510Sobrien			 R_ALPHA_HINT));
127360510Sobrien		if (xrel)
127460510Sobrien		  xrel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
127560510Sobrien
127660510Sobrien		info->changed_contents = true;
127760510Sobrien		info->changed_relocs = true;
127860510Sobrien	      }
127960510Sobrien	    else
128060510Sobrien	      all_optimized = false;
128160510Sobrien
128260510Sobrien	    /* ??? If target gp == current gp we can eliminate the gp reload.
128360510Sobrien	       This does depend on every place a gp could be reloaded will
128460510Sobrien	       be, which currently happens for all code produced by gcc, but
128560510Sobrien	       not necessarily by hand-coded assembly, or if sibling calls
128677303Sobrien	       are enabled in gcc.
128760510Sobrien
128860510Sobrien	       Perhaps conditionalize this on a flag being set in the target
128960510Sobrien	       object file's header, and have gcc set it?  */
129060510Sobrien	  }
129160510Sobrien	  break;
129260510Sobrien	}
129360510Sobrien    }
129460510Sobrien
129560510Sobrien  /* If all cases were optimized, we can reduce the use count on this
129660510Sobrien     got entry by one, possibly eliminating it.  */
129760510Sobrien  if (all_optimized)
129860510Sobrien    {
129960510Sobrien      info->gotent->use_count -= 1;
130060510Sobrien      alpha_elf_tdata (info->gotent->gotobj)->total_got_entries -= 1;
130160510Sobrien      if (!info->h)
130260510Sobrien	alpha_elf_tdata (info->gotent->gotobj)->n_local_got_entries -= 1;
130360510Sobrien
130460510Sobrien      /* If the literal instruction is no longer needed (it may have been
130560510Sobrien	 reused.  We can eliminate it.
130660510Sobrien	 ??? For now, I don't want to deal with compacting the section,
130760510Sobrien	 so just nop it out.  */
130860510Sobrien      if (!lit_reused)
130960510Sobrien	{
131060510Sobrien	  irel->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
131160510Sobrien	  info->changed_relocs = true;
131260510Sobrien
131360510Sobrien	  bfd_put_32 (info->abfd, INSN_UNOP, info->contents + irel->r_offset);
131460510Sobrien	  info->changed_contents = true;
131560510Sobrien	}
131660510Sobrien    }
131760510Sobrien
131860510Sobrien  return irel + count;
131960510Sobrien}
132060510Sobrien
132160510Sobrienstatic bfd_vma
132260510Sobrienelf64_alpha_relax_opt_call (info, symval)
132360510Sobrien     struct alpha_relax_info *info;
132460510Sobrien     bfd_vma symval;
132560510Sobrien{
132660510Sobrien  /* If the function has the same gp, and we can identify that the
132760510Sobrien     function does not use its function pointer, we can eliminate the
132860510Sobrien     address load.  */
132960510Sobrien
133060510Sobrien  /* If the symbol is marked NOPV, we are being told the function never
133160510Sobrien     needs its procedure value.  */
133277303Sobrien  if ((info->other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_NOPV)
133360510Sobrien    return symval;
133460510Sobrien
133560510Sobrien  /* If the symbol is marked STD_GP, we are being told the function does
133677303Sobrien     a normal ldgp in the first two words.  */
133777303Sobrien  else if ((info->other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_STD_GPLOAD)
133860510Sobrien    ;
133960510Sobrien
134060510Sobrien  /* Otherwise, we may be able to identify a GP load in the first two
134160510Sobrien     words, which we can then skip.  */
134277303Sobrien  else
134360510Sobrien    {
134460510Sobrien      Elf_Internal_Rela *tsec_relocs, *tsec_relend, *tsec_free, *gpdisp;
134560510Sobrien      bfd_vma ofs;
134660510Sobrien
134777303Sobrien      /* Load the relocations from the section that the target symbol is in.  */
134860510Sobrien      if (info->sec == info->tsec)
134960510Sobrien	{
135060510Sobrien	  tsec_relocs = info->relocs;
135160510Sobrien	  tsec_relend = info->relend;
135260510Sobrien	  tsec_free = NULL;
135360510Sobrien	}
135460510Sobrien      else
135560510Sobrien	{
135660510Sobrien	  tsec_relocs = (_bfd_elf64_link_read_relocs
135760510Sobrien		         (info->abfd, info->tsec, (PTR) NULL,
135860510Sobrien			 (Elf_Internal_Rela *) NULL,
135960510Sobrien			 info->link_info->keep_memory));
136060510Sobrien	  if (tsec_relocs == NULL)
136160510Sobrien	    return 0;
136260510Sobrien	  tsec_relend = tsec_relocs + info->tsec->reloc_count;
136360510Sobrien	  tsec_free = (info->link_info->keep_memory ? NULL : tsec_relocs);
136460510Sobrien	}
136560510Sobrien
136660510Sobrien      /* Recover the symbol's offset within the section.  */
136760510Sobrien      ofs = (symval - info->tsec->output_section->vma
136860510Sobrien	     - info->tsec->output_offset);
136977303Sobrien
137060510Sobrien      /* Look for a GPDISP reloc.  */
137160510Sobrien      gpdisp = (elf64_alpha_find_reloc_at_ofs
137260510Sobrien		(tsec_relocs, tsec_relend, ofs, R_ALPHA_GPDISP));
137360510Sobrien
137460510Sobrien      if (!gpdisp || gpdisp->r_addend != 4)
137560510Sobrien	{
137660510Sobrien	  if (tsec_free)
137760510Sobrien	    free (tsec_free);
137860510Sobrien	  return 0;
137960510Sobrien	}
138060510Sobrien      if (tsec_free)
138160510Sobrien        free (tsec_free);
138260510Sobrien    }
138360510Sobrien
138477303Sobrien  /* We've now determined that we can skip an initial gp load.  Verify
138560510Sobrien     that the call and the target use the same gp.   */
138660510Sobrien  if (info->link_info->hash->creator != info->tsec->owner->xvec
138760510Sobrien      || info->gotobj != alpha_elf_tdata (info->tsec->owner)->gotobj)
138860510Sobrien    return 0;
138960510Sobrien
139060510Sobrien  return symval + 8;
139160510Sobrien}
139260510Sobrien
139360510Sobrienstatic boolean
139460510Sobrienelf64_alpha_relax_without_lituse (info, symval, irel)
139560510Sobrien     struct alpha_relax_info *info;
139660510Sobrien     bfd_vma symval;
139760510Sobrien     Elf_Internal_Rela *irel;
139860510Sobrien{
139960510Sobrien  unsigned int insn;
140060510Sobrien  bfd_signed_vma disp;
140160510Sobrien
140260510Sobrien  /* Get the instruction.  */
140360510Sobrien  insn = bfd_get_32 (info->abfd, info->contents + irel->r_offset);
140460510Sobrien
140560510Sobrien  if (insn >> 26 != OP_LDQ)
140660510Sobrien    {
140760510Sobrien      ((*_bfd_error_handler)
140860510Sobrien       ("%s: %s+0x%lx: warning: LITERAL relocation against unexpected insn",
140960510Sobrien	bfd_get_filename (info->abfd), info->sec->name,
141060510Sobrien	(unsigned long) irel->r_offset));
141160510Sobrien      return true;
141260510Sobrien    }
141360510Sobrien
141460510Sobrien  /* So we aren't told much.  Do what we can with the address load and
141560510Sobrien     fake the rest.  All of the optimizations here require that the
141660510Sobrien     offset from the GP fit in 16 bits.  */
141760510Sobrien
141860510Sobrien  disp = symval - info->gp;
141960510Sobrien  if (disp < -0x8000 || disp >= 0x8000)
142060510Sobrien    return true;
142160510Sobrien
142260510Sobrien  /* On the LITERAL instruction itself, consider exchanging
142360510Sobrien     `ldq R,X(gp)' for `lda R,Y(gp)'.  */
142460510Sobrien
142560510Sobrien  insn = (OP_LDA << 26) | (insn & 0x03ff0000);
142660510Sobrien  bfd_put_32 (info->abfd, insn, info->contents + irel->r_offset);
142760510Sobrien  info->changed_contents = true;
142860510Sobrien
142960510Sobrien  irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), R_ALPHA_GPRELLOW);
143060510Sobrien  info->changed_relocs = true;
143160510Sobrien
143260510Sobrien  /* Reduce the use count on this got entry by one, possibly
143360510Sobrien     eliminating it.  */
143460510Sobrien  info->gotent->use_count -= 1;
143560510Sobrien  alpha_elf_tdata (info->gotent->gotobj)->total_got_entries -= 1;
143660510Sobrien  if (!info->h)
143760510Sobrien    alpha_elf_tdata (info->gotent->gotobj)->n_local_got_entries -= 1;
143860510Sobrien
143960510Sobrien  /* ??? Search forward through this basic block looking for insns
144060510Sobrien     that use the target register.  Stop after an insn modifying the
144160510Sobrien     register is seen, or after a branch or call.
144260510Sobrien
144360510Sobrien     Any such memory load insn may be substituted by a load directly
144460510Sobrien     off the GP.  This allows the memory load insn to be issued before
144577303Sobrien     the calculated GP register would otherwise be ready.
144660510Sobrien
144760510Sobrien     Any such jsr insn can be replaced by a bsr if it is in range.
144860510Sobrien
144960510Sobrien     This would mean that we'd have to _add_ relocations, the pain of
145060510Sobrien     which gives one pause.  */
145160510Sobrien
145260510Sobrien  return true;
145360510Sobrien}
145460510Sobrien
145560510Sobrienstatic boolean
145660510Sobrienelf64_alpha_relax_section (abfd, sec, link_info, again)
145760510Sobrien     bfd *abfd;
145860510Sobrien     asection *sec;
145960510Sobrien     struct bfd_link_info *link_info;
146060510Sobrien     boolean *again;
146160510Sobrien{
146260510Sobrien  Elf_Internal_Shdr *symtab_hdr;
146360510Sobrien  Elf_Internal_Rela *internal_relocs;
146460510Sobrien  Elf_Internal_Rela *free_relocs = NULL;
146560510Sobrien  Elf_Internal_Rela *irel, *irelend;
146660510Sobrien  bfd_byte *free_contents = NULL;
146760510Sobrien  Elf64_External_Sym *extsyms = NULL;
146860510Sobrien  Elf64_External_Sym *free_extsyms = NULL;
146960510Sobrien  struct alpha_elf_got_entry **local_got_entries;
147060510Sobrien  struct alpha_relax_info info;
147160510Sobrien
147260510Sobrien  /* We are not currently changing any sizes, so only one pass.  */
147360510Sobrien  *again = false;
147460510Sobrien
147560510Sobrien  if (link_info->relocateable
147660510Sobrien      || (sec->flags & SEC_RELOC) == 0
147760510Sobrien      || sec->reloc_count == 0)
147860510Sobrien    return true;
147960510Sobrien
148060510Sobrien  /* If this is the first time we have been called for this section,
148160510Sobrien     initialize the cooked size.  */
148260510Sobrien  if (sec->_cooked_size == 0)
148360510Sobrien    sec->_cooked_size = sec->_raw_size;
148460510Sobrien
148560510Sobrien  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
148660510Sobrien  local_got_entries = alpha_elf_tdata(abfd)->local_got_entries;
148760510Sobrien
148860510Sobrien  /* Load the relocations for this section.  */
148960510Sobrien  internal_relocs = (_bfd_elf64_link_read_relocs
149060510Sobrien		     (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
149160510Sobrien		      link_info->keep_memory));
149260510Sobrien  if (internal_relocs == NULL)
149360510Sobrien    goto error_return;
149460510Sobrien  if (! link_info->keep_memory)
149560510Sobrien    free_relocs = internal_relocs;
149660510Sobrien
149777303Sobrien  memset(&info, 0, sizeof (info));
149860510Sobrien  info.abfd = abfd;
149960510Sobrien  info.sec = sec;
150060510Sobrien  info.link_info = link_info;
150160510Sobrien  info.relocs = internal_relocs;
150260510Sobrien  info.relend = irelend = internal_relocs + sec->reloc_count;
150360510Sobrien
150460510Sobrien  /* Find the GP for this object.  */
150560510Sobrien  info.gotobj = alpha_elf_tdata (abfd)->gotobj;
150660510Sobrien  if (info.gotobj)
150760510Sobrien    {
150860510Sobrien      asection *sgot = alpha_elf_tdata (info.gotobj)->got;
150960510Sobrien      info.gp = _bfd_get_gp_value (info.gotobj);
151060510Sobrien      if (info.gp == 0)
151160510Sobrien	{
151260510Sobrien	  info.gp = (sgot->output_section->vma
151360510Sobrien		     + sgot->output_offset
151460510Sobrien		     + 0x8000);
151560510Sobrien	  _bfd_set_gp_value (info.gotobj, info.gp);
151660510Sobrien	}
151760510Sobrien    }
151860510Sobrien
151960510Sobrien  for (irel = internal_relocs; irel < irelend; irel++)
152060510Sobrien    {
152160510Sobrien      bfd_vma symval;
152260510Sobrien      Elf_Internal_Sym isym;
152360510Sobrien      struct alpha_elf_got_entry *gotent;
152460510Sobrien
152560510Sobrien      if (ELF64_R_TYPE (irel->r_info) != (int) R_ALPHA_LITERAL)
152660510Sobrien	continue;
152760510Sobrien
152860510Sobrien      /* Get the section contents.  */
152960510Sobrien      if (info.contents == NULL)
153060510Sobrien	{
153160510Sobrien	  if (elf_section_data (sec)->this_hdr.contents != NULL)
153260510Sobrien	    info.contents = elf_section_data (sec)->this_hdr.contents;
153360510Sobrien	  else
153460510Sobrien	    {
153560510Sobrien	      info.contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
153660510Sobrien	      if (info.contents == NULL)
153760510Sobrien		goto error_return;
153860510Sobrien	      free_contents = info.contents;
153960510Sobrien
154060510Sobrien	      if (! bfd_get_section_contents (abfd, sec, info.contents,
154160510Sobrien					      (file_ptr) 0, sec->_raw_size))
154260510Sobrien		goto error_return;
154360510Sobrien	    }
154460510Sobrien	}
154560510Sobrien
154660510Sobrien      /* Read this BFD's symbols if we haven't done so already.  */
154760510Sobrien      if (extsyms == NULL)
154860510Sobrien	{
154960510Sobrien	  if (symtab_hdr->contents != NULL)
155060510Sobrien	    extsyms = (Elf64_External_Sym *) symtab_hdr->contents;
155160510Sobrien	  else
155260510Sobrien	    {
155360510Sobrien	      extsyms = ((Elf64_External_Sym *)
155460510Sobrien			 bfd_malloc (symtab_hdr->sh_size));
155560510Sobrien	      if (extsyms == NULL)
155660510Sobrien		goto error_return;
155760510Sobrien	      free_extsyms = extsyms;
155860510Sobrien	      if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
155960510Sobrien		  || (bfd_read (extsyms, 1, symtab_hdr->sh_size, abfd)
156060510Sobrien		      != symtab_hdr->sh_size))
156160510Sobrien		goto error_return;
156260510Sobrien	    }
156360510Sobrien	}
156460510Sobrien
156560510Sobrien      /* Get the value of the symbol referred to by the reloc.  */
156660510Sobrien      if (ELF64_R_SYM (irel->r_info) < symtab_hdr->sh_info)
156760510Sobrien	{
156860510Sobrien	  /* A local symbol.  */
156960510Sobrien	  bfd_elf64_swap_symbol_in (abfd,
157060510Sobrien				    extsyms + ELF64_R_SYM (irel->r_info),
157160510Sobrien				    &isym);
157260510Sobrien	  if (isym.st_shndx == SHN_UNDEF)
157360510Sobrien	    info.tsec = bfd_und_section_ptr;
157460510Sobrien	  else if (isym.st_shndx > 0 && isym.st_shndx < SHN_LORESERVE)
157560510Sobrien	    info.tsec = bfd_section_from_elf_index (abfd, isym.st_shndx);
157660510Sobrien	  else if (isym.st_shndx == SHN_ABS)
157760510Sobrien	    info.tsec = bfd_abs_section_ptr;
157860510Sobrien	  else if (isym.st_shndx == SHN_COMMON)
157960510Sobrien	    info.tsec = bfd_com_section_ptr;
158077303Sobrien	  else
158177303Sobrien	    continue;	/* who knows.  */
158260510Sobrien
158360510Sobrien	  info.h = NULL;
158460510Sobrien	  info.other = isym.st_other;
158560510Sobrien	  gotent = local_got_entries[ELF64_R_SYM(irel->r_info)];
158660510Sobrien	  symval = isym.st_value;
158760510Sobrien	}
158860510Sobrien      else
158960510Sobrien	{
159060510Sobrien	  unsigned long indx;
159160510Sobrien	  struct alpha_elf_link_hash_entry *h;
159260510Sobrien
159360510Sobrien	  indx = ELF64_R_SYM (irel->r_info) - symtab_hdr->sh_info;
159460510Sobrien	  h = alpha_elf_sym_hashes (abfd)[indx];
159560510Sobrien	  BFD_ASSERT (h != NULL);
159660510Sobrien
159760510Sobrien	  while (h->root.root.type == bfd_link_hash_indirect
159860510Sobrien		 || h->root.root.type == bfd_link_hash_warning)
159960510Sobrien	    h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
160060510Sobrien
160160510Sobrien	  /* We can't do anthing with undefined or dynamic symbols.  */
160260510Sobrien	  if (h->root.root.type == bfd_link_hash_undefined
160360510Sobrien	      || h->root.root.type == bfd_link_hash_undefweak
160460510Sobrien	      || alpha_elf_dynamic_symbol_p (&h->root, link_info))
160560510Sobrien	    continue;
160660510Sobrien
160760510Sobrien	  info.h = h;
160860510Sobrien	  info.gotent = gotent;
160960510Sobrien	  info.tsec = h->root.root.u.def.section;
161060510Sobrien	  info.other = h->root.other;
161160510Sobrien	  gotent = h->got_entries;
161260510Sobrien	  symval = h->root.root.u.def.value;
161360510Sobrien	}
161460510Sobrien
161560510Sobrien      /* Search for the got entry to be used by this relocation.  */
161660510Sobrien      while (gotent->gotobj != info.gotobj || gotent->addend != irel->r_addend)
161760510Sobrien	gotent = gotent->next;
161860510Sobrien      info.gotent = gotent;
161960510Sobrien
162060510Sobrien      symval += info.tsec->output_section->vma + info.tsec->output_offset;
162160510Sobrien      symval += irel->r_addend;
162260510Sobrien
162360510Sobrien      BFD_ASSERT(info.gotent != NULL);
162460510Sobrien
162560510Sobrien      /* If there exist LITUSE relocations immediately following, this
162660510Sobrien	 opens up all sorts of interesting optimizations, because we
162760510Sobrien	 now know every location that this address load is used.  */
162860510Sobrien
162960510Sobrien      if (irel+1 < irelend && ELF64_R_TYPE (irel[1].r_info) == R_ALPHA_LITUSE)
163060510Sobrien	{
163160510Sobrien	  irel = elf64_alpha_relax_with_lituse (&info, symval, irel, irelend);
163260510Sobrien	  if (irel == NULL)
163360510Sobrien	    goto error_return;
163460510Sobrien	}
163560510Sobrien      else
163660510Sobrien	{
163760510Sobrien	  if (!elf64_alpha_relax_without_lituse (&info, symval, irel))
163860510Sobrien	    goto error_return;
163960510Sobrien	}
164060510Sobrien    }
164160510Sobrien
164260510Sobrien  if (!elf64_alpha_size_got_sections (abfd, link_info))
164360510Sobrien    return false;
164460510Sobrien
164560510Sobrien  if (info.changed_relocs)
164660510Sobrien    {
164760510Sobrien      elf_section_data (sec)->relocs = internal_relocs;
164860510Sobrien    }
164960510Sobrien  else if (free_relocs != NULL)
165060510Sobrien    {
165160510Sobrien      free (free_relocs);
165260510Sobrien    }
165360510Sobrien
165460510Sobrien  if (info.changed_contents)
165560510Sobrien    {
165660510Sobrien      elf_section_data (sec)->this_hdr.contents = info.contents;
165760510Sobrien    }
165860510Sobrien  else if (free_contents != NULL)
165960510Sobrien    {
166060510Sobrien      if (! link_info->keep_memory)
166160510Sobrien	free (free_contents);
166260510Sobrien      else
166360510Sobrien	{
166460510Sobrien	  /* Cache the section contents for elf_link_input_bfd.  */
166560510Sobrien	  elf_section_data (sec)->this_hdr.contents = info.contents;
166660510Sobrien	}
166760510Sobrien    }
166860510Sobrien
166960510Sobrien  if (free_extsyms != NULL)
167060510Sobrien    {
167160510Sobrien      if (! link_info->keep_memory)
167260510Sobrien	free (free_extsyms);
167360510Sobrien      else
167460510Sobrien	{
167560510Sobrien	  /* Cache the symbols for elf_link_input_bfd.  */
167660510Sobrien	  symtab_hdr->contents = extsyms;
167760510Sobrien	}
167860510Sobrien    }
167960510Sobrien
168060510Sobrien  *again = info.changed_contents || info.changed_relocs;
168160510Sobrien
168260510Sobrien  return true;
168360510Sobrien
168460510Sobrien error_return:
168560510Sobrien  if (free_relocs != NULL)
168660510Sobrien    free (free_relocs);
168760510Sobrien  if (free_contents != NULL)
168860510Sobrien    free (free_contents);
168960510Sobrien  if (free_extsyms != NULL)
169060510Sobrien    free (free_extsyms);
169160510Sobrien  return false;
169260510Sobrien}
169360510Sobrien
169433965Sjdp/* PLT/GOT Stuff */
169533965Sjdp#define PLT_HEADER_SIZE 32
169633965Sjdp#define PLT_HEADER_WORD1	0xc3600000	/* br   $27,.+4     */
169733965Sjdp#define PLT_HEADER_WORD2	0xa77b000c	/* ldq  $27,12($27) */
169833965Sjdp#define PLT_HEADER_WORD3	0x47ff041f	/* nop              */
169933965Sjdp#define PLT_HEADER_WORD4	0x6b7b0000	/* jmp  $27,($27)   */
170033965Sjdp
170133965Sjdp#define PLT_ENTRY_SIZE 12
170238889Sjdp#define PLT_ENTRY_WORD1		0xc3800000	/* br   $28, plt0   */
170338889Sjdp#define PLT_ENTRY_WORD2		0
170438889Sjdp#define PLT_ENTRY_WORD3		0
170533965Sjdp
170633965Sjdp#define MAX_GOT_ENTRIES		(64*1024 / 8)
170733965Sjdp
170868770Sobrien#ifndef ELF_DYNAMIC_INTERPRETER
170968770Sobrien#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so"
171068770Sobrien#endif
171133965Sjdp
171233965Sjdp/* Handle an Alpha specific section when reading an object file.  This
171333965Sjdp   is called when elfcode.h finds a section with an unknown type.
171460510Sobrien   FIXME: We need to handle the SHF_ALPHA_GPREL flag, but I'm not sure
171533965Sjdp   how to.  */
171633965Sjdp
171733965Sjdpstatic boolean
171833965Sjdpelf64_alpha_section_from_shdr (abfd, hdr, name)
171933965Sjdp     bfd *abfd;
172033965Sjdp     Elf64_Internal_Shdr *hdr;
172133965Sjdp     char *name;
172233965Sjdp{
172333965Sjdp  asection *newsect;
172433965Sjdp
172533965Sjdp  /* There ought to be a place to keep ELF backend specific flags, but
172633965Sjdp     at the moment there isn't one.  We just keep track of the
172733965Sjdp     sections by their name, instead.  Fortunately, the ABI gives
172833965Sjdp     suggested names for all the MIPS specific sections, so we will
172933965Sjdp     probably get away with this.  */
173033965Sjdp  switch (hdr->sh_type)
173133965Sjdp    {
173233965Sjdp    case SHT_ALPHA_DEBUG:
173333965Sjdp      if (strcmp (name, ".mdebug") != 0)
173433965Sjdp	return false;
173533965Sjdp      break;
173633965Sjdp#ifdef ERIC_neverdef
173733965Sjdp    case SHT_ALPHA_REGINFO:
173833965Sjdp      if (strcmp (name, ".reginfo") != 0
173933965Sjdp	  || hdr->sh_size != sizeof (Elf64_External_RegInfo))
174033965Sjdp	return false;
174133965Sjdp      break;
174233965Sjdp#endif
174333965Sjdp    default:
174433965Sjdp      return false;
174533965Sjdp    }
174633965Sjdp
174733965Sjdp  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
174833965Sjdp    return false;
174933965Sjdp  newsect = hdr->bfd_section;
175033965Sjdp
175133965Sjdp  if (hdr->sh_type == SHT_ALPHA_DEBUG)
175233965Sjdp    {
175333965Sjdp      if (! bfd_set_section_flags (abfd, newsect,
175433965Sjdp				   (bfd_get_section_flags (abfd, newsect)
175533965Sjdp				    | SEC_DEBUGGING)))
175633965Sjdp	return false;
175733965Sjdp    }
175833965Sjdp
175933965Sjdp#ifdef ERIC_neverdef
176033965Sjdp  /* For a .reginfo section, set the gp value in the tdata information
176133965Sjdp     from the contents of this section.  We need the gp value while
176233965Sjdp     processing relocs, so we just get it now.  */
176333965Sjdp  if (hdr->sh_type == SHT_ALPHA_REGINFO)
176433965Sjdp    {
176533965Sjdp      Elf64_External_RegInfo ext;
176633965Sjdp      Elf64_RegInfo s;
176733965Sjdp
176833965Sjdp      if (! bfd_get_section_contents (abfd, newsect, (PTR) &ext,
176933965Sjdp				      (file_ptr) 0, sizeof ext))
177033965Sjdp	return false;
177133965Sjdp      bfd_alpha_elf64_swap_reginfo_in (abfd, &ext, &s);
177233965Sjdp      elf_gp (abfd) = s.ri_gp_value;
177333965Sjdp    }
177433965Sjdp#endif
177533965Sjdp
177633965Sjdp  return true;
177733965Sjdp}
177833965Sjdp
177933965Sjdp/* Set the correct type for an Alpha ELF section.  We do this by the
178033965Sjdp   section name, which is a hack, but ought to work.  */
178133965Sjdp
178233965Sjdpstatic boolean
178333965Sjdpelf64_alpha_fake_sections (abfd, hdr, sec)
178433965Sjdp     bfd *abfd;
178533965Sjdp     Elf64_Internal_Shdr *hdr;
178633965Sjdp     asection *sec;
178733965Sjdp{
178833965Sjdp  register const char *name;
178933965Sjdp
179033965Sjdp  name = bfd_get_section_name (abfd, sec);
179133965Sjdp
179233965Sjdp  if (strcmp (name, ".mdebug") == 0)
179333965Sjdp    {
179433965Sjdp      hdr->sh_type = SHT_ALPHA_DEBUG;
179533965Sjdp      /* In a shared object on Irix 5.3, the .mdebug section has an
179633965Sjdp         entsize of 0.  FIXME: Does this matter?  */
179733965Sjdp      if ((abfd->flags & DYNAMIC) != 0 )
179833965Sjdp	hdr->sh_entsize = 0;
179933965Sjdp      else
180033965Sjdp	hdr->sh_entsize = 1;
180133965Sjdp    }
180233965Sjdp#ifdef ERIC_neverdef
180333965Sjdp  else if (strcmp (name, ".reginfo") == 0)
180433965Sjdp    {
180533965Sjdp      hdr->sh_type = SHT_ALPHA_REGINFO;
180633965Sjdp      /* In a shared object on Irix 5.3, the .reginfo section has an
180733965Sjdp         entsize of 0x18.  FIXME: Does this matter?  */
180833965Sjdp      if ((abfd->flags & DYNAMIC) != 0)
180933965Sjdp	hdr->sh_entsize = sizeof (Elf64_External_RegInfo);
181033965Sjdp      else
181133965Sjdp	hdr->sh_entsize = 1;
181233965Sjdp
181333965Sjdp      /* Force the section size to the correct value, even if the
181433965Sjdp	 linker thinks it is larger.  The link routine below will only
181533965Sjdp	 write out this much data for .reginfo.  */
181633965Sjdp      hdr->sh_size = sec->_raw_size = sizeof (Elf64_External_RegInfo);
181733965Sjdp    }
181833965Sjdp  else if (strcmp (name, ".hash") == 0
181933965Sjdp	   || strcmp (name, ".dynamic") == 0
182033965Sjdp	   || strcmp (name, ".dynstr") == 0)
182133965Sjdp    {
182233965Sjdp      hdr->sh_entsize = 0;
182333965Sjdp      hdr->sh_info = SIZEOF_ALPHA_DYNSYM_SECNAMES;
182433965Sjdp    }
182533965Sjdp#endif
182633965Sjdp  else if (strcmp (name, ".sdata") == 0
182733965Sjdp	   || strcmp (name, ".sbss") == 0
182833965Sjdp	   || strcmp (name, ".lit4") == 0
182933965Sjdp	   || strcmp (name, ".lit8") == 0)
183033965Sjdp    hdr->sh_flags |= SHF_ALPHA_GPREL;
183133965Sjdp
183233965Sjdp  return true;
183333965Sjdp}
183433965Sjdp
183560510Sobrien/* Hook called by the linker routine which adds symbols from an object
183660510Sobrien   file.  We use it to put .comm items in .sbss, and not .bss.  */
183733965Sjdp
183860510Sobrienstatic boolean
183960510Sobrienelf64_alpha_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
184033965Sjdp     bfd *abfd;
184160510Sobrien     struct bfd_link_info *info;
184260510Sobrien     const Elf_Internal_Sym *sym;
184360510Sobrien     const char **namep;
184460510Sobrien     flagword *flagsp;
184560510Sobrien     asection **secp;
184660510Sobrien     bfd_vma *valp;
184733965Sjdp{
184860510Sobrien  if (sym->st_shndx == SHN_COMMON
184960510Sobrien      && !info->relocateable
185060510Sobrien      && sym->st_size <= bfd_get_gp_size (abfd))
185160510Sobrien    {
185260510Sobrien      /* Common symbols less than or equal to -G nn bytes are
185360510Sobrien	 automatically put into .sbss.  */
185433965Sjdp
185560510Sobrien      asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
185633965Sjdp
185760510Sobrien      if (scomm == NULL)
185860510Sobrien	{
185960510Sobrien	  scomm = bfd_make_section (abfd, ".scommon");
186060510Sobrien	  if (scomm == NULL
186160510Sobrien	      || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
186260510Sobrien						       | SEC_IS_COMMON
186360510Sobrien						       | SEC_LINKER_CREATED)))
186460510Sobrien	    return false;
186560510Sobrien	}
186633965Sjdp
186760510Sobrien      *secp = scomm;
186860510Sobrien      *valp = sym->st_size;
186933965Sjdp    }
187033965Sjdp
187160510Sobrien  return true;
187233965Sjdp}
187333965Sjdp
187433965Sjdp/* Create the .got section.  */
187533965Sjdp
187633965Sjdpstatic boolean
187733965Sjdpelf64_alpha_create_got_section(abfd, info)
187833965Sjdp     bfd *abfd;
187933965Sjdp     struct bfd_link_info *info;
188033965Sjdp{
188133965Sjdp  asection *s;
188233965Sjdp
188333965Sjdp  if (bfd_get_section_by_name (abfd, ".got"))
188433965Sjdp    return true;
188533965Sjdp
188633965Sjdp  s = bfd_make_section (abfd, ".got");
188733965Sjdp  if (s == NULL
188833965Sjdp      || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
188933965Sjdp					   | SEC_HAS_CONTENTS
189033965Sjdp					   | SEC_IN_MEMORY
189133965Sjdp					   | SEC_LINKER_CREATED))
189233965Sjdp      || !bfd_set_section_alignment (abfd, s, 3))
189333965Sjdp    return false;
189433965Sjdp
189533965Sjdp  alpha_elf_tdata (abfd)->got = s;
189633965Sjdp
189733965Sjdp  return true;
189833965Sjdp}
189933965Sjdp
190033965Sjdp/* Create all the dynamic sections.  */
190133965Sjdp
190233965Sjdpstatic boolean
190333965Sjdpelf64_alpha_create_dynamic_sections (abfd, info)
190433965Sjdp     bfd *abfd;
190533965Sjdp     struct bfd_link_info *info;
190633965Sjdp{
190733965Sjdp  asection *s;
190833965Sjdp  struct elf_link_hash_entry *h;
190933965Sjdp
191033965Sjdp  /* We need to create .plt, .rela.plt, .got, and .rela.got sections.  */
191133965Sjdp
191233965Sjdp  s = bfd_make_section (abfd, ".plt");
191333965Sjdp  if (s == NULL
191433965Sjdp      || ! bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
191533965Sjdp					    | SEC_HAS_CONTENTS
191633965Sjdp					    | SEC_IN_MEMORY
191733965Sjdp					    | SEC_LINKER_CREATED
191833965Sjdp					    | SEC_CODE))
191933965Sjdp      || ! bfd_set_section_alignment (abfd, s, 3))
192033965Sjdp    return false;
192133965Sjdp
192233965Sjdp  /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
192333965Sjdp     .plt section.  */
192433965Sjdp  h = NULL;
192533965Sjdp  if (! (_bfd_generic_link_add_one_symbol
192633965Sjdp	 (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
192733965Sjdp	  (bfd_vma) 0, (const char *) NULL, false,
192833965Sjdp	  get_elf_backend_data (abfd)->collect,
192933965Sjdp	  (struct bfd_link_hash_entry **) &h)))
193033965Sjdp    return false;
193133965Sjdp  h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
193233965Sjdp  h->type = STT_OBJECT;
193333965Sjdp
193433965Sjdp  if (info->shared
193533965Sjdp      && ! _bfd_elf_link_record_dynamic_symbol (info, h))
193633965Sjdp    return false;
193733965Sjdp
193833965Sjdp  s = bfd_make_section (abfd, ".rela.plt");
193933965Sjdp  if (s == NULL
194033965Sjdp      || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
194133965Sjdp					   | SEC_HAS_CONTENTS
194233965Sjdp					   | SEC_IN_MEMORY
194333965Sjdp					   | SEC_LINKER_CREATED
194433965Sjdp					   | SEC_READONLY))
194533965Sjdp      || ! bfd_set_section_alignment (abfd, s, 3))
194633965Sjdp    return false;
194733965Sjdp
194833965Sjdp  /* We may or may not have created a .got section for this object, but
194933965Sjdp     we definitely havn't done the rest of the work.  */
195033965Sjdp
195133965Sjdp  if (!elf64_alpha_create_got_section (abfd, info))
195233965Sjdp    return false;
195333965Sjdp
195433965Sjdp  s = bfd_make_section(abfd, ".rela.got");
195533965Sjdp  if (s == NULL
195633965Sjdp      || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
195733965Sjdp					   | SEC_HAS_CONTENTS
195833965Sjdp					   | SEC_IN_MEMORY
195933965Sjdp					   | SEC_LINKER_CREATED
196033965Sjdp					   | SEC_READONLY))
196133965Sjdp      || !bfd_set_section_alignment (abfd, s, 3))
196233965Sjdp    return false;
196333965Sjdp
196433965Sjdp  /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the
196533965Sjdp     dynobj's .got section.  We don't do this in the linker script
196633965Sjdp     because we don't want to define the symbol if we are not creating
196733965Sjdp     a global offset table.  */
196833965Sjdp  h = NULL;
196933965Sjdp  if (!(_bfd_generic_link_add_one_symbol
197033965Sjdp	(info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL,
197133965Sjdp	 alpha_elf_tdata(abfd)->got, (bfd_vma) 0, (const char *) NULL,
197233965Sjdp	 false, get_elf_backend_data (abfd)->collect,
197333965Sjdp	 (struct bfd_link_hash_entry **) &h)))
197433965Sjdp    return false;
197533965Sjdp  h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
197633965Sjdp  h->type = STT_OBJECT;
197733965Sjdp
197833965Sjdp  if (info->shared
197933965Sjdp      && ! _bfd_elf_link_record_dynamic_symbol (info, h))
198033965Sjdp    return false;
198133965Sjdp
198233965Sjdp  elf_hash_table (info)->hgot = h;
198333965Sjdp
198433965Sjdp  return true;
198533965Sjdp}
198633965Sjdp
198733965Sjdp/* Read ECOFF debugging information from a .mdebug section into a
198833965Sjdp   ecoff_debug_info structure.  */
198933965Sjdp
199033965Sjdpstatic boolean
199133965Sjdpelf64_alpha_read_ecoff_info (abfd, section, debug)
199233965Sjdp     bfd *abfd;
199333965Sjdp     asection *section;
199433965Sjdp     struct ecoff_debug_info *debug;
199533965Sjdp{
199633965Sjdp  HDRR *symhdr;
199733965Sjdp  const struct ecoff_debug_swap *swap;
199833965Sjdp  char *ext_hdr = NULL;
199933965Sjdp
200033965Sjdp  swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
200177303Sobrien  memset (debug, 0, sizeof (*debug));
200233965Sjdp
200333965Sjdp  ext_hdr = (char *) bfd_malloc ((size_t) swap->external_hdr_size);
200433965Sjdp  if (ext_hdr == NULL && swap->external_hdr_size != 0)
200533965Sjdp    goto error_return;
200633965Sjdp
200733965Sjdp  if (bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0,
200833965Sjdp				swap->external_hdr_size)
200933965Sjdp      == false)
201033965Sjdp    goto error_return;
201133965Sjdp
201233965Sjdp  symhdr = &debug->symbolic_header;
201333965Sjdp  (*swap->swap_hdr_in) (abfd, ext_hdr, symhdr);
201433965Sjdp
201533965Sjdp  /* The symbolic header contains absolute file offsets and sizes to
201633965Sjdp     read.  */
201733965Sjdp#define READ(ptr, offset, count, size, type)				\
201833965Sjdp  if (symhdr->count == 0)						\
201933965Sjdp    debug->ptr = NULL;							\
202033965Sjdp  else									\
202133965Sjdp    {									\
202233965Sjdp      debug->ptr = (type) bfd_malloc ((size_t) (size * symhdr->count));	\
202333965Sjdp      if (debug->ptr == NULL)						\
202433965Sjdp	goto error_return;						\
202533965Sjdp      if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0	\
202633965Sjdp	  || (bfd_read (debug->ptr, size, symhdr->count,		\
202733965Sjdp			abfd) != size * symhdr->count))			\
202833965Sjdp	goto error_return;						\
202933965Sjdp    }
203033965Sjdp
203133965Sjdp  READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *);
203233965Sjdp  READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR);
203333965Sjdp  READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR);
203433965Sjdp  READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR);
203533965Sjdp  READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR);
203633965Sjdp  READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext),
203733965Sjdp	union aux_ext *);
203833965Sjdp  READ (ss, cbSsOffset, issMax, sizeof (char), char *);
203933965Sjdp  READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *);
204033965Sjdp  READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR);
204133965Sjdp  READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR);
204233965Sjdp  READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, PTR);
204333965Sjdp#undef READ
204433965Sjdp
204533965Sjdp  debug->fdr = NULL;
204633965Sjdp  debug->adjust = NULL;
204733965Sjdp
204833965Sjdp  return true;
204933965Sjdp
205033965Sjdp error_return:
205133965Sjdp  if (ext_hdr != NULL)
205233965Sjdp    free (ext_hdr);
205333965Sjdp  if (debug->line != NULL)
205433965Sjdp    free (debug->line);
205533965Sjdp  if (debug->external_dnr != NULL)
205633965Sjdp    free (debug->external_dnr);
205733965Sjdp  if (debug->external_pdr != NULL)
205833965Sjdp    free (debug->external_pdr);
205933965Sjdp  if (debug->external_sym != NULL)
206033965Sjdp    free (debug->external_sym);
206133965Sjdp  if (debug->external_opt != NULL)
206233965Sjdp    free (debug->external_opt);
206333965Sjdp  if (debug->external_aux != NULL)
206433965Sjdp    free (debug->external_aux);
206533965Sjdp  if (debug->ss != NULL)
206633965Sjdp    free (debug->ss);
206733965Sjdp  if (debug->ssext != NULL)
206833965Sjdp    free (debug->ssext);
206933965Sjdp  if (debug->external_fdr != NULL)
207033965Sjdp    free (debug->external_fdr);
207133965Sjdp  if (debug->external_rfd != NULL)
207233965Sjdp    free (debug->external_rfd);
207333965Sjdp  if (debug->external_ext != NULL)
207433965Sjdp    free (debug->external_ext);
207533965Sjdp  return false;
207633965Sjdp}
207733965Sjdp
207833965Sjdp/* Alpha ELF local labels start with '$'.  */
207933965Sjdp
208033965Sjdpstatic boolean
208133965Sjdpelf64_alpha_is_local_label_name (abfd, name)
208233965Sjdp     bfd *abfd;
208333965Sjdp     const char *name;
208433965Sjdp{
208533965Sjdp  return name[0] == '$';
208633965Sjdp}
208733965Sjdp
208833965Sjdp/* Alpha ELF follows MIPS ELF in using a special find_nearest_line
208933965Sjdp   routine in order to handle the ECOFF debugging information.  We
209033965Sjdp   still call this mips_elf_find_line because of the slot
209133965Sjdp   find_line_info in elf_obj_tdata is declared that way.  */
209233965Sjdp
209333965Sjdpstruct mips_elf_find_line
209433965Sjdp{
209533965Sjdp  struct ecoff_debug_info d;
209633965Sjdp  struct ecoff_find_line i;
209733965Sjdp};
209833965Sjdp
209933965Sjdpstatic boolean
210033965Sjdpelf64_alpha_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
210133965Sjdp			       functionname_ptr, line_ptr)
210233965Sjdp     bfd *abfd;
210333965Sjdp     asection *section;
210433965Sjdp     asymbol **symbols;
210533965Sjdp     bfd_vma offset;
210633965Sjdp     const char **filename_ptr;
210733965Sjdp     const char **functionname_ptr;
210833965Sjdp     unsigned int *line_ptr;
210933965Sjdp{
211033965Sjdp  asection *msec;
211133965Sjdp
211277303Sobrien  if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
211377303Sobrien				     filename_ptr, functionname_ptr,
211477303Sobrien				     line_ptr, 0,
211577303Sobrien				     &elf_tdata (abfd)->dwarf2_find_line_info))
211677303Sobrien    return true;
211777303Sobrien
211833965Sjdp  msec = bfd_get_section_by_name (abfd, ".mdebug");
211933965Sjdp  if (msec != NULL)
212033965Sjdp    {
212133965Sjdp      flagword origflags;
212233965Sjdp      struct mips_elf_find_line *fi;
212333965Sjdp      const struct ecoff_debug_swap * const swap =
212433965Sjdp	get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
212533965Sjdp
212633965Sjdp      /* If we are called during a link, alpha_elf_final_link may have
212733965Sjdp	 cleared the SEC_HAS_CONTENTS field.  We force it back on here
212833965Sjdp	 if appropriate (which it normally will be).  */
212933965Sjdp      origflags = msec->flags;
213033965Sjdp      if (elf_section_data (msec)->this_hdr.sh_type != SHT_NOBITS)
213133965Sjdp	msec->flags |= SEC_HAS_CONTENTS;
213233965Sjdp
213333965Sjdp      fi = elf_tdata (abfd)->find_line_info;
213433965Sjdp      if (fi == NULL)
213533965Sjdp	{
213633965Sjdp	  bfd_size_type external_fdr_size;
213733965Sjdp	  char *fraw_src;
213833965Sjdp	  char *fraw_end;
213933965Sjdp	  struct fdr *fdr_ptr;
214033965Sjdp
214133965Sjdp	  fi = ((struct mips_elf_find_line *)
214233965Sjdp		bfd_zalloc (abfd, sizeof (struct mips_elf_find_line)));
214333965Sjdp	  if (fi == NULL)
214433965Sjdp	    {
214533965Sjdp	      msec->flags = origflags;
214633965Sjdp	      return false;
214733965Sjdp	    }
214833965Sjdp
214933965Sjdp	  if (!elf64_alpha_read_ecoff_info (abfd, msec, &fi->d))
215033965Sjdp	    {
215133965Sjdp	      msec->flags = origflags;
215233965Sjdp	      return false;
215333965Sjdp	    }
215433965Sjdp
215533965Sjdp	  /* Swap in the FDR information.  */
215633965Sjdp	  fi->d.fdr = ((struct fdr *)
215733965Sjdp		       bfd_alloc (abfd,
215833965Sjdp				  (fi->d.symbolic_header.ifdMax *
215933965Sjdp				   sizeof (struct fdr))));
216033965Sjdp	  if (fi->d.fdr == NULL)
216133965Sjdp	    {
216233965Sjdp	      msec->flags = origflags;
216333965Sjdp	      return false;
216433965Sjdp	    }
216533965Sjdp	  external_fdr_size = swap->external_fdr_size;
216633965Sjdp	  fdr_ptr = fi->d.fdr;
216733965Sjdp	  fraw_src = (char *) fi->d.external_fdr;
216833965Sjdp	  fraw_end = (fraw_src
216933965Sjdp		      + fi->d.symbolic_header.ifdMax * external_fdr_size);
217033965Sjdp	  for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++)
217133965Sjdp	    (*swap->swap_fdr_in) (abfd, (PTR) fraw_src, fdr_ptr);
217233965Sjdp
217333965Sjdp	  elf_tdata (abfd)->find_line_info = fi;
217433965Sjdp
217533965Sjdp	  /* Note that we don't bother to ever free this information.
217633965Sjdp             find_nearest_line is either called all the time, as in
217733965Sjdp             objdump -l, so the information should be saved, or it is
217833965Sjdp             rarely called, as in ld error messages, so the memory
217933965Sjdp             wasted is unimportant.  Still, it would probably be a
218033965Sjdp             good idea for free_cached_info to throw it away.  */
218133965Sjdp	}
218233965Sjdp
218333965Sjdp      if (_bfd_ecoff_locate_line (abfd, section, offset, &fi->d, swap,
218433965Sjdp				  &fi->i, filename_ptr, functionname_ptr,
218533965Sjdp				  line_ptr))
218633965Sjdp	{
218733965Sjdp	  msec->flags = origflags;
218833965Sjdp	  return true;
218933965Sjdp	}
219033965Sjdp
219133965Sjdp      msec->flags = origflags;
219233965Sjdp    }
219333965Sjdp
219433965Sjdp  /* Fall back on the generic ELF find_nearest_line routine.  */
219533965Sjdp
219633965Sjdp  return _bfd_elf_find_nearest_line (abfd, section, symbols, offset,
219733965Sjdp				     filename_ptr, functionname_ptr,
219833965Sjdp				     line_ptr);
219933965Sjdp}
220033965Sjdp
220133965Sjdp/* Structure used to pass information to alpha_elf_output_extsym.  */
220233965Sjdp
220333965Sjdpstruct extsym_info
220433965Sjdp{
220533965Sjdp  bfd *abfd;
220633965Sjdp  struct bfd_link_info *info;
220733965Sjdp  struct ecoff_debug_info *debug;
220833965Sjdp  const struct ecoff_debug_swap *swap;
220933965Sjdp  boolean failed;
221033965Sjdp};
221133965Sjdp
221233965Sjdpstatic boolean
221333965Sjdpelf64_alpha_output_extsym (h, data)
221433965Sjdp     struct alpha_elf_link_hash_entry *h;
221533965Sjdp     PTR data;
221633965Sjdp{
221733965Sjdp  struct extsym_info *einfo = (struct extsym_info *) data;
221833965Sjdp  boolean strip;
221933965Sjdp  asection *sec, *output_section;
222033965Sjdp
222133965Sjdp  if (h->root.indx == -2)
222233965Sjdp    strip = false;
222333965Sjdp  else if (((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
222433965Sjdp           || (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0)
222533965Sjdp          && (h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
222633965Sjdp          && (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0)
222733965Sjdp    strip = true;
222833965Sjdp  else if (einfo->info->strip == strip_all
222933965Sjdp          || (einfo->info->strip == strip_some
223033965Sjdp              && bfd_hash_lookup (einfo->info->keep_hash,
223133965Sjdp                                  h->root.root.root.string,
223233965Sjdp                                  false, false) == NULL))
223333965Sjdp    strip = true;
223433965Sjdp  else
223533965Sjdp    strip = false;
223633965Sjdp
223733965Sjdp  if (strip)
223833965Sjdp    return true;
223933965Sjdp
224033965Sjdp  if (h->esym.ifd == -2)
224133965Sjdp    {
224233965Sjdp      h->esym.jmptbl = 0;
224333965Sjdp      h->esym.cobol_main = 0;
224433965Sjdp      h->esym.weakext = 0;
224533965Sjdp      h->esym.reserved = 0;
224633965Sjdp      h->esym.ifd = ifdNil;
224733965Sjdp      h->esym.asym.value = 0;
224833965Sjdp      h->esym.asym.st = stGlobal;
224933965Sjdp
225033965Sjdp      if (h->root.root.type != bfd_link_hash_defined
225133965Sjdp         && h->root.root.type != bfd_link_hash_defweak)
225233965Sjdp       h->esym.asym.sc = scAbs;
225333965Sjdp      else
225433965Sjdp       {
225533965Sjdp         const char *name;
225633965Sjdp
225733965Sjdp         sec = h->root.root.u.def.section;
225833965Sjdp         output_section = sec->output_section;
225933965Sjdp
226033965Sjdp         /* When making a shared library and symbol h is the one from
226133965Sjdp            the another shared library, OUTPUT_SECTION may be null.  */
226233965Sjdp         if (output_section == NULL)
226333965Sjdp           h->esym.asym.sc = scUndefined;
226433965Sjdp         else
226533965Sjdp           {
226633965Sjdp             name = bfd_section_name (output_section->owner, output_section);
226733965Sjdp
226833965Sjdp             if (strcmp (name, ".text") == 0)
226933965Sjdp               h->esym.asym.sc = scText;
227033965Sjdp             else if (strcmp (name, ".data") == 0)
227133965Sjdp               h->esym.asym.sc = scData;
227233965Sjdp             else if (strcmp (name, ".sdata") == 0)
227333965Sjdp               h->esym.asym.sc = scSData;
227433965Sjdp             else if (strcmp (name, ".rodata") == 0
227533965Sjdp                      || strcmp (name, ".rdata") == 0)
227633965Sjdp               h->esym.asym.sc = scRData;
227733965Sjdp             else if (strcmp (name, ".bss") == 0)
227833965Sjdp               h->esym.asym.sc = scBss;
227933965Sjdp             else if (strcmp (name, ".sbss") == 0)
228033965Sjdp               h->esym.asym.sc = scSBss;
228133965Sjdp             else if (strcmp (name, ".init") == 0)
228233965Sjdp               h->esym.asym.sc = scInit;
228333965Sjdp             else if (strcmp (name, ".fini") == 0)
228433965Sjdp               h->esym.asym.sc = scFini;
228533965Sjdp             else
228633965Sjdp               h->esym.asym.sc = scAbs;
228733965Sjdp           }
228833965Sjdp       }
228933965Sjdp
229033965Sjdp      h->esym.asym.reserved = 0;
229133965Sjdp      h->esym.asym.index = indexNil;
229233965Sjdp    }
229333965Sjdp
229433965Sjdp  if (h->root.root.type == bfd_link_hash_common)
229533965Sjdp    h->esym.asym.value = h->root.root.u.c.size;
229633965Sjdp  else if (h->root.root.type == bfd_link_hash_defined
229733965Sjdp	   || h->root.root.type == bfd_link_hash_defweak)
229833965Sjdp    {
229933965Sjdp      if (h->esym.asym.sc == scCommon)
230033965Sjdp       h->esym.asym.sc = scBss;
230133965Sjdp      else if (h->esym.asym.sc == scSCommon)
230233965Sjdp       h->esym.asym.sc = scSBss;
230333965Sjdp
230433965Sjdp      sec = h->root.root.u.def.section;
230533965Sjdp      output_section = sec->output_section;
230633965Sjdp      if (output_section != NULL)
230733965Sjdp       h->esym.asym.value = (h->root.root.u.def.value
230833965Sjdp                             + sec->output_offset
230933965Sjdp                             + output_section->vma);
231033965Sjdp      else
231133965Sjdp       h->esym.asym.value = 0;
231233965Sjdp    }
231333965Sjdp  else if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
231433965Sjdp    {
231533965Sjdp      /* Set type and value for a symbol with a function stub.  */
231633965Sjdp      h->esym.asym.st = stProc;
231733965Sjdp      sec = bfd_get_section_by_name (einfo->abfd, ".plt");
231833965Sjdp      if (sec == NULL)
231933965Sjdp	h->esym.asym.value = 0;
232033965Sjdp      else
232133965Sjdp	{
232233965Sjdp	  output_section = sec->output_section;
232333965Sjdp	  if (output_section != NULL)
232460510Sobrien	    h->esym.asym.value = (h->root.plt.offset
232533965Sjdp				  + sec->output_offset
232633965Sjdp				  + output_section->vma);
232733965Sjdp	  else
232833965Sjdp	    h->esym.asym.value = 0;
232933965Sjdp	}
233033965Sjdp#if 0 /* FIXME?  */
233133965Sjdp      h->esym.ifd = 0;
233233965Sjdp#endif
233333965Sjdp    }
233433965Sjdp
233533965Sjdp  if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap,
233633965Sjdp                                     h->root.root.root.string,
233733965Sjdp                                     &h->esym))
233833965Sjdp    {
233933965Sjdp      einfo->failed = true;
234033965Sjdp      return false;
234133965Sjdp    }
234233965Sjdp
234333965Sjdp  return true;
234433965Sjdp}
234533965Sjdp
234633965Sjdp/* FIXME:  Create a runtime procedure table from the .mdebug section.
234733965Sjdp
234833965Sjdpstatic boolean
234933965Sjdpmips_elf_create_procedure_table (handle, abfd, info, s, debug)
235033965Sjdp     PTR handle;
235133965Sjdp     bfd *abfd;
235233965Sjdp     struct bfd_link_info *info;
235333965Sjdp     asection *s;
235433965Sjdp     struct ecoff_debug_info *debug;
235533965Sjdp*/
235633965Sjdp
235733965Sjdp/* Handle dynamic relocations when doing an Alpha ELF link.  */
235833965Sjdp
235933965Sjdpstatic boolean
236033965Sjdpelf64_alpha_check_relocs (abfd, info, sec, relocs)
236133965Sjdp     bfd *abfd;
236233965Sjdp     struct bfd_link_info *info;
236333965Sjdp     asection *sec;
236433965Sjdp     const Elf_Internal_Rela *relocs;
236533965Sjdp{
236633965Sjdp  bfd *dynobj;
236733965Sjdp  asection *sreloc;
236833965Sjdp  const char *rel_sec_name;
236933965Sjdp  Elf_Internal_Shdr *symtab_hdr;
237033965Sjdp  struct alpha_elf_link_hash_entry **sym_hashes;
237133965Sjdp  struct alpha_elf_got_entry **local_got_entries;
237233965Sjdp  const Elf_Internal_Rela *rel, *relend;
237333965Sjdp  int got_created;
237433965Sjdp
237533965Sjdp  if (info->relocateable)
237633965Sjdp    return true;
237733965Sjdp
237833965Sjdp  dynobj = elf_hash_table(info)->dynobj;
237933965Sjdp  if (dynobj == NULL)
238033965Sjdp    elf_hash_table(info)->dynobj = dynobj = abfd;
238133965Sjdp
238233965Sjdp  sreloc = NULL;
238333965Sjdp  rel_sec_name = NULL;
238433965Sjdp  symtab_hdr = &elf_tdata(abfd)->symtab_hdr;
238533965Sjdp  sym_hashes = alpha_elf_sym_hashes(abfd);
238633965Sjdp  local_got_entries = alpha_elf_tdata(abfd)->local_got_entries;
238733965Sjdp  got_created = 0;
238833965Sjdp
238933965Sjdp  relend = relocs + sec->reloc_count;
239033965Sjdp  for (rel = relocs; rel < relend; ++rel)
239133965Sjdp    {
239233965Sjdp      unsigned long r_symndx, r_type;
239333965Sjdp      struct alpha_elf_link_hash_entry *h;
239433965Sjdp
239533965Sjdp      r_symndx = ELF64_R_SYM (rel->r_info);
239633965Sjdp      if (r_symndx < symtab_hdr->sh_info)
239733965Sjdp	h = NULL;
239833965Sjdp      else
239933965Sjdp	{
240033965Sjdp	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
240138889Sjdp
240238889Sjdp	  while (h->root.root.type == bfd_link_hash_indirect
240338889Sjdp		 || h->root.root.type == bfd_link_hash_warning)
240438889Sjdp	    h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
240538889Sjdp
240633965Sjdp	  h->root.elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
240733965Sjdp	}
240833965Sjdp      r_type = ELF64_R_TYPE (rel->r_info);
240933965Sjdp
241033965Sjdp      switch (r_type)
241133965Sjdp	{
241233965Sjdp	case R_ALPHA_LITERAL:
241333965Sjdp	  {
241433965Sjdp	    struct alpha_elf_got_entry *gotent;
241533965Sjdp	    int flags = 0;
241633965Sjdp
241733965Sjdp	    if (h)
241833965Sjdp	      {
241933965Sjdp		/* Search for and possibly create a got entry.  */
242033965Sjdp		for (gotent = h->got_entries; gotent ; gotent = gotent->next)
242133965Sjdp		  if (gotent->gotobj == abfd &&
242233965Sjdp		      gotent->addend == rel->r_addend)
242333965Sjdp		    break;
242433965Sjdp
242533965Sjdp		if (!gotent)
242633965Sjdp		  {
242733965Sjdp		    gotent = ((struct alpha_elf_got_entry *)
242833965Sjdp			      bfd_alloc (abfd,
242933965Sjdp					 sizeof (struct alpha_elf_got_entry)));
243033965Sjdp		    if (!gotent)
243133965Sjdp		      return false;
243233965Sjdp
243333965Sjdp		    gotent->gotobj = abfd;
243433965Sjdp		    gotent->addend = rel->r_addend;
243533965Sjdp		    gotent->got_offset = -1;
243633965Sjdp		    gotent->flags = 0;
243760510Sobrien		    gotent->use_count = 1;
243833965Sjdp
243933965Sjdp		    gotent->next = h->got_entries;
244033965Sjdp		    h->got_entries = gotent;
244133965Sjdp
244233965Sjdp		    alpha_elf_tdata (abfd)->total_got_entries++;
244333965Sjdp		  }
244460510Sobrien		else
244560510Sobrien		  gotent->use_count += 1;
244633965Sjdp	      }
244733965Sjdp	    else
244833965Sjdp	      {
244933965Sjdp		/* This is a local .got entry -- record for merge.  */
245033965Sjdp		if (!local_got_entries)
245133965Sjdp		  {
245233965Sjdp		    size_t size;
245333965Sjdp		    size = (symtab_hdr->sh_info
245433965Sjdp			    * sizeof (struct alpha_elf_got_entry *));
245533965Sjdp
245633965Sjdp		    local_got_entries = ((struct alpha_elf_got_entry **)
245733965Sjdp					 bfd_alloc (abfd, size));
245833965Sjdp		    if (!local_got_entries)
245933965Sjdp		      return false;
246033965Sjdp
246133965Sjdp		    memset (local_got_entries, 0, size);
246233965Sjdp		    alpha_elf_tdata (abfd)->local_got_entries =
246333965Sjdp		      local_got_entries;
246433965Sjdp		  }
246533965Sjdp
246633965Sjdp		for (gotent = local_got_entries[ELF64_R_SYM(rel->r_info)];
246733965Sjdp		     gotent != NULL && gotent->addend != rel->r_addend;
246833965Sjdp		     gotent = gotent->next)
246933965Sjdp		  continue;
247033965Sjdp		if (!gotent)
247133965Sjdp		  {
247233965Sjdp		    gotent = ((struct alpha_elf_got_entry *)
247333965Sjdp			      bfd_alloc (abfd,
247433965Sjdp					 sizeof (struct alpha_elf_got_entry)));
247533965Sjdp		    if (!gotent)
247633965Sjdp		      return false;
247733965Sjdp
247833965Sjdp		    gotent->gotobj = abfd;
247933965Sjdp		    gotent->addend = rel->r_addend;
248033965Sjdp		    gotent->got_offset = -1;
248133965Sjdp		    gotent->flags = 0;
248260510Sobrien		    gotent->use_count = 1;
248333965Sjdp
248433965Sjdp		    gotent->next = local_got_entries[ELF64_R_SYM(rel->r_info)];
248533965Sjdp		    local_got_entries[ELF64_R_SYM(rel->r_info)] = gotent;
248633965Sjdp
248733965Sjdp		    alpha_elf_tdata(abfd)->total_got_entries++;
248833965Sjdp		    alpha_elf_tdata(abfd)->n_local_got_entries++;
248933965Sjdp		  }
249060510Sobrien		else
249160510Sobrien		  gotent->use_count += 1;
249233965Sjdp	      }
249333965Sjdp
249433965Sjdp	    /* Remember how this literal is used from its LITUSEs.
249533965Sjdp	       This will be important when it comes to decide if we can
249633965Sjdp	       create a .plt entry for a function symbol.  */
249733965Sjdp	    if (rel+1 < relend
249833965Sjdp		&& ELF64_R_TYPE (rel[1].r_info) == R_ALPHA_LITUSE)
249933965Sjdp	      {
250033965Sjdp		do
250133965Sjdp		  {
250233965Sjdp		    ++rel;
250333965Sjdp		    if (rel->r_addend >= 1 && rel->r_addend <= 3)
250433965Sjdp		      flags |= 1 << rel->r_addend;
250533965Sjdp		  }
250633965Sjdp		while (rel+1 < relend &&
250733965Sjdp		       ELF64_R_TYPE (rel[1].r_info) == R_ALPHA_LITUSE);
250833965Sjdp	      }
250933965Sjdp	    else
251033965Sjdp	      {
251133965Sjdp		/* No LITUSEs -- presumably the address is not being
251233965Sjdp		   loaded for nothing.  */
251333965Sjdp		flags = ALPHA_ELF_LINK_HASH_LU_ADDR;
251433965Sjdp	      }
251533965Sjdp
251633965Sjdp	    gotent->flags |= flags;
251733965Sjdp	    if (h)
251833965Sjdp	      {
251933965Sjdp		/* Make a guess as to whether a .plt entry will be needed.  */
252033965Sjdp		if ((h->flags |= flags) == ALPHA_ELF_LINK_HASH_LU_FUNC)
252133965Sjdp		  h->root.elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
252233965Sjdp		else
252333965Sjdp		  h->root.elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
252433965Sjdp	      }
252533965Sjdp	  }
252633965Sjdp	  /* FALLTHRU */
252733965Sjdp
252833965Sjdp	case R_ALPHA_GPDISP:
252933965Sjdp	case R_ALPHA_GPREL32:
253060510Sobrien	case R_ALPHA_GPRELHIGH:
253160510Sobrien	case R_ALPHA_GPRELLOW:
253233965Sjdp	  /* We don't actually use the .got here, but the sections must
253333965Sjdp	     be created before the linker maps input sections to output
253433965Sjdp	     sections.  */
253533965Sjdp	  if (!got_created)
253633965Sjdp	    {
253733965Sjdp	      if (!elf64_alpha_create_got_section (abfd, info))
253833965Sjdp		return false;
253933965Sjdp
254033965Sjdp	      /* Make sure the object's gotobj is set to itself so
254133965Sjdp		 that we default to every object with its own .got.
254233965Sjdp		 We'll merge .gots later once we've collected each
254333965Sjdp		 object's info.  */
254433965Sjdp	      alpha_elf_tdata(abfd)->gotobj = abfd;
254533965Sjdp
254633965Sjdp	      got_created = 1;
254733965Sjdp	    }
254833965Sjdp	  break;
254933965Sjdp
255033965Sjdp	case R_ALPHA_SREL16:
255133965Sjdp	case R_ALPHA_SREL32:
255233965Sjdp	case R_ALPHA_SREL64:
255333965Sjdp	  if (h == NULL)
255433965Sjdp	    break;
255533965Sjdp	  /* FALLTHRU */
255633965Sjdp
255733965Sjdp	case R_ALPHA_REFLONG:
255833965Sjdp	case R_ALPHA_REFQUAD:
255933965Sjdp	  if (rel_sec_name == NULL)
256033965Sjdp	    {
256133965Sjdp	      rel_sec_name = (bfd_elf_string_from_elf_section
256233965Sjdp			      (abfd, elf_elfheader(abfd)->e_shstrndx,
256333965Sjdp			       elf_section_data(sec)->rel_hdr.sh_name));
256433965Sjdp	      if (rel_sec_name == NULL)
256533965Sjdp		return false;
256633965Sjdp
256733965Sjdp	      BFD_ASSERT (strncmp (rel_sec_name, ".rela", 5) == 0
256833965Sjdp			  && strcmp (bfd_get_section_name (abfd, sec),
256933965Sjdp				     rel_sec_name+5) == 0);
257033965Sjdp	    }
257133965Sjdp
257233965Sjdp	  /* We need to create the section here now whether we eventually
257333965Sjdp	     use it or not so that it gets mapped to an output section by
257433965Sjdp	     the linker.  If not used, we'll kill it in
257533965Sjdp	     size_dynamic_sections.  */
257633965Sjdp	  if (sreloc == NULL)
257733965Sjdp	    {
257833965Sjdp	      sreloc = bfd_get_section_by_name (dynobj, rel_sec_name);
257933965Sjdp	      if (sreloc == NULL)
258033965Sjdp		{
258133965Sjdp		  sreloc = bfd_make_section (dynobj, rel_sec_name);
258233965Sjdp		  if (sreloc == NULL
258333965Sjdp		      || !bfd_set_section_flags (dynobj, sreloc,
258477303Sobrien						 ((sec->flags & (SEC_ALLOC
258577303Sobrien								 | SEC_LOAD))
258633965Sjdp						  | SEC_HAS_CONTENTS
258733965Sjdp						  | SEC_IN_MEMORY
258833965Sjdp						  | SEC_LINKER_CREATED
258933965Sjdp						  | SEC_READONLY))
259033965Sjdp		      || !bfd_set_section_alignment (dynobj, sreloc, 3))
259133965Sjdp		    return false;
259233965Sjdp		}
259333965Sjdp	    }
259433965Sjdp
259533965Sjdp	  if (h)
259633965Sjdp	    {
259733965Sjdp	      /* Since we havn't seen all of the input symbols yet, we
259833965Sjdp		 don't know whether we'll actually need a dynamic relocation
259933965Sjdp		 entry for this reloc.  So make a record of it.  Once we
260033965Sjdp		 find out if this thing needs dynamic relocation we'll
260177303Sobrien		 expand the relocation sections by the appropriate amount.  */
260233965Sjdp
260333965Sjdp	      struct alpha_elf_reloc_entry *rent;
260433965Sjdp
260533965Sjdp	      for (rent = h->reloc_entries; rent; rent = rent->next)
260633965Sjdp		if (rent->rtype == r_type && rent->srel == sreloc)
260733965Sjdp		  break;
260833965Sjdp
260933965Sjdp	      if (!rent)
261033965Sjdp		{
261133965Sjdp		  rent = ((struct alpha_elf_reloc_entry *)
261233965Sjdp			  bfd_alloc (abfd,
261333965Sjdp				     sizeof (struct alpha_elf_reloc_entry)));
261433965Sjdp		  if (!rent)
261533965Sjdp		    return false;
261633965Sjdp
261733965Sjdp		  rent->srel = sreloc;
261833965Sjdp		  rent->rtype = r_type;
261933965Sjdp		  rent->count = 1;
262033965Sjdp
262133965Sjdp		  rent->next = h->reloc_entries;
262233965Sjdp		  h->reloc_entries = rent;
262333965Sjdp		}
262433965Sjdp	      else
262533965Sjdp		rent->count++;
262633965Sjdp	    }
262760510Sobrien	  else if (info->shared && (sec->flags & SEC_ALLOC))
262833965Sjdp	    {
262960510Sobrien	      /* If this is a shared library, and the section is to be
263060510Sobrien		 loaded into memory, we need a RELATIVE reloc.  */
263133965Sjdp	      sreloc->_raw_size += sizeof (Elf64_External_Rela);
263233965Sjdp	    }
263333965Sjdp	  break;
263433965Sjdp	}
263533965Sjdp    }
263633965Sjdp
263733965Sjdp  return true;
263833965Sjdp}
263933965Sjdp
264033965Sjdp/* Adjust a symbol defined by a dynamic object and referenced by a
264133965Sjdp   regular object.  The current definition is in some section of the
264233965Sjdp   dynamic object, but we're not including those sections.  We have to
264333965Sjdp   change the definition to something the rest of the link can
264433965Sjdp   understand.  */
264533965Sjdp
264633965Sjdpstatic boolean
264733965Sjdpelf64_alpha_adjust_dynamic_symbol (info, h)
264833965Sjdp     struct bfd_link_info *info;
264933965Sjdp     struct elf_link_hash_entry *h;
265033965Sjdp{
265133965Sjdp  bfd *dynobj;
265233965Sjdp  asection *s;
265333965Sjdp  struct alpha_elf_link_hash_entry *ah;
265433965Sjdp
265533965Sjdp  dynobj = elf_hash_table(info)->dynobj;
265633965Sjdp  ah = (struct alpha_elf_link_hash_entry *)h;
265733965Sjdp
265833965Sjdp  /* Now that we've seen all of the input symbols, finalize our decision
265933965Sjdp     about whether this symbol should get a .plt entry.  */
266033965Sjdp
266133965Sjdp  if (h->root.type != bfd_link_hash_undefweak
266233965Sjdp      && alpha_elf_dynamic_symbol_p (h, info)
266333965Sjdp      && ((h->type == STT_FUNC
266433965Sjdp	   && !(ah->flags & ALPHA_ELF_LINK_HASH_LU_ADDR))
266533965Sjdp	  || (h->type == STT_NOTYPE
266633965Sjdp	      && ah->flags == ALPHA_ELF_LINK_HASH_LU_FUNC))
266733965Sjdp      /* Don't prevent otherwise valid programs from linking by attempting
266833965Sjdp	 to create a new .got entry somewhere.  A Correct Solution would be
266933965Sjdp	 to add a new .got section to a new object file and let it be merged
267033965Sjdp	 somewhere later.  But for now don't bother.  */
267133965Sjdp      && ah->got_entries)
267233965Sjdp    {
267333965Sjdp      h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
267433965Sjdp
267533965Sjdp      s = bfd_get_section_by_name(dynobj, ".plt");
267633965Sjdp      if (!s && !elf64_alpha_create_dynamic_sections (dynobj, info))
267733965Sjdp	return false;
267833965Sjdp
267933965Sjdp      /* The first bit of the .plt is reserved.  */
268033965Sjdp      if (s->_raw_size == 0)
268133965Sjdp	s->_raw_size = PLT_HEADER_SIZE;
268233965Sjdp
268360510Sobrien      h->plt.offset = s->_raw_size;
268433965Sjdp      s->_raw_size += PLT_ENTRY_SIZE;
268533965Sjdp
268633965Sjdp      /* If this symbol is not defined in a regular file, and we are not
268733965Sjdp	 generating a shared library, then set the symbol to the location
268833965Sjdp	 in the .plt.  This is required to make function pointers compare
268933965Sjdp	 equal between the normal executable and the shared library.  */
269048850Sdfr      if (! info->shared
269148850Sdfr	  && h->root.type != bfd_link_hash_defweak)
269233965Sjdp	{
269333965Sjdp	  h->root.u.def.section = s;
269460510Sobrien	  h->root.u.def.value = h->plt.offset;
269533965Sjdp	}
269633965Sjdp
269733965Sjdp      /* We also need a JMP_SLOT entry in the .rela.plt section.  */
269833965Sjdp      s = bfd_get_section_by_name (dynobj, ".rela.plt");
269933965Sjdp      BFD_ASSERT (s != NULL);
270033965Sjdp      s->_raw_size += sizeof (Elf64_External_Rela);
270133965Sjdp
270233965Sjdp      return true;
270333965Sjdp    }
270433965Sjdp  else
270533965Sjdp    h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
270633965Sjdp
270733965Sjdp  /* If this is a weak symbol, and there is a real definition, the
270833965Sjdp     processor independent code will have arranged for us to see the
270933965Sjdp     real definition first, and we can just use the same value.  */
271033965Sjdp  if (h->weakdef != NULL)
271133965Sjdp    {
271233965Sjdp      BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
271333965Sjdp		  || h->weakdef->root.type == bfd_link_hash_defweak);
271433965Sjdp      h->root.u.def.section = h->weakdef->root.u.def.section;
271533965Sjdp      h->root.u.def.value = h->weakdef->root.u.def.value;
271633965Sjdp      return true;
271733965Sjdp    }
271833965Sjdp
271933965Sjdp  /* This is a reference to a symbol defined by a dynamic object which
272033965Sjdp     is not a function.  The Alpha, since it uses .got entries for all
272133965Sjdp     symbols even in regular objects, does not need the hackery of a
272233965Sjdp     .dynbss section and COPY dynamic relocations.  */
272333965Sjdp
272433965Sjdp  return true;
272533965Sjdp}
272633965Sjdp
272738889Sjdp/* Symbol versioning can create new symbols, and make our old symbols
272838889Sjdp   indirect to the new ones.  Consolidate the got and reloc information
272938889Sjdp   in these situations.  */
273038889Sjdp
273138889Sjdpstatic boolean
273238889Sjdpelf64_alpha_merge_ind_symbols (hi, dummy)
273338889Sjdp     struct alpha_elf_link_hash_entry *hi;
273438889Sjdp     PTR dummy;
273538889Sjdp{
273638889Sjdp  struct alpha_elf_link_hash_entry *hs;
273738889Sjdp
273838889Sjdp  if (hi->root.root.type != bfd_link_hash_indirect)
273938889Sjdp    return true;
274038889Sjdp  hs = hi;
274138889Sjdp  do {
274238889Sjdp    hs = (struct alpha_elf_link_hash_entry *)hs->root.root.u.i.link;
274338889Sjdp  } while (hs->root.root.type == bfd_link_hash_indirect);
274438889Sjdp
274538889Sjdp  /* Merge the flags.  Whee.  */
274638889Sjdp
274738889Sjdp  hs->flags |= hi->flags;
274838889Sjdp
274938889Sjdp  /* Merge the .got entries.  Cannibalize the old symbol's list in
275038889Sjdp     doing so, since we don't need it anymore.  */
275138889Sjdp
275238889Sjdp  if (hs->got_entries == NULL)
275338889Sjdp    hs->got_entries = hi->got_entries;
275438889Sjdp  else
275538889Sjdp    {
275638889Sjdp      struct alpha_elf_got_entry *gi, *gs, *gin, *gsh;
275738889Sjdp
275838889Sjdp      gsh = hs->got_entries;
275938889Sjdp      for (gi = hi->got_entries; gi ; gi = gin)
276038889Sjdp	{
276138889Sjdp	  gin = gi->next;
276238889Sjdp	  for (gs = gsh; gs ; gs = gs->next)
276360510Sobrien	    if (gi->gotobj == gs->gotobj && gi->addend == gs->addend)
276438889Sjdp	      goto got_found;
276538889Sjdp	  gi->next = hs->got_entries;
276638889Sjdp	  hs->got_entries = gi;
276738889Sjdp	got_found:;
276838889Sjdp	}
276938889Sjdp    }
277038889Sjdp  hi->got_entries = NULL;
277138889Sjdp
277238889Sjdp  /* And similar for the reloc entries.  */
277338889Sjdp
277438889Sjdp  if (hs->reloc_entries == NULL)
277538889Sjdp    hs->reloc_entries = hi->reloc_entries;
277638889Sjdp  else
277738889Sjdp    {
277838889Sjdp      struct alpha_elf_reloc_entry *ri, *rs, *rin, *rsh;
277938889Sjdp
278038889Sjdp      rsh = hs->reloc_entries;
278138889Sjdp      for (ri = hi->reloc_entries; ri ; ri = rin)
278238889Sjdp	{
278338889Sjdp	  rin = ri->next;
278438889Sjdp	  for (rs = rsh; rs ; rs = rs->next)
278538889Sjdp	    if (ri->rtype == rs->rtype)
278638889Sjdp	      {
278738889Sjdp		rs->count += ri->count;
278838889Sjdp		goto found_reloc;
278938889Sjdp	      }
279038889Sjdp	  ri->next = hs->reloc_entries;
279138889Sjdp	  hs->reloc_entries = ri;
279238889Sjdp	found_reloc:;
279338889Sjdp	}
279438889Sjdp    }
279538889Sjdp  hi->reloc_entries = NULL;
279638889Sjdp
279738889Sjdp  return true;
279838889Sjdp}
279938889Sjdp
280033965Sjdp/* Is it possible to merge two object file's .got tables?  */
280133965Sjdp
280233965Sjdpstatic boolean
280333965Sjdpelf64_alpha_can_merge_gots (a, b)
280433965Sjdp     bfd *a, *b;
280533965Sjdp{
280633965Sjdp  int total = alpha_elf_tdata (a)->total_got_entries;
280760510Sobrien  bfd *bsub;
280833965Sjdp
280933965Sjdp  /* Trivial quick fallout test.  */
281033965Sjdp  if (total + alpha_elf_tdata (b)->total_got_entries <= MAX_GOT_ENTRIES)
281133965Sjdp    return true;
281233965Sjdp
281333965Sjdp  /* By their nature, local .got entries cannot be merged.  */
281433965Sjdp  if ((total += alpha_elf_tdata (b)->n_local_got_entries) > MAX_GOT_ENTRIES)
281533965Sjdp    return false;
281633965Sjdp
281733965Sjdp  /* Failing the common trivial comparison, we must effectively
281833965Sjdp     perform the merge.  Not actually performing the merge means that
281933965Sjdp     we don't have to store undo information in case we fail.  */
282060510Sobrien  for (bsub = b; bsub ; bsub = alpha_elf_tdata (bsub)->in_got_link_next)
282160510Sobrien    {
282260510Sobrien      struct alpha_elf_link_hash_entry **hashes = alpha_elf_sym_hashes (bsub);
282360510Sobrien      Elf_Internal_Shdr *symtab_hdr = &elf_tdata (bsub)->symtab_hdr;
282460510Sobrien      int i, n;
282533965Sjdp
282660510Sobrien      n = symtab_hdr->sh_size / symtab_hdr->sh_entsize - symtab_hdr->sh_info;
282760510Sobrien      for (i = 0; i < n; ++i)
282860510Sobrien	{
282960510Sobrien	  struct alpha_elf_got_entry *ae, *be;
283060510Sobrien	  struct alpha_elf_link_hash_entry *h;
283138889Sjdp
283260510Sobrien	  h = hashes[i];
283360510Sobrien	  while (h->root.root.type == bfd_link_hash_indirect
283460510Sobrien	         || h->root.root.type == bfd_link_hash_warning)
283560510Sobrien	    h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
283638889Sjdp
283760510Sobrien	  for (be = h->got_entries; be ; be = be->next)
283860510Sobrien	    {
283960510Sobrien	      if (be->use_count == 0)
284060510Sobrien	        continue;
284160510Sobrien	      if (be->gotobj != b)
284260510Sobrien	        continue;
284333965Sjdp
284460510Sobrien	      for (ae = h->got_entries; ae ; ae = ae->next)
284560510Sobrien	        if (ae->gotobj == a && ae->addend == be->addend)
284660510Sobrien		  goto global_found;
284733965Sjdp
284860510Sobrien	      if (++total > MAX_GOT_ENTRIES)
284960510Sobrien	        return false;
285060510Sobrien	    global_found:;
285160510Sobrien	    }
285260510Sobrien	}
285360510Sobrien    }
285433965Sjdp
285533965Sjdp  return true;
285633965Sjdp}
285733965Sjdp
285833965Sjdp/* Actually merge two .got tables.  */
285933965Sjdp
286033965Sjdpstatic void
286133965Sjdpelf64_alpha_merge_gots (a, b)
286233965Sjdp     bfd *a, *b;
286333965Sjdp{
286460510Sobrien  int total = alpha_elf_tdata (a)->total_got_entries;
286560510Sobrien  bfd *bsub;
286633965Sjdp
286733965Sjdp  /* Remember local expansion.  */
286833965Sjdp  {
286960510Sobrien    int e = alpha_elf_tdata (b)->n_local_got_entries;
287033965Sjdp    total += e;
287160510Sobrien    alpha_elf_tdata (a)->n_local_got_entries += e;
287233965Sjdp  }
287333965Sjdp
287460510Sobrien  for (bsub = b; bsub ; bsub = alpha_elf_tdata (bsub)->in_got_link_next)
287560510Sobrien    {
287660510Sobrien      struct alpha_elf_got_entry **local_got_entries;
287760510Sobrien      struct alpha_elf_link_hash_entry **hashes;
287860510Sobrien      Elf_Internal_Shdr *symtab_hdr;
287960510Sobrien      int i, n;
288033965Sjdp
288160510Sobrien      /* Let the local .got entries know they are part of a new subsegment.  */
288260510Sobrien      local_got_entries = alpha_elf_tdata (bsub)->local_got_entries;
288360510Sobrien      if (local_got_entries)
288460510Sobrien        {
288560510Sobrien	  n = elf_tdata (bsub)->symtab_hdr.sh_info;
288660510Sobrien	  for (i = 0; i < n; ++i)
288760510Sobrien	    {
288860510Sobrien	      struct alpha_elf_got_entry *ent;
288960510Sobrien	      for (ent = local_got_entries[i]; ent; ent = ent->next)
289060510Sobrien	        ent->gotobj = a;
289160510Sobrien	    }
289260510Sobrien        }
289333965Sjdp
289460510Sobrien      /* Merge the global .got entries.  */
289560510Sobrien      hashes = alpha_elf_sym_hashes (bsub);
289660510Sobrien      symtab_hdr = &elf_tdata (bsub)->symtab_hdr;
289733965Sjdp
289860510Sobrien      n = symtab_hdr->sh_size / symtab_hdr->sh_entsize - symtab_hdr->sh_info;
289960510Sobrien      for (i = 0; i < n; ++i)
290060510Sobrien        {
290160510Sobrien	  struct alpha_elf_got_entry *ae, *be, **pbe, **start;
290260510Sobrien	  struct alpha_elf_link_hash_entry *h;
290338889Sjdp
290460510Sobrien	  h = hashes[i];
290560510Sobrien	  while (h->root.root.type == bfd_link_hash_indirect
290660510Sobrien	         || h->root.root.type == bfd_link_hash_warning)
290760510Sobrien	    h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
290838889Sjdp
290960510Sobrien	  start = &h->got_entries;
291060510Sobrien	  for (pbe = start, be = *start; be ; pbe = &be->next, be = be->next)
291160510Sobrien	    {
291260510Sobrien	      if (be->use_count == 0)
291360510Sobrien	        {
291433965Sjdp		  *pbe = be->next;
291560510Sobrien		  continue;
291660510Sobrien	        }
291760510Sobrien	      if (be->gotobj != b)
291860510Sobrien	        continue;
291933965Sjdp
292060510Sobrien	      for (ae = *start; ae ; ae = ae->next)
292160510Sobrien	        if (ae->gotobj == a && ae->addend == be->addend)
292260510Sobrien		  {
292360510Sobrien		    ae->flags |= be->flags;
292460510Sobrien		    ae->use_count += be->use_count;
292560510Sobrien		    *pbe = be->next;
292660510Sobrien		    goto global_found;
292760510Sobrien		  }
292860510Sobrien	      be->gotobj = a;
292960510Sobrien	      total += 1;
293060510Sobrien
293160510Sobrien	    global_found:;
293260510Sobrien	    }
293360510Sobrien        }
293460510Sobrien
293560510Sobrien      alpha_elf_tdata (bsub)->gotobj = a;
293660510Sobrien    }
293760510Sobrien  alpha_elf_tdata (a)->total_got_entries = total;
293860510Sobrien
293960510Sobrien  /* Merge the two in_got chains.  */
294060510Sobrien  {
294160510Sobrien    bfd *next;
294260510Sobrien
294360510Sobrien    bsub = a;
294460510Sobrien    while ((next = alpha_elf_tdata (bsub)->in_got_link_next) != NULL)
294560510Sobrien      bsub = next;
294660510Sobrien
294760510Sobrien    alpha_elf_tdata (bsub)->in_got_link_next = b;
294833965Sjdp  }
294933965Sjdp}
295033965Sjdp
295133965Sjdp/* Calculate the offsets for the got entries.  */
295233965Sjdp
295333965Sjdpstatic boolean
295433965Sjdpelf64_alpha_calc_got_offsets_for_symbol (h, arg)
295533965Sjdp     struct alpha_elf_link_hash_entry *h;
295633965Sjdp     PTR arg;
295733965Sjdp{
295833965Sjdp  struct alpha_elf_got_entry *gotent;
295933965Sjdp
296033965Sjdp  for (gotent = h->got_entries; gotent; gotent = gotent->next)
296160510Sobrien    if (gotent->use_count > 0)
296260510Sobrien      {
296360510Sobrien	bfd_size_type *plge
296460510Sobrien	  = &alpha_elf_tdata (gotent->gotobj)->got->_raw_size;
296533965Sjdp
296660510Sobrien	gotent->got_offset = *plge;
296760510Sobrien	*plge += 8;
296860510Sobrien      }
296960510Sobrien
297033965Sjdp  return true;
297133965Sjdp}
297233965Sjdp
297333965Sjdpstatic void
297433965Sjdpelf64_alpha_calc_got_offsets (info)
297533965Sjdp     struct bfd_link_info *info;
297633965Sjdp{
297733965Sjdp  bfd *i, *got_list = alpha_elf_hash_table(info)->got_list;
297833965Sjdp
297933965Sjdp  /* First, zero out the .got sizes, as we may be recalculating the
298033965Sjdp     .got after optimizing it.  */
298133965Sjdp  for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next)
298233965Sjdp    alpha_elf_tdata(i)->got->_raw_size = 0;
298333965Sjdp
298433965Sjdp  /* Next, fill in the offsets for all the global entries.  */
298533965Sjdp  alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
298633965Sjdp				elf64_alpha_calc_got_offsets_for_symbol,
298733965Sjdp				NULL);
298833965Sjdp
298933965Sjdp  /* Finally, fill in the offsets for the local entries.  */
299033965Sjdp  for (i = got_list; i ; i = alpha_elf_tdata(i)->got_link_next)
299133965Sjdp    {
299233965Sjdp      bfd_size_type got_offset = alpha_elf_tdata(i)->got->_raw_size;
299333965Sjdp      bfd *j;
299433965Sjdp
299533965Sjdp      for (j = i; j ; j = alpha_elf_tdata(j)->in_got_link_next)
299633965Sjdp	{
299733965Sjdp	  struct alpha_elf_got_entry **local_got_entries, *gotent;
299833965Sjdp	  int k, n;
299933965Sjdp
300033965Sjdp	  local_got_entries = alpha_elf_tdata(j)->local_got_entries;
300133965Sjdp	  if (!local_got_entries)
300233965Sjdp	    continue;
300333965Sjdp
300433965Sjdp	  for (k = 0, n = elf_tdata(j)->symtab_hdr.sh_info; k < n; ++k)
300533965Sjdp	    for (gotent = local_got_entries[k]; gotent; gotent = gotent->next)
300660510Sobrien	      if (gotent->use_count > 0)
300760510Sobrien	        {
300860510Sobrien		  gotent->got_offset = got_offset;
300960510Sobrien		  got_offset += 8;
301060510Sobrien	        }
301133965Sjdp	}
301233965Sjdp
301333965Sjdp      alpha_elf_tdata(i)->got->_raw_size = got_offset;
301460510Sobrien      alpha_elf_tdata(i)->got->_cooked_size = got_offset;
301533965Sjdp    }
301633965Sjdp}
301733965Sjdp
301833965Sjdp/* Constructs the gots.  */
301933965Sjdp
302033965Sjdpstatic boolean
302160510Sobrienelf64_alpha_size_got_sections (output_bfd, info)
302233965Sjdp     bfd *output_bfd;
302333965Sjdp     struct bfd_link_info *info;
302433965Sjdp{
302560510Sobrien  bfd *i, *got_list, *cur_got_obj;
302660510Sobrien  int something_changed = 0;
302733965Sjdp
302860510Sobrien  got_list = alpha_elf_hash_table (info)->got_list;
302933965Sjdp
303060510Sobrien  /* On the first time through, pretend we have an existing got list
303160510Sobrien     consisting of all of the input files.  */
303260510Sobrien  if (got_list == NULL)
303333965Sjdp    {
303460510Sobrien      for (i = info->input_bfds; i ; i = i->link_next)
303560510Sobrien	{
303660510Sobrien	  bfd *this_got = alpha_elf_tdata (i)->gotobj;
303760510Sobrien	  if (this_got == NULL)
303860510Sobrien	    continue;
303933965Sjdp
304060510Sobrien	  /* We are assuming no merging has yet ocurred.  */
304160510Sobrien	  BFD_ASSERT (this_got == i);
304233965Sjdp
304360510Sobrien          if (alpha_elf_tdata (this_got)->total_got_entries > MAX_GOT_ENTRIES)
304433965Sjdp	    {
304560510Sobrien	      /* Yikes! A single object file has too many entries.  */
304660510Sobrien	      (*_bfd_error_handler)
304760510Sobrien	        (_("%s: .got subsegment exceeds 64K (size %d)"),
304860510Sobrien	         bfd_get_filename (i),
304960510Sobrien	         alpha_elf_tdata (this_got)->total_got_entries * 8);
305060510Sobrien	      return false;
305133965Sjdp	    }
305260510Sobrien
305360510Sobrien	  if (got_list == NULL)
305460510Sobrien	    got_list = this_got;
305533965Sjdp	  else
305660510Sobrien	    alpha_elf_tdata(cur_got_obj)->got_link_next = this_got;
305760510Sobrien	  cur_got_obj = this_got;
305833965Sjdp	}
305960510Sobrien
306060510Sobrien      /* Strange degenerate case of no got references.  */
306160510Sobrien      if (got_list == NULL)
306260510Sobrien	return true;
306360510Sobrien
306460510Sobrien      alpha_elf_hash_table (info)->got_list = got_list;
306560510Sobrien
306660510Sobrien      /* Force got offsets to be recalculated.  */
306760510Sobrien      something_changed = 1;
306860510Sobrien    }
306960510Sobrien
307060510Sobrien  cur_got_obj = got_list;
307160510Sobrien  i = alpha_elf_tdata(cur_got_obj)->got_link_next;
307260510Sobrien  while (i != NULL)
307360510Sobrien    {
307460510Sobrien      if (elf64_alpha_can_merge_gots (cur_got_obj, i))
307560510Sobrien	{
307660510Sobrien	  elf64_alpha_merge_gots (cur_got_obj, i);
307760510Sobrien	  i = alpha_elf_tdata(i)->got_link_next;
307860510Sobrien	  alpha_elf_tdata(cur_got_obj)->got_link_next = i;
307960510Sobrien	  something_changed = 1;
308060510Sobrien	}
308133965Sjdp      else
308233965Sjdp	{
308333965Sjdp	  cur_got_obj = i;
308460510Sobrien	  i = alpha_elf_tdata(i)->got_link_next;
308533965Sjdp	}
308633965Sjdp    }
308733965Sjdp
308860510Sobrien  /* Once the gots have been merged, fill in the got offsets for
308960510Sobrien     everything therein.  */
309060510Sobrien  if (1 || something_changed)
309160510Sobrien    elf64_alpha_calc_got_offsets (info);
309233965Sjdp
309360510Sobrien  return true;
309460510Sobrien}
309533965Sjdp
309660510Sobrienstatic boolean
309760510Sobrienelf64_alpha_always_size_sections (output_bfd, info)
309860510Sobrien     bfd *output_bfd;
309960510Sobrien     struct bfd_link_info *info;
310060510Sobrien{
310160510Sobrien  bfd *i;
310260510Sobrien
310360510Sobrien  if (info->relocateable)
310460510Sobrien    return true;
310560510Sobrien
310660510Sobrien  /* First, take care of the indirect symbols created by versioning.  */
310760510Sobrien  alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
310860510Sobrien				elf64_alpha_merge_ind_symbols,
310960510Sobrien				NULL);
311060510Sobrien
311160510Sobrien  if (!elf64_alpha_size_got_sections (output_bfd, info))
311260510Sobrien    return false;
311360510Sobrien
311433965Sjdp  /* Allocate space for all of the .got subsections.  */
311560510Sobrien  i = alpha_elf_hash_table (info)->got_list;
311660510Sobrien  for ( ; i ; i = alpha_elf_tdata(i)->got_link_next)
311733965Sjdp    {
311833965Sjdp      asection *s = alpha_elf_tdata(i)->got;
311933965Sjdp      if (s->_raw_size > 0)
312033965Sjdp	{
312133965Sjdp	  s->contents = (bfd_byte *) bfd_zalloc (i, s->_raw_size);
312233965Sjdp	  if (s->contents == NULL)
312333965Sjdp	    return false;
312433965Sjdp	}
312533965Sjdp    }
312633965Sjdp
312733965Sjdp  return true;
312833965Sjdp}
312933965Sjdp
313033965Sjdp/* Work out the sizes of the dynamic relocation entries.  */
313133965Sjdp
313233965Sjdpstatic boolean
313333965Sjdpelf64_alpha_calc_dynrel_sizes (h, info)
313433965Sjdp     struct alpha_elf_link_hash_entry *h;
313533965Sjdp     struct bfd_link_info *info;
313633965Sjdp{
313733965Sjdp  /* If the symbol was defined as a common symbol in a regular object
313833965Sjdp     file, and there was no definition in any dynamic object, then the
313933965Sjdp     linker will have allocated space for the symbol in a common
314033965Sjdp     section but the ELF_LINK_HASH_DEF_REGULAR flag will not have been
314133965Sjdp     set.  This is done for dynamic symbols in
314233965Sjdp     elf_adjust_dynamic_symbol but this is not done for non-dynamic
314333965Sjdp     symbols, somehow.  */
314433965Sjdp  if (((h->root.elf_link_hash_flags
314533965Sjdp       & (ELF_LINK_HASH_DEF_REGULAR
314633965Sjdp	  | ELF_LINK_HASH_REF_REGULAR
314733965Sjdp	  | ELF_LINK_HASH_DEF_DYNAMIC))
314833965Sjdp       == ELF_LINK_HASH_REF_REGULAR)
314933965Sjdp      && (h->root.root.type == bfd_link_hash_defined
315033965Sjdp	  || h->root.root.type == bfd_link_hash_defweak)
315133965Sjdp      && !(h->root.root.u.def.section->owner->flags & DYNAMIC))
315233965Sjdp    {
315333965Sjdp      h->root.elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
315433965Sjdp    }
315533965Sjdp
315633965Sjdp  /* If the symbol is dynamic, we'll need all the relocations in their
315760510Sobrien     natural form.  If this is a shared object, and it has been forced
315860510Sobrien     local, we'll need the same number of RELATIVE relocations.  */
315960510Sobrien
316060510Sobrien  if (alpha_elf_dynamic_symbol_p (&h->root, info) || info->shared)
316133965Sjdp    {
316233965Sjdp      struct alpha_elf_reloc_entry *relent;
316348850Sdfr      bfd *dynobj;
316448850Sdfr      struct alpha_elf_got_entry *gotent;
316548850Sdfr      bfd_size_type count;
316648850Sdfr      asection *srel;
316733965Sjdp
316833965Sjdp      for (relent = h->reloc_entries; relent; relent = relent->next)
316960510Sobrien	if (relent->rtype == R_ALPHA_REFLONG
317060510Sobrien	    || relent->rtype == R_ALPHA_REFQUAD)
317160510Sobrien	  {
317260510Sobrien	    relent->srel->_raw_size +=
317377303Sobrien	      sizeof (Elf64_External_Rela) * relent->count;
317460510Sobrien	  }
317533965Sjdp
317648850Sdfr      dynobj = elf_hash_table(info)->dynobj;
317748850Sdfr      count = 0;
317848850Sdfr
317948850Sdfr      for (gotent = h->got_entries; gotent ; gotent = gotent->next)
318048850Sdfr	count++;
318148850Sdfr
318248850Sdfr      /* If we are using a .plt entry, subtract one, as the first
318348850Sdfr	 reference uses a .rela.plt entry instead.  */
318460510Sobrien      if (h->root.plt.offset != MINUS_ONE)
318548850Sdfr	count--;
318648850Sdfr
318748850Sdfr      if (count > 0)
318833965Sjdp	{
318948850Sdfr	  srel = bfd_get_section_by_name (dynobj, ".rela.got");
319048850Sdfr	  BFD_ASSERT (srel != NULL);
319148850Sdfr	  srel->_raw_size += sizeof (Elf64_External_Rela) * count;
319233965Sjdp	}
319333965Sjdp    }
319448850Sdfr
319533965Sjdp  return true;
319633965Sjdp}
319733965Sjdp
319833965Sjdp/* Set the sizes of the dynamic sections.  */
319933965Sjdp
320033965Sjdpstatic boolean
320133965Sjdpelf64_alpha_size_dynamic_sections (output_bfd, info)
320233965Sjdp     bfd *output_bfd;
320333965Sjdp     struct bfd_link_info *info;
320433965Sjdp{
320533965Sjdp  bfd *dynobj;
320633965Sjdp  asection *s;
320733965Sjdp  boolean reltext;
320833965Sjdp  boolean relplt;
320933965Sjdp
321033965Sjdp  dynobj = elf_hash_table(info)->dynobj;
321133965Sjdp  BFD_ASSERT(dynobj != NULL);
321233965Sjdp
321333965Sjdp  if (elf_hash_table (info)->dynamic_sections_created)
321433965Sjdp    {
321533965Sjdp      /* Set the contents of the .interp section to the interpreter.  */
321633965Sjdp      if (!info->shared)
321733965Sjdp	{
321833965Sjdp	  s = bfd_get_section_by_name (dynobj, ".interp");
321933965Sjdp	  BFD_ASSERT (s != NULL);
322033965Sjdp	  s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
322133965Sjdp	  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
322233965Sjdp	}
322333965Sjdp
322433965Sjdp      /* Now that we've seen all of the input files, we can decide which
322533965Sjdp	 symbols need dynamic relocation entries and which don't.  We've
322633965Sjdp	 collected information in check_relocs that we can now apply to
322733965Sjdp	 size the dynamic relocation sections.  */
322833965Sjdp      alpha_elf_link_hash_traverse (alpha_elf_hash_table (info),
322933965Sjdp				    elf64_alpha_calc_dynrel_sizes,
323033965Sjdp				    info);
323133965Sjdp
323233965Sjdp      /* When building shared libraries, each local .got entry needs a
323333965Sjdp	 RELATIVE reloc.  */
323433965Sjdp      if (info->shared)
323533965Sjdp	{
323633965Sjdp	  bfd *i;
323733965Sjdp	  asection *srel;
323833965Sjdp	  bfd_size_type count;
323933965Sjdp
324033965Sjdp	  srel = bfd_get_section_by_name (dynobj, ".rela.got");
324133965Sjdp	  BFD_ASSERT (srel != NULL);
324233965Sjdp
324333965Sjdp	  for (i = alpha_elf_hash_table(info)->got_list, count = 0;
324433965Sjdp	       i != NULL;
324533965Sjdp	       i = alpha_elf_tdata(i)->got_link_next)
324633965Sjdp	    count += alpha_elf_tdata(i)->n_local_got_entries;
324733965Sjdp
324877303Sobrien	  srel->_raw_size += count * sizeof (Elf64_External_Rela);
324933965Sjdp	}
325033965Sjdp    }
325133965Sjdp  /* else we're not dynamic and by definition we don't need such things.  */
325233965Sjdp
325333965Sjdp  /* The check_relocs and adjust_dynamic_symbol entry points have
325433965Sjdp     determined the sizes of the various dynamic sections.  Allocate
325533965Sjdp     memory for them.  */
325633965Sjdp  reltext = false;
325733965Sjdp  relplt = false;
325833965Sjdp  for (s = dynobj->sections; s != NULL; s = s->next)
325933965Sjdp    {
326033965Sjdp      const char *name;
326133965Sjdp      boolean strip;
326233965Sjdp
326333965Sjdp      if (!(s->flags & SEC_LINKER_CREATED))
326433965Sjdp	continue;
326533965Sjdp
326633965Sjdp      /* It's OK to base decisions on the section name, because none
326733965Sjdp	 of the dynobj section names depend upon the input files.  */
326833965Sjdp      name = bfd_get_section_name (dynobj, s);
326933965Sjdp
327033965Sjdp      /* If we don't need this section, strip it from the output file.
327133965Sjdp	 This is to handle .rela.bss and .rela.plt.  We must create it
327233965Sjdp	 in create_dynamic_sections, because it must be created before
327333965Sjdp	 the linker maps input sections to output sections.  The
327433965Sjdp	 linker does that before adjust_dynamic_symbol is called, and
327533965Sjdp	 it is that function which decides whether anything needs to
327633965Sjdp	 go into these sections.  */
327733965Sjdp
327833965Sjdp      strip = false;
327933965Sjdp
328033965Sjdp      if (strncmp (name, ".rela", 5) == 0)
328133965Sjdp	{
328233965Sjdp	  strip = (s->_raw_size == 0);
328333965Sjdp
328433965Sjdp	  if (!strip)
328533965Sjdp	    {
328633965Sjdp	      const char *outname;
328733965Sjdp	      asection *target;
328833965Sjdp
328933965Sjdp	      /* If this relocation section applies to a read only
329033965Sjdp		 section, then we probably need a DT_TEXTREL entry.  */
329133965Sjdp	      outname = bfd_get_section_name (output_bfd,
329233965Sjdp					      s->output_section);
329333965Sjdp	      target = bfd_get_section_by_name (output_bfd, outname + 5);
329433965Sjdp	      if (target != NULL
329538889Sjdp		  && (target->flags & SEC_READONLY) != 0
329638889Sjdp		  && (target->flags & SEC_ALLOC) != 0)
329733965Sjdp		reltext = true;
329833965Sjdp
329933965Sjdp	      if (strcmp(name, ".rela.plt") == 0)
330033965Sjdp		relplt = true;
330133965Sjdp
330233965Sjdp	      /* We use the reloc_count field as a counter if we need
330333965Sjdp		 to copy relocs into the output file.  */
330433965Sjdp	      s->reloc_count = 0;
330533965Sjdp	    }
330633965Sjdp	}
330733965Sjdp      else if (strcmp (name, ".plt") != 0)
330833965Sjdp	{
330933965Sjdp	  /* It's not one of our dynamic sections, so don't allocate space.  */
331033965Sjdp	  continue;
331133965Sjdp	}
331233965Sjdp
331333965Sjdp      if (strip)
331460510Sobrien	_bfd_strip_section_from_output (info, s);
331533965Sjdp      else
331633965Sjdp	{
331733965Sjdp	  /* Allocate memory for the section contents.  */
331833965Sjdp	  s->contents = (bfd_byte *) bfd_zalloc(dynobj, s->_raw_size);
331933965Sjdp	  if (s->contents == NULL && s->_raw_size != 0)
332033965Sjdp	    return false;
332133965Sjdp	}
332233965Sjdp    }
332333965Sjdp
332433965Sjdp  if (elf_hash_table (info)->dynamic_sections_created)
332533965Sjdp    {
332633965Sjdp      /* Add some entries to the .dynamic section.  We fill in the
332733965Sjdp	 values later, in elf64_alpha_finish_dynamic_sections, but we
332833965Sjdp	 must add the entries now so that we get the correct size for
332933965Sjdp	 the .dynamic section.  The DT_DEBUG entry is filled in by the
333033965Sjdp	 dynamic linker and used by the debugger.  */
333133965Sjdp      if (!info->shared)
333233965Sjdp	{
333333965Sjdp	  if (!bfd_elf64_add_dynamic_entry (info, DT_DEBUG, 0))
333433965Sjdp	    return false;
333533965Sjdp	}
333633965Sjdp
333733965Sjdp      if (! bfd_elf64_add_dynamic_entry (info, DT_PLTGOT, 0))
333833965Sjdp	return false;
333933965Sjdp
334033965Sjdp      if (relplt)
334133965Sjdp	{
334233965Sjdp	  if (! bfd_elf64_add_dynamic_entry (info, DT_PLTRELSZ, 0)
334333965Sjdp	      || ! bfd_elf64_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
334433965Sjdp	      || ! bfd_elf64_add_dynamic_entry (info, DT_JMPREL, 0))
334533965Sjdp	    return false;
334633965Sjdp	}
334733965Sjdp
334833965Sjdp      if (! bfd_elf64_add_dynamic_entry (info, DT_RELA, 0)
334933965Sjdp	  || ! bfd_elf64_add_dynamic_entry (info, DT_RELASZ, 0)
335033965Sjdp	  || ! bfd_elf64_add_dynamic_entry (info, DT_RELAENT,
335177303Sobrien					    sizeof (Elf64_External_Rela)))
335233965Sjdp	return false;
335333965Sjdp
335433965Sjdp      if (reltext)
335533965Sjdp	{
335633965Sjdp	  if (! bfd_elf64_add_dynamic_entry (info, DT_TEXTREL, 0))
335733965Sjdp	    return false;
335877303Sobrien	  info->flags |= DF_TEXTREL;
335933965Sjdp	}
336033965Sjdp    }
336133965Sjdp
336233965Sjdp  return true;
336333965Sjdp}
336433965Sjdp
336533965Sjdp/* Relocate an Alpha ELF section.  */
336633965Sjdp
336733965Sjdpstatic boolean
336833965Sjdpelf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section,
336933965Sjdp			      contents, relocs, local_syms, local_sections)
337033965Sjdp     bfd *output_bfd;
337133965Sjdp     struct bfd_link_info *info;
337233965Sjdp     bfd *input_bfd;
337333965Sjdp     asection *input_section;
337433965Sjdp     bfd_byte *contents;
337533965Sjdp     Elf_Internal_Rela *relocs;
337633965Sjdp     Elf_Internal_Sym *local_syms;
337733965Sjdp     asection **local_sections;
337833965Sjdp{
337933965Sjdp  Elf_Internal_Shdr *symtab_hdr;
338033965Sjdp  Elf_Internal_Rela *rel;
338133965Sjdp  Elf_Internal_Rela *relend;
338233965Sjdp  asection *sec, *sgot, *srel, *srelgot;
338333965Sjdp  bfd *dynobj, *gotobj;
338433965Sjdp  bfd_vma gp;
338533965Sjdp
338633965Sjdp  srelgot = srel = NULL;
338733965Sjdp  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
338833965Sjdp  dynobj = elf_hash_table (info)->dynobj;
338933965Sjdp  if (dynobj)
339033965Sjdp    {
339133965Sjdp      srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
339233965Sjdp    }
339333965Sjdp
339433965Sjdp  /* Find the gp value for this input bfd.  */
339533965Sjdp  sgot = NULL;
339633965Sjdp  gp = 0;
339733965Sjdp  gotobj = alpha_elf_tdata (input_bfd)->gotobj;
339833965Sjdp  if (gotobj)
339933965Sjdp    {
340033965Sjdp      sgot = alpha_elf_tdata (gotobj)->got;
340133965Sjdp      gp = _bfd_get_gp_value (gotobj);
340233965Sjdp      if (gp == 0)
340333965Sjdp	{
340433965Sjdp	  gp = (sgot->output_section->vma
340533965Sjdp		+ sgot->output_offset
340633965Sjdp		+ 0x8000);
340733965Sjdp	  _bfd_set_gp_value (gotobj, gp);
340833965Sjdp	}
340933965Sjdp    }
341033965Sjdp
341133965Sjdp  rel = relocs;
341233965Sjdp  relend = relocs + input_section->reloc_count;
341333965Sjdp  for (; rel < relend; rel++)
341433965Sjdp    {
341533965Sjdp      int r_type;
341633965Sjdp      reloc_howto_type *howto;
341733965Sjdp      unsigned long r_symndx;
341833965Sjdp      struct alpha_elf_link_hash_entry *h;
341933965Sjdp      Elf_Internal_Sym *sym;
342033965Sjdp      bfd_vma relocation;
342133965Sjdp      bfd_vma addend;
342233965Sjdp      bfd_reloc_status_type r;
342333965Sjdp
342433965Sjdp      r_type = ELF64_R_TYPE(rel->r_info);
342533965Sjdp      if (r_type < 0 || r_type >= (int) R_ALPHA_max)
342633965Sjdp	{
342733965Sjdp	  bfd_set_error (bfd_error_bad_value);
342833965Sjdp	  return false;
342933965Sjdp	}
343033965Sjdp      howto = elf64_alpha_howto_table + r_type;
343133965Sjdp
343233965Sjdp      r_symndx = ELF64_R_SYM(rel->r_info);
343333965Sjdp
343433965Sjdp      if (info->relocateable)
343533965Sjdp	{
343633965Sjdp	  /* This is a relocateable link.  We don't have to change
343733965Sjdp	     anything, unless the reloc is against a section symbol,
343833965Sjdp	     in which case we have to adjust according to where the
343933965Sjdp	     section symbol winds up in the output section.  */
344060510Sobrien
344177303Sobrien	  /* The symbol associated with GPDISP and LITUSE is
344260510Sobrien	     immaterial.  Only the addend is significant.  */
344360510Sobrien	  if (r_type == R_ALPHA_GPDISP || r_type == R_ALPHA_LITUSE)
344460510Sobrien	    continue;
344560510Sobrien
344633965Sjdp	  if (r_symndx < symtab_hdr->sh_info)
344733965Sjdp	    {
344833965Sjdp	      sym = local_syms + r_symndx;
344933965Sjdp	      if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
345033965Sjdp		{
345133965Sjdp		  sec = local_sections[r_symndx];
345233965Sjdp		  rel->r_addend += sec->output_offset + sym->st_value;
345333965Sjdp		}
345433965Sjdp	    }
345533965Sjdp
345633965Sjdp	  continue;
345733965Sjdp	}
345833965Sjdp
345933965Sjdp      /* This is a final link.  */
346033965Sjdp
346133965Sjdp      h = NULL;
346233965Sjdp      sym = NULL;
346333965Sjdp      sec = NULL;
346433965Sjdp
346533965Sjdp      if (r_symndx < symtab_hdr->sh_info)
346633965Sjdp	{
346733965Sjdp	  sym = local_syms + r_symndx;
346833965Sjdp	  sec = local_sections[r_symndx];
346933965Sjdp	  relocation = (sec->output_section->vma
347033965Sjdp			+ sec->output_offset
347133965Sjdp			+ sym->st_value);
347233965Sjdp	}
347333965Sjdp      else
347433965Sjdp	{
347533965Sjdp	  h = alpha_elf_sym_hashes (input_bfd)[r_symndx - symtab_hdr->sh_info];
347633965Sjdp
347733965Sjdp	  while (h->root.root.type == bfd_link_hash_indirect
347833965Sjdp		 || h->root.root.type == bfd_link_hash_warning)
347933965Sjdp	    h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
348033965Sjdp
348133965Sjdp	  if (h->root.root.type == bfd_link_hash_defined
348233965Sjdp	      || h->root.root.type == bfd_link_hash_defweak)
348333965Sjdp	    {
348433965Sjdp	      sec = h->root.root.u.def.section;
348533965Sjdp
348633965Sjdp#if rth_notdef
348733965Sjdp	      if ((r_type == R_ALPHA_LITERAL
348833965Sjdp		   && elf_hash_table(info)->dynamic_sections_created
348933965Sjdp		   && (!info->shared
349033965Sjdp		       || !info->symbolic
349133965Sjdp		       || !(h->root.elf_link_hash_flags
349233965Sjdp			    & ELF_LINK_HASH_DEF_REGULAR)))
349333965Sjdp		  || (info->shared
349433965Sjdp		      && (!info->symbolic
349533965Sjdp			  || !(h->root.elf_link_hash_flags
349633965Sjdp			       & ELF_LINK_HASH_DEF_REGULAR))
349733965Sjdp		      && (input_section->flags & SEC_ALLOC)
349833965Sjdp		      && (r_type == R_ALPHA_REFLONG
349933965Sjdp			  || r_type == R_ALPHA_REFQUAD
350033965Sjdp			  || r_type == R_ALPHA_LITERAL)))
350133965Sjdp		{
350233965Sjdp		  /* In these cases, we don't need the relocation value.
350333965Sjdp		     We check specially because in some obscure cases
350433965Sjdp		     sec->output_section will be NULL.  */
350533965Sjdp		  relocation = 0;
350633965Sjdp		}
350733965Sjdp#else
350833965Sjdp	      /* FIXME: Are not these obscure cases simply bugs?  Let's
350933965Sjdp		 get something working and come back to this.  */
351033965Sjdp	      if (sec->output_section == NULL)
351133965Sjdp		relocation = 0;
351233965Sjdp#endif /* rth_notdef */
351333965Sjdp	      else
351433965Sjdp		{
351533965Sjdp		  relocation = (h->root.root.u.def.value
351633965Sjdp				+ sec->output_section->vma
351733965Sjdp				+ sec->output_offset);
351833965Sjdp		}
351933965Sjdp	    }
352033965Sjdp	  else if (h->root.root.type == bfd_link_hash_undefweak)
352133965Sjdp	    relocation = 0;
352268770Sobrien	  else if (info->shared && !info->symbolic
352368770Sobrien		   && !info->no_undefined
352468770Sobrien		   && ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
352533965Sjdp	    relocation = 0;
352633965Sjdp	  else
352733965Sjdp	    {
352833965Sjdp	      if (!((*info->callbacks->undefined_symbol)
352933965Sjdp		    (info, h->root.root.root.string, input_bfd,
353060510Sobrien		     input_section, rel->r_offset,
353168770Sobrien		     (!info->shared || info->no_undefined
353268770Sobrien		      || ELF_ST_VISIBILITY (h->root.other)))))
353333965Sjdp		return false;
353433965Sjdp	      relocation = 0;
353533965Sjdp	    }
353633965Sjdp	}
353733965Sjdp      addend = rel->r_addend;
353833965Sjdp
353933965Sjdp      switch (r_type)
354033965Sjdp	{
354133965Sjdp	case R_ALPHA_GPDISP:
354233965Sjdp	  {
354333965Sjdp	    bfd_byte *p_ldah, *p_lda;
354433965Sjdp
354533965Sjdp	    BFD_ASSERT(gp != 0);
354633965Sjdp
354733965Sjdp	    relocation = (input_section->output_section->vma
354833965Sjdp			  + input_section->output_offset
354933965Sjdp			  + rel->r_offset);
355033965Sjdp
355133965Sjdp	    p_ldah = contents + rel->r_offset - input_section->vma;
355233965Sjdp	    p_lda = p_ldah + rel->r_addend;
355333965Sjdp
355433965Sjdp	    r = elf64_alpha_do_reloc_gpdisp (input_bfd, gp - relocation,
355533965Sjdp					     p_ldah, p_lda);
355633965Sjdp	  }
355733965Sjdp	  break;
355833965Sjdp
355933965Sjdp	case R_ALPHA_OP_PUSH:
356033965Sjdp	case R_ALPHA_OP_STORE:
356133965Sjdp	case R_ALPHA_OP_PSUB:
356233965Sjdp	case R_ALPHA_OP_PRSHIFT:
356333965Sjdp	  /* We hate these silly beasts.  */
356477303Sobrien	  abort ();
356533965Sjdp
356633965Sjdp	case R_ALPHA_LITERAL:
356733965Sjdp	  {
356833965Sjdp	    struct alpha_elf_got_entry *gotent;
356960510Sobrien	    boolean dynamic_symbol;
357033965Sjdp
357133965Sjdp	    BFD_ASSERT(sgot != NULL);
357233965Sjdp	    BFD_ASSERT(gp != 0);
357333965Sjdp
357433965Sjdp	    if (h != NULL)
357533965Sjdp	      {
357633965Sjdp		gotent = h->got_entries;
357760510Sobrien		dynamic_symbol = alpha_elf_dynamic_symbol_p (&h->root, info);
357833965Sjdp	      }
357933965Sjdp	    else
358033965Sjdp	      {
358133965Sjdp		gotent = (alpha_elf_tdata(input_bfd)->
358233965Sjdp			  local_got_entries[r_symndx]);
358360510Sobrien		dynamic_symbol = false;
358460510Sobrien	      }
358533965Sjdp
358660510Sobrien	    BFD_ASSERT(gotent != NULL);
358733965Sjdp
358860510Sobrien	    while (gotent->gotobj != gotobj || gotent->addend != addend)
358960510Sobrien	      gotent = gotent->next;
359033965Sjdp
359160510Sobrien	    BFD_ASSERT(gotent->use_count >= 1);
359233965Sjdp
359360510Sobrien	    /* Initialize the .got entry's value.  */
359460510Sobrien	    if (!(gotent->flags & ALPHA_ELF_GOT_ENTRY_RELOCS_DONE))
359560510Sobrien	      {
359660510Sobrien		bfd_put_64 (output_bfd, relocation+addend,
359760510Sobrien			    sgot->contents + gotent->got_offset);
359833965Sjdp
359960510Sobrien		/* If the symbol has been forced local, output a
360060510Sobrien		   RELATIVE reloc, otherwise it will be handled in
360160510Sobrien		   finish_dynamic_symbol.  */
360260510Sobrien		if (info->shared && !dynamic_symbol)
360360510Sobrien		  {
360460510Sobrien		    Elf_Internal_Rela outrel;
360533965Sjdp
360660510Sobrien		    BFD_ASSERT(srelgot != NULL);
360760510Sobrien
360860510Sobrien		    outrel.r_offset = (sgot->output_section->vma
360960510Sobrien				       + sgot->output_offset
361060510Sobrien				       + gotent->got_offset);
361160510Sobrien		    outrel.r_info = ELF64_R_INFO(0, R_ALPHA_RELATIVE);
361260510Sobrien		    outrel.r_addend = 0;
361360510Sobrien
361460510Sobrien		    bfd_elf64_swap_reloca_out (output_bfd, &outrel,
361560510Sobrien					       ((Elf64_External_Rela *)
361660510Sobrien					        srelgot->contents)
361760510Sobrien					       + srelgot->reloc_count++);
361877303Sobrien		    BFD_ASSERT (sizeof (Elf64_External_Rela)
361960510Sobrien				* srelgot->reloc_count
362060510Sobrien				<= srelgot->_cooked_size);
362133965Sjdp		  }
362260510Sobrien
362360510Sobrien		gotent->flags |= ALPHA_ELF_GOT_ENTRY_RELOCS_DONE;
362433965Sjdp	      }
362533965Sjdp
362633965Sjdp	    /* Figure the gprel relocation.  */
362733965Sjdp	    addend = 0;
362833965Sjdp	    relocation = (sgot->output_section->vma
362933965Sjdp			  + sgot->output_offset
363033965Sjdp			  + gotent->got_offset);
363133965Sjdp	    relocation -= gp;
363233965Sjdp	  }
363333965Sjdp	  /* overflow handled by _bfd_final_link_relocate */
363433965Sjdp	  goto default_reloc;
363533965Sjdp
363633965Sjdp	case R_ALPHA_GPREL32:
363760510Sobrien	case R_ALPHA_GPRELLOW:
363833965Sjdp	  BFD_ASSERT(gp != 0);
363933965Sjdp	  relocation -= gp;
364033965Sjdp	  goto default_reloc;
364133965Sjdp
364260510Sobrien	case R_ALPHA_GPRELHIGH:
364360510Sobrien	  BFD_ASSERT(gp != 0);
364460510Sobrien	  relocation -= gp;
364560510Sobrien	  relocation += addend;
364660510Sobrien	  addend = 0;
364760510Sobrien	  relocation = (((bfd_signed_vma) relocation >> 16)
364860510Sobrien			+ ((relocation >> 15) & 1));
364960510Sobrien	  goto default_reloc;
365060510Sobrien
365133965Sjdp	case R_ALPHA_BRADDR:
365233965Sjdp	case R_ALPHA_HINT:
365333965Sjdp	  /* The regular PC-relative stuff measures from the start of
365433965Sjdp	     the instruction rather than the end.  */
365533965Sjdp	  addend -= 4;
365633965Sjdp	  goto default_reloc;
365733965Sjdp
365833965Sjdp	case R_ALPHA_REFLONG:
365933965Sjdp	case R_ALPHA_REFQUAD:
366033965Sjdp	  {
366133965Sjdp	    Elf_Internal_Rela outrel;
366233965Sjdp	    boolean skip;
366333965Sjdp
366433965Sjdp	    /* Careful here to remember RELATIVE relocations for global
366533965Sjdp	       variables for symbolic shared objects.  */
366633965Sjdp
366733965Sjdp	    if (h && alpha_elf_dynamic_symbol_p (&h->root, info))
366833965Sjdp	      {
366933965Sjdp		BFD_ASSERT(h->root.dynindx != -1);
367033965Sjdp		outrel.r_info = ELF64_R_INFO(h->root.dynindx, r_type);
367133965Sjdp		outrel.r_addend = addend;
367233965Sjdp		addend = 0, relocation = 0;
367333965Sjdp	      }
367460510Sobrien	    else if (info->shared && (input_section->flags & SEC_ALLOC))
367533965Sjdp	      {
367633965Sjdp		outrel.r_info = ELF64_R_INFO(0, R_ALPHA_RELATIVE);
367733965Sjdp		outrel.r_addend = 0;
367833965Sjdp	      }
367933965Sjdp	    else
368033965Sjdp	      goto default_reloc;
368133965Sjdp
368233965Sjdp	    if (!srel)
368333965Sjdp	      {
368433965Sjdp		const char *name;
368533965Sjdp
368633965Sjdp		name = (bfd_elf_string_from_elf_section
368733965Sjdp			(input_bfd, elf_elfheader(input_bfd)->e_shstrndx,
368833965Sjdp			 elf_section_data(input_section)->rel_hdr.sh_name));
368933965Sjdp		BFD_ASSERT(name != NULL);
369033965Sjdp
369133965Sjdp		srel = bfd_get_section_by_name (dynobj, name);
369233965Sjdp		BFD_ASSERT(srel != NULL);
369333965Sjdp	      }
369433965Sjdp
369533965Sjdp	    skip = false;
369633965Sjdp
369733965Sjdp	    if (elf_section_data (input_section)->stab_info == NULL)
369833965Sjdp	      outrel.r_offset = rel->r_offset;
369933965Sjdp	    else
370033965Sjdp	      {
370133965Sjdp		bfd_vma off;
370233965Sjdp
370333965Sjdp		off = (_bfd_stab_section_offset
370433965Sjdp		       (output_bfd, &elf_hash_table (info)->stab_info,
370533965Sjdp			input_section,
370633965Sjdp			&elf_section_data (input_section)->stab_info,
370733965Sjdp			rel->r_offset));
370833965Sjdp		if (off == (bfd_vma) -1)
370933965Sjdp		  skip = true;
371033965Sjdp		outrel.r_offset = off;
371133965Sjdp	      }
371233965Sjdp
371333965Sjdp	    if (! skip)
371433965Sjdp	      outrel.r_offset += (input_section->output_section->vma
371533965Sjdp				  + input_section->output_offset);
371633965Sjdp	    else
371733965Sjdp	      memset (&outrel, 0, sizeof outrel);
371833965Sjdp
371933965Sjdp	    bfd_elf64_swap_reloca_out (output_bfd, &outrel,
372033965Sjdp				       ((Elf64_External_Rela *)
372133965Sjdp					srel->contents)
372233965Sjdp				       + srel->reloc_count++);
372377303Sobrien	    BFD_ASSERT (sizeof (Elf64_External_Rela) * srel->reloc_count
372448850Sdfr			<= srel->_cooked_size);
372533965Sjdp	  }
372633965Sjdp	  goto default_reloc;
372733965Sjdp
372833965Sjdp	default:
372933965Sjdp	default_reloc:
373033965Sjdp	  r = _bfd_final_link_relocate (howto, input_bfd, input_section,
373133965Sjdp					contents, rel->r_offset, relocation,
373233965Sjdp					addend);
373333965Sjdp	  break;
373433965Sjdp	}
373533965Sjdp
373633965Sjdp      switch (r)
373733965Sjdp	{
373833965Sjdp	case bfd_reloc_ok:
373933965Sjdp	  break;
374033965Sjdp
374133965Sjdp	case bfd_reloc_overflow:
374233965Sjdp	  {
374333965Sjdp	    const char *name;
374433965Sjdp
374533965Sjdp	    if (h != NULL)
374633965Sjdp	      name = h->root.root.root.string;
374733965Sjdp	    else
374833965Sjdp	      {
374933965Sjdp		name = (bfd_elf_string_from_elf_section
375033965Sjdp			(input_bfd, symtab_hdr->sh_link, sym->st_name));
375133965Sjdp		if (name == NULL)
375233965Sjdp		  return false;
375333965Sjdp		if (*name == '\0')
375433965Sjdp		  name = bfd_section_name (input_bfd, sec);
375533965Sjdp	      }
375633965Sjdp	    if (! ((*info->callbacks->reloc_overflow)
375733965Sjdp		   (info, name, howto->name, (bfd_vma) 0,
375833965Sjdp		    input_bfd, input_section, rel->r_offset)))
375933965Sjdp	      return false;
376033965Sjdp	  }
376133965Sjdp	  break;
376233965Sjdp
376333965Sjdp	default:
376433965Sjdp	case bfd_reloc_outofrange:
376533965Sjdp	  abort ();
376633965Sjdp	}
376733965Sjdp    }
376833965Sjdp
376933965Sjdp  return true;
377033965Sjdp}
377133965Sjdp
377233965Sjdp/* Finish up dynamic symbol handling.  We set the contents of various
377333965Sjdp   dynamic sections here.  */
377433965Sjdp
377533965Sjdpstatic boolean
377633965Sjdpelf64_alpha_finish_dynamic_symbol (output_bfd, info, h, sym)
377733965Sjdp     bfd *output_bfd;
377833965Sjdp     struct bfd_link_info *info;
377933965Sjdp     struct elf_link_hash_entry *h;
378033965Sjdp     Elf_Internal_Sym *sym;
378133965Sjdp{
378233965Sjdp  bfd *dynobj = elf_hash_table(info)->dynobj;
378333965Sjdp
378460510Sobrien  if (h->plt.offset != MINUS_ONE)
378533965Sjdp    {
378633965Sjdp      /* Fill in the .plt entry for this symbol.  */
378733965Sjdp      asection *splt, *sgot, *srel;
378833965Sjdp      Elf_Internal_Rela outrel;
378933965Sjdp      bfd_vma got_addr, plt_addr;
379033965Sjdp      bfd_vma plt_index;
379133965Sjdp      struct alpha_elf_got_entry *gotent;
379233965Sjdp
379333965Sjdp      BFD_ASSERT (h->dynindx != -1);
379433965Sjdp
379533965Sjdp      /* The first .got entry will be updated by the .plt with the
379633965Sjdp	 address of the target function.  */
379733965Sjdp      gotent = ((struct alpha_elf_link_hash_entry *) h)->got_entries;
379833965Sjdp      BFD_ASSERT (gotent && gotent->addend == 0);
379933965Sjdp
380033965Sjdp      splt = bfd_get_section_by_name (dynobj, ".plt");
380133965Sjdp      BFD_ASSERT (splt != NULL);
380233965Sjdp      srel = bfd_get_section_by_name (dynobj, ".rela.plt");
380333965Sjdp      BFD_ASSERT (srel != NULL);
380433965Sjdp      sgot = alpha_elf_tdata (gotent->gotobj)->got;
380533965Sjdp      BFD_ASSERT (sgot != NULL);
380633965Sjdp
380733965Sjdp      got_addr = (sgot->output_section->vma
380833965Sjdp		  + sgot->output_offset
380933965Sjdp		  + gotent->got_offset);
381033965Sjdp      plt_addr = (splt->output_section->vma
381133965Sjdp		  + splt->output_offset
381260510Sobrien		  + h->plt.offset);
381333965Sjdp
381460510Sobrien      plt_index = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
381533965Sjdp
381633965Sjdp      /* Fill in the entry in the procedure linkage table.  */
381733965Sjdp      {
381833965Sjdp	unsigned insn1, insn2, insn3;
381933965Sjdp
382060510Sobrien	insn1 = PLT_ENTRY_WORD1 | ((-(h->plt.offset + 4) >> 2) & 0x1fffff);
382138889Sjdp	insn2 = PLT_ENTRY_WORD2;
382238889Sjdp	insn3 = PLT_ENTRY_WORD3;
382333965Sjdp
382460510Sobrien	bfd_put_32 (output_bfd, insn1, splt->contents + h->plt.offset);
382560510Sobrien	bfd_put_32 (output_bfd, insn2, splt->contents + h->plt.offset + 4);
382660510Sobrien	bfd_put_32 (output_bfd, insn3, splt->contents + h->plt.offset + 8);
382733965Sjdp      }
382833965Sjdp
382933965Sjdp      /* Fill in the entry in the .rela.plt section.  */
383033965Sjdp      outrel.r_offset = got_addr;
383133965Sjdp      outrel.r_info = ELF64_R_INFO(h->dynindx, R_ALPHA_JMP_SLOT);
383233965Sjdp      outrel.r_addend = 0;
383333965Sjdp
383433965Sjdp      bfd_elf64_swap_reloca_out (output_bfd, &outrel,
383533965Sjdp				 ((Elf64_External_Rela *)srel->contents
383633965Sjdp				  + plt_index));
383733965Sjdp
383833965Sjdp      if (!(h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
383933965Sjdp	{
384033965Sjdp	  /* Mark the symbol as undefined, rather than as defined in the
384133965Sjdp	     .plt section.  Leave the value alone.  */
384233965Sjdp	  sym->st_shndx = SHN_UNDEF;
384333965Sjdp	}
384433965Sjdp
384533965Sjdp      /* Fill in the entries in the .got.  */
384633965Sjdp      bfd_put_64 (output_bfd, plt_addr, sgot->contents + gotent->got_offset);
384733965Sjdp
384833965Sjdp      /* Subsequent .got entries will continue to bounce through the .plt.  */
384948850Sdfr      if (gotent->next)
385033965Sjdp	{
385148850Sdfr	  srel = bfd_get_section_by_name (dynobj, ".rela.got");
385248850Sdfr	  BFD_ASSERT (! info->shared || srel != NULL);
385333965Sjdp
385448850Sdfr	  gotent = gotent->next;
385548850Sdfr	  do
385648850Sdfr	    {
385748850Sdfr	      sgot = alpha_elf_tdata(gotent->gotobj)->got;
385848850Sdfr	      BFD_ASSERT(sgot != NULL);
385948850Sdfr	      BFD_ASSERT(gotent->addend == 0);
386048850Sdfr
386148850Sdfr	      bfd_put_64 (output_bfd, plt_addr,
386248850Sdfr		          sgot->contents + gotent->got_offset);
386348850Sdfr
386448850Sdfr	      if (info->shared)
386548850Sdfr		{
386648850Sdfr		  outrel.r_offset = (sgot->output_section->vma
386748850Sdfr				     + sgot->output_offset
386848850Sdfr				     + gotent->got_offset);
386948850Sdfr		  outrel.r_info = ELF64_R_INFO(0, R_ALPHA_RELATIVE);
387048850Sdfr		  outrel.r_addend = 0;
387148850Sdfr
387248850Sdfr		  bfd_elf64_swap_reloca_out (output_bfd, &outrel,
387348850Sdfr					     ((Elf64_External_Rela *)
387448850Sdfr					      srel->contents)
387548850Sdfr					     + srel->reloc_count++);
387677303Sobrien		  BFD_ASSERT (sizeof (Elf64_External_Rela) * srel->reloc_count
387748850Sdfr			      <= srel->_cooked_size);
387848850Sdfr		}
387948850Sdfr
388048850Sdfr	      gotent = gotent->next;
388148850Sdfr	    }
388248850Sdfr          while (gotent != NULL);
388333965Sjdp	}
388433965Sjdp    }
388533965Sjdp  else if (alpha_elf_dynamic_symbol_p (h, info))
388633965Sjdp    {
388733965Sjdp      /* Fill in the dynamic relocations for this symbol's .got entries.  */
388833965Sjdp      asection *srel;
388933965Sjdp      Elf_Internal_Rela outrel;
389033965Sjdp      struct alpha_elf_got_entry *gotent;
389133965Sjdp
389233965Sjdp      srel = bfd_get_section_by_name (dynobj, ".rela.got");
389333965Sjdp      BFD_ASSERT (srel != NULL);
389433965Sjdp
389533965Sjdp      outrel.r_info = ELF64_R_INFO (h->dynindx, R_ALPHA_GLOB_DAT);
389633965Sjdp      for (gotent = ((struct alpha_elf_link_hash_entry *) h)->got_entries;
389733965Sjdp	   gotent != NULL;
389833965Sjdp	   gotent = gotent->next)
389933965Sjdp	{
390033965Sjdp	  asection *sgot = alpha_elf_tdata (gotent->gotobj)->got;
390133965Sjdp	  outrel.r_offset = (sgot->output_section->vma
390233965Sjdp			     + sgot->output_offset
390333965Sjdp			     + gotent->got_offset);
390433965Sjdp	  outrel.r_addend = gotent->addend;
390533965Sjdp
390633965Sjdp	  bfd_elf64_swap_reloca_out (output_bfd, &outrel,
390733965Sjdp				     ((Elf64_External_Rela *)srel->contents
390833965Sjdp				      + srel->reloc_count++));
390977303Sobrien	  BFD_ASSERT (sizeof (Elf64_External_Rela) * srel->reloc_count
391048850Sdfr		      <= srel->_cooked_size);
391133965Sjdp	}
391233965Sjdp    }
391333965Sjdp
391433965Sjdp  /* Mark some specially defined symbols as absolute.  */
391533965Sjdp  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
391633965Sjdp      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
391733965Sjdp      || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
391833965Sjdp    sym->st_shndx = SHN_ABS;
391933965Sjdp
392033965Sjdp  return true;
392133965Sjdp}
392233965Sjdp
392333965Sjdp/* Finish up the dynamic sections.  */
392433965Sjdp
392533965Sjdpstatic boolean
392633965Sjdpelf64_alpha_finish_dynamic_sections (output_bfd, info)
392733965Sjdp     bfd *output_bfd;
392833965Sjdp     struct bfd_link_info *info;
392933965Sjdp{
393033965Sjdp  bfd *dynobj;
393133965Sjdp  asection *sdyn;
393233965Sjdp
393333965Sjdp  dynobj = elf_hash_table (info)->dynobj;
393433965Sjdp  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
393533965Sjdp
393633965Sjdp  if (elf_hash_table (info)->dynamic_sections_created)
393733965Sjdp    {
393833965Sjdp      asection *splt;
393933965Sjdp      Elf64_External_Dyn *dyncon, *dynconend;
394033965Sjdp
394133965Sjdp      splt = bfd_get_section_by_name (dynobj, ".plt");
394233965Sjdp      BFD_ASSERT (splt != NULL && sdyn != NULL);
394333965Sjdp
394433965Sjdp      dyncon = (Elf64_External_Dyn *) sdyn->contents;
394533965Sjdp      dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
394633965Sjdp      for (; dyncon < dynconend; dyncon++)
394733965Sjdp	{
394833965Sjdp	  Elf_Internal_Dyn dyn;
394933965Sjdp	  const char *name;
395033965Sjdp	  asection *s;
395133965Sjdp
395233965Sjdp	  bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn);
395333965Sjdp
395433965Sjdp	  switch (dyn.d_tag)
395533965Sjdp	    {
395633965Sjdp	    case DT_PLTGOT:
395733965Sjdp	      name = ".plt";
395833965Sjdp	      goto get_vma;
395933965Sjdp	    case DT_PLTRELSZ:
396033965Sjdp	      name = ".rela.plt";
396133965Sjdp	      goto get_size;
396233965Sjdp	    case DT_JMPREL:
396333965Sjdp	      name = ".rela.plt";
396433965Sjdp	      goto get_vma;
396533965Sjdp
396633965Sjdp	    case DT_RELASZ:
396733965Sjdp	      /* My interpretation of the TIS v1.1 ELF document indicates
396833965Sjdp		 that RELASZ should not include JMPREL.  This is not what
396933965Sjdp		 the rest of the BFD does.  It is, however, what the
397033965Sjdp		 glibc ld.so wants.  Do this fixup here until we found
397133965Sjdp		 out who is right.  */
397233965Sjdp	      s = bfd_get_section_by_name (output_bfd, ".rela.plt");
397333965Sjdp	      if (s)
397433965Sjdp		{
397533965Sjdp		  dyn.d_un.d_val -=
397633965Sjdp		    (s->_cooked_size ? s->_cooked_size : s->_raw_size);
397733965Sjdp		}
397833965Sjdp	      break;
397933965Sjdp
398033965Sjdp	    get_vma:
398133965Sjdp	      s = bfd_get_section_by_name (output_bfd, name);
398233965Sjdp	      dyn.d_un.d_ptr = (s ? s->vma : 0);
398333965Sjdp	      break;
398433965Sjdp
398533965Sjdp	    get_size:
398633965Sjdp	      s = bfd_get_section_by_name (output_bfd, name);
398733965Sjdp	      dyn.d_un.d_val =
398833965Sjdp		(s->_cooked_size ? s->_cooked_size : s->_raw_size);
398933965Sjdp	      break;
399033965Sjdp	    }
399133965Sjdp
399233965Sjdp	  bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
399333965Sjdp	}
399433965Sjdp
399533965Sjdp      /* Initialize the PLT0 entry */
399633965Sjdp      if (splt->_raw_size > 0)
399733965Sjdp	{
399833965Sjdp	  bfd_put_32 (output_bfd, PLT_HEADER_WORD1, splt->contents);
399933965Sjdp	  bfd_put_32 (output_bfd, PLT_HEADER_WORD2, splt->contents + 4);
400033965Sjdp	  bfd_put_32 (output_bfd, PLT_HEADER_WORD3, splt->contents + 8);
400133965Sjdp	  bfd_put_32 (output_bfd, PLT_HEADER_WORD4, splt->contents + 12);
400233965Sjdp
400333965Sjdp	  /* The next two words will be filled in by ld.so */
400433965Sjdp	  bfd_put_64 (output_bfd, 0, splt->contents + 16);
400533965Sjdp	  bfd_put_64 (output_bfd, 0, splt->contents + 24);
400633965Sjdp
400733965Sjdp	  elf_section_data (splt->output_section)->this_hdr.sh_entsize =
400833965Sjdp	    PLT_HEADER_SIZE;
400933965Sjdp	}
401033965Sjdp    }
401133965Sjdp
401233965Sjdp  return true;
401333965Sjdp}
401433965Sjdp
401533965Sjdp/* We need to use a special link routine to handle the .reginfo and
401633965Sjdp   the .mdebug sections.  We need to merge all instances of these
401733965Sjdp   sections together, not write them all out sequentially.  */
401833965Sjdp
401933965Sjdpstatic boolean
402033965Sjdpelf64_alpha_final_link (abfd, info)
402133965Sjdp     bfd *abfd;
402233965Sjdp     struct bfd_link_info *info;
402333965Sjdp{
402433965Sjdp  asection *o;
402533965Sjdp  struct bfd_link_order *p;
402633965Sjdp  asection *reginfo_sec, *mdebug_sec, *gptab_data_sec, *gptab_bss_sec;
402733965Sjdp  struct ecoff_debug_info debug;
402833965Sjdp  const struct ecoff_debug_swap *swap
402933965Sjdp    = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
403033965Sjdp  HDRR *symhdr = &debug.symbolic_header;
403133965Sjdp  PTR mdebug_handle = NULL;
403233965Sjdp
403360510Sobrien#if 0
403460510Sobrien	      if (++ngots == 2)
403560510Sobrien		{
403660510Sobrien		  (*info->callbacks->warning)
403760510Sobrien		    (info, _("using multiple gp values"), (char *) NULL,
403860510Sobrien		     output_bfd, (asection *) NULL, (bfd_vma) 0);
403960510Sobrien		}
404060510Sobrien#endif
404160510Sobrien
404233965Sjdp  /* Go through the sections and collect the .reginfo and .mdebug
404333965Sjdp     information.  */
404433965Sjdp  reginfo_sec = NULL;
404533965Sjdp  mdebug_sec = NULL;
404633965Sjdp  gptab_data_sec = NULL;
404733965Sjdp  gptab_bss_sec = NULL;
404833965Sjdp  for (o = abfd->sections; o != (asection *) NULL; o = o->next)
404933965Sjdp    {
405033965Sjdp#ifdef ERIC_neverdef
405133965Sjdp      if (strcmp (o->name, ".reginfo") == 0)
405233965Sjdp	{
405333965Sjdp	  memset (&reginfo, 0, sizeof reginfo);
405433965Sjdp
405533965Sjdp	  /* We have found the .reginfo section in the output file.
405633965Sjdp	     Look through all the link_orders comprising it and merge
405733965Sjdp	     the information together.  */
405833965Sjdp	  for (p = o->link_order_head;
405933965Sjdp	       p != (struct bfd_link_order *) NULL;
406033965Sjdp	       p = p->next)
406133965Sjdp	    {
406233965Sjdp	      asection *input_section;
406333965Sjdp	      bfd *input_bfd;
406433965Sjdp	      Elf64_External_RegInfo ext;
406533965Sjdp	      Elf64_RegInfo sub;
406633965Sjdp
406733965Sjdp	      if (p->type != bfd_indirect_link_order)
406833965Sjdp		{
406933965Sjdp		  if (p->type == bfd_fill_link_order)
407033965Sjdp		    continue;
407133965Sjdp		  abort ();
407233965Sjdp		}
407333965Sjdp
407433965Sjdp	      input_section = p->u.indirect.section;
407533965Sjdp	      input_bfd = input_section->owner;
407633965Sjdp
407733965Sjdp	      /* The linker emulation code has probably clobbered the
407833965Sjdp                 size to be zero bytes.  */
407933965Sjdp	      if (input_section->_raw_size == 0)
408033965Sjdp		input_section->_raw_size = sizeof (Elf64_External_RegInfo);
408133965Sjdp
408233965Sjdp	      if (! bfd_get_section_contents (input_bfd, input_section,
408333965Sjdp					      (PTR) &ext,
408433965Sjdp					      (file_ptr) 0,
408533965Sjdp					      sizeof ext))
408633965Sjdp		return false;
408733965Sjdp
408833965Sjdp	      bfd_alpha_elf64_swap_reginfo_in (input_bfd, &ext, &sub);
408933965Sjdp
409033965Sjdp	      reginfo.ri_gprmask |= sub.ri_gprmask;
409133965Sjdp	      reginfo.ri_cprmask[0] |= sub.ri_cprmask[0];
409233965Sjdp	      reginfo.ri_cprmask[1] |= sub.ri_cprmask[1];
409333965Sjdp	      reginfo.ri_cprmask[2] |= sub.ri_cprmask[2];
409433965Sjdp	      reginfo.ri_cprmask[3] |= sub.ri_cprmask[3];
409533965Sjdp
409633965Sjdp	      /* ri_gp_value is set by the function
409733965Sjdp		 alpha_elf_section_processing when the section is
409833965Sjdp		 finally written out.  */
409933965Sjdp
410033965Sjdp	      /* Hack: reset the SEC_HAS_CONTENTS flag so that
410133965Sjdp		 elf_link_input_bfd ignores this section.  */
410233965Sjdp	      input_section->flags &=~ SEC_HAS_CONTENTS;
410333965Sjdp	    }
410433965Sjdp
410533965Sjdp	  /* Force the section size to the value we want.  */
410633965Sjdp	  o->_raw_size = sizeof (Elf64_External_RegInfo);
410733965Sjdp
410833965Sjdp	  /* Skip this section later on (I don't think this currently
410933965Sjdp	     matters, but someday it might).  */
411033965Sjdp	  o->link_order_head = (struct bfd_link_order *) NULL;
411133965Sjdp
411233965Sjdp	  reginfo_sec = o;
411333965Sjdp	}
411433965Sjdp#endif
411533965Sjdp
411633965Sjdp      if (strcmp (o->name, ".mdebug") == 0)
411733965Sjdp	{
411833965Sjdp	  struct extsym_info einfo;
411933965Sjdp
412033965Sjdp	  /* We have found the .mdebug section in the output file.
412133965Sjdp	     Look through all the link_orders comprising it and merge
412233965Sjdp	     the information together.  */
412333965Sjdp	  symhdr->magic = swap->sym_magic;
412433965Sjdp	  /* FIXME: What should the version stamp be?  */
412533965Sjdp	  symhdr->vstamp = 0;
412633965Sjdp	  symhdr->ilineMax = 0;
412733965Sjdp	  symhdr->cbLine = 0;
412833965Sjdp	  symhdr->idnMax = 0;
412933965Sjdp	  symhdr->ipdMax = 0;
413033965Sjdp	  symhdr->isymMax = 0;
413133965Sjdp	  symhdr->ioptMax = 0;
413233965Sjdp	  symhdr->iauxMax = 0;
413333965Sjdp	  symhdr->issMax = 0;
413433965Sjdp	  symhdr->issExtMax = 0;
413533965Sjdp	  symhdr->ifdMax = 0;
413633965Sjdp	  symhdr->crfd = 0;
413733965Sjdp	  symhdr->iextMax = 0;
413833965Sjdp
413933965Sjdp	  /* We accumulate the debugging information itself in the
414033965Sjdp	     debug_info structure.  */
414133965Sjdp	  debug.line = NULL;
414233965Sjdp	  debug.external_dnr = NULL;
414333965Sjdp	  debug.external_pdr = NULL;
414433965Sjdp	  debug.external_sym = NULL;
414533965Sjdp	  debug.external_opt = NULL;
414633965Sjdp	  debug.external_aux = NULL;
414733965Sjdp	  debug.ss = NULL;
414833965Sjdp	  debug.ssext = debug.ssext_end = NULL;
414933965Sjdp	  debug.external_fdr = NULL;
415033965Sjdp	  debug.external_rfd = NULL;
415133965Sjdp	  debug.external_ext = debug.external_ext_end = NULL;
415233965Sjdp
415333965Sjdp	  mdebug_handle = bfd_ecoff_debug_init (abfd, &debug, swap, info);
415433965Sjdp	  if (mdebug_handle == (PTR) NULL)
415533965Sjdp	    return false;
415633965Sjdp
415733965Sjdp	  if (1)
415833965Sjdp	    {
415933965Sjdp	      asection *s;
416033965Sjdp	      EXTR esym;
416133965Sjdp	      bfd_vma last;
416233965Sjdp	      unsigned int i;
416333965Sjdp	      static const char * const name[] =
416433965Sjdp		{
416533965Sjdp		  ".text", ".init", ".fini", ".data",
416633965Sjdp		  ".rodata", ".sdata", ".sbss", ".bss"
416733965Sjdp		};
416833965Sjdp	      static const int sc[] = { scText, scInit, scFini, scData,
416933965Sjdp					  scRData, scSData, scSBss, scBss };
417033965Sjdp
417133965Sjdp	      esym.jmptbl = 0;
417233965Sjdp	      esym.cobol_main = 0;
417333965Sjdp	      esym.weakext = 0;
417433965Sjdp	      esym.reserved = 0;
417533965Sjdp	      esym.ifd = ifdNil;
417633965Sjdp	      esym.asym.iss = issNil;
417733965Sjdp	      esym.asym.st = stLocal;
417833965Sjdp	      esym.asym.reserved = 0;
417933965Sjdp	      esym.asym.index = indexNil;
418033965Sjdp	      for (i = 0; i < 8; i++)
418133965Sjdp		{
418233965Sjdp		  esym.asym.sc = sc[i];
418333965Sjdp		  s = bfd_get_section_by_name (abfd, name[i]);
418433965Sjdp		  if (s != NULL)
418533965Sjdp		    {
418633965Sjdp		      esym.asym.value = s->vma;
418733965Sjdp		      last = s->vma + s->_raw_size;
418833965Sjdp		    }
418933965Sjdp		  else
419033965Sjdp		    esym.asym.value = last;
419133965Sjdp
419233965Sjdp		  if (! bfd_ecoff_debug_one_external (abfd, &debug, swap,
419333965Sjdp						      name[i], &esym))
419433965Sjdp		    return false;
419533965Sjdp		}
419633965Sjdp	    }
419733965Sjdp
419833965Sjdp	  for (p = o->link_order_head;
419933965Sjdp	       p != (struct bfd_link_order *) NULL;
420033965Sjdp	       p = p->next)
420133965Sjdp	    {
420233965Sjdp	      asection *input_section;
420333965Sjdp	      bfd *input_bfd;
420433965Sjdp	      const struct ecoff_debug_swap *input_swap;
420533965Sjdp	      struct ecoff_debug_info input_debug;
420633965Sjdp	      char *eraw_src;
420733965Sjdp	      char *eraw_end;
420833965Sjdp
420933965Sjdp	      if (p->type != bfd_indirect_link_order)
421033965Sjdp		{
421133965Sjdp		  if (p->type == bfd_fill_link_order)
421233965Sjdp		    continue;
421333965Sjdp		  abort ();
421433965Sjdp		}
421533965Sjdp
421633965Sjdp	      input_section = p->u.indirect.section;
421733965Sjdp	      input_bfd = input_section->owner;
421833965Sjdp
421933965Sjdp	      if (bfd_get_flavour (input_bfd) != bfd_target_elf_flavour
422033965Sjdp		  || (get_elf_backend_data (input_bfd)
422133965Sjdp		      ->elf_backend_ecoff_debug_swap) == NULL)
422233965Sjdp		{
422333965Sjdp		  /* I don't know what a non ALPHA ELF bfd would be
422433965Sjdp		     doing with a .mdebug section, but I don't really
422533965Sjdp		     want to deal with it.  */
422633965Sjdp		  continue;
422733965Sjdp		}
422833965Sjdp
422933965Sjdp	      input_swap = (get_elf_backend_data (input_bfd)
423033965Sjdp			    ->elf_backend_ecoff_debug_swap);
423133965Sjdp
423233965Sjdp	      BFD_ASSERT (p->size == input_section->_raw_size);
423333965Sjdp
423433965Sjdp	      /* The ECOFF linking code expects that we have already
423533965Sjdp		 read in the debugging information and set up an
423633965Sjdp		 ecoff_debug_info structure, so we do that now.  */
423733965Sjdp	      if (!elf64_alpha_read_ecoff_info (input_bfd, input_section,
423833965Sjdp						&input_debug))
423933965Sjdp		return false;
424033965Sjdp
424133965Sjdp	      if (! (bfd_ecoff_debug_accumulate
424233965Sjdp		     (mdebug_handle, abfd, &debug, swap, input_bfd,
424333965Sjdp		      &input_debug, input_swap, info)))
424433965Sjdp		return false;
424533965Sjdp
424633965Sjdp	      /* Loop through the external symbols.  For each one with
424733965Sjdp		 interesting information, try to find the symbol in
424833965Sjdp		 the linker global hash table and save the information
424933965Sjdp		 for the output external symbols.  */
425033965Sjdp	      eraw_src = input_debug.external_ext;
425133965Sjdp	      eraw_end = (eraw_src
425233965Sjdp			  + (input_debug.symbolic_header.iextMax
425333965Sjdp			     * input_swap->external_ext_size));
425433965Sjdp	      for (;
425533965Sjdp		   eraw_src < eraw_end;
425633965Sjdp		   eraw_src += input_swap->external_ext_size)
425733965Sjdp		{
425833965Sjdp		  EXTR ext;
425933965Sjdp		  const char *name;
426033965Sjdp		  struct alpha_elf_link_hash_entry *h;
426133965Sjdp
426233965Sjdp		  (*input_swap->swap_ext_in) (input_bfd, (PTR) eraw_src, &ext);
426333965Sjdp		  if (ext.asym.sc == scNil
426433965Sjdp		      || ext.asym.sc == scUndefined
426533965Sjdp		      || ext.asym.sc == scSUndefined)
426633965Sjdp		    continue;
426733965Sjdp
426833965Sjdp		  name = input_debug.ssext + ext.asym.iss;
426933965Sjdp		  h = alpha_elf_link_hash_lookup (alpha_elf_hash_table (info),
427033965Sjdp						  name, false, false, true);
427133965Sjdp		  if (h == NULL || h->esym.ifd != -2)
427233965Sjdp		    continue;
427333965Sjdp
427433965Sjdp		  if (ext.ifd != -1)
427533965Sjdp		    {
427633965Sjdp		      BFD_ASSERT (ext.ifd
427733965Sjdp				  < input_debug.symbolic_header.ifdMax);
427833965Sjdp		      ext.ifd = input_debug.ifdmap[ext.ifd];
427933965Sjdp		    }
428033965Sjdp
428133965Sjdp		  h->esym = ext;
428233965Sjdp		}
428333965Sjdp
428433965Sjdp	      /* Free up the information we just read.  */
428533965Sjdp	      free (input_debug.line);
428633965Sjdp	      free (input_debug.external_dnr);
428733965Sjdp	      free (input_debug.external_pdr);
428833965Sjdp	      free (input_debug.external_sym);
428933965Sjdp	      free (input_debug.external_opt);
429033965Sjdp	      free (input_debug.external_aux);
429133965Sjdp	      free (input_debug.ss);
429233965Sjdp	      free (input_debug.ssext);
429333965Sjdp	      free (input_debug.external_fdr);
429433965Sjdp	      free (input_debug.external_rfd);
429533965Sjdp	      free (input_debug.external_ext);
429633965Sjdp
429733965Sjdp	      /* Hack: reset the SEC_HAS_CONTENTS flag so that
429833965Sjdp		 elf_link_input_bfd ignores this section.  */
429933965Sjdp	      input_section->flags &=~ SEC_HAS_CONTENTS;
430033965Sjdp	    }
430133965Sjdp
430233965Sjdp#ifdef ERIC_neverdef
430333965Sjdp	  if (info->shared)
430433965Sjdp	    {
430533965Sjdp	      /* Create .rtproc section.  */
430633965Sjdp	      rtproc_sec = bfd_get_section_by_name (abfd, ".rtproc");
430733965Sjdp	      if (rtproc_sec == NULL)
430833965Sjdp		{
430933965Sjdp		  flagword flags = (SEC_HAS_CONTENTS
431033965Sjdp				    | SEC_IN_MEMORY
431133965Sjdp				    | SEC_LINKER_CREATED
431233965Sjdp				    | SEC_READONLY);
431333965Sjdp
431433965Sjdp		  rtproc_sec = bfd_make_section (abfd, ".rtproc");
431533965Sjdp		  if (rtproc_sec == NULL
431633965Sjdp		      || ! bfd_set_section_flags (abfd, rtproc_sec, flags)
431733965Sjdp		      || ! bfd_set_section_alignment (abfd, rtproc_sec, 12))
431833965Sjdp		    return false;
431933965Sjdp		}
432033965Sjdp
432133965Sjdp	      if (! alpha_elf_create_procedure_table (mdebug_handle, abfd,
432233965Sjdp						     info, rtproc_sec, &debug))
432333965Sjdp		return false;
432433965Sjdp	    }
432533965Sjdp#endif
432633965Sjdp
432733965Sjdp	  /* Build the external symbol information.  */
432833965Sjdp	  einfo.abfd = abfd;
432933965Sjdp	  einfo.info = info;
433033965Sjdp	  einfo.debug = &debug;
433133965Sjdp	  einfo.swap = swap;
433233965Sjdp	  einfo.failed = false;
433333965Sjdp	  elf_link_hash_traverse (elf_hash_table (info),
433433965Sjdp				  elf64_alpha_output_extsym,
433533965Sjdp				  (PTR) &einfo);
433633965Sjdp	  if (einfo.failed)
433733965Sjdp	    return false;
433833965Sjdp
433933965Sjdp	  /* Set the size of the .mdebug section.  */
434033965Sjdp	  o->_raw_size = bfd_ecoff_debug_size (abfd, &debug, swap);
434133965Sjdp
434233965Sjdp	  /* Skip this section later on (I don't think this currently
434333965Sjdp	     matters, but someday it might).  */
434433965Sjdp	  o->link_order_head = (struct bfd_link_order *) NULL;
434533965Sjdp
434633965Sjdp	  mdebug_sec = o;
434733965Sjdp	}
434833965Sjdp
434933965Sjdp#ifdef ERIC_neverdef
435033965Sjdp      if (strncmp (o->name, ".gptab.", sizeof ".gptab." - 1) == 0)
435133965Sjdp	{
435233965Sjdp	  const char *subname;
435333965Sjdp	  unsigned int c;
435433965Sjdp	  Elf64_gptab *tab;
435533965Sjdp	  Elf64_External_gptab *ext_tab;
435633965Sjdp	  unsigned int i;
435733965Sjdp
435833965Sjdp	  /* The .gptab.sdata and .gptab.sbss sections hold
435933965Sjdp	     information describing how the small data area would
436033965Sjdp	     change depending upon the -G switch.  These sections
436133965Sjdp	     not used in executables files.  */
436233965Sjdp	  if (! info->relocateable)
436333965Sjdp	    {
436433965Sjdp	      asection **secpp;
436533965Sjdp
436633965Sjdp	      for (p = o->link_order_head;
436733965Sjdp		   p != (struct bfd_link_order *) NULL;
436833965Sjdp		   p = p->next)
436933965Sjdp		{
437033965Sjdp		  asection *input_section;
437133965Sjdp
437233965Sjdp		  if (p->type != bfd_indirect_link_order)
437333965Sjdp		    {
437433965Sjdp		      if (p->type == bfd_fill_link_order)
437533965Sjdp			continue;
437633965Sjdp		      abort ();
437733965Sjdp		    }
437833965Sjdp
437933965Sjdp		  input_section = p->u.indirect.section;
438033965Sjdp
438133965Sjdp		  /* Hack: reset the SEC_HAS_CONTENTS flag so that
438233965Sjdp		     elf_link_input_bfd ignores this section.  */
438333965Sjdp		  input_section->flags &=~ SEC_HAS_CONTENTS;
438433965Sjdp		}
438533965Sjdp
438633965Sjdp	      /* Skip this section later on (I don't think this
438733965Sjdp		 currently matters, but someday it might).  */
438833965Sjdp	      o->link_order_head = (struct bfd_link_order *) NULL;
438933965Sjdp
439033965Sjdp	      /* Really remove the section.  */
439133965Sjdp	      for (secpp = &abfd->sections;
439233965Sjdp		   *secpp != o;
439333965Sjdp		   secpp = &(*secpp)->next)
439433965Sjdp		;
439533965Sjdp	      *secpp = (*secpp)->next;
439633965Sjdp	      --abfd->section_count;
439733965Sjdp
439833965Sjdp	      continue;
439933965Sjdp	    }
440033965Sjdp
440133965Sjdp	  /* There is one gptab for initialized data, and one for
440233965Sjdp	     uninitialized data.  */
440333965Sjdp	  if (strcmp (o->name, ".gptab.sdata") == 0)
440433965Sjdp	    gptab_data_sec = o;
440533965Sjdp	  else if (strcmp (o->name, ".gptab.sbss") == 0)
440633965Sjdp	    gptab_bss_sec = o;
440733965Sjdp	  else
440833965Sjdp	    {
440933965Sjdp	      (*_bfd_error_handler)
441060510Sobrien		(_("%s: illegal section name `%s'"),
441133965Sjdp		 bfd_get_filename (abfd), o->name);
441233965Sjdp	      bfd_set_error (bfd_error_nonrepresentable_section);
441333965Sjdp	      return false;
441433965Sjdp	    }
441533965Sjdp
441633965Sjdp	  /* The linker script always combines .gptab.data and
441733965Sjdp	     .gptab.sdata into .gptab.sdata, and likewise for
441833965Sjdp	     .gptab.bss and .gptab.sbss.  It is possible that there is
441933965Sjdp	     no .sdata or .sbss section in the output file, in which
442033965Sjdp	     case we must change the name of the output section.  */
442133965Sjdp	  subname = o->name + sizeof ".gptab" - 1;
442233965Sjdp	  if (bfd_get_section_by_name (abfd, subname) == NULL)
442333965Sjdp	    {
442433965Sjdp	      if (o == gptab_data_sec)
442533965Sjdp		o->name = ".gptab.data";
442633965Sjdp	      else
442733965Sjdp		o->name = ".gptab.bss";
442833965Sjdp	      subname = o->name + sizeof ".gptab" - 1;
442933965Sjdp	      BFD_ASSERT (bfd_get_section_by_name (abfd, subname) != NULL);
443033965Sjdp	    }
443133965Sjdp
443233965Sjdp	  /* Set up the first entry.  */
443333965Sjdp	  c = 1;
443433965Sjdp	  tab = (Elf64_gptab *) bfd_malloc (c * sizeof (Elf64_gptab));
443533965Sjdp	  if (tab == NULL)
443633965Sjdp	    return false;
443733965Sjdp	  tab[0].gt_header.gt_current_g_value = elf_gp_size (abfd);
443833965Sjdp	  tab[0].gt_header.gt_unused = 0;
443933965Sjdp
444033965Sjdp	  /* Combine the input sections.  */
444133965Sjdp	  for (p = o->link_order_head;
444233965Sjdp	       p != (struct bfd_link_order *) NULL;
444333965Sjdp	       p = p->next)
444433965Sjdp	    {
444533965Sjdp	      asection *input_section;
444633965Sjdp	      bfd *input_bfd;
444733965Sjdp	      bfd_size_type size;
444833965Sjdp	      unsigned long last;
444933965Sjdp	      bfd_size_type gpentry;
445033965Sjdp
445133965Sjdp	      if (p->type != bfd_indirect_link_order)
445233965Sjdp		{
445333965Sjdp		  if (p->type == bfd_fill_link_order)
445433965Sjdp		    continue;
445533965Sjdp		  abort ();
445633965Sjdp		}
445733965Sjdp
445833965Sjdp	      input_section = p->u.indirect.section;
445933965Sjdp	      input_bfd = input_section->owner;
446033965Sjdp
446133965Sjdp	      /* Combine the gptab entries for this input section one
446233965Sjdp		 by one.  We know that the input gptab entries are
446333965Sjdp		 sorted by ascending -G value.  */
446433965Sjdp	      size = bfd_section_size (input_bfd, input_section);
446533965Sjdp	      last = 0;
446633965Sjdp	      for (gpentry = sizeof (Elf64_External_gptab);
446733965Sjdp		   gpentry < size;
446833965Sjdp		   gpentry += sizeof (Elf64_External_gptab))
446933965Sjdp		{
447033965Sjdp		  Elf64_External_gptab ext_gptab;
447133965Sjdp		  Elf64_gptab int_gptab;
447233965Sjdp		  unsigned long val;
447333965Sjdp		  unsigned long add;
447433965Sjdp		  boolean exact;
447533965Sjdp		  unsigned int look;
447633965Sjdp
447733965Sjdp		  if (! (bfd_get_section_contents
447833965Sjdp			 (input_bfd, input_section, (PTR) &ext_gptab,
447933965Sjdp			  gpentry, sizeof (Elf64_External_gptab))))
448033965Sjdp		    {
448133965Sjdp		      free (tab);
448233965Sjdp		      return false;
448333965Sjdp		    }
448433965Sjdp
448533965Sjdp		  bfd_alpha_elf64_swap_gptab_in (input_bfd, &ext_gptab,
448633965Sjdp						&int_gptab);
448733965Sjdp		  val = int_gptab.gt_entry.gt_g_value;
448833965Sjdp		  add = int_gptab.gt_entry.gt_bytes - last;
448933965Sjdp
449033965Sjdp		  exact = false;
449133965Sjdp		  for (look = 1; look < c; look++)
449233965Sjdp		    {
449333965Sjdp		      if (tab[look].gt_entry.gt_g_value >= val)
449433965Sjdp			tab[look].gt_entry.gt_bytes += add;
449533965Sjdp
449633965Sjdp		      if (tab[look].gt_entry.gt_g_value == val)
449733965Sjdp			exact = true;
449833965Sjdp		    }
449933965Sjdp
450033965Sjdp		  if (! exact)
450133965Sjdp		    {
450233965Sjdp		      Elf64_gptab *new_tab;
450333965Sjdp		      unsigned int max;
450433965Sjdp
450533965Sjdp		      /* We need a new table entry.  */
450633965Sjdp		      new_tab = ((Elf64_gptab *)
450733965Sjdp				 bfd_realloc ((PTR) tab,
450833965Sjdp					      (c + 1) * sizeof (Elf64_gptab)));
450933965Sjdp		      if (new_tab == NULL)
451033965Sjdp			{
451133965Sjdp			  free (tab);
451233965Sjdp			  return false;
451333965Sjdp			}
451433965Sjdp		      tab = new_tab;
451533965Sjdp		      tab[c].gt_entry.gt_g_value = val;
451633965Sjdp		      tab[c].gt_entry.gt_bytes = add;
451733965Sjdp
451833965Sjdp		      /* Merge in the size for the next smallest -G
451933965Sjdp			 value, since that will be implied by this new
452033965Sjdp			 value.  */
452133965Sjdp		      max = 0;
452233965Sjdp		      for (look = 1; look < c; look++)
452333965Sjdp			{
452433965Sjdp			  if (tab[look].gt_entry.gt_g_value < val
452533965Sjdp			      && (max == 0
452633965Sjdp				  || (tab[look].gt_entry.gt_g_value
452733965Sjdp				      > tab[max].gt_entry.gt_g_value)))
452833965Sjdp			    max = look;
452933965Sjdp			}
453033965Sjdp		      if (max != 0)
453133965Sjdp			tab[c].gt_entry.gt_bytes +=
453233965Sjdp			  tab[max].gt_entry.gt_bytes;
453333965Sjdp
453433965Sjdp		      ++c;
453533965Sjdp		    }
453633965Sjdp
453733965Sjdp		  last = int_gptab.gt_entry.gt_bytes;
453833965Sjdp		}
453933965Sjdp
454033965Sjdp	      /* Hack: reset the SEC_HAS_CONTENTS flag so that
454133965Sjdp		 elf_link_input_bfd ignores this section.  */
454233965Sjdp	      input_section->flags &=~ SEC_HAS_CONTENTS;
454333965Sjdp	    }
454433965Sjdp
454533965Sjdp	  /* The table must be sorted by -G value.  */
454633965Sjdp	  if (c > 2)
454733965Sjdp	    qsort (tab + 1, c - 1, sizeof (tab[0]), gptab_compare);
454833965Sjdp
454933965Sjdp	  /* Swap out the table.  */
455033965Sjdp	  ext_tab = ((Elf64_External_gptab *)
455133965Sjdp		     bfd_alloc (abfd, c * sizeof (Elf64_External_gptab)));
455233965Sjdp	  if (ext_tab == NULL)
455333965Sjdp	    {
455433965Sjdp	      free (tab);
455533965Sjdp	      return false;
455633965Sjdp	    }
455733965Sjdp
455833965Sjdp	  for (i = 0; i < c; i++)
455933965Sjdp	    bfd_alpha_elf64_swap_gptab_out (abfd, tab + i, ext_tab + i);
456033965Sjdp	  free (tab);
456133965Sjdp
456233965Sjdp	  o->_raw_size = c * sizeof (Elf64_External_gptab);
456333965Sjdp	  o->contents = (bfd_byte *) ext_tab;
456433965Sjdp
456533965Sjdp	  /* Skip this section later on (I don't think this currently
456633965Sjdp	     matters, but someday it might).  */
456733965Sjdp	  o->link_order_head = (struct bfd_link_order *) NULL;
456833965Sjdp	}
456933965Sjdp#endif
457033965Sjdp
457133965Sjdp    }
457233965Sjdp
457333965Sjdp  /* Invoke the regular ELF backend linker to do all the work.  */
457433965Sjdp  if (! bfd_elf64_bfd_final_link (abfd, info))
457533965Sjdp    return false;
457633965Sjdp
457733965Sjdp  /* Now write out the computed sections.  */
457833965Sjdp
457933965Sjdp  /* The .got subsections...  */
458033965Sjdp  {
458133965Sjdp    bfd *i, *dynobj = elf_hash_table(info)->dynobj;
458233965Sjdp    for (i = alpha_elf_hash_table(info)->got_list;
458333965Sjdp	 i != NULL;
458433965Sjdp	 i = alpha_elf_tdata(i)->got_link_next)
458533965Sjdp      {
458633965Sjdp	asection *sgot;
458733965Sjdp
458833965Sjdp	/* elf_bfd_final_link already did everything in dynobj.  */
458933965Sjdp	if (i == dynobj)
459033965Sjdp	  continue;
459133965Sjdp
459233965Sjdp	sgot = alpha_elf_tdata(i)->got;
459333965Sjdp	if (! bfd_set_section_contents (abfd, sgot->output_section,
459433965Sjdp					sgot->contents, sgot->output_offset,
459533965Sjdp					sgot->_raw_size))
459633965Sjdp	  return false;
459733965Sjdp      }
459833965Sjdp  }
459933965Sjdp
460033965Sjdp#ifdef ERIC_neverdef
460133965Sjdp  if (reginfo_sec != (asection *) NULL)
460233965Sjdp    {
460333965Sjdp      Elf64_External_RegInfo ext;
460433965Sjdp
460533965Sjdp      bfd_alpha_elf64_swap_reginfo_out (abfd, &reginfo, &ext);
460633965Sjdp      if (! bfd_set_section_contents (abfd, reginfo_sec, (PTR) &ext,
460733965Sjdp				      (file_ptr) 0, sizeof ext))
460833965Sjdp	return false;
460933965Sjdp    }
461033965Sjdp#endif
461133965Sjdp
461233965Sjdp  if (mdebug_sec != (asection *) NULL)
461333965Sjdp    {
461433965Sjdp      BFD_ASSERT (abfd->output_has_begun);
461533965Sjdp      if (! bfd_ecoff_write_accumulated_debug (mdebug_handle, abfd, &debug,
461633965Sjdp					       swap, info,
461733965Sjdp					       mdebug_sec->filepos))
461833965Sjdp	return false;
461933965Sjdp
462033965Sjdp      bfd_ecoff_debug_free (mdebug_handle, abfd, &debug, swap, info);
462133965Sjdp    }
462233965Sjdp
462333965Sjdp  if (gptab_data_sec != (asection *) NULL)
462433965Sjdp    {
462533965Sjdp      if (! bfd_set_section_contents (abfd, gptab_data_sec,
462633965Sjdp				      gptab_data_sec->contents,
462733965Sjdp				      (file_ptr) 0,
462833965Sjdp				      gptab_data_sec->_raw_size))
462933965Sjdp	return false;
463033965Sjdp    }
463133965Sjdp
463233965Sjdp  if (gptab_bss_sec != (asection *) NULL)
463333965Sjdp    {
463433965Sjdp      if (! bfd_set_section_contents (abfd, gptab_bss_sec,
463533965Sjdp				      gptab_bss_sec->contents,
463633965Sjdp				      (file_ptr) 0,
463733965Sjdp				      gptab_bss_sec->_raw_size))
463833965Sjdp	return false;
463933965Sjdp    }
464033965Sjdp
464133965Sjdp  return true;
464233965Sjdp}
464333965Sjdp
464433965Sjdp/* ECOFF swapping routines.  These are used when dealing with the
464533965Sjdp   .mdebug section, which is in the ECOFF debugging format.  Copied
464677303Sobrien   from elf32-mips.c.  */
464733965Sjdpstatic const struct ecoff_debug_swap
464833965Sjdpelf64_alpha_ecoff_debug_swap =
464933965Sjdp{
465033965Sjdp  /* Symbol table magic number.  */
465133965Sjdp  magicSym2,
465233965Sjdp  /* Alignment of debugging information.  E.g., 4.  */
465333965Sjdp  8,
465433965Sjdp  /* Sizes of external symbolic information.  */
465533965Sjdp  sizeof (struct hdr_ext),
465633965Sjdp  sizeof (struct dnr_ext),
465733965Sjdp  sizeof (struct pdr_ext),
465833965Sjdp  sizeof (struct sym_ext),
465933965Sjdp  sizeof (struct opt_ext),
466033965Sjdp  sizeof (struct fdr_ext),
466133965Sjdp  sizeof (struct rfd_ext),
466233965Sjdp  sizeof (struct ext_ext),
466333965Sjdp  /* Functions to swap in external symbolic data.  */
466433965Sjdp  ecoff_swap_hdr_in,
466533965Sjdp  ecoff_swap_dnr_in,
466633965Sjdp  ecoff_swap_pdr_in,
466733965Sjdp  ecoff_swap_sym_in,
466833965Sjdp  ecoff_swap_opt_in,
466933965Sjdp  ecoff_swap_fdr_in,
467033965Sjdp  ecoff_swap_rfd_in,
467133965Sjdp  ecoff_swap_ext_in,
467233965Sjdp  _bfd_ecoff_swap_tir_in,
467333965Sjdp  _bfd_ecoff_swap_rndx_in,
467433965Sjdp  /* Functions to swap out external symbolic data.  */
467533965Sjdp  ecoff_swap_hdr_out,
467633965Sjdp  ecoff_swap_dnr_out,
467733965Sjdp  ecoff_swap_pdr_out,
467833965Sjdp  ecoff_swap_sym_out,
467933965Sjdp  ecoff_swap_opt_out,
468033965Sjdp  ecoff_swap_fdr_out,
468133965Sjdp  ecoff_swap_rfd_out,
468233965Sjdp  ecoff_swap_ext_out,
468333965Sjdp  _bfd_ecoff_swap_tir_out,
468433965Sjdp  _bfd_ecoff_swap_rndx_out,
468533965Sjdp  /* Function to read in symbolic data.  */
468633965Sjdp  elf64_alpha_read_ecoff_info
468733965Sjdp};
468833965Sjdp
468977303Sobrien/* Use a non-standard hash bucket size of 8.  */
469077303Sobrien
469177303Sobrienconst struct elf_size_info alpha_elf_size_info =
469277303Sobrien{
469377303Sobrien  sizeof (Elf64_External_Ehdr),
469477303Sobrien  sizeof (Elf64_External_Phdr),
469577303Sobrien  sizeof (Elf64_External_Shdr),
469677303Sobrien  sizeof (Elf64_External_Rel),
469777303Sobrien  sizeof (Elf64_External_Rela),
469877303Sobrien  sizeof (Elf64_External_Sym),
469977303Sobrien  sizeof (Elf64_External_Dyn),
470077303Sobrien  sizeof (Elf_External_Note),
470177303Sobrien  8,
470277303Sobrien  1,
470377303Sobrien  64, 8,
470477303Sobrien  ELFCLASS64, EV_CURRENT,
470577303Sobrien  bfd_elf64_write_out_phdrs,
470677303Sobrien  bfd_elf64_write_shdrs_and_ehdr,
470777303Sobrien  bfd_elf64_write_relocs,
470877303Sobrien  bfd_elf64_swap_symbol_out,
470977303Sobrien  bfd_elf64_slurp_reloc_table,
471077303Sobrien  bfd_elf64_slurp_symbol_table,
471177303Sobrien  bfd_elf64_swap_dyn_in,
471277303Sobrien  bfd_elf64_swap_dyn_out,
471377303Sobrien  NULL,
471477303Sobrien  NULL,
471577303Sobrien  NULL,
471677303Sobrien  NULL
471777303Sobrien};
471877303Sobrien
471933965Sjdp#define TARGET_LITTLE_SYM	bfd_elf64_alpha_vec
472033965Sjdp#define TARGET_LITTLE_NAME	"elf64-alpha"
472133965Sjdp#define ELF_ARCH		bfd_arch_alpha
472233965Sjdp#define ELF_MACHINE_CODE 	EM_ALPHA
472338889Sjdp#define ELF_MAXPAGESIZE 	0x10000
472433965Sjdp
472533965Sjdp#define bfd_elf64_bfd_link_hash_table_create \
472633965Sjdp  elf64_alpha_bfd_link_hash_table_create
472733965Sjdp
472833965Sjdp#define bfd_elf64_bfd_reloc_type_lookup \
472933965Sjdp  elf64_alpha_bfd_reloc_type_lookup
473033965Sjdp#define elf_info_to_howto \
473133965Sjdp  elf64_alpha_info_to_howto
473233965Sjdp
473333965Sjdp#define bfd_elf64_mkobject \
473433965Sjdp  elf64_alpha_mkobject
473533965Sjdp#define elf_backend_object_p \
473633965Sjdp  elf64_alpha_object_p
473733965Sjdp
473833965Sjdp#define elf_backend_section_from_shdr \
473933965Sjdp  elf64_alpha_section_from_shdr
474033965Sjdp#define elf_backend_fake_sections \
474133965Sjdp  elf64_alpha_fake_sections
474233965Sjdp
474333965Sjdp#define bfd_elf64_bfd_is_local_label_name \
474433965Sjdp  elf64_alpha_is_local_label_name
474533965Sjdp#define bfd_elf64_find_nearest_line \
474633965Sjdp  elf64_alpha_find_nearest_line
474760510Sobrien#define bfd_elf64_bfd_relax_section \
474860510Sobrien  elf64_alpha_relax_section
474933965Sjdp
475060510Sobrien#define elf_backend_add_symbol_hook \
475160510Sobrien  elf64_alpha_add_symbol_hook
475233965Sjdp#define elf_backend_check_relocs \
475333965Sjdp  elf64_alpha_check_relocs
475433965Sjdp#define elf_backend_create_dynamic_sections \
475533965Sjdp  elf64_alpha_create_dynamic_sections
475633965Sjdp#define elf_backend_adjust_dynamic_symbol \
475733965Sjdp  elf64_alpha_adjust_dynamic_symbol
475833965Sjdp#define elf_backend_always_size_sections \
475933965Sjdp  elf64_alpha_always_size_sections
476033965Sjdp#define elf_backend_size_dynamic_sections \
476133965Sjdp  elf64_alpha_size_dynamic_sections
476233965Sjdp#define elf_backend_relocate_section \
476333965Sjdp  elf64_alpha_relocate_section
476433965Sjdp#define elf_backend_finish_dynamic_symbol \
476533965Sjdp  elf64_alpha_finish_dynamic_symbol
476633965Sjdp#define elf_backend_finish_dynamic_sections \
476733965Sjdp  elf64_alpha_finish_dynamic_sections
476833965Sjdp#define bfd_elf64_bfd_final_link \
476933965Sjdp  elf64_alpha_final_link
477033965Sjdp
477133965Sjdp#define elf_backend_ecoff_debug_swap \
477233965Sjdp  &elf64_alpha_ecoff_debug_swap
477333965Sjdp
477477303Sobrien#define elf_backend_size_info \
477577303Sobrien  alpha_elf_size_info
477677303Sobrien
477777303Sobrien/* A few constants that determine how the .plt section is set up.  */
477833965Sjdp#define elf_backend_want_got_plt 0
477933965Sjdp#define elf_backend_plt_readonly 0
478033965Sjdp#define elf_backend_want_plt_sym 1
478160510Sobrien#define elf_backend_got_header_size 0
478260510Sobrien#define elf_backend_plt_header_size PLT_HEADER_SIZE
478333965Sjdp
478433965Sjdp#include "elf64-target.h"
4785