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