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