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