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