elfxx-ia64.c revision 99461
1/* IA-64 support for 64-bit ELF
2   Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3   Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4
5This file is part of BFD, the Binary File Descriptor library.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21#include "bfd.h"
22#include "sysdep.h"
23#include "libbfd.h"
24#include "elf-bfd.h"
25#include "opcode/ia64.h"
26#include "elf/ia64.h"
27
28/*
29 * THE RULES for all the stuff the linker creates --
30 *
31 * GOT		Entries created in response to LTOFF or LTOFF_FPTR
32 *		relocations.  Dynamic relocs created for dynamic
33 *		symbols in an application; REL relocs for locals
34 *		in a shared library.
35 *
36 * FPTR		The canonical function descriptor.  Created for local
37 *		symbols in applications.  Descriptors for dynamic symbols
38 *		and local symbols in shared libraries are created by
39 *		ld.so.  Thus there are no dynamic relocs against these
40 *		objects.  The FPTR relocs for such _are_ passed through
41 *		to the dynamic relocation tables.
42 *
43 * FULL_PLT	Created for a PCREL21B relocation against a dynamic symbol.
44 *		Requires the creation of a PLTOFF entry.  This does not
45 *		require any dynamic relocations.
46 *
47 * PLTOFF	Created by PLTOFF relocations.  For local symbols, this
48 *		is an alternate function descriptor, and in shared libraries
49 *		requires two REL relocations.  Note that this cannot be
50 *		transformed into an FPTR relocation, since it must be in
51 *		range of the GP.  For dynamic symbols, this is a function
52 *		descriptor for a MIN_PLT entry, and requires one IPLT reloc.
53 *
54 * MIN_PLT	Created by PLTOFF entries against dynamic symbols.  This
55 *		does not reqire dynamic relocations.
56 */
57
58#define USE_RELA		/* we want RELA relocs, not REL */
59
60#define NELEMS(a)	((int) (sizeof (a) / sizeof ((a)[0])))
61
62typedef struct bfd_hash_entry *(*new_hash_entry_func)
63  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
64
65/* In dynamically (linker-) created sections, we generally need to keep track
66   of the place a symbol or expression got allocated to. This is done via hash
67   tables that store entries of the following type.  */
68
69struct elfNN_ia64_dyn_sym_info
70{
71  /* The addend for which this entry is relevant.  */
72  bfd_vma addend;
73
74  /* Next addend in the list.  */
75  struct elfNN_ia64_dyn_sym_info *next;
76
77  bfd_vma got_offset;
78  bfd_vma fptr_offset;
79  bfd_vma pltoff_offset;
80  bfd_vma plt_offset;
81  bfd_vma plt2_offset;
82
83  /* The symbol table entry, if any, that this was derrived from.  */
84  struct elf_link_hash_entry *h;
85
86  /* Used to count non-got, non-plt relocations for delayed sizing
87     of relocation sections.  */
88  struct elfNN_ia64_dyn_reloc_entry
89  {
90    struct elfNN_ia64_dyn_reloc_entry *next;
91    asection *srel;
92    int type;
93    int count;
94  } *reloc_entries;
95
96  /* True when the section contents have been updated.  */
97  unsigned got_done : 1;
98  unsigned fptr_done : 1;
99  unsigned pltoff_done : 1;
100
101  /* True for the different kinds of linker data we want created.  */
102  unsigned want_got : 1;
103  unsigned want_fptr : 1;
104  unsigned want_ltoff_fptr : 1;
105  unsigned want_plt : 1;
106  unsigned want_plt2 : 1;
107  unsigned want_pltoff : 1;
108};
109
110struct elfNN_ia64_local_hash_entry
111{
112  struct bfd_hash_entry root;
113  struct elfNN_ia64_dyn_sym_info *info;
114
115  /* True if this hash entry's addends was translated for
116     SHF_MERGE optimization.  */
117  unsigned sec_merge_done : 1;
118};
119
120struct elfNN_ia64_local_hash_table
121{
122  struct bfd_hash_table root;
123  /* No additional fields for now.  */
124};
125
126struct elfNN_ia64_link_hash_entry
127{
128  struct elf_link_hash_entry root;
129  struct elfNN_ia64_dyn_sym_info *info;
130};
131
132struct elfNN_ia64_link_hash_table
133{
134  /* The main hash table */
135  struct elf_link_hash_table root;
136
137  asection *got_sec;		/* the linkage table section (or NULL) */
138  asection *rel_got_sec;	/* dynamic relocation section for same */
139  asection *fptr_sec;		/* function descriptor table (or NULL) */
140  asection *plt_sec;		/* the primary plt section (or NULL) */
141  asection *pltoff_sec;		/* private descriptors for plt (or NULL) */
142  asection *rel_pltoff_sec;	/* dynamic relocation section for same */
143
144  bfd_size_type minplt_entries;	/* number of minplt entries */
145  unsigned reltext : 1;		/* are there relocs against readonly sections? */
146
147  struct elfNN_ia64_local_hash_table loc_hash_table;
148};
149
150#define elfNN_ia64_hash_table(p) \
151  ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
152
153static bfd_reloc_status_type elfNN_ia64_reloc
154  PARAMS ((bfd *abfd, arelent *reloc, asymbol *sym, PTR data,
155	   asection *input_section, bfd *output_bfd, char **error_message));
156static reloc_howto_type * lookup_howto
157  PARAMS ((unsigned int rtype));
158static reloc_howto_type *elfNN_ia64_reloc_type_lookup
159  PARAMS ((bfd *abfd, bfd_reloc_code_real_type bfd_code));
160static void elfNN_ia64_info_to_howto
161  PARAMS ((bfd *abfd, arelent *bfd_reloc, ElfNN_Internal_Rela *elf_reloc));
162static boolean elfNN_ia64_relax_section
163  PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
164	  boolean *again));
165static boolean is_unwind_section_name
166  PARAMS ((bfd *abfd, const char *));
167static boolean elfNN_ia64_section_from_shdr
168  PARAMS ((bfd *, ElfNN_Internal_Shdr *, char *));
169static boolean elfNN_ia64_section_flags
170  PARAMS ((flagword *, ElfNN_Internal_Shdr *));
171static boolean elfNN_ia64_fake_sections
172  PARAMS ((bfd *abfd, ElfNN_Internal_Shdr *hdr, asection *sec));
173static void elfNN_ia64_final_write_processing
174  PARAMS ((bfd *abfd, boolean linker));
175static boolean elfNN_ia64_add_symbol_hook
176  PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
177	   const char **namep, flagword *flagsp, asection **secp,
178	   bfd_vma *valp));
179static boolean elfNN_ia64_aix_vec
180  PARAMS ((const bfd_target *vec));
181static boolean elfNN_ia64_aix_add_symbol_hook
182  PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
183	   const char **namep, flagword *flagsp, asection **secp,
184	   bfd_vma *valp));
185static boolean elfNN_ia64_aix_link_add_symbols
186  PARAMS ((bfd *abfd, struct bfd_link_info *info));
187static int elfNN_ia64_additional_program_headers
188  PARAMS ((bfd *abfd));
189static boolean elfNN_ia64_modify_segment_map
190  PARAMS ((bfd *));
191static boolean elfNN_ia64_is_local_label_name
192  PARAMS ((bfd *abfd, const char *name));
193static boolean elfNN_ia64_dynamic_symbol_p
194  PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info));
195static boolean elfNN_ia64_local_hash_table_init
196  PARAMS ((struct elfNN_ia64_local_hash_table *ht, bfd *abfd,
197	   new_hash_entry_func new));
198static struct bfd_hash_entry *elfNN_ia64_new_loc_hash_entry
199  PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
200	   const char *string));
201static struct bfd_hash_entry *elfNN_ia64_new_elf_hash_entry
202  PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
203	   const char *string));
204static void elfNN_ia64_hash_copy_indirect
205  PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *));
206static void elfNN_ia64_hash_hide_symbol
207  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, boolean));
208static struct bfd_link_hash_table *elfNN_ia64_hash_table_create
209  PARAMS ((bfd *abfd));
210static struct elfNN_ia64_local_hash_entry *elfNN_ia64_local_hash_lookup
211  PARAMS ((struct elfNN_ia64_local_hash_table *table, const char *string,
212	   boolean create, boolean copy));
213static boolean elfNN_ia64_global_dyn_sym_thunk
214  PARAMS ((struct bfd_hash_entry *, PTR));
215static boolean elfNN_ia64_local_dyn_sym_thunk
216  PARAMS ((struct bfd_hash_entry *, PTR));
217static void elfNN_ia64_dyn_sym_traverse
218  PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
219	   boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
220	   PTR info));
221static boolean elfNN_ia64_create_dynamic_sections
222  PARAMS ((bfd *abfd, struct bfd_link_info *info));
223static struct elfNN_ia64_local_hash_entry * get_local_sym_hash
224  PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
225	   bfd *abfd, const Elf_Internal_Rela *rel, boolean create));
226static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
227  PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
228	   struct elf_link_hash_entry *h,
229	   bfd *abfd, const Elf_Internal_Rela *rel, boolean create));
230static asection *get_got
231  PARAMS ((bfd *abfd, struct bfd_link_info *info,
232	   struct elfNN_ia64_link_hash_table *ia64_info));
233static asection *get_fptr
234  PARAMS ((bfd *abfd, struct bfd_link_info *info,
235	   struct elfNN_ia64_link_hash_table *ia64_info));
236static asection *get_pltoff
237  PARAMS ((bfd *abfd, struct bfd_link_info *info,
238	   struct elfNN_ia64_link_hash_table *ia64_info));
239static asection *get_reloc_section
240  PARAMS ((bfd *abfd, struct elfNN_ia64_link_hash_table *ia64_info,
241	   asection *sec, boolean create));
242static boolean count_dyn_reloc
243  PARAMS ((bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
244	   asection *srel, int type));
245static boolean elfNN_ia64_check_relocs
246  PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
247	   const Elf_Internal_Rela *relocs));
248static boolean elfNN_ia64_adjust_dynamic_symbol
249  PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
250static long global_sym_index
251  PARAMS ((struct elf_link_hash_entry *h));
252static boolean allocate_fptr
253  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
254static boolean allocate_global_data_got
255  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
256static boolean allocate_global_fptr_got
257  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
258static boolean allocate_local_got
259  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
260static boolean allocate_pltoff_entries
261  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
262static boolean allocate_plt_entries
263  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
264static boolean allocate_plt2_entries
265  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
266static boolean allocate_dynrel_entries
267  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
268static boolean elfNN_ia64_size_dynamic_sections
269  PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
270static bfd_reloc_status_type elfNN_ia64_install_value
271  PARAMS ((bfd *abfd, bfd_byte *hit_addr, bfd_vma val, unsigned int r_type));
272static void elfNN_ia64_install_dyn_reloc
273  PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
274	   asection *srel, bfd_vma offset, unsigned int type,
275	   long dynindx, bfd_vma addend));
276static bfd_vma set_got_entry
277  PARAMS ((bfd *abfd, struct bfd_link_info *info,
278	   struct elfNN_ia64_dyn_sym_info *dyn_i, long dynindx,
279	   bfd_vma addend, bfd_vma value, unsigned int dyn_r_type));
280static bfd_vma set_fptr_entry
281  PARAMS ((bfd *abfd, struct bfd_link_info *info,
282	   struct elfNN_ia64_dyn_sym_info *dyn_i,
283	   bfd_vma value));
284static bfd_vma set_pltoff_entry
285  PARAMS ((bfd *abfd, struct bfd_link_info *info,
286	   struct elfNN_ia64_dyn_sym_info *dyn_i,
287	   bfd_vma value, boolean));
288static int elfNN_ia64_unwind_entry_compare
289  PARAMS ((const PTR, const PTR));
290static boolean elfNN_ia64_final_link
291  PARAMS ((bfd *abfd, struct bfd_link_info *info));
292static boolean elfNN_ia64_relocate_section
293  PARAMS ((bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
294	   asection *input_section, bfd_byte *contents,
295	   Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms,
296	   asection **local_sections));
297static boolean elfNN_ia64_finish_dynamic_symbol
298  PARAMS ((bfd *output_bfd, struct bfd_link_info *info,
299	   struct elf_link_hash_entry *h, Elf_Internal_Sym *sym));
300static boolean elfNN_ia64_finish_dynamic_sections
301  PARAMS ((bfd *abfd, struct bfd_link_info *info));
302static boolean elfNN_ia64_set_private_flags
303  PARAMS ((bfd *abfd, flagword flags));
304static boolean elfNN_ia64_merge_private_bfd_data
305  PARAMS ((bfd *ibfd, bfd *obfd));
306static boolean elfNN_ia64_print_private_bfd_data
307  PARAMS ((bfd *abfd, PTR ptr));
308static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
309  PARAMS ((const Elf_Internal_Rela *));
310static boolean elfNN_ia64_hpux_vec
311  PARAMS ((const bfd_target *vec));
312static void elfNN_hpux_post_process_headers
313  PARAMS ((bfd *abfd, struct bfd_link_info *info));
314boolean elfNN_hpux_backend_section_from_bfd_section
315  PARAMS ((bfd *abfd, asection *sec, int *retval));
316
317/* ia64-specific relocation */
318
319/* Perform a relocation.  Not much to do here as all the hard work is
320   done in elfNN_ia64_final_link_relocate.  */
321static bfd_reloc_status_type
322elfNN_ia64_reloc (abfd, reloc, sym, data, input_section,
323		  output_bfd, error_message)
324     bfd *abfd ATTRIBUTE_UNUSED;
325     arelent *reloc;
326     asymbol *sym ATTRIBUTE_UNUSED;
327     PTR data ATTRIBUTE_UNUSED;
328     asection *input_section;
329     bfd *output_bfd;
330     char **error_message;
331{
332  if (output_bfd)
333    {
334      reloc->address += input_section->output_offset;
335      return bfd_reloc_ok;
336    }
337  *error_message = "Unsupported call to elfNN_ia64_reloc";
338  return bfd_reloc_notsupported;
339}
340
341#define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN)			\
342  HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed,	\
343	 elfNN_ia64_reloc, NAME, false, 0, 0, IN)
344
345/* This table has to be sorted according to increasing number of the
346   TYPE field.  */
347static reloc_howto_type ia64_howto_table[] =
348  {
349    IA64_HOWTO (R_IA64_NONE,	    "NONE",	   0, false, true),
350
351    IA64_HOWTO (R_IA64_IMM14,	    "IMM14",	   0, false, true),
352    IA64_HOWTO (R_IA64_IMM22,	    "IMM22",	   0, false, true),
353    IA64_HOWTO (R_IA64_IMM64,	    "IMM64",	   0, false, true),
354    IA64_HOWTO (R_IA64_DIR32MSB,    "DIR32MSB",	   2, false, true),
355    IA64_HOWTO (R_IA64_DIR32LSB,    "DIR32LSB",	   2, false, true),
356    IA64_HOWTO (R_IA64_DIR64MSB,    "DIR64MSB",	   4, false, true),
357    IA64_HOWTO (R_IA64_DIR64LSB,    "DIR64LSB",	   4, false, true),
358
359    IA64_HOWTO (R_IA64_GPREL22,	    "GPREL22",	   0, false, true),
360    IA64_HOWTO (R_IA64_GPREL64I,    "GPREL64I",	   0, false, true),
361    IA64_HOWTO (R_IA64_GPREL32MSB,  "GPREL32MSB",  2, false, true),
362    IA64_HOWTO (R_IA64_GPREL32LSB,  "GPREL32LSB",  2, false, true),
363    IA64_HOWTO (R_IA64_GPREL64MSB,  "GPREL64MSB",  4, false, true),
364    IA64_HOWTO (R_IA64_GPREL64LSB,  "GPREL64LSB",  4, false, true),
365
366    IA64_HOWTO (R_IA64_LTOFF22,	    "LTOFF22",	   0, false, true),
367    IA64_HOWTO (R_IA64_LTOFF64I,    "LTOFF64I",	   0, false, true),
368
369    IA64_HOWTO (R_IA64_PLTOFF22,    "PLTOFF22",	   0, false, true),
370    IA64_HOWTO (R_IA64_PLTOFF64I,   "PLTOFF64I",   0, false, true),
371    IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, false, true),
372    IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, false, true),
373
374    IA64_HOWTO (R_IA64_FPTR64I,	    "FPTR64I",	   0, false, true),
375    IA64_HOWTO (R_IA64_FPTR32MSB,   "FPTR32MSB",   2, false, true),
376    IA64_HOWTO (R_IA64_FPTR32LSB,   "FPTR32LSB",   2, false, true),
377    IA64_HOWTO (R_IA64_FPTR64MSB,   "FPTR64MSB",   4, false, true),
378    IA64_HOWTO (R_IA64_FPTR64LSB,   "FPTR64LSB",   4, false, true),
379
380    IA64_HOWTO (R_IA64_PCREL60B,    "PCREL60B",	   0, true, true),
381    IA64_HOWTO (R_IA64_PCREL21B,    "PCREL21B",	   0, true, true),
382    IA64_HOWTO (R_IA64_PCREL21M,    "PCREL21M",	   0, true, true),
383    IA64_HOWTO (R_IA64_PCREL21F,    "PCREL21F",	   0, true, true),
384    IA64_HOWTO (R_IA64_PCREL32MSB,  "PCREL32MSB",  2, true, true),
385    IA64_HOWTO (R_IA64_PCREL32LSB,  "PCREL32LSB",  2, true, true),
386    IA64_HOWTO (R_IA64_PCREL64MSB,  "PCREL64MSB",  4, true, true),
387    IA64_HOWTO (R_IA64_PCREL64LSB,  "PCREL64LSB",  4, true, true),
388
389    IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, false, true),
390    IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, false, true),
391    IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB, "LTOFF_FPTR32MSB", 2, false, true),
392    IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB, "LTOFF_FPTR32LSB", 2, false, true),
393    IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, false, true),
394    IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, false, true),
395
396    IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, false, true),
397    IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, false, true),
398    IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, false, true),
399    IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, false, true),
400
401    IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, false, true),
402    IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, false, true),
403    IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, false, true),
404    IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, false, true),
405
406    IA64_HOWTO (R_IA64_REL32MSB,    "REL32MSB",	   2, false, true),
407    IA64_HOWTO (R_IA64_REL32LSB,    "REL32LSB",	   2, false, true),
408    IA64_HOWTO (R_IA64_REL64MSB,    "REL64MSB",	   4, false, true),
409    IA64_HOWTO (R_IA64_REL64LSB,    "REL64LSB",	   4, false, true),
410
411    IA64_HOWTO (R_IA64_LTV32MSB,    "LTV32MSB",	   2, false, true),
412    IA64_HOWTO (R_IA64_LTV32LSB,    "LTV32LSB",	   2, false, true),
413    IA64_HOWTO (R_IA64_LTV64MSB,    "LTV64MSB",	   4, false, true),
414    IA64_HOWTO (R_IA64_LTV64LSB,    "LTV64LSB",	   4, false, true),
415
416    IA64_HOWTO (R_IA64_PCREL21BI,   "PCREL21BI",   0, true, true),
417    IA64_HOWTO (R_IA64_PCREL22,     "PCREL22",     0, true, true),
418    IA64_HOWTO (R_IA64_PCREL64I,    "PCREL64I",    0, true, true),
419
420    IA64_HOWTO (R_IA64_IPLTMSB,	    "IPLTMSB",	   4, false, true),
421    IA64_HOWTO (R_IA64_IPLTLSB,	    "IPLTLSB",	   4, false, true),
422    IA64_HOWTO (R_IA64_COPY,	    "COPY",	   4, false, true),
423    IA64_HOWTO (R_IA64_LTOFF22X,    "LTOFF22X",	   0, false, true),
424    IA64_HOWTO (R_IA64_LDXMOV,	    "LDXMOV",	   0, false, true),
425
426    IA64_HOWTO (R_IA64_TPREL22,	    "TPREL22",	   0, false, false),
427    IA64_HOWTO (R_IA64_TPREL64MSB,  "TPREL64MSB",  8, false, false),
428    IA64_HOWTO (R_IA64_TPREL64LSB,  "TPREL64LSB",  8, false, false),
429    IA64_HOWTO (R_IA64_LTOFF_TP22,  "LTOFF_TP22",  0, false, false),
430  };
431
432static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
433
434/* Given a BFD reloc type, return the matching HOWTO structure.  */
435
436static reloc_howto_type*
437lookup_howto (rtype)
438     unsigned int rtype;
439{
440  static int inited = 0;
441  int i;
442
443  if (!inited)
444    {
445      inited = 1;
446
447      memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
448      for (i = 0; i < NELEMS (ia64_howto_table); ++i)
449	elf_code_to_howto_index[ia64_howto_table[i].type] = i;
450    }
451
452  BFD_ASSERT (rtype <= R_IA64_MAX_RELOC_CODE);
453  i = elf_code_to_howto_index[rtype];
454  if (i >= NELEMS (ia64_howto_table))
455    return 0;
456  return ia64_howto_table + i;
457}
458
459static reloc_howto_type*
460elfNN_ia64_reloc_type_lookup (abfd, bfd_code)
461     bfd *abfd ATTRIBUTE_UNUSED;
462     bfd_reloc_code_real_type bfd_code;
463{
464  unsigned int rtype;
465
466  switch (bfd_code)
467    {
468    case BFD_RELOC_NONE:		rtype = R_IA64_NONE; break;
469
470    case BFD_RELOC_IA64_IMM14:		rtype = R_IA64_IMM14; break;
471    case BFD_RELOC_IA64_IMM22:		rtype = R_IA64_IMM22; break;
472    case BFD_RELOC_IA64_IMM64:		rtype = R_IA64_IMM64; break;
473
474    case BFD_RELOC_IA64_DIR32MSB:	rtype = R_IA64_DIR32MSB; break;
475    case BFD_RELOC_IA64_DIR32LSB:	rtype = R_IA64_DIR32LSB; break;
476    case BFD_RELOC_IA64_DIR64MSB:	rtype = R_IA64_DIR64MSB; break;
477    case BFD_RELOC_IA64_DIR64LSB:	rtype = R_IA64_DIR64LSB; break;
478
479    case BFD_RELOC_IA64_GPREL22:	rtype = R_IA64_GPREL22; break;
480    case BFD_RELOC_IA64_GPREL64I:	rtype = R_IA64_GPREL64I; break;
481    case BFD_RELOC_IA64_GPREL32MSB:	rtype = R_IA64_GPREL32MSB; break;
482    case BFD_RELOC_IA64_GPREL32LSB:	rtype = R_IA64_GPREL32LSB; break;
483    case BFD_RELOC_IA64_GPREL64MSB:	rtype = R_IA64_GPREL64MSB; break;
484    case BFD_RELOC_IA64_GPREL64LSB:	rtype = R_IA64_GPREL64LSB; break;
485
486    case BFD_RELOC_IA64_LTOFF22:	rtype = R_IA64_LTOFF22; break;
487    case BFD_RELOC_IA64_LTOFF64I:	rtype = R_IA64_LTOFF64I; break;
488
489    case BFD_RELOC_IA64_PLTOFF22:	rtype = R_IA64_PLTOFF22; break;
490    case BFD_RELOC_IA64_PLTOFF64I:	rtype = R_IA64_PLTOFF64I; break;
491    case BFD_RELOC_IA64_PLTOFF64MSB:	rtype = R_IA64_PLTOFF64MSB; break;
492    case BFD_RELOC_IA64_PLTOFF64LSB:	rtype = R_IA64_PLTOFF64LSB; break;
493    case BFD_RELOC_IA64_FPTR64I:	rtype = R_IA64_FPTR64I; break;
494    case BFD_RELOC_IA64_FPTR32MSB:	rtype = R_IA64_FPTR32MSB; break;
495    case BFD_RELOC_IA64_FPTR32LSB:	rtype = R_IA64_FPTR32LSB; break;
496    case BFD_RELOC_IA64_FPTR64MSB:	rtype = R_IA64_FPTR64MSB; break;
497    case BFD_RELOC_IA64_FPTR64LSB:	rtype = R_IA64_FPTR64LSB; break;
498
499    case BFD_RELOC_IA64_PCREL21B:	rtype = R_IA64_PCREL21B; break;
500    case BFD_RELOC_IA64_PCREL21BI:	rtype = R_IA64_PCREL21BI; break;
501    case BFD_RELOC_IA64_PCREL21M:	rtype = R_IA64_PCREL21M; break;
502    case BFD_RELOC_IA64_PCREL21F:	rtype = R_IA64_PCREL21F; break;
503    case BFD_RELOC_IA64_PCREL22:	rtype = R_IA64_PCREL22; break;
504    case BFD_RELOC_IA64_PCREL60B:	rtype = R_IA64_PCREL60B; break;
505    case BFD_RELOC_IA64_PCREL64I:	rtype = R_IA64_PCREL64I; break;
506    case BFD_RELOC_IA64_PCREL32MSB:	rtype = R_IA64_PCREL32MSB; break;
507    case BFD_RELOC_IA64_PCREL32LSB:	rtype = R_IA64_PCREL32LSB; break;
508    case BFD_RELOC_IA64_PCREL64MSB:	rtype = R_IA64_PCREL64MSB; break;
509    case BFD_RELOC_IA64_PCREL64LSB:	rtype = R_IA64_PCREL64LSB; break;
510
511    case BFD_RELOC_IA64_LTOFF_FPTR22:	rtype = R_IA64_LTOFF_FPTR22; break;
512    case BFD_RELOC_IA64_LTOFF_FPTR64I:	rtype = R_IA64_LTOFF_FPTR64I; break;
513    case BFD_RELOC_IA64_LTOFF_FPTR32MSB: rtype = R_IA64_LTOFF_FPTR32MSB; break;
514    case BFD_RELOC_IA64_LTOFF_FPTR32LSB: rtype = R_IA64_LTOFF_FPTR32LSB; break;
515    case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
516    case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
517
518    case BFD_RELOC_IA64_SEGREL32MSB:	rtype = R_IA64_SEGREL32MSB; break;
519    case BFD_RELOC_IA64_SEGREL32LSB:	rtype = R_IA64_SEGREL32LSB; break;
520    case BFD_RELOC_IA64_SEGREL64MSB:	rtype = R_IA64_SEGREL64MSB; break;
521    case BFD_RELOC_IA64_SEGREL64LSB:	rtype = R_IA64_SEGREL64LSB; break;
522
523    case BFD_RELOC_IA64_SECREL32MSB:	rtype = R_IA64_SECREL32MSB; break;
524    case BFD_RELOC_IA64_SECREL32LSB:	rtype = R_IA64_SECREL32LSB; break;
525    case BFD_RELOC_IA64_SECREL64MSB:	rtype = R_IA64_SECREL64MSB; break;
526    case BFD_RELOC_IA64_SECREL64LSB:	rtype = R_IA64_SECREL64LSB; break;
527
528    case BFD_RELOC_IA64_REL32MSB:	rtype = R_IA64_REL32MSB; break;
529    case BFD_RELOC_IA64_REL32LSB:	rtype = R_IA64_REL32LSB; break;
530    case BFD_RELOC_IA64_REL64MSB:	rtype = R_IA64_REL64MSB; break;
531    case BFD_RELOC_IA64_REL64LSB:	rtype = R_IA64_REL64LSB; break;
532
533    case BFD_RELOC_IA64_LTV32MSB:	rtype = R_IA64_LTV32MSB; break;
534    case BFD_RELOC_IA64_LTV32LSB:	rtype = R_IA64_LTV32LSB; break;
535    case BFD_RELOC_IA64_LTV64MSB:	rtype = R_IA64_LTV64MSB; break;
536    case BFD_RELOC_IA64_LTV64LSB:	rtype = R_IA64_LTV64LSB; break;
537
538    case BFD_RELOC_IA64_IPLTMSB:	rtype = R_IA64_IPLTMSB; break;
539    case BFD_RELOC_IA64_IPLTLSB:	rtype = R_IA64_IPLTLSB; break;
540    case BFD_RELOC_IA64_COPY:		rtype = R_IA64_COPY; break;
541    case BFD_RELOC_IA64_LTOFF22X:	rtype = R_IA64_LTOFF22X; break;
542    case BFD_RELOC_IA64_LDXMOV:		rtype = R_IA64_LDXMOV; break;
543
544    case BFD_RELOC_IA64_TPREL22:	rtype = R_IA64_TPREL22; break;
545    case BFD_RELOC_IA64_TPREL64MSB:	rtype = R_IA64_TPREL64MSB; break;
546    case BFD_RELOC_IA64_TPREL64LSB:	rtype = R_IA64_TPREL64LSB; break;
547    case BFD_RELOC_IA64_LTOFF_TP22:	rtype = R_IA64_LTOFF_TP22; break;
548
549    default: return 0;
550    }
551  return lookup_howto (rtype);
552}
553
554/* Given a ELF reloc, return the matching HOWTO structure.  */
555
556static void
557elfNN_ia64_info_to_howto (abfd, bfd_reloc, elf_reloc)
558     bfd *abfd ATTRIBUTE_UNUSED;
559     arelent *bfd_reloc;
560     ElfNN_Internal_Rela *elf_reloc;
561{
562  bfd_reloc->howto
563    = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc->r_info));
564}
565
566#define PLT_HEADER_SIZE		(3 * 16)
567#define PLT_MIN_ENTRY_SIZE	(1 * 16)
568#define PLT_FULL_ENTRY_SIZE	(2 * 16)
569#define PLT_RESERVED_WORDS	3
570
571static const bfd_byte plt_header[PLT_HEADER_SIZE] =
572{
573  0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21,  /*   [MMI]       mov r2=r14;;       */
574  0xe0, 0x00, 0x08, 0x00, 0x48, 0x00,  /*               addl r14=0,r2      */
575  0x00, 0x00, 0x04, 0x00,              /*               nop.i 0x0;;        */
576  0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14,  /*   [MMI]       ld8 r16=[r14],8;;  */
577  0x10, 0x41, 0x38, 0x30, 0x28, 0x00,  /*               ld8 r17=[r14],8    */
578  0x00, 0x00, 0x04, 0x00,              /*               nop.i 0x0;;        */
579  0x11, 0x08, 0x00, 0x1c, 0x18, 0x10,  /*   [MIB]       ld8 r1=[r14]       */
580  0x60, 0x88, 0x04, 0x80, 0x03, 0x00,  /*               mov b6=r17         */
581  0x60, 0x00, 0x80, 0x00               /*               br.few b6;;        */
582};
583
584static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
585{
586  0x11, 0x78, 0x00, 0x00, 0x00, 0x24,  /*   [MIB]       mov r15=0          */
587  0x00, 0x00, 0x00, 0x02, 0x00, 0x00,  /*               nop.i 0x0          */
588  0x00, 0x00, 0x00, 0x40               /*               br.few 0 <PLT0>;;  */
589};
590
591static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
592{
593  0x0b, 0x78, 0x00, 0x02, 0x00, 0x24,  /*   [MMI]       addl r15=0,r1;;    */
594  0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0,  /*               ld8 r16=[r15],8    */
595  0x01, 0x08, 0x00, 0x84,              /*               mov r14=r1;;       */
596  0x11, 0x08, 0x00, 0x1e, 0x18, 0x10,  /*   [MIB]       ld8 r1=[r15]       */
597  0x60, 0x80, 0x04, 0x80, 0x03, 0x00,  /*               mov b6=r16         */
598  0x60, 0x00, 0x80, 0x00               /*               br.few b6;;        */
599};
600
601#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
602#define AIX_DYNAMIC_INTERPRETER "/usr/lib/ia64l64/libc.so.1"
603#define DYNAMIC_INTERPRETER(abfd) \
604  (elfNN_ia64_aix_vec (abfd->xvec) ? AIX_DYNAMIC_INTERPRETER : ELF_DYNAMIC_INTERPRETER)
605
606/* Select out of range branch fixup type.  Note that Itanium does
607   not support brl, and so it gets emulated by the kernel.  */
608#undef USE_BRL
609
610static const bfd_byte oor_brl[16] =
611{
612  0x05, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MLX]        nop.m 0            */
613  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /*               brl.sptk.few tgt;; */
614  0x00, 0x00, 0x00, 0xc0
615};
616
617static const bfd_byte oor_ip[48] =
618{
619  0x04, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MLX]        nop.m 0            */
620  0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,  /*               movl r15=0         */
621  0x01, 0x00, 0x00, 0x60,
622  0x03, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MII]        nop.m 0            */
623  0x00, 0x01, 0x00, 0x60, 0x00, 0x00,  /*               mov r16=ip;;       */
624  0xf2, 0x80, 0x00, 0x80,              /*               add r16=r15,r16;;  */
625  0x11, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MIB]        nop.m 0            */
626  0x60, 0x80, 0x04, 0x80, 0x03, 0x00,  /*               mov b6=r16         */
627  0x60, 0x00, 0x80, 0x00               /*               br b6;;            */
628};
629
630/* These functions do relaxation for IA-64 ELF.
631
632   This is primarily to support branches to targets out of range;
633   relaxation of R_IA64_LTOFF22X and R_IA64_LDXMOV not yet supported.  */
634
635static boolean
636elfNN_ia64_relax_section (abfd, sec, link_info, again)
637     bfd *abfd;
638     asection *sec;
639     struct bfd_link_info *link_info;
640     boolean *again;
641{
642  struct one_fixup
643    {
644      struct one_fixup *next;
645      asection *tsec;
646      bfd_vma toff;
647      bfd_vma trampoff;
648    };
649
650  Elf_Internal_Shdr *symtab_hdr;
651  Elf_Internal_Shdr *shndx_hdr;
652  Elf_Internal_Rela *internal_relocs;
653  Elf_Internal_Rela *free_relocs = NULL;
654  Elf_Internal_Rela *irel, *irelend;
655  bfd_byte *contents;
656  bfd_byte *free_contents = NULL;
657  ElfNN_External_Sym *extsyms;
658  ElfNN_External_Sym *free_extsyms = NULL;
659  Elf_External_Sym_Shndx *shndx_buf = NULL;
660  struct elfNN_ia64_link_hash_table *ia64_info;
661  struct one_fixup *fixups = NULL;
662  boolean changed_contents = false;
663  boolean changed_relocs = false;
664
665  /* Assume we're not going to change any sizes, and we'll only need
666     one pass.  */
667  *again = false;
668
669  /* Nothing to do if there are no relocations.  */
670  if ((sec->flags & SEC_RELOC) == 0
671      || sec->reloc_count == 0)
672    return true;
673
674  /* If this is the first time we have been called for this section,
675     initialize the cooked size.  */
676  if (sec->_cooked_size == 0)
677    sec->_cooked_size = sec->_raw_size;
678
679  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
680
681  /* Load the relocations for this section.  */
682  internal_relocs = (_bfd_elfNN_link_read_relocs
683		     (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
684		      link_info->keep_memory));
685  if (internal_relocs == NULL)
686    goto error_return;
687
688  if (! link_info->keep_memory)
689    free_relocs = internal_relocs;
690
691  ia64_info = elfNN_ia64_hash_table (link_info);
692  irelend = internal_relocs + sec->reloc_count;
693
694  for (irel = internal_relocs; irel < irelend; irel++)
695    if (ELFNN_R_TYPE (irel->r_info) == (int) R_IA64_PCREL21B)
696      break;
697
698  /* No branch-type relocations.  */
699  if (irel == irelend)
700    {
701      if (free_relocs != NULL)
702	free (free_relocs);
703      return true;
704    }
705
706  /* Get the section contents.  */
707  if (elf_section_data (sec)->this_hdr.contents != NULL)
708    contents = elf_section_data (sec)->this_hdr.contents;
709  else
710    {
711      contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
712      if (contents == NULL)
713	goto error_return;
714      free_contents = contents;
715
716      if (! bfd_get_section_contents (abfd, sec, contents,
717				      (file_ptr) 0, sec->_raw_size))
718	goto error_return;
719    }
720
721  /* Read this BFD's local symbols.  */
722  if (symtab_hdr->contents != NULL)
723    extsyms = (ElfNN_External_Sym *) symtab_hdr->contents;
724  else
725    {
726      bfd_size_type amt;
727
728      amt = symtab_hdr->sh_info * sizeof (ElfNN_External_Sym);
729      extsyms = (ElfNN_External_Sym *) bfd_malloc (amt);
730      if (extsyms == NULL)
731	goto error_return;
732      free_extsyms = extsyms;
733      if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
734	  || bfd_bread (extsyms, amt, abfd) != amt)
735	goto error_return;
736    }
737
738  shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
739  if (shndx_hdr->sh_size != 0)
740    {
741      bfd_size_type amt;
742
743      amt = symtab_hdr->sh_info * sizeof (Elf_External_Sym_Shndx);
744      shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
745      if (shndx_buf == NULL)
746	goto error_return;
747      if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
748	  || bfd_bread (shndx_buf, amt, abfd) != amt)
749	goto error_return;
750    }
751
752  for (; irel < irelend; irel++)
753    {
754      bfd_vma symaddr, reladdr, trampoff, toff, roff;
755      Elf_Internal_Sym isym;
756      asection *tsec;
757      struct one_fixup *f;
758      bfd_size_type amt;
759
760      if (ELFNN_R_TYPE (irel->r_info) != (int) R_IA64_PCREL21B)
761	continue;
762
763      /* Get the value of the symbol referred to by the reloc.  */
764      if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
765	{
766	  ElfNN_External_Sym *esym;
767	  Elf_External_Sym_Shndx *shndx;
768
769	  /* A local symbol.  */
770	  esym = extsyms + ELFNN_R_SYM (irel->r_info);
771	  shndx = shndx_buf + (shndx_buf ? ELFNN_R_SYM (irel->r_info) : 0);
772	  bfd_elfNN_swap_symbol_in (abfd, esym, shndx, &isym);
773	  if (isym.st_shndx == SHN_UNDEF)
774	    continue;	/* We can't do anthing with undefined symbols.  */
775	  else if (isym.st_shndx == SHN_ABS)
776	    tsec = bfd_abs_section_ptr;
777	  else if (isym.st_shndx == SHN_COMMON)
778	    tsec = bfd_com_section_ptr;
779	  else if (isym.st_shndx == SHN_IA_64_ANSI_COMMON)
780	    tsec = bfd_com_section_ptr;
781	  else
782	    tsec = bfd_section_from_elf_index (abfd, isym.st_shndx);
783
784	  toff = isym.st_value;
785	}
786      else
787	{
788	  unsigned long indx;
789	  struct elf_link_hash_entry *h;
790          struct elfNN_ia64_dyn_sym_info *dyn_i;
791
792	  indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
793	  h = elf_sym_hashes (abfd)[indx];
794	  BFD_ASSERT (h != NULL);
795
796	  while (h->root.type == bfd_link_hash_indirect
797		 || h->root.type == bfd_link_hash_warning)
798	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
799
800	  dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, false);
801
802	  /* For branches to dynamic symbols, we're interested instead
803	     in a branch to the PLT entry.  */
804	  if (dyn_i && dyn_i->want_plt2)
805	    {
806	      tsec = ia64_info->plt_sec;
807	      toff = dyn_i->plt2_offset;
808	    }
809	  else
810	    {
811	      /* We can't do anthing with undefined symbols.  */
812	      if (h->root.type == bfd_link_hash_undefined
813		  || h->root.type == bfd_link_hash_undefweak)
814		continue;
815
816	      tsec = h->root.u.def.section;
817	      toff = h->root.u.def.value;
818	    }
819	}
820
821      symaddr = (tsec->output_section->vma
822		 + tsec->output_offset
823		 + toff
824		 + irel->r_addend);
825
826      roff = irel->r_offset;
827      reladdr = (sec->output_section->vma
828		 + sec->output_offset
829		 + roff) & (bfd_vma) -4;
830
831      /* If the branch is in range, no need to do anything.  */
832      if ((bfd_signed_vma) (symaddr - reladdr) >= -0x1000000
833	  && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
834	continue;
835
836      /* If the branch and target are in the same section, you've
837	 got one honking big section and we can't help you.  You'll
838	 get an error message later.  */
839      if (tsec == sec)
840	continue;
841
842      /* Look for an existing fixup to this address.  */
843      for (f = fixups; f ; f = f->next)
844	if (f->tsec == tsec && f->toff == toff)
845	  break;
846
847      if (f == NULL)
848	{
849	  /* Two alternatives: If it's a branch to a PLT entry, we can
850	     make a copy of the FULL_PLT entry.  Otherwise, we'll have
851	     to use a `brl' insn to get where we're going.  */
852
853	  size_t size;
854
855	  if (tsec == ia64_info->plt_sec)
856	    size = sizeof (plt_full_entry);
857	  else
858	    {
859#ifdef USE_BRL
860	      size = sizeof (oor_brl);
861#else
862	      size = sizeof (oor_ip);
863#endif
864	    }
865
866	  /* Resize the current section to make room for the new branch.  */
867	  trampoff = (sec->_cooked_size + 15) & (bfd_vma) -16;
868	  amt = trampoff + size;
869	  contents = (bfd_byte *) bfd_realloc (contents, amt);
870	  if (contents == NULL)
871	    goto error_return;
872	  sec->_cooked_size = amt;
873
874	  if (tsec == ia64_info->plt_sec)
875	    {
876	      memcpy (contents + trampoff, plt_full_entry, size);
877
878	      /* Hijack the old relocation for use as the PLTOFF reloc.  */
879	      irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
880					   R_IA64_PLTOFF22);
881	      irel->r_offset = trampoff;
882	    }
883	  else
884	    {
885#ifdef USE_BRL
886	      memcpy (contents + trampoff, oor_brl, size);
887	      irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
888					   R_IA64_PCREL60B);
889	      irel->r_offset = trampoff + 2;
890#else
891	      memcpy (contents + trampoff, oor_ip, size);
892	      irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
893					   R_IA64_PCREL64I);
894	      irel->r_addend -= 16;
895	      irel->r_offset = trampoff + 2;
896#endif
897	    }
898
899	  /* Record the fixup so we don't do it again this section.  */
900	  f = (struct one_fixup *) bfd_malloc ((bfd_size_type) sizeof (*f));
901	  f->next = fixups;
902	  f->tsec = tsec;
903	  f->toff = toff;
904	  f->trampoff = trampoff;
905	  fixups = f;
906	}
907      else
908	{
909	  /* Nop out the reloc, since we're finalizing things here.  */
910	  irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
911	}
912
913      /* Fix up the existing branch to hit the trampoline.  Hope like
914	 hell this doesn't overflow too.  */
915      if (elfNN_ia64_install_value (abfd, contents + roff,
916				    f->trampoff - (roff & (bfd_vma) -4),
917				    R_IA64_PCREL21B) != bfd_reloc_ok)
918	goto error_return;
919
920      changed_contents = true;
921      changed_relocs = true;
922    }
923
924  /* Clean up and go home.  */
925  while (fixups)
926    {
927      struct one_fixup *f = fixups;
928      fixups = fixups->next;
929      free (f);
930    }
931
932  if (changed_relocs)
933    elf_section_data (sec)->relocs = internal_relocs;
934  else if (free_relocs != NULL)
935    free (free_relocs);
936
937  if (changed_contents)
938    elf_section_data (sec)->this_hdr.contents = contents;
939  else if (free_contents != NULL)
940    {
941      if (! link_info->keep_memory)
942	free (free_contents);
943      else
944	{
945	  /* Cache the section contents for elf_link_input_bfd.  */
946	  elf_section_data (sec)->this_hdr.contents = contents;
947	}
948    }
949
950  if (shndx_buf != NULL)
951    free (shndx_buf);
952
953  if (free_extsyms != NULL)
954    {
955      if (! link_info->keep_memory)
956	free (free_extsyms);
957      else
958	{
959	  /* Cache the symbols for elf_link_input_bfd.  */
960	  symtab_hdr->contents = (unsigned char *) extsyms;
961	}
962    }
963
964  *again = changed_contents || changed_relocs;
965  return true;
966
967 error_return:
968  if (free_relocs != NULL)
969    free (free_relocs);
970  if (free_contents != NULL)
971    free (free_contents);
972  if (shndx_buf != NULL)
973    free (shndx_buf);
974  if (free_extsyms != NULL)
975    free (free_extsyms);
976  return false;
977}
978
979/* Return true if NAME is an unwind table section name.  */
980
981static inline boolean
982is_unwind_section_name (abfd, name)
983	bfd *abfd;
984	const char *name;
985{
986  size_t len1, len2, len3;
987
988  if (elfNN_ia64_hpux_vec (abfd->xvec)
989      && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
990    return false;
991
992  len1 = sizeof (ELF_STRING_ia64_unwind) - 1;
993  len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
994  len3 = sizeof (ELF_STRING_ia64_unwind_once) - 1;
995  return ((strncmp (name, ELF_STRING_ia64_unwind, len1) == 0
996	   && strncmp (name, ELF_STRING_ia64_unwind_info, len2) != 0)
997	  || strncmp (name, ELF_STRING_ia64_unwind_once, len3) == 0);
998}
999
1000/* Handle an IA-64 specific section when reading an object file.  This
1001   is called when elfcode.h finds a section with an unknown type.  */
1002
1003static boolean
1004elfNN_ia64_section_from_shdr (abfd, hdr, name)
1005     bfd *abfd;
1006     ElfNN_Internal_Shdr *hdr;
1007     char *name;
1008{
1009  asection *newsect;
1010
1011  /* There ought to be a place to keep ELF backend specific flags, but
1012     at the moment there isn't one.  We just keep track of the
1013     sections by their name, instead.  Fortunately, the ABI gives
1014     suggested names for all the MIPS specific sections, so we will
1015     probably get away with this.  */
1016  switch (hdr->sh_type)
1017    {
1018    case SHT_IA_64_UNWIND:
1019    case SHT_IA_64_HP_OPT_ANOT:
1020      break;
1021
1022    case SHT_IA_64_EXT:
1023      if (strcmp (name, ELF_STRING_ia64_archext) != 0)
1024	return false;
1025      break;
1026
1027    default:
1028      return false;
1029    }
1030
1031  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
1032    return false;
1033  newsect = hdr->bfd_section;
1034
1035  return true;
1036}
1037
1038/* Convert IA-64 specific section flags to bfd internal section flags.  */
1039
1040/* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1041   flag.  */
1042
1043static boolean
1044elfNN_ia64_section_flags (flags, hdr)
1045     flagword *flags;
1046     ElfNN_Internal_Shdr *hdr;
1047{
1048  if (hdr->sh_flags & SHF_IA_64_SHORT)
1049    *flags |= SEC_SMALL_DATA;
1050
1051  return true;
1052}
1053
1054/* Set the correct type for an IA-64 ELF section.  We do this by the
1055   section name, which is a hack, but ought to work.  */
1056
1057static boolean
1058elfNN_ia64_fake_sections (abfd, hdr, sec)
1059     bfd *abfd ATTRIBUTE_UNUSED;
1060     ElfNN_Internal_Shdr *hdr;
1061     asection *sec;
1062{
1063  register const char *name;
1064
1065  name = bfd_get_section_name (abfd, sec);
1066
1067  if (is_unwind_section_name (abfd, name))
1068    {
1069      /* We don't have the sections numbered at this point, so sh_info
1070	 is set later, in elfNN_ia64_final_write_processing.  */
1071      hdr->sh_type = SHT_IA_64_UNWIND;
1072      hdr->sh_flags |= SHF_LINK_ORDER;
1073    }
1074  else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
1075    hdr->sh_type = SHT_IA_64_EXT;
1076  else if (strcmp (name, ".HP.opt_annot") == 0)
1077    hdr->sh_type = SHT_IA_64_HP_OPT_ANOT;
1078  else if (strcmp (name, ".reloc") == 0)
1079    /*
1080     * This is an ugly, but unfortunately necessary hack that is
1081     * needed when producing EFI binaries on IA-64. It tells
1082     * elf.c:elf_fake_sections() not to consider ".reloc" as a section
1083     * containing ELF relocation info.  We need this hack in order to
1084     * be able to generate ELF binaries that can be translated into
1085     * EFI applications (which are essentially COFF objects).  Those
1086     * files contain a COFF ".reloc" section inside an ELFNN object,
1087     * which would normally cause BFD to segfault because it would
1088     * attempt to interpret this section as containing relocation
1089     * entries for section "oc".  With this hack enabled, ".reloc"
1090     * will be treated as a normal data section, which will avoid the
1091     * segfault.  However, you won't be able to create an ELFNN binary
1092     * with a section named "oc" that needs relocations, but that's
1093     * the kind of ugly side-effects you get when detecting section
1094     * types based on their names...  In practice, this limitation is
1095     * unlikely to bite.
1096     */
1097    hdr->sh_type = SHT_PROGBITS;
1098
1099  if (sec->flags & SEC_SMALL_DATA)
1100    hdr->sh_flags |= SHF_IA_64_SHORT;
1101
1102  return true;
1103}
1104
1105/* The final processing done just before writing out an IA-64 ELF
1106   object file.  */
1107
1108static void
1109elfNN_ia64_final_write_processing (abfd, linker)
1110     bfd *abfd;
1111     boolean linker ATTRIBUTE_UNUSED;
1112{
1113  Elf_Internal_Shdr *hdr;
1114  const char *sname;
1115  asection *text_sect, *s;
1116  size_t len;
1117
1118  for (s = abfd->sections; s; s = s->next)
1119    {
1120      hdr = &elf_section_data (s)->this_hdr;
1121      switch (hdr->sh_type)
1122	{
1123	case SHT_IA_64_UNWIND:
1124	  /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1125	     have to do this.  */
1126	  sname = bfd_get_section_name (abfd, s);
1127	  len = sizeof (ELF_STRING_ia64_unwind) - 1;
1128	  if (sname && strncmp (sname, ELF_STRING_ia64_unwind, len) == 0)
1129	    {
1130	      sname += len;
1131
1132	      if (sname[0] == '\0')
1133		/* .IA_64.unwind -> .text */
1134		text_sect = bfd_get_section_by_name (abfd, ".text");
1135	      else
1136		/* .IA_64.unwindFOO -> FOO */
1137		text_sect = bfd_get_section_by_name (abfd, sname);
1138	    }
1139	  else if (sname
1140		   && (len = sizeof (ELF_STRING_ia64_unwind_once) - 1,
1141		       strncmp (sname, ELF_STRING_ia64_unwind_once, len)) == 0)
1142	    {
1143	      /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
1144	      size_t len2 = sizeof (".gnu.linkonce.t.") - 1;
1145	      char *once_name = bfd_malloc (len2 + strlen (sname + len) + 1);
1146
1147	      if (once_name != NULL)
1148		{
1149		  memcpy (once_name, ".gnu.linkonce.t.", len2);
1150		  strcpy (once_name + len2, sname + len);
1151		  text_sect = bfd_get_section_by_name (abfd, once_name);
1152		  free (once_name);
1153		}
1154	      else
1155		/* Should only happen if we run out of memory, in
1156		   which case we're probably toast anyway.  Try to
1157		   cope by finding the section the slow way.  */
1158		for (text_sect = abfd->sections;
1159		     text_sect != NULL;
1160		     text_sect = text_sect->next)
1161		  {
1162		    if (strncmp (bfd_section_name (abfd, text_sect),
1163				 ".gnu.linkonce.t.", len2) == 0
1164			&& strcmp (bfd_section_name (abfd, text_sect) + len2,
1165				   sname + len) == 0)
1166		      break;
1167		  }
1168	    }
1169	  else
1170	    /* last resort: fall back on .text */
1171	    text_sect = bfd_get_section_by_name (abfd, ".text");
1172
1173	  if (text_sect)
1174	    {
1175	      /* The IA-64 processor-specific ABI requires setting
1176		 sh_link to the unwind section, whereas HP-UX requires
1177		 sh_info to do so.  For maximum compatibility, we'll
1178		 set both for now... */
1179	      hdr->sh_link = elf_section_data (text_sect)->this_idx;
1180	      hdr->sh_info = elf_section_data (text_sect)->this_idx;
1181	    }
1182	  break;
1183	}
1184    }
1185}
1186
1187/* Hook called by the linker routine which adds symbols from an object
1188   file.  We use it to put .comm items in .sbss, and not .bss.  */
1189
1190static boolean
1191elfNN_ia64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1192     bfd *abfd;
1193     struct bfd_link_info *info;
1194     const Elf_Internal_Sym *sym;
1195     const char **namep ATTRIBUTE_UNUSED;
1196     flagword *flagsp ATTRIBUTE_UNUSED;
1197     asection **secp;
1198     bfd_vma *valp;
1199{
1200  if (sym->st_shndx == SHN_COMMON
1201      && !info->relocateable
1202      && sym->st_size <= elf_gp_size (abfd))
1203    {
1204      /* Common symbols less than or equal to -G nn bytes are
1205	 automatically put into .sbss.  */
1206
1207      asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1208
1209      if (scomm == NULL)
1210	{
1211	  scomm = bfd_make_section (abfd, ".scommon");
1212	  if (scomm == NULL
1213	      || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
1214						       | SEC_IS_COMMON
1215						       | SEC_LINKER_CREATED)))
1216	    return false;
1217	}
1218
1219      *secp = scomm;
1220      *valp = sym->st_size;
1221    }
1222
1223  return true;
1224}
1225
1226static boolean
1227elfNN_ia64_aix_vec (const bfd_target *vec)
1228{
1229  extern const bfd_target bfd_elfNN_ia64_aix_little_vec;
1230  extern const bfd_target bfd_elfNN_ia64_aix_big_vec;
1231
1232  return (/**/vec == & bfd_elfNN_ia64_aix_little_vec
1233	  ||  vec == & bfd_elfNN_ia64_aix_big_vec);
1234}
1235
1236/* Hook called by the linker routine which adds symbols from an object
1237   file.  We use it to handle OS-specific symbols.  */
1238
1239static boolean
1240elfNN_ia64_aix_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1241     bfd *abfd;
1242     struct bfd_link_info *info;
1243     const Elf_Internal_Sym *sym;
1244     const char **namep;
1245     flagword *flagsp;
1246     asection **secp;
1247     bfd_vma *valp;
1248{
1249  if (strcmp (*namep, "__GLOB_DATA_PTR") == 0)
1250    {
1251      /* Define __GLOB_DATA_PTR when it is encountered.  This is expected to
1252	 be a linker-defined symbol by the Aix C runtime startup code. IBM sez
1253	 no one else should use it b/c it is undocumented.  */
1254      struct elf_link_hash_entry *h;
1255
1256      h = elf_link_hash_lookup (elf_hash_table (info), *namep,
1257				false, false, false);
1258      if (h == NULL)
1259	{
1260	  struct elf_backend_data *bed;
1261	  struct elfNN_ia64_link_hash_table *ia64_info;
1262
1263	  bed = get_elf_backend_data (abfd);
1264	  ia64_info = elfNN_ia64_hash_table (info);
1265
1266	  if (!(_bfd_generic_link_add_one_symbol
1267		(info, abfd, *namep, BSF_GLOBAL,
1268		 bfd_get_section_by_name (abfd, ".bss"),
1269		 bed->got_symbol_offset, (const char *) NULL, false,
1270		 bed->collect, (struct bfd_link_hash_entry **) &h)))
1271	    return false;
1272
1273	  h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
1274	  h->type = STT_OBJECT;
1275
1276	  if (! _bfd_elf_link_record_dynamic_symbol (info, h))
1277	    return false;
1278	}
1279
1280      return true;
1281    }
1282  else if (sym->st_shndx == SHN_LOOS)
1283    {
1284      unsigned int i;
1285
1286      /* SHN_AIX_SYSCALL: Treat this as any other symbol.  The special symbol
1287	 is only relevant when compiling code for extended system calls.
1288	 Replace the "special" section with .text, if possible.
1289	 Note that these symbols are always assumed to be in .text. */
1290      for (i = 1; i < elf_numsections (abfd); i++)
1291	{
1292	  asection * sec = bfd_section_from_elf_index (abfd, i);
1293
1294	  if (sec && strcmp (sec->name, ".text") == 0)
1295	    {
1296	      *secp = sec;
1297	      break;
1298	    }
1299	}
1300
1301      if (*secp == NULL)
1302	*secp = bfd_abs_section_ptr;
1303
1304      *valp = sym->st_size;
1305
1306      return true;
1307    }
1308  else
1309    {
1310      return elfNN_ia64_add_symbol_hook (abfd, info, sym,
1311					 namep, flagsp, secp, valp);
1312    }
1313}
1314
1315boolean
1316elfNN_ia64_aix_link_add_symbols (abfd, info)
1317     bfd *abfd;
1318     struct bfd_link_info *info;
1319{
1320  /* Make sure dynamic sections are always created.  */
1321  if (! elf_hash_table (info)->dynamic_sections_created
1322      && abfd->xvec == info->hash->creator)
1323    {
1324      if (! bfd_elfNN_link_create_dynamic_sections (abfd, info))
1325	return false;
1326    }
1327
1328  /* Now do the standard call.  */
1329  return bfd_elfNN_bfd_link_add_symbols (abfd, info);
1330}
1331
1332/* Return the number of additional phdrs we will need.  */
1333
1334static int
1335elfNN_ia64_additional_program_headers (abfd)
1336     bfd *abfd;
1337{
1338  asection *s;
1339  int ret = 0;
1340
1341  /* See if we need a PT_IA_64_ARCHEXT segment.  */
1342  s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1343  if (s && (s->flags & SEC_LOAD))
1344    ++ret;
1345
1346  /* Count how many PT_IA_64_UNWIND segments we need.  */
1347  for (s = abfd->sections; s; s = s->next)
1348    if (is_unwind_section_name (abfd, s->name) && (s->flags & SEC_LOAD))
1349      ++ret;
1350
1351  return ret;
1352}
1353
1354static boolean
1355elfNN_ia64_modify_segment_map (abfd)
1356     bfd *abfd;
1357{
1358  struct elf_segment_map *m, **pm;
1359  Elf_Internal_Shdr *hdr;
1360  asection *s;
1361  boolean unwind_found;
1362  asection *unwind_sec;
1363
1364  /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1365     all PT_LOAD segments.  */
1366  s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1367  if (s && (s->flags & SEC_LOAD))
1368    {
1369      for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1370	if (m->p_type == PT_IA_64_ARCHEXT)
1371	  break;
1372      if (m == NULL)
1373	{
1374	  m = ((struct elf_segment_map *)
1375	       bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1376	  if (m == NULL)
1377	    return false;
1378
1379	  m->p_type = PT_IA_64_ARCHEXT;
1380	  m->count = 1;
1381	  m->sections[0] = s;
1382
1383	  /* We want to put it after the PHDR and INTERP segments.  */
1384	  pm = &elf_tdata (abfd)->segment_map;
1385	  while (*pm != NULL
1386		 && ((*pm)->p_type == PT_PHDR
1387		     || (*pm)->p_type == PT_INTERP))
1388	    pm = &(*pm)->next;
1389
1390	  m->next = *pm;
1391	  *pm = m;
1392	}
1393    }
1394
1395  /* Install PT_IA_64_UNWIND segments, if needed.  */
1396  for (s = abfd->sections; s; s = s->next)
1397    {
1398      hdr = &elf_section_data (s)->this_hdr;
1399      if (hdr->sh_type != SHT_IA_64_UNWIND)
1400	continue;
1401
1402      if (s && (s->flags & SEC_LOAD))
1403	{
1404	  for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1405	    if (m->p_type == PT_IA_64_UNWIND)
1406	      {
1407		/* Look through all sections in the unwind segment
1408		   for a match since there may be multiple sections
1409		   to a segment.  */
1410
1411		unwind_sec = m->sections[0];
1412		unwind_found = false;
1413		while (unwind_sec != NULL && !unwind_found)
1414		  {
1415		    if (unwind_sec == s)
1416		      unwind_found = true;
1417		    else
1418		      unwind_sec = unwind_sec -> next;
1419		  }
1420		if (unwind_found)
1421		  break;
1422	      }
1423
1424	  if (m == NULL)
1425	    {
1426	      m = ((struct elf_segment_map *)
1427		   bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1428	      if (m == NULL)
1429		return false;
1430
1431	      m->p_type = PT_IA_64_UNWIND;
1432	      m->count = 1;
1433	      m->sections[0] = s;
1434	      m->next = NULL;
1435
1436	      /* We want to put it last.  */
1437	      pm = &elf_tdata (abfd)->segment_map;
1438	      while (*pm != NULL)
1439		pm = &(*pm)->next;
1440	      *pm = m;
1441	    }
1442	}
1443    }
1444
1445  /* Turn on PF_IA_64_NORECOV if needed.  This involves traversing all of
1446     the input sections for each output section in the segment and testing
1447     for SHF_IA_64_NORECOV on each.  */
1448  for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1449    if (m->p_type == PT_LOAD)
1450      {
1451	int i;
1452	for (i = m->count - 1; i >= 0; --i)
1453	  {
1454	    struct bfd_link_order *order = m->sections[i]->link_order_head;
1455	    while (order)
1456	      {
1457		if (order->type == bfd_indirect_link_order)
1458		  {
1459		    asection *is = order->u.indirect.section;
1460		    bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
1461		    if (flags & SHF_IA_64_NORECOV)
1462		      {
1463			m->p_flags |= PF_IA_64_NORECOV;
1464			goto found;
1465		      }
1466		  }
1467		order = order->next;
1468	      }
1469	  }
1470      found:;
1471      }
1472
1473  return true;
1474}
1475
1476/* According to the Tahoe assembler spec, all labels starting with a
1477   '.' are local.  */
1478
1479static boolean
1480elfNN_ia64_is_local_label_name (abfd, name)
1481     bfd *abfd ATTRIBUTE_UNUSED;
1482     const char *name;
1483{
1484  return name[0] == '.';
1485}
1486
1487/* Should we do dynamic things to this symbol?  */
1488
1489static boolean
1490elfNN_ia64_dynamic_symbol_p (h, info)
1491     struct elf_link_hash_entry *h;
1492     struct bfd_link_info *info;
1493{
1494  if (h == NULL)
1495    return false;
1496
1497  while (h->root.type == bfd_link_hash_indirect
1498	 || h->root.type == bfd_link_hash_warning)
1499    h = (struct elf_link_hash_entry *) h->root.u.i.link;
1500
1501  if (h->dynindx == -1)
1502    return false;
1503  switch (ELF_ST_VISIBILITY (h->other))
1504    {
1505    case STV_INTERNAL:
1506    case STV_HIDDEN:
1507      return false;
1508    }
1509
1510  if (h->root.type == bfd_link_hash_undefweak
1511      || h->root.type == bfd_link_hash_defweak)
1512    return true;
1513
1514  if ((info->shared && (!info->symbolic || info->allow_shlib_undefined))
1515      || ((h->elf_link_hash_flags
1516	   & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR))
1517	  == (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)))
1518    return true;
1519
1520  return false;
1521}
1522
1523static boolean
1524elfNN_ia64_local_hash_table_init (ht, abfd, new)
1525     struct elfNN_ia64_local_hash_table *ht;
1526     bfd *abfd ATTRIBUTE_UNUSED;
1527     new_hash_entry_func new;
1528{
1529  memset (ht, 0, sizeof (*ht));
1530  return bfd_hash_table_init (&ht->root, new);
1531}
1532
1533static struct bfd_hash_entry*
1534elfNN_ia64_new_loc_hash_entry (entry, table, string)
1535     struct bfd_hash_entry *entry;
1536     struct bfd_hash_table *table;
1537     const char *string;
1538{
1539  struct elfNN_ia64_local_hash_entry *ret;
1540  ret = (struct elfNN_ia64_local_hash_entry *) entry;
1541
1542  /* Allocate the structure if it has not already been allocated by a
1543     subclass.  */
1544  if (!ret)
1545    ret = bfd_hash_allocate (table, sizeof (*ret));
1546
1547  if (!ret)
1548    return 0;
1549
1550  /* Initialize our local data.  All zeros, and definitely easier
1551     than setting a handful of bit fields.  */
1552  memset (ret, 0, sizeof (*ret));
1553
1554  /* Call the allocation method of the superclass.  */
1555  ret = ((struct elfNN_ia64_local_hash_entry *)
1556	 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
1557
1558  return (struct bfd_hash_entry *) ret;
1559}
1560
1561static struct bfd_hash_entry*
1562elfNN_ia64_new_elf_hash_entry (entry, table, string)
1563     struct bfd_hash_entry *entry;
1564     struct bfd_hash_table *table;
1565     const char *string;
1566{
1567  struct elfNN_ia64_link_hash_entry *ret;
1568  ret = (struct elfNN_ia64_link_hash_entry *) entry;
1569
1570  /* Allocate the structure if it has not already been allocated by a
1571     subclass.  */
1572  if (!ret)
1573    ret = bfd_hash_allocate (table, sizeof (*ret));
1574
1575  if (!ret)
1576    return 0;
1577
1578  /* Initialize our local data.  All zeros, and definitely easier
1579     than setting a handful of bit fields.  */
1580  memset (ret, 0, sizeof (*ret));
1581
1582  /* Call the allocation method of the superclass.  */
1583  ret = ((struct elfNN_ia64_link_hash_entry *)
1584	 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1585				     table, string));
1586
1587  return (struct bfd_hash_entry *) ret;
1588}
1589
1590static void
1591elfNN_ia64_hash_copy_indirect (xdir, xind)
1592     struct elf_link_hash_entry *xdir, *xind;
1593{
1594  struct elfNN_ia64_link_hash_entry *dir, *ind;
1595
1596  dir = (struct elfNN_ia64_link_hash_entry *) xdir;
1597  ind = (struct elfNN_ia64_link_hash_entry *) xind;
1598
1599  /* Copy down any references that we may have already seen to the
1600     symbol which just became indirect.  */
1601
1602  dir->root.elf_link_hash_flags |=
1603    (ind->root.elf_link_hash_flags
1604     & (ELF_LINK_HASH_REF_DYNAMIC
1605        | ELF_LINK_HASH_REF_REGULAR
1606        | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
1607
1608  if (ind->root.root.type != bfd_link_hash_indirect)
1609    return;
1610
1611  /* Copy over the got and plt data.  This would have been done
1612     by check_relocs.  */
1613
1614  if (dir->info == NULL)
1615    {
1616      struct elfNN_ia64_dyn_sym_info *dyn_i;
1617
1618      dir->info = dyn_i = ind->info;
1619      ind->info = NULL;
1620
1621      /* Fix up the dyn_sym_info pointers to the global symbol.  */
1622      for (; dyn_i; dyn_i = dyn_i->next)
1623	dyn_i->h = &dir->root;
1624    }
1625  BFD_ASSERT (ind->info == NULL);
1626
1627  /* Copy over the dynindx.  */
1628
1629  if (dir->root.dynindx == -1)
1630    {
1631      dir->root.dynindx = ind->root.dynindx;
1632      dir->root.dynstr_index = ind->root.dynstr_index;
1633      ind->root.dynindx = -1;
1634      ind->root.dynstr_index = 0;
1635    }
1636  BFD_ASSERT (ind->root.dynindx == -1);
1637}
1638
1639static void
1640elfNN_ia64_hash_hide_symbol (info, xh, force_local)
1641     struct bfd_link_info *info;
1642     struct elf_link_hash_entry *xh;
1643     boolean force_local;
1644{
1645  struct elfNN_ia64_link_hash_entry *h;
1646  struct elfNN_ia64_dyn_sym_info *dyn_i;
1647
1648  h = (struct elfNN_ia64_link_hash_entry *)xh;
1649
1650  _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1651
1652  for (dyn_i = h->info; dyn_i; dyn_i = dyn_i->next)
1653    dyn_i->want_plt2 = 0;
1654}
1655
1656/* Create the derived linker hash table.  The IA-64 ELF port uses this
1657   derived hash table to keep information specific to the IA-64 ElF
1658   linker (without using static variables).  */
1659
1660static struct bfd_link_hash_table*
1661elfNN_ia64_hash_table_create (abfd)
1662     bfd *abfd;
1663{
1664  struct elfNN_ia64_link_hash_table *ret;
1665
1666  ret = bfd_zalloc (abfd, (bfd_size_type) sizeof (*ret));
1667  if (!ret)
1668    return 0;
1669  if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1670				      elfNN_ia64_new_elf_hash_entry))
1671    {
1672      bfd_release (abfd, ret);
1673      return 0;
1674    }
1675
1676  if (!elfNN_ia64_local_hash_table_init (&ret->loc_hash_table, abfd,
1677				         elfNN_ia64_new_loc_hash_entry))
1678    return 0;
1679  return &ret->root.root;
1680}
1681
1682/* Look up an entry in a Alpha ELF linker hash table.  */
1683
1684static INLINE struct elfNN_ia64_local_hash_entry *
1685elfNN_ia64_local_hash_lookup(table, string, create, copy)
1686     struct elfNN_ia64_local_hash_table *table;
1687     const char *string;
1688     boolean create, copy;
1689{
1690  return ((struct elfNN_ia64_local_hash_entry *)
1691	  bfd_hash_lookup (&table->root, string, create, copy));
1692}
1693
1694/* Traverse both local and global hash tables.  */
1695
1696struct elfNN_ia64_dyn_sym_traverse_data
1697{
1698  boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1699  PTR data;
1700};
1701
1702static boolean
1703elfNN_ia64_global_dyn_sym_thunk (xentry, xdata)
1704     struct bfd_hash_entry *xentry;
1705     PTR xdata;
1706{
1707  struct elfNN_ia64_link_hash_entry *entry
1708    = (struct elfNN_ia64_link_hash_entry *) xentry;
1709  struct elfNN_ia64_dyn_sym_traverse_data *data
1710    = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1711  struct elfNN_ia64_dyn_sym_info *dyn_i;
1712
1713  if (entry->root.root.type == bfd_link_hash_warning)
1714    entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
1715
1716  for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1717    if (! (*data->func) (dyn_i, data->data))
1718      return false;
1719  return true;
1720}
1721
1722static boolean
1723elfNN_ia64_local_dyn_sym_thunk (xentry, xdata)
1724     struct bfd_hash_entry *xentry;
1725     PTR xdata;
1726{
1727  struct elfNN_ia64_local_hash_entry *entry
1728    = (struct elfNN_ia64_local_hash_entry *) xentry;
1729  struct elfNN_ia64_dyn_sym_traverse_data *data
1730    = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1731  struct elfNN_ia64_dyn_sym_info *dyn_i;
1732
1733  for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1734    if (! (*data->func) (dyn_i, data->data))
1735      return false;
1736  return true;
1737}
1738
1739static void
1740elfNN_ia64_dyn_sym_traverse (ia64_info, func, data)
1741     struct elfNN_ia64_link_hash_table *ia64_info;
1742     boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1743     PTR data;
1744{
1745  struct elfNN_ia64_dyn_sym_traverse_data xdata;
1746
1747  xdata.func = func;
1748  xdata.data = data;
1749
1750  elf_link_hash_traverse (&ia64_info->root,
1751			  elfNN_ia64_global_dyn_sym_thunk, &xdata);
1752  bfd_hash_traverse (&ia64_info->loc_hash_table.root,
1753		     elfNN_ia64_local_dyn_sym_thunk, &xdata);
1754}
1755
1756static boolean
1757elfNN_ia64_create_dynamic_sections (abfd, info)
1758     bfd *abfd;
1759     struct bfd_link_info *info;
1760{
1761  struct elfNN_ia64_link_hash_table *ia64_info;
1762  asection *s;
1763
1764  if (! _bfd_elf_create_dynamic_sections (abfd, info))
1765    return false;
1766
1767  ia64_info = elfNN_ia64_hash_table (info);
1768
1769  ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
1770  ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
1771
1772  {
1773    flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
1774    bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
1775  }
1776
1777  if (!get_pltoff (abfd, info, ia64_info))
1778    return false;
1779
1780  s = bfd_make_section(abfd, ".rela.IA_64.pltoff");
1781  if (s == NULL
1782      || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1783					   | SEC_HAS_CONTENTS
1784					   | SEC_IN_MEMORY
1785					   | SEC_LINKER_CREATED
1786					   | SEC_READONLY))
1787      || !bfd_set_section_alignment (abfd, s, 3))
1788    return false;
1789  ia64_info->rel_pltoff_sec = s;
1790
1791  s = bfd_make_section(abfd, ".rela.got");
1792  if (s == NULL
1793      || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1794					   | SEC_HAS_CONTENTS
1795					   | SEC_IN_MEMORY
1796					   | SEC_LINKER_CREATED
1797					   | SEC_READONLY))
1798      || !bfd_set_section_alignment (abfd, s, 3))
1799    return false;
1800  ia64_info->rel_got_sec = s;
1801
1802  return true;
1803}
1804
1805/* Find and/or create a hash entry for local symbol.  */
1806static struct elfNN_ia64_local_hash_entry *
1807get_local_sym_hash (ia64_info, abfd, rel, create)
1808     struct elfNN_ia64_link_hash_table *ia64_info;
1809     bfd *abfd;
1810     const Elf_Internal_Rela *rel;
1811     boolean create;
1812{
1813  char *addr_name;
1814  size_t len;
1815  struct elfNN_ia64_local_hash_entry *ret;
1816
1817  /* Construct a string for use in the elfNN_ia64_local_hash_table.
1818     name describes what was once anonymous memory.  */
1819
1820  len = sizeof (void*)*2 + 1 + sizeof (bfd_vma)*4 + 1 + 1;
1821  len += 10;	/* %p slop */
1822
1823  addr_name = bfd_malloc (len);
1824  if (addr_name == NULL)
1825    return 0;
1826  sprintf (addr_name, "%p:%lx",
1827	   (void *) abfd, (unsigned long) ELFNN_R_SYM (rel->r_info));
1828
1829  /* Collect the canonical entry data for this address.  */
1830  ret = elfNN_ia64_local_hash_lookup (&ia64_info->loc_hash_table,
1831				      addr_name, create, create);
1832  free (addr_name);
1833  return ret;
1834}
1835
1836/* Find and/or create a descriptor for dynamic symbol info.  This will
1837   vary based on global or local symbol, and the addend to the reloc.  */
1838
1839static struct elfNN_ia64_dyn_sym_info *
1840get_dyn_sym_info (ia64_info, h, abfd, rel, create)
1841     struct elfNN_ia64_link_hash_table *ia64_info;
1842     struct elf_link_hash_entry *h;
1843     bfd *abfd;
1844     const Elf_Internal_Rela *rel;
1845     boolean create;
1846{
1847  struct elfNN_ia64_dyn_sym_info **pp;
1848  struct elfNN_ia64_dyn_sym_info *dyn_i;
1849  bfd_vma addend = rel ? rel->r_addend : 0;
1850
1851  if (h)
1852    pp = &((struct elfNN_ia64_link_hash_entry *)h)->info;
1853  else
1854    {
1855      struct elfNN_ia64_local_hash_entry *loc_h;
1856
1857      loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
1858      BFD_ASSERT (loc_h);
1859
1860      pp = &loc_h->info;
1861    }
1862
1863  for (dyn_i = *pp; dyn_i && dyn_i->addend != addend; dyn_i = *pp)
1864    pp = &dyn_i->next;
1865
1866  if (dyn_i == NULL && create)
1867    {
1868      dyn_i = ((struct elfNN_ia64_dyn_sym_info *)
1869	       bfd_zalloc (abfd, (bfd_size_type) sizeof *dyn_i));
1870      *pp = dyn_i;
1871      dyn_i->addend = addend;
1872    }
1873
1874  return dyn_i;
1875}
1876
1877static asection *
1878get_got (abfd, info, ia64_info)
1879     bfd *abfd;
1880     struct bfd_link_info *info;
1881     struct elfNN_ia64_link_hash_table *ia64_info;
1882{
1883  asection *got;
1884  bfd *dynobj;
1885
1886  got = ia64_info->got_sec;
1887  if (!got)
1888    {
1889      flagword flags;
1890
1891      dynobj = ia64_info->root.dynobj;
1892      if (!dynobj)
1893	ia64_info->root.dynobj = dynobj = abfd;
1894      if (!_bfd_elf_create_got_section (dynobj, info))
1895	return 0;
1896
1897      got = bfd_get_section_by_name (dynobj, ".got");
1898      BFD_ASSERT (got);
1899      ia64_info->got_sec = got;
1900
1901      flags = bfd_get_section_flags (abfd, got);
1902      bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
1903    }
1904
1905  return got;
1906}
1907
1908/* Create function descriptor section (.opd).  This section is called .opd
1909   because it contains "official prodecure descriptors".  The "official"
1910   refers to the fact that these descriptors are used when taking the address
1911   of a procedure, thus ensuring a unique address for each procedure.  */
1912
1913static asection *
1914get_fptr (abfd, info, ia64_info)
1915     bfd *abfd;
1916     struct bfd_link_info *info ATTRIBUTE_UNUSED;
1917     struct elfNN_ia64_link_hash_table *ia64_info;
1918{
1919  asection *fptr;
1920  bfd *dynobj;
1921
1922  fptr = ia64_info->fptr_sec;
1923  if (!fptr)
1924    {
1925      dynobj = ia64_info->root.dynobj;
1926      if (!dynobj)
1927	ia64_info->root.dynobj = dynobj = abfd;
1928
1929      fptr = bfd_make_section (dynobj, ".opd");
1930      if (!fptr
1931	  || !bfd_set_section_flags (dynobj, fptr,
1932				     (SEC_ALLOC
1933				      | SEC_LOAD
1934				      | SEC_HAS_CONTENTS
1935				      | SEC_IN_MEMORY
1936				      | SEC_READONLY
1937				      | SEC_LINKER_CREATED))
1938	  || !bfd_set_section_alignment (abfd, fptr, 4))
1939	{
1940	  BFD_ASSERT (0);
1941	  return NULL;
1942	}
1943
1944      ia64_info->fptr_sec = fptr;
1945    }
1946
1947  return fptr;
1948}
1949
1950static asection *
1951get_pltoff (abfd, info, ia64_info)
1952     bfd *abfd;
1953     struct bfd_link_info *info ATTRIBUTE_UNUSED;
1954     struct elfNN_ia64_link_hash_table *ia64_info;
1955{
1956  asection *pltoff;
1957  bfd *dynobj;
1958
1959  pltoff = ia64_info->pltoff_sec;
1960  if (!pltoff)
1961    {
1962      dynobj = ia64_info->root.dynobj;
1963      if (!dynobj)
1964	ia64_info->root.dynobj = dynobj = abfd;
1965
1966      pltoff = bfd_make_section (dynobj, ELF_STRING_ia64_pltoff);
1967      if (!pltoff
1968	  || !bfd_set_section_flags (dynobj, pltoff,
1969				     (SEC_ALLOC
1970				      | SEC_LOAD
1971				      | SEC_HAS_CONTENTS
1972				      | SEC_IN_MEMORY
1973				      | SEC_SMALL_DATA
1974				      | SEC_LINKER_CREATED))
1975	  || !bfd_set_section_alignment (abfd, pltoff, 4))
1976	{
1977	  BFD_ASSERT (0);
1978	  return NULL;
1979	}
1980
1981      ia64_info->pltoff_sec = pltoff;
1982    }
1983
1984  return pltoff;
1985}
1986
1987static asection *
1988get_reloc_section (abfd, ia64_info, sec, create)
1989     bfd *abfd;
1990     struct elfNN_ia64_link_hash_table *ia64_info;
1991     asection *sec;
1992     boolean create;
1993{
1994  const char *srel_name;
1995  asection *srel;
1996  bfd *dynobj;
1997
1998  srel_name = (bfd_elf_string_from_elf_section
1999	       (abfd, elf_elfheader(abfd)->e_shstrndx,
2000		elf_section_data(sec)->rel_hdr.sh_name));
2001  if (srel_name == NULL)
2002    return NULL;
2003
2004  BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0
2005	       && strcmp (bfd_get_section_name (abfd, sec),
2006			  srel_name+5) == 0)
2007	      || (strncmp (srel_name, ".rel", 4) == 0
2008		  && strcmp (bfd_get_section_name (abfd, sec),
2009			     srel_name+4) == 0));
2010
2011  dynobj = ia64_info->root.dynobj;
2012  if (!dynobj)
2013    ia64_info->root.dynobj = dynobj = abfd;
2014
2015  srel = bfd_get_section_by_name (dynobj, srel_name);
2016  if (srel == NULL && create)
2017    {
2018      srel = bfd_make_section (dynobj, srel_name);
2019      if (srel == NULL
2020	  || !bfd_set_section_flags (dynobj, srel,
2021				     (SEC_ALLOC
2022				      | SEC_LOAD
2023				      | SEC_HAS_CONTENTS
2024				      | SEC_IN_MEMORY
2025				      | SEC_LINKER_CREATED
2026				      | SEC_READONLY))
2027	  || !bfd_set_section_alignment (dynobj, srel, 3))
2028	return NULL;
2029    }
2030
2031  if (sec->flags & SEC_READONLY)
2032    ia64_info->reltext = 1;
2033
2034  return srel;
2035}
2036
2037static boolean
2038count_dyn_reloc (abfd, dyn_i, srel, type)
2039     bfd *abfd;
2040     struct elfNN_ia64_dyn_sym_info *dyn_i;
2041     asection *srel;
2042     int type;
2043{
2044  struct elfNN_ia64_dyn_reloc_entry *rent;
2045
2046  for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2047    if (rent->srel == srel && rent->type == type)
2048      break;
2049
2050  if (!rent)
2051    {
2052      rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2053	      bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
2054      if (!rent)
2055	return false;
2056
2057      rent->next = dyn_i->reloc_entries;
2058      rent->srel = srel;
2059      rent->type = type;
2060      rent->count = 0;
2061      dyn_i->reloc_entries = rent;
2062    }
2063  rent->count++;
2064
2065  return true;
2066}
2067
2068static boolean
2069elfNN_ia64_check_relocs (abfd, info, sec, relocs)
2070     bfd *abfd;
2071     struct bfd_link_info *info;
2072     asection *sec;
2073     const Elf_Internal_Rela *relocs;
2074{
2075  struct elfNN_ia64_link_hash_table *ia64_info;
2076  const Elf_Internal_Rela *relend;
2077  Elf_Internal_Shdr *symtab_hdr;
2078  const Elf_Internal_Rela *rel;
2079  asection *got, *fptr, *srel;
2080
2081  if (info->relocateable)
2082    return true;
2083
2084  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2085  ia64_info = elfNN_ia64_hash_table (info);
2086
2087  got = fptr = srel = NULL;
2088
2089  relend = relocs + sec->reloc_count;
2090  for (rel = relocs; rel < relend; ++rel)
2091    {
2092      enum {
2093	NEED_GOT = 1,
2094	NEED_FPTR = 2,
2095	NEED_PLTOFF = 4,
2096	NEED_MIN_PLT = 8,
2097	NEED_FULL_PLT = 16,
2098	NEED_DYNREL = 32,
2099	NEED_LTOFF_FPTR = 64,
2100      };
2101
2102      struct elf_link_hash_entry *h = NULL;
2103      unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
2104      struct elfNN_ia64_dyn_sym_info *dyn_i;
2105      int need_entry;
2106      boolean maybe_dynamic;
2107      int dynrel_type = R_IA64_NONE;
2108
2109      if (r_symndx >= symtab_hdr->sh_info)
2110	{
2111	  /* We're dealing with a global symbol -- find its hash entry
2112	     and mark it as being referenced.  */
2113	  long indx = r_symndx - symtab_hdr->sh_info;
2114	  h = elf_sym_hashes (abfd)[indx];
2115	  while (h->root.type == bfd_link_hash_indirect
2116		 || h->root.type == bfd_link_hash_warning)
2117	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
2118
2119	  h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
2120	}
2121
2122      /* We can only get preliminary data on whether a symbol is
2123	 locally or externally defined, as not all of the input files
2124	 have yet been processed.  Do something with what we know, as
2125	 this may help reduce memory usage and processing time later.  */
2126      maybe_dynamic = false;
2127      if (h && ((info->shared
2128		      && (!info->symbolic || info->allow_shlib_undefined))
2129		|| ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
2130		|| h->root.type == bfd_link_hash_defweak
2131		|| elfNN_ia64_aix_vec (abfd->xvec)))
2132	maybe_dynamic = true;
2133
2134      need_entry = 0;
2135      switch (ELFNN_R_TYPE (rel->r_info))
2136	{
2137	case R_IA64_TPREL22:
2138	case R_IA64_TPREL64MSB:
2139	case R_IA64_TPREL64LSB:
2140	case R_IA64_LTOFF_TP22:
2141	  return false;
2142
2143	case R_IA64_LTOFF_FPTR22:
2144	case R_IA64_LTOFF_FPTR64I:
2145	case R_IA64_LTOFF_FPTR32MSB:
2146	case R_IA64_LTOFF_FPTR32LSB:
2147	case R_IA64_LTOFF_FPTR64MSB:
2148	case R_IA64_LTOFF_FPTR64LSB:
2149	  need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2150	  break;
2151
2152	case R_IA64_FPTR64I:
2153	case R_IA64_FPTR32MSB:
2154	case R_IA64_FPTR32LSB:
2155	case R_IA64_FPTR64MSB:
2156	case R_IA64_FPTR64LSB:
2157	  if (info->shared || h || elfNN_ia64_aix_vec (abfd->xvec))
2158	    need_entry = NEED_FPTR | NEED_DYNREL;
2159	  else
2160	    need_entry = NEED_FPTR;
2161	  dynrel_type = R_IA64_FPTR64LSB;
2162	  break;
2163
2164	case R_IA64_LTOFF22:
2165	case R_IA64_LTOFF22X:
2166	case R_IA64_LTOFF64I:
2167	  need_entry = NEED_GOT;
2168	  break;
2169
2170	case R_IA64_PLTOFF22:
2171	case R_IA64_PLTOFF64I:
2172	case R_IA64_PLTOFF64MSB:
2173	case R_IA64_PLTOFF64LSB:
2174	  need_entry = NEED_PLTOFF;
2175	  if (h)
2176	    {
2177	      if (maybe_dynamic)
2178		need_entry |= NEED_MIN_PLT;
2179	    }
2180	  else
2181	    {
2182	      (*info->callbacks->warning)
2183		(info, _("@pltoff reloc against local symbol"), 0,
2184		 abfd, 0, (bfd_vma) 0);
2185	    }
2186	  break;
2187
2188	case R_IA64_PCREL21B:
2189        case R_IA64_PCREL60B:
2190	  /* Depending on where this symbol is defined, we may or may not
2191	     need a full plt entry.  Only skip if we know we'll not need
2192	     the entry -- static or symbolic, and the symbol definition
2193	     has already been seen.  */
2194	  if (maybe_dynamic && rel->r_addend == 0)
2195	    need_entry = NEED_FULL_PLT;
2196	  break;
2197
2198	case R_IA64_IMM14:
2199	case R_IA64_IMM22:
2200	case R_IA64_IMM64:
2201	case R_IA64_DIR32MSB:
2202	case R_IA64_DIR32LSB:
2203	case R_IA64_DIR64MSB:
2204	case R_IA64_DIR64LSB:
2205	  /* Shared objects will always need at least a REL relocation.  */
2206	  if (info->shared || maybe_dynamic
2207	      || (elfNN_ia64_aix_vec (abfd->xvec)
2208		  && (!h || strcmp (h->root.root.string,
2209				    "__GLOB_DATA_PTR") != 0)))
2210	    need_entry = NEED_DYNREL;
2211	  dynrel_type = R_IA64_DIR64LSB;
2212	  break;
2213
2214	case R_IA64_IPLTMSB:
2215	case R_IA64_IPLTLSB:
2216	  /* Shared objects will always need at least a REL relocation.  */
2217	  if (info->shared || maybe_dynamic)
2218	    need_entry = NEED_DYNREL;
2219	  dynrel_type = R_IA64_IPLTLSB;
2220	  break;
2221
2222	case R_IA64_PCREL22:
2223	case R_IA64_PCREL64I:
2224	case R_IA64_PCREL32MSB:
2225	case R_IA64_PCREL32LSB:
2226	case R_IA64_PCREL64MSB:
2227	case R_IA64_PCREL64LSB:
2228	  if (maybe_dynamic)
2229	    need_entry = NEED_DYNREL;
2230	  dynrel_type = R_IA64_PCREL64LSB;
2231	  break;
2232	}
2233
2234      if (!need_entry)
2235	continue;
2236
2237      if ((need_entry & NEED_FPTR) != 0
2238	  && rel->r_addend)
2239	{
2240	  (*info->callbacks->warning)
2241	    (info, _("non-zero addend in @fptr reloc"), 0,
2242	     abfd, 0, (bfd_vma) 0);
2243	}
2244
2245      dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, true);
2246
2247      /* Record whether or not this is a local symbol.  */
2248      dyn_i->h = h;
2249
2250      /* Create what's needed.  */
2251      if (need_entry & NEED_GOT)
2252	{
2253	  if (!got)
2254	    {
2255	      got = get_got (abfd, info, ia64_info);
2256	      if (!got)
2257		return false;
2258	    }
2259	  dyn_i->want_got = 1;
2260	}
2261      if (need_entry & NEED_FPTR)
2262	{
2263	  if (!fptr)
2264	    {
2265	      fptr = get_fptr (abfd, info, ia64_info);
2266	      if (!fptr)
2267		return false;
2268	    }
2269
2270	  /* FPTRs for shared libraries are allocated by the dynamic
2271	     linker.  Make sure this local symbol will appear in the
2272	     dynamic symbol table.  */
2273	  if (!h && (info->shared
2274		     /* AIX also needs one */
2275		     || elfNN_ia64_aix_vec (abfd->xvec)))
2276	    {
2277	      if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2278		     (info, abfd, (long) r_symndx)))
2279		return false;
2280	    }
2281
2282	  dyn_i->want_fptr = 1;
2283	}
2284      if (need_entry & NEED_LTOFF_FPTR)
2285	dyn_i->want_ltoff_fptr = 1;
2286      if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
2287	{
2288          if (!ia64_info->root.dynobj)
2289	    ia64_info->root.dynobj = abfd;
2290	  h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
2291	  dyn_i->want_plt = 1;
2292	}
2293      if (need_entry & NEED_FULL_PLT)
2294	dyn_i->want_plt2 = 1;
2295      if (need_entry & NEED_PLTOFF)
2296	dyn_i->want_pltoff = 1;
2297      if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
2298	{
2299	  if (!srel)
2300	    {
2301	      srel = get_reloc_section (abfd, ia64_info, sec, true);
2302	      if (!srel)
2303		return false;
2304	    }
2305	  if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type))
2306	    return false;
2307	}
2308    }
2309
2310  return true;
2311}
2312
2313struct elfNN_ia64_allocate_data
2314{
2315  struct bfd_link_info *info;
2316  bfd_size_type ofs;
2317};
2318
2319/* For cleanliness, and potentially faster dynamic loading, allocate
2320   external GOT entries first.  */
2321
2322static boolean
2323allocate_global_data_got (dyn_i, data)
2324     struct elfNN_ia64_dyn_sym_info *dyn_i;
2325     PTR data;
2326{
2327  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2328
2329  if (dyn_i->want_got
2330      && ! dyn_i->want_fptr
2331      && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2332	  || (elfNN_ia64_aix_vec (x->info->hash->creator)
2333	      && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2334				       "__GLOB_DATA_PTR") != 0))))
2335     {
2336       dyn_i->got_offset = x->ofs;
2337       x->ofs += 8;
2338     }
2339  return true;
2340}
2341
2342/* Next, allocate all the GOT entries used by LTOFF_FPTR relocs.  */
2343
2344static boolean
2345allocate_global_fptr_got (dyn_i, data)
2346     struct elfNN_ia64_dyn_sym_info *dyn_i;
2347     PTR data;
2348{
2349  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2350
2351  if (dyn_i->want_got
2352      && dyn_i->want_fptr
2353      && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2354	  || elfNN_ia64_aix_vec (x->info->hash->creator)))
2355    {
2356      dyn_i->got_offset = x->ofs;
2357      x->ofs += 8;
2358    }
2359  return true;
2360}
2361
2362/* Lastly, allocate all the GOT entries for local data.  */
2363
2364static boolean
2365allocate_local_got (dyn_i, data)
2366     struct elfNN_ia64_dyn_sym_info *dyn_i;
2367     PTR data;
2368{
2369  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2370
2371  if (dyn_i->want_got
2372      && ! (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2373	    || elfNN_ia64_aix_vec (x->info->hash->creator)))
2374    {
2375      dyn_i->got_offset = x->ofs;
2376      x->ofs += 8;
2377    }
2378  return true;
2379}
2380
2381/* Search for the index of a global symbol in it's defining object file.  */
2382
2383static long
2384global_sym_index (h)
2385     struct elf_link_hash_entry *h;
2386{
2387  struct elf_link_hash_entry **p;
2388  bfd *obj;
2389
2390  BFD_ASSERT (h->root.type == bfd_link_hash_defined
2391	      || h->root.type == bfd_link_hash_defweak);
2392
2393  obj = h->root.u.def.section->owner;
2394  for (p = elf_sym_hashes (obj); *p != h; ++p)
2395    continue;
2396
2397  return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2398}
2399
2400/* Allocate function descriptors.  We can do these for every function
2401   in a main executable that is not exported.  */
2402
2403static boolean
2404allocate_fptr (dyn_i, data)
2405     struct elfNN_ia64_dyn_sym_info *dyn_i;
2406     PTR data;
2407{
2408  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2409
2410  if (dyn_i->want_fptr)
2411    {
2412      struct elf_link_hash_entry *h = dyn_i->h;
2413
2414      if (h)
2415	while (h->root.type == bfd_link_hash_indirect
2416	       || h->root.type == bfd_link_hash_warning)
2417	  h = (struct elf_link_hash_entry *) h->root.u.i.link;
2418
2419      if (x->info->shared
2420	  /* AIX needs an FPTR in this case. */
2421	  || (elfNN_ia64_aix_vec (x->info->hash->creator)
2422	      && (!h
2423		  || h->root.type == bfd_link_hash_defined
2424		  || h->root.type == bfd_link_hash_defweak)))
2425	{
2426	  if (h && h->dynindx == -1)
2427	    {
2428	      BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2429			  || (h->root.type == bfd_link_hash_defweak));
2430
2431	      if (!_bfd_elfNN_link_record_local_dynamic_symbol
2432		    (x->info, h->root.u.def.section->owner,
2433		     global_sym_index (h)))
2434		return false;
2435	    }
2436
2437	  dyn_i->want_fptr = 0;
2438	}
2439      else if (h == NULL || h->dynindx == -1)
2440	{
2441	  dyn_i->fptr_offset = x->ofs;
2442	  x->ofs += 16;
2443	}
2444      else
2445	dyn_i->want_fptr = 0;
2446    }
2447  return true;
2448}
2449
2450/* Allocate all the minimal PLT entries.  */
2451
2452static boolean
2453allocate_plt_entries (dyn_i, data)
2454     struct elfNN_ia64_dyn_sym_info *dyn_i;
2455     PTR data;
2456{
2457  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2458
2459  if (dyn_i->want_plt)
2460    {
2461      struct elf_link_hash_entry *h = dyn_i->h;
2462
2463      if (h)
2464	while (h->root.type == bfd_link_hash_indirect
2465	       || h->root.type == bfd_link_hash_warning)
2466	  h = (struct elf_link_hash_entry *) h->root.u.i.link;
2467
2468      /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT.  */
2469      if (elfNN_ia64_dynamic_symbol_p (h, x->info))
2470	{
2471	  bfd_size_type offset = x->ofs;
2472	  if (offset == 0)
2473	    offset = PLT_HEADER_SIZE;
2474	  dyn_i->plt_offset = offset;
2475	  x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2476
2477	  dyn_i->want_pltoff = 1;
2478	}
2479      else
2480	{
2481	  dyn_i->want_plt = 0;
2482	  dyn_i->want_plt2 = 0;
2483	}
2484    }
2485  return true;
2486}
2487
2488/* Allocate all the full PLT entries.  */
2489
2490static boolean
2491allocate_plt2_entries (dyn_i, data)
2492     struct elfNN_ia64_dyn_sym_info *dyn_i;
2493     PTR data;
2494{
2495  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2496
2497  if (dyn_i->want_plt2)
2498    {
2499      struct elf_link_hash_entry *h = dyn_i->h;
2500      bfd_size_type ofs = x->ofs;
2501
2502      dyn_i->plt2_offset = ofs;
2503      x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2504
2505      while (h->root.type == bfd_link_hash_indirect
2506	     || h->root.type == bfd_link_hash_warning)
2507	h = (struct elf_link_hash_entry *) h->root.u.i.link;
2508      dyn_i->h->plt.offset = ofs;
2509    }
2510  return true;
2511}
2512
2513/* Allocate all the PLTOFF entries requested by relocations and
2514   plt entries.  We can't share space with allocated FPTR entries,
2515   because the latter are not necessarily addressable by the GP.
2516   ??? Relaxation might be able to determine that they are.  */
2517
2518static boolean
2519allocate_pltoff_entries (dyn_i, data)
2520     struct elfNN_ia64_dyn_sym_info *dyn_i;
2521     PTR data;
2522{
2523  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2524
2525  if (dyn_i->want_pltoff)
2526    {
2527      dyn_i->pltoff_offset = x->ofs;
2528      x->ofs += 16;
2529    }
2530  return true;
2531}
2532
2533/* Allocate dynamic relocations for those symbols that turned out
2534   to be dynamic.  */
2535
2536static boolean
2537allocate_dynrel_entries (dyn_i, data)
2538     struct elfNN_ia64_dyn_sym_info *dyn_i;
2539     PTR data;
2540{
2541  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2542  struct elfNN_ia64_link_hash_table *ia64_info;
2543  struct elfNN_ia64_dyn_reloc_entry *rent;
2544  boolean dynamic_symbol, shared;
2545
2546  ia64_info = elfNN_ia64_hash_table (x->info);
2547  dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2548    || (elfNN_ia64_aix_vec (x->info->hash->creator)
2549	/* Don't allocate an entry for __GLOB_DATA_PTR */
2550	&& (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2551	  "__GLOB_DATA_PTR") != 0));
2552  shared = x->info->shared;
2553
2554  /* Take care of the normal data relocations.  */
2555
2556  for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2557    {
2558      int count = rent->count;
2559
2560      switch (rent->type)
2561	{
2562	case R_IA64_FPTR64LSB:
2563	  /* Allocate one iff !want_fptr, which by this point will
2564	     be true only if we're actually allocating one statically
2565	     in the main executable.  */
2566	  if (dyn_i->want_fptr)
2567	    continue;
2568	  break;
2569	case R_IA64_PCREL64LSB:
2570	  if (!dynamic_symbol)
2571	    continue;
2572	  break;
2573	case R_IA64_DIR64LSB:
2574	  if (!dynamic_symbol && !shared)
2575	    continue;
2576	  break;
2577	case R_IA64_IPLTLSB:
2578	  if (!dynamic_symbol && !shared)
2579	    continue;
2580	  /* Use two REL relocations for IPLT relocations
2581	     against local symbols.  */
2582	  if (!dynamic_symbol)
2583	    count *= 2;
2584	  break;
2585	default:
2586	  abort ();
2587	}
2588      rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * count;
2589    }
2590
2591  /* Take care of the GOT and PLT relocations.  */
2592
2593  if (((dynamic_symbol || shared) && dyn_i->want_got)
2594      || (dyn_i->want_ltoff_fptr && dyn_i->h && dyn_i->h->dynindx != -1))
2595    ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2596
2597  if (dyn_i->want_pltoff)
2598    {
2599      bfd_size_type t = 0;
2600
2601      /* Dynamic symbols get one IPLT relocation.  Local symbols in
2602	 shared libraries get two REL relocations.  Local symbols in
2603	 main applications get nothing.  */
2604      if (dynamic_symbol)
2605	t = sizeof (ElfNN_External_Rela);
2606      else if (shared)
2607	t = 2 * sizeof (ElfNN_External_Rela);
2608
2609      ia64_info->rel_pltoff_sec->_raw_size += t;
2610    }
2611
2612  return true;
2613}
2614
2615static boolean
2616elfNN_ia64_adjust_dynamic_symbol (info, h)
2617     struct bfd_link_info *info ATTRIBUTE_UNUSED;
2618     struct elf_link_hash_entry *h;
2619{
2620  /* ??? Undefined symbols with PLT entries should be re-defined
2621     to be the PLT entry.  */
2622
2623  /* If this is a weak symbol, and there is a real definition, the
2624     processor independent code will have arranged for us to see the
2625     real definition first, and we can just use the same value.  */
2626  if (h->weakdef != NULL)
2627    {
2628      BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
2629                  || h->weakdef->root.type == bfd_link_hash_defweak);
2630      h->root.u.def.section = h->weakdef->root.u.def.section;
2631      h->root.u.def.value = h->weakdef->root.u.def.value;
2632      return true;
2633    }
2634
2635  /* If this is a reference to a symbol defined by a dynamic object which
2636     is not a function, we might allocate the symbol in our .dynbss section
2637     and allocate a COPY dynamic relocation.
2638
2639     But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2640     of hackery.  */
2641
2642  return true;
2643}
2644
2645static boolean
2646elfNN_ia64_size_dynamic_sections (output_bfd, info)
2647     bfd *output_bfd;
2648     struct bfd_link_info *info;
2649{
2650  struct elfNN_ia64_allocate_data data;
2651  struct elfNN_ia64_link_hash_table *ia64_info;
2652  asection *sec;
2653  bfd *dynobj;
2654  boolean relplt = false;
2655
2656  dynobj = elf_hash_table(info)->dynobj;
2657  ia64_info = elfNN_ia64_hash_table (info);
2658  BFD_ASSERT(dynobj != NULL);
2659  data.info = info;
2660
2661  /* Set the contents of the .interp section to the interpreter.  */
2662  if (ia64_info->root.dynamic_sections_created
2663      && !info->shared)
2664    {
2665      sec = bfd_get_section_by_name (dynobj, ".interp");
2666      BFD_ASSERT (sec != NULL);
2667      sec->contents = (bfd_byte *) DYNAMIC_INTERPRETER (output_bfd);
2668      sec->_raw_size = strlen (DYNAMIC_INTERPRETER (output_bfd)) + 1;
2669    }
2670
2671  /* Allocate the GOT entries.  */
2672
2673  if (ia64_info->got_sec)
2674    {
2675      data.ofs = 0;
2676      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
2677      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
2678      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
2679      ia64_info->got_sec->_raw_size = data.ofs;
2680    }
2681
2682  /* Allocate the FPTR entries.  */
2683
2684  if (ia64_info->fptr_sec)
2685    {
2686      data.ofs = 0;
2687      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
2688      ia64_info->fptr_sec->_raw_size = data.ofs;
2689    }
2690
2691  /* Now that we've seen all of the input files, we can decide which
2692     symbols need plt entries.  Allocate the minimal PLT entries first.
2693     We do this even though dynamic_sections_created may be false, because
2694     this has the side-effect of clearing want_plt and want_plt2.  */
2695
2696  data.ofs = 0;
2697  elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
2698
2699  ia64_info->minplt_entries = 0;
2700  if (data.ofs)
2701    {
2702      ia64_info->minplt_entries
2703	= (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
2704    }
2705
2706  /* Align the pointer for the plt2 entries.  */
2707  data.ofs = (data.ofs + 31) & (bfd_vma) -32;
2708
2709  elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
2710  if (data.ofs != 0)
2711    {
2712      BFD_ASSERT (ia64_info->root.dynamic_sections_created);
2713
2714      ia64_info->plt_sec->_raw_size = data.ofs;
2715
2716      /* If we've got a .plt, we need some extra memory for the dynamic
2717	 linker.  We stuff these in .got.plt.  */
2718      sec = bfd_get_section_by_name (dynobj, ".got.plt");
2719      sec->_raw_size = 8 * PLT_RESERVED_WORDS;
2720    }
2721
2722  /* Allocate the PLTOFF entries.  */
2723
2724  if (ia64_info->pltoff_sec)
2725    {
2726      data.ofs = 0;
2727      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
2728      ia64_info->pltoff_sec->_raw_size = data.ofs;
2729    }
2730
2731  if (ia64_info->root.dynamic_sections_created)
2732    {
2733      /* Allocate space for the dynamic relocations that turned out to be
2734	 required.  */
2735
2736      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
2737    }
2738
2739  /* We have now determined the sizes of the various dynamic sections.
2740     Allocate memory for them.  */
2741  for (sec = dynobj->sections; sec != NULL; sec = sec->next)
2742    {
2743      boolean strip;
2744
2745      if (!(sec->flags & SEC_LINKER_CREATED))
2746	continue;
2747
2748      /* If we don't need this section, strip it from the output file.
2749	 There were several sections primarily related to dynamic
2750	 linking that must be create before the linker maps input
2751	 sections to output sections.  The linker does that before
2752	 bfd_elf_size_dynamic_sections is called, and it is that
2753	 function which decides whether anything needs to go into
2754	 these sections.  */
2755
2756      strip = (sec->_raw_size == 0);
2757
2758      if (sec == ia64_info->got_sec)
2759	strip = false;
2760      else if (sec == ia64_info->rel_got_sec)
2761	{
2762	  if (strip)
2763	    ia64_info->rel_got_sec = NULL;
2764	  else
2765	    /* We use the reloc_count field as a counter if we need to
2766	       copy relocs into the output file.  */
2767	    sec->reloc_count = 0;
2768	}
2769      else if (sec == ia64_info->fptr_sec)
2770	{
2771	  if (strip)
2772	    ia64_info->fptr_sec = NULL;
2773	}
2774      else if (sec == ia64_info->plt_sec)
2775	{
2776	  if (strip)
2777	    ia64_info->plt_sec = NULL;
2778	}
2779      else if (sec == ia64_info->pltoff_sec)
2780	{
2781	  if (strip)
2782	    ia64_info->pltoff_sec = NULL;
2783	}
2784      else if (sec == ia64_info->rel_pltoff_sec)
2785	{
2786	  if (strip)
2787	    ia64_info->rel_pltoff_sec = NULL;
2788	  else
2789	    {
2790	      relplt = true;
2791	      /* We use the reloc_count field as a counter if we need to
2792		 copy relocs into the output file.  */
2793	      sec->reloc_count = 0;
2794	    }
2795	}
2796      else
2797	{
2798	  const char *name;
2799
2800	  /* It's OK to base decisions on the section name, because none
2801	     of the dynobj section names depend upon the input files.  */
2802	  name = bfd_get_section_name (dynobj, sec);
2803
2804	  if (strcmp (name, ".got.plt") == 0)
2805	    strip = false;
2806	  else if (strncmp (name, ".rel", 4) == 0)
2807	    {
2808	      if (!strip)
2809		{
2810		  /* We use the reloc_count field as a counter if we need to
2811		     copy relocs into the output file.  */
2812		  sec->reloc_count = 0;
2813		}
2814	    }
2815	  else
2816	    continue;
2817	}
2818
2819      if (strip)
2820	_bfd_strip_section_from_output (info, sec);
2821      else
2822	{
2823	  /* Allocate memory for the section contents.  */
2824	  sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->_raw_size);
2825	  if (sec->contents == NULL && sec->_raw_size != 0)
2826	    return false;
2827	}
2828    }
2829
2830  if (elf_hash_table (info)->dynamic_sections_created)
2831    {
2832      /* Add some entries to the .dynamic section.  We fill in the values
2833	 later (in finish_dynamic_sections) but we must add the entries now
2834	 so that we get the correct size for the .dynamic section.  */
2835
2836      if (!info->shared)
2837	{
2838	  /* The DT_DEBUG entry is filled in by the dynamic linker and used
2839	     by the debugger.  */
2840#define add_dynamic_entry(TAG, VAL) \
2841  bfd_elfNN_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
2842
2843	  if (!add_dynamic_entry (DT_DEBUG, 0))
2844	    return false;
2845	}
2846
2847      if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
2848	return false;
2849      if (!add_dynamic_entry (DT_PLTGOT, 0))
2850	return false;
2851
2852      if (relplt)
2853	{
2854	  if (!add_dynamic_entry (DT_PLTRELSZ, 0)
2855	      || !add_dynamic_entry (DT_PLTREL, DT_RELA)
2856	      || !add_dynamic_entry (DT_JMPREL, 0))
2857	    return false;
2858	}
2859
2860      if (!add_dynamic_entry (DT_RELA, 0)
2861	  || !add_dynamic_entry (DT_RELASZ, 0)
2862	  || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
2863	return false;
2864
2865      if (ia64_info->reltext)
2866	{
2867	  if (!add_dynamic_entry (DT_TEXTREL, 0))
2868	    return false;
2869	  info->flags |= DF_TEXTREL;
2870	}
2871    }
2872
2873  /* ??? Perhaps force __gp local.  */
2874
2875  return true;
2876}
2877
2878static bfd_reloc_status_type
2879elfNN_ia64_install_value (abfd, hit_addr, v, r_type)
2880     bfd *abfd;
2881     bfd_byte *hit_addr;
2882     bfd_vma v;
2883     unsigned int r_type;
2884{
2885  const struct ia64_operand *op;
2886  int bigendian = 0, shift = 0;
2887  bfd_vma t0, t1, insn, dword;
2888  enum ia64_opnd opnd;
2889  const char *err;
2890  size_t size = 8;
2891#ifdef BFD_HOST_U_64_BIT
2892  BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
2893#else
2894  bfd_vma val = v;
2895#endif
2896
2897  opnd = IA64_OPND_NIL;
2898  switch (r_type)
2899    {
2900    case R_IA64_NONE:
2901    case R_IA64_LDXMOV:
2902      return bfd_reloc_ok;
2903
2904      /* Instruction relocations.  */
2905
2906    case R_IA64_IMM14:		opnd = IA64_OPND_IMM14; break;
2907
2908    case R_IA64_PCREL21F:	opnd = IA64_OPND_TGT25; break;
2909    case R_IA64_PCREL21M:	opnd = IA64_OPND_TGT25b; break;
2910    case R_IA64_PCREL60B:	opnd = IA64_OPND_TGT64; break;
2911    case R_IA64_PCREL21B:
2912    case R_IA64_PCREL21BI:
2913      opnd = IA64_OPND_TGT25c;
2914      break;
2915
2916    case R_IA64_IMM22:
2917    case R_IA64_GPREL22:
2918    case R_IA64_LTOFF22:
2919    case R_IA64_LTOFF22X:
2920    case R_IA64_PLTOFF22:
2921    case R_IA64_PCREL22:
2922    case R_IA64_LTOFF_FPTR22:
2923      opnd = IA64_OPND_IMM22;
2924      break;
2925
2926    case R_IA64_IMM64:
2927    case R_IA64_GPREL64I:
2928    case R_IA64_LTOFF64I:
2929    case R_IA64_PLTOFF64I:
2930    case R_IA64_PCREL64I:
2931    case R_IA64_FPTR64I:
2932    case R_IA64_LTOFF_FPTR64I:
2933      opnd = IA64_OPND_IMMU64;
2934      break;
2935
2936      /* Data relocations.  */
2937
2938    case R_IA64_DIR32MSB:
2939    case R_IA64_GPREL32MSB:
2940    case R_IA64_FPTR32MSB:
2941    case R_IA64_PCREL32MSB:
2942    case R_IA64_LTOFF_FPTR32MSB:
2943    case R_IA64_SEGREL32MSB:
2944    case R_IA64_SECREL32MSB:
2945    case R_IA64_LTV32MSB:
2946      size = 4; bigendian = 1;
2947      break;
2948
2949    case R_IA64_DIR32LSB:
2950    case R_IA64_GPREL32LSB:
2951    case R_IA64_FPTR32LSB:
2952    case R_IA64_PCREL32LSB:
2953    case R_IA64_LTOFF_FPTR32LSB:
2954    case R_IA64_SEGREL32LSB:
2955    case R_IA64_SECREL32LSB:
2956    case R_IA64_LTV32LSB:
2957      size = 4; bigendian = 0;
2958      break;
2959
2960    case R_IA64_DIR64MSB:
2961    case R_IA64_GPREL64MSB:
2962    case R_IA64_PLTOFF64MSB:
2963    case R_IA64_FPTR64MSB:
2964    case R_IA64_PCREL64MSB:
2965    case R_IA64_LTOFF_FPTR64MSB:
2966    case R_IA64_SEGREL64MSB:
2967    case R_IA64_SECREL64MSB:
2968    case R_IA64_LTV64MSB:
2969      size = 8; bigendian = 1;
2970      break;
2971
2972    case R_IA64_DIR64LSB:
2973    case R_IA64_GPREL64LSB:
2974    case R_IA64_PLTOFF64LSB:
2975    case R_IA64_FPTR64LSB:
2976    case R_IA64_PCREL64LSB:
2977    case R_IA64_LTOFF_FPTR64LSB:
2978    case R_IA64_SEGREL64LSB:
2979    case R_IA64_SECREL64LSB:
2980    case R_IA64_LTV64LSB:
2981      size = 8; bigendian = 0;
2982      break;
2983
2984      /* Unsupported / Dynamic relocations.  */
2985    default:
2986      return bfd_reloc_notsupported;
2987    }
2988
2989  switch (opnd)
2990    {
2991    case IA64_OPND_IMMU64:
2992      hit_addr -= (long) hit_addr & 0x3;
2993      t0 = bfd_get_64 (abfd, hit_addr);
2994      t1 = bfd_get_64 (abfd, hit_addr + 8);
2995
2996      /* tmpl/s: bits  0.. 5 in t0
2997	 slot 0: bits  5..45 in t0
2998	 slot 1: bits 46..63 in t0, bits 0..22 in t1
2999	 slot 2: bits 23..63 in t1 */
3000
3001      /* First, clear the bits that form the 64 bit constant.  */
3002      t0 &= ~(0x3ffffLL << 46);
3003      t1 &= ~(0x7fffffLL
3004	      | ((  (0x07fLL << 13) | (0x1ffLL << 27)
3005		    | (0x01fLL << 22) | (0x001LL << 21)
3006		    | (0x001LL << 36)) << 23));
3007
3008      t0 |= ((val >> 22) & 0x03ffffLL) << 46;		/* 18 lsbs of imm41 */
3009      t1 |= ((val >> 40) & 0x7fffffLL) <<  0;		/* 23 msbs of imm41 */
3010      t1 |= (  (((val >>  0) & 0x07f) << 13)		/* imm7b */
3011	       | (((val >>  7) & 0x1ff) << 27)		/* imm9d */
3012	       | (((val >> 16) & 0x01f) << 22)		/* imm5c */
3013	       | (((val >> 21) & 0x001) << 21)		/* ic */
3014	       | (((val >> 63) & 0x001) << 36)) << 23;	/* i */
3015
3016      bfd_put_64 (abfd, t0, hit_addr);
3017      bfd_put_64 (abfd, t1, hit_addr + 8);
3018      break;
3019
3020    case IA64_OPND_TGT64:
3021      hit_addr -= (long) hit_addr & 0x3;
3022      t0 = bfd_get_64 (abfd, hit_addr);
3023      t1 = bfd_get_64 (abfd, hit_addr + 8);
3024
3025      /* tmpl/s: bits  0.. 5 in t0
3026	 slot 0: bits  5..45 in t0
3027	 slot 1: bits 46..63 in t0, bits 0..22 in t1
3028	 slot 2: bits 23..63 in t1 */
3029
3030      /* First, clear the bits that form the 64 bit constant.  */
3031      t0 &= ~(0x3ffffLL << 46);
3032      t1 &= ~(0x7fffffLL
3033	      | ((1LL << 36 | 0xfffffLL << 13) << 23));
3034
3035      val >>= 4;
3036      t0 |= ((val >> 20) & 0xffffLL) << 2 << 46;	/* 16 lsbs of imm39 */
3037      t1 |= ((val >> 36) & 0x7fffffLL) << 0;		/* 23 msbs of imm39 */
3038      t1 |= ((((val >> 0) & 0xfffffLL) << 13)		/* imm20b */
3039	      | (((val >> 59) & 0x1LL) << 36)) << 23;	/* i */
3040
3041      bfd_put_64 (abfd, t0, hit_addr);
3042      bfd_put_64 (abfd, t1, hit_addr + 8);
3043      break;
3044
3045    default:
3046      switch ((long) hit_addr & 0x3)
3047	{
3048	case 0: shift =  5; break;
3049	case 1: shift = 14; hit_addr += 3; break;
3050	case 2: shift = 23; hit_addr += 6; break;
3051	case 3: return bfd_reloc_notsupported; /* shouldn't happen...  */
3052	}
3053      dword = bfd_get_64 (abfd, hit_addr);
3054      insn = (dword >> shift) & 0x1ffffffffffLL;
3055
3056      op = elf64_ia64_operands + opnd;
3057      err = (*op->insert) (op, val, (ia64_insn *)& insn);
3058      if (err)
3059	return bfd_reloc_overflow;
3060
3061      dword &= ~(0x1ffffffffffLL << shift);
3062      dword |= (insn << shift);
3063      bfd_put_64 (abfd, dword, hit_addr);
3064      break;
3065
3066    case IA64_OPND_NIL:
3067      /* A data relocation.  */
3068      if (bigendian)
3069	if (size == 4)
3070	  bfd_putb32 (val, hit_addr);
3071	else
3072	  bfd_putb64 (val, hit_addr);
3073      else
3074	if (size == 4)
3075	  bfd_putl32 (val, hit_addr);
3076	else
3077	  bfd_putl64 (val, hit_addr);
3078      break;
3079    }
3080
3081  return bfd_reloc_ok;
3082}
3083
3084static void
3085elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
3086			      dynindx, addend)
3087     bfd *abfd;
3088     struct bfd_link_info *info;
3089     asection *sec;
3090     asection *srel;
3091     bfd_vma offset;
3092     unsigned int type;
3093     long dynindx;
3094     bfd_vma addend;
3095{
3096  Elf_Internal_Rela outrel;
3097
3098  offset += sec->output_section->vma + sec->output_offset;
3099
3100  BFD_ASSERT (dynindx != -1);
3101  outrel.r_info = ELFNN_R_INFO (dynindx, type);
3102  outrel.r_addend = addend;
3103  outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
3104  if ((outrel.r_offset | 1) == (bfd_vma) -1)
3105    {
3106      /* Run for the hills.  We shouldn't be outputting a relocation
3107	 for this.  So do what everyone else does and output a no-op.  */
3108      outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
3109      outrel.r_addend = 0;
3110      outrel.r_offset = 0;
3111    }
3112
3113  bfd_elfNN_swap_reloca_out (abfd, &outrel,
3114			     ((ElfNN_External_Rela *) srel->contents
3115			      + srel->reloc_count++));
3116  BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count
3117	      <= srel->_cooked_size);
3118}
3119
3120/* Store an entry for target address TARGET_ADDR in the linkage table
3121   and return the gp-relative address of the linkage table entry.  */
3122
3123static bfd_vma
3124set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
3125     bfd *abfd;
3126     struct bfd_link_info *info;
3127     struct elfNN_ia64_dyn_sym_info *dyn_i;
3128     long dynindx;
3129     bfd_vma addend;
3130     bfd_vma value;
3131     unsigned int dyn_r_type;
3132{
3133  struct elfNN_ia64_link_hash_table *ia64_info;
3134  asection *got_sec;
3135
3136  ia64_info = elfNN_ia64_hash_table (info);
3137  got_sec = ia64_info->got_sec;
3138
3139  BFD_ASSERT ((dyn_i->got_offset & 7) == 0);
3140
3141  if (! dyn_i->got_done)
3142    {
3143      dyn_i->got_done = true;
3144
3145      /* Store the target address in the linkage table entry.  */
3146      bfd_put_64 (abfd, value, got_sec->contents + dyn_i->got_offset);
3147
3148      /* Install a dynamic relocation if needed.  */
3149      if (info->shared
3150          || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info)
3151	  || elfNN_ia64_aix_vec (abfd->xvec)
3152	  || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
3153	{
3154	  if (dynindx == -1)
3155	    {
3156	      dyn_r_type = R_IA64_REL64LSB;
3157	      dynindx = 0;
3158	      addend = value;
3159	    }
3160
3161	  if (bfd_big_endian (abfd))
3162	    {
3163	      switch (dyn_r_type)
3164		{
3165		case R_IA64_REL64LSB:
3166		  dyn_r_type = R_IA64_REL64MSB;
3167		  break;
3168		case R_IA64_DIR64LSB:
3169		  dyn_r_type = R_IA64_DIR64MSB;
3170		  break;
3171		case R_IA64_FPTR64LSB:
3172		  dyn_r_type = R_IA64_FPTR64MSB;
3173		  break;
3174		default:
3175		  BFD_ASSERT (false);
3176		  break;
3177		}
3178	    }
3179
3180	  elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
3181					ia64_info->rel_got_sec,
3182					dyn_i->got_offset, dyn_r_type,
3183					dynindx, addend);
3184	}
3185    }
3186
3187  /* Return the address of the linkage table entry.  */
3188  value = (got_sec->output_section->vma
3189	   + got_sec->output_offset
3190	   + dyn_i->got_offset);
3191
3192  return value;
3193}
3194
3195/* Fill in a function descriptor consisting of the function's code
3196   address and its global pointer.  Return the descriptor's address.  */
3197
3198static bfd_vma
3199set_fptr_entry (abfd, info, dyn_i, value)
3200     bfd *abfd;
3201     struct bfd_link_info *info;
3202     struct elfNN_ia64_dyn_sym_info *dyn_i;
3203     bfd_vma value;
3204{
3205  struct elfNN_ia64_link_hash_table *ia64_info;
3206  asection *fptr_sec;
3207
3208  ia64_info = elfNN_ia64_hash_table (info);
3209  fptr_sec = ia64_info->fptr_sec;
3210
3211  if (!dyn_i->fptr_done)
3212    {
3213      dyn_i->fptr_done = 1;
3214
3215      /* Fill in the function descriptor.  */
3216      bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
3217      bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
3218		  fptr_sec->contents + dyn_i->fptr_offset + 8);
3219    }
3220
3221  /* Return the descriptor's address.  */
3222  value = (fptr_sec->output_section->vma
3223	   + fptr_sec->output_offset
3224	   + dyn_i->fptr_offset);
3225
3226  return value;
3227}
3228
3229/* Fill in a PLTOFF entry consisting of the function's code address
3230   and its global pointer.  Return the descriptor's address.  */
3231
3232static bfd_vma
3233set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
3234     bfd *abfd;
3235     struct bfd_link_info *info;
3236     struct elfNN_ia64_dyn_sym_info *dyn_i;
3237     bfd_vma value;
3238     boolean is_plt;
3239{
3240  struct elfNN_ia64_link_hash_table *ia64_info;
3241  asection *pltoff_sec;
3242
3243  ia64_info = elfNN_ia64_hash_table (info);
3244  pltoff_sec = ia64_info->pltoff_sec;
3245
3246  /* Don't do anything if this symbol uses a real PLT entry.  In
3247     that case, we'll fill this in during finish_dynamic_symbol.  */
3248  if ((! dyn_i->want_plt || is_plt)
3249      && !dyn_i->pltoff_done)
3250    {
3251      bfd_vma gp = _bfd_get_gp_value (abfd);
3252
3253      /* Fill in the function descriptor.  */
3254      bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
3255      bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
3256
3257      /* Install dynamic relocations if needed.  */
3258      if (!is_plt && info->shared)
3259	{
3260	  unsigned int dyn_r_type;
3261
3262	  if (bfd_big_endian (abfd))
3263	    dyn_r_type = R_IA64_REL64MSB;
3264	  else
3265	    dyn_r_type = R_IA64_REL64LSB;
3266
3267	  elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3268					ia64_info->rel_pltoff_sec,
3269					dyn_i->pltoff_offset,
3270					dyn_r_type, 0, value);
3271	  elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3272					ia64_info->rel_pltoff_sec,
3273					dyn_i->pltoff_offset + 8,
3274					dyn_r_type, 0, gp);
3275	}
3276
3277      dyn_i->pltoff_done = 1;
3278    }
3279
3280  /* Return the descriptor's address.  */
3281  value = (pltoff_sec->output_section->vma
3282	   + pltoff_sec->output_offset
3283	   + dyn_i->pltoff_offset);
3284
3285  return value;
3286}
3287
3288/* Called through qsort to sort the .IA_64.unwind section during a
3289   non-relocatable link.  Set elfNN_ia64_unwind_entry_compare_bfd
3290   to the output bfd so we can do proper endianness frobbing.  */
3291
3292static bfd *elfNN_ia64_unwind_entry_compare_bfd;
3293
3294static int
3295elfNN_ia64_unwind_entry_compare (a, b)
3296     const PTR a;
3297     const PTR b;
3298{
3299  bfd_vma av, bv;
3300
3301  av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
3302  bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
3303
3304  return (av < bv ? -1 : av > bv ? 1 : 0);
3305}
3306
3307static boolean
3308elfNN_ia64_final_link (abfd, info)
3309     bfd *abfd;
3310     struct bfd_link_info *info;
3311{
3312  struct elfNN_ia64_link_hash_table *ia64_info;
3313  asection *unwind_output_sec;
3314
3315  ia64_info = elfNN_ia64_hash_table (info);
3316
3317  /* Make sure we've got ourselves a nice fat __gp value.  */
3318  if (!info->relocateable)
3319    {
3320      bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
3321      bfd_vma min_short_vma = min_vma, max_short_vma = 0;
3322      struct elf_link_hash_entry *gp;
3323      bfd_vma gp_val;
3324      asection *os;
3325
3326      /* Find the min and max vma of all sections marked short.  Also
3327	 collect min and max vma of any type, for use in selecting a
3328	 nice gp.  */
3329      for (os = abfd->sections; os ; os = os->next)
3330	{
3331	  bfd_vma lo, hi;
3332
3333	  if ((os->flags & SEC_ALLOC) == 0)
3334	    continue;
3335
3336	  lo = os->vma;
3337	  hi = os->vma + os->_raw_size;
3338	  if (hi < lo)
3339	    hi = (bfd_vma) -1;
3340
3341	  if (min_vma > lo)
3342	    min_vma = lo;
3343	  if (max_vma < hi)
3344	    max_vma = hi;
3345	  if (os->flags & SEC_SMALL_DATA)
3346	    {
3347	      if (min_short_vma > lo)
3348		min_short_vma = lo;
3349	      if (max_short_vma < hi)
3350		max_short_vma = hi;
3351	    }
3352	}
3353
3354      /* See if the user wants to force a value.  */
3355      gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", false,
3356				 false, false);
3357
3358      if (gp
3359	  && (gp->root.type == bfd_link_hash_defined
3360	      || gp->root.type == bfd_link_hash_defweak))
3361	{
3362	  asection *gp_sec = gp->root.u.def.section;
3363	  gp_val = (gp->root.u.def.value
3364		    + gp_sec->output_section->vma
3365		    + gp_sec->output_offset);
3366	}
3367      else
3368	{
3369	  /* Pick a sensible value.  */
3370
3371	  asection *got_sec = ia64_info->got_sec;
3372
3373	  /* Start with just the address of the .got.  */
3374	  if (got_sec)
3375	    gp_val = got_sec->output_section->vma;
3376	  else if (max_short_vma != 0)
3377	    gp_val = min_short_vma;
3378	  else
3379	    gp_val = min_vma;
3380
3381	  /* If it is possible to address the entire image, but we
3382	     don't with the choice above, adjust.  */
3383	  if (max_vma - min_vma < 0x400000
3384	      && max_vma - gp_val <= 0x200000
3385	      && gp_val - min_vma > 0x200000)
3386	    gp_val = min_vma + 0x200000;
3387	  else if (max_short_vma != 0)
3388	    {
3389	      /* If we don't cover all the short data, adjust.  */
3390	      if (max_short_vma - gp_val >= 0x200000)
3391		gp_val = min_short_vma + 0x200000;
3392
3393	      /* If we're addressing stuff past the end, adjust back.  */
3394	      if (gp_val > max_vma)
3395		gp_val = max_vma - 0x200000 + 8;
3396	    }
3397	}
3398
3399      /* Validate whether all SHF_IA_64_SHORT sections are within
3400	 range of the chosen GP.  */
3401
3402      if (max_short_vma != 0)
3403	{
3404	  if (max_short_vma - min_short_vma >= 0x400000)
3405	    {
3406	      (*_bfd_error_handler)
3407		(_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3408		 bfd_get_filename (abfd),
3409		 (unsigned long) (max_short_vma - min_short_vma));
3410	      return false;
3411	    }
3412	  else if ((gp_val > min_short_vma
3413		    && gp_val - min_short_vma > 0x200000)
3414		   || (gp_val < max_short_vma
3415		       && max_short_vma - gp_val >= 0x200000))
3416	    {
3417	      (*_bfd_error_handler)
3418		(_("%s: __gp does not cover short data segment"),
3419		 bfd_get_filename (abfd));
3420	      return false;
3421	    }
3422	}
3423
3424      _bfd_set_gp_value (abfd, gp_val);
3425
3426      if (gp)
3427	{
3428	  gp->root.type = bfd_link_hash_defined;
3429	  gp->root.u.def.value = gp_val;
3430	  gp->root.u.def.section = bfd_abs_section_ptr;
3431	}
3432    }
3433
3434  /* If we're producing a final executable, we need to sort the contents
3435     of the .IA_64.unwind section.  Force this section to be relocated
3436     into memory rather than written immediately to the output file.  */
3437  unwind_output_sec = NULL;
3438  if (!info->relocateable)
3439    {
3440      asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3441      if (s)
3442	{
3443	  unwind_output_sec = s->output_section;
3444	  unwind_output_sec->contents
3445	    = bfd_malloc (unwind_output_sec->_raw_size);
3446	  if (unwind_output_sec->contents == NULL)
3447	    return false;
3448	}
3449    }
3450
3451  /* Invoke the regular ELF backend linker to do all the work.  */
3452  if (!bfd_elfNN_bfd_final_link (abfd, info))
3453    return false;
3454
3455  if (unwind_output_sec)
3456    {
3457      elfNN_ia64_unwind_entry_compare_bfd = abfd;
3458      qsort (unwind_output_sec->contents,
3459	     (size_t) (unwind_output_sec->_raw_size / 24),
3460	     24,
3461	     elfNN_ia64_unwind_entry_compare);
3462
3463      if (! bfd_set_section_contents (abfd, unwind_output_sec,
3464				      unwind_output_sec->contents, (bfd_vma) 0,
3465				      unwind_output_sec->_raw_size))
3466	return false;
3467    }
3468
3469  return true;
3470}
3471
3472static boolean
3473elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
3474			     contents, relocs, local_syms, local_sections)
3475     bfd *output_bfd;
3476     struct bfd_link_info *info;
3477     bfd *input_bfd;
3478     asection *input_section;
3479     bfd_byte *contents;
3480     Elf_Internal_Rela *relocs;
3481     Elf_Internal_Sym *local_syms;
3482     asection **local_sections;
3483{
3484  struct elfNN_ia64_link_hash_table *ia64_info;
3485  Elf_Internal_Shdr *symtab_hdr;
3486  Elf_Internal_Rela *rel;
3487  Elf_Internal_Rela *relend;
3488  asection *srel;
3489  boolean ret_val = true;	/* for non-fatal errors */
3490  bfd_vma gp_val;
3491
3492  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3493  ia64_info = elfNN_ia64_hash_table (info);
3494
3495  /* Infect various flags from the input section to the output section.  */
3496  if (info->relocateable)
3497    {
3498      bfd_vma flags;
3499
3500      flags = elf_section_data(input_section)->this_hdr.sh_flags;
3501      flags &= SHF_IA_64_NORECOV;
3502
3503      elf_section_data(input_section->output_section)
3504	->this_hdr.sh_flags |= flags;
3505      return true;
3506    }
3507
3508  gp_val = _bfd_get_gp_value (output_bfd);
3509  srel = get_reloc_section (input_bfd, ia64_info, input_section, false);
3510
3511  rel = relocs;
3512  relend = relocs + input_section->reloc_count;
3513  for (; rel < relend; ++rel)
3514    {
3515      struct elf_link_hash_entry *h;
3516      struct elfNN_ia64_dyn_sym_info *dyn_i;
3517      bfd_reloc_status_type r;
3518      reloc_howto_type *howto;
3519      unsigned long r_symndx;
3520      Elf_Internal_Sym *sym;
3521      unsigned int r_type;
3522      bfd_vma value;
3523      asection *sym_sec;
3524      bfd_byte *hit_addr;
3525      boolean dynamic_symbol_p;
3526      boolean undef_weak_ref;
3527
3528      r_type = ELFNN_R_TYPE (rel->r_info);
3529      if (r_type > R_IA64_MAX_RELOC_CODE)
3530	{
3531	  (*_bfd_error_handler)
3532	    (_("%s: unknown relocation type %d"),
3533	     bfd_archive_filename (input_bfd), (int)r_type);
3534	  bfd_set_error (bfd_error_bad_value);
3535	  ret_val = false;
3536	  continue;
3537	}
3538
3539      howto = lookup_howto (r_type);
3540      r_symndx = ELFNN_R_SYM (rel->r_info);
3541      h = NULL;
3542      sym = NULL;
3543      sym_sec = NULL;
3544      undef_weak_ref = false;
3545
3546      if (r_symndx < symtab_hdr->sh_info)
3547	{
3548	  /* Reloc against local symbol.  */
3549	  sym = local_syms + r_symndx;
3550	  sym_sec = local_sections[r_symndx];
3551	  value = _bfd_elf_rela_local_sym (output_bfd, sym, sym_sec, rel);
3552	  if ((sym_sec->flags & SEC_MERGE)
3553	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION
3554	      && (elf_section_data (sym_sec)->sec_info_type
3555		  == ELF_INFO_TYPE_MERGE))
3556 	    {
3557	      struct elfNN_ia64_local_hash_entry *loc_h;
3558
3559	      loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, false);
3560	      if (loc_h && ! loc_h->sec_merge_done)
3561		{
3562		  struct elfNN_ia64_dyn_sym_info *dynent;
3563		  asection *msec;
3564
3565		  for (dynent = loc_h->info; dynent; dynent = dynent->next)
3566		    {
3567		      msec = sym_sec;
3568		      dynent->addend =
3569			_bfd_merged_section_offset (output_bfd, &msec,
3570						    elf_section_data (msec)->
3571						    sec_info,
3572						    sym->st_value
3573						    + dynent->addend,
3574						    (bfd_vma) 0);
3575		      dynent->addend -= sym->st_value;
3576		      dynent->addend += msec->output_section->vma
3577					+ msec->output_offset
3578					- sym_sec->output_section->vma
3579					- sym_sec->output_offset;
3580		    }
3581		  loc_h->sec_merge_done = 1;
3582		}
3583	    }
3584	}
3585      else
3586	{
3587	  long indx;
3588
3589	  /* Reloc against global symbol.  */
3590	  indx = r_symndx - symtab_hdr->sh_info;
3591	  h = elf_sym_hashes (input_bfd)[indx];
3592	  while (h->root.type == bfd_link_hash_indirect
3593		 || h->root.type == bfd_link_hash_warning)
3594	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
3595
3596	  value = 0;
3597	  if (h->root.type == bfd_link_hash_defined
3598	      || h->root.type == bfd_link_hash_defweak)
3599	    {
3600	      sym_sec = h->root.u.def.section;
3601
3602	      /* Detect the cases that sym_sec->output_section is
3603		 expected to be NULL -- all cases in which the symbol
3604		 is defined in another shared module.  This includes
3605		 PLT relocs for which we've created a PLT entry and
3606		 other relocs for which we're prepared to create
3607		 dynamic relocations.  */
3608	      /* ??? Just accept it NULL and continue.  */
3609
3610	      if (sym_sec->output_section != NULL)
3611		{
3612		  value = (h->root.u.def.value
3613			   + sym_sec->output_section->vma
3614			   + sym_sec->output_offset);
3615		}
3616	    }
3617	  else if (h->root.type == bfd_link_hash_undefweak)
3618	    undef_weak_ref = true;
3619	  else if (info->shared
3620		   && (!info->symbolic || info->allow_shlib_undefined)
3621		   && !info->no_undefined
3622		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
3623	    ;
3624	  else
3625	    {
3626	      if (! ((*info->callbacks->undefined_symbol)
3627		     (info, h->root.root.string, input_bfd,
3628		      input_section, rel->r_offset,
3629		      (!info->shared || info->no_undefined
3630		       || ELF_ST_VISIBILITY (h->other)))))
3631		return false;
3632	      ret_val = false;
3633	      continue;
3634	    }
3635	}
3636
3637      hit_addr = contents + rel->r_offset;
3638      value += rel->r_addend;
3639      dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info);
3640
3641      switch (r_type)
3642	{
3643	case R_IA64_NONE:
3644	case R_IA64_LDXMOV:
3645	  continue;
3646
3647	case R_IA64_IMM14:
3648	case R_IA64_IMM22:
3649	case R_IA64_IMM64:
3650	case R_IA64_DIR32MSB:
3651	case R_IA64_DIR32LSB:
3652	case R_IA64_DIR64MSB:
3653	case R_IA64_DIR64LSB:
3654	  /* Install a dynamic relocation for this reloc.  */
3655	  if ((dynamic_symbol_p || info->shared
3656	       || (elfNN_ia64_aix_vec (info->hash->creator)
3657		   /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
3658		   && (!h || strcmp (h->root.root.string,
3659				     "__GLOB_DATA_PTR") != 0)))
3660	      && r_symndx != 0
3661	      && (input_section->flags & SEC_ALLOC) != 0)
3662	    {
3663	      unsigned int dyn_r_type;
3664	      long dynindx;
3665	      bfd_vma addend;
3666
3667	      BFD_ASSERT (srel != NULL);
3668
3669	      /* If we don't need dynamic symbol lookup, find a
3670		 matching RELATIVE relocation.  */
3671	      dyn_r_type = r_type;
3672	      if (dynamic_symbol_p)
3673		{
3674		  dynindx = h->dynindx;
3675		  addend = rel->r_addend;
3676		  value = 0;
3677		}
3678	      else
3679		{
3680		  switch (r_type)
3681		    {
3682		    case R_IA64_DIR32MSB:
3683		      dyn_r_type = R_IA64_REL32MSB;
3684		      break;
3685		    case R_IA64_DIR32LSB:
3686		      dyn_r_type = R_IA64_REL32LSB;
3687		      break;
3688		    case R_IA64_DIR64MSB:
3689		      dyn_r_type = R_IA64_REL64MSB;
3690		      break;
3691		    case R_IA64_DIR64LSB:
3692		      dyn_r_type = R_IA64_REL64LSB;
3693		      break;
3694
3695		    default:
3696		      /* We can't represent this without a dynamic symbol.
3697			 Adjust the relocation to be against an output
3698			 section symbol, which are always present in the
3699			 dynamic symbol table.  */
3700		      /* ??? People shouldn't be doing non-pic code in
3701			 shared libraries.  Hork.  */
3702		      (*_bfd_error_handler)
3703			(_("%s: linking non-pic code in a shared library"),
3704			 bfd_archive_filename (input_bfd));
3705		      ret_val = false;
3706		      continue;
3707		    }
3708		  dynindx = 0;
3709		  addend = value;
3710		}
3711
3712	      if (elfNN_ia64_aix_vec (info->hash->creator))
3713		rel->r_addend = value;
3714	      elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3715					    srel, rel->r_offset, dyn_r_type,
3716					    dynindx, addend);
3717	    }
3718	  /* FALLTHRU */
3719
3720	case R_IA64_LTV32MSB:
3721	case R_IA64_LTV32LSB:
3722	case R_IA64_LTV64MSB:
3723	case R_IA64_LTV64LSB:
3724	  r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3725	  break;
3726
3727	case R_IA64_GPREL22:
3728	case R_IA64_GPREL64I:
3729	case R_IA64_GPREL32MSB:
3730	case R_IA64_GPREL32LSB:
3731	case R_IA64_GPREL64MSB:
3732	case R_IA64_GPREL64LSB:
3733	  if (dynamic_symbol_p)
3734	    {
3735	      (*_bfd_error_handler)
3736		(_("%s: @gprel relocation against dynamic symbol %s"),
3737		 bfd_archive_filename (input_bfd), h->root.root.string);
3738	      ret_val = false;
3739	      continue;
3740	    }
3741	  value -= gp_val;
3742	  r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3743	  break;
3744
3745	case R_IA64_LTOFF22:
3746	case R_IA64_LTOFF22X:
3747	case R_IA64_LTOFF64I:
3748          dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3749	  value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
3750				 rel->r_addend, value, R_IA64_DIR64LSB);
3751	  value -= gp_val;
3752	  r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3753	  break;
3754
3755	case R_IA64_PLTOFF22:
3756	case R_IA64_PLTOFF64I:
3757	case R_IA64_PLTOFF64MSB:
3758	case R_IA64_PLTOFF64LSB:
3759          dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3760	  value = set_pltoff_entry (output_bfd, info, dyn_i, value, false);
3761	  value -= gp_val;
3762	  r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3763	  break;
3764
3765	case R_IA64_FPTR64I:
3766	case R_IA64_FPTR32MSB:
3767	case R_IA64_FPTR32LSB:
3768	case R_IA64_FPTR64MSB:
3769	case R_IA64_FPTR64LSB:
3770          dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3771	  if (dyn_i->want_fptr)
3772	    {
3773	      if (!undef_weak_ref)
3774		value = set_fptr_entry (output_bfd, info, dyn_i, value);
3775	    }
3776	  else
3777	    {
3778	      long dynindx;
3779
3780	      /* Otherwise, we expect the dynamic linker to create
3781		 the entry.  */
3782
3783	      if (h)
3784		{
3785		  if (h->dynindx != -1)
3786		    dynindx = h->dynindx;
3787		  else
3788		    dynindx = (_bfd_elf_link_lookup_local_dynindx
3789			       (info, h->root.u.def.section->owner,
3790				global_sym_index (h)));
3791		}
3792	      else
3793		{
3794		  dynindx = (_bfd_elf_link_lookup_local_dynindx
3795			     (info, input_bfd, (long) r_symndx));
3796		}
3797
3798	      elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3799					    srel, rel->r_offset, r_type,
3800					    dynindx, rel->r_addend);
3801	      value = 0;
3802	    }
3803
3804	  r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3805	  break;
3806
3807	case R_IA64_LTOFF_FPTR22:
3808	case R_IA64_LTOFF_FPTR64I:
3809	case R_IA64_LTOFF_FPTR32MSB:
3810	case R_IA64_LTOFF_FPTR32LSB:
3811	case R_IA64_LTOFF_FPTR64MSB:
3812	case R_IA64_LTOFF_FPTR64LSB:
3813	  {
3814	    long dynindx;
3815
3816	    dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3817	    if (dyn_i->want_fptr)
3818	      {
3819		BFD_ASSERT (h == NULL || h->dynindx == -1)
3820	        if (!undef_weak_ref)
3821	          value = set_fptr_entry (output_bfd, info, dyn_i, value);
3822		dynindx = -1;
3823	      }
3824	    else
3825	      {
3826	        /* Otherwise, we expect the dynamic linker to create
3827		   the entry.  */
3828	        if (h)
3829		  {
3830		    if (h->dynindx != -1)
3831		      dynindx = h->dynindx;
3832		    else
3833		      dynindx = (_bfd_elf_link_lookup_local_dynindx
3834				 (info, h->root.u.def.section->owner,
3835				  global_sym_index (h)));
3836		  }
3837		else
3838		  dynindx = (_bfd_elf_link_lookup_local_dynindx
3839			     (info, input_bfd, (long) r_symndx));
3840		value = 0;
3841	      }
3842
3843	    value = set_got_entry (output_bfd, info, dyn_i, dynindx,
3844				   rel->r_addend, value, R_IA64_FPTR64LSB);
3845	    value -= gp_val;
3846	    r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3847	  }
3848	  break;
3849
3850	case R_IA64_PCREL32MSB:
3851	case R_IA64_PCREL32LSB:
3852	case R_IA64_PCREL64MSB:
3853	case R_IA64_PCREL64LSB:
3854	  /* Install a dynamic relocation for this reloc.  */
3855	  if ((dynamic_symbol_p
3856	       || elfNN_ia64_aix_vec (info->hash->creator))
3857	      && r_symndx != 0)
3858	    {
3859	      BFD_ASSERT (srel != NULL);
3860
3861	      elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3862					    srel, rel->r_offset, r_type,
3863					    h->dynindx, rel->r_addend);
3864	    }
3865	  goto finish_pcrel;
3866
3867	case R_IA64_PCREL21BI:
3868	case R_IA64_PCREL21F:
3869	case R_IA64_PCREL21M:
3870	  /* ??? These two are only used for speculation fixup code.
3871	     They should never be dynamic.  */
3872	  if (dynamic_symbol_p)
3873	    {
3874	      (*_bfd_error_handler)
3875		(_("%s: dynamic relocation against speculation fixup"),
3876		 bfd_archive_filename (input_bfd));
3877	      ret_val = false;
3878	      continue;
3879	    }
3880	  if (undef_weak_ref)
3881	    {
3882	      (*_bfd_error_handler)
3883		(_("%s: speculation fixup against undefined weak symbol"),
3884		 bfd_archive_filename (input_bfd));
3885	      ret_val = false;
3886	      continue;
3887	    }
3888	  goto finish_pcrel;
3889
3890	case R_IA64_PCREL21B:
3891	case R_IA64_PCREL60B:
3892	  /* We should have created a PLT entry for any dynamic symbol.  */
3893	  dyn_i = NULL;
3894	  if (h)
3895	    dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
3896
3897	  if (dyn_i && dyn_i->want_plt2)
3898	    {
3899	      /* Should have caught this earlier.  */
3900	      BFD_ASSERT (rel->r_addend == 0);
3901
3902	      value = (ia64_info->plt_sec->output_section->vma
3903		       + ia64_info->plt_sec->output_offset
3904		       + dyn_i->plt2_offset);
3905	    }
3906	  else
3907	    {
3908	      /* Since there's no PLT entry, Validate that this is
3909		 locally defined.  */
3910	      BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
3911
3912	      /* If the symbol is undef_weak, we shouldn't be trying
3913		 to call it.  There's every chance that we'd wind up
3914		 with an out-of-range fixup here.  Don't bother setting
3915		 any value at all.  */
3916	      if (undef_weak_ref)
3917		continue;
3918	    }
3919	  goto finish_pcrel;
3920
3921	case R_IA64_PCREL22:
3922	case R_IA64_PCREL64I:
3923	finish_pcrel:
3924	  /* Make pc-relative.  */
3925	  value -= (input_section->output_section->vma
3926		    + input_section->output_offset
3927		    + rel->r_offset) & ~ (bfd_vma) 0x3;
3928	  r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3929	  break;
3930
3931	case R_IA64_SEGREL32MSB:
3932	case R_IA64_SEGREL32LSB:
3933	case R_IA64_SEGREL64MSB:
3934	case R_IA64_SEGREL64LSB:
3935	  if (r_symndx == 0)
3936	    {
3937	      /* If the input section was discarded from the output, then
3938		 do nothing.  */
3939	      r = bfd_reloc_ok;
3940	    }
3941	  else
3942	    {
3943	      struct elf_segment_map *m;
3944	      Elf_Internal_Phdr *p;
3945
3946	      /* Find the segment that contains the output_section.  */
3947	      for (m = elf_tdata (output_bfd)->segment_map,
3948		     p = elf_tdata (output_bfd)->phdr;
3949		   m != NULL;
3950		   m = m->next, p++)
3951		{
3952		  int i;
3953		  for (i = m->count - 1; i >= 0; i--)
3954		    if (m->sections[i] == sym_sec->output_section)
3955		      break;
3956		  if (i >= 0)
3957		    break;
3958		}
3959
3960	      if (m == NULL)
3961		{
3962		  r = bfd_reloc_notsupported;
3963		}
3964	      else
3965		{
3966		  /* The VMA of the segment is the vaddr of the associated
3967		     program header.  */
3968		  if (value > p->p_vaddr)
3969		    value -= p->p_vaddr;
3970		  else
3971		    value = 0;
3972		  r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
3973						r_type);
3974		}
3975	      break;
3976	    }
3977
3978	case R_IA64_SECREL32MSB:
3979	case R_IA64_SECREL32LSB:
3980	case R_IA64_SECREL64MSB:
3981	case R_IA64_SECREL64LSB:
3982	  /* Make output-section relative.  */
3983	  if (value > input_section->output_section->vma)
3984	    value -= input_section->output_section->vma;
3985	  else
3986	    value = 0;
3987	  r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3988	  break;
3989
3990	case R_IA64_IPLTMSB:
3991	case R_IA64_IPLTLSB:
3992	  /* Install a dynamic relocation for this reloc.  */
3993	  if ((dynamic_symbol_p || info->shared)
3994	      && (input_section->flags & SEC_ALLOC) != 0)
3995	    {
3996	      BFD_ASSERT (srel != NULL);
3997
3998	      /* If we don't need dynamic symbol lookup, install two
3999		 RELATIVE relocations.  */
4000	      if (! dynamic_symbol_p)
4001		{
4002		  unsigned int dyn_r_type;
4003
4004		  if (r_type == R_IA64_IPLTMSB)
4005		    dyn_r_type = R_IA64_REL64MSB;
4006		  else
4007		    dyn_r_type = R_IA64_REL64LSB;
4008
4009		  elfNN_ia64_install_dyn_reloc (output_bfd, info,
4010						input_section,
4011						srel, rel->r_offset,
4012						dyn_r_type, 0, value);
4013		  elfNN_ia64_install_dyn_reloc (output_bfd, info,
4014						input_section,
4015						srel, rel->r_offset + 8,
4016						dyn_r_type, 0, gp_val);
4017		}
4018	      else
4019		elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4020					      srel, rel->r_offset, r_type,
4021					      h->dynindx, rel->r_addend);
4022	    }
4023
4024	  if (r_type == R_IA64_IPLTMSB)
4025	    r_type = R_IA64_DIR64MSB;
4026	  else
4027	    r_type = R_IA64_DIR64LSB;
4028	  elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4029	  r = elfNN_ia64_install_value (output_bfd, hit_addr + 8, gp_val,
4030					r_type);
4031	  break;
4032
4033	default:
4034	  r = bfd_reloc_notsupported;
4035	  break;
4036	}
4037
4038      switch (r)
4039	{
4040	case bfd_reloc_ok:
4041	  break;
4042
4043	case bfd_reloc_undefined:
4044	  /* This can happen for global table relative relocs if
4045	     __gp is undefined.  This is a panic situation so we
4046	     don't try to continue.  */
4047	  (*info->callbacks->undefined_symbol)
4048	    (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
4049	  return false;
4050
4051	case bfd_reloc_notsupported:
4052	  {
4053	    const char *name;
4054
4055	    if (h)
4056	      name = h->root.root.string;
4057	    else
4058	      {
4059		name = bfd_elf_string_from_elf_section (input_bfd,
4060							symtab_hdr->sh_link,
4061							sym->st_name);
4062		if (name == NULL)
4063		  return false;
4064		if (*name == '\0')
4065		  name = bfd_section_name (input_bfd, input_section);
4066	      }
4067	    if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
4068					      name, input_bfd,
4069					      input_section, rel->r_offset))
4070	      return false;
4071	    ret_val = false;
4072	  }
4073	  break;
4074
4075	case bfd_reloc_dangerous:
4076	case bfd_reloc_outofrange:
4077	case bfd_reloc_overflow:
4078	default:
4079	  {
4080	    const char *name;
4081
4082	    if (h)
4083	      name = h->root.root.string;
4084	    else
4085	      {
4086		name = bfd_elf_string_from_elf_section (input_bfd,
4087							symtab_hdr->sh_link,
4088							sym->st_name);
4089		if (name == NULL)
4090		  return false;
4091		if (*name == '\0')
4092		  name = bfd_section_name (input_bfd, input_section);
4093	      }
4094	    if (!(*info->callbacks->reloc_overflow) (info, name,
4095						     howto->name,
4096						     (bfd_vma) 0,
4097						     input_bfd,
4098						     input_section,
4099						     rel->r_offset))
4100	      return false;
4101	    ret_val = false;
4102	  }
4103	  break;
4104	}
4105    }
4106
4107  return ret_val;
4108}
4109
4110static boolean
4111elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
4112     bfd *output_bfd;
4113     struct bfd_link_info *info;
4114     struct elf_link_hash_entry *h;
4115     Elf_Internal_Sym *sym;
4116{
4117  struct elfNN_ia64_link_hash_table *ia64_info;
4118  struct elfNN_ia64_dyn_sym_info *dyn_i;
4119
4120  ia64_info = elfNN_ia64_hash_table (info);
4121  dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
4122
4123  /* Fill in the PLT data, if required.  */
4124  if (dyn_i && dyn_i->want_plt)
4125    {
4126      Elf_Internal_Rela outrel;
4127      bfd_byte *loc;
4128      asection *plt_sec;
4129      bfd_vma plt_addr, pltoff_addr, gp_val, index;
4130      ElfNN_External_Rela *rel;
4131
4132      gp_val = _bfd_get_gp_value (output_bfd);
4133
4134      /* Initialize the minimal PLT entry.  */
4135
4136      index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
4137      plt_sec = ia64_info->plt_sec;
4138      loc = plt_sec->contents + dyn_i->plt_offset;
4139
4140      memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
4141      elfNN_ia64_install_value (output_bfd, loc, index, R_IA64_IMM22);
4142      elfNN_ia64_install_value (output_bfd, loc+2, -dyn_i->plt_offset,
4143				R_IA64_PCREL21B);
4144
4145      plt_addr = (plt_sec->output_section->vma
4146		  + plt_sec->output_offset
4147		  + dyn_i->plt_offset);
4148      pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, true);
4149
4150      /* Initialize the FULL PLT entry, if needed.  */
4151      if (dyn_i->want_plt2)
4152	{
4153	  loc = plt_sec->contents + dyn_i->plt2_offset;
4154
4155	  memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
4156	  elfNN_ia64_install_value (output_bfd, loc, pltoff_addr - gp_val,
4157				    R_IA64_IMM22);
4158
4159	  /* Mark the symbol as undefined, rather than as defined in the
4160	     plt section.  Leave the value alone.  */
4161	  /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4162	     first place.  But perhaps elflink.h did some for us.  */
4163	  if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
4164	    sym->st_shndx = SHN_UNDEF;
4165	}
4166
4167      /* Create the dynamic relocation.  */
4168      outrel.r_offset = pltoff_addr;
4169      if (bfd_little_endian (output_bfd))
4170	outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
4171      else
4172	outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
4173      outrel.r_addend = 0;
4174
4175      /* This is fun.  In the .IA_64.pltoff section, we've got entries
4176	 that correspond both to real PLT entries, and those that
4177	 happened to resolve to local symbols but need to be created
4178	 to satisfy @pltoff relocations.  The .rela.IA_64.pltoff
4179	 relocations for the real PLT should come at the end of the
4180	 section, so that they can be indexed by plt entry at runtime.
4181
4182	 We emitted all of the relocations for the non-PLT @pltoff
4183	 entries during relocate_section.  So we can consider the
4184	 existing sec->reloc_count to be the base of the array of
4185	 PLT relocations.  */
4186
4187      rel = (ElfNN_External_Rela *)ia64_info->rel_pltoff_sec->contents;
4188      rel += ia64_info->rel_pltoff_sec->reloc_count;
4189
4190      bfd_elfNN_swap_reloca_out (output_bfd, &outrel, rel + index);
4191    }
4192
4193  /* Mark some specially defined symbols as absolute.  */
4194  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4195      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
4196      || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4197    sym->st_shndx = SHN_ABS;
4198
4199  return true;
4200}
4201
4202static boolean
4203elfNN_ia64_finish_dynamic_sections (abfd, info)
4204     bfd *abfd;
4205     struct bfd_link_info *info;
4206{
4207  struct elfNN_ia64_link_hash_table *ia64_info;
4208  bfd *dynobj;
4209
4210  ia64_info = elfNN_ia64_hash_table (info);
4211  dynobj = ia64_info->root.dynobj;
4212
4213  if (elf_hash_table (info)->dynamic_sections_created)
4214    {
4215      ElfNN_External_Dyn *dyncon, *dynconend;
4216      asection *sdyn, *sgotplt;
4217      bfd_vma gp_val;
4218
4219      sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4220      sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
4221      BFD_ASSERT (sdyn != NULL);
4222      dyncon = (ElfNN_External_Dyn *) sdyn->contents;
4223      dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
4224
4225      gp_val = _bfd_get_gp_value (abfd);
4226
4227      for (; dyncon < dynconend; dyncon++)
4228	{
4229	  Elf_Internal_Dyn dyn;
4230
4231	  bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
4232
4233	  switch (dyn.d_tag)
4234	    {
4235	    case DT_PLTGOT:
4236	      dyn.d_un.d_ptr = gp_val;
4237	      break;
4238
4239	    case DT_PLTRELSZ:
4240	      dyn.d_un.d_val = (ia64_info->minplt_entries
4241				* sizeof (ElfNN_External_Rela));
4242	      break;
4243
4244	    case DT_JMPREL:
4245	      /* See the comment above in finish_dynamic_symbol.  */
4246	      dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
4247				+ ia64_info->rel_pltoff_sec->output_offset
4248				+ (ia64_info->rel_pltoff_sec->reloc_count
4249				   * sizeof (ElfNN_External_Rela)));
4250	      break;
4251
4252	    case DT_IA_64_PLT_RESERVE:
4253	      dyn.d_un.d_ptr = (sgotplt->output_section->vma
4254				+ sgotplt->output_offset);
4255	      break;
4256
4257	    case DT_RELASZ:
4258	      /* Do not have RELASZ include JMPREL.  This makes things
4259		 easier on ld.so.  This is not what the rest of BFD set up.  */
4260	      dyn.d_un.d_val -= (ia64_info->minplt_entries
4261				 * sizeof (ElfNN_External_Rela));
4262	      break;
4263	    }
4264
4265	  bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
4266	}
4267
4268      /* Initialize the PLT0 entry */
4269      if (ia64_info->plt_sec)
4270	{
4271	  bfd_byte *loc = ia64_info->plt_sec->contents;
4272	  bfd_vma pltres;
4273
4274	  memcpy (loc, plt_header, PLT_HEADER_SIZE);
4275
4276	  pltres = (sgotplt->output_section->vma
4277		    + sgotplt->output_offset
4278		    - gp_val);
4279
4280	  elfNN_ia64_install_value (abfd, loc+1, pltres, R_IA64_GPREL22);
4281	}
4282    }
4283
4284  return true;
4285}
4286
4287/* ELF file flag handling: */
4288
4289/* Function to keep IA-64 specific file flags.  */
4290static boolean
4291elfNN_ia64_set_private_flags (abfd, flags)
4292     bfd *abfd;
4293     flagword flags;
4294{
4295  BFD_ASSERT (!elf_flags_init (abfd)
4296	      || elf_elfheader (abfd)->e_flags == flags);
4297
4298  elf_elfheader (abfd)->e_flags = flags;
4299  elf_flags_init (abfd) = true;
4300  return true;
4301}
4302
4303/* Merge backend specific data from an object file to the output
4304   object file when linking.  */
4305static boolean
4306elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
4307     bfd *ibfd, *obfd;
4308{
4309  flagword out_flags;
4310  flagword in_flags;
4311  boolean ok = true;
4312
4313  /* Don't even pretend to support mixed-format linking.  */
4314  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4315      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4316    return false;
4317
4318  in_flags  = elf_elfheader (ibfd)->e_flags;
4319  out_flags = elf_elfheader (obfd)->e_flags;
4320
4321  if (! elf_flags_init (obfd))
4322    {
4323      elf_flags_init (obfd) = true;
4324      elf_elfheader (obfd)->e_flags = in_flags;
4325
4326      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4327	  && bfd_get_arch_info (obfd)->the_default)
4328	{
4329	  return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4330				    bfd_get_mach (ibfd));
4331	}
4332
4333      return true;
4334    }
4335
4336  /* Check flag compatibility.  */
4337  if (in_flags == out_flags)
4338    return true;
4339
4340  /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set.  */
4341  if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
4342    elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
4343
4344  if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
4345    {
4346      (*_bfd_error_handler)
4347	(_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4348	 bfd_archive_filename (ibfd));
4349
4350      bfd_set_error (bfd_error_bad_value);
4351      ok = false;
4352    }
4353  if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
4354    {
4355      (*_bfd_error_handler)
4356	(_("%s: linking big-endian files with little-endian files"),
4357	 bfd_archive_filename (ibfd));
4358
4359      bfd_set_error (bfd_error_bad_value);
4360      ok = false;
4361    }
4362  if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4363    {
4364      (*_bfd_error_handler)
4365	(_("%s: linking 64-bit files with 32-bit files"),
4366	 bfd_archive_filename (ibfd));
4367
4368      bfd_set_error (bfd_error_bad_value);
4369      ok = false;
4370    }
4371  if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4372    {
4373      (*_bfd_error_handler)
4374	(_("%s: linking constant-gp files with non-constant-gp files"),
4375	 bfd_archive_filename (ibfd));
4376
4377      bfd_set_error (bfd_error_bad_value);
4378      ok = false;
4379    }
4380  if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4381      != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4382    {
4383      (*_bfd_error_handler)
4384	(_("%s: linking auto-pic files with non-auto-pic files"),
4385	 bfd_archive_filename (ibfd));
4386
4387      bfd_set_error (bfd_error_bad_value);
4388      ok = false;
4389    }
4390
4391  return ok;
4392}
4393
4394static boolean
4395elfNN_ia64_print_private_bfd_data (abfd, ptr)
4396     bfd *abfd;
4397     PTR ptr;
4398{
4399  FILE *file = (FILE *) ptr;
4400  flagword flags = elf_elfheader (abfd)->e_flags;
4401
4402  BFD_ASSERT (abfd != NULL && ptr != NULL);
4403
4404  fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4405	   (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4406	   (flags & EF_IA_64_EXT) ? "EXT, " : "",
4407	   (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4408	   (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4409	   (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4410	   (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4411	   (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4412	   (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4413
4414  _bfd_elf_print_private_bfd_data (abfd, ptr);
4415  return true;
4416}
4417
4418static enum elf_reloc_type_class
4419elfNN_ia64_reloc_type_class (rela)
4420     const Elf_Internal_Rela *rela;
4421{
4422  switch ((int) ELFNN_R_TYPE (rela->r_info))
4423    {
4424    case R_IA64_REL32MSB:
4425    case R_IA64_REL32LSB:
4426    case R_IA64_REL64MSB:
4427    case R_IA64_REL64LSB:
4428      return reloc_class_relative;
4429    case R_IA64_IPLTMSB:
4430    case R_IA64_IPLTLSB:
4431      return reloc_class_plt;
4432    case R_IA64_COPY:
4433      return reloc_class_copy;
4434    default:
4435      return reloc_class_normal;
4436    }
4437}
4438
4439static boolean
4440elfNN_ia64_hpux_vec (const bfd_target *vec)
4441{
4442  extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
4443  return (vec == & bfd_elfNN_ia64_hpux_big_vec);
4444}
4445
4446static void
4447elfNN_hpux_post_process_headers (abfd, info)
4448	bfd *abfd;
4449	struct bfd_link_info *info ATTRIBUTE_UNUSED;
4450{
4451  Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
4452
4453  i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_HPUX;
4454  i_ehdrp->e_ident[EI_ABIVERSION] = 1;
4455}
4456
4457boolean
4458elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
4459	bfd *abfd ATTRIBUTE_UNUSED;
4460	asection *sec;
4461	int *retval;
4462{
4463  if (bfd_is_com_section (sec))
4464    {
4465      *retval = SHN_IA_64_ANSI_COMMON;
4466      return true;
4467    }
4468  return false;
4469}
4470
4471#define TARGET_LITTLE_SYM		bfd_elfNN_ia64_little_vec
4472#define TARGET_LITTLE_NAME		"elfNN-ia64-little"
4473#define TARGET_BIG_SYM			bfd_elfNN_ia64_big_vec
4474#define TARGET_BIG_NAME			"elfNN-ia64-big"
4475#define ELF_ARCH			bfd_arch_ia64
4476#define ELF_MACHINE_CODE		EM_IA_64
4477#define ELF_MACHINE_ALT1		1999	/* EAS2.3 */
4478#define ELF_MACHINE_ALT2		1998	/* EAS2.2 */
4479#define ELF_MAXPAGESIZE			0x10000	/* 64KB */
4480
4481#define elf_backend_section_from_shdr \
4482	elfNN_ia64_section_from_shdr
4483#define elf_backend_section_flags \
4484	elfNN_ia64_section_flags
4485#define elf_backend_fake_sections \
4486	elfNN_ia64_fake_sections
4487#define elf_backend_final_write_processing \
4488	elfNN_ia64_final_write_processing
4489#define elf_backend_add_symbol_hook \
4490	elfNN_ia64_add_symbol_hook
4491#define elf_backend_additional_program_headers \
4492	elfNN_ia64_additional_program_headers
4493#define elf_backend_modify_segment_map \
4494	elfNN_ia64_modify_segment_map
4495#define elf_info_to_howto \
4496	elfNN_ia64_info_to_howto
4497
4498#define bfd_elfNN_bfd_reloc_type_lookup \
4499	elfNN_ia64_reloc_type_lookup
4500#define bfd_elfNN_bfd_is_local_label_name \
4501	elfNN_ia64_is_local_label_name
4502#define bfd_elfNN_bfd_relax_section \
4503	elfNN_ia64_relax_section
4504
4505/* Stuff for the BFD linker: */
4506#define bfd_elfNN_bfd_link_hash_table_create \
4507	elfNN_ia64_hash_table_create
4508#define elf_backend_create_dynamic_sections \
4509	elfNN_ia64_create_dynamic_sections
4510#define elf_backend_check_relocs \
4511	elfNN_ia64_check_relocs
4512#define elf_backend_adjust_dynamic_symbol \
4513	elfNN_ia64_adjust_dynamic_symbol
4514#define elf_backend_size_dynamic_sections \
4515	elfNN_ia64_size_dynamic_sections
4516#define elf_backend_relocate_section \
4517	elfNN_ia64_relocate_section
4518#define elf_backend_finish_dynamic_symbol \
4519	elfNN_ia64_finish_dynamic_symbol
4520#define elf_backend_finish_dynamic_sections \
4521	elfNN_ia64_finish_dynamic_sections
4522#define bfd_elfNN_bfd_final_link \
4523	elfNN_ia64_final_link
4524
4525#define bfd_elfNN_bfd_merge_private_bfd_data \
4526	elfNN_ia64_merge_private_bfd_data
4527#define bfd_elfNN_bfd_set_private_flags \
4528	elfNN_ia64_set_private_flags
4529#define bfd_elfNN_bfd_print_private_bfd_data \
4530	elfNN_ia64_print_private_bfd_data
4531
4532#define elf_backend_plt_readonly	1
4533#define elf_backend_want_plt_sym	0
4534#define elf_backend_plt_alignment	5
4535#define elf_backend_got_header_size	0
4536#define elf_backend_plt_header_size	PLT_HEADER_SIZE
4537#define elf_backend_want_got_plt	1
4538#define elf_backend_may_use_rel_p	1
4539#define elf_backend_may_use_rela_p	1
4540#define elf_backend_default_use_rela_p	1
4541#define elf_backend_want_dynbss		0
4542#define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4543#define elf_backend_hide_symbol		elfNN_ia64_hash_hide_symbol
4544#define elf_backend_reloc_type_class	elfNN_ia64_reloc_type_class
4545#define elf_backend_rela_normal		1
4546
4547#include "elfNN-target.h"
4548
4549/* AIX-specific vectors.  */
4550
4551#undef  TARGET_LITTLE_SYM
4552#define TARGET_LITTLE_SYM		bfd_elfNN_ia64_aix_little_vec
4553#undef  TARGET_LITTLE_NAME
4554#define TARGET_LITTLE_NAME		"elfNN-ia64-aix-little"
4555#undef  TARGET_BIG_SYM
4556#define TARGET_BIG_SYM			bfd_elfNN_ia64_aix_big_vec
4557#undef  TARGET_BIG_NAME
4558#define TARGET_BIG_NAME			"elfNN-ia64-aix-big"
4559
4560#undef  elf_backend_add_symbol_hook
4561#define elf_backend_add_symbol_hook 	elfNN_ia64_aix_add_symbol_hook
4562
4563#undef  bfd_elfNN_bfd_link_add_symbols
4564#define bfd_elfNN_bfd_link_add_symbols 	elfNN_ia64_aix_link_add_symbols
4565
4566#define elfNN_bed elfNN_ia64_aix_bed
4567
4568#include "elfNN-target.h"
4569
4570/* HPUX-specific vectors.  */
4571
4572#undef  TARGET_LITTLE_SYM
4573#undef  TARGET_LITTLE_NAME
4574#undef  TARGET_BIG_SYM
4575#define TARGET_BIG_SYM                  bfd_elfNN_ia64_hpux_big_vec
4576#undef  TARGET_BIG_NAME
4577#define TARGET_BIG_NAME                 "elfNN-ia64-hpux-big"
4578
4579/* We need to undo the AIX specific functions.  */
4580
4581#undef  elf_backend_add_symbol_hook
4582#define elf_backend_add_symbol_hook	elfNN_ia64_add_symbol_hook
4583
4584#undef  bfd_elfNN_bfd_link_add_symbols
4585#define bfd_elfNN_bfd_link_add_symbols	_bfd_generic_link_add_symbols
4586
4587/* These are HP-UX specific functions.  */
4588
4589#undef  elf_backend_post_process_headers
4590#define elf_backend_post_process_headers elfNN_hpux_post_process_headers
4591
4592#undef  elf_backend_section_from_bfd_section
4593#define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
4594
4595#undef  ELF_MAXPAGESIZE
4596#define ELF_MAXPAGESIZE                 0x1000  /* 1K */
4597
4598#undef  elfNN_bed
4599#define elfNN_bed elfNN_ia64_hpux_bed
4600
4601#include "elfNN-target.h"
4602