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