OSDN Git Service

* Makefile.am: Remove all mention of elflink.h.
[pf3gnuchains/pf3gnuchains3x.git] / 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)
2945     {
2946       BFD_ASSERT (ia64_info->root.dynamic_sections_created);
2947
2948       ia64_info->plt_sec->_raw_size = data.ofs;
2949
2950       /* If we've got a .plt, we need some extra memory for the dynamic
2951          linker.  We stuff these in .got.plt.  */
2952       sec = bfd_get_section_by_name (dynobj, ".got.plt");
2953       sec->_raw_size = 8 * PLT_RESERVED_WORDS;
2954     }
2955
2956   /* Allocate the PLTOFF entries.  */
2957
2958   if (ia64_info->pltoff_sec)
2959     {
2960       data.ofs = 0;
2961       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
2962       ia64_info->pltoff_sec->_raw_size = data.ofs;
2963     }
2964
2965   if (ia64_info->root.dynamic_sections_created)
2966     {
2967       /* Allocate space for the dynamic relocations that turned out to be
2968          required.  */
2969
2970       if (info->shared && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
2971         ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2972       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
2973     }
2974
2975   /* We have now determined the sizes of the various dynamic sections.
2976      Allocate memory for them.  */
2977   for (sec = dynobj->sections; sec != NULL; sec = sec->next)
2978     {
2979       bfd_boolean strip;
2980
2981       if (!(sec->flags & SEC_LINKER_CREATED))
2982         continue;
2983
2984       /* If we don't need this section, strip it from the output file.
2985          There were several sections primarily related to dynamic
2986          linking that must be create before the linker maps input
2987          sections to output sections.  The linker does that before
2988          bfd_elf_size_dynamic_sections is called, and it is that
2989          function which decides whether anything needs to go into
2990          these sections.  */
2991
2992       strip = (sec->_raw_size == 0);
2993
2994       if (sec == ia64_info->got_sec)
2995         strip = FALSE;
2996       else if (sec == ia64_info->rel_got_sec)
2997         {
2998           if (strip)
2999             ia64_info->rel_got_sec = NULL;
3000           else
3001             /* We use the reloc_count field as a counter if we need to
3002                copy relocs into the output file.  */
3003             sec->reloc_count = 0;
3004         }
3005       else if (sec == ia64_info->fptr_sec)
3006         {
3007           if (strip)
3008             ia64_info->fptr_sec = NULL;
3009         }
3010       else if (sec == ia64_info->rel_fptr_sec)
3011         {
3012           if (strip)
3013             ia64_info->rel_fptr_sec = NULL;
3014           else
3015             /* We use the reloc_count field as a counter if we need to
3016                copy relocs into the output file.  */
3017             sec->reloc_count = 0;
3018         }
3019       else if (sec == ia64_info->plt_sec)
3020         {
3021           if (strip)
3022             ia64_info->plt_sec = NULL;
3023         }
3024       else if (sec == ia64_info->pltoff_sec)
3025         {
3026           if (strip)
3027             ia64_info->pltoff_sec = NULL;
3028         }
3029       else if (sec == ia64_info->rel_pltoff_sec)
3030         {
3031           if (strip)
3032             ia64_info->rel_pltoff_sec = NULL;
3033           else
3034             {
3035               relplt = TRUE;
3036               /* We use the reloc_count field as a counter if we need to
3037                  copy relocs into the output file.  */
3038               sec->reloc_count = 0;
3039             }
3040         }
3041       else
3042         {
3043           const char *name;
3044
3045           /* It's OK to base decisions on the section name, because none
3046              of the dynobj section names depend upon the input files.  */
3047           name = bfd_get_section_name (dynobj, sec);
3048
3049           if (strcmp (name, ".got.plt") == 0)
3050             strip = FALSE;
3051           else if (strncmp (name, ".rel", 4) == 0)
3052             {
3053               if (!strip)
3054                 {
3055                   /* We use the reloc_count field as a counter if we need to
3056                      copy relocs into the output file.  */
3057                   sec->reloc_count = 0;
3058                 }
3059             }
3060           else
3061             continue;
3062         }
3063
3064       if (strip)
3065         _bfd_strip_section_from_output (info, sec);
3066       else
3067         {
3068           /* Allocate memory for the section contents.  */
3069           sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->_raw_size);
3070           if (sec->contents == NULL && sec->_raw_size != 0)
3071             return FALSE;
3072         }
3073     }
3074
3075   if (elf_hash_table (info)->dynamic_sections_created)
3076     {
3077       /* Add some entries to the .dynamic section.  We fill in the values
3078          later (in finish_dynamic_sections) but we must add the entries now
3079          so that we get the correct size for the .dynamic section.  */
3080
3081       if (info->executable)
3082         {
3083           /* The DT_DEBUG entry is filled in by the dynamic linker and used
3084              by the debugger.  */
3085 #define add_dynamic_entry(TAG, VAL) \
3086   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3087
3088           if (!add_dynamic_entry (DT_DEBUG, 0))
3089             return FALSE;
3090         }
3091
3092       if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
3093         return FALSE;
3094       if (!add_dynamic_entry (DT_PLTGOT, 0))
3095         return FALSE;
3096
3097       if (relplt)
3098         {
3099           if (!add_dynamic_entry (DT_PLTRELSZ, 0)
3100               || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3101               || !add_dynamic_entry (DT_JMPREL, 0))
3102             return FALSE;
3103         }
3104
3105       if (!add_dynamic_entry (DT_RELA, 0)
3106           || !add_dynamic_entry (DT_RELASZ, 0)
3107           || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
3108         return FALSE;
3109
3110       if (ia64_info->reltext)
3111         {
3112           if (!add_dynamic_entry (DT_TEXTREL, 0))
3113             return FALSE;
3114           info->flags |= DF_TEXTREL;
3115         }
3116     }
3117
3118   /* ??? Perhaps force __gp local.  */
3119
3120   return TRUE;
3121 }
3122
3123 static bfd_reloc_status_type
3124 elfNN_ia64_install_value (abfd, hit_addr, v, r_type)
3125      bfd *abfd;
3126      bfd_byte *hit_addr;
3127      bfd_vma v;
3128      unsigned int r_type;
3129 {
3130   const struct ia64_operand *op;
3131   int bigendian = 0, shift = 0;
3132   bfd_vma t0, t1, insn, dword;
3133   enum ia64_opnd opnd;
3134   const char *err;
3135   size_t size = 8;
3136 #ifdef BFD_HOST_U_64_BIT
3137   BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
3138 #else
3139   bfd_vma val = v;
3140 #endif
3141
3142   opnd = IA64_OPND_NIL;
3143   switch (r_type)
3144     {
3145     case R_IA64_NONE:
3146     case R_IA64_LDXMOV:
3147       return bfd_reloc_ok;
3148
3149       /* Instruction relocations.  */
3150
3151     case R_IA64_IMM14:
3152     case R_IA64_TPREL14:
3153     case R_IA64_DTPREL14:
3154       opnd = IA64_OPND_IMM14;
3155       break;
3156
3157     case R_IA64_PCREL21F:       opnd = IA64_OPND_TGT25; break;
3158     case R_IA64_PCREL21M:       opnd = IA64_OPND_TGT25b; break;
3159     case R_IA64_PCREL60B:       opnd = IA64_OPND_TGT64; break;
3160     case R_IA64_PCREL21B:
3161     case R_IA64_PCREL21BI:
3162       opnd = IA64_OPND_TGT25c;
3163       break;
3164
3165     case R_IA64_IMM22:
3166     case R_IA64_GPREL22:
3167     case R_IA64_LTOFF22:
3168     case R_IA64_LTOFF22X:
3169     case R_IA64_PLTOFF22:
3170     case R_IA64_PCREL22:
3171     case R_IA64_LTOFF_FPTR22:
3172     case R_IA64_TPREL22:
3173     case R_IA64_DTPREL22:
3174     case R_IA64_LTOFF_TPREL22:
3175     case R_IA64_LTOFF_DTPMOD22:
3176     case R_IA64_LTOFF_DTPREL22:
3177       opnd = IA64_OPND_IMM22;
3178       break;
3179
3180     case R_IA64_IMM64:
3181     case R_IA64_GPREL64I:
3182     case R_IA64_LTOFF64I:
3183     case R_IA64_PLTOFF64I:
3184     case R_IA64_PCREL64I:
3185     case R_IA64_FPTR64I:
3186     case R_IA64_LTOFF_FPTR64I:
3187     case R_IA64_TPREL64I:
3188     case R_IA64_DTPREL64I:
3189       opnd = IA64_OPND_IMMU64;
3190       break;
3191
3192       /* Data relocations.  */
3193
3194     case R_IA64_DIR32MSB:
3195     case R_IA64_GPREL32MSB:
3196     case R_IA64_FPTR32MSB:
3197     case R_IA64_PCREL32MSB:
3198     case R_IA64_LTOFF_FPTR32MSB:
3199     case R_IA64_SEGREL32MSB:
3200     case R_IA64_SECREL32MSB:
3201     case R_IA64_LTV32MSB:
3202     case R_IA64_DTPREL32MSB:
3203       size = 4; bigendian = 1;
3204       break;
3205
3206     case R_IA64_DIR32LSB:
3207     case R_IA64_GPREL32LSB:
3208     case R_IA64_FPTR32LSB:
3209     case R_IA64_PCREL32LSB:
3210     case R_IA64_LTOFF_FPTR32LSB:
3211     case R_IA64_SEGREL32LSB:
3212     case R_IA64_SECREL32LSB:
3213     case R_IA64_LTV32LSB:
3214     case R_IA64_DTPREL32LSB:
3215       size = 4; bigendian = 0;
3216       break;
3217
3218     case R_IA64_DIR64MSB:
3219     case R_IA64_GPREL64MSB:
3220     case R_IA64_PLTOFF64MSB:
3221     case R_IA64_FPTR64MSB:
3222     case R_IA64_PCREL64MSB:
3223     case R_IA64_LTOFF_FPTR64MSB:
3224     case R_IA64_SEGREL64MSB:
3225     case R_IA64_SECREL64MSB:
3226     case R_IA64_LTV64MSB:
3227     case R_IA64_TPREL64MSB:
3228     case R_IA64_DTPMOD64MSB:
3229     case R_IA64_DTPREL64MSB:
3230       size = 8; bigendian = 1;
3231       break;
3232
3233     case R_IA64_DIR64LSB:
3234     case R_IA64_GPREL64LSB:
3235     case R_IA64_PLTOFF64LSB:
3236     case R_IA64_FPTR64LSB:
3237     case R_IA64_PCREL64LSB:
3238     case R_IA64_LTOFF_FPTR64LSB:
3239     case R_IA64_SEGREL64LSB:
3240     case R_IA64_SECREL64LSB:
3241     case R_IA64_LTV64LSB:
3242     case R_IA64_TPREL64LSB:
3243     case R_IA64_DTPMOD64LSB:
3244     case R_IA64_DTPREL64LSB:
3245       size = 8; bigendian = 0;
3246       break;
3247
3248       /* Unsupported / Dynamic relocations.  */
3249     default:
3250       return bfd_reloc_notsupported;
3251     }
3252
3253   switch (opnd)
3254     {
3255     case IA64_OPND_IMMU64:
3256       hit_addr -= (long) hit_addr & 0x3;
3257       t0 = bfd_get_64 (abfd, hit_addr);
3258       t1 = bfd_get_64 (abfd, hit_addr + 8);
3259
3260       /* tmpl/s: bits  0.. 5 in t0
3261          slot 0: bits  5..45 in t0
3262          slot 1: bits 46..63 in t0, bits 0..22 in t1
3263          slot 2: bits 23..63 in t1 */
3264
3265       /* First, clear the bits that form the 64 bit constant.  */
3266       t0 &= ~(0x3ffffLL << 46);
3267       t1 &= ~(0x7fffffLL
3268               | ((  (0x07fLL << 13) | (0x1ffLL << 27)
3269                     | (0x01fLL << 22) | (0x001LL << 21)
3270                     | (0x001LL << 36)) << 23));
3271
3272       t0 |= ((val >> 22) & 0x03ffffLL) << 46;           /* 18 lsbs of imm41 */
3273       t1 |= ((val >> 40) & 0x7fffffLL) <<  0;           /* 23 msbs of imm41 */
3274       t1 |= (  (((val >>  0) & 0x07f) << 13)            /* imm7b */
3275                | (((val >>  7) & 0x1ff) << 27)          /* imm9d */
3276                | (((val >> 16) & 0x01f) << 22)          /* imm5c */
3277                | (((val >> 21) & 0x001) << 21)          /* ic */
3278                | (((val >> 63) & 0x001) << 36)) << 23;  /* i */
3279
3280       bfd_put_64 (abfd, t0, hit_addr);
3281       bfd_put_64 (abfd, t1, hit_addr + 8);
3282       break;
3283
3284     case IA64_OPND_TGT64:
3285       hit_addr -= (long) hit_addr & 0x3;
3286       t0 = bfd_get_64 (abfd, hit_addr);
3287       t1 = bfd_get_64 (abfd, hit_addr + 8);
3288
3289       /* tmpl/s: bits  0.. 5 in t0
3290          slot 0: bits  5..45 in t0
3291          slot 1: bits 46..63 in t0, bits 0..22 in t1
3292          slot 2: bits 23..63 in t1 */
3293
3294       /* First, clear the bits that form the 64 bit constant.  */
3295       t0 &= ~(0x3ffffLL << 46);
3296       t1 &= ~(0x7fffffLL
3297               | ((1LL << 36 | 0xfffffLL << 13) << 23));
3298
3299       val >>= 4;
3300       t0 |= ((val >> 20) & 0xffffLL) << 2 << 46;        /* 16 lsbs of imm39 */
3301       t1 |= ((val >> 36) & 0x7fffffLL) << 0;            /* 23 msbs of imm39 */
3302       t1 |= ((((val >> 0) & 0xfffffLL) << 13)           /* imm20b */
3303               | (((val >> 59) & 0x1LL) << 36)) << 23;   /* i */
3304
3305       bfd_put_64 (abfd, t0, hit_addr);
3306       bfd_put_64 (abfd, t1, hit_addr + 8);
3307       break;
3308
3309     default:
3310       switch ((long) hit_addr & 0x3)
3311         {
3312         case 0: shift =  5; break;
3313         case 1: shift = 14; hit_addr += 3; break;
3314         case 2: shift = 23; hit_addr += 6; break;
3315         case 3: return bfd_reloc_notsupported; /* shouldn't happen...  */
3316         }
3317       dword = bfd_get_64 (abfd, hit_addr);
3318       insn = (dword >> shift) & 0x1ffffffffffLL;
3319
3320       op = elf64_ia64_operands + opnd;
3321       err = (*op->insert) (op, val, (ia64_insn *)& insn);
3322       if (err)
3323         return bfd_reloc_overflow;
3324
3325       dword &= ~(0x1ffffffffffLL << shift);
3326       dword |= (insn << shift);
3327       bfd_put_64 (abfd, dword, hit_addr);
3328       break;
3329
3330     case IA64_OPND_NIL:
3331       /* A data relocation.  */
3332       if (bigendian)
3333         if (size == 4)
3334           bfd_putb32 (val, hit_addr);
3335         else
3336           bfd_putb64 (val, hit_addr);
3337       else
3338         if (size == 4)
3339           bfd_putl32 (val, hit_addr);
3340         else
3341           bfd_putl64 (val, hit_addr);
3342       break;
3343     }
3344
3345   return bfd_reloc_ok;
3346 }
3347
3348 static void
3349 elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
3350                               dynindx, addend)
3351      bfd *abfd;
3352      struct bfd_link_info *info;
3353      asection *sec;
3354      asection *srel;
3355      bfd_vma offset;
3356      unsigned int type;
3357      long dynindx;
3358      bfd_vma addend;
3359 {
3360   Elf_Internal_Rela outrel;
3361   bfd_byte *loc;
3362
3363   BFD_ASSERT (dynindx != -1);
3364   outrel.r_info = ELFNN_R_INFO (dynindx, type);
3365   outrel.r_addend = addend;
3366   outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
3367   if (outrel.r_offset >= (bfd_vma) -2)
3368     {
3369       /* Run for the hills.  We shouldn't be outputting a relocation
3370          for this.  So do what everyone else does and output a no-op.  */
3371       outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
3372       outrel.r_addend = 0;
3373       outrel.r_offset = 0;
3374     }
3375   else
3376     outrel.r_offset += sec->output_section->vma + sec->output_offset;
3377
3378   loc = srel->contents;
3379   loc += srel->reloc_count++ * sizeof (ElfNN_External_Rela);
3380   bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3381   BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count
3382               <= srel->_cooked_size);
3383 }
3384
3385 /* Store an entry for target address TARGET_ADDR in the linkage table
3386    and return the gp-relative address of the linkage table entry.  */
3387
3388 static bfd_vma
3389 set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
3390      bfd *abfd;
3391      struct bfd_link_info *info;
3392      struct elfNN_ia64_dyn_sym_info *dyn_i;
3393      long dynindx;
3394      bfd_vma addend;
3395      bfd_vma value;
3396      unsigned int dyn_r_type;
3397 {
3398   struct elfNN_ia64_link_hash_table *ia64_info;
3399   asection *got_sec;
3400   bfd_boolean done;
3401   bfd_vma got_offset;
3402
3403   ia64_info = elfNN_ia64_hash_table (info);
3404   got_sec = ia64_info->got_sec;
3405
3406   switch (dyn_r_type)
3407     {
3408     case R_IA64_TPREL64LSB:
3409       done = dyn_i->tprel_done;
3410       dyn_i->tprel_done = TRUE;
3411       got_offset = dyn_i->tprel_offset;
3412       break;
3413     case R_IA64_DTPMOD64LSB:
3414       if (dyn_i->dtpmod_offset != ia64_info->self_dtpmod_offset)
3415         {
3416           done = dyn_i->dtpmod_done;
3417           dyn_i->dtpmod_done = TRUE;
3418         }
3419       else
3420         {
3421           done = ia64_info->self_dtpmod_done;
3422           ia64_info->self_dtpmod_done = TRUE;
3423           dynindx = 0;
3424         }
3425       got_offset = dyn_i->dtpmod_offset;
3426       break;
3427     case R_IA64_DTPREL64LSB:
3428       done = dyn_i->dtprel_done;
3429       dyn_i->dtprel_done = TRUE;
3430       got_offset = dyn_i->dtprel_offset;
3431       break;
3432     default:
3433       done = dyn_i->got_done;
3434       dyn_i->got_done = TRUE;
3435       got_offset = dyn_i->got_offset;
3436       break;
3437     }
3438
3439   BFD_ASSERT ((got_offset & 7) == 0);
3440
3441   if (! done)
3442     {
3443       /* Store the target address in the linkage table entry.  */
3444       bfd_put_64 (abfd, value, got_sec->contents + got_offset);
3445
3446       /* Install a dynamic relocation if needed.  */
3447       if (((info->shared
3448             && (!dyn_i->h
3449                 || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
3450                 || dyn_i->h->root.type != bfd_link_hash_undefweak)
3451             && dyn_r_type != R_IA64_DTPREL64LSB)
3452            || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info, dyn_r_type)
3453            || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
3454           && (!dyn_i->want_ltoff_fptr
3455               || !info->pie
3456               || !dyn_i->h
3457               || dyn_i->h->root.type != bfd_link_hash_undefweak))
3458         {
3459           if (dynindx == -1
3460               && dyn_r_type != R_IA64_TPREL64LSB
3461               && dyn_r_type != R_IA64_DTPMOD64LSB
3462               && dyn_r_type != R_IA64_DTPREL64LSB)
3463             {
3464               dyn_r_type = R_IA64_REL64LSB;
3465               dynindx = 0;
3466               addend = value;
3467             }
3468
3469           if (bfd_big_endian (abfd))
3470             {
3471               switch (dyn_r_type)
3472                 {
3473                 case R_IA64_REL64LSB:
3474                   dyn_r_type = R_IA64_REL64MSB;
3475                   break;
3476                 case R_IA64_DIR64LSB:
3477                   dyn_r_type = R_IA64_DIR64MSB;
3478                   break;
3479                 case R_IA64_FPTR64LSB:
3480                   dyn_r_type = R_IA64_FPTR64MSB;
3481                   break;
3482                 case R_IA64_TPREL64LSB:
3483                   dyn_r_type = R_IA64_TPREL64MSB;
3484                   break;
3485                 case R_IA64_DTPMOD64LSB:
3486                   dyn_r_type = R_IA64_DTPMOD64MSB;
3487                   break;
3488                 case R_IA64_DTPREL64LSB:
3489                   dyn_r_type = R_IA64_DTPREL64MSB;
3490                   break;
3491                 default:
3492                   BFD_ASSERT (FALSE);
3493                   break;
3494                 }
3495             }
3496
3497           elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
3498                                         ia64_info->rel_got_sec,
3499                                         got_offset, dyn_r_type,
3500                                         dynindx, addend);
3501         }
3502     }
3503
3504   /* Return the address of the linkage table entry.  */
3505   value = (got_sec->output_section->vma
3506            + got_sec->output_offset
3507            + got_offset);
3508
3509   return value;
3510 }
3511
3512 /* Fill in a function descriptor consisting of the function's code
3513    address and its global pointer.  Return the descriptor's address.  */
3514
3515 static bfd_vma
3516 set_fptr_entry (abfd, info, dyn_i, value)
3517      bfd *abfd;
3518      struct bfd_link_info *info;
3519      struct elfNN_ia64_dyn_sym_info *dyn_i;
3520      bfd_vma value;
3521 {
3522   struct elfNN_ia64_link_hash_table *ia64_info;
3523   asection *fptr_sec;
3524
3525   ia64_info = elfNN_ia64_hash_table (info);
3526   fptr_sec = ia64_info->fptr_sec;
3527
3528   if (!dyn_i->fptr_done)
3529     {
3530       dyn_i->fptr_done = 1;
3531
3532       /* Fill in the function descriptor.  */
3533       bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
3534       bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
3535                   fptr_sec->contents + dyn_i->fptr_offset + 8);
3536       if (ia64_info->rel_fptr_sec)
3537         {
3538           Elf_Internal_Rela outrel;
3539           bfd_byte *loc;
3540
3541           if (bfd_little_endian (abfd))
3542             outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTLSB);
3543           else
3544             outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTMSB);
3545           outrel.r_addend = value;
3546           outrel.r_offset = (fptr_sec->output_section->vma
3547                              + fptr_sec->output_offset
3548                              + dyn_i->fptr_offset);
3549           loc = ia64_info->rel_fptr_sec->contents;
3550           loc += ia64_info->rel_fptr_sec->reloc_count++
3551                  * sizeof (ElfNN_External_Rela);
3552           bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3553         }
3554     }
3555
3556   /* Return the descriptor's address.  */
3557   value = (fptr_sec->output_section->vma
3558            + fptr_sec->output_offset
3559            + dyn_i->fptr_offset);
3560
3561   return value;
3562 }
3563
3564 /* Fill in a PLTOFF entry consisting of the function's code address
3565    and its global pointer.  Return the descriptor's address.  */
3566
3567 static bfd_vma
3568 set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
3569      bfd *abfd;
3570      struct bfd_link_info *info;
3571      struct elfNN_ia64_dyn_sym_info *dyn_i;
3572      bfd_vma value;
3573      bfd_boolean is_plt;
3574 {
3575   struct elfNN_ia64_link_hash_table *ia64_info;
3576   asection *pltoff_sec;
3577
3578   ia64_info = elfNN_ia64_hash_table (info);
3579   pltoff_sec = ia64_info->pltoff_sec;
3580
3581   /* Don't do anything if this symbol uses a real PLT entry.  In
3582      that case, we'll fill this in during finish_dynamic_symbol.  */
3583   if ((! dyn_i->want_plt || is_plt)
3584       && !dyn_i->pltoff_done)
3585     {
3586       bfd_vma gp = _bfd_get_gp_value (abfd);
3587
3588       /* Fill in the function descriptor.  */
3589       bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
3590       bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
3591
3592       /* Install dynamic relocations if needed.  */
3593       if (!is_plt
3594           && info->shared
3595           && (!dyn_i->h
3596               || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
3597               || dyn_i->h->root.type != bfd_link_hash_undefweak))
3598         {
3599           unsigned int dyn_r_type;
3600
3601           if (bfd_big_endian (abfd))
3602             dyn_r_type = R_IA64_REL64MSB;
3603           else
3604             dyn_r_type = R_IA64_REL64LSB;
3605
3606           elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3607                                         ia64_info->rel_pltoff_sec,
3608                                         dyn_i->pltoff_offset,
3609                                         dyn_r_type, 0, value);
3610           elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3611                                         ia64_info->rel_pltoff_sec,
3612                                         dyn_i->pltoff_offset + 8,
3613                                         dyn_r_type, 0, gp);
3614         }
3615
3616       dyn_i->pltoff_done = 1;
3617     }
3618
3619   /* Return the descriptor's address.  */
3620   value = (pltoff_sec->output_section->vma
3621            + pltoff_sec->output_offset
3622            + dyn_i->pltoff_offset);
3623
3624   return value;
3625 }
3626
3627 /* Return the base VMA address which should be subtracted from real addresses
3628    when resolving @tprel() relocation.
3629    Main program TLS (whose template starts at PT_TLS p_vaddr)
3630    is assigned offset round(16, PT_TLS p_align).  */
3631
3632 static bfd_vma
3633 elfNN_ia64_tprel_base (info)
3634      struct bfd_link_info *info;
3635 {
3636   asection *tls_sec = elf_hash_table (info)->tls_sec;
3637
3638   BFD_ASSERT (tls_sec != NULL);
3639   return tls_sec->vma - align_power ((bfd_vma) 16, tls_sec->alignment_power);
3640 }
3641
3642 /* Return the base VMA address which should be subtracted from real addresses
3643    when resolving @dtprel() relocation.
3644    This is PT_TLS segment p_vaddr.  */
3645
3646 static bfd_vma
3647 elfNN_ia64_dtprel_base (info)
3648      struct bfd_link_info *info;
3649 {
3650   BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
3651   return elf_hash_table (info)->tls_sec->vma;
3652 }
3653
3654 /* Called through qsort to sort the .IA_64.unwind section during a
3655    non-relocatable link.  Set elfNN_ia64_unwind_entry_compare_bfd
3656    to the output bfd so we can do proper endianness frobbing.  */
3657
3658 static bfd *elfNN_ia64_unwind_entry_compare_bfd;
3659
3660 static int
3661 elfNN_ia64_unwind_entry_compare (a, b)
3662      const PTR a;
3663      const PTR b;
3664 {
3665   bfd_vma av, bv;
3666
3667   av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
3668   bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
3669
3670   return (av < bv ? -1 : av > bv ? 1 : 0);
3671 }
3672
3673 /* Make sure we've got ourselves a nice fat __gp value.  */
3674 static bfd_boolean
3675 elfNN_ia64_choose_gp (abfd, info)
3676      bfd *abfd;
3677      struct bfd_link_info *info;
3678 {
3679   bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
3680   bfd_vma min_short_vma = min_vma, max_short_vma = 0;
3681   struct elf_link_hash_entry *gp;
3682   bfd_vma gp_val;
3683   asection *os;
3684   struct elfNN_ia64_link_hash_table *ia64_info;
3685
3686   ia64_info = elfNN_ia64_hash_table (info);
3687
3688   /* Find the min and max vma of all sections marked short.  Also collect
3689      min and max vma of any type, for use in selecting a nice gp.  */
3690   for (os = abfd->sections; os ; os = os->next)
3691     {
3692       bfd_vma lo, hi;
3693
3694       if ((os->flags & SEC_ALLOC) == 0)
3695         continue;
3696
3697       lo = os->vma;
3698       hi = os->vma + os->_raw_size;
3699       if (hi < lo)
3700         hi = (bfd_vma) -1;
3701
3702       if (min_vma > lo)
3703         min_vma = lo;
3704       if (max_vma < hi)
3705         max_vma = hi;
3706       if (os->flags & SEC_SMALL_DATA)
3707         {
3708           if (min_short_vma > lo)
3709             min_short_vma = lo;
3710           if (max_short_vma < hi)
3711             max_short_vma = hi;
3712         }
3713     }
3714
3715   /* See if the user wants to force a value.  */
3716   gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3717                              FALSE, FALSE);
3718
3719   if (gp
3720       && (gp->root.type == bfd_link_hash_defined
3721           || gp->root.type == bfd_link_hash_defweak))
3722     {
3723       asection *gp_sec = gp->root.u.def.section;
3724       gp_val = (gp->root.u.def.value
3725                 + gp_sec->output_section->vma
3726                 + gp_sec->output_offset);
3727     }
3728   else
3729     {
3730       /* Pick a sensible value.  */
3731
3732       asection *got_sec = ia64_info->got_sec;
3733
3734       /* Start with just the address of the .got.  */
3735       if (got_sec)
3736         gp_val = got_sec->output_section->vma;
3737       else if (max_short_vma != 0)
3738         gp_val = min_short_vma;
3739       else
3740         gp_val = min_vma;
3741
3742       /* If it is possible to address the entire image, but we
3743          don't with the choice above, adjust.  */
3744       if (max_vma - min_vma < 0x400000
3745           && max_vma - gp_val <= 0x200000
3746           && gp_val - min_vma > 0x200000)
3747         gp_val = min_vma + 0x200000;
3748       else if (max_short_vma != 0)
3749         {
3750           /* If we don't cover all the short data, adjust.  */
3751           if (max_short_vma - gp_val >= 0x200000)
3752             gp_val = min_short_vma + 0x200000;
3753
3754           /* If we're addressing stuff past the end, adjust back.  */
3755           if (gp_val > max_vma)
3756             gp_val = max_vma - 0x200000 + 8;
3757         }
3758     }
3759
3760   /* Validate whether all SHF_IA_64_SHORT sections are within
3761      range of the chosen GP.  */
3762
3763   if (max_short_vma != 0)
3764     {
3765       if (max_short_vma - min_short_vma >= 0x400000)
3766         {
3767           (*_bfd_error_handler)
3768             (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3769              bfd_get_filename (abfd),
3770              (unsigned long) (max_short_vma - min_short_vma));
3771           return FALSE;
3772         }
3773       else if ((gp_val > min_short_vma
3774                 && gp_val - min_short_vma > 0x200000)
3775                || (gp_val < max_short_vma
3776                    && max_short_vma - gp_val >= 0x200000))
3777         {
3778           (*_bfd_error_handler)
3779             (_("%s: __gp does not cover short data segment"),
3780              bfd_get_filename (abfd));
3781           return FALSE;
3782         }
3783     }
3784
3785   _bfd_set_gp_value (abfd, gp_val);
3786
3787   return TRUE;
3788 }
3789
3790 static bfd_boolean
3791 elfNN_ia64_final_link (abfd, info)
3792      bfd *abfd;
3793      struct bfd_link_info *info;
3794 {
3795   struct elfNN_ia64_link_hash_table *ia64_info;
3796   asection *unwind_output_sec;
3797
3798   ia64_info = elfNN_ia64_hash_table (info);
3799
3800   /* Make sure we've got ourselves a nice fat __gp value.  */
3801   if (!info->relocatable)
3802     {
3803       bfd_vma gp_val = _bfd_get_gp_value (abfd);
3804       struct elf_link_hash_entry *gp;
3805
3806       if (gp_val == 0)
3807         {
3808           if (! elfNN_ia64_choose_gp (abfd, info))
3809             return FALSE;
3810           gp_val = _bfd_get_gp_value (abfd);
3811         }
3812
3813       gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3814                                  FALSE, FALSE);
3815       if (gp)
3816         {
3817           gp->root.type = bfd_link_hash_defined;
3818           gp->root.u.def.value = gp_val;
3819           gp->root.u.def.section = bfd_abs_section_ptr;
3820         }
3821     }
3822
3823   /* If we're producing a final executable, we need to sort the contents
3824      of the .IA_64.unwind section.  Force this section to be relocated
3825      into memory rather than written immediately to the output file.  */
3826   unwind_output_sec = NULL;
3827   if (!info->relocatable)
3828     {
3829       asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3830       if (s)
3831         {
3832           unwind_output_sec = s->output_section;
3833           unwind_output_sec->contents
3834             = bfd_malloc (unwind_output_sec->_raw_size);
3835           if (unwind_output_sec->contents == NULL)
3836             return FALSE;
3837         }
3838     }
3839
3840   /* Invoke the regular ELF backend linker to do all the work.  */
3841   if (!bfd_elf_final_link (abfd, info))
3842     return FALSE;
3843
3844   if (unwind_output_sec)
3845     {
3846       elfNN_ia64_unwind_entry_compare_bfd = abfd;
3847       qsort (unwind_output_sec->contents,
3848              (size_t) (unwind_output_sec->_raw_size / 24),
3849              24,
3850              elfNN_ia64_unwind_entry_compare);
3851
3852       if (! bfd_set_section_contents (abfd, unwind_output_sec,
3853                                       unwind_output_sec->contents, (bfd_vma) 0,
3854                                       unwind_output_sec->_raw_size))
3855         return FALSE;
3856     }
3857
3858   return TRUE;
3859 }
3860
3861 static bfd_boolean
3862 elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
3863                              contents, relocs, local_syms, local_sections)
3864      bfd *output_bfd;
3865      struct bfd_link_info *info;
3866      bfd *input_bfd;
3867      asection *input_section;
3868      bfd_byte *contents;
3869      Elf_Internal_Rela *relocs;
3870      Elf_Internal_Sym *local_syms;
3871      asection **local_sections;
3872 {
3873   struct elfNN_ia64_link_hash_table *ia64_info;
3874   Elf_Internal_Shdr *symtab_hdr;
3875   Elf_Internal_Rela *rel;
3876   Elf_Internal_Rela *relend;
3877   asection *srel;
3878   bfd_boolean ret_val = TRUE;   /* for non-fatal errors */
3879   bfd_vma gp_val;
3880
3881   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3882   ia64_info = elfNN_ia64_hash_table (info);
3883
3884   /* Infect various flags from the input section to the output section.  */
3885   if (info->relocatable)
3886     {
3887       bfd_vma flags;
3888
3889       flags = elf_section_data(input_section)->this_hdr.sh_flags;
3890       flags &= SHF_IA_64_NORECOV;
3891
3892       elf_section_data(input_section->output_section)
3893         ->this_hdr.sh_flags |= flags;
3894       return TRUE;
3895     }
3896
3897   gp_val = _bfd_get_gp_value (output_bfd);
3898   srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
3899
3900   rel = relocs;
3901   relend = relocs + input_section->reloc_count;
3902   for (; rel < relend; ++rel)
3903     {
3904       struct elf_link_hash_entry *h;
3905       struct elfNN_ia64_dyn_sym_info *dyn_i;
3906       bfd_reloc_status_type r;
3907       reloc_howto_type *howto;
3908       unsigned long r_symndx;
3909       Elf_Internal_Sym *sym;
3910       unsigned int r_type;
3911       bfd_vma value;
3912       asection *sym_sec;
3913       bfd_byte *hit_addr;
3914       bfd_boolean dynamic_symbol_p;
3915       bfd_boolean undef_weak_ref;
3916
3917       r_type = ELFNN_R_TYPE (rel->r_info);
3918       if (r_type > R_IA64_MAX_RELOC_CODE)
3919         {
3920           (*_bfd_error_handler)
3921             (_("%s: unknown relocation type %d"),
3922              bfd_archive_filename (input_bfd), (int)r_type);
3923           bfd_set_error (bfd_error_bad_value);
3924           ret_val = FALSE;
3925           continue;
3926         }
3927
3928       howto = lookup_howto (r_type);
3929       r_symndx = ELFNN_R_SYM (rel->r_info);
3930       h = NULL;
3931       sym = NULL;
3932       sym_sec = NULL;
3933       undef_weak_ref = FALSE;
3934
3935       if (r_symndx < symtab_hdr->sh_info)
3936         {
3937           /* Reloc against local symbol.  */
3938           asection *msec;
3939           sym = local_syms + r_symndx;
3940           sym_sec = local_sections[r_symndx];
3941           msec = sym_sec;
3942           value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
3943           if ((sym_sec->flags & SEC_MERGE)
3944               && ELF_ST_TYPE (sym->st_info) == STT_SECTION
3945               && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
3946             {
3947               struct elfNN_ia64_local_hash_entry *loc_h;
3948
3949               loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
3950               if (loc_h && ! loc_h->sec_merge_done)
3951                 {
3952                   struct elfNN_ia64_dyn_sym_info *dynent;
3953
3954                   for (dynent = loc_h->info; dynent; dynent = dynent->next)
3955                     {
3956                       msec = sym_sec;
3957                       dynent->addend =
3958                         _bfd_merged_section_offset (output_bfd, &msec,
3959                                                     elf_section_data (msec)->
3960                                                     sec_info,
3961                                                     sym->st_value
3962                                                     + dynent->addend,
3963                                                     (bfd_vma) 0);
3964                       dynent->addend -= sym->st_value;
3965                       dynent->addend += msec->output_section->vma
3966                                         + msec->output_offset
3967                                         - sym_sec->output_section->vma
3968                                         - sym_sec->output_offset;
3969                     }
3970                   loc_h->sec_merge_done = 1;
3971                 }
3972             }
3973         }
3974       else
3975         {
3976           bfd_boolean unresolved_reloc;
3977           bfd_boolean warned;
3978           struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
3979
3980           RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
3981                                    r_symndx, symtab_hdr, sym_hashes,
3982                                    h, sym_sec, value,
3983                                    unresolved_reloc, warned);
3984
3985           if (h->root.type == bfd_link_hash_undefweak)
3986             undef_weak_ref = TRUE;
3987           else if (warned)
3988             continue;
3989         }
3990
3991       hit_addr = contents + rel->r_offset;
3992       value += rel->r_addend;
3993       dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type);
3994
3995       switch (r_type)
3996         {
3997         case R_IA64_NONE:
3998         case R_IA64_LDXMOV:
3999           continue;
4000
4001         case R_IA64_IMM14:
4002         case R_IA64_IMM22:
4003         case R_IA64_IMM64:
4004         case R_IA64_DIR32MSB:
4005         case R_IA64_DIR32LSB:
4006         case R_IA64_DIR64MSB:
4007         case R_IA64_DIR64LSB:
4008           /* Install a dynamic relocation for this reloc.  */
4009           if ((dynamic_symbol_p || info->shared)
4010               && r_symndx != 0
4011               && (input_section->flags & SEC_ALLOC) != 0)
4012             {
4013               unsigned int dyn_r_type;
4014               long dynindx;
4015               bfd_vma addend;
4016
4017               BFD_ASSERT (srel != NULL);
4018
4019               switch (r_type)
4020                 {
4021                 case R_IA64_IMM14:
4022                 case R_IA64_IMM22:
4023                 case R_IA64_IMM64:
4024                   /* ??? People shouldn't be doing non-pic code in
4025                      shared libraries nor dynamic executables.  */
4026                   (*_bfd_error_handler)
4027                     (_("%s: non-pic code with imm relocation against dynamic symbol `%s'"),
4028                      bfd_archive_filename (input_bfd),
4029                      h->root.root.string);
4030                   ret_val = FALSE;
4031                   continue;
4032
4033                 default:
4034                   break;
4035                 }
4036
4037               /* If we don't need dynamic symbol lookup, find a
4038                  matching RELATIVE relocation.  */
4039               dyn_r_type = r_type;
4040               if (dynamic_symbol_p)
4041                 {
4042                   dynindx = h->dynindx;
4043                   addend = rel->r_addend;
4044                   value = 0;
4045                 }
4046               else
4047                 {
4048                   switch (r_type)
4049                     {
4050                     case R_IA64_DIR32MSB:
4051                       dyn_r_type = R_IA64_REL32MSB;
4052                       break;
4053                     case R_IA64_DIR32LSB:
4054                       dyn_r_type = R_IA64_REL32LSB;
4055                       break;
4056                     case R_IA64_DIR64MSB:
4057                       dyn_r_type = R_IA64_REL64MSB;
4058                       break;
4059                     case R_IA64_DIR64LSB:
4060                       dyn_r_type = R_IA64_REL64LSB;
4061                       break;
4062
4063                     default:
4064                       break;
4065                     }
4066                   dynindx = 0;
4067                   addend = value;
4068                 }
4069
4070               elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4071                                             srel, rel->r_offset, dyn_r_type,
4072                                             dynindx, addend);
4073             }
4074           /* Fall through.  */
4075
4076         case R_IA64_LTV32MSB:
4077         case R_IA64_LTV32LSB:
4078         case R_IA64_LTV64MSB:
4079         case R_IA64_LTV64LSB:
4080           r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4081           break;
4082
4083         case R_IA64_GPREL22:
4084         case R_IA64_GPREL64I:
4085         case R_IA64_GPREL32MSB:
4086         case R_IA64_GPREL32LSB:
4087         case R_IA64_GPREL64MSB:
4088         case R_IA64_GPREL64LSB:
4089           if (dynamic_symbol_p)
4090             {
4091               (*_bfd_error_handler)
4092                 (_("%s: @gprel relocation against dynamic symbol %s"),
4093                  bfd_archive_filename (input_bfd), h->root.root.string);
4094               ret_val = FALSE;
4095               continue;
4096             }
4097           value -= gp_val;
4098           r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4099           break;
4100
4101         case R_IA64_LTOFF22:
4102         case R_IA64_LTOFF22X:
4103         case R_IA64_LTOFF64I:
4104           dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4105           value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
4106                                  rel->r_addend, value, R_IA64_DIR64LSB);
4107           value -= gp_val;
4108           r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4109           break;
4110
4111         case R_IA64_PLTOFF22:
4112         case R_IA64_PLTOFF64I:
4113         case R_IA64_PLTOFF64MSB:
4114         case R_IA64_PLTOFF64LSB:
4115           dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4116           value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
4117           value -= gp_val;
4118           r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4119           break;
4120
4121         case R_IA64_FPTR64I:
4122         case R_IA64_FPTR32MSB:
4123         case R_IA64_FPTR32LSB:
4124         case R_IA64_FPTR64MSB:
4125         case R_IA64_FPTR64LSB:
4126           dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4127           if (dyn_i->want_fptr)
4128             {
4129               if (!undef_weak_ref)
4130                 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4131             }
4132           if (!dyn_i->want_fptr || info->pie)
4133             {
4134               long dynindx;
4135               unsigned int dyn_r_type = r_type;
4136               bfd_vma addend = rel->r_addend;
4137
4138               /* Otherwise, we expect the dynamic linker to create
4139                  the entry.  */
4140
4141               if (dyn_i->want_fptr)
4142                 {
4143                   if (r_type == R_IA64_FPTR64I)
4144                     {
4145                       /* We can't represent this without a dynamic symbol.
4146                          Adjust the relocation to be against an output
4147                          section symbol, which are always present in the
4148                          dynamic symbol table.  */
4149                       /* ??? People shouldn't be doing non-pic code in
4150                          shared libraries.  Hork.  */
4151                       (*_bfd_error_handler)
4152                         (_("%s: linking non-pic code in a position independent executable"),
4153                          bfd_archive_filename (input_bfd));
4154                       ret_val = FALSE;
4155                       continue;
4156                     }
4157                   dynindx = 0;
4158                   addend = value;
4159                   dyn_r_type = r_type + R_IA64_REL64LSB - R_IA64_FPTR64LSB;
4160                 }
4161               else if (h)
4162                 {
4163                   if (h->dynindx != -1)
4164                     dynindx = h->dynindx;
4165                   else
4166                     dynindx = (_bfd_elf_link_lookup_local_dynindx
4167                                (info, h->root.u.def.section->owner,
4168                                 global_sym_index (h)));
4169                   value = 0;
4170                 }
4171               else
4172                 {
4173                   dynindx = (_bfd_elf_link_lookup_local_dynindx
4174                              (info, input_bfd, (long) r_symndx));
4175                   value = 0;
4176                 }
4177
4178               elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4179                                             srel, rel->r_offset, dyn_r_type,
4180                                             dynindx, addend);
4181             }
4182
4183           r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4184           break;
4185
4186         case R_IA64_LTOFF_FPTR22:
4187         case R_IA64_LTOFF_FPTR64I:
4188         case R_IA64_LTOFF_FPTR32MSB:
4189         case R_IA64_LTOFF_FPTR32LSB:
4190         case R_IA64_LTOFF_FPTR64MSB:
4191         case R_IA64_LTOFF_FPTR64LSB:
4192           {
4193             long dynindx;
4194
4195             dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4196             if (dyn_i->want_fptr)
4197               {
4198                 BFD_ASSERT (h == NULL || h->dynindx == -1)
4199                 if (!undef_weak_ref)
4200                   value = set_fptr_entry (output_bfd, info, dyn_i, value);
4201                 dynindx = -1;
4202               }
4203             else
4204               {
4205                 /* Otherwise, we expect the dynamic linker to create
4206                    the entry.  */
4207                 if (h)
4208                   {
4209                     if (h->dynindx != -1)
4210                       dynindx = h->dynindx;
4211                     else
4212                       dynindx = (_bfd_elf_link_lookup_local_dynindx
4213                                  (info, h->root.u.def.section->owner,
4214                                   global_sym_index (h)));
4215                   }
4216                 else
4217                   dynindx = (_bfd_elf_link_lookup_local_dynindx
4218                              (info, input_bfd, (long) r_symndx));
4219                 value = 0;
4220               }
4221
4222             value = set_got_entry (output_bfd, info, dyn_i, dynindx,
4223                                    rel->r_addend, value, R_IA64_FPTR64LSB);
4224             value -= gp_val;
4225             r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4226           }
4227           break;
4228
4229         case R_IA64_PCREL32MSB:
4230         case R_IA64_PCREL32LSB:
4231         case R_IA64_PCREL64MSB:
4232         case R_IA64_PCREL64LSB:
4233           /* Install a dynamic relocation for this reloc.  */
4234           if (dynamic_symbol_p && r_symndx != 0)
4235             {
4236               BFD_ASSERT (srel != NULL);
4237
4238               elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4239                                             srel, rel->r_offset, r_type,
4240                                             h->dynindx, rel->r_addend);
4241             }
4242           goto finish_pcrel;
4243
4244         case R_IA64_PCREL21B:
4245         case R_IA64_PCREL60B:
4246           /* We should have created a PLT entry for any dynamic symbol.  */
4247           dyn_i = NULL;
4248           if (h)
4249             dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4250
4251           if (dyn_i && dyn_i->want_plt2)
4252             {
4253               /* Should have caught this earlier.  */
4254               BFD_ASSERT (rel->r_addend == 0);
4255
4256               value = (ia64_info->plt_sec->output_section->vma
4257                        + ia64_info->plt_sec->output_offset
4258                        + dyn_i->plt2_offset);
4259             }
4260           else
4261             {
4262               /* Since there's no PLT entry, Validate that this is
4263                  locally defined.  */
4264               BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
4265
4266               /* If the symbol is undef_weak, we shouldn't be trying
4267                  to call it.  There's every chance that we'd wind up
4268                  with an out-of-range fixup here.  Don't bother setting
4269                  any value at all.  */
4270               if (undef_weak_ref)
4271                 continue;
4272             }
4273           goto finish_pcrel;
4274
4275         case R_IA64_PCREL21BI:
4276         case R_IA64_PCREL21F:
4277         case R_IA64_PCREL21M:
4278         case R_IA64_PCREL22:
4279         case R_IA64_PCREL64I:
4280           /* The PCREL21BI reloc is specifically not intended for use with
4281              dynamic relocs.  PCREL21F and PCREL21M are used for speculation
4282              fixup code, and thus probably ought not be dynamic.  The 
4283              PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs.  */
4284           if (dynamic_symbol_p)
4285             {
4286               const char *msg;
4287
4288               if (r_type == R_IA64_PCREL21BI)
4289                 msg = _("%s: @internal branch to dynamic symbol %s");
4290               else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
4291                 msg = _("%s: speculation fixup to dynamic symbol %s");
4292               else
4293                 msg = _("%s: @pcrel relocation against dynamic symbol %s");
4294               (*_bfd_error_handler) (msg, bfd_archive_filename (input_bfd),
4295                                      h->root.root.string);
4296               ret_val = FALSE;
4297               continue;
4298             }
4299           goto finish_pcrel;
4300
4301         finish_pcrel:
4302           /* Make pc-relative.  */
4303           value -= (input_section->output_section->vma
4304                     + input_section->output_offset
4305                     + rel->r_offset) & ~ (bfd_vma) 0x3;
4306           r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4307           break;
4308
4309         case R_IA64_SEGREL32MSB:
4310         case R_IA64_SEGREL32LSB:
4311         case R_IA64_SEGREL64MSB:
4312         case R_IA64_SEGREL64LSB:
4313           if (r_symndx == 0)
4314             {
4315               /* If the input section was discarded from the output, then
4316                  do nothing.  */
4317               r = bfd_reloc_ok;
4318             }
4319           else
4320             {
4321               struct elf_segment_map *m;
4322               Elf_Internal_Phdr *p;
4323
4324               /* Find the segment that contains the output_section.  */
4325               for (m = elf_tdata (output_bfd)->segment_map,
4326                      p = elf_tdata (output_bfd)->phdr;
4327                    m != NULL;
4328                    m = m->next, p++)
4329                 {
4330                   int i;
4331                   for (i = m->count - 1; i >= 0; i--)
4332                     if (m->sections[i] == input_section->output_section)
4333                       break;
4334                   if (i >= 0)
4335                     break;
4336                 }
4337
4338               if (m == NULL)
4339                 {
4340                   r = bfd_reloc_notsupported;
4341                 }
4342               else
4343                 {
4344                   /* The VMA of the segment is the vaddr of the associated
4345                      program header.  */
4346                   if (value > p->p_vaddr)
4347                     value -= p->p_vaddr;
4348                   else
4349                     value = 0;
4350                   r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
4351                                                 r_type);
4352                 }
4353               break;
4354             }
4355
4356         case R_IA64_SECREL32MSB:
4357         case R_IA64_SECREL32LSB:
4358         case R_IA64_SECREL64MSB:
4359         case R_IA64_SECREL64LSB:
4360           /* Make output-section relative.  */
4361           if (value > input_section->output_section->vma)
4362             value -= input_section->output_section->vma;
4363           else
4364             value = 0;
4365           r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4366           break;
4367
4368         case R_IA64_IPLTMSB:
4369         case R_IA64_IPLTLSB:
4370           /* Install a dynamic relocation for this reloc.  */
4371           if ((dynamic_symbol_p || info->shared)
4372               && (input_section->flags & SEC_ALLOC) != 0)
4373             {
4374               BFD_ASSERT (srel != NULL);
4375
4376               /* If we don't need dynamic symbol lookup, install two
4377                  RELATIVE relocations.  */
4378               if (!dynamic_symbol_p)
4379                 {
4380                   unsigned int dyn_r_type;
4381
4382                   if (r_type == R_IA64_IPLTMSB)
4383                     dyn_r_type = R_IA64_REL64MSB;
4384                   else
4385                     dyn_r_type = R_IA64_REL64LSB;
4386
4387                   elfNN_ia64_install_dyn_reloc (output_bfd, info,
4388                                                 input_section,
4389                                                 srel, rel->r_offset,
4390                                                 dyn_r_type, 0, value);
4391                   elfNN_ia64_install_dyn_reloc (output_bfd, info,
4392                                                 input_section,
4393                                                 srel, rel->r_offset + 8,
4394                                                 dyn_r_type, 0, gp_val);
4395                 }
4396               else
4397                 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4398                                               srel, rel->r_offset, r_type,
4399                                               h->dynindx, rel->r_addend);
4400             }
4401
4402           if (r_type == R_IA64_IPLTMSB)
4403             r_type = R_IA64_DIR64MSB;
4404           else
4405             r_type = R_IA64_DIR64LSB;
4406           elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4407           r = elfNN_ia64_install_value (output_bfd, hit_addr + 8, gp_val,
4408                                         r_type);
4409           break;
4410
4411         case R_IA64_TPREL14:
4412         case R_IA64_TPREL22:
4413         case R_IA64_TPREL64I:
4414           value -= elfNN_ia64_tprel_base (info);
4415           r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4416           break;
4417
4418         case R_IA64_DTPREL14:
4419         case R_IA64_DTPREL22:
4420         case R_IA64_DTPREL64I:
4421         case R_IA64_DTPREL64LSB:
4422         case R_IA64_DTPREL64MSB:
4423           value -= elfNN_ia64_dtprel_base (info);
4424           r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4425           break;
4426
4427         case R_IA64_LTOFF_TPREL22:
4428         case R_IA64_LTOFF_DTPMOD22:
4429         case R_IA64_LTOFF_DTPREL22:
4430           {
4431             int got_r_type;
4432             long dynindx = h ? h->dynindx : -1;
4433             bfd_vma r_addend = rel->r_addend;
4434
4435             switch (r_type)
4436               {
4437               default:
4438               case R_IA64_LTOFF_TPREL22:
4439                 if (!dynamic_symbol_p)
4440                   {
4441                     if (!info->shared)
4442                       value -= elfNN_ia64_tprel_base (info);
4443                     else
4444                       {
4445                         r_addend += value - elfNN_ia64_dtprel_base (info);
4446                         dynindx = 0;
4447                       }
4448                   }
4449                 got_r_type = R_IA64_TPREL64LSB;
4450                 break;
4451               case R_IA64_LTOFF_DTPMOD22:
4452                 if (!dynamic_symbol_p && !info->shared)
4453                   value = 1;
4454                 got_r_type = R_IA64_DTPMOD64LSB;
4455                 break;
4456               case R_IA64_LTOFF_DTPREL22:
4457                 if (!dynamic_symbol_p)
4458                   value -= elfNN_ia64_dtprel_base (info);
4459                 got_r_type = R_IA64_DTPREL64LSB;
4460                 break;
4461               }
4462             dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4463             value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
4464                                    value, got_r_type);
4465             value -= gp_val;
4466             r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
4467                                           r_type);
4468           }
4469           break;
4470
4471         default:
4472           r = bfd_reloc_notsupported;
4473           break;
4474         }
4475
4476       switch (r)
4477         {
4478         case bfd_reloc_ok:
4479           break;
4480
4481         case bfd_reloc_undefined:
4482           /* This can happen for global table relative relocs if
4483              __gp is undefined.  This is a panic situation so we
4484              don't try to continue.  */
4485           (*info->callbacks->undefined_symbol)
4486             (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
4487           return FALSE;
4488
4489         case bfd_reloc_notsupported:
4490           {
4491             const char *name;
4492
4493             if (h)
4494               name = h->root.root.string;
4495             else
4496               {
4497                 name = bfd_elf_string_from_elf_section (input_bfd,
4498                                                         symtab_hdr->sh_link,
4499                                                         sym->st_name);
4500                 if (name == NULL)
4501                   return FALSE;
4502                 if (*name == '\0')
4503                   name = bfd_section_name (input_bfd, input_section);
4504               }
4505             if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
4506                                               name, input_bfd,
4507                                               input_section, rel->r_offset))
4508               return FALSE;
4509             ret_val = FALSE;
4510           }
4511           break;
4512
4513         case bfd_reloc_dangerous:
4514         case bfd_reloc_outofrange:
4515         case bfd_reloc_overflow:
4516         default:
4517           {
4518             const char *name;
4519
4520             if (h)
4521               name = h->root.root.string;
4522             else
4523               {
4524                 name = bfd_elf_string_from_elf_section (input_bfd,
4525                                                         symtab_hdr->sh_link,
4526                                                         sym->st_name);
4527                 if (name == NULL)
4528                   return FALSE;
4529                 if (*name == '\0')
4530                   name = bfd_section_name (input_bfd, input_section);
4531               }
4532             if (!(*info->callbacks->reloc_overflow) (info, name,
4533                                                      howto->name,
4534                                                      (bfd_vma) 0,
4535                                                      input_bfd,
4536                                                      input_section,
4537                                                      rel->r_offset))
4538               return FALSE;
4539             ret_val = FALSE;
4540           }
4541           break;
4542         }
4543     }
4544
4545   return ret_val;
4546 }
4547
4548 static bfd_boolean
4549 elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
4550      bfd *output_bfd;
4551      struct bfd_link_info *info;
4552      struct elf_link_hash_entry *h;
4553      Elf_Internal_Sym *sym;
4554 {
4555   struct elfNN_ia64_link_hash_table *ia64_info;
4556   struct elfNN_ia64_dyn_sym_info *dyn_i;
4557
4558   ia64_info = elfNN_ia64_hash_table (info);
4559   dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4560
4561   /* Fill in the PLT data, if required.  */
4562   if (dyn_i && dyn_i->want_plt)
4563     {
4564       Elf_Internal_Rela outrel;
4565       bfd_byte *loc;
4566       asection *plt_sec;
4567       bfd_vma plt_addr, pltoff_addr, gp_val, index;
4568
4569       gp_val = _bfd_get_gp_value (output_bfd);
4570
4571       /* Initialize the minimal PLT entry.  */
4572
4573       index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
4574       plt_sec = ia64_info->plt_sec;
4575       loc = plt_sec->contents + dyn_i->plt_offset;
4576
4577       memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
4578       elfNN_ia64_install_value (output_bfd, loc, index, R_IA64_IMM22);
4579       elfNN_ia64_install_value (output_bfd, loc+2, -dyn_i->plt_offset,
4580                                 R_IA64_PCREL21B);
4581
4582       plt_addr = (plt_sec->output_section->vma
4583                   + plt_sec->output_offset
4584                   + dyn_i->plt_offset);
4585       pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
4586
4587       /* Initialize the FULL PLT entry, if needed.  */
4588       if (dyn_i->want_plt2)
4589         {
4590           loc = plt_sec->contents + dyn_i->plt2_offset;
4591
4592           memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
4593           elfNN_ia64_install_value (output_bfd, loc, pltoff_addr - gp_val,
4594                                     R_IA64_IMM22);
4595
4596           /* Mark the symbol as undefined, rather than as defined in the
4597              plt section.  Leave the value alone.  */
4598           /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4599              first place.  But perhaps elflink.c did some for us.  */
4600           if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
4601             sym->st_shndx = SHN_UNDEF;
4602         }
4603
4604       /* Create the dynamic relocation.  */
4605       outrel.r_offset = pltoff_addr;
4606       if (bfd_little_endian (output_bfd))
4607         outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
4608       else
4609         outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
4610       outrel.r_addend = 0;
4611
4612       /* This is fun.  In the .IA_64.pltoff section, we've got entries
4613          that correspond both to real PLT entries, and those that
4614          happened to resolve to local symbols but need to be created
4615          to satisfy @pltoff relocations.  The .rela.IA_64.pltoff
4616          relocations for the real PLT should come at the end of the
4617          section, so that they can be indexed by plt entry at runtime.
4618
4619          We emitted all of the relocations for the non-PLT @pltoff
4620          entries during relocate_section.  So we can consider the
4621          existing sec->reloc_count to be the base of the array of
4622          PLT relocations.  */
4623
4624       loc = ia64_info->rel_pltoff_sec->contents;
4625       loc += ((ia64_info->rel_pltoff_sec->reloc_count + index)
4626               * sizeof (ElfNN_External_Rela));
4627       bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
4628     }
4629
4630   /* Mark some specially defined symbols as absolute.  */
4631   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4632       || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
4633       || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4634     sym->st_shndx = SHN_ABS;
4635
4636   return TRUE;
4637 }
4638
4639 static bfd_boolean
4640 elfNN_ia64_finish_dynamic_sections (abfd, info)
4641      bfd *abfd;
4642      struct bfd_link_info *info;
4643 {
4644   struct elfNN_ia64_link_hash_table *ia64_info;
4645   bfd *dynobj;
4646
4647   ia64_info = elfNN_ia64_hash_table (info);
4648   dynobj = ia64_info->root.dynobj;
4649
4650   if (elf_hash_table (info)->dynamic_sections_created)
4651     {
4652       ElfNN_External_Dyn *dyncon, *dynconend;
4653       asection *sdyn, *sgotplt;
4654       bfd_vma gp_val;
4655
4656       sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4657       sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
4658       BFD_ASSERT (sdyn != NULL);
4659       dyncon = (ElfNN_External_Dyn *) sdyn->contents;
4660       dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
4661
4662       gp_val = _bfd_get_gp_value (abfd);
4663
4664       for (; dyncon < dynconend; dyncon++)
4665         {
4666           Elf_Internal_Dyn dyn;
4667
4668           bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
4669
4670           switch (dyn.d_tag)
4671             {
4672             case DT_PLTGOT:
4673               dyn.d_un.d_ptr = gp_val;
4674               break;
4675
4676             case DT_PLTRELSZ:
4677               dyn.d_un.d_val = (ia64_info->minplt_entries
4678                                 * sizeof (ElfNN_External_Rela));
4679               break;
4680
4681             case DT_JMPREL:
4682               /* See the comment above in finish_dynamic_symbol.  */
4683               dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
4684                                 + ia64_info->rel_pltoff_sec->output_offset
4685                                 + (ia64_info->rel_pltoff_sec->reloc_count
4686                                    * sizeof (ElfNN_External_Rela)));
4687               break;
4688
4689             case DT_IA_64_PLT_RESERVE:
4690               dyn.d_un.d_ptr = (sgotplt->output_section->vma
4691                                 + sgotplt->output_offset);
4692               break;
4693
4694             case DT_RELASZ:
4695               /* Do not have RELASZ include JMPREL.  This makes things
4696                  easier on ld.so.  This is not what the rest of BFD set up.  */
4697               dyn.d_un.d_val -= (ia64_info->minplt_entries
4698                                  * sizeof (ElfNN_External_Rela));
4699               break;
4700             }
4701
4702           bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
4703         }
4704
4705       /* Initialize the PLT0 entry.  */
4706       if (ia64_info->plt_sec)
4707         {
4708           bfd_byte *loc = ia64_info->plt_sec->contents;
4709           bfd_vma pltres;
4710
4711           memcpy (loc, plt_header, PLT_HEADER_SIZE);
4712
4713           pltres = (sgotplt->output_section->vma
4714                     + sgotplt->output_offset
4715                     - gp_val);
4716
4717           elfNN_ia64_install_value (abfd, loc+1, pltres, R_IA64_GPREL22);
4718         }
4719     }
4720
4721   return TRUE;
4722 }
4723 \f
4724 /* ELF file flag handling:  */
4725
4726 /* Function to keep IA-64 specific file flags.  */
4727 static bfd_boolean
4728 elfNN_ia64_set_private_flags (abfd, flags)
4729      bfd *abfd;
4730      flagword flags;
4731 {
4732   BFD_ASSERT (!elf_flags_init (abfd)
4733               || elf_elfheader (abfd)->e_flags == flags);
4734
4735   elf_elfheader (abfd)->e_flags = flags;
4736   elf_flags_init (abfd) = TRUE;
4737   return TRUE;
4738 }
4739
4740 /* Merge backend specific data from an object file to the output
4741    object file when linking.  */
4742 static bfd_boolean
4743 elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
4744      bfd *ibfd, *obfd;
4745 {
4746   flagword out_flags;
4747   flagword in_flags;
4748   bfd_boolean ok = TRUE;
4749
4750   /* Don't even pretend to support mixed-format linking.  */
4751   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4752       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4753     return FALSE;
4754
4755   in_flags  = elf_elfheader (ibfd)->e_flags;
4756   out_flags = elf_elfheader (obfd)->e_flags;
4757
4758   if (! elf_flags_init (obfd))
4759     {
4760       elf_flags_init (obfd) = TRUE;
4761       elf_elfheader (obfd)->e_flags = in_flags;
4762
4763       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4764           && bfd_get_arch_info (obfd)->the_default)
4765         {
4766           return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4767                                     bfd_get_mach (ibfd));
4768         }
4769
4770       return TRUE;
4771     }
4772
4773   /* Check flag compatibility.  */
4774   if (in_flags == out_flags)
4775     return TRUE;
4776
4777   /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set.  */
4778   if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
4779     elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
4780
4781   if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
4782     {
4783       (*_bfd_error_handler)
4784         (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4785          bfd_archive_filename (ibfd));
4786
4787       bfd_set_error (bfd_error_bad_value);
4788       ok = FALSE;
4789     }
4790   if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
4791     {
4792       (*_bfd_error_handler)
4793         (_("%s: linking big-endian files with little-endian files"),
4794          bfd_archive_filename (ibfd));
4795
4796       bfd_set_error (bfd_error_bad_value);
4797       ok = FALSE;
4798     }
4799   if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4800     {
4801       (*_bfd_error_handler)
4802         (_("%s: linking 64-bit files with 32-bit files"),
4803          bfd_archive_filename (ibfd));
4804
4805       bfd_set_error (bfd_error_bad_value);
4806       ok = FALSE;
4807     }
4808   if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4809     {
4810       (*_bfd_error_handler)
4811         (_("%s: linking constant-gp files with non-constant-gp files"),
4812          bfd_archive_filename (ibfd));
4813
4814       bfd_set_error (bfd_error_bad_value);
4815       ok = FALSE;
4816     }
4817   if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4818       != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4819     {
4820       (*_bfd_error_handler)
4821         (_("%s: linking auto-pic files with non-auto-pic files"),
4822          bfd_archive_filename (ibfd));
4823
4824       bfd_set_error (bfd_error_bad_value);
4825       ok = FALSE;
4826     }
4827
4828   return ok;
4829 }
4830
4831 static bfd_boolean
4832 elfNN_ia64_print_private_bfd_data (abfd, ptr)
4833      bfd *abfd;
4834      PTR ptr;
4835 {
4836   FILE *file = (FILE *) ptr;
4837   flagword flags = elf_elfheader (abfd)->e_flags;
4838
4839   BFD_ASSERT (abfd != NULL && ptr != NULL);
4840
4841   fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4842            (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4843            (flags & EF_IA_64_EXT) ? "EXT, " : "",
4844            (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4845            (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4846            (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4847            (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4848            (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4849            (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4850
4851   _bfd_elf_print_private_bfd_data (abfd, ptr);
4852   return TRUE;
4853 }
4854
4855 static enum elf_reloc_type_class
4856 elfNN_ia64_reloc_type_class (rela)
4857      const Elf_Internal_Rela *rela;
4858 {
4859   switch ((int) ELFNN_R_TYPE (rela->r_info))
4860     {
4861     case R_IA64_REL32MSB:
4862     case R_IA64_REL32LSB:
4863     case R_IA64_REL64MSB:
4864     case R_IA64_REL64LSB:
4865       return reloc_class_relative;
4866     case R_IA64_IPLTMSB:
4867     case R_IA64_IPLTLSB:
4868       return reloc_class_plt;
4869     case R_IA64_COPY:
4870       return reloc_class_copy;
4871     default:
4872       return reloc_class_normal;
4873     }
4874 }
4875
4876 static struct bfd_elf_special_section const elfNN_ia64_special_sections[]=
4877 {
4878   { ".sbss",  5, -1, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
4879   { ".sdata", 6, -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
4880   { NULL,     0,  0, 0,            0 }
4881 };
4882
4883 static bfd_boolean
4884 elfNN_ia64_hpux_vec (const bfd_target *vec)
4885 {
4886   extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
4887   return (vec == & bfd_elfNN_ia64_hpux_big_vec);
4888 }
4889
4890 static void
4891 elfNN_hpux_post_process_headers (abfd, info)
4892         bfd *abfd;
4893         struct bfd_link_info *info ATTRIBUTE_UNUSED;
4894 {
4895   Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
4896
4897   i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_HPUX;
4898   i_ehdrp->e_ident[EI_ABIVERSION] = 1;
4899 }
4900
4901 bfd_boolean
4902 elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
4903         bfd *abfd ATTRIBUTE_UNUSED;
4904         asection *sec;
4905         int *retval;
4906 {
4907   if (bfd_is_com_section (sec))
4908     {
4909       *retval = SHN_IA_64_ANSI_COMMON;
4910       return TRUE;
4911     }
4912   return FALSE;
4913 }
4914
4915 static void
4916 elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
4917                                       asymbol *asym)
4918 {
4919   elf_symbol_type *elfsym = (elf_symbol_type *) asym;;
4920
4921   switch (elfsym->internal_elf_sym.st_shndx)
4922     {
4923     case SHN_IA_64_ANSI_COMMON:
4924       asym->section = bfd_com_section_ptr;
4925       asym->value = elfsym->internal_elf_sym.st_size;
4926       asym->flags &= ~BSF_GLOBAL;
4927       break;
4928     }
4929 }
4930
4931 \f
4932 #define TARGET_LITTLE_SYM               bfd_elfNN_ia64_little_vec
4933 #define TARGET_LITTLE_NAME              "elfNN-ia64-little"
4934 #define TARGET_BIG_SYM                  bfd_elfNN_ia64_big_vec
4935 #define TARGET_BIG_NAME                 "elfNN-ia64-big"
4936 #define ELF_ARCH                        bfd_arch_ia64
4937 #define ELF_MACHINE_CODE                EM_IA_64
4938 #define ELF_MACHINE_ALT1                1999    /* EAS2.3 */
4939 #define ELF_MACHINE_ALT2                1998    /* EAS2.2 */
4940 #define ELF_MAXPAGESIZE                 0x10000 /* 64KB */
4941
4942 #define elf_backend_section_from_shdr \
4943         elfNN_ia64_section_from_shdr
4944 #define elf_backend_section_flags \
4945         elfNN_ia64_section_flags
4946 #define elf_backend_fake_sections \
4947         elfNN_ia64_fake_sections
4948 #define elf_backend_final_write_processing \
4949         elfNN_ia64_final_write_processing
4950 #define elf_backend_add_symbol_hook \
4951         elfNN_ia64_add_symbol_hook
4952 #define elf_backend_additional_program_headers \
4953         elfNN_ia64_additional_program_headers
4954 #define elf_backend_modify_segment_map \
4955         elfNN_ia64_modify_segment_map
4956 #define elf_info_to_howto \
4957         elfNN_ia64_info_to_howto
4958
4959 #define bfd_elfNN_bfd_reloc_type_lookup \
4960         elfNN_ia64_reloc_type_lookup
4961 #define bfd_elfNN_bfd_is_local_label_name \
4962         elfNN_ia64_is_local_label_name
4963 #define bfd_elfNN_bfd_relax_section \
4964         elfNN_ia64_relax_section
4965
4966 /* Stuff for the BFD linker: */
4967 #define bfd_elfNN_bfd_link_hash_table_create \
4968         elfNN_ia64_hash_table_create
4969 #define bfd_elfNN_bfd_link_hash_table_free \
4970         elfNN_ia64_hash_table_free
4971 #define elf_backend_create_dynamic_sections \
4972         elfNN_ia64_create_dynamic_sections
4973 #define elf_backend_check_relocs \
4974         elfNN_ia64_check_relocs
4975 #define elf_backend_adjust_dynamic_symbol \
4976         elfNN_ia64_adjust_dynamic_symbol
4977 #define elf_backend_size_dynamic_sections \
4978         elfNN_ia64_size_dynamic_sections
4979 #define elf_backend_relocate_section \
4980         elfNN_ia64_relocate_section
4981 #define elf_backend_finish_dynamic_symbol \
4982         elfNN_ia64_finish_dynamic_symbol
4983 #define elf_backend_finish_dynamic_sections \
4984         elfNN_ia64_finish_dynamic_sections
4985 #define bfd_elfNN_bfd_final_link \
4986         elfNN_ia64_final_link
4987
4988 #define bfd_elfNN_bfd_merge_private_bfd_data \
4989         elfNN_ia64_merge_private_bfd_data
4990 #define bfd_elfNN_bfd_set_private_flags \
4991         elfNN_ia64_set_private_flags
4992 #define bfd_elfNN_bfd_print_private_bfd_data \
4993         elfNN_ia64_print_private_bfd_data
4994
4995 #define elf_backend_plt_readonly        1
4996 #define elf_backend_want_plt_sym        0
4997 #define elf_backend_plt_alignment       5
4998 #define elf_backend_got_header_size     0
4999 #define elf_backend_want_got_plt        1
5000 #define elf_backend_may_use_rel_p       1
5001 #define elf_backend_may_use_rela_p      1
5002 #define elf_backend_default_use_rela_p  1
5003 #define elf_backend_want_dynbss         0
5004 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
5005 #define elf_backend_hide_symbol         elfNN_ia64_hash_hide_symbol
5006 #define elf_backend_reloc_type_class    elfNN_ia64_reloc_type_class
5007 #define elf_backend_rela_normal         1
5008 #define elf_backend_special_sections    elfNN_ia64_special_sections
5009
5010 #include "elfNN-target.h"
5011
5012 /* HPUX-specific vectors.  */
5013
5014 #undef  TARGET_LITTLE_SYM
5015 #undef  TARGET_LITTLE_NAME
5016 #undef  TARGET_BIG_SYM
5017 #define TARGET_BIG_SYM                  bfd_elfNN_ia64_hpux_big_vec
5018 #undef  TARGET_BIG_NAME
5019 #define TARGET_BIG_NAME                 "elfNN-ia64-hpux-big"
5020
5021 /* These are HP-UX specific functions.  */
5022
5023 #undef  elf_backend_post_process_headers
5024 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
5025
5026 #undef  elf_backend_section_from_bfd_section
5027 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
5028
5029 #undef elf_backend_symbol_processing
5030 #define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
5031
5032 #undef  elf_backend_want_p_paddr_set_to_zero
5033 #define elf_backend_want_p_paddr_set_to_zero 1
5034
5035 #undef  ELF_MAXPAGESIZE
5036 #define ELF_MAXPAGESIZE                 0x1000  /* 1K */
5037
5038 #undef  elfNN_bed
5039 #define elfNN_bed elfNN_ia64_hpux_bed
5040
5041 #include "elfNN-target.h"
5042
5043 #undef  elf_backend_want_p_paddr_set_to_zero