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