1/* IA-64 support for 64-bit ELF
2   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
3   Free Software Foundation, Inc.
4   Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5
6   This file is part of BFD, the Binary File Descriptor library.
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
21
22#include "bfd.h"
23#include "sysdep.h"
24#include "libbfd.h"
25#include "elf-bfd.h"
26#include "opcode/ia64.h"
27#include "elf/ia64.h"
28#include "objalloc.h"
29#include "hashtab.h"
30
31#define ARCH_SIZE	NN
32
33#if ARCH_SIZE == 64
34#define	LOG_SECTION_ALIGN	3
35#endif
36
37#if ARCH_SIZE == 32
38#define	LOG_SECTION_ALIGN	2
39#endif
40
41/* THE RULES for all the stuff the linker creates --
42
43  GOT		Entries created in response to LTOFF or LTOFF_FPTR
44 		relocations.  Dynamic relocs created for dynamic
45 		symbols in an application; REL relocs for locals
46 		in a shared library.
47
48  FPTR		The canonical function descriptor.  Created for local
49 		symbols in applications.  Descriptors for dynamic symbols
50 		and local symbols in shared libraries are created by
51 		ld.so.  Thus there are no dynamic relocs against these
52 		objects.  The FPTR relocs for such _are_ passed through
53 		to the dynamic relocation tables.
54
55  FULL_PLT	Created for a PCREL21B relocation against a dynamic symbol.
56 		Requires the creation of a PLTOFF entry.  This does not
57 		require any dynamic relocations.
58
59  PLTOFF	Created by PLTOFF relocations.  For local symbols, this
60 		is an alternate function descriptor, and in shared libraries
61 		requires two REL relocations.  Note that this cannot be
62 		transformed into an FPTR relocation, since it must be in
63 		range of the GP.  For dynamic symbols, this is a function
64 		descriptor for a MIN_PLT entry, and requires one IPLT reloc.
65
66  MIN_PLT	Created by PLTOFF entries against dynamic symbols.  This
67 		does not require dynamic relocations.  */
68
69#define NELEMS(a)	((int) (sizeof (a) / sizeof ((a)[0])))
70
71typedef struct bfd_hash_entry *(*new_hash_entry_func)
72  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
73
74/* In dynamically (linker-) created sections, we generally need to keep track
75   of the place a symbol or expression got allocated to. This is done via hash
76   tables that store entries of the following type.  */
77
78struct elfNN_ia64_dyn_sym_info
79{
80  /* The addend for which this entry is relevant.  */
81  bfd_vma addend;
82
83  bfd_vma got_offset;
84  bfd_vma fptr_offset;
85  bfd_vma pltoff_offset;
86  bfd_vma plt_offset;
87  bfd_vma plt2_offset;
88  bfd_vma tprel_offset;
89  bfd_vma dtpmod_offset;
90  bfd_vma dtprel_offset;
91
92  /* The symbol table entry, if any, that this was derived from.  */
93  struct elf_link_hash_entry *h;
94
95  /* Used to count non-got, non-plt relocations for delayed sizing
96     of relocation sections.  */
97  struct elfNN_ia64_dyn_reloc_entry
98  {
99    struct elfNN_ia64_dyn_reloc_entry *next;
100    asection *srel;
101    int type;
102    int count;
103
104    /* Is this reloc against readonly section? */
105    bfd_boolean reltext;
106  } *reloc_entries;
107
108  /* TRUE when the section contents have been updated.  */
109  unsigned got_done : 1;
110  unsigned fptr_done : 1;
111  unsigned pltoff_done : 1;
112  unsigned tprel_done : 1;
113  unsigned dtpmod_done : 1;
114  unsigned dtprel_done : 1;
115
116  /* TRUE for the different kinds of linker data we want created.  */
117  unsigned want_got : 1;
118  unsigned want_gotx : 1;
119  unsigned want_fptr : 1;
120  unsigned want_ltoff_fptr : 1;
121  unsigned want_plt : 1;
122  unsigned want_plt2 : 1;
123  unsigned want_pltoff : 1;
124  unsigned want_tprel : 1;
125  unsigned want_dtpmod : 1;
126  unsigned want_dtprel : 1;
127};
128
129struct elfNN_ia64_local_hash_entry
130{
131  int id;
132  unsigned int r_sym;
133  /* The number of elements in elfNN_ia64_dyn_sym_info array.  */
134  unsigned int count;
135  /* The number of sorted elements in elfNN_ia64_dyn_sym_info array.  */
136  unsigned int sorted_count;
137  /* The size of elfNN_ia64_dyn_sym_info array.  */
138  unsigned int size;
139  /* The array of elfNN_ia64_dyn_sym_info.  */
140  struct elfNN_ia64_dyn_sym_info *info;
141
142  /* TRUE if this hash entry's addends was translated for
143     SHF_MERGE optimization.  */
144  unsigned sec_merge_done : 1;
145};
146
147struct elfNN_ia64_link_hash_entry
148{
149  struct elf_link_hash_entry root;
150  /* The number of elements in elfNN_ia64_dyn_sym_info array.  */
151  unsigned int count;
152  /* The number of sorted elements in elfNN_ia64_dyn_sym_info array.  */
153  unsigned int sorted_count;
154  /* The size of elfNN_ia64_dyn_sym_info array.  */
155  unsigned int size;
156  /* The array of elfNN_ia64_dyn_sym_info.  */
157  struct elfNN_ia64_dyn_sym_info *info;
158};
159
160struct elfNN_ia64_link_hash_table
161{
162  /* The main hash table.  */
163  struct elf_link_hash_table root;
164
165  asection *got_sec;		/* the linkage table section (or NULL) */
166  asection *rel_got_sec;	/* dynamic relocation section for same */
167  asection *fptr_sec;		/* function descriptor table (or NULL) */
168  asection *rel_fptr_sec;	/* dynamic relocation section for same */
169  asection *plt_sec;		/* the primary plt section (or NULL) */
170  asection *pltoff_sec;		/* private descriptors for plt (or NULL) */
171  asection *rel_pltoff_sec;	/* dynamic relocation section for same */
172
173  bfd_size_type minplt_entries;	/* number of minplt entries */
174  unsigned reltext : 1;		/* are there relocs against readonly sections? */
175  unsigned self_dtpmod_done : 1;/* has self DTPMOD entry been finished? */
176  bfd_vma self_dtpmod_offset;	/* .got offset to self DTPMOD entry */
177
178  htab_t loc_hash_table;
179  void *loc_hash_memory;
180};
181
182struct elfNN_ia64_allocate_data
183{
184  struct bfd_link_info *info;
185  bfd_size_type ofs;
186  bfd_boolean only_got;
187};
188
189#define elfNN_ia64_hash_table(p) \
190  ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
191
192static bfd_reloc_status_type elfNN_ia64_reloc
193  PARAMS ((bfd *abfd, arelent *reloc, asymbol *sym, PTR data,
194	   asection *input_section, bfd *output_bfd, char **error_message));
195static reloc_howto_type * lookup_howto
196  PARAMS ((unsigned int rtype));
197static reloc_howto_type *elfNN_ia64_reloc_type_lookup
198  PARAMS ((bfd *abfd, bfd_reloc_code_real_type bfd_code));
199static void elfNN_ia64_info_to_howto
200  PARAMS ((bfd *abfd, arelent *bfd_reloc, Elf_Internal_Rela *elf_reloc));
201static bfd_boolean elfNN_ia64_relax_section
202  PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
203	  bfd_boolean *again));
204static void elfNN_ia64_relax_ldxmov
205  PARAMS((bfd_byte *contents, bfd_vma off));
206static bfd_boolean is_unwind_section_name
207  PARAMS ((bfd *abfd, const char *));
208static bfd_boolean elfNN_ia64_section_flags
209  PARAMS ((flagword *, const Elf_Internal_Shdr *));
210static bfd_boolean elfNN_ia64_fake_sections
211  PARAMS ((bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec));
212static void elfNN_ia64_final_write_processing
213  PARAMS ((bfd *abfd, bfd_boolean linker));
214static bfd_boolean elfNN_ia64_add_symbol_hook
215  PARAMS ((bfd *abfd, struct bfd_link_info *info, Elf_Internal_Sym *sym,
216	   const char **namep, flagword *flagsp, asection **secp,
217	   bfd_vma *valp));
218static int elfNN_ia64_additional_program_headers
219  PARAMS ((bfd *abfd));
220static bfd_boolean elfNN_ia64_modify_segment_map
221  PARAMS ((bfd *, struct bfd_link_info *));
222static bfd_boolean elfNN_ia64_is_local_label_name
223  PARAMS ((bfd *abfd, const char *name));
224static bfd_boolean elfNN_ia64_dynamic_symbol_p
225  PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info, int));
226static struct bfd_hash_entry *elfNN_ia64_new_elf_hash_entry
227  PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
228	   const char *string));
229static void elfNN_ia64_hash_copy_indirect
230  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *,
231	   struct elf_link_hash_entry *));
232static void elfNN_ia64_hash_hide_symbol
233  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean));
234static hashval_t elfNN_ia64_local_htab_hash PARAMS ((const void *));
235static int elfNN_ia64_local_htab_eq PARAMS ((const void *ptr1,
236					     const void *ptr2));
237static struct bfd_link_hash_table *elfNN_ia64_hash_table_create
238  PARAMS ((bfd *abfd));
239static void elfNN_ia64_hash_table_free
240  PARAMS ((struct bfd_link_hash_table *hash));
241static bfd_boolean elfNN_ia64_global_dyn_sym_thunk
242  PARAMS ((struct bfd_hash_entry *, PTR));
243static int elfNN_ia64_local_dyn_sym_thunk
244  PARAMS ((void **, PTR));
245static void elfNN_ia64_dyn_sym_traverse
246  PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
247	   bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
248	   PTR info));
249static bfd_boolean elfNN_ia64_create_dynamic_sections
250  PARAMS ((bfd *abfd, struct bfd_link_info *info));
251static struct elfNN_ia64_local_hash_entry * get_local_sym_hash
252  PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
253	   bfd *abfd, const Elf_Internal_Rela *rel, bfd_boolean create));
254static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
255  PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
256	   struct elf_link_hash_entry *h,
257	   bfd *abfd, const Elf_Internal_Rela *rel, bfd_boolean create));
258static asection *get_got
259  PARAMS ((bfd *abfd, struct bfd_link_info *info,
260	   struct elfNN_ia64_link_hash_table *ia64_info));
261static asection *get_fptr
262  PARAMS ((bfd *abfd, struct bfd_link_info *info,
263	   struct elfNN_ia64_link_hash_table *ia64_info));
264static asection *get_pltoff
265  PARAMS ((bfd *abfd, struct bfd_link_info *info,
266	   struct elfNN_ia64_link_hash_table *ia64_info));
267static asection *get_reloc_section
268  PARAMS ((bfd *abfd, struct elfNN_ia64_link_hash_table *ia64_info,
269	   asection *sec, bfd_boolean create));
270static bfd_boolean elfNN_ia64_check_relocs
271  PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
272	   const Elf_Internal_Rela *relocs));
273static bfd_boolean elfNN_ia64_adjust_dynamic_symbol
274  PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
275static long global_sym_index
276  PARAMS ((struct elf_link_hash_entry *h));
277static bfd_boolean allocate_fptr
278  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
279static bfd_boolean allocate_global_data_got
280  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
281static bfd_boolean allocate_global_fptr_got
282  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
283static bfd_boolean allocate_local_got
284  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
285static bfd_boolean allocate_pltoff_entries
286  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
287static bfd_boolean allocate_plt_entries
288  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
289static bfd_boolean allocate_plt2_entries
290  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
291static bfd_boolean allocate_dynrel_entries
292  PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
293static bfd_boolean elfNN_ia64_size_dynamic_sections
294  PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
295static bfd_reloc_status_type elfNN_ia64_install_value
296  PARAMS ((bfd_byte *hit_addr, bfd_vma val, unsigned int r_type));
297static void elfNN_ia64_install_dyn_reloc
298  PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
299	   asection *srel, bfd_vma offset, unsigned int type,
300	   long dynindx, bfd_vma addend));
301static bfd_vma set_got_entry
302  PARAMS ((bfd *abfd, struct bfd_link_info *info,
303	   struct elfNN_ia64_dyn_sym_info *dyn_i, long dynindx,
304	   bfd_vma addend, bfd_vma value, unsigned int dyn_r_type));
305static bfd_vma set_fptr_entry
306  PARAMS ((bfd *abfd, struct bfd_link_info *info,
307	   struct elfNN_ia64_dyn_sym_info *dyn_i,
308	   bfd_vma value));
309static bfd_vma set_pltoff_entry
310  PARAMS ((bfd *abfd, struct bfd_link_info *info,
311	   struct elfNN_ia64_dyn_sym_info *dyn_i,
312	   bfd_vma value, bfd_boolean));
313static bfd_vma elfNN_ia64_tprel_base
314  PARAMS ((struct bfd_link_info *info));
315static bfd_vma elfNN_ia64_dtprel_base
316  PARAMS ((struct bfd_link_info *info));
317static int elfNN_ia64_unwind_entry_compare
318  PARAMS ((const PTR, const PTR));
319static bfd_boolean elfNN_ia64_choose_gp
320  PARAMS ((bfd *abfd, struct bfd_link_info *info));
321static bfd_boolean elfNN_ia64_final_link
322  PARAMS ((bfd *abfd, struct bfd_link_info *info));
323static bfd_boolean elfNN_ia64_relocate_section
324  PARAMS ((bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
325	   asection *input_section, bfd_byte *contents,
326	   Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms,
327	   asection **local_sections));
328static bfd_boolean elfNN_ia64_finish_dynamic_symbol
329  PARAMS ((bfd *output_bfd, struct bfd_link_info *info,
330	   struct elf_link_hash_entry *h, Elf_Internal_Sym *sym));
331static bfd_boolean elfNN_ia64_finish_dynamic_sections
332  PARAMS ((bfd *abfd, struct bfd_link_info *info));
333static bfd_boolean elfNN_ia64_set_private_flags
334  PARAMS ((bfd *abfd, flagword flags));
335static bfd_boolean elfNN_ia64_merge_private_bfd_data
336  PARAMS ((bfd *ibfd, bfd *obfd));
337static bfd_boolean elfNN_ia64_print_private_bfd_data
338  PARAMS ((bfd *abfd, PTR ptr));
339static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
340  PARAMS ((const Elf_Internal_Rela *));
341static bfd_boolean elfNN_ia64_hpux_vec
342  PARAMS ((const bfd_target *vec));
343static void elfNN_hpux_post_process_headers
344  PARAMS ((bfd *abfd, struct bfd_link_info *info));
345bfd_boolean elfNN_hpux_backend_section_from_bfd_section
346  PARAMS ((bfd *abfd, asection *sec, int *retval));
347
348/* ia64-specific relocation.  */
349
350/* Perform a relocation.  Not much to do here as all the hard work is
351   done in elfNN_ia64_final_link_relocate.  */
352static bfd_reloc_status_type
353elfNN_ia64_reloc (abfd, reloc, sym, data, input_section,
354		  output_bfd, error_message)
355     bfd *abfd ATTRIBUTE_UNUSED;
356     arelent *reloc;
357     asymbol *sym ATTRIBUTE_UNUSED;
358     PTR data ATTRIBUTE_UNUSED;
359     asection *input_section;
360     bfd *output_bfd;
361     char **error_message;
362{
363  if (output_bfd)
364    {
365      reloc->address += input_section->output_offset;
366      return bfd_reloc_ok;
367    }
368
369  if (input_section->flags & SEC_DEBUGGING)
370    return bfd_reloc_continue;
371
372  *error_message = "Unsupported call to elfNN_ia64_reloc";
373  return bfd_reloc_notsupported;
374}
375
376#define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN)			\
377  HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed,	\
378	 elfNN_ia64_reloc, NAME, FALSE, 0, -1, IN)
379
380/* This table has to be sorted according to increasing number of the
381   TYPE field.  */
382static reloc_howto_type ia64_howto_table[] =
383  {
384    IA64_HOWTO (R_IA64_NONE,	    "NONE",	   0, FALSE, TRUE),
385
386    IA64_HOWTO (R_IA64_IMM14,	    "IMM14",	   0, FALSE, TRUE),
387    IA64_HOWTO (R_IA64_IMM22,	    "IMM22",	   0, FALSE, TRUE),
388    IA64_HOWTO (R_IA64_IMM64,	    "IMM64",	   0, FALSE, TRUE),
389    IA64_HOWTO (R_IA64_DIR32MSB,    "DIR32MSB",	   2, FALSE, TRUE),
390    IA64_HOWTO (R_IA64_DIR32LSB,    "DIR32LSB",	   2, FALSE, TRUE),
391    IA64_HOWTO (R_IA64_DIR64MSB,    "DIR64MSB",	   4, FALSE, TRUE),
392    IA64_HOWTO (R_IA64_DIR64LSB,    "DIR64LSB",	   4, FALSE, TRUE),
393
394    IA64_HOWTO (R_IA64_GPREL22,	    "GPREL22",	   0, FALSE, TRUE),
395    IA64_HOWTO (R_IA64_GPREL64I,    "GPREL64I",	   0, FALSE, TRUE),
396    IA64_HOWTO (R_IA64_GPREL32MSB,  "GPREL32MSB",  2, FALSE, TRUE),
397    IA64_HOWTO (R_IA64_GPREL32LSB,  "GPREL32LSB",  2, FALSE, TRUE),
398    IA64_HOWTO (R_IA64_GPREL64MSB,  "GPREL64MSB",  4, FALSE, TRUE),
399    IA64_HOWTO (R_IA64_GPREL64LSB,  "GPREL64LSB",  4, FALSE, TRUE),
400
401    IA64_HOWTO (R_IA64_LTOFF22,	    "LTOFF22",	   0, FALSE, TRUE),
402    IA64_HOWTO (R_IA64_LTOFF64I,    "LTOFF64I",	   0, FALSE, TRUE),
403
404    IA64_HOWTO (R_IA64_PLTOFF22,    "PLTOFF22",	   0, FALSE, TRUE),
405    IA64_HOWTO (R_IA64_PLTOFF64I,   "PLTOFF64I",   0, FALSE, TRUE),
406    IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, FALSE, TRUE),
407    IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, FALSE, TRUE),
408
409    IA64_HOWTO (R_IA64_FPTR64I,	    "FPTR64I",	   0, FALSE, TRUE),
410    IA64_HOWTO (R_IA64_FPTR32MSB,   "FPTR32MSB",   2, FALSE, TRUE),
411    IA64_HOWTO (R_IA64_FPTR32LSB,   "FPTR32LSB",   2, FALSE, TRUE),
412    IA64_HOWTO (R_IA64_FPTR64MSB,   "FPTR64MSB",   4, FALSE, TRUE),
413    IA64_HOWTO (R_IA64_FPTR64LSB,   "FPTR64LSB",   4, FALSE, TRUE),
414
415    IA64_HOWTO (R_IA64_PCREL60B,    "PCREL60B",	   0, TRUE, TRUE),
416    IA64_HOWTO (R_IA64_PCREL21B,    "PCREL21B",	   0, TRUE, TRUE),
417    IA64_HOWTO (R_IA64_PCREL21M,    "PCREL21M",	   0, TRUE, TRUE),
418    IA64_HOWTO (R_IA64_PCREL21F,    "PCREL21F",	   0, TRUE, TRUE),
419    IA64_HOWTO (R_IA64_PCREL32MSB,  "PCREL32MSB",  2, TRUE, TRUE),
420    IA64_HOWTO (R_IA64_PCREL32LSB,  "PCREL32LSB",  2, TRUE, TRUE),
421    IA64_HOWTO (R_IA64_PCREL64MSB,  "PCREL64MSB",  4, TRUE, TRUE),
422    IA64_HOWTO (R_IA64_PCREL64LSB,  "PCREL64LSB",  4, TRUE, TRUE),
423
424    IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, FALSE, TRUE),
425    IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, FALSE, TRUE),
426    IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB, "LTOFF_FPTR32MSB", 2, FALSE, TRUE),
427    IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB, "LTOFF_FPTR32LSB", 2, FALSE, TRUE),
428    IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, FALSE, TRUE),
429    IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, FALSE, TRUE),
430
431    IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, FALSE, TRUE),
432    IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, FALSE, TRUE),
433    IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, FALSE, TRUE),
434    IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, FALSE, TRUE),
435
436    IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, FALSE, TRUE),
437    IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, FALSE, TRUE),
438    IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, FALSE, TRUE),
439    IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, FALSE, TRUE),
440
441    IA64_HOWTO (R_IA64_REL32MSB,    "REL32MSB",	   2, FALSE, TRUE),
442    IA64_HOWTO (R_IA64_REL32LSB,    "REL32LSB",	   2, FALSE, TRUE),
443    IA64_HOWTO (R_IA64_REL64MSB,    "REL64MSB",	   4, FALSE, TRUE),
444    IA64_HOWTO (R_IA64_REL64LSB,    "REL64LSB",	   4, FALSE, TRUE),
445
446    IA64_HOWTO (R_IA64_LTV32MSB,    "LTV32MSB",	   2, FALSE, TRUE),
447    IA64_HOWTO (R_IA64_LTV32LSB,    "LTV32LSB",	   2, FALSE, TRUE),
448    IA64_HOWTO (R_IA64_LTV64MSB,    "LTV64MSB",	   4, FALSE, TRUE),
449    IA64_HOWTO (R_IA64_LTV64LSB,    "LTV64LSB",	   4, FALSE, TRUE),
450
451    IA64_HOWTO (R_IA64_PCREL21BI,   "PCREL21BI",   0, TRUE, TRUE),
452    IA64_HOWTO (R_IA64_PCREL22,     "PCREL22",     0, TRUE, TRUE),
453    IA64_HOWTO (R_IA64_PCREL64I,    "PCREL64I",    0, TRUE, TRUE),
454
455    IA64_HOWTO (R_IA64_IPLTMSB,	    "IPLTMSB",	   4, FALSE, TRUE),
456    IA64_HOWTO (R_IA64_IPLTLSB,	    "IPLTLSB",	   4, FALSE, TRUE),
457    IA64_HOWTO (R_IA64_COPY,	    "COPY",	   4, FALSE, TRUE),
458    IA64_HOWTO (R_IA64_LTOFF22X,    "LTOFF22X",	   0, FALSE, TRUE),
459    IA64_HOWTO (R_IA64_LDXMOV,	    "LDXMOV",	   0, FALSE, TRUE),
460
461    IA64_HOWTO (R_IA64_TPREL14,	    "TPREL14",	   0, FALSE, FALSE),
462    IA64_HOWTO (R_IA64_TPREL22,	    "TPREL22",	   0, FALSE, FALSE),
463    IA64_HOWTO (R_IA64_TPREL64I,    "TPREL64I",	   0, FALSE, FALSE),
464    IA64_HOWTO (R_IA64_TPREL64MSB,  "TPREL64MSB",  4, FALSE, FALSE),
465    IA64_HOWTO (R_IA64_TPREL64LSB,  "TPREL64LSB",  4, FALSE, FALSE),
466    IA64_HOWTO (R_IA64_LTOFF_TPREL22, "LTOFF_TPREL22",  0, FALSE, FALSE),
467
468    IA64_HOWTO (R_IA64_DTPMOD64MSB, "DTPMOD64MSB",  4, FALSE, FALSE),
469    IA64_HOWTO (R_IA64_DTPMOD64LSB, "DTPMOD64LSB",  4, FALSE, FALSE),
470    IA64_HOWTO (R_IA64_LTOFF_DTPMOD22, "LTOFF_DTPMOD22", 0, FALSE, FALSE),
471
472    IA64_HOWTO (R_IA64_DTPREL14,    "DTPREL14",	   0, FALSE, FALSE),
473    IA64_HOWTO (R_IA64_DTPREL22,    "DTPREL22",	   0, FALSE, FALSE),
474    IA64_HOWTO (R_IA64_DTPREL64I,   "DTPREL64I",   0, FALSE, FALSE),
475    IA64_HOWTO (R_IA64_DTPREL32MSB, "DTPREL32MSB", 2, FALSE, FALSE),
476    IA64_HOWTO (R_IA64_DTPREL32LSB, "DTPREL32LSB", 2, FALSE, FALSE),
477    IA64_HOWTO (R_IA64_DTPREL64MSB, "DTPREL64MSB", 4, FALSE, FALSE),
478    IA64_HOWTO (R_IA64_DTPREL64LSB, "DTPREL64LSB", 4, FALSE, FALSE),
479    IA64_HOWTO (R_IA64_LTOFF_DTPREL22, "LTOFF_DTPREL22", 0, FALSE, FALSE),
480  };
481
482static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
483
484/* Given a BFD reloc type, return the matching HOWTO structure.  */
485
486static reloc_howto_type *
487lookup_howto (rtype)
488     unsigned int rtype;
489{
490  static int inited = 0;
491  int i;
492
493  if (!inited)
494    {
495      inited = 1;
496
497      memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
498      for (i = 0; i < NELEMS (ia64_howto_table); ++i)
499	elf_code_to_howto_index[ia64_howto_table[i].type] = i;
500    }
501
502  if (rtype > R_IA64_MAX_RELOC_CODE)
503    return 0;
504  i = elf_code_to_howto_index[rtype];
505  if (i >= NELEMS (ia64_howto_table))
506    return 0;
507  return ia64_howto_table + i;
508}
509
510static reloc_howto_type*
511elfNN_ia64_reloc_type_lookup (abfd, bfd_code)
512     bfd *abfd ATTRIBUTE_UNUSED;
513     bfd_reloc_code_real_type bfd_code;
514{
515  unsigned int rtype;
516
517  switch (bfd_code)
518    {
519    case BFD_RELOC_NONE:		rtype = R_IA64_NONE; break;
520
521    case BFD_RELOC_IA64_IMM14:		rtype = R_IA64_IMM14; break;
522    case BFD_RELOC_IA64_IMM22:		rtype = R_IA64_IMM22; break;
523    case BFD_RELOC_IA64_IMM64:		rtype = R_IA64_IMM64; break;
524
525    case BFD_RELOC_IA64_DIR32MSB:	rtype = R_IA64_DIR32MSB; break;
526    case BFD_RELOC_IA64_DIR32LSB:	rtype = R_IA64_DIR32LSB; break;
527    case BFD_RELOC_IA64_DIR64MSB:	rtype = R_IA64_DIR64MSB; break;
528    case BFD_RELOC_IA64_DIR64LSB:	rtype = R_IA64_DIR64LSB; break;
529
530    case BFD_RELOC_IA64_GPREL22:	rtype = R_IA64_GPREL22; break;
531    case BFD_RELOC_IA64_GPREL64I:	rtype = R_IA64_GPREL64I; break;
532    case BFD_RELOC_IA64_GPREL32MSB:	rtype = R_IA64_GPREL32MSB; break;
533    case BFD_RELOC_IA64_GPREL32LSB:	rtype = R_IA64_GPREL32LSB; break;
534    case BFD_RELOC_IA64_GPREL64MSB:	rtype = R_IA64_GPREL64MSB; break;
535    case BFD_RELOC_IA64_GPREL64LSB:	rtype = R_IA64_GPREL64LSB; break;
536
537    case BFD_RELOC_IA64_LTOFF22:	rtype = R_IA64_LTOFF22; break;
538    case BFD_RELOC_IA64_LTOFF64I:	rtype = R_IA64_LTOFF64I; break;
539
540    case BFD_RELOC_IA64_PLTOFF22:	rtype = R_IA64_PLTOFF22; break;
541    case BFD_RELOC_IA64_PLTOFF64I:	rtype = R_IA64_PLTOFF64I; break;
542    case BFD_RELOC_IA64_PLTOFF64MSB:	rtype = R_IA64_PLTOFF64MSB; break;
543    case BFD_RELOC_IA64_PLTOFF64LSB:	rtype = R_IA64_PLTOFF64LSB; break;
544    case BFD_RELOC_IA64_FPTR64I:	rtype = R_IA64_FPTR64I; break;
545    case BFD_RELOC_IA64_FPTR32MSB:	rtype = R_IA64_FPTR32MSB; break;
546    case BFD_RELOC_IA64_FPTR32LSB:	rtype = R_IA64_FPTR32LSB; break;
547    case BFD_RELOC_IA64_FPTR64MSB:	rtype = R_IA64_FPTR64MSB; break;
548    case BFD_RELOC_IA64_FPTR64LSB:	rtype = R_IA64_FPTR64LSB; break;
549
550    case BFD_RELOC_IA64_PCREL21B:	rtype = R_IA64_PCREL21B; break;
551    case BFD_RELOC_IA64_PCREL21BI:	rtype = R_IA64_PCREL21BI; break;
552    case BFD_RELOC_IA64_PCREL21M:	rtype = R_IA64_PCREL21M; break;
553    case BFD_RELOC_IA64_PCREL21F:	rtype = R_IA64_PCREL21F; break;
554    case BFD_RELOC_IA64_PCREL22:	rtype = R_IA64_PCREL22; break;
555    case BFD_RELOC_IA64_PCREL60B:	rtype = R_IA64_PCREL60B; break;
556    case BFD_RELOC_IA64_PCREL64I:	rtype = R_IA64_PCREL64I; break;
557    case BFD_RELOC_IA64_PCREL32MSB:	rtype = R_IA64_PCREL32MSB; break;
558    case BFD_RELOC_IA64_PCREL32LSB:	rtype = R_IA64_PCREL32LSB; break;
559    case BFD_RELOC_IA64_PCREL64MSB:	rtype = R_IA64_PCREL64MSB; break;
560    case BFD_RELOC_IA64_PCREL64LSB:	rtype = R_IA64_PCREL64LSB; break;
561
562    case BFD_RELOC_IA64_LTOFF_FPTR22:	rtype = R_IA64_LTOFF_FPTR22; break;
563    case BFD_RELOC_IA64_LTOFF_FPTR64I:	rtype = R_IA64_LTOFF_FPTR64I; break;
564    case BFD_RELOC_IA64_LTOFF_FPTR32MSB: rtype = R_IA64_LTOFF_FPTR32MSB; break;
565    case BFD_RELOC_IA64_LTOFF_FPTR32LSB: rtype = R_IA64_LTOFF_FPTR32LSB; break;
566    case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
567    case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
568
569    case BFD_RELOC_IA64_SEGREL32MSB:	rtype = R_IA64_SEGREL32MSB; break;
570    case BFD_RELOC_IA64_SEGREL32LSB:	rtype = R_IA64_SEGREL32LSB; break;
571    case BFD_RELOC_IA64_SEGREL64MSB:	rtype = R_IA64_SEGREL64MSB; break;
572    case BFD_RELOC_IA64_SEGREL64LSB:	rtype = R_IA64_SEGREL64LSB; break;
573
574    case BFD_RELOC_IA64_SECREL32MSB:	rtype = R_IA64_SECREL32MSB; break;
575    case BFD_RELOC_IA64_SECREL32LSB:	rtype = R_IA64_SECREL32LSB; break;
576    case BFD_RELOC_IA64_SECREL64MSB:	rtype = R_IA64_SECREL64MSB; break;
577    case BFD_RELOC_IA64_SECREL64LSB:	rtype = R_IA64_SECREL64LSB; break;
578
579    case BFD_RELOC_IA64_REL32MSB:	rtype = R_IA64_REL32MSB; break;
580    case BFD_RELOC_IA64_REL32LSB:	rtype = R_IA64_REL32LSB; break;
581    case BFD_RELOC_IA64_REL64MSB:	rtype = R_IA64_REL64MSB; break;
582    case BFD_RELOC_IA64_REL64LSB:	rtype = R_IA64_REL64LSB; break;
583
584    case BFD_RELOC_IA64_LTV32MSB:	rtype = R_IA64_LTV32MSB; break;
585    case BFD_RELOC_IA64_LTV32LSB:	rtype = R_IA64_LTV32LSB; break;
586    case BFD_RELOC_IA64_LTV64MSB:	rtype = R_IA64_LTV64MSB; break;
587    case BFD_RELOC_IA64_LTV64LSB:	rtype = R_IA64_LTV64LSB; break;
588
589    case BFD_RELOC_IA64_IPLTMSB:	rtype = R_IA64_IPLTMSB; break;
590    case BFD_RELOC_IA64_IPLTLSB:	rtype = R_IA64_IPLTLSB; break;
591    case BFD_RELOC_IA64_COPY:		rtype = R_IA64_COPY; break;
592    case BFD_RELOC_IA64_LTOFF22X:	rtype = R_IA64_LTOFF22X; break;
593    case BFD_RELOC_IA64_LDXMOV:		rtype = R_IA64_LDXMOV; break;
594
595    case BFD_RELOC_IA64_TPREL14:	rtype = R_IA64_TPREL14; break;
596    case BFD_RELOC_IA64_TPREL22:	rtype = R_IA64_TPREL22; break;
597    case BFD_RELOC_IA64_TPREL64I:	rtype = R_IA64_TPREL64I; break;
598    case BFD_RELOC_IA64_TPREL64MSB:	rtype = R_IA64_TPREL64MSB; break;
599    case BFD_RELOC_IA64_TPREL64LSB:	rtype = R_IA64_TPREL64LSB; break;
600    case BFD_RELOC_IA64_LTOFF_TPREL22:	rtype = R_IA64_LTOFF_TPREL22; break;
601
602    case BFD_RELOC_IA64_DTPMOD64MSB:	rtype = R_IA64_DTPMOD64MSB; break;
603    case BFD_RELOC_IA64_DTPMOD64LSB:	rtype = R_IA64_DTPMOD64LSB; break;
604    case BFD_RELOC_IA64_LTOFF_DTPMOD22:	rtype = R_IA64_LTOFF_DTPMOD22; break;
605
606    case BFD_RELOC_IA64_DTPREL14:	rtype = R_IA64_DTPREL14; break;
607    case BFD_RELOC_IA64_DTPREL22:	rtype = R_IA64_DTPREL22; break;
608    case BFD_RELOC_IA64_DTPREL64I:	rtype = R_IA64_DTPREL64I; break;
609    case BFD_RELOC_IA64_DTPREL32MSB:	rtype = R_IA64_DTPREL32MSB; break;
610    case BFD_RELOC_IA64_DTPREL32LSB:	rtype = R_IA64_DTPREL32LSB; break;
611    case BFD_RELOC_IA64_DTPREL64MSB:	rtype = R_IA64_DTPREL64MSB; break;
612    case BFD_RELOC_IA64_DTPREL64LSB:	rtype = R_IA64_DTPREL64LSB; break;
613    case BFD_RELOC_IA64_LTOFF_DTPREL22:	rtype = R_IA64_LTOFF_DTPREL22; break;
614
615    default: return 0;
616    }
617  return lookup_howto (rtype);
618}
619
620/* Given a ELF reloc, return the matching HOWTO structure.  */
621
622static void
623elfNN_ia64_info_to_howto (abfd, bfd_reloc, elf_reloc)
624     bfd *abfd ATTRIBUTE_UNUSED;
625     arelent *bfd_reloc;
626     Elf_Internal_Rela *elf_reloc;
627{
628  bfd_reloc->howto
629    = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc->r_info));
630}
631
632#define PLT_HEADER_SIZE		(3 * 16)
633#define PLT_MIN_ENTRY_SIZE	(1 * 16)
634#define PLT_FULL_ENTRY_SIZE	(2 * 16)
635#define PLT_RESERVED_WORDS	3
636
637static const bfd_byte plt_header[PLT_HEADER_SIZE] =
638{
639  0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21,  /*   [MMI]       mov r2=r14;;       */
640  0xe0, 0x00, 0x08, 0x00, 0x48, 0x00,  /*               addl r14=0,r2      */
641  0x00, 0x00, 0x04, 0x00,              /*               nop.i 0x0;;        */
642  0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14,  /*   [MMI]       ld8 r16=[r14],8;;  */
643  0x10, 0x41, 0x38, 0x30, 0x28, 0x00,  /*               ld8 r17=[r14],8    */
644  0x00, 0x00, 0x04, 0x00,              /*               nop.i 0x0;;        */
645  0x11, 0x08, 0x00, 0x1c, 0x18, 0x10,  /*   [MIB]       ld8 r1=[r14]       */
646  0x60, 0x88, 0x04, 0x80, 0x03, 0x00,  /*               mov b6=r17         */
647  0x60, 0x00, 0x80, 0x00               /*               br.few b6;;        */
648};
649
650static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
651{
652  0x11, 0x78, 0x00, 0x00, 0x00, 0x24,  /*   [MIB]       mov r15=0          */
653  0x00, 0x00, 0x00, 0x02, 0x00, 0x00,  /*               nop.i 0x0          */
654  0x00, 0x00, 0x00, 0x40               /*               br.few 0 <PLT0>;;  */
655};
656
657static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
658{
659  0x0b, 0x78, 0x00, 0x02, 0x00, 0x24,  /*   [MMI]       addl r15=0,r1;;    */
660  0x00, 0x41, 0x3c, 0x70, 0x29, 0xc0,  /*               ld8.acq r16=[r15],8*/
661  0x01, 0x08, 0x00, 0x84,              /*               mov r14=r1;;       */
662  0x11, 0x08, 0x00, 0x1e, 0x18, 0x10,  /*   [MIB]       ld8 r1=[r15]       */
663  0x60, 0x80, 0x04, 0x80, 0x03, 0x00,  /*               mov b6=r16         */
664  0x60, 0x00, 0x80, 0x00               /*               br.few b6;;        */
665};
666
667#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
668
669static const bfd_byte oor_brl[16] =
670{
671  0x05, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MLX]        nop.m 0            */
672  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /*               brl.sptk.few tgt;; */
673  0x00, 0x00, 0x00, 0xc0
674};
675
676static const bfd_byte oor_ip[48] =
677{
678  0x04, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MLX]        nop.m 0            */
679  0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,  /*               movl r15=0         */
680  0x01, 0x00, 0x00, 0x60,
681  0x03, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MII]        nop.m 0            */
682  0x00, 0x01, 0x00, 0x60, 0x00, 0x00,  /*               mov r16=ip;;       */
683  0xf2, 0x80, 0x00, 0x80,              /*               add r16=r15,r16;;  */
684  0x11, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MIB]        nop.m 0            */
685  0x60, 0x80, 0x04, 0x80, 0x03, 0x00,  /*               mov b6=r16         */
686  0x60, 0x00, 0x80, 0x00               /*               br b6;;            */
687};
688
689static size_t oor_branch_size = sizeof (oor_brl);
690
691void
692bfd_elfNN_ia64_after_parse (int itanium)
693{
694  oor_branch_size = itanium ? sizeof (oor_ip) : sizeof (oor_brl);
695}
696
697#define BTYPE_SHIFT	6
698#define Y_SHIFT		26
699#define X6_SHIFT	27
700#define X4_SHIFT	27
701#define X3_SHIFT	33
702#define X2_SHIFT	31
703#define X_SHIFT		33
704#define OPCODE_SHIFT	37
705
706#define OPCODE_BITS	(0xfLL << OPCODE_SHIFT)
707#define X6_BITS		(0x3fLL << X6_SHIFT)
708#define X4_BITS		(0xfLL << X4_SHIFT)
709#define X3_BITS		(0x7LL << X3_SHIFT)
710#define X2_BITS		(0x3LL << X2_SHIFT)
711#define X_BITS		(0x1LL << X_SHIFT)
712#define Y_BITS		(0x1LL << Y_SHIFT)
713#define BTYPE_BITS	(0x7LL << BTYPE_SHIFT)
714#define PREDICATE_BITS	(0x3fLL)
715
716#define IS_NOP_B(i) \
717  (((i) & (OPCODE_BITS | X6_BITS)) == (2LL << OPCODE_SHIFT))
718#define IS_NOP_F(i) \
719  (((i) & (OPCODE_BITS | X_BITS | X6_BITS | Y_BITS)) \
720   == (0x1LL << X6_SHIFT))
721#define IS_NOP_I(i) \
722  (((i) & (OPCODE_BITS | X3_BITS | X6_BITS | Y_BITS)) \
723   == (0x1LL << X6_SHIFT))
724#define IS_NOP_M(i) \
725  (((i) & (OPCODE_BITS | X3_BITS | X2_BITS | X4_BITS | Y_BITS)) \
726   == (0x1LL << X4_SHIFT))
727#define IS_BR_COND(i) \
728  (((i) & (OPCODE_BITS | BTYPE_BITS)) == (0x4LL << OPCODE_SHIFT))
729#define IS_BR_CALL(i) \
730  (((i) & OPCODE_BITS) == (0x5LL << OPCODE_SHIFT))
731
732static bfd_boolean
733elfNN_ia64_relax_br (bfd_byte *contents, bfd_vma off)
734{
735  unsigned int template, mlx;
736  bfd_vma t0, t1, s0, s1, s2, br_code;
737  long br_slot;
738  bfd_byte *hit_addr;
739
740  hit_addr = (bfd_byte *) (contents + off);
741  br_slot = (long) hit_addr & 0x3;
742  hit_addr -= br_slot;
743  t0 = bfd_getl64 (hit_addr + 0);
744  t1 = bfd_getl64 (hit_addr + 8);
745
746  /* Check if we can turn br into brl.  A label is always at the start
747     of the bundle.  Even if there are predicates on NOPs, we still
748     perform this optimization.  */
749  template = t0 & 0x1e;
750  s0 = (t0 >> 5) & 0x1ffffffffffLL;
751  s1 = ((t0 >> 46) | (t1 << 18)) & 0x1ffffffffffLL;
752  s2 = (t1 >> 23) & 0x1ffffffffffLL;
753  switch (br_slot)
754    {
755    case 0:
756      /* Check if slot 1 and slot 2 are NOPs. Possible template is
757         BBB.  We only need to check nop.b.  */
758      if (!(IS_NOP_B (s1) && IS_NOP_B (s2)))
759	return FALSE;
760      br_code = s0;
761      break;
762    case 1:
763      /* Check if slot 2 is NOP. Possible templates are MBB and BBB.
764	 For BBB, slot 0 also has to be nop.b.  */
765      if (!((template == 0x12				/* MBB */
766	     && IS_NOP_B (s2))
767	    || (template == 0x16			/* BBB */
768		&& IS_NOP_B (s0)
769		&& IS_NOP_B (s2))))
770	return FALSE;
771      br_code = s1;
772      break;
773    case 2:
774      /* Check if slot 1 is NOP. Possible templates are MIB, MBB, BBB,
775	 MMB and MFB. For BBB, slot 0 also has to be nop.b.  */
776      if (!((template == 0x10				/* MIB */
777	     && IS_NOP_I (s1))
778	    || (template == 0x12			/* MBB */
779		&& IS_NOP_B (s1))
780	    || (template == 0x16			/* BBB */
781		&& IS_NOP_B (s0)
782		&& IS_NOP_B (s1))
783	    || (template == 0x18			/* MMB */
784		&& IS_NOP_M (s1))
785	    || (template == 0x1c			/* MFB */
786		&& IS_NOP_F (s1))))
787	return FALSE;
788      br_code = s2;
789      break;
790    default:
791      /* It should never happen.  */
792      abort ();
793    }
794
795  /* We can turn br.cond/br.call into brl.cond/brl.call.  */
796  if (!(IS_BR_COND (br_code) || IS_BR_CALL (br_code)))
797    return FALSE;
798
799  /* Turn br into brl by setting bit 40.  */
800  br_code |= 0x1LL << 40;
801
802  /* Turn the old bundle into a MLX bundle with the same stop-bit
803     variety.  */
804  if (t0 & 0x1)
805    mlx = 0x5;
806  else
807    mlx = 0x4;
808
809  if (template == 0x16)
810    {
811      /* For BBB, we need to put nop.m in slot 0.  We keep the original
812	 predicate only if slot 0 isn't br.  */
813      if (br_slot == 0)
814	t0 = 0LL;
815      else
816	t0 &= PREDICATE_BITS << 5;
817      t0 |= 0x1LL << (X4_SHIFT + 5);
818    }
819  else
820    {
821      /* Keep the original instruction in slot 0.  */
822      t0 &= 0x1ffffffffffLL << 5;
823    }
824
825  t0 |= mlx;
826
827  /* Put brl in slot 1.  */
828  t1 = br_code << 23;
829
830  bfd_putl64 (t0, hit_addr);
831  bfd_putl64 (t1, hit_addr + 8);
832  return TRUE;
833}
834
835static void
836elfNN_ia64_relax_brl (bfd_byte *contents, bfd_vma off)
837{
838  int template;
839  bfd_byte *hit_addr;
840  bfd_vma t0, t1, i0, i1, i2;
841
842  hit_addr = (bfd_byte *) (contents + off);
843  hit_addr -= (long) hit_addr & 0x3;
844  t0 = bfd_getl64 (hit_addr);
845  t1 = bfd_getl64 (hit_addr + 8);
846
847  /* Keep the instruction in slot 0. */
848  i0 = (t0 >> 5) & 0x1ffffffffffLL;
849  /* Use nop.b for slot 1. */
850  i1 = 0x4000000000LL;
851  /* For slot 2, turn brl into br by masking out bit 40.  */
852  i2 = (t1 >> 23) & 0x0ffffffffffLL;
853
854  /* Turn a MLX bundle into a MBB bundle with the same stop-bit
855     variety.  */
856  if (t0 & 0x1)
857    template = 0x13;
858  else
859    template = 0x12;
860  t0 = (i1 << 46) | (i0 << 5) | template;
861  t1 = (i2 << 23) | (i1 >> 18);
862
863  bfd_putl64 (t0, hit_addr);
864  bfd_putl64 (t1, hit_addr + 8);
865}
866
867/* Rename some of the generic section flags to better document how they
868   are used here.  */
869#define skip_relax_pass_0 need_finalize_relax
870#define skip_relax_pass_1 has_gp_reloc
871
872
873/* These functions do relaxation for IA-64 ELF.  */
874
875static bfd_boolean
876elfNN_ia64_relax_section (abfd, sec, link_info, again)
877     bfd *abfd;
878     asection *sec;
879     struct bfd_link_info *link_info;
880     bfd_boolean *again;
881{
882  struct one_fixup
883    {
884      struct one_fixup *next;
885      asection *tsec;
886      bfd_vma toff;
887      bfd_vma trampoff;
888    };
889
890  Elf_Internal_Shdr *symtab_hdr;
891  Elf_Internal_Rela *internal_relocs;
892  Elf_Internal_Rela *irel, *irelend;
893  bfd_byte *contents;
894  Elf_Internal_Sym *isymbuf = NULL;
895  struct elfNN_ia64_link_hash_table *ia64_info;
896  struct one_fixup *fixups = NULL;
897  bfd_boolean changed_contents = FALSE;
898  bfd_boolean changed_relocs = FALSE;
899  bfd_boolean changed_got = FALSE;
900  bfd_boolean skip_relax_pass_0 = TRUE;
901  bfd_boolean skip_relax_pass_1 = TRUE;
902  bfd_vma gp = 0;
903
904  /* Assume we're not going to change any sizes, and we'll only need
905     one pass.  */
906  *again = FALSE;
907
908  /* Don't even try to relax for non-ELF outputs.  */
909  if (!is_elf_hash_table (link_info->hash))
910    return FALSE;
911
912  /* Nothing to do if there are no relocations or there is no need for
913     the current pass.  */
914  if ((sec->flags & SEC_RELOC) == 0
915      || sec->reloc_count == 0
916      || (link_info->relax_pass == 0 && sec->skip_relax_pass_0)
917      || (link_info->relax_pass == 1 && sec->skip_relax_pass_1))
918    return TRUE;
919
920  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
921
922  /* Load the relocations for this section.  */
923  internal_relocs = (_bfd_elf_link_read_relocs
924		     (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
925		      link_info->keep_memory));
926  if (internal_relocs == NULL)
927    return FALSE;
928
929  ia64_info = elfNN_ia64_hash_table (link_info);
930  irelend = internal_relocs + sec->reloc_count;
931
932  /* Get the section contents.  */
933  if (elf_section_data (sec)->this_hdr.contents != NULL)
934    contents = elf_section_data (sec)->this_hdr.contents;
935  else
936    {
937      if (!bfd_malloc_and_get_section (abfd, sec, &contents))
938	goto error_return;
939    }
940
941  for (irel = internal_relocs; irel < irelend; irel++)
942    {
943      unsigned long r_type = ELFNN_R_TYPE (irel->r_info);
944      bfd_vma symaddr, reladdr, trampoff, toff, roff;
945      asection *tsec;
946      struct one_fixup *f;
947      bfd_size_type amt;
948      bfd_boolean is_branch;
949      struct elfNN_ia64_dyn_sym_info *dyn_i;
950      char symtype;
951
952      switch (r_type)
953	{
954	case R_IA64_PCREL21B:
955	case R_IA64_PCREL21BI:
956	case R_IA64_PCREL21M:
957	case R_IA64_PCREL21F:
958	  /* In pass 1, all br relaxations are done. We can skip it. */
959	  if (link_info->relax_pass == 1)
960	    continue;
961	  skip_relax_pass_0 = FALSE;
962	  is_branch = TRUE;
963	  break;
964
965	case R_IA64_PCREL60B:
966	  /* We can't optimize brl to br in pass 0 since br relaxations
967	     will increase the code size. Defer it to pass 1.  */
968	  if (link_info->relax_pass == 0)
969	    {
970	      skip_relax_pass_1 = FALSE;
971	      continue;
972	    }
973	  is_branch = TRUE;
974	  break;
975
976	case R_IA64_LTOFF22X:
977	case R_IA64_LDXMOV:
978	  /* We can't relax ldx/mov in pass 0 since br relaxations will
979	     increase the code size. Defer it to pass 1.  */
980	  if (link_info->relax_pass == 0)
981	    {
982	      skip_relax_pass_1 = FALSE;
983	      continue;
984	    }
985	  is_branch = FALSE;
986	  break;
987
988	default:
989	  continue;
990	}
991
992      /* Get the value of the symbol referred to by the reloc.  */
993      if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
994	{
995	  /* A local symbol.  */
996	  Elf_Internal_Sym *isym;
997
998	  /* Read this BFD's local symbols.  */
999	  if (isymbuf == NULL)
1000	    {
1001	      isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1002	      if (isymbuf == NULL)
1003		isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1004						symtab_hdr->sh_info, 0,
1005						NULL, NULL, NULL);
1006	      if (isymbuf == 0)
1007		goto error_return;
1008	    }
1009
1010	  isym = isymbuf + ELFNN_R_SYM (irel->r_info);
1011	  if (isym->st_shndx == SHN_UNDEF)
1012	    continue;	/* We can't do anything with undefined symbols.  */
1013	  else if (isym->st_shndx == SHN_ABS)
1014	    tsec = bfd_abs_section_ptr;
1015	  else if (isym->st_shndx == SHN_COMMON)
1016	    tsec = bfd_com_section_ptr;
1017	  else if (isym->st_shndx == SHN_IA_64_ANSI_COMMON)
1018	    tsec = bfd_com_section_ptr;
1019	  else
1020	    tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1021
1022	  toff = isym->st_value;
1023	  dyn_i = get_dyn_sym_info (ia64_info, NULL, abfd, irel, FALSE);
1024	  symtype = ELF_ST_TYPE (isym->st_info);
1025	}
1026      else
1027	{
1028	  unsigned long indx;
1029	  struct elf_link_hash_entry *h;
1030
1031	  indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1032	  h = elf_sym_hashes (abfd)[indx];
1033	  BFD_ASSERT (h != NULL);
1034
1035	  while (h->root.type == bfd_link_hash_indirect
1036		 || h->root.type == bfd_link_hash_warning)
1037	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
1038
1039	  dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, FALSE);
1040
1041	  /* For branches to dynamic symbols, we're interested instead
1042	     in a branch to the PLT entry.  */
1043	  if (is_branch && dyn_i && dyn_i->want_plt2)
1044	    {
1045	      /* Internal branches shouldn't be sent to the PLT.
1046		 Leave this for now and we'll give an error later.  */
1047	      if (r_type != R_IA64_PCREL21B)
1048		continue;
1049
1050	      tsec = ia64_info->plt_sec;
1051	      toff = dyn_i->plt2_offset;
1052	      BFD_ASSERT (irel->r_addend == 0);
1053	    }
1054
1055	  /* Can't do anything else with dynamic symbols.  */
1056	  else if (elfNN_ia64_dynamic_symbol_p (h, link_info, r_type))
1057	    continue;
1058
1059	  else
1060	    {
1061	      /* We can't do anything with undefined symbols.  */
1062	      if (h->root.type == bfd_link_hash_undefined
1063		  || h->root.type == bfd_link_hash_undefweak)
1064		continue;
1065
1066	      tsec = h->root.u.def.section;
1067	      toff = h->root.u.def.value;
1068	    }
1069
1070	  symtype = h->type;
1071	}
1072
1073      if (tsec->sec_info_type == ELF_INFO_TYPE_MERGE)
1074	{
1075	  /* At this stage in linking, no SEC_MERGE symbol has been
1076	     adjusted, so all references to such symbols need to be
1077	     passed through _bfd_merged_section_offset.  (Later, in
1078	     relocate_section, all SEC_MERGE symbols *except* for
1079	     section symbols have been adjusted.)
1080
1081	     gas may reduce relocations against symbols in SEC_MERGE
1082	     sections to a relocation against the section symbol when
1083	     the original addend was zero.  When the reloc is against
1084	     a section symbol we should include the addend in the
1085	     offset passed to _bfd_merged_section_offset, since the
1086	     location of interest is the original symbol.  On the
1087	     other hand, an access to "sym+addend" where "sym" is not
1088	     a section symbol should not include the addend;  Such an
1089	     access is presumed to be an offset from "sym";  The
1090	     location of interest is just "sym".  */
1091	   if (symtype == STT_SECTION)
1092	     toff += irel->r_addend;
1093
1094	   toff = _bfd_merged_section_offset (abfd, &tsec,
1095					      elf_section_data (tsec)->sec_info,
1096					      toff);
1097
1098	   if (symtype != STT_SECTION)
1099	     toff += irel->r_addend;
1100	}
1101      else
1102	toff += irel->r_addend;
1103
1104      symaddr = tsec->output_section->vma + tsec->output_offset + toff;
1105
1106      roff = irel->r_offset;
1107
1108      if (is_branch)
1109	{
1110	  bfd_signed_vma offset;
1111
1112	  reladdr = (sec->output_section->vma
1113		     + sec->output_offset
1114		     + roff) & (bfd_vma) -4;
1115
1116	  /* If the branch is in range, no need to do anything.  */
1117	  if ((bfd_signed_vma) (symaddr - reladdr) >= -0x1000000
1118	      && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
1119	    {
1120	      /* If the 60-bit branch is in 21-bit range, optimize it. */
1121	      if (r_type == R_IA64_PCREL60B)
1122		{
1123		  elfNN_ia64_relax_brl (contents, roff);
1124
1125		  irel->r_info
1126		    = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1127				    R_IA64_PCREL21B);
1128
1129		  /* If the original relocation offset points to slot
1130		     1, change it to slot 2.  */
1131		  if ((irel->r_offset & 3) == 1)
1132		    irel->r_offset += 1;
1133		}
1134
1135	      continue;
1136	    }
1137	  else if (r_type == R_IA64_PCREL60B)
1138	    continue;
1139	  else if (elfNN_ia64_relax_br (contents, roff))
1140	    {
1141	      irel->r_info
1142		= ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1143				R_IA64_PCREL60B);
1144
1145	      /* Make the relocation offset point to slot 1.  */
1146	      irel->r_offset = (irel->r_offset & ~((bfd_vma) 0x3)) + 1;
1147	      continue;
1148	    }
1149
1150	  /* We can't put a trampoline in a .init/.fini section. Issue
1151	     an error.  */
1152	  if (strcmp (sec->output_section->name, ".init") == 0
1153	      || strcmp (sec->output_section->name, ".fini") == 0)
1154	    {
1155	      (*_bfd_error_handler)
1156		(_("%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."),
1157		 sec->owner, sec, (unsigned long) roff);
1158	      bfd_set_error (bfd_error_bad_value);
1159	      goto error_return;
1160	    }
1161
1162	  /* If the branch and target are in the same section, you've
1163	     got one honking big section and we can't help you unless
1164	     you are branching backwards.  You'll get an error message
1165	     later.  */
1166	  if (tsec == sec && toff > roff)
1167	    continue;
1168
1169	  /* Look for an existing fixup to this address.  */
1170	  for (f = fixups; f ; f = f->next)
1171	    if (f->tsec == tsec && f->toff == toff)
1172	      break;
1173
1174	  if (f == NULL)
1175	    {
1176	      /* Two alternatives: If it's a branch to a PLT entry, we can
1177		 make a copy of the FULL_PLT entry.  Otherwise, we'll have
1178		 to use a `brl' insn to get where we're going.  */
1179
1180	      size_t size;
1181
1182	      if (tsec == ia64_info->plt_sec)
1183		size = sizeof (plt_full_entry);
1184	      else
1185		size = oor_branch_size;
1186
1187	      /* Resize the current section to make room for the new branch. */
1188	      trampoff = (sec->size + 15) & (bfd_vma) -16;
1189
1190	      /* If trampoline is out of range, there is nothing we
1191		 can do.  */
1192	      offset = trampoff - (roff & (bfd_vma) -4);
1193	      if (offset < -0x1000000 || offset > 0x0FFFFF0)
1194		continue;
1195
1196	      amt = trampoff + size;
1197	      contents = (bfd_byte *) bfd_realloc (contents, amt);
1198	      if (contents == NULL)
1199		goto error_return;
1200	      sec->size = amt;
1201
1202	      if (tsec == ia64_info->plt_sec)
1203		{
1204		  memcpy (contents + trampoff, plt_full_entry, size);
1205
1206		  /* Hijack the old relocation for use as the PLTOFF reloc.  */
1207		  irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1208					       R_IA64_PLTOFF22);
1209		  irel->r_offset = trampoff;
1210		}
1211	      else
1212		{
1213		  if (size == sizeof (oor_ip))
1214		    {
1215		      memcpy (contents + trampoff, oor_ip, size);
1216		      irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1217						   R_IA64_PCREL64I);
1218		      irel->r_addend -= 16;
1219		      irel->r_offset = trampoff + 2;
1220		    }
1221		  else
1222		    {
1223		      memcpy (contents + trampoff, oor_brl, size);
1224		      irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1225						   R_IA64_PCREL60B);
1226		      irel->r_offset = trampoff + 2;
1227		    }
1228
1229		}
1230
1231	      /* Record the fixup so we don't do it again this section.  */
1232	      f = (struct one_fixup *)
1233		bfd_malloc ((bfd_size_type) sizeof (*f));
1234	      f->next = fixups;
1235	      f->tsec = tsec;
1236	      f->toff = toff;
1237	      f->trampoff = trampoff;
1238	      fixups = f;
1239	    }
1240	  else
1241	    {
1242	      /* If trampoline is out of range, there is nothing we
1243		 can do.  */
1244	      offset = f->trampoff - (roff & (bfd_vma) -4);
1245	      if (offset < -0x1000000 || offset > 0x0FFFFF0)
1246		continue;
1247
1248	      /* Nop out the reloc, since we're finalizing things here.  */
1249	      irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
1250	    }
1251
1252	  /* Fix up the existing branch to hit the trampoline.  */
1253	  if (elfNN_ia64_install_value (contents + roff, offset, r_type)
1254	      != bfd_reloc_ok)
1255	    goto error_return;
1256
1257	  changed_contents = TRUE;
1258	  changed_relocs = TRUE;
1259	}
1260      else
1261	{
1262	  /* Fetch the gp.  */
1263	  if (gp == 0)
1264	    {
1265	      bfd *obfd = sec->output_section->owner;
1266	      gp = _bfd_get_gp_value (obfd);
1267	      if (gp == 0)
1268		{
1269		  if (!elfNN_ia64_choose_gp (obfd, link_info))
1270		    goto error_return;
1271		  gp = _bfd_get_gp_value (obfd);
1272		}
1273	    }
1274
1275	  /* If the data is out of range, do nothing.  */
1276	  if ((bfd_signed_vma) (symaddr - gp) >= 0x200000
1277	      ||(bfd_signed_vma) (symaddr - gp) < -0x200000)
1278	    continue;
1279
1280	  if (r_type == R_IA64_LTOFF22X)
1281	    {
1282	      irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1283					   R_IA64_GPREL22);
1284	      changed_relocs = TRUE;
1285	      if (dyn_i->want_gotx)
1286		{
1287		  dyn_i->want_gotx = 0;
1288		  changed_got |= !dyn_i->want_got;
1289		}
1290	    }
1291	  else
1292	    {
1293	      elfNN_ia64_relax_ldxmov (contents, roff);
1294	      irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
1295	      changed_contents = TRUE;
1296	      changed_relocs = TRUE;
1297	    }
1298	}
1299    }
1300
1301  /* ??? If we created fixups, this may push the code segment large
1302     enough that the data segment moves, which will change the GP.
1303     Reset the GP so that we re-calculate next round.  We need to
1304     do this at the _beginning_ of the next round; now will not do.  */
1305
1306  /* Clean up and go home.  */
1307  while (fixups)
1308    {
1309      struct one_fixup *f = fixups;
1310      fixups = fixups->next;
1311      free (f);
1312    }
1313
1314  if (isymbuf != NULL
1315      && symtab_hdr->contents != (unsigned char *) isymbuf)
1316    {
1317      if (! link_info->keep_memory)
1318	free (isymbuf);
1319      else
1320	{
1321	  /* Cache the symbols for elf_link_input_bfd.  */
1322	  symtab_hdr->contents = (unsigned char *) isymbuf;
1323	}
1324    }
1325
1326  if (contents != NULL
1327      && elf_section_data (sec)->this_hdr.contents != contents)
1328    {
1329      if (!changed_contents && !link_info->keep_memory)
1330	free (contents);
1331      else
1332	{
1333	  /* Cache the section contents for elf_link_input_bfd.  */
1334	  elf_section_data (sec)->this_hdr.contents = contents;
1335	}
1336    }
1337
1338  if (elf_section_data (sec)->relocs != internal_relocs)
1339    {
1340      if (!changed_relocs)
1341	free (internal_relocs);
1342      else
1343	elf_section_data (sec)->relocs = internal_relocs;
1344    }
1345
1346  if (changed_got)
1347    {
1348      struct elfNN_ia64_allocate_data data;
1349      data.info = link_info;
1350      data.ofs = 0;
1351      ia64_info->self_dtpmod_offset = (bfd_vma) -1;
1352
1353      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
1354      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
1355      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
1356      ia64_info->got_sec->size = data.ofs;
1357
1358      if (ia64_info->root.dynamic_sections_created
1359	  && ia64_info->rel_got_sec != NULL)
1360	{
1361	  /* Resize .rela.got.  */
1362	  ia64_info->rel_got_sec->size = 0;
1363	  if (link_info->shared
1364	      && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
1365	    ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
1366	  data.only_got = TRUE;
1367	  elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries,
1368				       &data);
1369	}
1370    }
1371
1372  if (link_info->relax_pass == 0)
1373    {
1374      /* Pass 0 is only needed to relax br.  */
1375      sec->skip_relax_pass_0 = skip_relax_pass_0;
1376      sec->skip_relax_pass_1 = skip_relax_pass_1;
1377    }
1378
1379  *again = changed_contents || changed_relocs;
1380  return TRUE;
1381
1382 error_return:
1383  if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
1384    free (isymbuf);
1385  if (contents != NULL
1386      && elf_section_data (sec)->this_hdr.contents != contents)
1387    free (contents);
1388  if (internal_relocs != NULL
1389      && elf_section_data (sec)->relocs != internal_relocs)
1390    free (internal_relocs);
1391  return FALSE;
1392}
1393#undef skip_relax_pass_0
1394#undef skip_relax_pass_1
1395
1396static void
1397elfNN_ia64_relax_ldxmov (contents, off)
1398     bfd_byte *contents;
1399     bfd_vma off;
1400{
1401  int shift, r1, r3;
1402  bfd_vma dword, insn;
1403
1404  switch ((int)off & 0x3)
1405    {
1406    case 0: shift =  5; break;
1407    case 1: shift = 14; off += 3; break;
1408    case 2: shift = 23; off += 6; break;
1409    default:
1410      abort ();
1411    }
1412
1413  dword = bfd_getl64 (contents + off);
1414  insn = (dword >> shift) & 0x1ffffffffffLL;
1415
1416  r1 = (insn >> 6) & 127;
1417  r3 = (insn >> 20) & 127;
1418  if (r1 == r3)
1419    insn = 0x8000000;				   /* nop */
1420  else
1421    insn = (insn & 0x7f01fff) | 0x10800000000LL;   /* (qp) mov r1 = r3 */
1422
1423  dword &= ~(0x1ffffffffffLL << shift);
1424  dword |= (insn << shift);
1425  bfd_putl64 (dword, contents + off);
1426}
1427
1428/* Return TRUE if NAME is an unwind table section name.  */
1429
1430static inline bfd_boolean
1431is_unwind_section_name (abfd, name)
1432	bfd *abfd;
1433	const char *name;
1434{
1435  size_t len1, len2, len3;
1436
1437  if (elfNN_ia64_hpux_vec (abfd->xvec)
1438      && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
1439    return FALSE;
1440
1441  len1 = sizeof (ELF_STRING_ia64_unwind) - 1;
1442  len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
1443  len3 = sizeof (ELF_STRING_ia64_unwind_once) - 1;
1444  return ((strncmp (name, ELF_STRING_ia64_unwind, len1) == 0
1445	   && strncmp (name, ELF_STRING_ia64_unwind_info, len2) != 0)
1446	  || strncmp (name, ELF_STRING_ia64_unwind_once, len3) == 0);
1447}
1448
1449/* Handle an IA-64 specific section when reading an object file.  This
1450   is called when bfd_section_from_shdr finds a section with an unknown
1451   type.  */
1452
1453static bfd_boolean
1454elfNN_ia64_section_from_shdr (bfd *abfd,
1455			      Elf_Internal_Shdr *hdr,
1456			      const char *name,
1457			      int shindex)
1458{
1459  asection *newsect;
1460
1461  /* There ought to be a place to keep ELF backend specific flags, but
1462     at the moment there isn't one.  We just keep track of the
1463     sections by their name, instead.  Fortunately, the ABI gives
1464     suggested names for all the MIPS specific sections, so we will
1465     probably get away with this.  */
1466  switch (hdr->sh_type)
1467    {
1468    case SHT_IA_64_UNWIND:
1469    case SHT_IA_64_HP_OPT_ANOT:
1470      break;
1471
1472    case SHT_IA_64_EXT:
1473      if (strcmp (name, ELF_STRING_ia64_archext) != 0)
1474	return FALSE;
1475      break;
1476
1477    default:
1478      return FALSE;
1479    }
1480
1481  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
1482    return FALSE;
1483  newsect = hdr->bfd_section;
1484
1485  return TRUE;
1486}
1487
1488/* Convert IA-64 specific section flags to bfd internal section flags.  */
1489
1490/* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1491   flag.  */
1492
1493static bfd_boolean
1494elfNN_ia64_section_flags (flags, hdr)
1495     flagword *flags;
1496     const Elf_Internal_Shdr *hdr;
1497{
1498  if (hdr->sh_flags & SHF_IA_64_SHORT)
1499    *flags |= SEC_SMALL_DATA;
1500
1501  return TRUE;
1502}
1503
1504/* Set the correct type for an IA-64 ELF section.  We do this by the
1505   section name, which is a hack, but ought to work.  */
1506
1507static bfd_boolean
1508elfNN_ia64_fake_sections (abfd, hdr, sec)
1509     bfd *abfd ATTRIBUTE_UNUSED;
1510     Elf_Internal_Shdr *hdr;
1511     asection *sec;
1512{
1513  register const char *name;
1514
1515  name = bfd_get_section_name (abfd, sec);
1516
1517  if (is_unwind_section_name (abfd, name))
1518    {
1519      /* We don't have the sections numbered at this point, so sh_info
1520	 is set later, in elfNN_ia64_final_write_processing.  */
1521      hdr->sh_type = SHT_IA_64_UNWIND;
1522      hdr->sh_flags |= SHF_LINK_ORDER;
1523    }
1524  else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
1525    hdr->sh_type = SHT_IA_64_EXT;
1526  else if (strcmp (name, ".HP.opt_annot") == 0)
1527    hdr->sh_type = SHT_IA_64_HP_OPT_ANOT;
1528  else if (strcmp (name, ".reloc") == 0)
1529    /* This is an ugly, but unfortunately necessary hack that is
1530       needed when producing EFI binaries on IA-64. It tells
1531       elf.c:elf_fake_sections() not to consider ".reloc" as a section
1532       containing ELF relocation info.  We need this hack in order to
1533       be able to generate ELF binaries that can be translated into
1534       EFI applications (which are essentially COFF objects).  Those
1535       files contain a COFF ".reloc" section inside an ELFNN object,
1536       which would normally cause BFD to segfault because it would
1537       attempt to interpret this section as containing relocation
1538       entries for section "oc".  With this hack enabled, ".reloc"
1539       will be treated as a normal data section, which will avoid the
1540       segfault.  However, you won't be able to create an ELFNN binary
1541       with a section named "oc" that needs relocations, but that's
1542       the kind of ugly side-effects you get when detecting section
1543       types based on their names...  In practice, this limitation is
1544       unlikely to bite.  */
1545    hdr->sh_type = SHT_PROGBITS;
1546
1547  if (sec->flags & SEC_SMALL_DATA)
1548    hdr->sh_flags |= SHF_IA_64_SHORT;
1549
1550  /* Some HP linkers look for the SHF_IA_64_HP_TLS flag instead of SHF_TLS. */
1551
1552  if (elfNN_ia64_hpux_vec (abfd->xvec) && (sec->flags & SHF_TLS))
1553    hdr->sh_flags |= SHF_IA_64_HP_TLS;
1554
1555  return TRUE;
1556}
1557
1558/* The final processing done just before writing out an IA-64 ELF
1559   object file.  */
1560
1561static void
1562elfNN_ia64_final_write_processing (abfd, linker)
1563     bfd *abfd;
1564     bfd_boolean linker ATTRIBUTE_UNUSED;
1565{
1566  Elf_Internal_Shdr *hdr;
1567  asection *s;
1568
1569  for (s = abfd->sections; s; s = s->next)
1570    {
1571      hdr = &elf_section_data (s)->this_hdr;
1572      switch (hdr->sh_type)
1573	{
1574	case SHT_IA_64_UNWIND:
1575	  /* The IA-64 processor-specific ABI requires setting sh_link
1576	     to the unwind section, whereas HP-UX requires sh_info to
1577	     do so.  For maximum compatibility, we'll set both for
1578	     now... */
1579	  hdr->sh_info = hdr->sh_link;
1580	  break;
1581	}
1582    }
1583
1584  if (! elf_flags_init (abfd))
1585    {
1586      unsigned long flags = 0;
1587
1588      if (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
1589	flags |= EF_IA_64_BE;
1590      if (bfd_get_mach (abfd) == bfd_mach_ia64_elf64)
1591	flags |= EF_IA_64_ABI64;
1592
1593      elf_elfheader(abfd)->e_flags = flags;
1594      elf_flags_init (abfd) = TRUE;
1595    }
1596}
1597
1598/* Hook called by the linker routine which adds symbols from an object
1599   file.  We use it to put .comm items in .sbss, and not .bss.  */
1600
1601static bfd_boolean
1602elfNN_ia64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1603     bfd *abfd;
1604     struct bfd_link_info *info;
1605     Elf_Internal_Sym *sym;
1606     const char **namep ATTRIBUTE_UNUSED;
1607     flagword *flagsp ATTRIBUTE_UNUSED;
1608     asection **secp;
1609     bfd_vma *valp;
1610{
1611  if (sym->st_shndx == SHN_COMMON
1612      && !info->relocatable
1613      && sym->st_size <= elf_gp_size (abfd))
1614    {
1615      /* Common symbols less than or equal to -G nn bytes are
1616	 automatically put into .sbss.  */
1617
1618      asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1619
1620      if (scomm == NULL)
1621	{
1622	  scomm = bfd_make_section_with_flags (abfd, ".scommon",
1623					       (SEC_ALLOC
1624						| SEC_IS_COMMON
1625						| SEC_LINKER_CREATED));
1626	  if (scomm == NULL)
1627	    return FALSE;
1628	}
1629
1630      *secp = scomm;
1631      *valp = sym->st_size;
1632    }
1633
1634  return TRUE;
1635}
1636
1637/* Return the number of additional phdrs we will need.  */
1638
1639static int
1640elfNN_ia64_additional_program_headers (abfd)
1641     bfd *abfd;
1642{
1643  asection *s;
1644  int ret = 0;
1645
1646  /* See if we need a PT_IA_64_ARCHEXT segment.  */
1647  s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1648  if (s && (s->flags & SEC_LOAD))
1649    ++ret;
1650
1651  /* Count how many PT_IA_64_UNWIND segments we need.  */
1652  for (s = abfd->sections; s; s = s->next)
1653    if (is_unwind_section_name (abfd, s->name) && (s->flags & SEC_LOAD))
1654      ++ret;
1655
1656  return ret;
1657}
1658
1659static bfd_boolean
1660elfNN_ia64_modify_segment_map (abfd, info)
1661     bfd *abfd;
1662     struct bfd_link_info *info ATTRIBUTE_UNUSED;
1663{
1664  struct elf_segment_map *m, **pm;
1665  Elf_Internal_Shdr *hdr;
1666  asection *s;
1667
1668  /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1669     all PT_LOAD segments.  */
1670  s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1671  if (s && (s->flags & SEC_LOAD))
1672    {
1673      for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1674	if (m->p_type == PT_IA_64_ARCHEXT)
1675	  break;
1676      if (m == NULL)
1677	{
1678	  m = ((struct elf_segment_map *)
1679	       bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1680	  if (m == NULL)
1681	    return FALSE;
1682
1683	  m->p_type = PT_IA_64_ARCHEXT;
1684	  m->count = 1;
1685	  m->sections[0] = s;
1686
1687	  /* We want to put it after the PHDR and INTERP segments.  */
1688	  pm = &elf_tdata (abfd)->segment_map;
1689	  while (*pm != NULL
1690		 && ((*pm)->p_type == PT_PHDR
1691		     || (*pm)->p_type == PT_INTERP))
1692	    pm = &(*pm)->next;
1693
1694	  m->next = *pm;
1695	  *pm = m;
1696	}
1697    }
1698
1699  /* Install PT_IA_64_UNWIND segments, if needed.  */
1700  for (s = abfd->sections; s; s = s->next)
1701    {
1702      hdr = &elf_section_data (s)->this_hdr;
1703      if (hdr->sh_type != SHT_IA_64_UNWIND)
1704	continue;
1705
1706      if (s && (s->flags & SEC_LOAD))
1707	{
1708	  for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1709	    if (m->p_type == PT_IA_64_UNWIND)
1710	      {
1711		int i;
1712
1713		/* Look through all sections in the unwind segment
1714		   for a match since there may be multiple sections
1715		   to a segment.  */
1716		for (i = m->count - 1; i >= 0; --i)
1717		  if (m->sections[i] == s)
1718		    break;
1719
1720		if (i >= 0)
1721		  break;
1722	      }
1723
1724	  if (m == NULL)
1725	    {
1726	      m = ((struct elf_segment_map *)
1727		   bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1728	      if (m == NULL)
1729		return FALSE;
1730
1731	      m->p_type = PT_IA_64_UNWIND;
1732	      m->count = 1;
1733	      m->sections[0] = s;
1734	      m->next = NULL;
1735
1736	      /* We want to put it last.  */
1737	      pm = &elf_tdata (abfd)->segment_map;
1738	      while (*pm != NULL)
1739		pm = &(*pm)->next;
1740	      *pm = m;
1741	    }
1742	}
1743    }
1744
1745  /* Turn on PF_IA_64_NORECOV if needed.  This involves traversing all of
1746     the input sections for each output section in the segment and testing
1747     for SHF_IA_64_NORECOV on each.  */
1748  for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1749    if (m->p_type == PT_LOAD)
1750      {
1751	int i;
1752	for (i = m->count - 1; i >= 0; --i)
1753	  {
1754	    struct bfd_link_order *order = m->sections[i]->map_head.link_order;
1755	    while (order)
1756	      {
1757		if (order->type == bfd_indirect_link_order)
1758		  {
1759		    asection *is = order->u.indirect.section;
1760		    bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
1761		    if (flags & SHF_IA_64_NORECOV)
1762		      {
1763			m->p_flags |= PF_IA_64_NORECOV;
1764			goto found;
1765		      }
1766		  }
1767		order = order->next;
1768	      }
1769	  }
1770      found:;
1771      }
1772
1773  return TRUE;
1774}
1775
1776/* According to the Tahoe assembler spec, all labels starting with a
1777   '.' are local.  */
1778
1779static bfd_boolean
1780elfNN_ia64_is_local_label_name (abfd, name)
1781     bfd *abfd ATTRIBUTE_UNUSED;
1782     const char *name;
1783{
1784  return name[0] == '.';
1785}
1786
1787/* Should we do dynamic things to this symbol?  */
1788
1789static bfd_boolean
1790elfNN_ia64_dynamic_symbol_p (h, info, r_type)
1791     struct elf_link_hash_entry *h;
1792     struct bfd_link_info *info;
1793     int r_type;
1794{
1795  bfd_boolean ignore_protected
1796    = ((r_type & 0xf8) == 0x40		/* FPTR relocs */
1797       || (r_type & 0xf8) == 0x50);	/* LTOFF_FPTR relocs */
1798
1799  return _bfd_elf_dynamic_symbol_p (h, info, ignore_protected);
1800}
1801
1802static struct bfd_hash_entry*
1803elfNN_ia64_new_elf_hash_entry (entry, table, string)
1804     struct bfd_hash_entry *entry;
1805     struct bfd_hash_table *table;
1806     const char *string;
1807{
1808  struct elfNN_ia64_link_hash_entry *ret;
1809  ret = (struct elfNN_ia64_link_hash_entry *) entry;
1810
1811  /* Allocate the structure if it has not already been allocated by a
1812     subclass.  */
1813  if (!ret)
1814    ret = bfd_hash_allocate (table, sizeof (*ret));
1815
1816  if (!ret)
1817    return 0;
1818
1819  /* Call the allocation method of the superclass.  */
1820  ret = ((struct elfNN_ia64_link_hash_entry *)
1821	 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1822				     table, string));
1823
1824  ret->info = NULL;
1825  ret->count = 0;
1826  ret->sorted_count = 0;
1827  ret->size = 0;
1828  return (struct bfd_hash_entry *) ret;
1829}
1830
1831static void
1832elfNN_ia64_hash_copy_indirect (info, xdir, xind)
1833     struct bfd_link_info *info;
1834     struct elf_link_hash_entry *xdir, *xind;
1835{
1836  struct elfNN_ia64_link_hash_entry *dir, *ind;
1837
1838  dir = (struct elfNN_ia64_link_hash_entry *) xdir;
1839  ind = (struct elfNN_ia64_link_hash_entry *) xind;
1840
1841  /* Copy down any references that we may have already seen to the
1842     symbol which just became indirect.  */
1843
1844  dir->root.ref_dynamic |= ind->root.ref_dynamic;
1845  dir->root.ref_regular |= ind->root.ref_regular;
1846  dir->root.ref_regular_nonweak |= ind->root.ref_regular_nonweak;
1847  dir->root.needs_plt |= ind->root.needs_plt;
1848
1849  if (ind->root.root.type != bfd_link_hash_indirect)
1850    return;
1851
1852  /* Copy over the got and plt data.  This would have been done
1853     by check_relocs.  */
1854
1855  if (ind->info != NULL)
1856    {
1857      struct elfNN_ia64_dyn_sym_info *dyn_i;
1858      unsigned int count;
1859
1860      if (dir->info)
1861	free (dir->info);
1862
1863      dir->info = ind->info;
1864      dir->count = ind->count;
1865      dir->sorted_count = ind->sorted_count;
1866      dir->size = ind->size;
1867
1868      ind->info = NULL;
1869      ind->count = 0;
1870      ind->sorted_count = 0;
1871      ind->size = 0;
1872
1873      /* Fix up the dyn_sym_info pointers to the global symbol.  */
1874      for (count = dir->count, dyn_i = dir->info;
1875	   count != 0;
1876	   count--, dyn_i++)
1877	dyn_i->h = &dir->root;
1878    }
1879
1880  /* Copy over the dynindx.  */
1881
1882  if (ind->root.dynindx != -1)
1883    {
1884      if (dir->root.dynindx != -1)
1885	_bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
1886				dir->root.dynstr_index);
1887      dir->root.dynindx = ind->root.dynindx;
1888      dir->root.dynstr_index = ind->root.dynstr_index;
1889      ind->root.dynindx = -1;
1890      ind->root.dynstr_index = 0;
1891    }
1892}
1893
1894static void
1895elfNN_ia64_hash_hide_symbol (info, xh, force_local)
1896     struct bfd_link_info *info;
1897     struct elf_link_hash_entry *xh;
1898     bfd_boolean force_local;
1899{
1900  struct elfNN_ia64_link_hash_entry *h;
1901  struct elfNN_ia64_dyn_sym_info *dyn_i;
1902  unsigned int count;
1903
1904  h = (struct elfNN_ia64_link_hash_entry *)xh;
1905
1906  _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1907
1908  for (count = h->count, dyn_i = h->info;
1909       count != 0;
1910       count--, dyn_i++)
1911    {
1912      dyn_i->want_plt2 = 0;
1913      dyn_i->want_plt = 0;
1914    }
1915}
1916
1917/* Compute a hash of a local hash entry.  */
1918
1919static hashval_t
1920elfNN_ia64_local_htab_hash (ptr)
1921     const void *ptr;
1922{
1923  struct elfNN_ia64_local_hash_entry *entry
1924    = (struct elfNN_ia64_local_hash_entry *) ptr;
1925
1926  return (((entry->id & 0xff) << 24) | ((entry->id & 0xff00) << 8))
1927	  ^ entry->r_sym ^ (entry->id >> 16);
1928}
1929
1930/* Compare local hash entries.  */
1931
1932static int
1933elfNN_ia64_local_htab_eq (ptr1, ptr2)
1934     const void *ptr1, *ptr2;
1935{
1936  struct elfNN_ia64_local_hash_entry *entry1
1937    = (struct elfNN_ia64_local_hash_entry *) ptr1;
1938  struct elfNN_ia64_local_hash_entry *entry2
1939    = (struct elfNN_ia64_local_hash_entry *) ptr2;
1940
1941  return entry1->id == entry2->id && entry1->r_sym == entry2->r_sym;
1942}
1943
1944/* Create the derived linker hash table.  The IA-64 ELF port uses this
1945   derived hash table to keep information specific to the IA-64 ElF
1946   linker (without using static variables).  */
1947
1948static struct bfd_link_hash_table*
1949elfNN_ia64_hash_table_create (abfd)
1950     bfd *abfd;
1951{
1952  struct elfNN_ia64_link_hash_table *ret;
1953
1954  ret = bfd_zmalloc ((bfd_size_type) sizeof (*ret));
1955  if (!ret)
1956    return 0;
1957
1958  if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1959				      elfNN_ia64_new_elf_hash_entry,
1960				      sizeof (struct elfNN_ia64_link_hash_entry)))
1961    {
1962      free (ret);
1963      return 0;
1964    }
1965
1966  ret->loc_hash_table = htab_try_create (1024, elfNN_ia64_local_htab_hash,
1967					 elfNN_ia64_local_htab_eq, NULL);
1968  ret->loc_hash_memory = objalloc_create ();
1969  if (!ret->loc_hash_table || !ret->loc_hash_memory)
1970    {
1971      free (ret);
1972      return 0;
1973    }
1974
1975  return &ret->root.root;
1976}
1977
1978/* Free the global elfNN_ia64_dyn_sym_info array.  */
1979
1980static bfd_boolean
1981elfNN_ia64_global_dyn_info_free (void **xentry,
1982				PTR unused ATTRIBUTE_UNUSED)
1983{
1984  struct elfNN_ia64_link_hash_entry *entry
1985    = (struct elfNN_ia64_link_hash_entry *) xentry;
1986
1987  if (entry->root.root.type == bfd_link_hash_warning)
1988    entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
1989
1990  if (entry->info)
1991    {
1992      free (entry->info);
1993      entry->info = NULL;
1994      entry->count = 0;
1995      entry->sorted_count = 0;
1996      entry->size = 0;
1997    }
1998
1999  return TRUE;
2000}
2001
2002/* Free the local elfNN_ia64_dyn_sym_info array.  */
2003
2004static bfd_boolean
2005elfNN_ia64_local_dyn_info_free (void **slot,
2006				PTR unused ATTRIBUTE_UNUSED)
2007{
2008  struct elfNN_ia64_local_hash_entry *entry
2009    = (struct elfNN_ia64_local_hash_entry *) *slot;
2010
2011  if (entry->info)
2012    {
2013      free (entry->info);
2014      entry->info = NULL;
2015      entry->count = 0;
2016      entry->sorted_count = 0;
2017      entry->size = 0;
2018    }
2019
2020  return TRUE;
2021}
2022
2023/* Destroy IA-64 linker hash table.  */
2024
2025static void
2026elfNN_ia64_hash_table_free (hash)
2027     struct bfd_link_hash_table *hash;
2028{
2029  struct elfNN_ia64_link_hash_table *ia64_info
2030    = (struct elfNN_ia64_link_hash_table *) hash;
2031  if (ia64_info->loc_hash_table)
2032    {
2033      htab_traverse (ia64_info->loc_hash_table,
2034		     elfNN_ia64_local_dyn_info_free, NULL);
2035      htab_delete (ia64_info->loc_hash_table);
2036    }
2037  if (ia64_info->loc_hash_memory)
2038    objalloc_free ((struct objalloc *) ia64_info->loc_hash_memory);
2039  elf_link_hash_traverse (&ia64_info->root,
2040			  elfNN_ia64_global_dyn_info_free, NULL);
2041  _bfd_generic_link_hash_table_free (hash);
2042}
2043
2044/* Traverse both local and global hash tables.  */
2045
2046struct elfNN_ia64_dyn_sym_traverse_data
2047{
2048  bfd_boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
2049  PTR data;
2050};
2051
2052static bfd_boolean
2053elfNN_ia64_global_dyn_sym_thunk (xentry, xdata)
2054     struct bfd_hash_entry *xentry;
2055     PTR xdata;
2056{
2057  struct elfNN_ia64_link_hash_entry *entry
2058    = (struct elfNN_ia64_link_hash_entry *) xentry;
2059  struct elfNN_ia64_dyn_sym_traverse_data *data
2060    = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
2061  struct elfNN_ia64_dyn_sym_info *dyn_i;
2062  unsigned int count;
2063
2064  if (entry->root.root.type == bfd_link_hash_warning)
2065    entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
2066
2067  for (count = entry->count, dyn_i = entry->info;
2068       count != 0;
2069       count--, dyn_i++)
2070    if (! (*data->func) (dyn_i, data->data))
2071      return FALSE;
2072  return TRUE;
2073}
2074
2075static bfd_boolean
2076elfNN_ia64_local_dyn_sym_thunk (slot, xdata)
2077     void **slot;
2078     PTR xdata;
2079{
2080  struct elfNN_ia64_local_hash_entry *entry
2081    = (struct elfNN_ia64_local_hash_entry *) *slot;
2082  struct elfNN_ia64_dyn_sym_traverse_data *data
2083    = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
2084  struct elfNN_ia64_dyn_sym_info *dyn_i;
2085  unsigned int count;
2086
2087  for (count = entry->count, dyn_i = entry->info;
2088       count != 0;
2089       count--, dyn_i++)
2090    if (! (*data->func) (dyn_i, data->data))
2091      return FALSE;
2092  return TRUE;
2093}
2094
2095static void
2096elfNN_ia64_dyn_sym_traverse (ia64_info, func, data)
2097     struct elfNN_ia64_link_hash_table *ia64_info;
2098     bfd_boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
2099     PTR data;
2100{
2101  struct elfNN_ia64_dyn_sym_traverse_data xdata;
2102
2103  xdata.func = func;
2104  xdata.data = data;
2105
2106  elf_link_hash_traverse (&ia64_info->root,
2107			  elfNN_ia64_global_dyn_sym_thunk, &xdata);
2108  htab_traverse (ia64_info->loc_hash_table,
2109		 elfNN_ia64_local_dyn_sym_thunk, &xdata);
2110}
2111
2112static bfd_boolean
2113elfNN_ia64_create_dynamic_sections (abfd, info)
2114     bfd *abfd;
2115     struct bfd_link_info *info;
2116{
2117  struct elfNN_ia64_link_hash_table *ia64_info;
2118  asection *s;
2119
2120  if (! _bfd_elf_create_dynamic_sections (abfd, info))
2121    return FALSE;
2122
2123  ia64_info = elfNN_ia64_hash_table (info);
2124
2125  ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
2126  ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
2127
2128  {
2129    flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
2130    bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
2131    /* The .got section is always aligned at 8 bytes.  */
2132    bfd_set_section_alignment (abfd, ia64_info->got_sec, 3);
2133  }
2134
2135  if (!get_pltoff (abfd, info, ia64_info))
2136    return FALSE;
2137
2138  s = bfd_make_section_with_flags (abfd, ".rela.IA_64.pltoff",
2139				   (SEC_ALLOC | SEC_LOAD
2140				    | SEC_HAS_CONTENTS
2141				    | SEC_IN_MEMORY
2142				    | SEC_LINKER_CREATED
2143				    | SEC_READONLY));
2144  if (s == NULL
2145      || !bfd_set_section_alignment (abfd, s, LOG_SECTION_ALIGN))
2146    return FALSE;
2147  ia64_info->rel_pltoff_sec = s;
2148
2149  s = bfd_make_section_with_flags (abfd, ".rela.got",
2150				   (SEC_ALLOC | SEC_LOAD
2151				    | SEC_HAS_CONTENTS
2152				    | SEC_IN_MEMORY
2153				    | SEC_LINKER_CREATED
2154				    | SEC_READONLY));
2155  if (s == NULL
2156      || !bfd_set_section_alignment (abfd, s, LOG_SECTION_ALIGN))
2157    return FALSE;
2158  ia64_info->rel_got_sec = s;
2159
2160  return TRUE;
2161}
2162
2163/* Find and/or create a hash entry for local symbol.  */
2164static struct elfNN_ia64_local_hash_entry *
2165get_local_sym_hash (ia64_info, abfd, rel, create)
2166     struct elfNN_ia64_link_hash_table *ia64_info;
2167     bfd *abfd;
2168     const Elf_Internal_Rela *rel;
2169     bfd_boolean create;
2170{
2171  struct elfNN_ia64_local_hash_entry e, *ret;
2172  asection *sec = abfd->sections;
2173  hashval_t h = (((sec->id & 0xff) << 24) | ((sec->id & 0xff00) << 8))
2174		^ ELFNN_R_SYM (rel->r_info) ^ (sec->id >> 16);
2175  void **slot;
2176
2177  e.id = sec->id;
2178  e.r_sym = ELFNN_R_SYM (rel->r_info);
2179  slot = htab_find_slot_with_hash (ia64_info->loc_hash_table, &e, h,
2180				   create ? INSERT : NO_INSERT);
2181
2182  if (!slot)
2183    return NULL;
2184
2185  if (*slot)
2186    return (struct elfNN_ia64_local_hash_entry *) *slot;
2187
2188  ret = (struct elfNN_ia64_local_hash_entry *)
2189	objalloc_alloc ((struct objalloc *) ia64_info->loc_hash_memory,
2190			sizeof (struct elfNN_ia64_local_hash_entry));
2191  if (ret)
2192    {
2193      memset (ret, 0, sizeof (*ret));
2194      ret->id = sec->id;
2195      ret->r_sym = ELFNN_R_SYM (rel->r_info);
2196      *slot = ret;
2197    }
2198  return ret;
2199}
2200
2201/* Used to sort elfNN_ia64_dyn_sym_info array.  */
2202
2203static int
2204addend_compare (const void *xp, const void *yp)
2205{
2206  const struct elfNN_ia64_dyn_sym_info *x
2207    = (const struct elfNN_ia64_dyn_sym_info *) xp;
2208  const struct elfNN_ia64_dyn_sym_info *y
2209    = (const struct elfNN_ia64_dyn_sym_info *) yp;
2210
2211  return x->addend - y->addend;
2212}
2213
2214/* Sort elfNN_ia64_dyn_sym_info array and remove duplicates.  */
2215
2216static unsigned int
2217sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info *info,
2218		   unsigned int count)
2219{
2220  bfd_vma curr, prev;
2221  unsigned int i, dup, diff, dest, src, len;
2222
2223  qsort (info, count, sizeof (*info), addend_compare);
2224
2225  /* Find the first duplicate.  */
2226  prev = info [0].addend;
2227  for (i = 1; i < count; i++)
2228    {
2229      curr = info [i].addend;
2230      if (curr == prev)
2231	break;
2232      prev = curr;
2233    }
2234
2235  /* Remove duplicates.  */
2236  if (i < count)
2237    {
2238      /* We need to move a block of elements to here.  */
2239      dest = i++;
2240      while (i < count)
2241	{
2242	  curr = info [i].addend;
2243
2244	  /* Move a block of elements whose first one is different from
2245	     the previous.  */
2246	  if (curr == prev)
2247	    {
2248	      for (src = i + 1; src < count; src++)
2249		if (info [src].addend != curr)
2250		  break;
2251	    }
2252	  else
2253	    src = i;
2254
2255	  if (src >= count)
2256	    break;
2257
2258	  /* Find the next duplicate.  */
2259	  prev = info [src].addend;
2260	  for (dup = src + 1; dup < count; dup++)
2261	    {
2262	      curr = info [dup].addend;
2263	      if (curr == prev)
2264		break;
2265	      prev = curr;
2266	    }
2267
2268	  /* How much to move.  */
2269	  len = dup - src;
2270	  i = dup + 1;
2271
2272	  if (len == 1 && dup < count)
2273	    {
2274	      /* If we only move 1 element, we combine it with the next
2275		 one.  Find the next different one.  */
2276	      for (diff = dup + 1, src++; diff < count; diff++, src++)
2277		if (info [diff].addend != curr)
2278		  break;
2279
2280	      if (diff < count)
2281		{
2282		  /* Find the next duplicate.  */
2283		  prev = info [diff].addend;
2284		  for (dup = diff + 1; dup < count; dup++)
2285		    {
2286		      curr = info [dup].addend;
2287		      if (curr == prev)
2288			break;
2289		      prev = curr;
2290		      diff++;
2291		    }
2292
2293		  len = diff - src + 1;
2294		  i = diff + 1;
2295		}
2296	    }
2297
2298	  memmove (&info [dest], &info [src], len * sizeof (*info));
2299
2300	  dest += len;
2301	}
2302
2303      count = dest;
2304    }
2305
2306  return count;
2307}
2308
2309/* Find and/or create a descriptor for dynamic symbol info.  This will
2310   vary based on global or local symbol, and the addend to the reloc.
2311
2312   We don't sort when inserting.  Also, we sort and eliminate
2313   duplicates if there is an unsorted section.  Typically, this will
2314   only happen once, because we do all insertions before lookups.  We
2315   then use bsearch to do a lookup.  This also allows lookups to be
2316   fast.  So we have fast insertion (O(log N) due to duplicate check),
2317   fast lookup (O(log N)) and one sort (O(N log N) expected time).
2318   Previously, all lookups were O(N) because of the use of the linked
2319   list and also all insertions were O(N) because of the check for
2320   duplicates.  There are some complications here because the array
2321   size grows occasionally, which may add an O(N) factor, but this
2322   should be rare.  Also,  we free the excess array allocation, which
2323   requires a copy which is O(N), but this only happens once.  */
2324
2325static struct elfNN_ia64_dyn_sym_info *
2326get_dyn_sym_info (ia64_info, h, abfd, rel, create)
2327     struct elfNN_ia64_link_hash_table *ia64_info;
2328     struct elf_link_hash_entry *h;
2329     bfd *abfd;
2330     const Elf_Internal_Rela *rel;
2331     bfd_boolean create;
2332{
2333  struct elfNN_ia64_dyn_sym_info **info_p, *info, *dyn_i, key;
2334  unsigned int *count_p, *sorted_count_p, *size_p;
2335  unsigned int count, sorted_count, size;
2336  bfd_vma addend = rel ? rel->r_addend : 0;
2337  bfd_size_type amt;
2338
2339  if (h)
2340    {
2341      struct elfNN_ia64_link_hash_entry *global_h;
2342
2343      global_h = (struct elfNN_ia64_link_hash_entry *) h;
2344      info_p = &global_h->info;
2345      count_p = &global_h->count;
2346      sorted_count_p = &global_h->sorted_count;
2347      size_p = &global_h->size;
2348    }
2349  else
2350    {
2351      struct elfNN_ia64_local_hash_entry *loc_h;
2352
2353      loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
2354      if (!loc_h)
2355	{
2356	  BFD_ASSERT (!create);
2357	  return NULL;
2358	}
2359
2360      info_p = &loc_h->info;
2361      count_p = &loc_h->count;
2362      sorted_count_p = &loc_h->sorted_count;
2363      size_p = &loc_h->size;
2364    }
2365
2366  count = *count_p;
2367  sorted_count = *sorted_count_p;
2368  size = *size_p;
2369  info = *info_p;
2370  if (create)
2371    {
2372      /* When we create the array, we don't check for duplicates,
2373         except in the previously sorted section if one exists, and
2374	 against the last inserted entry.  This allows insertions to
2375	 be fast.  */
2376      if (info)
2377	{
2378	  if (sorted_count)
2379	    {
2380	      /* Try bsearch first on the sorted section.  */
2381	      key.addend = addend;
2382	      dyn_i = bsearch (&key, info, sorted_count,
2383			       sizeof (*info), addend_compare);
2384
2385	      if (dyn_i)
2386		{
2387		  return dyn_i;
2388		}
2389	    }
2390
2391	  /* Do a quick check for the last inserted entry.  */
2392	  dyn_i = info + count - 1;
2393	  if (dyn_i->addend == addend)
2394	    {
2395	      return dyn_i;
2396	    }
2397	}
2398
2399      if (size == 0)
2400	{
2401	  /* It is the very first element. We create the array of size
2402	     1.  */
2403	  size = 1;
2404	  amt = size * sizeof (*info);
2405	  info = bfd_malloc (amt);
2406	}
2407      else if (size <= count)
2408	{
2409	  /* We double the array size every time when we reach the
2410	     size limit.  */
2411	  size += size;
2412	  amt = size * sizeof (*info);
2413	  info = bfd_realloc (info, amt);
2414	}
2415      else
2416	goto has_space;
2417
2418      if (info == NULL)
2419	return NULL;
2420      *size_p = size;
2421      *info_p = info;
2422
2423has_space:
2424      /* Append the new one to the array.  */
2425      dyn_i = info + count;
2426      memset (dyn_i, 0, sizeof (*dyn_i));
2427      dyn_i->addend = addend;
2428
2429      /* We increment count only since the new ones are unsorted and
2430	 may have duplicate.  */
2431      (*count_p)++;
2432    }
2433  else
2434    {
2435      /* It is a lookup without insertion.  Sort array if part of the
2436	 array isn't sorted.  */
2437      if (count != sorted_count)
2438	{
2439	  count = sort_dyn_sym_info (info, count);
2440	  *count_p = count;
2441	  *sorted_count_p = count;
2442	}
2443
2444      /* Free unused memory.  */
2445      if (size != count)
2446	{
2447	  amt = count * sizeof (*info);
2448	  info = bfd_malloc (amt);
2449	  if (info != NULL)
2450	    {
2451	      memcpy (info, *info_p, amt);
2452	      free (*info_p);
2453	      *size_p = count;
2454	      *info_p = info;
2455	    }
2456	}
2457
2458      key.addend = addend;
2459      dyn_i = bsearch (&key, info, count,
2460		       sizeof (*info), addend_compare);
2461    }
2462
2463  return dyn_i;
2464}
2465
2466static asection *
2467get_got (abfd, info, ia64_info)
2468     bfd *abfd;
2469     struct bfd_link_info *info;
2470     struct elfNN_ia64_link_hash_table *ia64_info;
2471{
2472  asection *got;
2473  bfd *dynobj;
2474
2475  got = ia64_info->got_sec;
2476  if (!got)
2477    {
2478      flagword flags;
2479
2480      dynobj = ia64_info->root.dynobj;
2481      if (!dynobj)
2482	ia64_info->root.dynobj = dynobj = abfd;
2483      if (!_bfd_elf_create_got_section (dynobj, info))
2484	return 0;
2485
2486      got = bfd_get_section_by_name (dynobj, ".got");
2487      BFD_ASSERT (got);
2488      ia64_info->got_sec = got;
2489
2490      /* The .got section is always aligned at 8 bytes.  */
2491      if (!bfd_set_section_alignment (abfd, got, 3))
2492	return 0;
2493
2494      flags = bfd_get_section_flags (abfd, got);
2495      bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
2496    }
2497
2498  return got;
2499}
2500
2501/* Create function descriptor section (.opd).  This section is called .opd
2502   because it contains "official procedure descriptors".  The "official"
2503   refers to the fact that these descriptors are used when taking the address
2504   of a procedure, thus ensuring a unique address for each procedure.  */
2505
2506static asection *
2507get_fptr (abfd, info, ia64_info)
2508     bfd *abfd;
2509     struct bfd_link_info *info;
2510     struct elfNN_ia64_link_hash_table *ia64_info;
2511{
2512  asection *fptr;
2513  bfd *dynobj;
2514
2515  fptr = ia64_info->fptr_sec;
2516  if (!fptr)
2517    {
2518      dynobj = ia64_info->root.dynobj;
2519      if (!dynobj)
2520	ia64_info->root.dynobj = dynobj = abfd;
2521
2522      fptr = bfd_make_section_with_flags (dynobj, ".opd",
2523					  (SEC_ALLOC
2524					   | SEC_LOAD
2525					   | SEC_HAS_CONTENTS
2526					   | SEC_IN_MEMORY
2527					   | (info->pie ? 0 : SEC_READONLY)
2528					   | SEC_LINKER_CREATED));
2529      if (!fptr
2530	  || !bfd_set_section_alignment (abfd, fptr, 4))
2531	{
2532	  BFD_ASSERT (0);
2533	  return NULL;
2534	}
2535
2536      ia64_info->fptr_sec = fptr;
2537
2538      if (info->pie)
2539	{
2540	  asection *fptr_rel;
2541	  fptr_rel = bfd_make_section_with_flags (dynobj, ".rela.opd",
2542						  (SEC_ALLOC | SEC_LOAD
2543						   | SEC_HAS_CONTENTS
2544						   | SEC_IN_MEMORY
2545						   | SEC_LINKER_CREATED
2546						   | SEC_READONLY));
2547	  if (fptr_rel == NULL
2548	      || !bfd_set_section_alignment (abfd, fptr_rel,
2549					     LOG_SECTION_ALIGN))
2550	    {
2551	      BFD_ASSERT (0);
2552	      return NULL;
2553	    }
2554
2555	  ia64_info->rel_fptr_sec = fptr_rel;
2556	}
2557    }
2558
2559  return fptr;
2560}
2561
2562static asection *
2563get_pltoff (abfd, info, ia64_info)
2564     bfd *abfd;
2565     struct bfd_link_info *info ATTRIBUTE_UNUSED;
2566     struct elfNN_ia64_link_hash_table *ia64_info;
2567{
2568  asection *pltoff;
2569  bfd *dynobj;
2570
2571  pltoff = ia64_info->pltoff_sec;
2572  if (!pltoff)
2573    {
2574      dynobj = ia64_info->root.dynobj;
2575      if (!dynobj)
2576	ia64_info->root.dynobj = dynobj = abfd;
2577
2578      pltoff = bfd_make_section_with_flags (dynobj,
2579					    ELF_STRING_ia64_pltoff,
2580					    (SEC_ALLOC
2581					     | SEC_LOAD
2582					     | SEC_HAS_CONTENTS
2583					     | SEC_IN_MEMORY
2584					     | SEC_SMALL_DATA
2585					     | SEC_LINKER_CREATED));
2586      if (!pltoff
2587	  || !bfd_set_section_alignment (abfd, pltoff, 4))
2588	{
2589	  BFD_ASSERT (0);
2590	  return NULL;
2591	}
2592
2593      ia64_info->pltoff_sec = pltoff;
2594    }
2595
2596  return pltoff;
2597}
2598
2599static asection *
2600get_reloc_section (abfd, ia64_info, sec, create)
2601     bfd *abfd;
2602     struct elfNN_ia64_link_hash_table *ia64_info;
2603     asection *sec;
2604     bfd_boolean create;
2605{
2606  const char *srel_name;
2607  asection *srel;
2608  bfd *dynobj;
2609
2610  srel_name = (bfd_elf_string_from_elf_section
2611	       (abfd, elf_elfheader(abfd)->e_shstrndx,
2612		elf_section_data(sec)->rel_hdr.sh_name));
2613  if (srel_name == NULL)
2614    return NULL;
2615
2616  BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0
2617	       && strcmp (bfd_get_section_name (abfd, sec),
2618			  srel_name+5) == 0)
2619	      || (strncmp (srel_name, ".rel", 4) == 0
2620		  && strcmp (bfd_get_section_name (abfd, sec),
2621			     srel_name+4) == 0));
2622
2623  dynobj = ia64_info->root.dynobj;
2624  if (!dynobj)
2625    ia64_info->root.dynobj = dynobj = abfd;
2626
2627  srel = bfd_get_section_by_name (dynobj, srel_name);
2628  if (srel == NULL && create)
2629    {
2630      srel = bfd_make_section_with_flags (dynobj, srel_name,
2631					  (SEC_ALLOC | SEC_LOAD
2632					   | SEC_HAS_CONTENTS
2633					   | SEC_IN_MEMORY
2634					   | SEC_LINKER_CREATED
2635					   | SEC_READONLY));
2636      if (srel == NULL
2637	  || !bfd_set_section_alignment (dynobj, srel,
2638					 LOG_SECTION_ALIGN))
2639	return NULL;
2640    }
2641
2642  return srel;
2643}
2644
2645static bfd_boolean
2646count_dyn_reloc (bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
2647		 asection *srel, int type, bfd_boolean reltext)
2648{
2649  struct elfNN_ia64_dyn_reloc_entry *rent;
2650
2651  for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2652    if (rent->srel == srel && rent->type == type)
2653      break;
2654
2655  if (!rent)
2656    {
2657      rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2658	      bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
2659      if (!rent)
2660	return FALSE;
2661
2662      rent->next = dyn_i->reloc_entries;
2663      rent->srel = srel;
2664      rent->type = type;
2665      rent->count = 0;
2666      dyn_i->reloc_entries = rent;
2667    }
2668  rent->reltext = reltext;
2669  rent->count++;
2670
2671  return TRUE;
2672}
2673
2674static bfd_boolean
2675elfNN_ia64_check_relocs (abfd, info, sec, relocs)
2676     bfd *abfd;
2677     struct bfd_link_info *info;
2678     asection *sec;
2679     const Elf_Internal_Rela *relocs;
2680{
2681  struct elfNN_ia64_link_hash_table *ia64_info;
2682  const Elf_Internal_Rela *relend;
2683  Elf_Internal_Shdr *symtab_hdr;
2684  const Elf_Internal_Rela *rel;
2685  asection *got, *fptr, *srel, *pltoff;
2686  enum {
2687    NEED_GOT = 1,
2688    NEED_GOTX = 2,
2689    NEED_FPTR = 4,
2690    NEED_PLTOFF = 8,
2691    NEED_MIN_PLT = 16,
2692    NEED_FULL_PLT = 32,
2693    NEED_DYNREL = 64,
2694    NEED_LTOFF_FPTR = 128,
2695    NEED_TPREL = 256,
2696    NEED_DTPMOD = 512,
2697    NEED_DTPREL = 1024
2698  };
2699  int need_entry;
2700  struct elf_link_hash_entry *h;
2701  unsigned long r_symndx;
2702  bfd_boolean maybe_dynamic;
2703
2704  if (info->relocatable)
2705    return TRUE;
2706
2707  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2708  ia64_info = elfNN_ia64_hash_table (info);
2709
2710  got = fptr = srel = pltoff = NULL;
2711
2712  relend = relocs + sec->reloc_count;
2713
2714  /* We scan relocations first to create dynamic relocation arrays.  We
2715     modified get_dyn_sym_info to allow fast insertion and support fast
2716     lookup in the next loop.  */
2717  for (rel = relocs; rel < relend; ++rel)
2718    {
2719      r_symndx = ELFNN_R_SYM (rel->r_info);
2720      if (r_symndx >= symtab_hdr->sh_info)
2721	{
2722	  long indx = r_symndx - symtab_hdr->sh_info;
2723	  h = elf_sym_hashes (abfd)[indx];
2724	  while (h->root.type == bfd_link_hash_indirect
2725		 || h->root.type == bfd_link_hash_warning)
2726	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
2727	}
2728      else
2729	h = NULL;
2730
2731      /* We can only get preliminary data on whether a symbol is
2732	 locally or externally defined, as not all of the input files
2733	 have yet been processed.  Do something with what we know, as
2734	 this may help reduce memory usage and processing time later.  */
2735      maybe_dynamic = (h && ((!info->executable
2736			      && (!info->symbolic
2737				  || info->unresolved_syms_in_shared_libs == RM_IGNORE))
2738			     || !h->def_regular
2739			     || h->root.type == bfd_link_hash_defweak));
2740
2741      need_entry = 0;
2742      switch (ELFNN_R_TYPE (rel->r_info))
2743	{
2744	case R_IA64_TPREL64MSB:
2745	case R_IA64_TPREL64LSB:
2746	  if (info->shared || maybe_dynamic)
2747	    need_entry = NEED_DYNREL;
2748	  break;
2749
2750	case R_IA64_LTOFF_TPREL22:
2751	  need_entry = NEED_TPREL;
2752	  if (info->shared)
2753	    info->flags |= DF_STATIC_TLS;
2754	  break;
2755
2756	case R_IA64_DTPREL32MSB:
2757	case R_IA64_DTPREL32LSB:
2758	case R_IA64_DTPREL64MSB:
2759	case R_IA64_DTPREL64LSB:
2760	  if (info->shared || maybe_dynamic)
2761	    need_entry = NEED_DYNREL;
2762	  break;
2763
2764	case R_IA64_LTOFF_DTPREL22:
2765	  need_entry = NEED_DTPREL;
2766	  break;
2767
2768	case R_IA64_DTPMOD64MSB:
2769	case R_IA64_DTPMOD64LSB:
2770	  if (info->shared || maybe_dynamic)
2771	    need_entry = NEED_DYNREL;
2772	  break;
2773
2774	case R_IA64_LTOFF_DTPMOD22:
2775	  need_entry = NEED_DTPMOD;
2776	  break;
2777
2778	case R_IA64_LTOFF_FPTR22:
2779	case R_IA64_LTOFF_FPTR64I:
2780	case R_IA64_LTOFF_FPTR32MSB:
2781	case R_IA64_LTOFF_FPTR32LSB:
2782	case R_IA64_LTOFF_FPTR64MSB:
2783	case R_IA64_LTOFF_FPTR64LSB:
2784	  need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2785	  break;
2786
2787	case R_IA64_FPTR64I:
2788	case R_IA64_FPTR32MSB:
2789	case R_IA64_FPTR32LSB:
2790	case R_IA64_FPTR64MSB:
2791	case R_IA64_FPTR64LSB:
2792	  if (info->shared || h)
2793	    need_entry = NEED_FPTR | NEED_DYNREL;
2794	  else
2795	    need_entry = NEED_FPTR;
2796	  break;
2797
2798	case R_IA64_LTOFF22:
2799	case R_IA64_LTOFF64I:
2800	  need_entry = NEED_GOT;
2801	  break;
2802
2803	case R_IA64_LTOFF22X:
2804	  need_entry = NEED_GOTX;
2805	  break;
2806
2807	case R_IA64_PLTOFF22:
2808	case R_IA64_PLTOFF64I:
2809	case R_IA64_PLTOFF64MSB:
2810	case R_IA64_PLTOFF64LSB:
2811	  need_entry = NEED_PLTOFF;
2812	  if (h)
2813	    {
2814	      if (maybe_dynamic)
2815		need_entry |= NEED_MIN_PLT;
2816	    }
2817	  else
2818	    {
2819	      (*info->callbacks->warning)
2820		(info, _("@pltoff reloc against local symbol"), 0,
2821		 abfd, 0, (bfd_vma) 0);
2822	    }
2823	  break;
2824
2825	case R_IA64_PCREL21B:
2826        case R_IA64_PCREL60B:
2827	  /* Depending on where this symbol is defined, we may or may not
2828	     need a full plt entry.  Only skip if we know we'll not need
2829	     the entry -- static or symbolic, and the symbol definition
2830	     has already been seen.  */
2831	  if (maybe_dynamic && rel->r_addend == 0)
2832	    need_entry = NEED_FULL_PLT;
2833	  break;
2834
2835	case R_IA64_IMM14:
2836	case R_IA64_IMM22:
2837	case R_IA64_IMM64:
2838	case R_IA64_DIR32MSB:
2839	case R_IA64_DIR32LSB:
2840	case R_IA64_DIR64MSB:
2841	case R_IA64_DIR64LSB:
2842	  /* Shared objects will always need at least a REL relocation.  */
2843	  if (info->shared || maybe_dynamic)
2844	    need_entry = NEED_DYNREL;
2845	  break;
2846
2847	case R_IA64_IPLTMSB:
2848	case R_IA64_IPLTLSB:
2849	  /* Shared objects will always need at least a REL relocation.  */
2850	  if (info->shared || maybe_dynamic)
2851	    need_entry = NEED_DYNREL;
2852	  break;
2853
2854	case R_IA64_PCREL22:
2855	case R_IA64_PCREL64I:
2856	case R_IA64_PCREL32MSB:
2857	case R_IA64_PCREL32LSB:
2858	case R_IA64_PCREL64MSB:
2859	case R_IA64_PCREL64LSB:
2860	  if (maybe_dynamic)
2861	    need_entry = NEED_DYNREL;
2862	  break;
2863	}
2864
2865      if (!need_entry)
2866	continue;
2867
2868      if ((need_entry & NEED_FPTR) != 0
2869	  && rel->r_addend)
2870	{
2871	  (*info->callbacks->warning)
2872	    (info, _("non-zero addend in @fptr reloc"), 0,
2873	     abfd, 0, (bfd_vma) 0);
2874	}
2875
2876      if (get_dyn_sym_info (ia64_info, h, abfd, rel, TRUE) == NULL)
2877	return FALSE;
2878    }
2879
2880  /* Now, we only do lookup without insertion, which is very fast
2881     with the modified get_dyn_sym_info.  */
2882  for (rel = relocs; rel < relend; ++rel)
2883    {
2884      struct elfNN_ia64_dyn_sym_info *dyn_i;
2885      int dynrel_type = R_IA64_NONE;
2886
2887      r_symndx = ELFNN_R_SYM (rel->r_info);
2888      if (r_symndx >= symtab_hdr->sh_info)
2889	{
2890	  /* We're dealing with a global symbol -- find its hash entry
2891	     and mark it as being referenced.  */
2892	  long indx = r_symndx - symtab_hdr->sh_info;
2893	  h = elf_sym_hashes (abfd)[indx];
2894	  while (h->root.type == bfd_link_hash_indirect
2895		 || h->root.type == bfd_link_hash_warning)
2896	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
2897
2898	  h->ref_regular = 1;
2899	}
2900      else
2901	h = NULL;
2902
2903      /* We can only get preliminary data on whether a symbol is
2904	 locally or externally defined, as not all of the input files
2905	 have yet been processed.  Do something with what we know, as
2906	 this may help reduce memory usage and processing time later.  */
2907      maybe_dynamic = (h && ((!info->executable
2908			      && (!info->symbolic
2909				  || info->unresolved_syms_in_shared_libs == RM_IGNORE))
2910			     || !h->def_regular
2911			     || h->root.type == bfd_link_hash_defweak));
2912
2913      need_entry = 0;
2914      switch (ELFNN_R_TYPE (rel->r_info))
2915	{
2916	case R_IA64_TPREL64MSB:
2917	case R_IA64_TPREL64LSB:
2918	  if (info->shared || maybe_dynamic)
2919	    need_entry = NEED_DYNREL;
2920	  dynrel_type = R_IA64_TPREL64LSB;
2921	  if (info->shared)
2922	    info->flags |= DF_STATIC_TLS;
2923	  break;
2924
2925	case R_IA64_LTOFF_TPREL22:
2926	  need_entry = NEED_TPREL;
2927	  if (info->shared)
2928	    info->flags |= DF_STATIC_TLS;
2929	  break;
2930
2931	case R_IA64_DTPREL32MSB:
2932	case R_IA64_DTPREL32LSB:
2933	case R_IA64_DTPREL64MSB:
2934	case R_IA64_DTPREL64LSB:
2935	  if (info->shared || maybe_dynamic)
2936	    need_entry = NEED_DYNREL;
2937	  dynrel_type = R_IA64_DTPRELNNLSB;
2938	  break;
2939
2940	case R_IA64_LTOFF_DTPREL22:
2941	  need_entry = NEED_DTPREL;
2942	  break;
2943
2944	case R_IA64_DTPMOD64MSB:
2945	case R_IA64_DTPMOD64LSB:
2946	  if (info->shared || maybe_dynamic)
2947	    need_entry = NEED_DYNREL;
2948	  dynrel_type = R_IA64_DTPMOD64LSB;
2949	  break;
2950
2951	case R_IA64_LTOFF_DTPMOD22:
2952	  need_entry = NEED_DTPMOD;
2953	  break;
2954
2955	case R_IA64_LTOFF_FPTR22:
2956	case R_IA64_LTOFF_FPTR64I:
2957	case R_IA64_LTOFF_FPTR32MSB:
2958	case R_IA64_LTOFF_FPTR32LSB:
2959	case R_IA64_LTOFF_FPTR64MSB:
2960	case R_IA64_LTOFF_FPTR64LSB:
2961	  need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2962	  break;
2963
2964	case R_IA64_FPTR64I:
2965	case R_IA64_FPTR32MSB:
2966	case R_IA64_FPTR32LSB:
2967	case R_IA64_FPTR64MSB:
2968	case R_IA64_FPTR64LSB:
2969	  if (info->shared || h)
2970	    need_entry = NEED_FPTR | NEED_DYNREL;
2971	  else
2972	    need_entry = NEED_FPTR;
2973	  dynrel_type = R_IA64_FPTRNNLSB;
2974	  break;
2975
2976	case R_IA64_LTOFF22:
2977	case R_IA64_LTOFF64I:
2978	  need_entry = NEED_GOT;
2979	  break;
2980
2981	case R_IA64_LTOFF22X:
2982	  need_entry = NEED_GOTX;
2983	  break;
2984
2985	case R_IA64_PLTOFF22:
2986	case R_IA64_PLTOFF64I:
2987	case R_IA64_PLTOFF64MSB:
2988	case R_IA64_PLTOFF64LSB:
2989	  need_entry = NEED_PLTOFF;
2990	  if (h)
2991	    {
2992	      if (maybe_dynamic)
2993		need_entry |= NEED_MIN_PLT;
2994	    }
2995	  break;
2996
2997	case R_IA64_PCREL21B:
2998        case R_IA64_PCREL60B:
2999	  /* Depending on where this symbol is defined, we may or may not
3000	     need a full plt entry.  Only skip if we know we'll not need
3001	     the entry -- static or symbolic, and the symbol definition
3002	     has already been seen.  */
3003	  if (maybe_dynamic && rel->r_addend == 0)
3004	    need_entry = NEED_FULL_PLT;
3005	  break;
3006
3007	case R_IA64_IMM14:
3008	case R_IA64_IMM22:
3009	case R_IA64_IMM64:
3010	case R_IA64_DIR32MSB:
3011	case R_IA64_DIR32LSB:
3012	case R_IA64_DIR64MSB:
3013	case R_IA64_DIR64LSB:
3014	  /* Shared objects will always need at least a REL relocation.  */
3015	  if (info->shared || maybe_dynamic)
3016	    need_entry = NEED_DYNREL;
3017	  dynrel_type = R_IA64_DIRNNLSB;
3018	  break;
3019
3020	case R_IA64_IPLTMSB:
3021	case R_IA64_IPLTLSB:
3022	  /* Shared objects will always need at least a REL relocation.  */
3023	  if (info->shared || maybe_dynamic)
3024	    need_entry = NEED_DYNREL;
3025	  dynrel_type = R_IA64_IPLTLSB;
3026	  break;
3027
3028	case R_IA64_PCREL22:
3029	case R_IA64_PCREL64I:
3030	case R_IA64_PCREL32MSB:
3031	case R_IA64_PCREL32LSB:
3032	case R_IA64_PCREL64MSB:
3033	case R_IA64_PCREL64LSB:
3034	  if (maybe_dynamic)
3035	    need_entry = NEED_DYNREL;
3036	  dynrel_type = R_IA64_PCRELNNLSB;
3037	  break;
3038	}
3039
3040      if (!need_entry)
3041	continue;
3042
3043      dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, FALSE);
3044
3045      /* Record whether or not this is a local symbol.  */
3046      dyn_i->h = h;
3047
3048      /* Create what's needed.  */
3049      if (need_entry & (NEED_GOT | NEED_GOTX | NEED_TPREL
3050			| NEED_DTPMOD | NEED_DTPREL))
3051	{
3052	  if (!got)
3053	    {
3054	      got = get_got (abfd, info, ia64_info);
3055	      if (!got)
3056		return FALSE;
3057	    }
3058	  if (need_entry & NEED_GOT)
3059	    dyn_i->want_got = 1;
3060	  if (need_entry & NEED_GOTX)
3061	    dyn_i->want_gotx = 1;
3062	  if (need_entry & NEED_TPREL)
3063	    dyn_i->want_tprel = 1;
3064	  if (need_entry & NEED_DTPMOD)
3065	    dyn_i->want_dtpmod = 1;
3066	  if (need_entry & NEED_DTPREL)
3067	    dyn_i->want_dtprel = 1;
3068	}
3069      if (need_entry & NEED_FPTR)
3070	{
3071	  if (!fptr)
3072	    {
3073	      fptr = get_fptr (abfd, info, ia64_info);
3074	      if (!fptr)
3075		return FALSE;
3076	    }
3077
3078	  /* FPTRs for shared libraries are allocated by the dynamic
3079	     linker.  Make sure this local symbol will appear in the
3080	     dynamic symbol table.  */
3081	  if (!h && info->shared)
3082	    {
3083	      if (! (bfd_elf_link_record_local_dynamic_symbol
3084		     (info, abfd, (long) r_symndx)))
3085		return FALSE;
3086	    }
3087
3088	  dyn_i->want_fptr = 1;
3089	}
3090      if (need_entry & NEED_LTOFF_FPTR)
3091	dyn_i->want_ltoff_fptr = 1;
3092      if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
3093	{
3094          if (!ia64_info->root.dynobj)
3095	    ia64_info->root.dynobj = abfd;
3096	  h->needs_plt = 1;
3097	  dyn_i->want_plt = 1;
3098	}
3099      if (need_entry & NEED_FULL_PLT)
3100	dyn_i->want_plt2 = 1;
3101      if (need_entry & NEED_PLTOFF)
3102	{
3103	  /* This is needed here, in case @pltoff is used in a non-shared
3104	     link.  */
3105	  if (!pltoff)
3106	    {
3107	      pltoff = get_pltoff (abfd, info, ia64_info);
3108	      if (!pltoff)
3109		return FALSE;
3110	    }
3111
3112	  dyn_i->want_pltoff = 1;
3113	}
3114      if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
3115	{
3116	  if (!srel)
3117	    {
3118	      srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
3119	      if (!srel)
3120		return FALSE;
3121	    }
3122	  if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type,
3123				(sec->flags & SEC_READONLY) != 0))
3124	    return FALSE;
3125	}
3126    }
3127
3128  return TRUE;
3129}
3130
3131/* For cleanliness, and potentially faster dynamic loading, allocate
3132   external GOT entries first.  */
3133
3134static bfd_boolean
3135allocate_global_data_got (dyn_i, data)
3136     struct elfNN_ia64_dyn_sym_info *dyn_i;
3137     PTR data;
3138{
3139  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3140
3141  if ((dyn_i->want_got || dyn_i->want_gotx)
3142      && ! dyn_i->want_fptr
3143      && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
3144     {
3145       dyn_i->got_offset = x->ofs;
3146       x->ofs += 8;
3147     }
3148  if (dyn_i->want_tprel)
3149    {
3150      dyn_i->tprel_offset = x->ofs;
3151      x->ofs += 8;
3152    }
3153  if (dyn_i->want_dtpmod)
3154    {
3155      if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
3156	{
3157	  dyn_i->dtpmod_offset = x->ofs;
3158	  x->ofs += 8;
3159	}
3160      else
3161	{
3162	  struct elfNN_ia64_link_hash_table *ia64_info;
3163
3164	  ia64_info = elfNN_ia64_hash_table (x->info);
3165	  if (ia64_info->self_dtpmod_offset == (bfd_vma) -1)
3166	    {
3167	      ia64_info->self_dtpmod_offset = x->ofs;
3168	      x->ofs += 8;
3169	    }
3170	  dyn_i->dtpmod_offset = ia64_info->self_dtpmod_offset;
3171	}
3172    }
3173  if (dyn_i->want_dtprel)
3174    {
3175      dyn_i->dtprel_offset = x->ofs;
3176      x->ofs += 8;
3177    }
3178  return TRUE;
3179}
3180
3181/* Next, allocate all the GOT entries used by LTOFF_FPTR relocs.  */
3182
3183static bfd_boolean
3184allocate_global_fptr_got (dyn_i, data)
3185     struct elfNN_ia64_dyn_sym_info *dyn_i;
3186     PTR data;
3187{
3188  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3189
3190  if (dyn_i->want_got
3191      && dyn_i->want_fptr
3192      && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, R_IA64_FPTRNNLSB))
3193    {
3194      dyn_i->got_offset = x->ofs;
3195      x->ofs += 8;
3196    }
3197  return TRUE;
3198}
3199
3200/* Lastly, allocate all the GOT entries for local data.  */
3201
3202static bfd_boolean
3203allocate_local_got (dyn_i, data)
3204     struct elfNN_ia64_dyn_sym_info *dyn_i;
3205     PTR data;
3206{
3207  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3208
3209  if ((dyn_i->want_got || dyn_i->want_gotx)
3210      && !elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
3211    {
3212      dyn_i->got_offset = x->ofs;
3213      x->ofs += 8;
3214    }
3215  return TRUE;
3216}
3217
3218/* Search for the index of a global symbol in it's defining object file.  */
3219
3220static long
3221global_sym_index (h)
3222     struct elf_link_hash_entry *h;
3223{
3224  struct elf_link_hash_entry **p;
3225  bfd *obj;
3226
3227  BFD_ASSERT (h->root.type == bfd_link_hash_defined
3228	      || h->root.type == bfd_link_hash_defweak);
3229
3230  obj = h->root.u.def.section->owner;
3231  for (p = elf_sym_hashes (obj); *p != h; ++p)
3232    continue;
3233
3234  return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
3235}
3236
3237/* Allocate function descriptors.  We can do these for every function
3238   in a main executable that is not exported.  */
3239
3240static bfd_boolean
3241allocate_fptr (dyn_i, data)
3242     struct elfNN_ia64_dyn_sym_info *dyn_i;
3243     PTR data;
3244{
3245  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3246
3247  if (dyn_i->want_fptr)
3248    {
3249      struct elf_link_hash_entry *h = dyn_i->h;
3250
3251      if (h)
3252	while (h->root.type == bfd_link_hash_indirect
3253	       || h->root.type == bfd_link_hash_warning)
3254	  h = (struct elf_link_hash_entry *) h->root.u.i.link;
3255
3256      if (!x->info->executable
3257	  && (!h
3258	      || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
3259	      || (h->root.type != bfd_link_hash_undefweak
3260		  && h->root.type != bfd_link_hash_undefined)))
3261	{
3262	  if (h && h->dynindx == -1)
3263	    {
3264	      BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
3265			  || (h->root.type == bfd_link_hash_defweak));
3266
3267	      if (!bfd_elf_link_record_local_dynamic_symbol
3268		    (x->info, h->root.u.def.section->owner,
3269		     global_sym_index (h)))
3270		return FALSE;
3271	    }
3272
3273	  dyn_i->want_fptr = 0;
3274	}
3275      else if (h == NULL || h->dynindx == -1)
3276	{
3277	  dyn_i->fptr_offset = x->ofs;
3278	  x->ofs += 16;
3279	}
3280      else
3281	dyn_i->want_fptr = 0;
3282    }
3283  return TRUE;
3284}
3285
3286/* Allocate all the minimal PLT entries.  */
3287
3288static bfd_boolean
3289allocate_plt_entries (dyn_i, data)
3290     struct elfNN_ia64_dyn_sym_info *dyn_i;
3291     PTR data;
3292{
3293  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3294
3295  if (dyn_i->want_plt)
3296    {
3297      struct elf_link_hash_entry *h = dyn_i->h;
3298
3299      if (h)
3300	while (h->root.type == bfd_link_hash_indirect
3301	       || h->root.type == bfd_link_hash_warning)
3302	  h = (struct elf_link_hash_entry *) h->root.u.i.link;
3303
3304      /* ??? Versioned symbols seem to lose NEEDS_PLT.  */
3305      if (elfNN_ia64_dynamic_symbol_p (h, x->info, 0))
3306	{
3307	  bfd_size_type offset = x->ofs;
3308	  if (offset == 0)
3309	    offset = PLT_HEADER_SIZE;
3310	  dyn_i->plt_offset = offset;
3311	  x->ofs = offset + PLT_MIN_ENTRY_SIZE;
3312
3313	  dyn_i->want_pltoff = 1;
3314	}
3315      else
3316	{
3317	  dyn_i->want_plt = 0;
3318	  dyn_i->want_plt2 = 0;
3319	}
3320    }
3321  return TRUE;
3322}
3323
3324/* Allocate all the full PLT entries.  */
3325
3326static bfd_boolean
3327allocate_plt2_entries (dyn_i, data)
3328     struct elfNN_ia64_dyn_sym_info *dyn_i;
3329     PTR data;
3330{
3331  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3332
3333  if (dyn_i->want_plt2)
3334    {
3335      struct elf_link_hash_entry *h = dyn_i->h;
3336      bfd_size_type ofs = x->ofs;
3337
3338      dyn_i->plt2_offset = ofs;
3339      x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
3340
3341      while (h->root.type == bfd_link_hash_indirect
3342	     || h->root.type == bfd_link_hash_warning)
3343	h = (struct elf_link_hash_entry *) h->root.u.i.link;
3344      dyn_i->h->plt.offset = ofs;
3345    }
3346  return TRUE;
3347}
3348
3349/* Allocate all the PLTOFF entries requested by relocations and
3350   plt entries.  We can't share space with allocated FPTR entries,
3351   because the latter are not necessarily addressable by the GP.
3352   ??? Relaxation might be able to determine that they are.  */
3353
3354static bfd_boolean
3355allocate_pltoff_entries (dyn_i, data)
3356     struct elfNN_ia64_dyn_sym_info *dyn_i;
3357     PTR data;
3358{
3359  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3360
3361  if (dyn_i->want_pltoff)
3362    {
3363      dyn_i->pltoff_offset = x->ofs;
3364      x->ofs += 16;
3365    }
3366  return TRUE;
3367}
3368
3369/* Allocate dynamic relocations for those symbols that turned out
3370   to be dynamic.  */
3371
3372static bfd_boolean
3373allocate_dynrel_entries (dyn_i, data)
3374     struct elfNN_ia64_dyn_sym_info *dyn_i;
3375     PTR data;
3376{
3377  struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3378  struct elfNN_ia64_link_hash_table *ia64_info;
3379  struct elfNN_ia64_dyn_reloc_entry *rent;
3380  bfd_boolean dynamic_symbol, shared, resolved_zero;
3381
3382  ia64_info = elfNN_ia64_hash_table (x->info);
3383
3384  /* Note that this can't be used in relation to FPTR relocs below.  */
3385  dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0);
3386
3387  shared = x->info->shared;
3388  resolved_zero = (dyn_i->h
3389		   && ELF_ST_VISIBILITY (dyn_i->h->other)
3390		   && dyn_i->h->root.type == bfd_link_hash_undefweak);
3391
3392  /* Take care of the GOT and PLT relocations.  */
3393
3394  if ((!resolved_zero
3395       && (dynamic_symbol || shared)
3396       && (dyn_i->want_got || dyn_i->want_gotx))
3397      || (dyn_i->want_ltoff_fptr
3398	  && dyn_i->h
3399	  && dyn_i->h->dynindx != -1))
3400    {
3401      if (!dyn_i->want_ltoff_fptr
3402	  || !x->info->pie
3403	  || dyn_i->h == NULL
3404	  || dyn_i->h->root.type != bfd_link_hash_undefweak)
3405	ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
3406    }
3407  if ((dynamic_symbol || shared) && dyn_i->want_tprel)
3408    ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
3409  if (dynamic_symbol && dyn_i->want_dtpmod)
3410    ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
3411  if (dynamic_symbol && dyn_i->want_dtprel)
3412    ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
3413
3414  if (x->only_got)
3415    return TRUE;
3416
3417  if (ia64_info->rel_fptr_sec && dyn_i->want_fptr)
3418    {
3419      if (dyn_i->h == NULL || dyn_i->h->root.type != bfd_link_hash_undefweak)
3420	ia64_info->rel_fptr_sec->size += sizeof (ElfNN_External_Rela);
3421    }
3422
3423  if (!resolved_zero && dyn_i->want_pltoff)
3424    {
3425      bfd_size_type t = 0;
3426
3427      /* Dynamic symbols get one IPLT relocation.  Local symbols in
3428	 shared libraries get two REL relocations.  Local symbols in
3429	 main applications get nothing.  */
3430      if (dynamic_symbol)
3431	t = sizeof (ElfNN_External_Rela);
3432      else if (shared)
3433	t = 2 * sizeof (ElfNN_External_Rela);
3434
3435      ia64_info->rel_pltoff_sec->size += t;
3436    }
3437
3438  /* Take care of the normal data relocations.  */
3439
3440  for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
3441    {
3442      int count = rent->count;
3443
3444      switch (rent->type)
3445	{
3446	case R_IA64_FPTR32LSB:
3447	case R_IA64_FPTR64LSB:
3448	  /* Allocate one iff !want_fptr and not PIE, which by this point
3449	     will be true only if we're actually allocating one statically
3450	     in the main executable.  Position independent executables
3451	     need a relative reloc.  */
3452	  if (dyn_i->want_fptr && !x->info->pie)
3453	    continue;
3454	  break;
3455	case R_IA64_PCREL32LSB:
3456	case R_IA64_PCREL64LSB:
3457	  if (!dynamic_symbol)
3458	    continue;
3459	  break;
3460	case R_IA64_DIR32LSB:
3461	case R_IA64_DIR64LSB:
3462	  if (!dynamic_symbol && !shared)
3463	    continue;
3464	  break;
3465	case R_IA64_IPLTLSB:
3466	  if (!dynamic_symbol && !shared)
3467	    continue;
3468	  /* Use two REL relocations for IPLT relocations
3469	     against local symbols.  */
3470	  if (!dynamic_symbol)
3471	    count *= 2;
3472	  break;
3473	case R_IA64_DTPREL32LSB:
3474	case R_IA64_TPREL64LSB:
3475	case R_IA64_DTPREL64LSB:
3476	case R_IA64_DTPMOD64LSB:
3477	  break;
3478	default:
3479	  abort ();
3480	}
3481      if (rent->reltext)
3482	ia64_info->reltext = 1;
3483      rent->srel->size += sizeof (ElfNN_External_Rela) * count;
3484    }
3485
3486  return TRUE;
3487}
3488
3489static bfd_boolean
3490elfNN_ia64_adjust_dynamic_symbol (info, h)
3491     struct bfd_link_info *info ATTRIBUTE_UNUSED;
3492     struct elf_link_hash_entry *h;
3493{
3494  /* ??? Undefined symbols with PLT entries should be re-defined
3495     to be the PLT entry.  */
3496
3497  /* If this is a weak symbol, and there is a real definition, the
3498     processor independent code will have arranged for us to see the
3499     real definition first, and we can just use the same value.  */
3500  if (h->u.weakdef != NULL)
3501    {
3502      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
3503                  || h->u.weakdef->root.type == bfd_link_hash_defweak);
3504      h->root.u.def.section = h->u.weakdef->root.u.def.section;
3505      h->root.u.def.value = h->u.weakdef->root.u.def.value;
3506      return TRUE;
3507    }
3508
3509  /* If this is a reference to a symbol defined by a dynamic object which
3510     is not a function, we might allocate the symbol in our .dynbss section
3511     and allocate a COPY dynamic relocation.
3512
3513     But IA-64 code is canonically PIC, so as a rule we can avoid this sort
3514     of hackery.  */
3515
3516  return TRUE;
3517}
3518
3519static bfd_boolean
3520elfNN_ia64_size_dynamic_sections (output_bfd, info)
3521     bfd *output_bfd ATTRIBUTE_UNUSED;
3522     struct bfd_link_info *info;
3523{
3524  struct elfNN_ia64_allocate_data data;
3525  struct elfNN_ia64_link_hash_table *ia64_info;
3526  asection *sec;
3527  bfd *dynobj;
3528  bfd_boolean relplt = FALSE;
3529
3530  dynobj = elf_hash_table(info)->dynobj;
3531  ia64_info = elfNN_ia64_hash_table (info);
3532  ia64_info->self_dtpmod_offset = (bfd_vma) -1;
3533  BFD_ASSERT(dynobj != NULL);
3534  data.info = info;
3535
3536  /* Set the contents of the .interp section to the interpreter.  */
3537  if (ia64_info->root.dynamic_sections_created
3538      && info->executable)
3539    {
3540      sec = bfd_get_section_by_name (dynobj, ".interp");
3541      BFD_ASSERT (sec != NULL);
3542      sec->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
3543      sec->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
3544    }
3545
3546  /* Allocate the GOT entries.  */
3547
3548  if (ia64_info->got_sec)
3549    {
3550      data.ofs = 0;
3551      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
3552      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
3553      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
3554      ia64_info->got_sec->size = data.ofs;
3555    }
3556
3557  /* Allocate the FPTR entries.  */
3558
3559  if (ia64_info->fptr_sec)
3560    {
3561      data.ofs = 0;
3562      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
3563      ia64_info->fptr_sec->size = data.ofs;
3564    }
3565
3566  /* Now that we've seen all of the input files, we can decide which
3567     symbols need plt entries.  Allocate the minimal PLT entries first.
3568     We do this even though dynamic_sections_created may be FALSE, because
3569     this has the side-effect of clearing want_plt and want_plt2.  */
3570
3571  data.ofs = 0;
3572  elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
3573
3574  ia64_info->minplt_entries = 0;
3575  if (data.ofs)
3576    {
3577      ia64_info->minplt_entries
3578	= (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
3579    }
3580
3581  /* Align the pointer for the plt2 entries.  */
3582  data.ofs = (data.ofs + 31) & (bfd_vma) -32;
3583
3584  elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
3585  if (data.ofs != 0 || ia64_info->root.dynamic_sections_created)
3586    {
3587      /* FIXME: we always reserve the memory for dynamic linker even if
3588	 there are no PLT entries since dynamic linker may assume the
3589	 reserved memory always exists.  */
3590
3591      BFD_ASSERT (ia64_info->root.dynamic_sections_created);
3592
3593      ia64_info->plt_sec->size = data.ofs;
3594
3595      /* If we've got a .plt, we need some extra memory for the dynamic
3596	 linker.  We stuff these in .got.plt.  */
3597      sec = bfd_get_section_by_name (dynobj, ".got.plt");
3598      sec->size = 8 * PLT_RESERVED_WORDS;
3599    }
3600
3601  /* Allocate the PLTOFF entries.  */
3602
3603  if (ia64_info->pltoff_sec)
3604    {
3605      data.ofs = 0;
3606      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
3607      ia64_info->pltoff_sec->size = data.ofs;
3608    }
3609
3610  if (ia64_info->root.dynamic_sections_created)
3611    {
3612      /* Allocate space for the dynamic relocations that turned out to be
3613	 required.  */
3614
3615      if (info->shared && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
3616	ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
3617      data.only_got = FALSE;
3618      elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
3619    }
3620
3621  /* We have now determined the sizes of the various dynamic sections.
3622     Allocate memory for them.  */
3623  for (sec = dynobj->sections; sec != NULL; sec = sec->next)
3624    {
3625      bfd_boolean strip;
3626
3627      if (!(sec->flags & SEC_LINKER_CREATED))
3628	continue;
3629
3630      /* If we don't need this section, strip it from the output file.
3631	 There were several sections primarily related to dynamic
3632	 linking that must be create before the linker maps input
3633	 sections to output sections.  The linker does that before
3634	 bfd_elf_size_dynamic_sections is called, and it is that
3635	 function which decides whether anything needs to go into
3636	 these sections.  */
3637
3638      strip = (sec->size == 0);
3639
3640      if (sec == ia64_info->got_sec)
3641	strip = FALSE;
3642      else if (sec == ia64_info->rel_got_sec)
3643	{
3644	  if (strip)
3645	    ia64_info->rel_got_sec = NULL;
3646	  else
3647	    /* We use the reloc_count field as a counter if we need to
3648	       copy relocs into the output file.  */
3649	    sec->reloc_count = 0;
3650	}
3651      else if (sec == ia64_info->fptr_sec)
3652	{
3653	  if (strip)
3654	    ia64_info->fptr_sec = NULL;
3655	}
3656      else if (sec == ia64_info->rel_fptr_sec)
3657	{
3658	  if (strip)
3659	    ia64_info->rel_fptr_sec = NULL;
3660	  else
3661	    /* We use the reloc_count field as a counter if we need to
3662	       copy relocs into the output file.  */
3663	    sec->reloc_count = 0;
3664	}
3665      else if (sec == ia64_info->plt_sec)
3666	{
3667	  if (strip)
3668	    ia64_info->plt_sec = NULL;
3669	}
3670      else if (sec == ia64_info->pltoff_sec)
3671	{
3672	  if (strip)
3673	    ia64_info->pltoff_sec = NULL;
3674	}
3675      else if (sec == ia64_info->rel_pltoff_sec)
3676	{
3677	  if (strip)
3678	    ia64_info->rel_pltoff_sec = NULL;
3679	  else
3680	    {
3681	      relplt = TRUE;
3682	      /* We use the reloc_count field as a counter if we need to
3683		 copy relocs into the output file.  */
3684	      sec->reloc_count = 0;
3685	    }
3686	}
3687      else
3688	{
3689	  const char *name;
3690
3691	  /* It's OK to base decisions on the section name, because none
3692	     of the dynobj section names depend upon the input files.  */
3693	  name = bfd_get_section_name (dynobj, sec);
3694
3695	  if (strcmp (name, ".got.plt") == 0)
3696	    strip = FALSE;
3697	  else if (strncmp (name, ".rel", 4) == 0)
3698	    {
3699	      if (!strip)
3700		{
3701		  /* We use the reloc_count field as a counter if we need to
3702		     copy relocs into the output file.  */
3703		  sec->reloc_count = 0;
3704		}
3705	    }
3706	  else
3707	    continue;
3708	}
3709
3710      if (strip)
3711	sec->flags |= SEC_EXCLUDE;
3712      else
3713	{
3714	  /* Allocate memory for the section contents.  */
3715	  sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->size);
3716	  if (sec->contents == NULL && sec->size != 0)
3717	    return FALSE;
3718	}
3719    }
3720
3721  if (elf_hash_table (info)->dynamic_sections_created)
3722    {
3723      /* Add some entries to the .dynamic section.  We fill in the values
3724	 later (in finish_dynamic_sections) but we must add the entries now
3725	 so that we get the correct size for the .dynamic section.  */
3726
3727      if (info->executable)
3728	{
3729	  /* The DT_DEBUG entry is filled in by the dynamic linker and used
3730	     by the debugger.  */
3731#define add_dynamic_entry(TAG, VAL) \
3732  _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3733
3734	  if (!add_dynamic_entry (DT_DEBUG, 0))
3735	    return FALSE;
3736	}
3737
3738      if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
3739	return FALSE;
3740      if (!add_dynamic_entry (DT_PLTGOT, 0))
3741	return FALSE;
3742
3743      if (relplt)
3744	{
3745	  if (!add_dynamic_entry (DT_PLTRELSZ, 0)
3746	      || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3747	      || !add_dynamic_entry (DT_JMPREL, 0))
3748	    return FALSE;
3749	}
3750
3751      if (!add_dynamic_entry (DT_RELA, 0)
3752	  || !add_dynamic_entry (DT_RELASZ, 0)
3753	  || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
3754	return FALSE;
3755
3756      if (ia64_info->reltext)
3757	{
3758	  if (!add_dynamic_entry (DT_TEXTREL, 0))
3759	    return FALSE;
3760	  info->flags |= DF_TEXTREL;
3761	}
3762    }
3763
3764  /* ??? Perhaps force __gp local.  */
3765
3766  return TRUE;
3767}
3768
3769static bfd_reloc_status_type
3770elfNN_ia64_install_value (hit_addr, v, r_type)
3771     bfd_byte *hit_addr;
3772     bfd_vma v;
3773     unsigned int r_type;
3774{
3775  const struct ia64_operand *op;
3776  int bigendian = 0, shift = 0;
3777  bfd_vma t0, t1, dword;
3778  ia64_insn insn;
3779  enum ia64_opnd opnd;
3780  const char *err;
3781  size_t size = 8;
3782#ifdef BFD_HOST_U_64_BIT
3783  BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
3784#else
3785  bfd_vma val = v;
3786#endif
3787
3788  opnd = IA64_OPND_NIL;
3789  switch (r_type)
3790    {
3791    case R_IA64_NONE:
3792    case R_IA64_LDXMOV:
3793      return bfd_reloc_ok;
3794
3795      /* Instruction relocations.  */
3796
3797    case R_IA64_IMM14:
3798    case R_IA64_TPREL14:
3799    case R_IA64_DTPREL14:
3800      opnd = IA64_OPND_IMM14;
3801      break;
3802
3803    case R_IA64_PCREL21F:	opnd = IA64_OPND_TGT25; break;
3804    case R_IA64_PCREL21M:	opnd = IA64_OPND_TGT25b; break;
3805    case R_IA64_PCREL60B:	opnd = IA64_OPND_TGT64; break;
3806    case R_IA64_PCREL21B:
3807    case R_IA64_PCREL21BI:
3808      opnd = IA64_OPND_TGT25c;
3809      break;
3810
3811    case R_IA64_IMM22:
3812    case R_IA64_GPREL22:
3813    case R_IA64_LTOFF22:
3814    case R_IA64_LTOFF22X:
3815    case R_IA64_PLTOFF22:
3816    case R_IA64_PCREL22:
3817    case R_IA64_LTOFF_FPTR22:
3818    case R_IA64_TPREL22:
3819    case R_IA64_DTPREL22:
3820    case R_IA64_LTOFF_TPREL22:
3821    case R_IA64_LTOFF_DTPMOD22:
3822    case R_IA64_LTOFF_DTPREL22:
3823      opnd = IA64_OPND_IMM22;
3824      break;
3825
3826    case R_IA64_IMM64:
3827    case R_IA64_GPREL64I:
3828    case R_IA64_LTOFF64I:
3829    case R_IA64_PLTOFF64I:
3830    case R_IA64_PCREL64I:
3831    case R_IA64_FPTR64I:
3832    case R_IA64_LTOFF_FPTR64I:
3833    case R_IA64_TPREL64I:
3834    case R_IA64_DTPREL64I:
3835      opnd = IA64_OPND_IMMU64;
3836      break;
3837
3838      /* Data relocations.  */
3839
3840    case R_IA64_DIR32MSB:
3841    case R_IA64_GPREL32MSB:
3842    case R_IA64_FPTR32MSB:
3843    case R_IA64_PCREL32MSB:
3844    case R_IA64_LTOFF_FPTR32MSB:
3845    case R_IA64_SEGREL32MSB:
3846    case R_IA64_SECREL32MSB:
3847    case R_IA64_LTV32MSB:
3848    case R_IA64_DTPREL32MSB:
3849      size = 4; bigendian = 1;
3850      break;
3851
3852    case R_IA64_DIR32LSB:
3853    case R_IA64_GPREL32LSB:
3854    case R_IA64_FPTR32LSB:
3855    case R_IA64_PCREL32LSB:
3856    case R_IA64_LTOFF_FPTR32LSB:
3857    case R_IA64_SEGREL32LSB:
3858    case R_IA64_SECREL32LSB:
3859    case R_IA64_LTV32LSB:
3860    case R_IA64_DTPREL32LSB:
3861      size = 4; bigendian = 0;
3862      break;
3863
3864    case R_IA64_DIR64MSB:
3865    case R_IA64_GPREL64MSB:
3866    case R_IA64_PLTOFF64MSB:
3867    case R_IA64_FPTR64MSB:
3868    case R_IA64_PCREL64MSB:
3869    case R_IA64_LTOFF_FPTR64MSB:
3870    case R_IA64_SEGREL64MSB:
3871    case R_IA64_SECREL64MSB:
3872    case R_IA64_LTV64MSB:
3873    case R_IA64_TPREL64MSB:
3874    case R_IA64_DTPMOD64MSB:
3875    case R_IA64_DTPREL64MSB:
3876      size = 8; bigendian = 1;
3877      break;
3878
3879    case R_IA64_DIR64LSB:
3880    case R_IA64_GPREL64LSB:
3881    case R_IA64_PLTOFF64LSB:
3882    case R_IA64_FPTR64LSB:
3883    case R_IA64_PCREL64LSB:
3884    case R_IA64_LTOFF_FPTR64LSB:
3885    case R_IA64_SEGREL64LSB:
3886    case R_IA64_SECREL64LSB:
3887    case R_IA64_LTV64LSB:
3888    case R_IA64_TPREL64LSB:
3889    case R_IA64_DTPMOD64LSB:
3890    case R_IA64_DTPREL64LSB:
3891      size = 8; bigendian = 0;
3892      break;
3893
3894      /* Unsupported / Dynamic relocations.  */
3895    default:
3896      return bfd_reloc_notsupported;
3897    }
3898
3899  switch (opnd)
3900    {
3901    case IA64_OPND_IMMU64:
3902      hit_addr -= (long) hit_addr & 0x3;
3903      t0 = bfd_getl64 (hit_addr);
3904      t1 = bfd_getl64 (hit_addr + 8);
3905
3906      /* tmpl/s: bits  0.. 5 in t0
3907	 slot 0: bits  5..45 in t0
3908	 slot 1: bits 46..63 in t0, bits 0..22 in t1
3909	 slot 2: bits 23..63 in t1 */
3910
3911      /* First, clear the bits that form the 64 bit constant.  */
3912      t0 &= ~(0x3ffffLL << 46);
3913      t1 &= ~(0x7fffffLL
3914	      | ((  (0x07fLL << 13) | (0x1ffLL << 27)
3915		    | (0x01fLL << 22) | (0x001LL << 21)
3916		    | (0x001LL << 36)) << 23));
3917
3918      t0 |= ((val >> 22) & 0x03ffffLL) << 46;		/* 18 lsbs of imm41 */
3919      t1 |= ((val >> 40) & 0x7fffffLL) <<  0;		/* 23 msbs of imm41 */
3920      t1 |= (  (((val >>  0) & 0x07f) << 13)		/* imm7b */
3921	       | (((val >>  7) & 0x1ff) << 27)		/* imm9d */
3922	       | (((val >> 16) & 0x01f) << 22)		/* imm5c */
3923	       | (((val >> 21) & 0x001) << 21)		/* ic */
3924	       | (((val >> 63) & 0x001) << 36)) << 23;	/* i */
3925
3926      bfd_putl64 (t0, hit_addr);
3927      bfd_putl64 (t1, hit_addr + 8);
3928      break;
3929
3930    case IA64_OPND_TGT64:
3931      hit_addr -= (long) hit_addr & 0x3;
3932      t0 = bfd_getl64 (hit_addr);
3933      t1 = bfd_getl64 (hit_addr + 8);
3934
3935      /* tmpl/s: bits  0.. 5 in t0
3936	 slot 0: bits  5..45 in t0
3937	 slot 1: bits 46..63 in t0, bits 0..22 in t1
3938	 slot 2: bits 23..63 in t1 */
3939
3940      /* First, clear the bits that form the 64 bit constant.  */
3941      t0 &= ~(0x3ffffLL << 46);
3942      t1 &= ~(0x7fffffLL
3943	      | ((1LL << 36 | 0xfffffLL << 13) << 23));
3944
3945      val >>= 4;
3946      t0 |= ((val >> 20) & 0xffffLL) << 2 << 46;	/* 16 lsbs of imm39 */
3947      t1 |= ((val >> 36) & 0x7fffffLL) << 0;		/* 23 msbs of imm39 */
3948      t1 |= ((((val >> 0) & 0xfffffLL) << 13)		/* imm20b */
3949	      | (((val >> 59) & 0x1LL) << 36)) << 23;	/* i */
3950
3951      bfd_putl64 (t0, hit_addr);
3952      bfd_putl64 (t1, hit_addr + 8);
3953      break;
3954
3955    default:
3956      switch ((long) hit_addr & 0x3)
3957	{
3958	case 0: shift =  5; break;
3959	case 1: shift = 14; hit_addr += 3; break;
3960	case 2: shift = 23; hit_addr += 6; break;
3961	case 3: return bfd_reloc_notsupported; /* shouldn't happen...  */
3962	}
3963      dword = bfd_getl64 (hit_addr);
3964      insn = (dword >> shift) & 0x1ffffffffffLL;
3965
3966      op = elf64_ia64_operands + opnd;
3967      err = (*op->insert) (op, val, &insn);
3968      if (err)
3969	return bfd_reloc_overflow;
3970
3971      dword &= ~(0x1ffffffffffLL << shift);
3972      dword |= (insn << shift);
3973      bfd_putl64 (dword, hit_addr);
3974      break;
3975
3976    case IA64_OPND_NIL:
3977      /* A data relocation.  */
3978      if (bigendian)
3979	if (size == 4)
3980	  bfd_putb32 (val, hit_addr);
3981	else
3982	  bfd_putb64 (val, hit_addr);
3983      else
3984	if (size == 4)
3985	  bfd_putl32 (val, hit_addr);
3986	else
3987	  bfd_putl64 (val, hit_addr);
3988      break;
3989    }
3990
3991  return bfd_reloc_ok;
3992}
3993
3994static void
3995elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
3996			      dynindx, addend)
3997     bfd *abfd;
3998     struct bfd_link_info *info;
3999     asection *sec;
4000     asection *srel;
4001     bfd_vma offset;
4002     unsigned int type;
4003     long dynindx;
4004     bfd_vma addend;
4005{
4006  Elf_Internal_Rela outrel;
4007  bfd_byte *loc;
4008
4009  BFD_ASSERT (dynindx != -1);
4010  outrel.r_info = ELFNN_R_INFO (dynindx, type);
4011  outrel.r_addend = addend;
4012  outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
4013  if (outrel.r_offset >= (bfd_vma) -2)
4014    {
4015      /* Run for the hills.  We shouldn't be outputting a relocation
4016	 for this.  So do what everyone else does and output a no-op.  */
4017      outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
4018      outrel.r_addend = 0;
4019      outrel.r_offset = 0;
4020    }
4021  else
4022    outrel.r_offset += sec->output_section->vma + sec->output_offset;
4023
4024  loc = srel->contents;
4025  loc += srel->reloc_count++ * sizeof (ElfNN_External_Rela);
4026  bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
4027  BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count <= srel->size);
4028}
4029
4030/* Store an entry for target address TARGET_ADDR in the linkage table
4031   and return the gp-relative address of the linkage table entry.  */
4032
4033static bfd_vma
4034set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
4035     bfd *abfd;
4036     struct bfd_link_info *info;
4037     struct elfNN_ia64_dyn_sym_info *dyn_i;
4038     long dynindx;
4039     bfd_vma addend;
4040     bfd_vma value;
4041     unsigned int dyn_r_type;
4042{
4043  struct elfNN_ia64_link_hash_table *ia64_info;
4044  asection *got_sec;
4045  bfd_boolean done;
4046  bfd_vma got_offset;
4047
4048  ia64_info = elfNN_ia64_hash_table (info);
4049  got_sec = ia64_info->got_sec;
4050
4051  switch (dyn_r_type)
4052    {
4053    case R_IA64_TPREL64LSB:
4054      done = dyn_i->tprel_done;
4055      dyn_i->tprel_done = TRUE;
4056      got_offset = dyn_i->tprel_offset;
4057      break;
4058    case R_IA64_DTPMOD64LSB:
4059      if (dyn_i->dtpmod_offset != ia64_info->self_dtpmod_offset)
4060	{
4061	  done = dyn_i->dtpmod_done;
4062	  dyn_i->dtpmod_done = TRUE;
4063	}
4064      else
4065	{
4066	  done = ia64_info->self_dtpmod_done;
4067	  ia64_info->self_dtpmod_done = TRUE;
4068	  dynindx = 0;
4069	}
4070      got_offset = dyn_i->dtpmod_offset;
4071      break;
4072    case R_IA64_DTPREL32LSB:
4073    case R_IA64_DTPREL64LSB:
4074      done = dyn_i->dtprel_done;
4075      dyn_i->dtprel_done = TRUE;
4076      got_offset = dyn_i->dtprel_offset;
4077      break;
4078    default:
4079      done = dyn_i->got_done;
4080      dyn_i->got_done = TRUE;
4081      got_offset = dyn_i->got_offset;
4082      break;
4083    }
4084
4085  BFD_ASSERT ((got_offset & 7) == 0);
4086
4087  if (! done)
4088    {
4089      /* Store the target address in the linkage table entry.  */
4090      bfd_put_64 (abfd, value, got_sec->contents + got_offset);
4091
4092      /* Install a dynamic relocation if needed.  */
4093      if (((info->shared
4094	    && (!dyn_i->h
4095		|| ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
4096		|| dyn_i->h->root.type != bfd_link_hash_undefweak)
4097	    && dyn_r_type != R_IA64_DTPREL32LSB
4098	    && dyn_r_type != R_IA64_DTPREL64LSB)
4099           || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info, dyn_r_type)
4100	   || (dynindx != -1
4101	       && (dyn_r_type == R_IA64_FPTR32LSB
4102		   || dyn_r_type == R_IA64_FPTR64LSB)))
4103	  && (!dyn_i->want_ltoff_fptr
4104	      || !info->pie
4105	      || !dyn_i->h
4106	      || dyn_i->h->root.type != bfd_link_hash_undefweak))
4107	{
4108	  if (dynindx == -1
4109	      && dyn_r_type != R_IA64_TPREL64LSB
4110	      && dyn_r_type != R_IA64_DTPMOD64LSB
4111	      && dyn_r_type != R_IA64_DTPREL32LSB
4112	      && dyn_r_type != R_IA64_DTPREL64LSB)
4113	    {
4114	      dyn_r_type = R_IA64_RELNNLSB;
4115	      dynindx = 0;
4116	      addend = value;
4117	    }
4118
4119	  if (bfd_big_endian (abfd))
4120	    {
4121	      switch (dyn_r_type)
4122		{
4123		case R_IA64_REL32LSB:
4124		  dyn_r_type = R_IA64_REL32MSB;
4125		  break;
4126		case R_IA64_DIR32LSB:
4127		  dyn_r_type = R_IA64_DIR32MSB;
4128		  break;
4129		case R_IA64_FPTR32LSB:
4130		  dyn_r_type = R_IA64_FPTR32MSB;
4131		  break;
4132		case R_IA64_DTPREL32LSB:
4133		  dyn_r_type = R_IA64_DTPREL32MSB;
4134		  break;
4135		case R_IA64_REL64LSB:
4136		  dyn_r_type = R_IA64_REL64MSB;
4137		  break;
4138		case R_IA64_DIR64LSB:
4139		  dyn_r_type = R_IA64_DIR64MSB;
4140		  break;
4141		case R_IA64_FPTR64LSB:
4142		  dyn_r_type = R_IA64_FPTR64MSB;
4143		  break;
4144		case R_IA64_TPREL64LSB:
4145		  dyn_r_type = R_IA64_TPREL64MSB;
4146		  break;
4147		case R_IA64_DTPMOD64LSB:
4148		  dyn_r_type = R_IA64_DTPMOD64MSB;
4149		  break;
4150		case R_IA64_DTPREL64LSB:
4151		  dyn_r_type = R_IA64_DTPREL64MSB;
4152		  break;
4153		default:
4154		  BFD_ASSERT (FALSE);
4155		  break;
4156		}
4157	    }
4158
4159	  elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
4160					ia64_info->rel_got_sec,
4161					got_offset, dyn_r_type,
4162					dynindx, addend);
4163	}
4164    }
4165
4166  /* Return the address of the linkage table entry.  */
4167  value = (got_sec->output_section->vma
4168	   + got_sec->output_offset
4169	   + got_offset);
4170
4171  return value;
4172}
4173
4174/* Fill in a function descriptor consisting of the function's code
4175   address and its global pointer.  Return the descriptor's address.  */
4176
4177static bfd_vma
4178set_fptr_entry (abfd, info, dyn_i, value)
4179     bfd *abfd;
4180     struct bfd_link_info *info;
4181     struct elfNN_ia64_dyn_sym_info *dyn_i;
4182     bfd_vma value;
4183{
4184  struct elfNN_ia64_link_hash_table *ia64_info;
4185  asection *fptr_sec;
4186
4187  ia64_info = elfNN_ia64_hash_table (info);
4188  fptr_sec = ia64_info->fptr_sec;
4189
4190  if (!dyn_i->fptr_done)
4191    {
4192      dyn_i->fptr_done = 1;
4193
4194      /* Fill in the function descriptor.  */
4195      bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
4196      bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
4197		  fptr_sec->contents + dyn_i->fptr_offset + 8);
4198      if (ia64_info->rel_fptr_sec)
4199	{
4200	  Elf_Internal_Rela outrel;
4201	  bfd_byte *loc;
4202
4203	  if (bfd_little_endian (abfd))
4204	    outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTLSB);
4205	  else
4206	    outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTMSB);
4207	  outrel.r_addend = value;
4208	  outrel.r_offset = (fptr_sec->output_section->vma
4209			     + fptr_sec->output_offset
4210			     + dyn_i->fptr_offset);
4211	  loc = ia64_info->rel_fptr_sec->contents;
4212	  loc += ia64_info->rel_fptr_sec->reloc_count++
4213		 * sizeof (ElfNN_External_Rela);
4214	  bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
4215	}
4216    }
4217
4218  /* Return the descriptor's address.  */
4219  value = (fptr_sec->output_section->vma
4220	   + fptr_sec->output_offset
4221	   + dyn_i->fptr_offset);
4222
4223  return value;
4224}
4225
4226/* Fill in a PLTOFF entry consisting of the function's code address
4227   and its global pointer.  Return the descriptor's address.  */
4228
4229static bfd_vma
4230set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
4231     bfd *abfd;
4232     struct bfd_link_info *info;
4233     struct elfNN_ia64_dyn_sym_info *dyn_i;
4234     bfd_vma value;
4235     bfd_boolean is_plt;
4236{
4237  struct elfNN_ia64_link_hash_table *ia64_info;
4238  asection *pltoff_sec;
4239
4240  ia64_info = elfNN_ia64_hash_table (info);
4241  pltoff_sec = ia64_info->pltoff_sec;
4242
4243  /* Don't do anything if this symbol uses a real PLT entry.  In
4244     that case, we'll fill this in during finish_dynamic_symbol.  */
4245  if ((! dyn_i->want_plt || is_plt)
4246      && !dyn_i->pltoff_done)
4247    {
4248      bfd_vma gp = _bfd_get_gp_value (abfd);
4249
4250      /* Fill in the function descriptor.  */
4251      bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
4252      bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
4253
4254      /* Install dynamic relocations if needed.  */
4255      if (!is_plt
4256	  && info->shared
4257	  && (!dyn_i->h
4258	      || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
4259	      || dyn_i->h->root.type != bfd_link_hash_undefweak))
4260	{
4261	  unsigned int dyn_r_type;
4262
4263	  if (bfd_big_endian (abfd))
4264	    dyn_r_type = R_IA64_RELNNMSB;
4265	  else
4266	    dyn_r_type = R_IA64_RELNNLSB;
4267
4268	  elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
4269					ia64_info->rel_pltoff_sec,
4270					dyn_i->pltoff_offset,
4271					dyn_r_type, 0, value);
4272	  elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
4273					ia64_info->rel_pltoff_sec,
4274					dyn_i->pltoff_offset + ARCH_SIZE / 8,
4275					dyn_r_type, 0, gp);
4276	}
4277
4278      dyn_i->pltoff_done = 1;
4279    }
4280
4281  /* Return the descriptor's address.  */
4282  value = (pltoff_sec->output_section->vma
4283	   + pltoff_sec->output_offset
4284	   + dyn_i->pltoff_offset);
4285
4286  return value;
4287}
4288
4289/* Return the base VMA address which should be subtracted from real addresses
4290   when resolving @tprel() relocation.
4291   Main program TLS (whose template starts at PT_TLS p_vaddr)
4292   is assigned offset round(2 * size of pointer, PT_TLS p_align).  */
4293
4294static bfd_vma
4295elfNN_ia64_tprel_base (info)
4296     struct bfd_link_info *info;
4297{
4298  asection *tls_sec = elf_hash_table (info)->tls_sec;
4299
4300  BFD_ASSERT (tls_sec != NULL);
4301  return tls_sec->vma - align_power ((bfd_vma) ARCH_SIZE / 4,
4302				     tls_sec->alignment_power);
4303}
4304
4305/* Return the base VMA address which should be subtracted from real addresses
4306   when resolving @dtprel() relocation.
4307   This is PT_TLS segment p_vaddr.  */
4308
4309static bfd_vma
4310elfNN_ia64_dtprel_base (info)
4311     struct bfd_link_info *info;
4312{
4313  BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
4314  return elf_hash_table (info)->tls_sec->vma;
4315}
4316
4317/* Called through qsort to sort the .IA_64.unwind section during a
4318   non-relocatable link.  Set elfNN_ia64_unwind_entry_compare_bfd
4319   to the output bfd so we can do proper endianness frobbing.  */
4320
4321static bfd *elfNN_ia64_unwind_entry_compare_bfd;
4322
4323static int
4324elfNN_ia64_unwind_entry_compare (a, b)
4325     const PTR a;
4326     const PTR b;
4327{
4328  bfd_vma av, bv;
4329
4330  av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
4331  bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
4332
4333  return (av < bv ? -1 : av > bv ? 1 : 0);
4334}
4335
4336/* Make sure we've got ourselves a nice fat __gp value.  */
4337static bfd_boolean
4338elfNN_ia64_choose_gp (abfd, info)
4339     bfd *abfd;
4340     struct bfd_link_info *info;
4341{
4342  bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
4343  bfd_vma min_short_vma = min_vma, max_short_vma = 0;
4344  struct elf_link_hash_entry *gp;
4345  bfd_vma gp_val;
4346  asection *os;
4347  struct elfNN_ia64_link_hash_table *ia64_info;
4348
4349  ia64_info = elfNN_ia64_hash_table (info);
4350
4351  /* Find the min and max vma of all sections marked short.  Also collect
4352     min and max vma of any type, for use in selecting a nice gp.  */
4353  for (os = abfd->sections; os ; os = os->next)
4354    {
4355      bfd_vma lo, hi;
4356
4357      if ((os->flags & SEC_ALLOC) == 0)
4358	continue;
4359
4360      lo = os->vma;
4361      hi = os->vma + os->size;
4362      if (hi < lo)
4363	hi = (bfd_vma) -1;
4364
4365      if (min_vma > lo)
4366	min_vma = lo;
4367      if (max_vma < hi)
4368	max_vma = hi;
4369      if (os->flags & SEC_SMALL_DATA)
4370	{
4371	  if (min_short_vma > lo)
4372	    min_short_vma = lo;
4373	  if (max_short_vma < hi)
4374	    max_short_vma = hi;
4375	}
4376    }
4377
4378  /* See if the user wants to force a value.  */
4379  gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
4380			     FALSE, FALSE);
4381
4382  if (gp
4383      && (gp->root.type == bfd_link_hash_defined
4384	  || gp->root.type == bfd_link_hash_defweak))
4385    {
4386      asection *gp_sec = gp->root.u.def.section;
4387      gp_val = (gp->root.u.def.value
4388		+ gp_sec->output_section->vma
4389		+ gp_sec->output_offset);
4390    }
4391  else
4392    {
4393      /* Pick a sensible value.  */
4394
4395      asection *got_sec = ia64_info->got_sec;
4396
4397      /* Start with just the address of the .got.  */
4398      if (got_sec)
4399	gp_val = got_sec->output_section->vma;
4400      else if (max_short_vma != 0)
4401	gp_val = min_short_vma;
4402      else if (max_vma - min_vma < 0x200000)
4403	gp_val = min_vma;
4404      else
4405	gp_val = max_vma - 0x200000 + 8;
4406
4407      /* If it is possible to address the entire image, but we
4408	 don't with the choice above, adjust.  */
4409      if (max_vma - min_vma < 0x400000
4410	  && (max_vma - gp_val >= 0x200000
4411	      || gp_val - min_vma > 0x200000))
4412	gp_val = min_vma + 0x200000;
4413      else if (max_short_vma != 0)
4414	{
4415	  /* If we don't cover all the short data, adjust.  */
4416	  if (max_short_vma - gp_val >= 0x200000)
4417	    gp_val = min_short_vma + 0x200000;
4418
4419	  /* If we're addressing stuff past the end, adjust back.  */
4420	  if (gp_val > max_vma)
4421	    gp_val = max_vma - 0x200000 + 8;
4422	}
4423    }
4424
4425  /* Validate whether all SHF_IA_64_SHORT sections are within
4426     range of the chosen GP.  */
4427
4428  if (max_short_vma != 0)
4429    {
4430      if (max_short_vma - min_short_vma >= 0x400000)
4431	{
4432	  (*_bfd_error_handler)
4433	    (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
4434	     bfd_get_filename (abfd),
4435	     (unsigned long) (max_short_vma - min_short_vma));
4436	  return FALSE;
4437	}
4438      else if ((gp_val > min_short_vma
4439		&& gp_val - min_short_vma > 0x200000)
4440	       || (gp_val < max_short_vma
4441		   && max_short_vma - gp_val >= 0x200000))
4442	{
4443	  (*_bfd_error_handler)
4444	    (_("%s: __gp does not cover short data segment"),
4445	     bfd_get_filename (abfd));
4446	  return FALSE;
4447	}
4448    }
4449
4450  _bfd_set_gp_value (abfd, gp_val);
4451
4452  return TRUE;
4453}
4454
4455static bfd_boolean
4456elfNN_ia64_final_link (abfd, info)
4457     bfd *abfd;
4458     struct bfd_link_info *info;
4459{
4460  struct elfNN_ia64_link_hash_table *ia64_info;
4461  asection *unwind_output_sec;
4462
4463  ia64_info = elfNN_ia64_hash_table (info);
4464
4465  /* Make sure we've got ourselves a nice fat __gp value.  */
4466  if (!info->relocatable)
4467    {
4468      bfd_vma gp_val;
4469      struct elf_link_hash_entry *gp;
4470
4471      /* We assume after gp is set, section size will only decrease. We
4472	 need to adjust gp for it.  */
4473      _bfd_set_gp_value (abfd, 0);
4474      if (! elfNN_ia64_choose_gp (abfd, info))
4475	return FALSE;
4476      gp_val = _bfd_get_gp_value (abfd);
4477
4478      gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
4479			         FALSE, FALSE);
4480      if (gp)
4481	{
4482	  gp->root.type = bfd_link_hash_defined;
4483	  gp->root.u.def.value = gp_val;
4484	  gp->root.u.def.section = bfd_abs_section_ptr;
4485	}
4486    }
4487
4488  /* If we're producing a final executable, we need to sort the contents
4489     of the .IA_64.unwind section.  Force this section to be relocated
4490     into memory rather than written immediately to the output file.  */
4491  unwind_output_sec = NULL;
4492  if (!info->relocatable)
4493    {
4494      asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
4495      if (s)
4496	{
4497	  unwind_output_sec = s->output_section;
4498	  unwind_output_sec->contents
4499	    = bfd_malloc (unwind_output_sec->size);
4500	  if (unwind_output_sec->contents == NULL)
4501	    return FALSE;
4502	}
4503    }
4504
4505  /* Invoke the regular ELF backend linker to do all the work.  */
4506  if (!bfd_elf_final_link (abfd, info))
4507    return FALSE;
4508
4509  if (unwind_output_sec)
4510    {
4511      elfNN_ia64_unwind_entry_compare_bfd = abfd;
4512      qsort (unwind_output_sec->contents,
4513	     (size_t) (unwind_output_sec->size / 24),
4514	     24,
4515	     elfNN_ia64_unwind_entry_compare);
4516
4517      if (! bfd_set_section_contents (abfd, unwind_output_sec,
4518				      unwind_output_sec->contents, (bfd_vma) 0,
4519				      unwind_output_sec->size))
4520	return FALSE;
4521    }
4522
4523  return TRUE;
4524}
4525
4526static bfd_boolean
4527elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
4528			     contents, relocs, local_syms, local_sections)
4529     bfd *output_bfd;
4530     struct bfd_link_info *info;
4531     bfd *input_bfd;
4532     asection *input_section;
4533     bfd_byte *contents;
4534     Elf_Internal_Rela *relocs;
4535     Elf_Internal_Sym *local_syms;
4536     asection **local_sections;
4537{
4538  struct elfNN_ia64_link_hash_table *ia64_info;
4539  Elf_Internal_Shdr *symtab_hdr;
4540  Elf_Internal_Rela *rel;
4541  Elf_Internal_Rela *relend;
4542  asection *srel;
4543  bfd_boolean ret_val = TRUE;	/* for non-fatal errors */
4544  bfd_vma gp_val;
4545
4546  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
4547  ia64_info = elfNN_ia64_hash_table (info);
4548
4549  /* Infect various flags from the input section to the output section.  */
4550  if (info->relocatable)
4551    {
4552      bfd_vma flags;
4553
4554      flags = elf_section_data(input_section)->this_hdr.sh_flags;
4555      flags &= SHF_IA_64_NORECOV;
4556
4557      elf_section_data(input_section->output_section)
4558	->this_hdr.sh_flags |= flags;
4559      return TRUE;
4560    }
4561
4562  gp_val = _bfd_get_gp_value (output_bfd);
4563  srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
4564
4565  rel = relocs;
4566  relend = relocs + input_section->reloc_count;
4567  for (; rel < relend; ++rel)
4568    {
4569      struct elf_link_hash_entry *h;
4570      struct elfNN_ia64_dyn_sym_info *dyn_i;
4571      bfd_reloc_status_type r;
4572      reloc_howto_type *howto;
4573      unsigned long r_symndx;
4574      Elf_Internal_Sym *sym;
4575      unsigned int r_type;
4576      bfd_vma value;
4577      asection *sym_sec;
4578      bfd_byte *hit_addr;
4579      bfd_boolean dynamic_symbol_p;
4580      bfd_boolean undef_weak_ref;
4581
4582      r_type = ELFNN_R_TYPE (rel->r_info);
4583      if (r_type > R_IA64_MAX_RELOC_CODE)
4584	{
4585	  (*_bfd_error_handler)
4586	    (_("%B: unknown relocation type %d"),
4587	     input_bfd, (int) r_type);
4588	  bfd_set_error (bfd_error_bad_value);
4589	  ret_val = FALSE;
4590	  continue;
4591	}
4592
4593      howto = lookup_howto (r_type);
4594      r_symndx = ELFNN_R_SYM (rel->r_info);
4595      h = NULL;
4596      sym = NULL;
4597      sym_sec = NULL;
4598      undef_weak_ref = FALSE;
4599
4600      if (r_symndx < symtab_hdr->sh_info)
4601	{
4602	  /* Reloc against local symbol.  */
4603	  asection *msec;
4604	  sym = local_syms + r_symndx;
4605	  sym_sec = local_sections[r_symndx];
4606	  msec = sym_sec;
4607	  value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
4608	  if ((sym_sec->flags & SEC_MERGE)
4609	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION
4610	      && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
4611 	    {
4612	      struct elfNN_ia64_local_hash_entry *loc_h;
4613
4614	      loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
4615	      if (loc_h && ! loc_h->sec_merge_done)
4616		{
4617		  struct elfNN_ia64_dyn_sym_info *dynent;
4618		  unsigned int count;
4619
4620		  for (count = loc_h->count, dynent = loc_h->info;
4621		       count != 0;
4622		       count--, dynent++)
4623		    {
4624		      msec = sym_sec;
4625		      dynent->addend =
4626			_bfd_merged_section_offset (output_bfd, &msec,
4627						    elf_section_data (msec)->
4628						    sec_info,
4629						    sym->st_value
4630						    + dynent->addend);
4631		      dynent->addend -= sym->st_value;
4632		      dynent->addend += msec->output_section->vma
4633					+ msec->output_offset
4634					- sym_sec->output_section->vma
4635					- sym_sec->output_offset;
4636		    }
4637
4638		  qsort (loc_h->info, loc_h->count,
4639			 sizeof (*loc_h->info), addend_compare);
4640
4641		  loc_h->sec_merge_done = 1;
4642		}
4643	    }
4644	}
4645      else
4646	{
4647	  bfd_boolean unresolved_reloc;
4648	  bfd_boolean warned;
4649	  struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
4650
4651	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
4652				   r_symndx, symtab_hdr, sym_hashes,
4653				   h, sym_sec, value,
4654				   unresolved_reloc, warned);
4655
4656	  if (h->root.type == bfd_link_hash_undefweak)
4657	    undef_weak_ref = TRUE;
4658	  else if (warned)
4659	    continue;
4660	}
4661
4662      hit_addr = contents + rel->r_offset;
4663      value += rel->r_addend;
4664      dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type);
4665
4666      switch (r_type)
4667	{
4668	case R_IA64_NONE:
4669	case R_IA64_LDXMOV:
4670	  continue;
4671
4672	case R_IA64_IMM14:
4673	case R_IA64_IMM22:
4674	case R_IA64_IMM64:
4675	case R_IA64_DIR32MSB:
4676	case R_IA64_DIR32LSB:
4677	case R_IA64_DIR64MSB:
4678	case R_IA64_DIR64LSB:
4679	  /* Install a dynamic relocation for this reloc.  */
4680	  if ((dynamic_symbol_p || info->shared)
4681	      && r_symndx != 0
4682	      && (input_section->flags & SEC_ALLOC) != 0)
4683	    {
4684	      unsigned int dyn_r_type;
4685	      long dynindx;
4686	      bfd_vma addend;
4687
4688	      BFD_ASSERT (srel != NULL);
4689
4690	      switch (r_type)
4691		{
4692		case R_IA64_IMM14:
4693		case R_IA64_IMM22:
4694		case R_IA64_IMM64:
4695		  /* ??? People shouldn't be doing non-pic code in
4696		     shared libraries nor dynamic executables.  */
4697		  (*_bfd_error_handler)
4698		    (_("%B: non-pic code with imm relocation against dynamic symbol `%s'"),
4699		     input_bfd,
4700		     h ? h->root.root.string
4701		       : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4702					   sym_sec));
4703		  ret_val = FALSE;
4704		  continue;
4705
4706		default:
4707		  break;
4708		}
4709
4710	      /* If we don't need dynamic symbol lookup, find a
4711		 matching RELATIVE relocation.  */
4712	      dyn_r_type = r_type;
4713	      if (dynamic_symbol_p)
4714		{
4715		  dynindx = h->dynindx;
4716		  addend = rel->r_addend;
4717		  value = 0;
4718		}
4719	      else
4720		{
4721		  switch (r_type)
4722		    {
4723		    case R_IA64_DIR32MSB:
4724		      dyn_r_type = R_IA64_REL32MSB;
4725		      break;
4726		    case R_IA64_DIR32LSB:
4727		      dyn_r_type = R_IA64_REL32LSB;
4728		      break;
4729		    case R_IA64_DIR64MSB:
4730		      dyn_r_type = R_IA64_REL64MSB;
4731		      break;
4732		    case R_IA64_DIR64LSB:
4733		      dyn_r_type = R_IA64_REL64LSB;
4734		      break;
4735
4736		    default:
4737		      break;
4738		    }
4739		  dynindx = 0;
4740		  addend = value;
4741		}
4742
4743	      elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4744					    srel, rel->r_offset, dyn_r_type,
4745					    dynindx, addend);
4746	    }
4747	  /* Fall through.  */
4748
4749	case R_IA64_LTV32MSB:
4750	case R_IA64_LTV32LSB:
4751	case R_IA64_LTV64MSB:
4752	case R_IA64_LTV64LSB:
4753	  r = elfNN_ia64_install_value (hit_addr, value, r_type);
4754	  break;
4755
4756	case R_IA64_GPREL22:
4757	case R_IA64_GPREL64I:
4758	case R_IA64_GPREL32MSB:
4759	case R_IA64_GPREL32LSB:
4760	case R_IA64_GPREL64MSB:
4761	case R_IA64_GPREL64LSB:
4762	  if (dynamic_symbol_p)
4763	    {
4764	      (*_bfd_error_handler)
4765		(_("%B: @gprel relocation against dynamic symbol %s"),
4766		 input_bfd,
4767		 h ? h->root.root.string
4768		   : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4769				       sym_sec));
4770	      ret_val = FALSE;
4771	      continue;
4772	    }
4773	  value -= gp_val;
4774	  r = elfNN_ia64_install_value (hit_addr, value, r_type);
4775	  break;
4776
4777	case R_IA64_LTOFF22:
4778	case R_IA64_LTOFF22X:
4779	case R_IA64_LTOFF64I:
4780          dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4781	  value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
4782				 rel->r_addend, value, R_IA64_DIRNNLSB);
4783	  value -= gp_val;
4784	  r = elfNN_ia64_install_value (hit_addr, value, r_type);
4785	  break;
4786
4787	case R_IA64_PLTOFF22:
4788	case R_IA64_PLTOFF64I:
4789	case R_IA64_PLTOFF64MSB:
4790	case R_IA64_PLTOFF64LSB:
4791          dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4792	  value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
4793	  value -= gp_val;
4794	  r = elfNN_ia64_install_value (hit_addr, value, r_type);
4795	  break;
4796
4797	case R_IA64_FPTR64I:
4798	case R_IA64_FPTR32MSB:
4799	case R_IA64_FPTR32LSB:
4800	case R_IA64_FPTR64MSB:
4801	case R_IA64_FPTR64LSB:
4802          dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4803	  if (dyn_i->want_fptr)
4804	    {
4805	      if (!undef_weak_ref)
4806		value = set_fptr_entry (output_bfd, info, dyn_i, value);
4807	    }
4808	  if (!dyn_i->want_fptr || info->pie)
4809	    {
4810	      long dynindx;
4811	      unsigned int dyn_r_type = r_type;
4812	      bfd_vma addend = rel->r_addend;
4813
4814	      /* Otherwise, we expect the dynamic linker to create
4815		 the entry.  */
4816
4817	      if (dyn_i->want_fptr)
4818		{
4819		  if (r_type == R_IA64_FPTR64I)
4820		    {
4821		      /* We can't represent this without a dynamic symbol.
4822			 Adjust the relocation to be against an output
4823			 section symbol, which are always present in the
4824			 dynamic symbol table.  */
4825		      /* ??? People shouldn't be doing non-pic code in
4826			 shared libraries.  Hork.  */
4827		      (*_bfd_error_handler)
4828			(_("%B: linking non-pic code in a position independent executable"),
4829			 input_bfd);
4830		      ret_val = FALSE;
4831		      continue;
4832		    }
4833		  dynindx = 0;
4834		  addend = value;
4835		  dyn_r_type = r_type + R_IA64_RELNNLSB - R_IA64_FPTRNNLSB;
4836		}
4837	      else if (h)
4838		{
4839		  if (h->dynindx != -1)
4840		    dynindx = h->dynindx;
4841		  else
4842		    dynindx = (_bfd_elf_link_lookup_local_dynindx
4843			       (info, h->root.u.def.section->owner,
4844				global_sym_index (h)));
4845		  value = 0;
4846		}
4847	      else
4848		{
4849		  dynindx = (_bfd_elf_link_lookup_local_dynindx
4850			     (info, input_bfd, (long) r_symndx));
4851		  value = 0;
4852		}
4853
4854	      elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4855					    srel, rel->r_offset, dyn_r_type,
4856					    dynindx, addend);
4857	    }
4858
4859	  r = elfNN_ia64_install_value (hit_addr, value, r_type);
4860	  break;
4861
4862	case R_IA64_LTOFF_FPTR22:
4863	case R_IA64_LTOFF_FPTR64I:
4864	case R_IA64_LTOFF_FPTR32MSB:
4865	case R_IA64_LTOFF_FPTR32LSB:
4866	case R_IA64_LTOFF_FPTR64MSB:
4867	case R_IA64_LTOFF_FPTR64LSB:
4868	  {
4869	    long dynindx;
4870
4871	    dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4872	    if (dyn_i->want_fptr)
4873	      {
4874		BFD_ASSERT (h == NULL || h->dynindx == -1);
4875	        if (!undef_weak_ref)
4876	          value = set_fptr_entry (output_bfd, info, dyn_i, value);
4877		dynindx = -1;
4878	      }
4879	    else
4880	      {
4881	        /* Otherwise, we expect the dynamic linker to create
4882		   the entry.  */
4883	        if (h)
4884		  {
4885		    if (h->dynindx != -1)
4886		      dynindx = h->dynindx;
4887		    else
4888		      dynindx = (_bfd_elf_link_lookup_local_dynindx
4889				 (info, h->root.u.def.section->owner,
4890				  global_sym_index (h)));
4891		  }
4892		else
4893		  dynindx = (_bfd_elf_link_lookup_local_dynindx
4894			     (info, input_bfd, (long) r_symndx));
4895		value = 0;
4896	      }
4897
4898	    value = set_got_entry (output_bfd, info, dyn_i, dynindx,
4899				   rel->r_addend, value, R_IA64_FPTRNNLSB);
4900	    value -= gp_val;
4901	    r = elfNN_ia64_install_value (hit_addr, value, r_type);
4902	  }
4903	  break;
4904
4905	case R_IA64_PCREL32MSB:
4906	case R_IA64_PCREL32LSB:
4907	case R_IA64_PCREL64MSB:
4908	case R_IA64_PCREL64LSB:
4909	  /* Install a dynamic relocation for this reloc.  */
4910	  if (dynamic_symbol_p && r_symndx != 0)
4911	    {
4912	      BFD_ASSERT (srel != NULL);
4913
4914	      elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4915					    srel, rel->r_offset, r_type,
4916					    h->dynindx, rel->r_addend);
4917	    }
4918	  goto finish_pcrel;
4919
4920	case R_IA64_PCREL21B:
4921	case R_IA64_PCREL60B:
4922	  /* We should have created a PLT entry for any dynamic symbol.  */
4923	  dyn_i = NULL;
4924	  if (h)
4925	    dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4926
4927	  if (dyn_i && dyn_i->want_plt2)
4928	    {
4929	      /* Should have caught this earlier.  */
4930	      BFD_ASSERT (rel->r_addend == 0);
4931
4932	      value = (ia64_info->plt_sec->output_section->vma
4933		       + ia64_info->plt_sec->output_offset
4934		       + dyn_i->plt2_offset);
4935	    }
4936	  else
4937	    {
4938	      /* Since there's no PLT entry, Validate that this is
4939		 locally defined.  */
4940	      BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
4941
4942	      /* If the symbol is undef_weak, we shouldn't be trying
4943		 to call it.  There's every chance that we'd wind up
4944		 with an out-of-range fixup here.  Don't bother setting
4945		 any value at all.  */
4946	      if (undef_weak_ref)
4947		continue;
4948	    }
4949	  goto finish_pcrel;
4950
4951	case R_IA64_PCREL21BI:
4952	case R_IA64_PCREL21F:
4953	case R_IA64_PCREL21M:
4954	case R_IA64_PCREL22:
4955	case R_IA64_PCREL64I:
4956	  /* The PCREL21BI reloc is specifically not intended for use with
4957	     dynamic relocs.  PCREL21F and PCREL21M are used for speculation
4958	     fixup code, and thus probably ought not be dynamic.  The
4959	     PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs.  */
4960	  if (dynamic_symbol_p)
4961	    {
4962	      const char *msg;
4963
4964	      if (r_type == R_IA64_PCREL21BI)
4965		msg = _("%B: @internal branch to dynamic symbol %s");
4966	      else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
4967		msg = _("%B: speculation fixup to dynamic symbol %s");
4968	      else
4969		msg = _("%B: @pcrel relocation against dynamic symbol %s");
4970	      (*_bfd_error_handler) (msg, input_bfd,
4971				     h ? h->root.root.string
4972				       : bfd_elf_sym_name (input_bfd,
4973							   symtab_hdr,
4974							   sym,
4975							   sym_sec));
4976	      ret_val = FALSE;
4977	      continue;
4978	    }
4979	  goto finish_pcrel;
4980
4981	finish_pcrel:
4982	  /* Make pc-relative.  */
4983	  value -= (input_section->output_section->vma
4984		    + input_section->output_offset
4985		    + rel->r_offset) & ~ (bfd_vma) 0x3;
4986	  r = elfNN_ia64_install_value (hit_addr, value, r_type);
4987	  break;
4988
4989	case R_IA64_SEGREL32MSB:
4990	case R_IA64_SEGREL32LSB:
4991	case R_IA64_SEGREL64MSB:
4992	case R_IA64_SEGREL64LSB:
4993	  if (r_symndx == 0)
4994	    {
4995	      /* If the input section was discarded from the output, then
4996		 do nothing.  */
4997	      r = bfd_reloc_ok;
4998	    }
4999	  else
5000	    {
5001	      struct elf_segment_map *m;
5002	      Elf_Internal_Phdr *p;
5003
5004	      /* Find the segment that contains the output_section.  */
5005	      for (m = elf_tdata (output_bfd)->segment_map,
5006		     p = elf_tdata (output_bfd)->phdr;
5007		   m != NULL;
5008		   m = m->next, p++)
5009		{
5010		  int i;
5011		  for (i = m->count - 1; i >= 0; i--)
5012		    if (m->sections[i] == input_section->output_section)
5013		      break;
5014		  if (i >= 0)
5015		    break;
5016		}
5017
5018	      if (m == NULL)
5019		{
5020		  r = bfd_reloc_notsupported;
5021		}
5022	      else
5023		{
5024		  /* The VMA of the segment is the vaddr of the associated
5025		     program header.  */
5026		  if (value > p->p_vaddr)
5027		    value -= p->p_vaddr;
5028		  else
5029		    value = 0;
5030		  r = elfNN_ia64_install_value (hit_addr, value, r_type);
5031		}
5032	      break;
5033	    }
5034
5035	case R_IA64_SECREL32MSB:
5036	case R_IA64_SECREL32LSB:
5037	case R_IA64_SECREL64MSB:
5038	case R_IA64_SECREL64LSB:
5039	  /* Make output-section relative to section where the symbol
5040	     is defined. PR 475  */
5041	  if (sym_sec)
5042	    value -= sym_sec->output_section->vma;
5043	  r = elfNN_ia64_install_value (hit_addr, value, r_type);
5044	  break;
5045
5046	case R_IA64_IPLTMSB:
5047	case R_IA64_IPLTLSB:
5048	  /* Install a dynamic relocation for this reloc.  */
5049	  if ((dynamic_symbol_p || info->shared)
5050	      && (input_section->flags & SEC_ALLOC) != 0)
5051	    {
5052	      BFD_ASSERT (srel != NULL);
5053
5054	      /* If we don't need dynamic symbol lookup, install two
5055		 RELATIVE relocations.  */
5056	      if (!dynamic_symbol_p)
5057		{
5058		  unsigned int dyn_r_type;
5059
5060		  if (r_type == R_IA64_IPLTMSB)
5061		    dyn_r_type = R_IA64_REL64MSB;
5062		  else
5063		    dyn_r_type = R_IA64_REL64LSB;
5064
5065		  elfNN_ia64_install_dyn_reloc (output_bfd, info,
5066						input_section,
5067						srel, rel->r_offset,
5068						dyn_r_type, 0, value);
5069		  elfNN_ia64_install_dyn_reloc (output_bfd, info,
5070						input_section,
5071						srel, rel->r_offset + 8,
5072						dyn_r_type, 0, gp_val);
5073		}
5074	      else
5075		elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
5076					      srel, rel->r_offset, r_type,
5077					      h->dynindx, rel->r_addend);
5078	    }
5079
5080	  if (r_type == R_IA64_IPLTMSB)
5081	    r_type = R_IA64_DIR64MSB;
5082	  else
5083	    r_type = R_IA64_DIR64LSB;
5084	  elfNN_ia64_install_value (hit_addr, value, r_type);
5085	  r = elfNN_ia64_install_value (hit_addr + 8, gp_val, r_type);
5086	  break;
5087
5088	case R_IA64_TPREL14:
5089	case R_IA64_TPREL22:
5090	case R_IA64_TPREL64I:
5091	  value -= elfNN_ia64_tprel_base (info);
5092	  r = elfNN_ia64_install_value (hit_addr, value, r_type);
5093	  break;
5094
5095	case R_IA64_DTPREL14:
5096	case R_IA64_DTPREL22:
5097	case R_IA64_DTPREL64I:
5098	case R_IA64_DTPREL32LSB:
5099	case R_IA64_DTPREL32MSB:
5100	case R_IA64_DTPREL64LSB:
5101	case R_IA64_DTPREL64MSB:
5102	  value -= elfNN_ia64_dtprel_base (info);
5103	  r = elfNN_ia64_install_value (hit_addr, value, r_type);
5104	  break;
5105
5106	case R_IA64_LTOFF_TPREL22:
5107	case R_IA64_LTOFF_DTPMOD22:
5108	case R_IA64_LTOFF_DTPREL22:
5109	  {
5110	    int got_r_type;
5111	    long dynindx = h ? h->dynindx : -1;
5112	    bfd_vma r_addend = rel->r_addend;
5113
5114	    switch (r_type)
5115	      {
5116	      default:
5117	      case R_IA64_LTOFF_TPREL22:
5118		if (!dynamic_symbol_p)
5119		  {
5120		    if (!info->shared)
5121		      value -= elfNN_ia64_tprel_base (info);
5122		    else
5123		      {
5124			r_addend += value - elfNN_ia64_dtprel_base (info);
5125			dynindx = 0;
5126		      }
5127		  }
5128		got_r_type = R_IA64_TPREL64LSB;
5129		break;
5130	      case R_IA64_LTOFF_DTPMOD22:
5131		if (!dynamic_symbol_p && !info->shared)
5132		  value = 1;
5133		got_r_type = R_IA64_DTPMOD64LSB;
5134		break;
5135	      case R_IA64_LTOFF_DTPREL22:
5136		if (!dynamic_symbol_p)
5137		  value -= elfNN_ia64_dtprel_base (info);
5138		got_r_type = R_IA64_DTPRELNNLSB;
5139		break;
5140	      }
5141	    dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
5142	    value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
5143				   value, got_r_type);
5144	    value -= gp_val;
5145	    r = elfNN_ia64_install_value (hit_addr, value, r_type);
5146	  }
5147	  break;
5148
5149	default:
5150	  r = bfd_reloc_notsupported;
5151	  break;
5152	}
5153
5154      switch (r)
5155	{
5156	case bfd_reloc_ok:
5157	  break;
5158
5159	case bfd_reloc_undefined:
5160	  /* This can happen for global table relative relocs if
5161	     __gp is undefined.  This is a panic situation so we
5162	     don't try to continue.  */
5163	  (*info->callbacks->undefined_symbol)
5164	    (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
5165	  return FALSE;
5166
5167	case bfd_reloc_notsupported:
5168	  {
5169	    const char *name;
5170
5171	    if (h)
5172	      name = h->root.root.string;
5173	    else
5174	      name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
5175				       sym_sec);
5176	    if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
5177					      name, input_bfd,
5178					      input_section, rel->r_offset))
5179	      return FALSE;
5180	    ret_val = FALSE;
5181	  }
5182	  break;
5183
5184	case bfd_reloc_dangerous:
5185	case bfd_reloc_outofrange:
5186	case bfd_reloc_overflow:
5187	default:
5188	  {
5189	    const char *name;
5190
5191	    if (h)
5192	      name = h->root.root.string;
5193	    else
5194	      name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
5195				       sym_sec);
5196
5197	    switch (r_type)
5198	      {
5199	      case R_IA64_PCREL21B:
5200	      case R_IA64_PCREL21BI:
5201	      case R_IA64_PCREL21M:
5202	      case R_IA64_PCREL21F:
5203		if (is_elf_hash_table (info->hash))
5204		  {
5205		    /* Relaxtion is always performed for ELF output.
5206		       Overflow failures for those relocations mean
5207		       that the section is too big to relax.  */
5208		    (*_bfd_error_handler)
5209		      (_("%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."),
5210		       input_bfd, input_section, howto->name, name,
5211		       rel->r_offset, input_section->size);
5212		    break;
5213		  }
5214	      default:
5215		if (!(*info->callbacks->reloc_overflow) (info,
5216							 &h->root,
5217							 name,
5218							 howto->name,
5219							 (bfd_vma) 0,
5220							 input_bfd,
5221							 input_section,
5222							 rel->r_offset))
5223		  return FALSE;
5224		break;
5225	      }
5226
5227	    ret_val = FALSE;
5228	  }
5229	  break;
5230	}
5231    }
5232
5233  return ret_val;
5234}
5235
5236static bfd_boolean
5237elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
5238     bfd *output_bfd;
5239     struct bfd_link_info *info;
5240     struct elf_link_hash_entry *h;
5241     Elf_Internal_Sym *sym;
5242{
5243  struct elfNN_ia64_link_hash_table *ia64_info;
5244  struct elfNN_ia64_dyn_sym_info *dyn_i;
5245
5246  ia64_info = elfNN_ia64_hash_table (info);
5247  dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
5248
5249  /* Fill in the PLT data, if required.  */
5250  if (dyn_i && dyn_i->want_plt)
5251    {
5252      Elf_Internal_Rela outrel;
5253      bfd_byte *loc;
5254      asection *plt_sec;
5255      bfd_vma plt_addr, pltoff_addr, gp_val, index;
5256
5257      gp_val = _bfd_get_gp_value (output_bfd);
5258
5259      /* Initialize the minimal PLT entry.  */
5260
5261      index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
5262      plt_sec = ia64_info->plt_sec;
5263      loc = plt_sec->contents + dyn_i->plt_offset;
5264
5265      memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
5266      elfNN_ia64_install_value (loc, index, R_IA64_IMM22);
5267      elfNN_ia64_install_value (loc+2, -dyn_i->plt_offset, R_IA64_PCREL21B);
5268
5269      plt_addr = (plt_sec->output_section->vma
5270		  + plt_sec->output_offset
5271		  + dyn_i->plt_offset);
5272      pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
5273
5274      /* Initialize the FULL PLT entry, if needed.  */
5275      if (dyn_i->want_plt2)
5276	{
5277	  loc = plt_sec->contents + dyn_i->plt2_offset;
5278
5279	  memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
5280	  elfNN_ia64_install_value (loc, pltoff_addr - gp_val, R_IA64_IMM22);
5281
5282	  /* Mark the symbol as undefined, rather than as defined in the
5283	     plt section.  Leave the value alone.  */
5284	  /* ??? We didn't redefine it in adjust_dynamic_symbol in the
5285	     first place.  But perhaps elflink.c did some for us.  */
5286	  if (!h->def_regular)
5287	    sym->st_shndx = SHN_UNDEF;
5288	}
5289
5290      /* Create the dynamic relocation.  */
5291      outrel.r_offset = pltoff_addr;
5292      if (bfd_little_endian (output_bfd))
5293	outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
5294      else
5295	outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
5296      outrel.r_addend = 0;
5297
5298      /* This is fun.  In the .IA_64.pltoff section, we've got entries
5299	 that correspond both to real PLT entries, and those that
5300	 happened to resolve to local symbols but need to be created
5301	 to satisfy @pltoff relocations.  The .rela.IA_64.pltoff
5302	 relocations for the real PLT should come at the end of the
5303	 section, so that they can be indexed by plt entry at runtime.
5304
5305	 We emitted all of the relocations for the non-PLT @pltoff
5306	 entries during relocate_section.  So we can consider the
5307	 existing sec->reloc_count to be the base of the array of
5308	 PLT relocations.  */
5309
5310      loc = ia64_info->rel_pltoff_sec->contents;
5311      loc += ((ia64_info->rel_pltoff_sec->reloc_count + index)
5312	      * sizeof (ElfNN_External_Rela));
5313      bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
5314    }
5315
5316  /* Mark some specially defined symbols as absolute.  */
5317  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
5318      || h == ia64_info->root.hgot
5319      || h == ia64_info->root.hplt)
5320    sym->st_shndx = SHN_ABS;
5321
5322  return TRUE;
5323}
5324
5325static bfd_boolean
5326elfNN_ia64_finish_dynamic_sections (abfd, info)
5327     bfd *abfd;
5328     struct bfd_link_info *info;
5329{
5330  struct elfNN_ia64_link_hash_table *ia64_info;
5331  bfd *dynobj;
5332
5333  ia64_info = elfNN_ia64_hash_table (info);
5334  dynobj = ia64_info->root.dynobj;
5335
5336  if (elf_hash_table (info)->dynamic_sections_created)
5337    {
5338      ElfNN_External_Dyn *dyncon, *dynconend;
5339      asection *sdyn, *sgotplt;
5340      bfd_vma gp_val;
5341
5342      sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
5343      sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
5344      BFD_ASSERT (sdyn != NULL);
5345      dyncon = (ElfNN_External_Dyn *) sdyn->contents;
5346      dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
5347
5348      gp_val = _bfd_get_gp_value (abfd);
5349
5350      for (; dyncon < dynconend; dyncon++)
5351	{
5352	  Elf_Internal_Dyn dyn;
5353
5354	  bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
5355
5356	  switch (dyn.d_tag)
5357	    {
5358	    case DT_PLTGOT:
5359	      dyn.d_un.d_ptr = gp_val;
5360	      break;
5361
5362	    case DT_PLTRELSZ:
5363	      dyn.d_un.d_val = (ia64_info->minplt_entries
5364				* sizeof (ElfNN_External_Rela));
5365	      break;
5366
5367	    case DT_JMPREL:
5368	      /* See the comment above in finish_dynamic_symbol.  */
5369	      dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
5370				+ ia64_info->rel_pltoff_sec->output_offset
5371				+ (ia64_info->rel_pltoff_sec->reloc_count
5372				   * sizeof (ElfNN_External_Rela)));
5373	      break;
5374
5375	    case DT_IA_64_PLT_RESERVE:
5376	      dyn.d_un.d_ptr = (sgotplt->output_section->vma
5377				+ sgotplt->output_offset);
5378	      break;
5379
5380	    case DT_RELASZ:
5381	      /* Do not have RELASZ include JMPREL.  This makes things
5382		 easier on ld.so.  This is not what the rest of BFD set up.  */
5383	      dyn.d_un.d_val -= (ia64_info->minplt_entries
5384				 * sizeof (ElfNN_External_Rela));
5385	      break;
5386	    }
5387
5388	  bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
5389	}
5390
5391      /* Initialize the PLT0 entry.  */
5392      if (ia64_info->plt_sec)
5393	{
5394	  bfd_byte *loc = ia64_info->plt_sec->contents;
5395	  bfd_vma pltres;
5396
5397	  memcpy (loc, plt_header, PLT_HEADER_SIZE);
5398
5399	  pltres = (sgotplt->output_section->vma
5400		    + sgotplt->output_offset
5401		    - gp_val);
5402
5403	  elfNN_ia64_install_value (loc+1, pltres, R_IA64_GPREL22);
5404	}
5405    }
5406
5407  return TRUE;
5408}
5409
5410/* ELF file flag handling:  */
5411
5412/* Function to keep IA-64 specific file flags.  */
5413static bfd_boolean
5414elfNN_ia64_set_private_flags (abfd, flags)
5415     bfd *abfd;
5416     flagword flags;
5417{
5418  BFD_ASSERT (!elf_flags_init (abfd)
5419	      || elf_elfheader (abfd)->e_flags == flags);
5420
5421  elf_elfheader (abfd)->e_flags = flags;
5422  elf_flags_init (abfd) = TRUE;
5423  return TRUE;
5424}
5425
5426/* Merge backend specific data from an object file to the output
5427   object file when linking.  */
5428static bfd_boolean
5429elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
5430     bfd *ibfd, *obfd;
5431{
5432  flagword out_flags;
5433  flagword in_flags;
5434  bfd_boolean ok = TRUE;
5435
5436  /* Don't even pretend to support mixed-format linking.  */
5437  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
5438      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
5439    return FALSE;
5440
5441  in_flags  = elf_elfheader (ibfd)->e_flags;
5442  out_flags = elf_elfheader (obfd)->e_flags;
5443
5444  if (! elf_flags_init (obfd))
5445    {
5446      elf_flags_init (obfd) = TRUE;
5447      elf_elfheader (obfd)->e_flags = in_flags;
5448
5449      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
5450	  && bfd_get_arch_info (obfd)->the_default)
5451	{
5452	  return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
5453				    bfd_get_mach (ibfd));
5454	}
5455
5456      return TRUE;
5457    }
5458
5459  /* Check flag compatibility.  */
5460  if (in_flags == out_flags)
5461    return TRUE;
5462
5463  /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set.  */
5464  if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
5465    elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
5466
5467  if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
5468    {
5469      (*_bfd_error_handler)
5470	(_("%B: linking trap-on-NULL-dereference with non-trapping files"),
5471	 ibfd);
5472
5473      bfd_set_error (bfd_error_bad_value);
5474      ok = FALSE;
5475    }
5476  if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
5477    {
5478      (*_bfd_error_handler)
5479	(_("%B: linking big-endian files with little-endian files"),
5480	 ibfd);
5481
5482      bfd_set_error (bfd_error_bad_value);
5483      ok = FALSE;
5484    }
5485  if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
5486    {
5487      (*_bfd_error_handler)
5488	(_("%B: linking 64-bit files with 32-bit files"),
5489	 ibfd);
5490
5491      bfd_set_error (bfd_error_bad_value);
5492      ok = FALSE;
5493    }
5494  if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
5495    {
5496      (*_bfd_error_handler)
5497	(_("%B: linking constant-gp files with non-constant-gp files"),
5498	 ibfd);
5499
5500      bfd_set_error (bfd_error_bad_value);
5501      ok = FALSE;
5502    }
5503  if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
5504      != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
5505    {
5506      (*_bfd_error_handler)
5507	(_("%B: linking auto-pic files with non-auto-pic files"),
5508	 ibfd);
5509
5510      bfd_set_error (bfd_error_bad_value);
5511      ok = FALSE;
5512    }
5513
5514  return ok;
5515}
5516
5517static bfd_boolean
5518elfNN_ia64_print_private_bfd_data (abfd, ptr)
5519     bfd *abfd;
5520     PTR ptr;
5521{
5522  FILE *file = (FILE *) ptr;
5523  flagword flags = elf_elfheader (abfd)->e_flags;
5524
5525  BFD_ASSERT (abfd != NULL && ptr != NULL);
5526
5527  fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
5528	   (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
5529	   (flags & EF_IA_64_EXT) ? "EXT, " : "",
5530	   (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
5531	   (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
5532	   (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
5533	   (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
5534	   (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
5535	   (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
5536
5537  _bfd_elf_print_private_bfd_data (abfd, ptr);
5538  return TRUE;
5539}
5540
5541static enum elf_reloc_type_class
5542elfNN_ia64_reloc_type_class (rela)
5543     const Elf_Internal_Rela *rela;
5544{
5545  switch ((int) ELFNN_R_TYPE (rela->r_info))
5546    {
5547    case R_IA64_REL32MSB:
5548    case R_IA64_REL32LSB:
5549    case R_IA64_REL64MSB:
5550    case R_IA64_REL64LSB:
5551      return reloc_class_relative;
5552    case R_IA64_IPLTMSB:
5553    case R_IA64_IPLTLSB:
5554      return reloc_class_plt;
5555    case R_IA64_COPY:
5556      return reloc_class_copy;
5557    default:
5558      return reloc_class_normal;
5559    }
5560}
5561
5562static const struct bfd_elf_special_section elfNN_ia64_special_sections[] =
5563{
5564  { ".sbss",  5, -1, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
5565  { ".sdata", 6, -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
5566  { NULL,        0, 0, 0,            0 }
5567};
5568
5569static bfd_boolean
5570elfNN_ia64_object_p (bfd *abfd)
5571{
5572  asection *sec;
5573  asection *group, *unwi, *unw;
5574  flagword flags;
5575  const char *name;
5576  char *unwi_name, *unw_name;
5577  bfd_size_type amt;
5578
5579  if (abfd->flags & DYNAMIC)
5580    return TRUE;
5581
5582  /* Flags for fake group section.  */
5583  flags = (SEC_LINKER_CREATED | SEC_GROUP | SEC_LINK_ONCE
5584	   | SEC_EXCLUDE);
5585
5586  /* We add a fake section group for each .gnu.linkonce.t.* section,
5587     which isn't in a section group, and its unwind sections.  */
5588  for (sec = abfd->sections; sec != NULL; sec = sec->next)
5589    {
5590      if (elf_sec_group (sec) == NULL
5591	  && ((sec->flags & (SEC_LINK_ONCE | SEC_CODE | SEC_GROUP))
5592	      == (SEC_LINK_ONCE | SEC_CODE))
5593	  && strncmp (sec->name, ".gnu.linkonce.t.", 16) == 0)
5594	{
5595	  name = sec->name + 16;
5596
5597	  amt = strlen (name) + sizeof (".gnu.linkonce.ia64unwi.");
5598	  unwi_name = bfd_alloc (abfd, amt);
5599	  if (!unwi_name)
5600	    return FALSE;
5601
5602	  strcpy (stpcpy (unwi_name, ".gnu.linkonce.ia64unwi."), name);
5603	  unwi = bfd_get_section_by_name (abfd, unwi_name);
5604
5605	  amt = strlen (name) + sizeof (".gnu.linkonce.ia64unw.");
5606	  unw_name = bfd_alloc (abfd, amt);
5607	  if (!unw_name)
5608	    return FALSE;
5609
5610	  strcpy (stpcpy (unw_name, ".gnu.linkonce.ia64unw."), name);
5611	  unw = bfd_get_section_by_name (abfd, unw_name);
5612
5613	  /* We need to create a fake group section for it and its
5614	     unwind sections.  */
5615	  group = bfd_make_section_anyway_with_flags (abfd, name,
5616						      flags);
5617	  if (group == NULL)
5618	    return FALSE;
5619
5620	  /* Move the fake group section to the beginning.  */
5621	  bfd_section_list_remove (abfd, group);
5622	  bfd_section_list_prepend (abfd, group);
5623
5624	  elf_next_in_group (group) = sec;
5625
5626	  elf_group_name (sec) = name;
5627	  elf_next_in_group (sec) = sec;
5628	  elf_sec_group (sec) = group;
5629
5630	  if (unwi)
5631	    {
5632	      elf_group_name (unwi) = name;
5633	      elf_next_in_group (unwi) = sec;
5634	      elf_next_in_group (sec) = unwi;
5635	      elf_sec_group (unwi) = group;
5636	    }
5637
5638	   if (unw)
5639	     {
5640	       elf_group_name (unw) = name;
5641	       if (unwi)
5642		 {
5643		   elf_next_in_group (unw) = elf_next_in_group (unwi);
5644		   elf_next_in_group (unwi) = unw;
5645		 }
5646	       else
5647		 {
5648		   elf_next_in_group (unw) = sec;
5649		   elf_next_in_group (sec) = unw;
5650		 }
5651	       elf_sec_group (unw) = group;
5652	     }
5653
5654	   /* Fake SHT_GROUP section header.  */
5655	  elf_section_data (group)->this_hdr.bfd_section = group;
5656	  elf_section_data (group)->this_hdr.sh_type = SHT_GROUP;
5657	}
5658    }
5659  return TRUE;
5660}
5661
5662static bfd_boolean
5663elfNN_ia64_hpux_vec (const bfd_target *vec)
5664{
5665  extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
5666  return (vec == & bfd_elfNN_ia64_hpux_big_vec);
5667}
5668
5669static void
5670elfNN_hpux_post_process_headers (abfd, info)
5671	bfd *abfd;
5672	struct bfd_link_info *info ATTRIBUTE_UNUSED;
5673{
5674  Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
5675
5676  i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_HPUX;
5677  i_ehdrp->e_ident[EI_ABIVERSION] = 1;
5678}
5679
5680bfd_boolean
5681elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
5682	bfd *abfd ATTRIBUTE_UNUSED;
5683	asection *sec;
5684	int *retval;
5685{
5686  if (bfd_is_com_section (sec))
5687    {
5688      *retval = SHN_IA_64_ANSI_COMMON;
5689      return TRUE;
5690    }
5691  return FALSE;
5692}
5693
5694static void
5695elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
5696				      asymbol *asym)
5697{
5698  elf_symbol_type *elfsym = (elf_symbol_type *) asym;
5699
5700  switch (elfsym->internal_elf_sym.st_shndx)
5701    {
5702    case SHN_IA_64_ANSI_COMMON:
5703      asym->section = bfd_com_section_ptr;
5704      asym->value = elfsym->internal_elf_sym.st_size;
5705      asym->flags &= ~BSF_GLOBAL;
5706      break;
5707    }
5708}
5709
5710
5711#define TARGET_LITTLE_SYM		bfd_elfNN_ia64_little_vec
5712#define TARGET_LITTLE_NAME		"elfNN-ia64-little"
5713#define TARGET_BIG_SYM			bfd_elfNN_ia64_big_vec
5714#define TARGET_BIG_NAME			"elfNN-ia64-big"
5715#define ELF_ARCH			bfd_arch_ia64
5716#define ELF_MACHINE_CODE		EM_IA_64
5717#define ELF_MACHINE_ALT1		1999	/* EAS2.3 */
5718#define ELF_MACHINE_ALT2		1998	/* EAS2.2 */
5719#define ELF_MAXPAGESIZE			0x10000	/* 64KB */
5720
5721#define elf_backend_section_from_shdr \
5722	elfNN_ia64_section_from_shdr
5723#define elf_backend_section_flags \
5724	elfNN_ia64_section_flags
5725#define elf_backend_fake_sections \
5726	elfNN_ia64_fake_sections
5727#define elf_backend_final_write_processing \
5728	elfNN_ia64_final_write_processing
5729#define elf_backend_add_symbol_hook \
5730	elfNN_ia64_add_symbol_hook
5731#define elf_backend_additional_program_headers \
5732	elfNN_ia64_additional_program_headers
5733#define elf_backend_modify_segment_map \
5734	elfNN_ia64_modify_segment_map
5735#define elf_info_to_howto \
5736	elfNN_ia64_info_to_howto
5737
5738#define bfd_elfNN_bfd_reloc_type_lookup \
5739	elfNN_ia64_reloc_type_lookup
5740#define bfd_elfNN_bfd_is_local_label_name \
5741	elfNN_ia64_is_local_label_name
5742#define bfd_elfNN_bfd_relax_section \
5743	elfNN_ia64_relax_section
5744
5745#define elf_backend_object_p \
5746	elfNN_ia64_object_p
5747
5748/* Stuff for the BFD linker: */
5749#define bfd_elfNN_bfd_link_hash_table_create \
5750	elfNN_ia64_hash_table_create
5751#define bfd_elfNN_bfd_link_hash_table_free \
5752	elfNN_ia64_hash_table_free
5753#define elf_backend_create_dynamic_sections \
5754	elfNN_ia64_create_dynamic_sections
5755#define elf_backend_check_relocs \
5756	elfNN_ia64_check_relocs
5757#define elf_backend_adjust_dynamic_symbol \
5758	elfNN_ia64_adjust_dynamic_symbol
5759#define elf_backend_size_dynamic_sections \
5760	elfNN_ia64_size_dynamic_sections
5761#define elf_backend_relocate_section \
5762	elfNN_ia64_relocate_section
5763#define elf_backend_finish_dynamic_symbol \
5764	elfNN_ia64_finish_dynamic_symbol
5765#define elf_backend_finish_dynamic_sections \
5766	elfNN_ia64_finish_dynamic_sections
5767#define bfd_elfNN_bfd_final_link \
5768	elfNN_ia64_final_link
5769
5770#define bfd_elfNN_bfd_merge_private_bfd_data \
5771	elfNN_ia64_merge_private_bfd_data
5772#define bfd_elfNN_bfd_set_private_flags \
5773	elfNN_ia64_set_private_flags
5774#define bfd_elfNN_bfd_print_private_bfd_data \
5775	elfNN_ia64_print_private_bfd_data
5776
5777#define elf_backend_plt_readonly	1
5778#define elf_backend_want_plt_sym	0
5779#define elf_backend_plt_alignment	5
5780#define elf_backend_got_header_size	0
5781#define elf_backend_want_got_plt	1
5782#define elf_backend_may_use_rel_p	1
5783#define elf_backend_may_use_rela_p	1
5784#define elf_backend_default_use_rela_p	1
5785#define elf_backend_want_dynbss		0
5786#define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
5787#define elf_backend_hide_symbol		elfNN_ia64_hash_hide_symbol
5788#define elf_backend_fixup_symbol	_bfd_elf_link_hash_fixup_symbol
5789#define elf_backend_reloc_type_class	elfNN_ia64_reloc_type_class
5790#define elf_backend_rela_normal		1
5791#define elf_backend_special_sections	elfNN_ia64_special_sections
5792
5793/* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
5794   SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
5795   We don't want to flood users with so many error messages. We turn
5796   off the warning for now. It will be turned on later when the Intel
5797   compiler is fixed.   */
5798#define elf_backend_link_order_error_handler NULL
5799
5800#include "elfNN-target.h"
5801
5802/* HPUX-specific vectors.  */
5803
5804#undef  TARGET_LITTLE_SYM
5805#undef  TARGET_LITTLE_NAME
5806#undef  TARGET_BIG_SYM
5807#define TARGET_BIG_SYM                  bfd_elfNN_ia64_hpux_big_vec
5808#undef  TARGET_BIG_NAME
5809#define TARGET_BIG_NAME                 "elfNN-ia64-hpux-big"
5810
5811/* These are HP-UX specific functions.  */
5812
5813#undef  elf_backend_post_process_headers
5814#define elf_backend_post_process_headers elfNN_hpux_post_process_headers
5815
5816#undef  elf_backend_section_from_bfd_section
5817#define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
5818
5819#undef elf_backend_symbol_processing
5820#define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
5821
5822#undef  elf_backend_want_p_paddr_set_to_zero
5823#define elf_backend_want_p_paddr_set_to_zero 1
5824
5825#undef  ELF_MAXPAGESIZE
5826#define ELF_MAXPAGESIZE                 0x1000  /* 1K */
5827
5828#undef  elfNN_bed
5829#define elfNN_bed elfNN_ia64_hpux_bed
5830
5831#include "elfNN-target.h"
5832
5833#undef  elf_backend_want_p_paddr_set_to_zero
5834