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