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