bfd/
[platform/upstream/binutils.git] / bfd / elfxx-ia64.c
1 /* IA-64 support for 64-bit ELF
2    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004
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, "TPREL64MSB",  4, FALSE, FALSE),
449     IA64_HOWTO (R_IA64_DTPMOD64LSB, "TPREL64LSB",  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                 (_("%s: Can't relax br at 0x%lx in section `%s'. Please use brl or indirect branch."),
981                  bfd_archive_filename (sec->owner),
982                  (unsigned long) roff, sec->name);
983               bfd_set_error (bfd_error_bad_value);
984               goto error_return;
985             }
986
987           /* If the branch and target are in the same section, you've
988              got one honking big section and we can't help you.  You'll
989              get an error message later.  */
990           if (tsec == sec)
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   /* Initialize our local data.  All zeros, and definitely easier
1621      than setting a handful of bit fields.  */
1622   memset (ret, 0, sizeof (*ret));
1623
1624   /* Call the allocation method of the superclass.  */
1625   ret = ((struct elfNN_ia64_link_hash_entry *)
1626          _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1627                                      table, string));
1628
1629   return (struct bfd_hash_entry *) ret;
1630 }
1631
1632 static void
1633 elfNN_ia64_hash_copy_indirect (bed, xdir, xind)
1634      const struct elf_backend_data *bed ATTRIBUTE_UNUSED;
1635      struct elf_link_hash_entry *xdir, *xind;
1636 {
1637   struct elfNN_ia64_link_hash_entry *dir, *ind;
1638
1639   dir = (struct elfNN_ia64_link_hash_entry *) xdir;
1640   ind = (struct elfNN_ia64_link_hash_entry *) xind;
1641
1642   /* Copy down any references that we may have already seen to the
1643      symbol which just became indirect.  */
1644
1645   dir->root.elf_link_hash_flags |=
1646     (ind->root.elf_link_hash_flags
1647      & (ELF_LINK_HASH_REF_DYNAMIC
1648         | ELF_LINK_HASH_REF_REGULAR
1649         | ELF_LINK_HASH_REF_REGULAR_NONWEAK
1650         | ELF_LINK_HASH_NEEDS_PLT));
1651
1652   if (ind->root.root.type != bfd_link_hash_indirect)
1653     return;
1654
1655   /* Copy over the got and plt data.  This would have been done
1656      by check_relocs.  */
1657
1658   if (dir->info == NULL)
1659     {
1660       struct elfNN_ia64_dyn_sym_info *dyn_i;
1661
1662       dir->info = dyn_i = ind->info;
1663       ind->info = NULL;
1664
1665       /* Fix up the dyn_sym_info pointers to the global symbol.  */
1666       for (; dyn_i; dyn_i = dyn_i->next)
1667         dyn_i->h = &dir->root;
1668     }
1669   BFD_ASSERT (ind->info == NULL);
1670
1671   /* Copy over the dynindx.  */
1672
1673   if (dir->root.dynindx == -1)
1674     {
1675       dir->root.dynindx = ind->root.dynindx;
1676       dir->root.dynstr_index = ind->root.dynstr_index;
1677       ind->root.dynindx = -1;
1678       ind->root.dynstr_index = 0;
1679     }
1680   BFD_ASSERT (ind->root.dynindx == -1);
1681 }
1682
1683 static void
1684 elfNN_ia64_hash_hide_symbol (info, xh, force_local)
1685      struct bfd_link_info *info;
1686      struct elf_link_hash_entry *xh;
1687      bfd_boolean force_local;
1688 {
1689   struct elfNN_ia64_link_hash_entry *h;
1690   struct elfNN_ia64_dyn_sym_info *dyn_i;
1691
1692   h = (struct elfNN_ia64_link_hash_entry *)xh;
1693
1694   _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1695
1696   for (dyn_i = h->info; dyn_i; dyn_i = dyn_i->next)
1697     {
1698       dyn_i->want_plt2 = 0;
1699       dyn_i->want_plt = 0;
1700     }
1701 }
1702
1703 /* Compute a hash of a local hash entry.  */
1704
1705 static hashval_t
1706 elfNN_ia64_local_htab_hash (ptr)
1707      const void *ptr;
1708 {
1709   struct elfNN_ia64_local_hash_entry *entry
1710     = (struct elfNN_ia64_local_hash_entry *) ptr;
1711
1712   return (((entry->id & 0xff) << 24) | ((entry->id & 0xff00) << 8))
1713           ^ entry->r_sym ^ (entry->id >> 16);
1714 }
1715
1716 /* Compare local hash entries.  */
1717
1718 static int
1719 elfNN_ia64_local_htab_eq (ptr1, ptr2)
1720      const void *ptr1, *ptr2;
1721 {
1722   struct elfNN_ia64_local_hash_entry *entry1
1723     = (struct elfNN_ia64_local_hash_entry *) ptr1;
1724   struct elfNN_ia64_local_hash_entry *entry2
1725     = (struct elfNN_ia64_local_hash_entry *) ptr2;
1726
1727   return entry1->id == entry2->id && entry1->r_sym == entry2->r_sym;
1728 }
1729
1730 /* Create the derived linker hash table.  The IA-64 ELF port uses this
1731    derived hash table to keep information specific to the IA-64 ElF
1732    linker (without using static variables).  */
1733
1734 static struct bfd_link_hash_table*
1735 elfNN_ia64_hash_table_create (abfd)
1736      bfd *abfd;
1737 {
1738   struct elfNN_ia64_link_hash_table *ret;
1739
1740   ret = bfd_zmalloc ((bfd_size_type) sizeof (*ret));
1741   if (!ret)
1742     return 0;
1743
1744   if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1745                                       elfNN_ia64_new_elf_hash_entry))
1746     {
1747       free (ret);
1748       return 0;
1749     }
1750
1751   ret->loc_hash_table = htab_try_create (1024, elfNN_ia64_local_htab_hash,
1752                                          elfNN_ia64_local_htab_eq, NULL);
1753   ret->loc_hash_memory = objalloc_create ();
1754   if (!ret->loc_hash_table || !ret->loc_hash_memory)
1755     {
1756       free (ret);
1757       return 0;
1758     }
1759
1760   return &ret->root.root;
1761 }
1762
1763 /* Destroy IA-64 linker hash table.  */
1764
1765 static void
1766 elfNN_ia64_hash_table_free (hash)
1767      struct bfd_link_hash_table *hash;
1768 {
1769   struct elfNN_ia64_link_hash_table *ia64_info
1770     = (struct elfNN_ia64_link_hash_table *) hash;
1771   if (ia64_info->loc_hash_table)
1772     htab_delete (ia64_info->loc_hash_table);
1773   if (ia64_info->loc_hash_memory)
1774     objalloc_free ((struct objalloc *) ia64_info->loc_hash_memory);
1775   _bfd_generic_link_hash_table_free (hash);
1776 }
1777
1778 /* Traverse both local and global hash tables.  */
1779
1780 struct elfNN_ia64_dyn_sym_traverse_data
1781 {
1782   bfd_boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1783   PTR data;
1784 };
1785
1786 static bfd_boolean
1787 elfNN_ia64_global_dyn_sym_thunk (xentry, xdata)
1788      struct bfd_hash_entry *xentry;
1789      PTR xdata;
1790 {
1791   struct elfNN_ia64_link_hash_entry *entry
1792     = (struct elfNN_ia64_link_hash_entry *) xentry;
1793   struct elfNN_ia64_dyn_sym_traverse_data *data
1794     = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1795   struct elfNN_ia64_dyn_sym_info *dyn_i;
1796
1797   if (entry->root.root.type == bfd_link_hash_warning)
1798     entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
1799
1800   for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1801     if (! (*data->func) (dyn_i, data->data))
1802       return FALSE;
1803   return TRUE;
1804 }
1805
1806 static bfd_boolean
1807 elfNN_ia64_local_dyn_sym_thunk (slot, xdata)
1808      void **slot;
1809      PTR xdata;
1810 {
1811   struct elfNN_ia64_local_hash_entry *entry
1812     = (struct elfNN_ia64_local_hash_entry *) *slot;
1813   struct elfNN_ia64_dyn_sym_traverse_data *data
1814     = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1815   struct elfNN_ia64_dyn_sym_info *dyn_i;
1816
1817   for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1818     if (! (*data->func) (dyn_i, data->data))
1819       return 0;
1820   return 1;
1821 }
1822
1823 static void
1824 elfNN_ia64_dyn_sym_traverse (ia64_info, func, data)
1825      struct elfNN_ia64_link_hash_table *ia64_info;
1826      bfd_boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1827      PTR data;
1828 {
1829   struct elfNN_ia64_dyn_sym_traverse_data xdata;
1830
1831   xdata.func = func;
1832   xdata.data = data;
1833
1834   elf_link_hash_traverse (&ia64_info->root,
1835                           elfNN_ia64_global_dyn_sym_thunk, &xdata);
1836   htab_traverse (ia64_info->loc_hash_table,
1837                  elfNN_ia64_local_dyn_sym_thunk, &xdata);
1838 }
1839 \f
1840 static bfd_boolean
1841 elfNN_ia64_create_dynamic_sections (abfd, info)
1842      bfd *abfd;
1843      struct bfd_link_info *info;
1844 {
1845   struct elfNN_ia64_link_hash_table *ia64_info;
1846   asection *s;
1847
1848   if (! _bfd_elf_create_dynamic_sections (abfd, info))
1849     return FALSE;
1850
1851   ia64_info = elfNN_ia64_hash_table (info);
1852
1853   ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
1854   ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
1855
1856   {
1857     flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
1858     bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
1859     /* The .got section is always aligned at 8 bytes.  */
1860     bfd_set_section_alignment (abfd, ia64_info->got_sec, 3);
1861   }
1862
1863   if (!get_pltoff (abfd, info, ia64_info))
1864     return FALSE;
1865
1866   s = bfd_make_section(abfd, ".rela.IA_64.pltoff");
1867   if (s == NULL
1868       || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1869                                            | SEC_HAS_CONTENTS
1870                                            | SEC_IN_MEMORY
1871                                            | SEC_LINKER_CREATED
1872                                            | SEC_READONLY))
1873       || !bfd_set_section_alignment (abfd, s, 3))
1874     return FALSE;
1875   ia64_info->rel_pltoff_sec = s;
1876
1877   s = bfd_make_section(abfd, ".rela.got");
1878   if (s == NULL
1879       || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1880                                            | SEC_HAS_CONTENTS
1881                                            | SEC_IN_MEMORY
1882                                            | SEC_LINKER_CREATED
1883                                            | SEC_READONLY))
1884       || !bfd_set_section_alignment (abfd, s, 3))
1885     return FALSE;
1886   ia64_info->rel_got_sec = s;
1887
1888   return TRUE;
1889 }
1890
1891 /* Find and/or create a hash entry for local symbol.  */
1892 static struct elfNN_ia64_local_hash_entry *
1893 get_local_sym_hash (ia64_info, abfd, rel, create)
1894      struct elfNN_ia64_link_hash_table *ia64_info;
1895      bfd *abfd;
1896      const Elf_Internal_Rela *rel;
1897      bfd_boolean create;
1898 {
1899   struct elfNN_ia64_local_hash_entry e, *ret;
1900   asection *sec = abfd->sections;
1901   hashval_t h = (((sec->id & 0xff) << 24) | ((sec->id & 0xff00) << 8))
1902                 ^ ELFNN_R_SYM (rel->r_info) ^ (sec->id >> 16);
1903   void **slot;
1904
1905   e.id = sec->id;
1906   e.r_sym = ELFNN_R_SYM (rel->r_info);
1907   slot = htab_find_slot_with_hash (ia64_info->loc_hash_table, &e, h,
1908                                    create ? INSERT : NO_INSERT);
1909
1910   if (!slot)
1911     return NULL;
1912
1913   if (*slot)
1914     return (struct elfNN_ia64_local_hash_entry *) *slot;
1915
1916   ret = (struct elfNN_ia64_local_hash_entry *)
1917         objalloc_alloc ((struct objalloc *) ia64_info->loc_hash_memory,
1918                         sizeof (struct elfNN_ia64_local_hash_entry));
1919   if (ret)
1920     {
1921       memset (ret, 0, sizeof (*ret));
1922       ret->id = sec->id;
1923       ret->r_sym = ELFNN_R_SYM (rel->r_info);
1924       *slot = ret;
1925     }
1926   return ret;
1927 }
1928
1929 /* Find and/or create a descriptor for dynamic symbol info.  This will
1930    vary based on global or local symbol, and the addend to the reloc.  */
1931
1932 static struct elfNN_ia64_dyn_sym_info *
1933 get_dyn_sym_info (ia64_info, h, abfd, rel, create)
1934      struct elfNN_ia64_link_hash_table *ia64_info;
1935      struct elf_link_hash_entry *h;
1936      bfd *abfd;
1937      const Elf_Internal_Rela *rel;
1938      bfd_boolean create;
1939 {
1940   struct elfNN_ia64_dyn_sym_info **pp;
1941   struct elfNN_ia64_dyn_sym_info *dyn_i;
1942   bfd_vma addend = rel ? rel->r_addend : 0;
1943
1944   if (h)
1945     pp = &((struct elfNN_ia64_link_hash_entry *)h)->info;
1946   else
1947     {
1948       struct elfNN_ia64_local_hash_entry *loc_h;
1949
1950       loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
1951       if (!loc_h)
1952         {
1953           BFD_ASSERT (!create);
1954           return NULL;
1955         }
1956
1957       pp = &loc_h->info;
1958     }
1959
1960   for (dyn_i = *pp; dyn_i && dyn_i->addend != addend; dyn_i = *pp)
1961     pp = &dyn_i->next;
1962
1963   if (dyn_i == NULL && create)
1964     {
1965       dyn_i = ((struct elfNN_ia64_dyn_sym_info *)
1966                bfd_zalloc (abfd, (bfd_size_type) sizeof *dyn_i));
1967       *pp = dyn_i;
1968       dyn_i->addend = addend;
1969     }
1970
1971   return dyn_i;
1972 }
1973
1974 static asection *
1975 get_got (abfd, info, ia64_info)
1976      bfd *abfd;
1977      struct bfd_link_info *info;
1978      struct elfNN_ia64_link_hash_table *ia64_info;
1979 {
1980   asection *got;
1981   bfd *dynobj;
1982
1983   got = ia64_info->got_sec;
1984   if (!got)
1985     {
1986       flagword flags;
1987
1988       dynobj = ia64_info->root.dynobj;
1989       if (!dynobj)
1990         ia64_info->root.dynobj = dynobj = abfd;
1991       if (!_bfd_elf_create_got_section (dynobj, info))
1992         return 0;
1993
1994       got = bfd_get_section_by_name (dynobj, ".got");
1995       BFD_ASSERT (got);
1996       ia64_info->got_sec = got;
1997
1998       /* The .got section is always aligned at 8 bytes.  */
1999       if (!bfd_set_section_alignment (abfd, got, 3))
2000         return 0;
2001
2002       flags = bfd_get_section_flags (abfd, got);
2003       bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
2004     }
2005
2006   return got;
2007 }
2008
2009 /* Create function descriptor section (.opd).  This section is called .opd
2010    because it contains "official procedure descriptors".  The "official"
2011    refers to the fact that these descriptors are used when taking the address
2012    of a procedure, thus ensuring a unique address for each procedure.  */
2013
2014 static asection *
2015 get_fptr (abfd, info, ia64_info)
2016      bfd *abfd;
2017      struct bfd_link_info *info;
2018      struct elfNN_ia64_link_hash_table *ia64_info;
2019 {
2020   asection *fptr;
2021   bfd *dynobj;
2022
2023   fptr = ia64_info->fptr_sec;
2024   if (!fptr)
2025     {
2026       dynobj = ia64_info->root.dynobj;
2027       if (!dynobj)
2028         ia64_info->root.dynobj = dynobj = abfd;
2029
2030       fptr = bfd_make_section (dynobj, ".opd");
2031       if (!fptr
2032           || !bfd_set_section_flags (dynobj, fptr,
2033                                      (SEC_ALLOC
2034                                       | SEC_LOAD
2035                                       | SEC_HAS_CONTENTS
2036                                       | SEC_IN_MEMORY
2037                                       | (info->pie ? 0 : SEC_READONLY)
2038                                       | SEC_LINKER_CREATED))
2039           || !bfd_set_section_alignment (abfd, fptr, 4))
2040         {
2041           BFD_ASSERT (0);
2042           return NULL;
2043         }
2044
2045       ia64_info->fptr_sec = fptr;
2046
2047       if (info->pie)
2048         {
2049           asection *fptr_rel;
2050           fptr_rel = bfd_make_section(dynobj, ".rela.opd");
2051           if (fptr_rel == NULL
2052               || !bfd_set_section_flags (dynobj, fptr_rel,
2053                                          (SEC_ALLOC | SEC_LOAD
2054                                           | SEC_HAS_CONTENTS
2055                                           | SEC_IN_MEMORY
2056                                           | SEC_LINKER_CREATED
2057                                           | SEC_READONLY))
2058               || !bfd_set_section_alignment (abfd, fptr_rel, 3))
2059             {
2060               BFD_ASSERT (0);
2061               return NULL;
2062             }
2063
2064           ia64_info->rel_fptr_sec = fptr_rel;
2065         }
2066     }
2067
2068   return fptr;
2069 }
2070
2071 static asection *
2072 get_pltoff (abfd, info, ia64_info)
2073      bfd *abfd;
2074      struct bfd_link_info *info ATTRIBUTE_UNUSED;
2075      struct elfNN_ia64_link_hash_table *ia64_info;
2076 {
2077   asection *pltoff;
2078   bfd *dynobj;
2079
2080   pltoff = ia64_info->pltoff_sec;
2081   if (!pltoff)
2082     {
2083       dynobj = ia64_info->root.dynobj;
2084       if (!dynobj)
2085         ia64_info->root.dynobj = dynobj = abfd;
2086
2087       pltoff = bfd_make_section (dynobj, ELF_STRING_ia64_pltoff);
2088       if (!pltoff
2089           || !bfd_set_section_flags (dynobj, pltoff,
2090                                      (SEC_ALLOC
2091                                       | SEC_LOAD
2092                                       | SEC_HAS_CONTENTS
2093                                       | SEC_IN_MEMORY
2094                                       | SEC_SMALL_DATA
2095                                       | SEC_LINKER_CREATED))
2096           || !bfd_set_section_alignment (abfd, pltoff, 4))
2097         {
2098           BFD_ASSERT (0);
2099           return NULL;
2100         }
2101
2102       ia64_info->pltoff_sec = pltoff;
2103     }
2104
2105   return pltoff;
2106 }
2107
2108 static asection *
2109 get_reloc_section (abfd, ia64_info, sec, create)
2110      bfd *abfd;
2111      struct elfNN_ia64_link_hash_table *ia64_info;
2112      asection *sec;
2113      bfd_boolean create;
2114 {
2115   const char *srel_name;
2116   asection *srel;
2117   bfd *dynobj;
2118
2119   srel_name = (bfd_elf_string_from_elf_section
2120                (abfd, elf_elfheader(abfd)->e_shstrndx,
2121                 elf_section_data(sec)->rel_hdr.sh_name));
2122   if (srel_name == NULL)
2123     return NULL;
2124
2125   BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0
2126                && strcmp (bfd_get_section_name (abfd, sec),
2127                           srel_name+5) == 0)
2128               || (strncmp (srel_name, ".rel", 4) == 0
2129                   && strcmp (bfd_get_section_name (abfd, sec),
2130                              srel_name+4) == 0));
2131
2132   dynobj = ia64_info->root.dynobj;
2133   if (!dynobj)
2134     ia64_info->root.dynobj = dynobj = abfd;
2135
2136   srel = bfd_get_section_by_name (dynobj, srel_name);
2137   if (srel == NULL && create)
2138     {
2139       srel = bfd_make_section (dynobj, srel_name);
2140       if (srel == NULL
2141           || !bfd_set_section_flags (dynobj, srel,
2142                                      (SEC_ALLOC
2143                                       | SEC_LOAD
2144                                       | SEC_HAS_CONTENTS
2145                                       | SEC_IN_MEMORY
2146                                       | SEC_LINKER_CREATED
2147                                       | SEC_READONLY))
2148           || !bfd_set_section_alignment (dynobj, srel, 3))
2149         return NULL;
2150     }
2151
2152   return srel;
2153 }
2154
2155 static bfd_boolean
2156 count_dyn_reloc (bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
2157                  asection *srel, int type, bfd_boolean reltext)
2158 {
2159   struct elfNN_ia64_dyn_reloc_entry *rent;
2160
2161   for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2162     if (rent->srel == srel && rent->type == type)
2163       break;
2164
2165   if (!rent)
2166     {
2167       rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2168               bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
2169       if (!rent)
2170         return FALSE;
2171
2172       rent->next = dyn_i->reloc_entries;
2173       rent->srel = srel;
2174       rent->type = type;
2175       rent->count = 0;
2176       dyn_i->reloc_entries = rent;
2177     }
2178   rent->reltext = reltext;
2179   rent->count++;
2180
2181   return TRUE;
2182 }
2183
2184 static bfd_boolean
2185 elfNN_ia64_check_relocs (abfd, info, sec, relocs)
2186      bfd *abfd;
2187      struct bfd_link_info *info;
2188      asection *sec;
2189      const Elf_Internal_Rela *relocs;
2190 {
2191   struct elfNN_ia64_link_hash_table *ia64_info;
2192   const Elf_Internal_Rela *relend;
2193   Elf_Internal_Shdr *symtab_hdr;
2194   const Elf_Internal_Rela *rel;
2195   asection *got, *fptr, *srel, *pltoff;
2196
2197   if (info->relocatable)
2198     return TRUE;
2199
2200   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2201   ia64_info = elfNN_ia64_hash_table (info);
2202
2203   got = fptr = srel = pltoff = NULL;
2204
2205   relend = relocs + sec->reloc_count;
2206   for (rel = relocs; rel < relend; ++rel)
2207     {
2208       enum {
2209         NEED_GOT = 1,
2210         NEED_GOTX = 2,
2211         NEED_FPTR = 4,
2212         NEED_PLTOFF = 8,
2213         NEED_MIN_PLT = 16,
2214         NEED_FULL_PLT = 32,
2215         NEED_DYNREL = 64,
2216         NEED_LTOFF_FPTR = 128,
2217         NEED_TPREL = 256,
2218         NEED_DTPMOD = 512,
2219         NEED_DTPREL = 1024
2220       };
2221
2222       struct elf_link_hash_entry *h = NULL;
2223       unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
2224       struct elfNN_ia64_dyn_sym_info *dyn_i;
2225       int need_entry;
2226       bfd_boolean maybe_dynamic;
2227       int dynrel_type = R_IA64_NONE;
2228
2229       if (r_symndx >= symtab_hdr->sh_info)
2230         {
2231           /* We're dealing with a global symbol -- find its hash entry
2232              and mark it as being referenced.  */
2233           long indx = r_symndx - symtab_hdr->sh_info;
2234           h = elf_sym_hashes (abfd)[indx];
2235           while (h->root.type == bfd_link_hash_indirect
2236                  || h->root.type == bfd_link_hash_warning)
2237             h = (struct elf_link_hash_entry *) h->root.u.i.link;
2238
2239           h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
2240         }
2241
2242       /* We can only get preliminary data on whether a symbol is
2243          locally or externally defined, as not all of the input files
2244          have yet been processed.  Do something with what we know, as
2245          this may help reduce memory usage and processing time later.  */
2246       maybe_dynamic = FALSE;
2247       if (h && ((!info->executable
2248                  && (!info->symbolic || info->unresolved_syms_in_shared_libs == RM_IGNORE))
2249                 || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
2250                 || h->root.type == bfd_link_hash_defweak))
2251         maybe_dynamic = TRUE;
2252
2253       need_entry = 0;
2254       switch (ELFNN_R_TYPE (rel->r_info))
2255         {
2256         case R_IA64_TPREL64MSB:
2257         case R_IA64_TPREL64LSB:
2258           if (info->shared || maybe_dynamic)
2259             need_entry = NEED_DYNREL;
2260           dynrel_type = R_IA64_TPREL64LSB;
2261           if (info->shared)
2262             info->flags |= DF_STATIC_TLS;
2263           break;
2264
2265         case R_IA64_LTOFF_TPREL22:
2266           need_entry = NEED_TPREL;
2267           if (info->shared)
2268             info->flags |= DF_STATIC_TLS;
2269           break;
2270
2271         case R_IA64_DTPREL64MSB:
2272         case R_IA64_DTPREL64LSB:
2273           if (info->shared || maybe_dynamic)
2274             need_entry = NEED_DYNREL;
2275           dynrel_type = R_IA64_DTPREL64LSB;
2276           break;
2277
2278         case R_IA64_LTOFF_DTPREL22:
2279           need_entry = NEED_DTPREL;
2280           break;
2281
2282         case R_IA64_DTPMOD64MSB:
2283         case R_IA64_DTPMOD64LSB:
2284           if (info->shared || maybe_dynamic)
2285             need_entry = NEED_DYNREL;
2286           dynrel_type = R_IA64_DTPMOD64LSB;
2287           break;
2288
2289         case R_IA64_LTOFF_DTPMOD22:
2290           need_entry = NEED_DTPMOD;
2291           break;
2292
2293         case R_IA64_LTOFF_FPTR22:
2294         case R_IA64_LTOFF_FPTR64I:
2295         case R_IA64_LTOFF_FPTR32MSB:
2296         case R_IA64_LTOFF_FPTR32LSB:
2297         case R_IA64_LTOFF_FPTR64MSB:
2298         case R_IA64_LTOFF_FPTR64LSB:
2299           need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2300           break;
2301
2302         case R_IA64_FPTR64I:
2303         case R_IA64_FPTR32MSB:
2304         case R_IA64_FPTR32LSB:
2305         case R_IA64_FPTR64MSB:
2306         case R_IA64_FPTR64LSB:
2307           if (info->shared || h)
2308             need_entry = NEED_FPTR | NEED_DYNREL;
2309           else
2310             need_entry = NEED_FPTR;
2311           dynrel_type = R_IA64_FPTR64LSB;
2312           break;
2313
2314         case R_IA64_LTOFF22:
2315         case R_IA64_LTOFF64I:
2316           need_entry = NEED_GOT;
2317           break;
2318
2319         case R_IA64_LTOFF22X:
2320           need_entry = NEED_GOTX;
2321           break;
2322
2323         case R_IA64_PLTOFF22:
2324         case R_IA64_PLTOFF64I:
2325         case R_IA64_PLTOFF64MSB:
2326         case R_IA64_PLTOFF64LSB:
2327           need_entry = NEED_PLTOFF;
2328           if (h)
2329             {
2330               if (maybe_dynamic)
2331                 need_entry |= NEED_MIN_PLT;
2332             }
2333           else
2334             {
2335               (*info->callbacks->warning)
2336                 (info, _("@pltoff reloc against local symbol"), 0,
2337                  abfd, 0, (bfd_vma) 0);
2338             }
2339           break;
2340
2341         case R_IA64_PCREL21B:
2342         case R_IA64_PCREL60B:
2343           /* Depending on where this symbol is defined, we may or may not
2344              need a full plt entry.  Only skip if we know we'll not need
2345              the entry -- static or symbolic, and the symbol definition
2346              has already been seen.  */
2347           if (maybe_dynamic && rel->r_addend == 0)
2348             need_entry = NEED_FULL_PLT;
2349           break;
2350
2351         case R_IA64_IMM14:
2352         case R_IA64_IMM22:
2353         case R_IA64_IMM64:
2354         case R_IA64_DIR32MSB:
2355         case R_IA64_DIR32LSB:
2356         case R_IA64_DIR64MSB:
2357         case R_IA64_DIR64LSB:
2358           /* Shared objects will always need at least a REL relocation.  */
2359           if (info->shared || maybe_dynamic)
2360             need_entry = NEED_DYNREL;
2361           dynrel_type = R_IA64_DIR64LSB;
2362           break;
2363
2364         case R_IA64_IPLTMSB:
2365         case R_IA64_IPLTLSB:
2366           /* Shared objects will always need at least a REL relocation.  */
2367           if (info->shared || maybe_dynamic)
2368             need_entry = NEED_DYNREL;
2369           dynrel_type = R_IA64_IPLTLSB;
2370           break;
2371
2372         case R_IA64_PCREL22:
2373         case R_IA64_PCREL64I:
2374         case R_IA64_PCREL32MSB:
2375         case R_IA64_PCREL32LSB:
2376         case R_IA64_PCREL64MSB:
2377         case R_IA64_PCREL64LSB:
2378           if (maybe_dynamic)
2379             need_entry = NEED_DYNREL;
2380           dynrel_type = R_IA64_PCREL64LSB;
2381           break;
2382         }
2383
2384       if (!need_entry)
2385         continue;
2386
2387       if ((need_entry & NEED_FPTR) != 0
2388           && rel->r_addend)
2389         {
2390           (*info->callbacks->warning)
2391             (info, _("non-zero addend in @fptr reloc"), 0,
2392              abfd, 0, (bfd_vma) 0);
2393         }
2394
2395       dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, TRUE);
2396
2397       /* Record whether or not this is a local symbol.  */
2398       dyn_i->h = h;
2399
2400       /* Create what's needed.  */
2401       if (need_entry & (NEED_GOT | NEED_GOTX | NEED_TPREL
2402                         | NEED_DTPMOD | NEED_DTPREL))
2403         {
2404           if (!got)
2405             {
2406               got = get_got (abfd, info, ia64_info);
2407               if (!got)
2408                 return FALSE;
2409             }
2410           if (need_entry & NEED_GOT)
2411             dyn_i->want_got = 1;
2412           if (need_entry & NEED_GOTX)
2413             dyn_i->want_gotx = 1;
2414           if (need_entry & NEED_TPREL)
2415             dyn_i->want_tprel = 1;
2416           if (need_entry & NEED_DTPMOD)
2417             dyn_i->want_dtpmod = 1;
2418           if (need_entry & NEED_DTPREL)
2419             dyn_i->want_dtprel = 1;
2420         }
2421       if (need_entry & NEED_FPTR)
2422         {
2423           if (!fptr)
2424             {
2425               fptr = get_fptr (abfd, info, ia64_info);
2426               if (!fptr)
2427                 return FALSE;
2428             }
2429
2430           /* FPTRs for shared libraries are allocated by the dynamic
2431              linker.  Make sure this local symbol will appear in the
2432              dynamic symbol table.  */
2433           if (!h && info->shared)
2434             {
2435               if (! (bfd_elf_link_record_local_dynamic_symbol
2436                      (info, abfd, (long) r_symndx)))
2437                 return FALSE;
2438             }
2439
2440           dyn_i->want_fptr = 1;
2441         }
2442       if (need_entry & NEED_LTOFF_FPTR)
2443         dyn_i->want_ltoff_fptr = 1;
2444       if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
2445         {
2446           if (!ia64_info->root.dynobj)
2447             ia64_info->root.dynobj = abfd;
2448           h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
2449           dyn_i->want_plt = 1;
2450         }
2451       if (need_entry & NEED_FULL_PLT)
2452         dyn_i->want_plt2 = 1;
2453       if (need_entry & NEED_PLTOFF)
2454         {
2455           /* This is needed here, in case @pltoff is used in a non-shared
2456              link.  */
2457           if (!pltoff)
2458             {
2459               pltoff = get_pltoff (abfd, info, ia64_info);
2460               if (!pltoff)
2461                 return FALSE;
2462             }
2463           
2464           dyn_i->want_pltoff = 1;
2465         }
2466       if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
2467         {
2468           if (!srel)
2469             {
2470               srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
2471               if (!srel)
2472                 return FALSE;
2473             }
2474           if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type,
2475                                 (sec->flags & SEC_READONLY) != 0))
2476             return FALSE;
2477         }
2478     }
2479
2480   return TRUE;
2481 }
2482
2483 /* For cleanliness, and potentially faster dynamic loading, allocate
2484    external GOT entries first.  */
2485
2486 static bfd_boolean
2487 allocate_global_data_got (dyn_i, data)
2488      struct elfNN_ia64_dyn_sym_info *dyn_i;
2489      PTR data;
2490 {
2491   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2492
2493   if ((dyn_i->want_got || dyn_i->want_gotx)
2494       && ! dyn_i->want_fptr
2495       && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
2496      {
2497        dyn_i->got_offset = x->ofs;
2498        x->ofs += 8;
2499      }
2500   if (dyn_i->want_tprel)
2501     {
2502       dyn_i->tprel_offset = x->ofs;
2503       x->ofs += 8;
2504     }
2505   if (dyn_i->want_dtpmod)
2506     {
2507       if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
2508         {
2509           dyn_i->dtpmod_offset = x->ofs;
2510           x->ofs += 8;
2511         }
2512       else
2513         {
2514           struct elfNN_ia64_link_hash_table *ia64_info;
2515
2516           ia64_info = elfNN_ia64_hash_table (x->info);
2517           if (ia64_info->self_dtpmod_offset == (bfd_vma) -1)
2518             {
2519               ia64_info->self_dtpmod_offset = x->ofs;
2520               x->ofs += 8;
2521             }
2522           dyn_i->dtpmod_offset = ia64_info->self_dtpmod_offset;
2523         }
2524     }
2525   if (dyn_i->want_dtprel)
2526     {
2527       dyn_i->dtprel_offset = x->ofs;
2528       x->ofs += 8;
2529     }
2530   return TRUE;
2531 }
2532
2533 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs.  */
2534
2535 static bfd_boolean
2536 allocate_global_fptr_got (dyn_i, data)
2537      struct elfNN_ia64_dyn_sym_info *dyn_i;
2538      PTR data;
2539 {
2540   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2541
2542   if (dyn_i->want_got
2543       && dyn_i->want_fptr
2544       && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, R_IA64_FPTR64LSB))
2545     {
2546       dyn_i->got_offset = x->ofs;
2547       x->ofs += 8;
2548     }
2549   return TRUE;
2550 }
2551
2552 /* Lastly, allocate all the GOT entries for local data.  */
2553
2554 static bfd_boolean
2555 allocate_local_got (dyn_i, data)
2556      struct elfNN_ia64_dyn_sym_info *dyn_i;
2557      PTR data;
2558 {
2559   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2560
2561   if ((dyn_i->want_got || dyn_i->want_gotx)
2562       && !elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
2563     {
2564       dyn_i->got_offset = x->ofs;
2565       x->ofs += 8;
2566     }
2567   return TRUE;
2568 }
2569
2570 /* Search for the index of a global symbol in it's defining object file.  */
2571
2572 static long
2573 global_sym_index (h)
2574      struct elf_link_hash_entry *h;
2575 {
2576   struct elf_link_hash_entry **p;
2577   bfd *obj;
2578
2579   BFD_ASSERT (h->root.type == bfd_link_hash_defined
2580               || h->root.type == bfd_link_hash_defweak);
2581
2582   obj = h->root.u.def.section->owner;
2583   for (p = elf_sym_hashes (obj); *p != h; ++p)
2584     continue;
2585
2586   return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2587 }
2588
2589 /* Allocate function descriptors.  We can do these for every function
2590    in a main executable that is not exported.  */
2591
2592 static bfd_boolean
2593 allocate_fptr (dyn_i, data)
2594      struct elfNN_ia64_dyn_sym_info *dyn_i;
2595      PTR data;
2596 {
2597   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2598
2599   if (dyn_i->want_fptr)
2600     {
2601       struct elf_link_hash_entry *h = dyn_i->h;
2602
2603       if (h)
2604         while (h->root.type == bfd_link_hash_indirect
2605                || h->root.type == bfd_link_hash_warning)
2606           h = (struct elf_link_hash_entry *) h->root.u.i.link;
2607
2608       if (!x->info->executable
2609           && (!h
2610               || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
2611               || h->root.type != bfd_link_hash_undefweak))
2612         {
2613           if (h && h->dynindx == -1)
2614             {
2615               BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2616                           || (h->root.type == bfd_link_hash_defweak));
2617
2618               if (!bfd_elf_link_record_local_dynamic_symbol
2619                     (x->info, h->root.u.def.section->owner,
2620                      global_sym_index (h)))
2621                 return FALSE;
2622             }
2623
2624           dyn_i->want_fptr = 0;
2625         }
2626       else if (h == NULL || h->dynindx == -1)
2627         {
2628           dyn_i->fptr_offset = x->ofs;
2629           x->ofs += 16;
2630         }
2631       else
2632         dyn_i->want_fptr = 0;
2633     }
2634   return TRUE;
2635 }
2636
2637 /* Allocate all the minimal PLT entries.  */
2638
2639 static bfd_boolean
2640 allocate_plt_entries (dyn_i, data)
2641      struct elfNN_ia64_dyn_sym_info *dyn_i;
2642      PTR data;
2643 {
2644   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2645
2646   if (dyn_i->want_plt)
2647     {
2648       struct elf_link_hash_entry *h = dyn_i->h;
2649
2650       if (h)
2651         while (h->root.type == bfd_link_hash_indirect
2652                || h->root.type == bfd_link_hash_warning)
2653           h = (struct elf_link_hash_entry *) h->root.u.i.link;
2654
2655       /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT.  */
2656       if (elfNN_ia64_dynamic_symbol_p (h, x->info, 0))
2657         {
2658           bfd_size_type offset = x->ofs;
2659           if (offset == 0)
2660             offset = PLT_HEADER_SIZE;
2661           dyn_i->plt_offset = offset;
2662           x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2663
2664           dyn_i->want_pltoff = 1;
2665         }
2666       else
2667         {
2668           dyn_i->want_plt = 0;
2669           dyn_i->want_plt2 = 0;
2670         }
2671     }
2672   return TRUE;
2673 }
2674
2675 /* Allocate all the full PLT entries.  */
2676
2677 static bfd_boolean
2678 allocate_plt2_entries (dyn_i, data)
2679      struct elfNN_ia64_dyn_sym_info *dyn_i;
2680      PTR data;
2681 {
2682   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2683
2684   if (dyn_i->want_plt2)
2685     {
2686       struct elf_link_hash_entry *h = dyn_i->h;
2687       bfd_size_type ofs = x->ofs;
2688
2689       dyn_i->plt2_offset = ofs;
2690       x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2691
2692       while (h->root.type == bfd_link_hash_indirect
2693              || h->root.type == bfd_link_hash_warning)
2694         h = (struct elf_link_hash_entry *) h->root.u.i.link;
2695       dyn_i->h->plt.offset = ofs;
2696     }
2697   return TRUE;
2698 }
2699
2700 /* Allocate all the PLTOFF entries requested by relocations and
2701    plt entries.  We can't share space with allocated FPTR entries,
2702    because the latter are not necessarily addressable by the GP.
2703    ??? Relaxation might be able to determine that they are.  */
2704
2705 static bfd_boolean
2706 allocate_pltoff_entries (dyn_i, data)
2707      struct elfNN_ia64_dyn_sym_info *dyn_i;
2708      PTR data;
2709 {
2710   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2711
2712   if (dyn_i->want_pltoff)
2713     {
2714       dyn_i->pltoff_offset = x->ofs;
2715       x->ofs += 16;
2716     }
2717   return TRUE;
2718 }
2719
2720 /* Allocate dynamic relocations for those symbols that turned out
2721    to be dynamic.  */
2722
2723 static bfd_boolean
2724 allocate_dynrel_entries (dyn_i, data)
2725      struct elfNN_ia64_dyn_sym_info *dyn_i;
2726      PTR data;
2727 {
2728   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2729   struct elfNN_ia64_link_hash_table *ia64_info;
2730   struct elfNN_ia64_dyn_reloc_entry *rent;
2731   bfd_boolean dynamic_symbol, shared, resolved_zero;
2732
2733   ia64_info = elfNN_ia64_hash_table (x->info);
2734
2735   /* Note that this can't be used in relation to FPTR relocs below.  */
2736   dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0);
2737
2738   shared = x->info->shared;
2739   resolved_zero = (dyn_i->h
2740                    && ELF_ST_VISIBILITY (dyn_i->h->other)
2741                    && dyn_i->h->root.type == bfd_link_hash_undefweak);
2742
2743   /* Take care of the normal data relocations.  */
2744
2745   for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2746     {
2747       int count = rent->count;
2748
2749       switch (rent->type)
2750         {
2751         case R_IA64_FPTR64LSB:
2752           /* Allocate one iff !want_fptr and not PIE, which by this point
2753              will be true only if we're actually allocating one statically
2754              in the main executable.  Position independent executables
2755              need a relative reloc.  */
2756           if (dyn_i->want_fptr && !x->info->pie)
2757             continue;
2758           break;
2759         case R_IA64_PCREL64LSB:
2760           if (!dynamic_symbol)
2761             continue;
2762           break;
2763         case R_IA64_DIR64LSB:
2764           if (!dynamic_symbol && !shared)
2765             continue;
2766           break;
2767         case R_IA64_IPLTLSB:
2768           if (!dynamic_symbol && !shared)
2769             continue;
2770           /* Use two REL relocations for IPLT relocations
2771              against local symbols.  */
2772           if (!dynamic_symbol)
2773             count *= 2;
2774           break;
2775         case R_IA64_TPREL64LSB:
2776         case R_IA64_DTPREL64LSB:
2777         case R_IA64_DTPMOD64LSB:
2778           break;
2779         default:
2780           abort ();
2781         }
2782       if (rent->reltext)
2783         ia64_info->reltext = 1;
2784       rent->srel->size += sizeof (ElfNN_External_Rela) * count;
2785     }
2786
2787   /* Take care of the GOT and PLT relocations.  */
2788
2789   if ((!resolved_zero
2790        && (dynamic_symbol || shared)
2791        && (dyn_i->want_got || dyn_i->want_gotx))
2792       || (dyn_i->want_ltoff_fptr
2793           && dyn_i->h
2794           && dyn_i->h->dynindx != -1))
2795     {
2796       if (!dyn_i->want_ltoff_fptr
2797           || !x->info->pie
2798           || dyn_i->h == NULL
2799           || dyn_i->h->root.type != bfd_link_hash_undefweak)
2800         ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
2801     }
2802   if ((dynamic_symbol || shared) && dyn_i->want_tprel)
2803     ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
2804   if (dynamic_symbol && dyn_i->want_dtpmod)
2805     ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
2806   if (dynamic_symbol && dyn_i->want_dtprel)
2807     ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
2808   if (ia64_info->rel_fptr_sec && dyn_i->want_fptr)
2809     {
2810       if (dyn_i->h == NULL || dyn_i->h->root.type != bfd_link_hash_undefweak)
2811         ia64_info->rel_fptr_sec->size += sizeof (ElfNN_External_Rela);
2812     }
2813
2814   if (!resolved_zero && dyn_i->want_pltoff)
2815     {
2816       bfd_size_type t = 0;
2817
2818       /* Dynamic symbols get one IPLT relocation.  Local symbols in
2819          shared libraries get two REL relocations.  Local symbols in
2820          main applications get nothing.  */
2821       if (dynamic_symbol)
2822         t = sizeof (ElfNN_External_Rela);
2823       else if (shared)
2824         t = 2 * sizeof (ElfNN_External_Rela);
2825
2826       ia64_info->rel_pltoff_sec->size += t;
2827     }
2828
2829   return TRUE;
2830 }
2831
2832 static bfd_boolean
2833 elfNN_ia64_adjust_dynamic_symbol (info, h)
2834      struct bfd_link_info *info ATTRIBUTE_UNUSED;
2835      struct elf_link_hash_entry *h;
2836 {
2837   /* ??? Undefined symbols with PLT entries should be re-defined
2838      to be the PLT entry.  */
2839
2840   /* If this is a weak symbol, and there is a real definition, the
2841      processor independent code will have arranged for us to see the
2842      real definition first, and we can just use the same value.  */
2843   if (h->weakdef != NULL)
2844     {
2845       BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
2846                   || h->weakdef->root.type == bfd_link_hash_defweak);
2847       h->root.u.def.section = h->weakdef->root.u.def.section;
2848       h->root.u.def.value = h->weakdef->root.u.def.value;
2849       return TRUE;
2850     }
2851
2852   /* If this is a reference to a symbol defined by a dynamic object which
2853      is not a function, we might allocate the symbol in our .dynbss section
2854      and allocate a COPY dynamic relocation.
2855
2856      But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2857      of hackery.  */
2858
2859   return TRUE;
2860 }
2861
2862 static bfd_boolean
2863 elfNN_ia64_size_dynamic_sections (output_bfd, info)
2864      bfd *output_bfd ATTRIBUTE_UNUSED;
2865      struct bfd_link_info *info;
2866 {
2867   struct elfNN_ia64_allocate_data data;
2868   struct elfNN_ia64_link_hash_table *ia64_info;
2869   asection *sec;
2870   bfd *dynobj;
2871   bfd_boolean relplt = FALSE;
2872
2873   dynobj = elf_hash_table(info)->dynobj;
2874   ia64_info = elfNN_ia64_hash_table (info);
2875   ia64_info->self_dtpmod_offset = (bfd_vma) -1;
2876   BFD_ASSERT(dynobj != NULL);
2877   data.info = info;
2878
2879   /* Set the contents of the .interp section to the interpreter.  */
2880   if (ia64_info->root.dynamic_sections_created
2881       && info->executable)
2882     {
2883       sec = bfd_get_section_by_name (dynobj, ".interp");
2884       BFD_ASSERT (sec != NULL);
2885       sec->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
2886       sec->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
2887     }
2888
2889   /* Allocate the GOT entries.  */
2890
2891   if (ia64_info->got_sec)
2892     {
2893       data.ofs = 0;
2894       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
2895       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
2896       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
2897       ia64_info->got_sec->size = data.ofs;
2898     }
2899
2900   /* Allocate the FPTR entries.  */
2901
2902   if (ia64_info->fptr_sec)
2903     {
2904       data.ofs = 0;
2905       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
2906       ia64_info->fptr_sec->size = data.ofs;
2907     }
2908
2909   /* Now that we've seen all of the input files, we can decide which
2910      symbols need plt entries.  Allocate the minimal PLT entries first.
2911      We do this even though dynamic_sections_created may be FALSE, because
2912      this has the side-effect of clearing want_plt and want_plt2.  */
2913
2914   data.ofs = 0;
2915   elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
2916
2917   ia64_info->minplt_entries = 0;
2918   if (data.ofs)
2919     {
2920       ia64_info->minplt_entries
2921         = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
2922     }
2923
2924   /* Align the pointer for the plt2 entries.  */
2925   data.ofs = (data.ofs + 31) & (bfd_vma) -32;
2926
2927   elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
2928   if (data.ofs != 0 || ia64_info->root.dynamic_sections_created)
2929     {
2930       /* FIXME: we always reserve the memory for dynamic linker even if
2931          there are no PLT entries since dynamic linker may assume the
2932          reserved memory always exists.  */
2933
2934       BFD_ASSERT (ia64_info->root.dynamic_sections_created);
2935
2936       ia64_info->plt_sec->size = data.ofs;
2937
2938       /* If we've got a .plt, we need some extra memory for the dynamic
2939          linker.  We stuff these in .got.plt.  */
2940       sec = bfd_get_section_by_name (dynobj, ".got.plt");
2941       sec->size = 8 * PLT_RESERVED_WORDS;
2942     }
2943
2944   /* Allocate the PLTOFF entries.  */
2945
2946   if (ia64_info->pltoff_sec)
2947     {
2948       data.ofs = 0;
2949       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
2950       ia64_info->pltoff_sec->size = data.ofs;
2951     }
2952
2953   if (ia64_info->root.dynamic_sections_created)
2954     {
2955       /* Allocate space for the dynamic relocations that turned out to be
2956          required.  */
2957
2958       if (info->shared && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
2959         ia64_info->rel_got_sec->size += sizeof (ElfNN_External_Rela);
2960       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
2961     }
2962
2963   /* We have now determined the sizes of the various dynamic sections.
2964      Allocate memory for them.  */
2965   for (sec = dynobj->sections; sec != NULL; sec = sec->next)
2966     {
2967       bfd_boolean strip;
2968
2969       if (!(sec->flags & SEC_LINKER_CREATED))
2970         continue;
2971
2972       /* If we don't need this section, strip it from the output file.
2973          There were several sections primarily related to dynamic
2974          linking that must be create before the linker maps input
2975          sections to output sections.  The linker does that before
2976          bfd_elf_size_dynamic_sections is called, and it is that
2977          function which decides whether anything needs to go into
2978          these sections.  */
2979
2980       strip = (sec->size == 0);
2981
2982       if (sec == ia64_info->got_sec)
2983         strip = FALSE;
2984       else if (sec == ia64_info->rel_got_sec)
2985         {
2986           if (strip)
2987             ia64_info->rel_got_sec = NULL;
2988           else
2989             /* We use the reloc_count field as a counter if we need to
2990                copy relocs into the output file.  */
2991             sec->reloc_count = 0;
2992         }
2993       else if (sec == ia64_info->fptr_sec)
2994         {
2995           if (strip)
2996             ia64_info->fptr_sec = NULL;
2997         }
2998       else if (sec == ia64_info->rel_fptr_sec)
2999         {
3000           if (strip)
3001             ia64_info->rel_fptr_sec = NULL;
3002           else
3003             /* We use the reloc_count field as a counter if we need to
3004                copy relocs into the output file.  */
3005             sec->reloc_count = 0;
3006         }
3007       else if (sec == ia64_info->plt_sec)
3008         {
3009           if (strip)
3010             ia64_info->plt_sec = NULL;
3011         }
3012       else if (sec == ia64_info->pltoff_sec)
3013         {
3014           if (strip)
3015             ia64_info->pltoff_sec = NULL;
3016         }
3017       else if (sec == ia64_info->rel_pltoff_sec)
3018         {
3019           if (strip)
3020             ia64_info->rel_pltoff_sec = NULL;
3021           else
3022             {
3023               relplt = TRUE;
3024               /* We use the reloc_count field as a counter if we need to
3025                  copy relocs into the output file.  */
3026               sec->reloc_count = 0;
3027             }
3028         }
3029       else
3030         {
3031           const char *name;
3032
3033           /* It's OK to base decisions on the section name, because none
3034              of the dynobj section names depend upon the input files.  */
3035           name = bfd_get_section_name (dynobj, sec);
3036
3037           if (strcmp (name, ".got.plt") == 0)
3038             strip = FALSE;
3039           else if (strncmp (name, ".rel", 4) == 0)
3040             {
3041               if (!strip)
3042                 {
3043                   /* We use the reloc_count field as a counter if we need to
3044                      copy relocs into the output file.  */
3045                   sec->reloc_count = 0;
3046                 }
3047             }
3048           else
3049             continue;
3050         }
3051
3052       if (strip)
3053         _bfd_strip_section_from_output (info, sec);
3054       else
3055         {
3056           /* Allocate memory for the section contents.  */
3057           sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->size);
3058           if (sec->contents == NULL && sec->size != 0)
3059             return FALSE;
3060         }
3061     }
3062
3063   if (elf_hash_table (info)->dynamic_sections_created)
3064     {
3065       /* Add some entries to the .dynamic section.  We fill in the values
3066          later (in finish_dynamic_sections) but we must add the entries now
3067          so that we get the correct size for the .dynamic section.  */
3068
3069       if (info->executable)
3070         {
3071           /* The DT_DEBUG entry is filled in by the dynamic linker and used
3072              by the debugger.  */
3073 #define add_dynamic_entry(TAG, VAL) \
3074   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3075
3076           if (!add_dynamic_entry (DT_DEBUG, 0))
3077             return FALSE;
3078         }
3079
3080       if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
3081         return FALSE;
3082       if (!add_dynamic_entry (DT_PLTGOT, 0))
3083         return FALSE;
3084
3085       if (relplt)
3086         {
3087           if (!add_dynamic_entry (DT_PLTRELSZ, 0)
3088               || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3089               || !add_dynamic_entry (DT_JMPREL, 0))
3090             return FALSE;
3091         }
3092
3093       if (!add_dynamic_entry (DT_RELA, 0)
3094           || !add_dynamic_entry (DT_RELASZ, 0)
3095           || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
3096         return FALSE;
3097
3098       if (ia64_info->reltext)
3099         {
3100           if (!add_dynamic_entry (DT_TEXTREL, 0))
3101             return FALSE;
3102           info->flags |= DF_TEXTREL;
3103         }
3104     }
3105
3106   /* ??? Perhaps force __gp local.  */
3107
3108   return TRUE;
3109 }
3110
3111 static bfd_reloc_status_type
3112 elfNN_ia64_install_value (hit_addr, v, r_type)
3113      bfd_byte *hit_addr;
3114      bfd_vma v;
3115      unsigned int r_type;
3116 {
3117   const struct ia64_operand *op;
3118   int bigendian = 0, shift = 0;
3119   bfd_vma t0, t1, insn, dword;
3120   enum ia64_opnd opnd;
3121   const char *err;
3122   size_t size = 8;
3123 #ifdef BFD_HOST_U_64_BIT
3124   BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
3125 #else
3126   bfd_vma val = v;
3127 #endif
3128
3129   opnd = IA64_OPND_NIL;
3130   switch (r_type)
3131     {
3132     case R_IA64_NONE:
3133     case R_IA64_LDXMOV:
3134       return bfd_reloc_ok;
3135
3136       /* Instruction relocations.  */
3137
3138     case R_IA64_IMM14:
3139     case R_IA64_TPREL14:
3140     case R_IA64_DTPREL14:
3141       opnd = IA64_OPND_IMM14;
3142       break;
3143
3144     case R_IA64_PCREL21F:       opnd = IA64_OPND_TGT25; break;
3145     case R_IA64_PCREL21M:       opnd = IA64_OPND_TGT25b; break;
3146     case R_IA64_PCREL60B:       opnd = IA64_OPND_TGT64; break;
3147     case R_IA64_PCREL21B:
3148     case R_IA64_PCREL21BI:
3149       opnd = IA64_OPND_TGT25c;
3150       break;
3151
3152     case R_IA64_IMM22:
3153     case R_IA64_GPREL22:
3154     case R_IA64_LTOFF22:
3155     case R_IA64_LTOFF22X:
3156     case R_IA64_PLTOFF22:
3157     case R_IA64_PCREL22:
3158     case R_IA64_LTOFF_FPTR22:
3159     case R_IA64_TPREL22:
3160     case R_IA64_DTPREL22:
3161     case R_IA64_LTOFF_TPREL22:
3162     case R_IA64_LTOFF_DTPMOD22:
3163     case R_IA64_LTOFF_DTPREL22:
3164       opnd = IA64_OPND_IMM22;
3165       break;
3166
3167     case R_IA64_IMM64:
3168     case R_IA64_GPREL64I:
3169     case R_IA64_LTOFF64I:
3170     case R_IA64_PLTOFF64I:
3171     case R_IA64_PCREL64I:
3172     case R_IA64_FPTR64I:
3173     case R_IA64_LTOFF_FPTR64I:
3174     case R_IA64_TPREL64I:
3175     case R_IA64_DTPREL64I:
3176       opnd = IA64_OPND_IMMU64;
3177       break;
3178
3179       /* Data relocations.  */
3180
3181     case R_IA64_DIR32MSB:
3182     case R_IA64_GPREL32MSB:
3183     case R_IA64_FPTR32MSB:
3184     case R_IA64_PCREL32MSB:
3185     case R_IA64_LTOFF_FPTR32MSB:
3186     case R_IA64_SEGREL32MSB:
3187     case R_IA64_SECREL32MSB:
3188     case R_IA64_LTV32MSB:
3189     case R_IA64_DTPREL32MSB:
3190       size = 4; bigendian = 1;
3191       break;
3192
3193     case R_IA64_DIR32LSB:
3194     case R_IA64_GPREL32LSB:
3195     case R_IA64_FPTR32LSB:
3196     case R_IA64_PCREL32LSB:
3197     case R_IA64_LTOFF_FPTR32LSB:
3198     case R_IA64_SEGREL32LSB:
3199     case R_IA64_SECREL32LSB:
3200     case R_IA64_LTV32LSB:
3201     case R_IA64_DTPREL32LSB:
3202       size = 4; bigendian = 0;
3203       break;
3204
3205     case R_IA64_DIR64MSB:
3206     case R_IA64_GPREL64MSB:
3207     case R_IA64_PLTOFF64MSB:
3208     case R_IA64_FPTR64MSB:
3209     case R_IA64_PCREL64MSB:
3210     case R_IA64_LTOFF_FPTR64MSB:
3211     case R_IA64_SEGREL64MSB:
3212     case R_IA64_SECREL64MSB:
3213     case R_IA64_LTV64MSB:
3214     case R_IA64_TPREL64MSB:
3215     case R_IA64_DTPMOD64MSB:
3216     case R_IA64_DTPREL64MSB:
3217       size = 8; bigendian = 1;
3218       break;
3219
3220     case R_IA64_DIR64LSB:
3221     case R_IA64_GPREL64LSB:
3222     case R_IA64_PLTOFF64LSB:
3223     case R_IA64_FPTR64LSB:
3224     case R_IA64_PCREL64LSB:
3225     case R_IA64_LTOFF_FPTR64LSB:
3226     case R_IA64_SEGREL64LSB:
3227     case R_IA64_SECREL64LSB:
3228     case R_IA64_LTV64LSB:
3229     case R_IA64_TPREL64LSB:
3230     case R_IA64_DTPMOD64LSB:
3231     case R_IA64_DTPREL64LSB:
3232       size = 8; bigendian = 0;
3233       break;
3234
3235       /* Unsupported / Dynamic relocations.  */
3236     default:
3237       return bfd_reloc_notsupported;
3238     }
3239
3240   switch (opnd)
3241     {
3242     case IA64_OPND_IMMU64:
3243       hit_addr -= (long) hit_addr & 0x3;
3244       t0 = bfd_getl64 (hit_addr);
3245       t1 = bfd_getl64 (hit_addr + 8);
3246
3247       /* tmpl/s: bits  0.. 5 in t0
3248          slot 0: bits  5..45 in t0
3249          slot 1: bits 46..63 in t0, bits 0..22 in t1
3250          slot 2: bits 23..63 in t1 */
3251
3252       /* First, clear the bits that form the 64 bit constant.  */
3253       t0 &= ~(0x3ffffLL << 46);
3254       t1 &= ~(0x7fffffLL
3255               | ((  (0x07fLL << 13) | (0x1ffLL << 27)
3256                     | (0x01fLL << 22) | (0x001LL << 21)
3257                     | (0x001LL << 36)) << 23));
3258
3259       t0 |= ((val >> 22) & 0x03ffffLL) << 46;           /* 18 lsbs of imm41 */
3260       t1 |= ((val >> 40) & 0x7fffffLL) <<  0;           /* 23 msbs of imm41 */
3261       t1 |= (  (((val >>  0) & 0x07f) << 13)            /* imm7b */
3262                | (((val >>  7) & 0x1ff) << 27)          /* imm9d */
3263                | (((val >> 16) & 0x01f) << 22)          /* imm5c */
3264                | (((val >> 21) & 0x001) << 21)          /* ic */
3265                | (((val >> 63) & 0x001) << 36)) << 23;  /* i */
3266
3267       bfd_putl64 (t0, hit_addr);
3268       bfd_putl64 (t1, hit_addr + 8);
3269       break;
3270
3271     case IA64_OPND_TGT64:
3272       hit_addr -= (long) hit_addr & 0x3;
3273       t0 = bfd_getl64 (hit_addr);
3274       t1 = bfd_getl64 (hit_addr + 8);
3275
3276       /* tmpl/s: bits  0.. 5 in t0
3277          slot 0: bits  5..45 in t0
3278          slot 1: bits 46..63 in t0, bits 0..22 in t1
3279          slot 2: bits 23..63 in t1 */
3280
3281       /* First, clear the bits that form the 64 bit constant.  */
3282       t0 &= ~(0x3ffffLL << 46);
3283       t1 &= ~(0x7fffffLL
3284               | ((1LL << 36 | 0xfffffLL << 13) << 23));
3285
3286       val >>= 4;
3287       t0 |= ((val >> 20) & 0xffffLL) << 2 << 46;        /* 16 lsbs of imm39 */
3288       t1 |= ((val >> 36) & 0x7fffffLL) << 0;            /* 23 msbs of imm39 */
3289       t1 |= ((((val >> 0) & 0xfffffLL) << 13)           /* imm20b */
3290               | (((val >> 59) & 0x1LL) << 36)) << 23;   /* i */
3291
3292       bfd_putl64 (t0, hit_addr);
3293       bfd_putl64 (t1, hit_addr + 8);
3294       break;
3295
3296     default:
3297       switch ((long) hit_addr & 0x3)
3298         {
3299         case 0: shift =  5; break;
3300         case 1: shift = 14; hit_addr += 3; break;
3301         case 2: shift = 23; hit_addr += 6; break;
3302         case 3: return bfd_reloc_notsupported; /* shouldn't happen...  */
3303         }
3304       dword = bfd_getl64 (hit_addr);
3305       insn = (dword >> shift) & 0x1ffffffffffLL;
3306
3307       op = elf64_ia64_operands + opnd;
3308       err = (*op->insert) (op, val, (ia64_insn *)& insn);
3309       if (err)
3310         return bfd_reloc_overflow;
3311
3312       dword &= ~(0x1ffffffffffLL << shift);
3313       dword |= (insn << shift);
3314       bfd_putl64 (dword, hit_addr);
3315       break;
3316
3317     case IA64_OPND_NIL:
3318       /* A data relocation.  */
3319       if (bigendian)
3320         if (size == 4)
3321           bfd_putb32 (val, hit_addr);
3322         else
3323           bfd_putb64 (val, hit_addr);
3324       else
3325         if (size == 4)
3326           bfd_putl32 (val, hit_addr);
3327         else
3328           bfd_putl64 (val, hit_addr);
3329       break;
3330     }
3331
3332   return bfd_reloc_ok;
3333 }
3334
3335 static void
3336 elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
3337                               dynindx, addend)
3338      bfd *abfd;
3339      struct bfd_link_info *info;
3340      asection *sec;
3341      asection *srel;
3342      bfd_vma offset;
3343      unsigned int type;
3344      long dynindx;
3345      bfd_vma addend;
3346 {
3347   Elf_Internal_Rela outrel;
3348   bfd_byte *loc;
3349
3350   BFD_ASSERT (dynindx != -1);
3351   outrel.r_info = ELFNN_R_INFO (dynindx, type);
3352   outrel.r_addend = addend;
3353   outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
3354   if (outrel.r_offset >= (bfd_vma) -2)
3355     {
3356       /* Run for the hills.  We shouldn't be outputting a relocation
3357          for this.  So do what everyone else does and output a no-op.  */
3358       outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
3359       outrel.r_addend = 0;
3360       outrel.r_offset = 0;
3361     }
3362   else
3363     outrel.r_offset += sec->output_section->vma + sec->output_offset;
3364
3365   loc = srel->contents;
3366   loc += srel->reloc_count++ * sizeof (ElfNN_External_Rela);
3367   bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3368   BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count <= srel->size);
3369 }
3370
3371 /* Store an entry for target address TARGET_ADDR in the linkage table
3372    and return the gp-relative address of the linkage table entry.  */
3373
3374 static bfd_vma
3375 set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
3376      bfd *abfd;
3377      struct bfd_link_info *info;
3378      struct elfNN_ia64_dyn_sym_info *dyn_i;
3379      long dynindx;
3380      bfd_vma addend;
3381      bfd_vma value;
3382      unsigned int dyn_r_type;
3383 {
3384   struct elfNN_ia64_link_hash_table *ia64_info;
3385   asection *got_sec;
3386   bfd_boolean done;
3387   bfd_vma got_offset;
3388
3389   ia64_info = elfNN_ia64_hash_table (info);
3390   got_sec = ia64_info->got_sec;
3391
3392   switch (dyn_r_type)
3393     {
3394     case R_IA64_TPREL64LSB:
3395       done = dyn_i->tprel_done;
3396       dyn_i->tprel_done = TRUE;
3397       got_offset = dyn_i->tprel_offset;
3398       break;
3399     case R_IA64_DTPMOD64LSB:
3400       if (dyn_i->dtpmod_offset != ia64_info->self_dtpmod_offset)
3401         {
3402           done = dyn_i->dtpmod_done;
3403           dyn_i->dtpmod_done = TRUE;
3404         }
3405       else
3406         {
3407           done = ia64_info->self_dtpmod_done;
3408           ia64_info->self_dtpmod_done = TRUE;
3409           dynindx = 0;
3410         }
3411       got_offset = dyn_i->dtpmod_offset;
3412       break;
3413     case R_IA64_DTPREL64LSB:
3414       done = dyn_i->dtprel_done;
3415       dyn_i->dtprel_done = TRUE;
3416       got_offset = dyn_i->dtprel_offset;
3417       break;
3418     default:
3419       done = dyn_i->got_done;
3420       dyn_i->got_done = TRUE;
3421       got_offset = dyn_i->got_offset;
3422       break;
3423     }
3424
3425   BFD_ASSERT ((got_offset & 7) == 0);
3426
3427   if (! done)
3428     {
3429       /* Store the target address in the linkage table entry.  */
3430       bfd_put_64 (abfd, value, got_sec->contents + got_offset);
3431
3432       /* Install a dynamic relocation if needed.  */
3433       if (((info->shared
3434             && (!dyn_i->h
3435                 || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
3436                 || dyn_i->h->root.type != bfd_link_hash_undefweak)
3437             && dyn_r_type != R_IA64_DTPREL64LSB)
3438            || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info, dyn_r_type)
3439            || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
3440           && (!dyn_i->want_ltoff_fptr
3441               || !info->pie
3442               || !dyn_i->h
3443               || dyn_i->h->root.type != bfd_link_hash_undefweak))
3444         {
3445           if (dynindx == -1
3446               && dyn_r_type != R_IA64_TPREL64LSB
3447               && dyn_r_type != R_IA64_DTPMOD64LSB
3448               && dyn_r_type != R_IA64_DTPREL64LSB)
3449             {
3450               dyn_r_type = R_IA64_REL64LSB;
3451               dynindx = 0;
3452               addend = value;
3453             }
3454
3455           if (bfd_big_endian (abfd))
3456             {
3457               switch (dyn_r_type)
3458                 {
3459                 case R_IA64_REL64LSB:
3460                   dyn_r_type = R_IA64_REL64MSB;
3461                   break;
3462                 case R_IA64_DIR64LSB:
3463                   dyn_r_type = R_IA64_DIR64MSB;
3464                   break;
3465                 case R_IA64_FPTR64LSB:
3466                   dyn_r_type = R_IA64_FPTR64MSB;
3467                   break;
3468                 case R_IA64_TPREL64LSB:
3469                   dyn_r_type = R_IA64_TPREL64MSB;
3470                   break;
3471                 case R_IA64_DTPMOD64LSB:
3472                   dyn_r_type = R_IA64_DTPMOD64MSB;
3473                   break;
3474                 case R_IA64_DTPREL64LSB:
3475                   dyn_r_type = R_IA64_DTPREL64MSB;
3476                   break;
3477                 default:
3478                   BFD_ASSERT (FALSE);
3479                   break;
3480                 }
3481             }
3482
3483           elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
3484                                         ia64_info->rel_got_sec,
3485                                         got_offset, dyn_r_type,
3486                                         dynindx, addend);
3487         }
3488     }
3489
3490   /* Return the address of the linkage table entry.  */
3491   value = (got_sec->output_section->vma
3492            + got_sec->output_offset
3493            + got_offset);
3494
3495   return value;
3496 }
3497
3498 /* Fill in a function descriptor consisting of the function's code
3499    address and its global pointer.  Return the descriptor's address.  */
3500
3501 static bfd_vma
3502 set_fptr_entry (abfd, info, dyn_i, value)
3503      bfd *abfd;
3504      struct bfd_link_info *info;
3505      struct elfNN_ia64_dyn_sym_info *dyn_i;
3506      bfd_vma value;
3507 {
3508   struct elfNN_ia64_link_hash_table *ia64_info;
3509   asection *fptr_sec;
3510
3511   ia64_info = elfNN_ia64_hash_table (info);
3512   fptr_sec = ia64_info->fptr_sec;
3513
3514   if (!dyn_i->fptr_done)
3515     {
3516       dyn_i->fptr_done = 1;
3517
3518       /* Fill in the function descriptor.  */
3519       bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
3520       bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
3521                   fptr_sec->contents + dyn_i->fptr_offset + 8);
3522       if (ia64_info->rel_fptr_sec)
3523         {
3524           Elf_Internal_Rela outrel;
3525           bfd_byte *loc;
3526
3527           if (bfd_little_endian (abfd))
3528             outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTLSB);
3529           else
3530             outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTMSB);
3531           outrel.r_addend = value;
3532           outrel.r_offset = (fptr_sec->output_section->vma
3533                              + fptr_sec->output_offset
3534                              + dyn_i->fptr_offset);
3535           loc = ia64_info->rel_fptr_sec->contents;
3536           loc += ia64_info->rel_fptr_sec->reloc_count++
3537                  * sizeof (ElfNN_External_Rela);
3538           bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3539         }
3540     }
3541
3542   /* Return the descriptor's address.  */
3543   value = (fptr_sec->output_section->vma
3544            + fptr_sec->output_offset
3545            + dyn_i->fptr_offset);
3546
3547   return value;
3548 }
3549
3550 /* Fill in a PLTOFF entry consisting of the function's code address
3551    and its global pointer.  Return the descriptor's address.  */
3552
3553 static bfd_vma
3554 set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
3555      bfd *abfd;
3556      struct bfd_link_info *info;
3557      struct elfNN_ia64_dyn_sym_info *dyn_i;
3558      bfd_vma value;
3559      bfd_boolean is_plt;
3560 {
3561   struct elfNN_ia64_link_hash_table *ia64_info;
3562   asection *pltoff_sec;
3563
3564   ia64_info = elfNN_ia64_hash_table (info);
3565   pltoff_sec = ia64_info->pltoff_sec;
3566
3567   /* Don't do anything if this symbol uses a real PLT entry.  In
3568      that case, we'll fill this in during finish_dynamic_symbol.  */
3569   if ((! dyn_i->want_plt || is_plt)
3570       && !dyn_i->pltoff_done)
3571     {
3572       bfd_vma gp = _bfd_get_gp_value (abfd);
3573
3574       /* Fill in the function descriptor.  */
3575       bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
3576       bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
3577
3578       /* Install dynamic relocations if needed.  */
3579       if (!is_plt
3580           && info->shared
3581           && (!dyn_i->h
3582               || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
3583               || dyn_i->h->root.type != bfd_link_hash_undefweak))
3584         {
3585           unsigned int dyn_r_type;
3586
3587           if (bfd_big_endian (abfd))
3588             dyn_r_type = R_IA64_REL64MSB;
3589           else
3590             dyn_r_type = R_IA64_REL64LSB;
3591
3592           elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3593                                         ia64_info->rel_pltoff_sec,
3594                                         dyn_i->pltoff_offset,
3595                                         dyn_r_type, 0, value);
3596           elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3597                                         ia64_info->rel_pltoff_sec,
3598                                         dyn_i->pltoff_offset + 8,
3599                                         dyn_r_type, 0, gp);
3600         }
3601
3602       dyn_i->pltoff_done = 1;
3603     }
3604
3605   /* Return the descriptor's address.  */
3606   value = (pltoff_sec->output_section->vma
3607            + pltoff_sec->output_offset
3608            + dyn_i->pltoff_offset);
3609
3610   return value;
3611 }
3612
3613 /* Return the base VMA address which should be subtracted from real addresses
3614    when resolving @tprel() relocation.
3615    Main program TLS (whose template starts at PT_TLS p_vaddr)
3616    is assigned offset round(16, PT_TLS p_align).  */
3617
3618 static bfd_vma
3619 elfNN_ia64_tprel_base (info)
3620      struct bfd_link_info *info;
3621 {
3622   asection *tls_sec = elf_hash_table (info)->tls_sec;
3623
3624   BFD_ASSERT (tls_sec != NULL);
3625   return tls_sec->vma - align_power ((bfd_vma) 16, tls_sec->alignment_power);
3626 }
3627
3628 /* Return the base VMA address which should be subtracted from real addresses
3629    when resolving @dtprel() relocation.
3630    This is PT_TLS segment p_vaddr.  */
3631
3632 static bfd_vma
3633 elfNN_ia64_dtprel_base (info)
3634      struct bfd_link_info *info;
3635 {
3636   BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
3637   return elf_hash_table (info)->tls_sec->vma;
3638 }
3639
3640 /* Called through qsort to sort the .IA_64.unwind section during a
3641    non-relocatable link.  Set elfNN_ia64_unwind_entry_compare_bfd
3642    to the output bfd so we can do proper endianness frobbing.  */
3643
3644 static bfd *elfNN_ia64_unwind_entry_compare_bfd;
3645
3646 static int
3647 elfNN_ia64_unwind_entry_compare (a, b)
3648      const PTR a;
3649      const PTR b;
3650 {
3651   bfd_vma av, bv;
3652
3653   av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
3654   bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
3655
3656   return (av < bv ? -1 : av > bv ? 1 : 0);
3657 }
3658
3659 /* Make sure we've got ourselves a nice fat __gp value.  */
3660 static bfd_boolean
3661 elfNN_ia64_choose_gp (abfd, info)
3662      bfd *abfd;
3663      struct bfd_link_info *info;
3664 {
3665   bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
3666   bfd_vma min_short_vma = min_vma, max_short_vma = 0;
3667   struct elf_link_hash_entry *gp;
3668   bfd_vma gp_val;
3669   asection *os;
3670   struct elfNN_ia64_link_hash_table *ia64_info;
3671
3672   ia64_info = elfNN_ia64_hash_table (info);
3673
3674   /* Find the min and max vma of all sections marked short.  Also collect
3675      min and max vma of any type, for use in selecting a nice gp.  */
3676   for (os = abfd->sections; os ; os = os->next)
3677     {
3678       bfd_vma lo, hi;
3679
3680       if ((os->flags & SEC_ALLOC) == 0)
3681         continue;
3682
3683       lo = os->vma;
3684       hi = os->vma + os->size;
3685       if (hi < lo)
3686         hi = (bfd_vma) -1;
3687
3688       if (min_vma > lo)
3689         min_vma = lo;
3690       if (max_vma < hi)
3691         max_vma = hi;
3692       if (os->flags & SEC_SMALL_DATA)
3693         {
3694           if (min_short_vma > lo)
3695             min_short_vma = lo;
3696           if (max_short_vma < hi)
3697             max_short_vma = hi;
3698         }
3699     }
3700
3701   /* See if the user wants to force a value.  */
3702   gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3703                              FALSE, FALSE);
3704
3705   if (gp
3706       && (gp->root.type == bfd_link_hash_defined
3707           || gp->root.type == bfd_link_hash_defweak))
3708     {
3709       asection *gp_sec = gp->root.u.def.section;
3710       gp_val = (gp->root.u.def.value
3711                 + gp_sec->output_section->vma
3712                 + gp_sec->output_offset);
3713     }
3714   else
3715     {
3716       /* Pick a sensible value.  */
3717
3718       asection *got_sec = ia64_info->got_sec;
3719
3720       /* Start with just the address of the .got.  */
3721       if (got_sec)
3722         gp_val = got_sec->output_section->vma;
3723       else if (max_short_vma != 0)
3724         gp_val = min_short_vma;
3725       else
3726         gp_val = min_vma;
3727
3728       /* If it is possible to address the entire image, but we
3729          don't with the choice above, adjust.  */
3730       if (max_vma - min_vma < 0x400000
3731           && max_vma - gp_val <= 0x200000
3732           && gp_val - min_vma > 0x200000)
3733         gp_val = min_vma + 0x200000;
3734       else if (max_short_vma != 0)
3735         {
3736           /* If we don't cover all the short data, adjust.  */
3737           if (max_short_vma - gp_val >= 0x200000)
3738             gp_val = min_short_vma + 0x200000;
3739
3740           /* If we're addressing stuff past the end, adjust back.  */
3741           if (gp_val > max_vma)
3742             gp_val = max_vma - 0x200000 + 8;
3743         }
3744     }
3745
3746   /* Validate whether all SHF_IA_64_SHORT sections are within
3747      range of the chosen GP.  */
3748
3749   if (max_short_vma != 0)
3750     {
3751       if (max_short_vma - min_short_vma >= 0x400000)
3752         {
3753           (*_bfd_error_handler)
3754             (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3755              bfd_get_filename (abfd),
3756              (unsigned long) (max_short_vma - min_short_vma));
3757           return FALSE;
3758         }
3759       else if ((gp_val > min_short_vma
3760                 && gp_val - min_short_vma > 0x200000)
3761                || (gp_val < max_short_vma
3762                    && max_short_vma - gp_val >= 0x200000))
3763         {
3764           (*_bfd_error_handler)
3765             (_("%s: __gp does not cover short data segment"),
3766              bfd_get_filename (abfd));
3767           return FALSE;
3768         }
3769     }
3770
3771   _bfd_set_gp_value (abfd, gp_val);
3772
3773   return TRUE;
3774 }
3775
3776 static bfd_boolean
3777 elfNN_ia64_final_link (abfd, info)
3778      bfd *abfd;
3779      struct bfd_link_info *info;
3780 {
3781   struct elfNN_ia64_link_hash_table *ia64_info;
3782   asection *unwind_output_sec;
3783
3784   ia64_info = elfNN_ia64_hash_table (info);
3785
3786   /* Make sure we've got ourselves a nice fat __gp value.  */
3787   if (!info->relocatable)
3788     {
3789       bfd_vma gp_val = _bfd_get_gp_value (abfd);
3790       struct elf_link_hash_entry *gp;
3791
3792       if (gp_val == 0)
3793         {
3794           if (! elfNN_ia64_choose_gp (abfd, info))
3795             return FALSE;
3796           gp_val = _bfd_get_gp_value (abfd);
3797         }
3798
3799       gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3800                                  FALSE, FALSE);
3801       if (gp)
3802         {
3803           gp->root.type = bfd_link_hash_defined;
3804           gp->root.u.def.value = gp_val;
3805           gp->root.u.def.section = bfd_abs_section_ptr;
3806         }
3807     }
3808
3809   /* If we're producing a final executable, we need to sort the contents
3810      of the .IA_64.unwind section.  Force this section to be relocated
3811      into memory rather than written immediately to the output file.  */
3812   unwind_output_sec = NULL;
3813   if (!info->relocatable)
3814     {
3815       asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3816       if (s)
3817         {
3818           unwind_output_sec = s->output_section;
3819           unwind_output_sec->contents
3820             = bfd_malloc (unwind_output_sec->size);
3821           if (unwind_output_sec->contents == NULL)
3822             return FALSE;
3823         }
3824     }
3825
3826   /* Invoke the regular ELF backend linker to do all the work.  */
3827   if (!bfd_elf_final_link (abfd, info))
3828     return FALSE;
3829
3830   if (unwind_output_sec)
3831     {
3832       elfNN_ia64_unwind_entry_compare_bfd = abfd;
3833       qsort (unwind_output_sec->contents,
3834              (size_t) (unwind_output_sec->size / 24),
3835              24,
3836              elfNN_ia64_unwind_entry_compare);
3837
3838       if (! bfd_set_section_contents (abfd, unwind_output_sec,
3839                                       unwind_output_sec->contents, (bfd_vma) 0,
3840                                       unwind_output_sec->size))
3841         return FALSE;
3842     }
3843
3844   return TRUE;
3845 }
3846
3847 static bfd_boolean
3848 elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
3849                              contents, relocs, local_syms, local_sections)
3850      bfd *output_bfd;
3851      struct bfd_link_info *info;
3852      bfd *input_bfd;
3853      asection *input_section;
3854      bfd_byte *contents;
3855      Elf_Internal_Rela *relocs;
3856      Elf_Internal_Sym *local_syms;
3857      asection **local_sections;
3858 {
3859   struct elfNN_ia64_link_hash_table *ia64_info;
3860   Elf_Internal_Shdr *symtab_hdr;
3861   Elf_Internal_Rela *rel;
3862   Elf_Internal_Rela *relend;
3863   asection *srel;
3864   bfd_boolean ret_val = TRUE;   /* for non-fatal errors */
3865   bfd_vma gp_val;
3866
3867   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3868   ia64_info = elfNN_ia64_hash_table (info);
3869
3870   /* Infect various flags from the input section to the output section.  */
3871   if (info->relocatable)
3872     {
3873       bfd_vma flags;
3874
3875       flags = elf_section_data(input_section)->this_hdr.sh_flags;
3876       flags &= SHF_IA_64_NORECOV;
3877
3878       elf_section_data(input_section->output_section)
3879         ->this_hdr.sh_flags |= flags;
3880       return TRUE;
3881     }
3882
3883   gp_val = _bfd_get_gp_value (output_bfd);
3884   srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
3885
3886   rel = relocs;
3887   relend = relocs + input_section->reloc_count;
3888   for (; rel < relend; ++rel)
3889     {
3890       struct elf_link_hash_entry *h;
3891       struct elfNN_ia64_dyn_sym_info *dyn_i;
3892       bfd_reloc_status_type r;
3893       reloc_howto_type *howto;
3894       unsigned long r_symndx;
3895       Elf_Internal_Sym *sym;
3896       unsigned int r_type;
3897       bfd_vma value;
3898       asection *sym_sec;
3899       bfd_byte *hit_addr;
3900       bfd_boolean dynamic_symbol_p;
3901       bfd_boolean undef_weak_ref;
3902
3903       r_type = ELFNN_R_TYPE (rel->r_info);
3904       if (r_type > R_IA64_MAX_RELOC_CODE)
3905         {
3906           (*_bfd_error_handler)
3907             (_("%s: unknown relocation type %d"),
3908              bfd_archive_filename (input_bfd), (int)r_type);
3909           bfd_set_error (bfd_error_bad_value);
3910           ret_val = FALSE;
3911           continue;
3912         }
3913
3914       howto = lookup_howto (r_type);
3915       r_symndx = ELFNN_R_SYM (rel->r_info);
3916       h = NULL;
3917       sym = NULL;
3918       sym_sec = NULL;
3919       undef_weak_ref = FALSE;
3920
3921       if (r_symndx < symtab_hdr->sh_info)
3922         {
3923           /* Reloc against local symbol.  */
3924           asection *msec;
3925           sym = local_syms + r_symndx;
3926           sym_sec = local_sections[r_symndx];
3927           msec = sym_sec;
3928           value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
3929           if ((sym_sec->flags & SEC_MERGE)
3930               && ELF_ST_TYPE (sym->st_info) == STT_SECTION
3931               && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
3932             {
3933               struct elfNN_ia64_local_hash_entry *loc_h;
3934
3935               loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
3936               if (loc_h && ! loc_h->sec_merge_done)
3937                 {
3938                   struct elfNN_ia64_dyn_sym_info *dynent;
3939
3940                   for (dynent = loc_h->info; dynent; dynent = dynent->next)
3941                     {
3942                       msec = sym_sec;
3943                       dynent->addend =
3944                         _bfd_merged_section_offset (output_bfd, &msec,
3945                                                     elf_section_data (msec)->
3946                                                     sec_info,
3947                                                     sym->st_value
3948                                                     + dynent->addend);
3949                       dynent->addend -= sym->st_value;
3950                       dynent->addend += msec->output_section->vma
3951                                         + msec->output_offset
3952                                         - sym_sec->output_section->vma
3953                                         - sym_sec->output_offset;
3954                     }
3955                   loc_h->sec_merge_done = 1;
3956                 }
3957             }
3958         }
3959       else
3960         {
3961           bfd_boolean unresolved_reloc;
3962           bfd_boolean warned;
3963           struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
3964
3965           RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
3966                                    r_symndx, symtab_hdr, sym_hashes,
3967                                    h, sym_sec, value,
3968                                    unresolved_reloc, warned);
3969
3970           if (h->root.type == bfd_link_hash_undefweak)
3971             undef_weak_ref = TRUE;
3972           else if (warned)
3973             continue;
3974         }
3975
3976       hit_addr = contents + rel->r_offset;
3977       value += rel->r_addend;
3978       dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type);
3979
3980       switch (r_type)
3981         {
3982         case R_IA64_NONE:
3983         case R_IA64_LDXMOV:
3984           continue;
3985
3986         case R_IA64_IMM14:
3987         case R_IA64_IMM22:
3988         case R_IA64_IMM64:
3989         case R_IA64_DIR32MSB:
3990         case R_IA64_DIR32LSB:
3991         case R_IA64_DIR64MSB:
3992         case R_IA64_DIR64LSB:
3993           /* Install a dynamic relocation for this reloc.  */
3994           if ((dynamic_symbol_p || info->shared)
3995               && r_symndx != 0
3996               && (input_section->flags & SEC_ALLOC) != 0)
3997             {
3998               unsigned int dyn_r_type;
3999               long dynindx;
4000               bfd_vma addend;
4001
4002               BFD_ASSERT (srel != NULL);
4003
4004               switch (r_type)
4005                 {
4006                 case R_IA64_IMM14:
4007                 case R_IA64_IMM22:
4008                 case R_IA64_IMM64:
4009                   /* ??? People shouldn't be doing non-pic code in
4010                      shared libraries nor dynamic executables.  */
4011                   (*_bfd_error_handler)
4012                     (_("%s: non-pic code with imm relocation against dynamic symbol `%s'"),
4013                      bfd_archive_filename (input_bfd),
4014                      h->root.root.string);
4015                   ret_val = FALSE;
4016                   continue;
4017
4018                 default:
4019                   break;
4020                 }
4021
4022               /* If we don't need dynamic symbol lookup, find a
4023                  matching RELATIVE relocation.  */
4024               dyn_r_type = r_type;
4025               if (dynamic_symbol_p)
4026                 {
4027                   dynindx = h->dynindx;
4028                   addend = rel->r_addend;
4029                   value = 0;
4030                 }
4031               else
4032                 {
4033                   switch (r_type)
4034                     {
4035                     case R_IA64_DIR32MSB:
4036                       dyn_r_type = R_IA64_REL32MSB;
4037                       break;
4038                     case R_IA64_DIR32LSB:
4039                       dyn_r_type = R_IA64_REL32LSB;
4040                       break;
4041                     case R_IA64_DIR64MSB:
4042                       dyn_r_type = R_IA64_REL64MSB;
4043                       break;
4044                     case R_IA64_DIR64LSB:
4045                       dyn_r_type = R_IA64_REL64LSB;
4046                       break;
4047
4048                     default:
4049                       break;
4050                     }
4051                   dynindx = 0;
4052                   addend = value;
4053                 }
4054
4055               elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4056                                             srel, rel->r_offset, dyn_r_type,
4057                                             dynindx, addend);
4058             }
4059           /* Fall through.  */
4060
4061         case R_IA64_LTV32MSB:
4062         case R_IA64_LTV32LSB:
4063         case R_IA64_LTV64MSB:
4064         case R_IA64_LTV64LSB:
4065           r = elfNN_ia64_install_value (hit_addr, value, r_type);
4066           break;
4067
4068         case R_IA64_GPREL22:
4069         case R_IA64_GPREL64I:
4070         case R_IA64_GPREL32MSB:
4071         case R_IA64_GPREL32LSB:
4072         case R_IA64_GPREL64MSB:
4073         case R_IA64_GPREL64LSB:
4074           if (dynamic_symbol_p)
4075             {
4076               (*_bfd_error_handler)
4077                 (_("%s: @gprel relocation against dynamic symbol %s"),
4078                  bfd_archive_filename (input_bfd), h->root.root.string);
4079               ret_val = FALSE;
4080               continue;
4081             }
4082           value -= gp_val;
4083           r = elfNN_ia64_install_value (hit_addr, value, r_type);
4084           break;
4085
4086         case R_IA64_LTOFF22:
4087         case R_IA64_LTOFF22X:
4088         case R_IA64_LTOFF64I:
4089           dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4090           value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
4091                                  rel->r_addend, value, R_IA64_DIR64LSB);
4092           value -= gp_val;
4093           r = elfNN_ia64_install_value (hit_addr, value, r_type);
4094           break;
4095
4096         case R_IA64_PLTOFF22:
4097         case R_IA64_PLTOFF64I:
4098         case R_IA64_PLTOFF64MSB:
4099         case R_IA64_PLTOFF64LSB:
4100           dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4101           value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
4102           value -= gp_val;
4103           r = elfNN_ia64_install_value (hit_addr, value, r_type);
4104           break;
4105
4106         case R_IA64_FPTR64I:
4107         case R_IA64_FPTR32MSB:
4108         case R_IA64_FPTR32LSB:
4109         case R_IA64_FPTR64MSB:
4110         case R_IA64_FPTR64LSB:
4111           dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4112           if (dyn_i->want_fptr)
4113             {
4114               if (!undef_weak_ref)
4115                 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4116             }
4117           if (!dyn_i->want_fptr || info->pie)
4118             {
4119               long dynindx;
4120               unsigned int dyn_r_type = r_type;
4121               bfd_vma addend = rel->r_addend;
4122
4123               /* Otherwise, we expect the dynamic linker to create
4124                  the entry.  */
4125
4126               if (dyn_i->want_fptr)
4127                 {
4128                   if (r_type == R_IA64_FPTR64I)
4129                     {
4130                       /* We can't represent this without a dynamic symbol.
4131                          Adjust the relocation to be against an output
4132                          section symbol, which are always present in the
4133                          dynamic symbol table.  */
4134                       /* ??? People shouldn't be doing non-pic code in
4135                          shared libraries.  Hork.  */
4136                       (*_bfd_error_handler)
4137                         (_("%s: linking non-pic code in a position independent executable"),
4138                          bfd_archive_filename (input_bfd));
4139                       ret_val = FALSE;
4140                       continue;
4141                     }
4142                   dynindx = 0;
4143                   addend = value;
4144                   dyn_r_type = r_type + R_IA64_REL64LSB - R_IA64_FPTR64LSB;
4145                 }
4146               else if (h)
4147                 {
4148                   if (h->dynindx != -1)
4149                     dynindx = h->dynindx;
4150                   else
4151                     dynindx = (_bfd_elf_link_lookup_local_dynindx
4152                                (info, h->root.u.def.section->owner,
4153                                 global_sym_index (h)));
4154                   value = 0;
4155                 }
4156               else
4157                 {
4158                   dynindx = (_bfd_elf_link_lookup_local_dynindx
4159                              (info, input_bfd, (long) r_symndx));
4160                   value = 0;
4161                 }
4162
4163               elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4164                                             srel, rel->r_offset, dyn_r_type,
4165                                             dynindx, addend);
4166             }
4167
4168           r = elfNN_ia64_install_value (hit_addr, value, r_type);
4169           break;
4170
4171         case R_IA64_LTOFF_FPTR22:
4172         case R_IA64_LTOFF_FPTR64I:
4173         case R_IA64_LTOFF_FPTR32MSB:
4174         case R_IA64_LTOFF_FPTR32LSB:
4175         case R_IA64_LTOFF_FPTR64MSB:
4176         case R_IA64_LTOFF_FPTR64LSB:
4177           {
4178             long dynindx;
4179
4180             dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4181             if (dyn_i->want_fptr)
4182               {
4183                 BFD_ASSERT (h == NULL || h->dynindx == -1)
4184                 if (!undef_weak_ref)
4185                   value = set_fptr_entry (output_bfd, info, dyn_i, value);
4186                 dynindx = -1;
4187               }
4188             else
4189               {
4190                 /* Otherwise, we expect the dynamic linker to create
4191                    the entry.  */
4192                 if (h)
4193                   {
4194                     if (h->dynindx != -1)
4195                       dynindx = h->dynindx;
4196                     else
4197                       dynindx = (_bfd_elf_link_lookup_local_dynindx
4198                                  (info, h->root.u.def.section->owner,
4199                                   global_sym_index (h)));
4200                   }
4201                 else
4202                   dynindx = (_bfd_elf_link_lookup_local_dynindx
4203                              (info, input_bfd, (long) r_symndx));
4204                 value = 0;
4205               }
4206
4207             value = set_got_entry (output_bfd, info, dyn_i, dynindx,
4208                                    rel->r_addend, value, R_IA64_FPTR64LSB);
4209             value -= gp_val;
4210             r = elfNN_ia64_install_value (hit_addr, value, r_type);
4211           }
4212           break;
4213
4214         case R_IA64_PCREL32MSB:
4215         case R_IA64_PCREL32LSB:
4216         case R_IA64_PCREL64MSB:
4217         case R_IA64_PCREL64LSB:
4218           /* Install a dynamic relocation for this reloc.  */
4219           if (dynamic_symbol_p && r_symndx != 0)
4220             {
4221               BFD_ASSERT (srel != NULL);
4222
4223               elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4224                                             srel, rel->r_offset, r_type,
4225                                             h->dynindx, rel->r_addend);
4226             }
4227           goto finish_pcrel;
4228
4229         case R_IA64_PCREL21B:
4230         case R_IA64_PCREL60B:
4231           /* We should have created a PLT entry for any dynamic symbol.  */
4232           dyn_i = NULL;
4233           if (h)
4234             dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4235
4236           if (dyn_i && dyn_i->want_plt2)
4237             {
4238               /* Should have caught this earlier.  */
4239               BFD_ASSERT (rel->r_addend == 0);
4240
4241               value = (ia64_info->plt_sec->output_section->vma
4242                        + ia64_info->plt_sec->output_offset
4243                        + dyn_i->plt2_offset);
4244             }
4245           else
4246             {
4247               /* Since there's no PLT entry, Validate that this is
4248                  locally defined.  */
4249               BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
4250
4251               /* If the symbol is undef_weak, we shouldn't be trying
4252                  to call it.  There's every chance that we'd wind up
4253                  with an out-of-range fixup here.  Don't bother setting
4254                  any value at all.  */
4255               if (undef_weak_ref)
4256                 continue;
4257             }
4258           goto finish_pcrel;
4259
4260         case R_IA64_PCREL21BI:
4261         case R_IA64_PCREL21F:
4262         case R_IA64_PCREL21M:
4263         case R_IA64_PCREL22:
4264         case R_IA64_PCREL64I:
4265           /* The PCREL21BI reloc is specifically not intended for use with
4266              dynamic relocs.  PCREL21F and PCREL21M are used for speculation
4267              fixup code, and thus probably ought not be dynamic.  The 
4268              PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs.  */
4269           if (dynamic_symbol_p)
4270             {
4271               const char *msg;
4272
4273               if (r_type == R_IA64_PCREL21BI)
4274                 msg = _("%s: @internal branch to dynamic symbol %s");
4275               else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
4276                 msg = _("%s: speculation fixup to dynamic symbol %s");
4277               else
4278                 msg = _("%s: @pcrel relocation against dynamic symbol %s");
4279               (*_bfd_error_handler) (msg, bfd_archive_filename (input_bfd),
4280                                      h->root.root.string);
4281               ret_val = FALSE;
4282               continue;
4283             }
4284           goto finish_pcrel;
4285
4286         finish_pcrel:
4287           /* Make pc-relative.  */
4288           value -= (input_section->output_section->vma
4289                     + input_section->output_offset
4290                     + rel->r_offset) & ~ (bfd_vma) 0x3;
4291           r = elfNN_ia64_install_value (hit_addr, value, r_type);
4292           break;
4293
4294         case R_IA64_SEGREL32MSB:
4295         case R_IA64_SEGREL32LSB:
4296         case R_IA64_SEGREL64MSB:
4297         case R_IA64_SEGREL64LSB:
4298           if (r_symndx == 0)
4299             {
4300               /* If the input section was discarded from the output, then
4301                  do nothing.  */
4302               r = bfd_reloc_ok;
4303             }
4304           else
4305             {
4306               struct elf_segment_map *m;
4307               Elf_Internal_Phdr *p;
4308
4309               /* Find the segment that contains the output_section.  */
4310               for (m = elf_tdata (output_bfd)->segment_map,
4311                      p = elf_tdata (output_bfd)->phdr;
4312                    m != NULL;
4313                    m = m->next, p++)
4314                 {
4315                   int i;
4316                   for (i = m->count - 1; i >= 0; i--)
4317                     if (m->sections[i] == input_section->output_section)
4318                       break;
4319                   if (i >= 0)
4320                     break;
4321                 }
4322
4323               if (m == NULL)
4324                 {
4325                   r = bfd_reloc_notsupported;
4326                 }
4327               else
4328                 {
4329                   /* The VMA of the segment is the vaddr of the associated
4330                      program header.  */
4331                   if (value > p->p_vaddr)
4332                     value -= p->p_vaddr;
4333                   else
4334                     value = 0;
4335                   r = elfNN_ia64_install_value (hit_addr, value, r_type);
4336                 }
4337               break;
4338             }
4339
4340         case R_IA64_SECREL32MSB:
4341         case R_IA64_SECREL32LSB:
4342         case R_IA64_SECREL64MSB:
4343         case R_IA64_SECREL64LSB:
4344           /* Make output-section relative.  */
4345           if (value > input_section->output_section->vma)
4346             value -= input_section->output_section->vma;
4347           else
4348             value = 0;
4349           r = elfNN_ia64_install_value (hit_addr, value, r_type);
4350           break;
4351
4352         case R_IA64_IPLTMSB:
4353         case R_IA64_IPLTLSB:
4354           /* Install a dynamic relocation for this reloc.  */
4355           if ((dynamic_symbol_p || info->shared)
4356               && (input_section->flags & SEC_ALLOC) != 0)
4357             {
4358               BFD_ASSERT (srel != NULL);
4359
4360               /* If we don't need dynamic symbol lookup, install two
4361                  RELATIVE relocations.  */
4362               if (!dynamic_symbol_p)
4363                 {
4364                   unsigned int dyn_r_type;
4365
4366                   if (r_type == R_IA64_IPLTMSB)
4367                     dyn_r_type = R_IA64_REL64MSB;
4368                   else
4369                     dyn_r_type = R_IA64_REL64LSB;
4370
4371                   elfNN_ia64_install_dyn_reloc (output_bfd, info,
4372                                                 input_section,
4373                                                 srel, rel->r_offset,
4374                                                 dyn_r_type, 0, value);
4375                   elfNN_ia64_install_dyn_reloc (output_bfd, info,
4376                                                 input_section,
4377                                                 srel, rel->r_offset + 8,
4378                                                 dyn_r_type, 0, gp_val);
4379                 }
4380               else
4381                 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4382                                               srel, rel->r_offset, r_type,
4383                                               h->dynindx, rel->r_addend);
4384             }
4385
4386           if (r_type == R_IA64_IPLTMSB)
4387             r_type = R_IA64_DIR64MSB;
4388           else
4389             r_type = R_IA64_DIR64LSB;
4390           elfNN_ia64_install_value (hit_addr, value, r_type);
4391           r = elfNN_ia64_install_value (hit_addr + 8, gp_val, r_type);
4392           break;
4393
4394         case R_IA64_TPREL14:
4395         case R_IA64_TPREL22:
4396         case R_IA64_TPREL64I:
4397           value -= elfNN_ia64_tprel_base (info);
4398           r = elfNN_ia64_install_value (hit_addr, value, r_type);
4399           break;
4400
4401         case R_IA64_DTPREL14:
4402         case R_IA64_DTPREL22:
4403         case R_IA64_DTPREL64I:
4404         case R_IA64_DTPREL64LSB:
4405         case R_IA64_DTPREL64MSB:
4406           value -= elfNN_ia64_dtprel_base (info);
4407           r = elfNN_ia64_install_value (hit_addr, value, r_type);
4408           break;
4409
4410         case R_IA64_LTOFF_TPREL22:
4411         case R_IA64_LTOFF_DTPMOD22:
4412         case R_IA64_LTOFF_DTPREL22:
4413           {
4414             int got_r_type;
4415             long dynindx = h ? h->dynindx : -1;
4416             bfd_vma r_addend = rel->r_addend;
4417
4418             switch (r_type)
4419               {
4420               default:
4421               case R_IA64_LTOFF_TPREL22:
4422                 if (!dynamic_symbol_p)
4423                   {
4424                     if (!info->shared)
4425                       value -= elfNN_ia64_tprel_base (info);
4426                     else
4427                       {
4428                         r_addend += value - elfNN_ia64_dtprel_base (info);
4429                         dynindx = 0;
4430                       }
4431                   }
4432                 got_r_type = R_IA64_TPREL64LSB;
4433                 break;
4434               case R_IA64_LTOFF_DTPMOD22:
4435                 if (!dynamic_symbol_p && !info->shared)
4436                   value = 1;
4437                 got_r_type = R_IA64_DTPMOD64LSB;
4438                 break;
4439               case R_IA64_LTOFF_DTPREL22:
4440                 if (!dynamic_symbol_p)
4441                   value -= elfNN_ia64_dtprel_base (info);
4442                 got_r_type = R_IA64_DTPREL64LSB;
4443                 break;
4444               }
4445             dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4446             value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
4447                                    value, got_r_type);
4448             value -= gp_val;
4449             r = elfNN_ia64_install_value (hit_addr, value, r_type);
4450           }
4451           break;
4452
4453         default:
4454           r = bfd_reloc_notsupported;
4455           break;
4456         }
4457
4458       switch (r)
4459         {
4460         case bfd_reloc_ok:
4461           break;
4462
4463         case bfd_reloc_undefined:
4464           /* This can happen for global table relative relocs if
4465              __gp is undefined.  This is a panic situation so we
4466              don't try to continue.  */
4467           (*info->callbacks->undefined_symbol)
4468             (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
4469           return FALSE;
4470
4471         case bfd_reloc_notsupported:
4472           {
4473             const char *name;
4474
4475             if (h)
4476               name = h->root.root.string;
4477             else
4478               {
4479                 name = bfd_elf_string_from_elf_section (input_bfd,
4480                                                         symtab_hdr->sh_link,
4481                                                         sym->st_name);
4482                 if (name == NULL)
4483                   return FALSE;
4484                 if (*name == '\0')
4485                   name = bfd_section_name (input_bfd, input_section);
4486               }
4487             if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
4488                                               name, input_bfd,
4489                                               input_section, rel->r_offset))
4490               return FALSE;
4491             ret_val = FALSE;
4492           }
4493           break;
4494
4495         case bfd_reloc_dangerous:
4496         case bfd_reloc_outofrange:
4497         case bfd_reloc_overflow:
4498         default:
4499           {
4500             const char *name;
4501
4502             if (h)
4503               name = h->root.root.string;
4504             else
4505               {
4506                 name = bfd_elf_string_from_elf_section (input_bfd,
4507                                                         symtab_hdr->sh_link,
4508                                                         sym->st_name);
4509                 if (name == NULL)
4510                   return FALSE;
4511                 if (*name == '\0')
4512                   name = bfd_section_name (input_bfd, input_section);
4513               }
4514             if (!(*info->callbacks->reloc_overflow) (info, name,
4515                                                      howto->name,
4516                                                      (bfd_vma) 0,
4517                                                      input_bfd,
4518                                                      input_section,
4519                                                      rel->r_offset))
4520               return FALSE;
4521             ret_val = FALSE;
4522           }
4523           break;
4524         }
4525     }
4526
4527   return ret_val;
4528 }
4529
4530 static bfd_boolean
4531 elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
4532      bfd *output_bfd;
4533      struct bfd_link_info *info;
4534      struct elf_link_hash_entry *h;
4535      Elf_Internal_Sym *sym;
4536 {
4537   struct elfNN_ia64_link_hash_table *ia64_info;
4538   struct elfNN_ia64_dyn_sym_info *dyn_i;
4539
4540   ia64_info = elfNN_ia64_hash_table (info);
4541   dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4542
4543   /* Fill in the PLT data, if required.  */
4544   if (dyn_i && dyn_i->want_plt)
4545     {
4546       Elf_Internal_Rela outrel;
4547       bfd_byte *loc;
4548       asection *plt_sec;
4549       bfd_vma plt_addr, pltoff_addr, gp_val, index;
4550
4551       gp_val = _bfd_get_gp_value (output_bfd);
4552
4553       /* Initialize the minimal PLT entry.  */
4554
4555       index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
4556       plt_sec = ia64_info->plt_sec;
4557       loc = plt_sec->contents + dyn_i->plt_offset;
4558
4559       memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
4560       elfNN_ia64_install_value (loc, index, R_IA64_IMM22);
4561       elfNN_ia64_install_value (loc+2, -dyn_i->plt_offset, R_IA64_PCREL21B);
4562
4563       plt_addr = (plt_sec->output_section->vma
4564                   + plt_sec->output_offset
4565                   + dyn_i->plt_offset);
4566       pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
4567
4568       /* Initialize the FULL PLT entry, if needed.  */
4569       if (dyn_i->want_plt2)
4570         {
4571           loc = plt_sec->contents + dyn_i->plt2_offset;
4572
4573           memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
4574           elfNN_ia64_install_value (loc, pltoff_addr - gp_val, R_IA64_IMM22);
4575
4576           /* Mark the symbol as undefined, rather than as defined in the
4577              plt section.  Leave the value alone.  */
4578           /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4579              first place.  But perhaps elflink.c did some for us.  */
4580           if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
4581             sym->st_shndx = SHN_UNDEF;
4582         }
4583
4584       /* Create the dynamic relocation.  */
4585       outrel.r_offset = pltoff_addr;
4586       if (bfd_little_endian (output_bfd))
4587         outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
4588       else
4589         outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
4590       outrel.r_addend = 0;
4591
4592       /* This is fun.  In the .IA_64.pltoff section, we've got entries
4593          that correspond both to real PLT entries, and those that
4594          happened to resolve to local symbols but need to be created
4595          to satisfy @pltoff relocations.  The .rela.IA_64.pltoff
4596          relocations for the real PLT should come at the end of the
4597          section, so that they can be indexed by plt entry at runtime.
4598
4599          We emitted all of the relocations for the non-PLT @pltoff
4600          entries during relocate_section.  So we can consider the
4601          existing sec->reloc_count to be the base of the array of
4602          PLT relocations.  */
4603
4604       loc = ia64_info->rel_pltoff_sec->contents;
4605       loc += ((ia64_info->rel_pltoff_sec->reloc_count + index)
4606               * sizeof (ElfNN_External_Rela));
4607       bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
4608     }
4609
4610   /* Mark some specially defined symbols as absolute.  */
4611   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4612       || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
4613       || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4614     sym->st_shndx = SHN_ABS;
4615
4616   return TRUE;
4617 }
4618
4619 static bfd_boolean
4620 elfNN_ia64_finish_dynamic_sections (abfd, info)
4621      bfd *abfd;
4622      struct bfd_link_info *info;
4623 {
4624   struct elfNN_ia64_link_hash_table *ia64_info;
4625   bfd *dynobj;
4626
4627   ia64_info = elfNN_ia64_hash_table (info);
4628   dynobj = ia64_info->root.dynobj;
4629
4630   if (elf_hash_table (info)->dynamic_sections_created)
4631     {
4632       ElfNN_External_Dyn *dyncon, *dynconend;
4633       asection *sdyn, *sgotplt;
4634       bfd_vma gp_val;
4635
4636       sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4637       sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
4638       BFD_ASSERT (sdyn != NULL);
4639       dyncon = (ElfNN_External_Dyn *) sdyn->contents;
4640       dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
4641
4642       gp_val = _bfd_get_gp_value (abfd);
4643
4644       for (; dyncon < dynconend; dyncon++)
4645         {
4646           Elf_Internal_Dyn dyn;
4647
4648           bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
4649
4650           switch (dyn.d_tag)
4651             {
4652             case DT_PLTGOT:
4653               dyn.d_un.d_ptr = gp_val;
4654               break;
4655
4656             case DT_PLTRELSZ:
4657               dyn.d_un.d_val = (ia64_info->minplt_entries
4658                                 * sizeof (ElfNN_External_Rela));
4659               break;
4660
4661             case DT_JMPREL:
4662               /* See the comment above in finish_dynamic_symbol.  */
4663               dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
4664                                 + ia64_info->rel_pltoff_sec->output_offset
4665                                 + (ia64_info->rel_pltoff_sec->reloc_count
4666                                    * sizeof (ElfNN_External_Rela)));
4667               break;
4668
4669             case DT_IA_64_PLT_RESERVE:
4670               dyn.d_un.d_ptr = (sgotplt->output_section->vma
4671                                 + sgotplt->output_offset);
4672               break;
4673
4674             case DT_RELASZ:
4675               /* Do not have RELASZ include JMPREL.  This makes things
4676                  easier on ld.so.  This is not what the rest of BFD set up.  */
4677               dyn.d_un.d_val -= (ia64_info->minplt_entries
4678                                  * sizeof (ElfNN_External_Rela));
4679               break;
4680             }
4681
4682           bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
4683         }
4684
4685       /* Initialize the PLT0 entry.  */
4686       if (ia64_info->plt_sec)
4687         {
4688           bfd_byte *loc = ia64_info->plt_sec->contents;
4689           bfd_vma pltres;
4690
4691           memcpy (loc, plt_header, PLT_HEADER_SIZE);
4692
4693           pltres = (sgotplt->output_section->vma
4694                     + sgotplt->output_offset
4695                     - gp_val);
4696
4697           elfNN_ia64_install_value (loc+1, pltres, R_IA64_GPREL22);
4698         }
4699     }
4700
4701   return TRUE;
4702 }
4703 \f
4704 /* ELF file flag handling:  */
4705
4706 /* Function to keep IA-64 specific file flags.  */
4707 static bfd_boolean
4708 elfNN_ia64_set_private_flags (abfd, flags)
4709      bfd *abfd;
4710      flagword flags;
4711 {
4712   BFD_ASSERT (!elf_flags_init (abfd)
4713               || elf_elfheader (abfd)->e_flags == flags);
4714
4715   elf_elfheader (abfd)->e_flags = flags;
4716   elf_flags_init (abfd) = TRUE;
4717   return TRUE;
4718 }
4719
4720 /* Merge backend specific data from an object file to the output
4721    object file when linking.  */
4722 static bfd_boolean
4723 elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
4724      bfd *ibfd, *obfd;
4725 {
4726   flagword out_flags;
4727   flagword in_flags;
4728   bfd_boolean ok = TRUE;
4729
4730   /* Don't even pretend to support mixed-format linking.  */
4731   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4732       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4733     return FALSE;
4734
4735   in_flags  = elf_elfheader (ibfd)->e_flags;
4736   out_flags = elf_elfheader (obfd)->e_flags;
4737
4738   if (! elf_flags_init (obfd))
4739     {
4740       elf_flags_init (obfd) = TRUE;
4741       elf_elfheader (obfd)->e_flags = in_flags;
4742
4743       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4744           && bfd_get_arch_info (obfd)->the_default)
4745         {
4746           return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4747                                     bfd_get_mach (ibfd));
4748         }
4749
4750       return TRUE;
4751     }
4752
4753   /* Check flag compatibility.  */
4754   if (in_flags == out_flags)
4755     return TRUE;
4756
4757   /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set.  */
4758   if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
4759     elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
4760
4761   if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
4762     {
4763       (*_bfd_error_handler)
4764         (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4765          bfd_archive_filename (ibfd));
4766
4767       bfd_set_error (bfd_error_bad_value);
4768       ok = FALSE;
4769     }
4770   if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
4771     {
4772       (*_bfd_error_handler)
4773         (_("%s: linking big-endian files with little-endian files"),
4774          bfd_archive_filename (ibfd));
4775
4776       bfd_set_error (bfd_error_bad_value);
4777       ok = FALSE;
4778     }
4779   if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4780     {
4781       (*_bfd_error_handler)
4782         (_("%s: linking 64-bit files with 32-bit files"),
4783          bfd_archive_filename (ibfd));
4784
4785       bfd_set_error (bfd_error_bad_value);
4786       ok = FALSE;
4787     }
4788   if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4789     {
4790       (*_bfd_error_handler)
4791         (_("%s: linking constant-gp files with non-constant-gp files"),
4792          bfd_archive_filename (ibfd));
4793
4794       bfd_set_error (bfd_error_bad_value);
4795       ok = FALSE;
4796     }
4797   if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4798       != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4799     {
4800       (*_bfd_error_handler)
4801         (_("%s: linking auto-pic files with non-auto-pic files"),
4802          bfd_archive_filename (ibfd));
4803
4804       bfd_set_error (bfd_error_bad_value);
4805       ok = FALSE;
4806     }
4807
4808   return ok;
4809 }
4810
4811 static bfd_boolean
4812 elfNN_ia64_print_private_bfd_data (abfd, ptr)
4813      bfd *abfd;
4814      PTR ptr;
4815 {
4816   FILE *file = (FILE *) ptr;
4817   flagword flags = elf_elfheader (abfd)->e_flags;
4818
4819   BFD_ASSERT (abfd != NULL && ptr != NULL);
4820
4821   fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4822            (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4823            (flags & EF_IA_64_EXT) ? "EXT, " : "",
4824            (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4825            (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4826            (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4827            (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4828            (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4829            (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4830
4831   _bfd_elf_print_private_bfd_data (abfd, ptr);
4832   return TRUE;
4833 }
4834
4835 static enum elf_reloc_type_class
4836 elfNN_ia64_reloc_type_class (rela)
4837      const Elf_Internal_Rela *rela;
4838 {
4839   switch ((int) ELFNN_R_TYPE (rela->r_info))
4840     {
4841     case R_IA64_REL32MSB:
4842     case R_IA64_REL32LSB:
4843     case R_IA64_REL64MSB:
4844     case R_IA64_REL64LSB:
4845       return reloc_class_relative;
4846     case R_IA64_IPLTMSB:
4847     case R_IA64_IPLTLSB:
4848       return reloc_class_plt;
4849     case R_IA64_COPY:
4850       return reloc_class_copy;
4851     default:
4852       return reloc_class_normal;
4853     }
4854 }
4855
4856 static struct bfd_elf_special_section const elfNN_ia64_special_sections[]=
4857 {
4858   { ".sbss",  5, -1, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
4859   { ".sdata", 6, -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
4860   { NULL,     0,  0, 0,            0 }
4861 };
4862
4863 static bfd_boolean
4864 elfNN_ia64_hpux_vec (const bfd_target *vec)
4865 {
4866   extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
4867   return (vec == & bfd_elfNN_ia64_hpux_big_vec);
4868 }
4869
4870 static void
4871 elfNN_hpux_post_process_headers (abfd, info)
4872         bfd *abfd;
4873         struct bfd_link_info *info ATTRIBUTE_UNUSED;
4874 {
4875   Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
4876
4877   i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_HPUX;
4878   i_ehdrp->e_ident[EI_ABIVERSION] = 1;
4879 }
4880
4881 bfd_boolean
4882 elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
4883         bfd *abfd ATTRIBUTE_UNUSED;
4884         asection *sec;
4885         int *retval;
4886 {
4887   if (bfd_is_com_section (sec))
4888     {
4889       *retval = SHN_IA_64_ANSI_COMMON;
4890       return TRUE;
4891     }
4892   return FALSE;
4893 }
4894
4895 static void
4896 elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
4897                                       asymbol *asym)
4898 {
4899   elf_symbol_type *elfsym = (elf_symbol_type *) asym;;
4900
4901   switch (elfsym->internal_elf_sym.st_shndx)
4902     {
4903     case SHN_IA_64_ANSI_COMMON:
4904       asym->section = bfd_com_section_ptr;
4905       asym->value = elfsym->internal_elf_sym.st_size;
4906       asym->flags &= ~BSF_GLOBAL;
4907       break;
4908     }
4909 }
4910
4911 \f
4912 #define TARGET_LITTLE_SYM               bfd_elfNN_ia64_little_vec
4913 #define TARGET_LITTLE_NAME              "elfNN-ia64-little"
4914 #define TARGET_BIG_SYM                  bfd_elfNN_ia64_big_vec
4915 #define TARGET_BIG_NAME                 "elfNN-ia64-big"
4916 #define ELF_ARCH                        bfd_arch_ia64
4917 #define ELF_MACHINE_CODE                EM_IA_64
4918 #define ELF_MACHINE_ALT1                1999    /* EAS2.3 */
4919 #define ELF_MACHINE_ALT2                1998    /* EAS2.2 */
4920 #define ELF_MAXPAGESIZE                 0x10000 /* 64KB */
4921
4922 #define elf_backend_section_from_shdr \
4923         elfNN_ia64_section_from_shdr
4924 #define elf_backend_section_flags \
4925         elfNN_ia64_section_flags
4926 #define elf_backend_fake_sections \
4927         elfNN_ia64_fake_sections
4928 #define elf_backend_final_write_processing \
4929         elfNN_ia64_final_write_processing
4930 #define elf_backend_add_symbol_hook \
4931         elfNN_ia64_add_symbol_hook
4932 #define elf_backend_additional_program_headers \
4933         elfNN_ia64_additional_program_headers
4934 #define elf_backend_modify_segment_map \
4935         elfNN_ia64_modify_segment_map
4936 #define elf_info_to_howto \
4937         elfNN_ia64_info_to_howto
4938
4939 #define bfd_elfNN_bfd_reloc_type_lookup \
4940         elfNN_ia64_reloc_type_lookup
4941 #define bfd_elfNN_bfd_is_local_label_name \
4942         elfNN_ia64_is_local_label_name
4943 #define bfd_elfNN_bfd_relax_section \
4944         elfNN_ia64_relax_section
4945
4946 /* Stuff for the BFD linker: */
4947 #define bfd_elfNN_bfd_link_hash_table_create \
4948         elfNN_ia64_hash_table_create
4949 #define bfd_elfNN_bfd_link_hash_table_free \
4950         elfNN_ia64_hash_table_free
4951 #define elf_backend_create_dynamic_sections \
4952         elfNN_ia64_create_dynamic_sections
4953 #define elf_backend_check_relocs \
4954         elfNN_ia64_check_relocs
4955 #define elf_backend_adjust_dynamic_symbol \
4956         elfNN_ia64_adjust_dynamic_symbol
4957 #define elf_backend_size_dynamic_sections \
4958         elfNN_ia64_size_dynamic_sections
4959 #define elf_backend_relocate_section \
4960         elfNN_ia64_relocate_section
4961 #define elf_backend_finish_dynamic_symbol \
4962         elfNN_ia64_finish_dynamic_symbol
4963 #define elf_backend_finish_dynamic_sections \
4964         elfNN_ia64_finish_dynamic_sections
4965 #define bfd_elfNN_bfd_final_link \
4966         elfNN_ia64_final_link
4967
4968 #define bfd_elfNN_bfd_merge_private_bfd_data \
4969         elfNN_ia64_merge_private_bfd_data
4970 #define bfd_elfNN_bfd_set_private_flags \
4971         elfNN_ia64_set_private_flags
4972 #define bfd_elfNN_bfd_print_private_bfd_data \
4973         elfNN_ia64_print_private_bfd_data
4974
4975 #define elf_backend_plt_readonly        1
4976 #define elf_backend_want_plt_sym        0
4977 #define elf_backend_plt_alignment       5
4978 #define elf_backend_got_header_size     0
4979 #define elf_backend_want_got_plt        1
4980 #define elf_backend_may_use_rel_p       1
4981 #define elf_backend_may_use_rela_p      1
4982 #define elf_backend_default_use_rela_p  1
4983 #define elf_backend_want_dynbss         0
4984 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4985 #define elf_backend_hide_symbol         elfNN_ia64_hash_hide_symbol
4986 #define elf_backend_reloc_type_class    elfNN_ia64_reloc_type_class
4987 #define elf_backend_rela_normal         1
4988 #define elf_backend_special_sections    elfNN_ia64_special_sections
4989
4990 #include "elfNN-target.h"
4991
4992 /* HPUX-specific vectors.  */
4993
4994 #undef  TARGET_LITTLE_SYM
4995 #undef  TARGET_LITTLE_NAME
4996 #undef  TARGET_BIG_SYM
4997 #define TARGET_BIG_SYM                  bfd_elfNN_ia64_hpux_big_vec
4998 #undef  TARGET_BIG_NAME
4999 #define TARGET_BIG_NAME                 "elfNN-ia64-hpux-big"
5000
5001 /* These are HP-UX specific functions.  */
5002
5003 #undef  elf_backend_post_process_headers
5004 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
5005
5006 #undef  elf_backend_section_from_bfd_section
5007 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
5008
5009 #undef elf_backend_symbol_processing
5010 #define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
5011
5012 #undef  elf_backend_want_p_paddr_set_to_zero
5013 #define elf_backend_want_p_paddr_set_to_zero 1
5014
5015 #undef  ELF_MAXPAGESIZE
5016 #define ELF_MAXPAGESIZE                 0x1000  /* 1K */
5017
5018 #undef  elfNN_bed
5019 #define elfNN_bed elfNN_ia64_hpux_bed
5020
5021 #include "elfNN-target.h"
5022
5023 #undef  elf_backend_want_p_paddr_set_to_zero