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