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