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