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