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