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