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