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