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