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