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