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