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