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