1 1.1 christos /* LoongArch-specific support for NN-bit ELF. 2 1.1.1.3 christos Copyright (C) 2021-2025 Free Software Foundation, Inc. 3 1.1 christos Contributed by Loongson Ltd. 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; see the file COPYING3. If not, 19 1.1 christos see <http://www.gnu.org/licenses/>. */ 20 1.1 christos 21 1.1 christos #include "ansidecl.h" 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 #define ARCH_SIZE NN 26 1.1 christos #include "elf-bfd.h" 27 1.1 christos #include "objalloc.h" 28 1.1.1.3 christos #include "splay-tree.h" 29 1.1 christos #include "elf/loongarch.h" 30 1.1 christos #include "elfxx-loongarch.h" 31 1.1.1.2 christos #include "opcode/loongarch.h" 32 1.1 christos 33 1.1 christos static bool 34 1.1 christos loongarch_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, 35 1.1 christos Elf_Internal_Rela *dst) 36 1.1 christos { 37 1.1 christos cache_ptr->howto = loongarch_elf_rtype_to_howto (abfd, 38 1.1 christos ELFNN_R_TYPE (dst->r_info)); 39 1.1 christos return cache_ptr->howto != NULL; 40 1.1 christos } 41 1.1 christos 42 1.1 christos /* LoongArch ELF linker hash entry. */ 43 1.1 christos struct loongarch_elf_link_hash_entry 44 1.1 christos { 45 1.1 christos struct elf_link_hash_entry elf; 46 1.1 christos 47 1.1 christos #define GOT_UNKNOWN 0 48 1.1 christos #define GOT_NORMAL 1 49 1.1 christos #define GOT_TLS_GD 2 50 1.1 christos #define GOT_TLS_IE 4 51 1.1 christos #define GOT_TLS_LE 8 52 1.1.1.2 christos #define GOT_TLS_GDESC 16 53 1.1.1.2 christos 54 1.1.1.2 christos #define GOT_TLS_GD_BOTH_P(tls_type) \ 55 1.1.1.2 christos ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GDESC)) 56 1.1.1.2 christos #define GOT_TLS_GD_ANY_P(tls_type) \ 57 1.1.1.2 christos ((tls_type & GOT_TLS_GD) || (tls_type & GOT_TLS_GDESC)) 58 1.1 christos char tls_type; 59 1.1 christos }; 60 1.1 christos 61 1.1 christos #define loongarch_elf_hash_entry(ent) \ 62 1.1 christos ((struct loongarch_elf_link_hash_entry *) (ent)) 63 1.1 christos 64 1.1 christos struct _bfd_loongarch_elf_obj_tdata 65 1.1 christos { 66 1.1 christos struct elf_obj_tdata root; 67 1.1 christos 68 1.1 christos /* The tls_type for each local got entry. */ 69 1.1 christos char *local_got_tls_type; 70 1.1 christos }; 71 1.1 christos 72 1.1 christos #define _bfd_loongarch_elf_tdata(abfd) \ 73 1.1 christos ((struct _bfd_loongarch_elf_obj_tdata *) (abfd)->tdata.any) 74 1.1 christos 75 1.1 christos #define _bfd_loongarch_elf_local_got_tls_type(abfd) \ 76 1.1 christos (_bfd_loongarch_elf_tdata (abfd)->local_got_tls_type) 77 1.1 christos 78 1.1 christos #define _bfd_loongarch_elf_tls_type(abfd, h, symndx) \ 79 1.1 christos (*((h) != NULL \ 80 1.1 christos ? &loongarch_elf_hash_entry (h)->tls_type \ 81 1.1 christos : &_bfd_loongarch_elf_local_got_tls_type (abfd)[symndx])) 82 1.1 christos 83 1.1 christos #define is_loongarch_elf(bfd) \ 84 1.1 christos (bfd_get_flavour (bfd) == bfd_target_elf_flavour \ 85 1.1 christos && elf_tdata (bfd) != NULL \ 86 1.1 christos && elf_object_id (bfd) == LARCH_ELF_DATA) 87 1.1 christos 88 1.1.1.3 christos static bool 89 1.1.1.3 christos elfNN_loongarch_object (bfd *abfd) 90 1.1.1.3 christos { 91 1.1.1.3 christos return bfd_elf_allocate_object (abfd, 92 1.1.1.3 christos sizeof (struct _bfd_loongarch_elf_obj_tdata)); 93 1.1.1.3 christos } 94 1.1.1.3 christos 95 1.1.1.3 christos struct relr_entry 96 1.1.1.3 christos { 97 1.1.1.3 christos asection *sec; 98 1.1.1.3 christos bfd_vma off; 99 1.1.1.3 christos }; 100 1.1.1.3 christos 101 1.1 christos struct loongarch_elf_link_hash_table 102 1.1 christos { 103 1.1 christos struct elf_link_hash_table elf; 104 1.1 christos 105 1.1 christos /* Short-cuts to get to dynamic linker sections. */ 106 1.1 christos asection *sdyntdata; 107 1.1 christos 108 1.1 christos /* Small local sym to section mapping cache. */ 109 1.1 christos struct sym_cache sym_cache; 110 1.1 christos 111 1.1 christos /* Used by local STT_GNU_IFUNC symbols. */ 112 1.1 christos htab_t loc_hash_table; 113 1.1 christos void *loc_hash_memory; 114 1.1 christos 115 1.1 christos /* The max alignment of output sections. */ 116 1.1 christos bfd_vma max_alignment; 117 1.1.1.2 christos 118 1.1.1.2 christos /* The data segment phase, don't relax the section 119 1.1.1.2 christos when it is exp_seg_relro_adjust. */ 120 1.1.1.2 christos int *data_segment_phase; 121 1.1.1.3 christos 122 1.1.1.3 christos /* Array of relative relocs to be emitted in DT_RELR format. */ 123 1.1.1.3 christos bfd_size_type relr_alloc; 124 1.1.1.3 christos bfd_size_type relr_count; 125 1.1.1.3 christos struct relr_entry *relr; 126 1.1.1.3 christos 127 1.1.1.3 christos /* Sorted output addresses of above relative relocs. */ 128 1.1.1.3 christos bfd_vma *relr_sorted; 129 1.1.1.3 christos 130 1.1.1.3 christos /* Layout recomputation count. */ 131 1.1.1.3 christos bfd_size_type relr_layout_iter; 132 1.1.1.3 christos 133 1.1.1.3 christos /* In BFD DT_RELR is implemented as a "relaxation." If in a relax trip 134 1.1.1.3 christos size_relative_relocs is updating the layout, relax_section may see 135 1.1.1.3 christos a partially updated state (some sections have vma updated but the 136 1.1.1.3 christos others do not), and it's unsafe to do the normal relaxation. */ 137 1.1.1.3 christos bool layout_mutating_for_relr; 138 1.1.1.3 christos 139 1.1.1.3 christos /* Pending relaxation (byte deletion) operations meant for roughly 140 1.1.1.3 christos sequential access. */ 141 1.1.1.3 christos splay_tree pending_delete_ops; 142 1.1.1.3 christos }; 143 1.1.1.3 christos 144 1.1.1.3 christos struct loongarch_elf_section_data 145 1.1.1.3 christos { 146 1.1.1.3 christos struct bfd_elf_section_data elf; 147 1.1.1.3 christos 148 1.1.1.3 christos /* &htab->relr[i] where i is the smallest number s.t. 149 1.1.1.3 christos elf_section_data (htab->relr[i].sec) == &elf. 150 1.1.1.3 christos NULL if there exists no such i. */ 151 1.1.1.3 christos struct relr_entry *relr; 152 1.1 christos }; 153 1.1 christos 154 1.1.1.3 christos /* We need an additional field in elf_section_data to handle complex 155 1.1.1.3 christos interactions between DT_RELR and relaxation. */ 156 1.1.1.3 christos static bool 157 1.1.1.3 christos loongarch_elf_new_section_hook (bfd *abfd, asection *sec) 158 1.1.1.3 christos { 159 1.1.1.3 christos struct loongarch_elf_section_data *sdata; 160 1.1.1.3 christos 161 1.1.1.3 christos sdata = bfd_zalloc (abfd, sizeof (*sdata)); 162 1.1.1.3 christos if (!sdata) 163 1.1.1.3 christos return false; 164 1.1.1.3 christos sec->used_by_bfd = sdata; 165 1.1.1.3 christos 166 1.1.1.3 christos return _bfd_elf_new_section_hook (abfd, sec); 167 1.1.1.3 christos } 168 1.1.1.3 christos 169 1.1.1.3 christos #define loongarch_elf_section_data(x) \ 170 1.1.1.3 christos ((struct loongarch_elf_section_data *) elf_section_data (x)) 171 1.1.1.3 christos 172 1.1 christos /* Get the LoongArch ELF linker hash table from a link_info structure. */ 173 1.1 christos #define loongarch_elf_hash_table(p) \ 174 1.1.1.3 christos ((struct loongarch_elf_link_hash_table *) ((p)->hash)) \ 175 1.1.1.3 christos 176 1.1.1.3 christos /* During linker relaxation, indicates whether the section has already 177 1.1.1.3 christos undergone alignment processing and no more byte deletion is permitted. */ 178 1.1.1.3 christos #define loongarch_sec_closed_for_deletion(sec) ((sec)->sec_flg0) 179 1.1 christos 180 1.1 christos #define MINUS_ONE ((bfd_vma) 0 - 1) 181 1.1 christos 182 1.1 christos #define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset) 183 1.1 christos 184 1.1 christos #define LARCH_ELF_LOG_WORD_BYTES (ARCH_SIZE == 32 ? 2 : 3) 185 1.1 christos #define LARCH_ELF_WORD_BYTES (1 << LARCH_ELF_LOG_WORD_BYTES) 186 1.1 christos 187 1.1 christos #define PLT_HEADER_INSNS 8 188 1.1 christos #define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4) 189 1.1 christos 190 1.1 christos #define PLT_ENTRY_INSNS 4 191 1.1 christos #define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4) 192 1.1 christos 193 1.1 christos #define GOT_ENTRY_SIZE (LARCH_ELF_WORD_BYTES) 194 1.1 christos 195 1.1.1.3 christos /* Reserve two entries of GOTPLT for ld.so, one is used for PLT 196 1.1.1.3 christos resolver _dl_runtime_resolve, the other is used for link map. */ 197 1.1 christos #define GOTPLT_HEADER_SIZE (GOT_ENTRY_SIZE * 2) 198 1.1 christos 199 1.1 christos #define elf_backend_want_got_plt 1 200 1.1 christos 201 1.1 christos #define elf_backend_plt_readonly 1 202 1.1 christos 203 1.1.1.2 christos #define elf_backend_want_plt_sym 1 204 1.1 christos #define elf_backend_plt_alignment 4 205 1.1 christos #define elf_backend_can_gc_sections 1 206 1.1.1.2 christos #define elf_backend_can_refcount 1 207 1.1 christos #define elf_backend_want_got_sym 1 208 1.1 christos 209 1.1 christos #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 1) 210 1.1 christos 211 1.1 christos #define elf_backend_want_dynrelro 1 212 1.1.1.2 christos #define elf_backend_rela_normal 1 213 1.1.1.2 christos #define elf_backend_default_execstack 0 214 1.1.1.2 christos 215 1.1.1.2 christos #define IS_LOONGARCH_TLS_TRANS_RELOC(R_TYPE) \ 216 1.1.1.2 christos ((R_TYPE) == R_LARCH_TLS_DESC_PC_HI20 \ 217 1.1.1.2 christos || (R_TYPE) == R_LARCH_TLS_DESC_PC_LO12 \ 218 1.1.1.2 christos || (R_TYPE) == R_LARCH_TLS_DESC_LD \ 219 1.1.1.2 christos || (R_TYPE) == R_LARCH_TLS_DESC_CALL \ 220 1.1.1.2 christos || (R_TYPE) == R_LARCH_TLS_IE_PC_HI20 \ 221 1.1.1.2 christos || (R_TYPE) == R_LARCH_TLS_IE_PC_LO12) 222 1.1 christos 223 1.1.1.3 christos #define IS_OUTDATED_TLS_LE_RELOC(R_TYPE) \ 224 1.1.1.3 christos ((R_TYPE) == R_LARCH_TLS_LE_HI20 \ 225 1.1.1.3 christos || (R_TYPE) == R_LARCH_TLS_LE_LO12 \ 226 1.1.1.3 christos || (R_TYPE) == R_LARCH_TLS_LE64_LO20 \ 227 1.1.1.3 christos || (R_TYPE) == R_LARCH_TLS_LE64_HI12) 228 1.1.1.3 christos 229 1.1.1.3 christos #define IS_CALL_RELOC(R_TYPE) \ 230 1.1.1.3 christos ((R_TYPE) == R_LARCH_B26 \ 231 1.1.1.3 christos ||(R_TYPE) == R_LARCH_CALL36) 232 1.1.1.3 christos 233 1.1.1.3 christos /* If TLS GD/IE need dynamic relocations, INDX will be the dynamic indx, 234 1.1.1.3 christos and set NEED_RELOC to true used in allocate_dynrelocs and 235 1.1.1.3 christos loongarch_elf_relocate_section for TLS GD/IE. */ 236 1.1.1.3 christos #define LARCH_TLS_GD_IE_NEED_DYN_RELOC(INFO, DYN, H, INDX, NEED_RELOC) \ 237 1.1.1.3 christos do \ 238 1.1.1.3 christos { \ 239 1.1.1.3 christos if ((H) != NULL \ 240 1.1.1.3 christos && (H)->dynindx != -1 \ 241 1.1.1.3 christos && WILL_CALL_FINISH_DYNAMIC_SYMBOL ((DYN), \ 242 1.1.1.3 christos bfd_link_pic (INFO), (H))) \ 243 1.1.1.3 christos (INDX) = (H)->dynindx; \ 244 1.1.1.3 christos if (((H) == NULL \ 245 1.1.1.3 christos || ELF_ST_VISIBILITY ((H)->other) == STV_DEFAULT \ 246 1.1.1.3 christos || (H)->root.type != bfd_link_hash_undefweak) \ 247 1.1.1.3 christos && (!bfd_link_executable (INFO) \ 248 1.1.1.3 christos || (INDX) != 0)) \ 249 1.1.1.3 christos (NEED_RELOC) = true; \ 250 1.1.1.3 christos } \ 251 1.1.1.3 christos while (0) 252 1.1.1.3 christos 253 1.1.1.3 christos /* TL;DR always use it in this file instead when you want to type 254 1.1.1.3 christos SYMBOL_REFERENCES_LOCAL. 255 1.1.1.3 christos 256 1.1.1.3 christos It's like SYMBOL_REFERENCES_LOCAL, but it returns true for local 257 1.1.1.3 christos protected functions. It happens to be same as SYMBOL_CALLS_LOCAL but 258 1.1.1.3 christos let's not reuse SYMBOL_CALLS_LOCAL or "CALLS" may puzzle people. 259 1.1.1.3 christos 260 1.1.1.3 christos We do generate a PLT entry when someone attempts to la.pcrel an external 261 1.1.1.3 christos function. But we never really implemented "R_LARCH_COPY", thus we've 262 1.1.1.3 christos never supported la.pcrel an external symbol unless the loaded address is 263 1.1.1.3 christos only used for locating a function to be called. Thus the PLT entry is 264 1.1.1.3 christos a normal PLT entry, not intended to be a so-called "canonical PLT entry" 265 1.1.1.3 christos on the ports supporting copy relocation. So attempting to la.pcrel an 266 1.1.1.3 christos external function will just break pointer equality, even it's a 267 1.1.1.3 christos STV_DEFAULT function: 268 1.1.1.3 christos 269 1.1.1.3 christos $ cat t.c 270 1.1.1.3 christos #include <assert.h> 271 1.1.1.3 christos void check(void *p) {assert(p == check);} 272 1.1.1.3 christos $ cat main.c 273 1.1.1.3 christos extern void check(void *); 274 1.1.1.3 christos int main(void) { check(check); } 275 1.1.1.3 christos $ cc t.c -fPIC -shared -o t.so 276 1.1.1.3 christos $ cc main.c -mdirect-extern-access t.so -Wl,-rpath=. -fpie -pie 277 1.1.1.3 christos $ ./a.out 278 1.1.1.3 christos a.out: t.c:2: check: Assertion `p == check' failed. 279 1.1.1.3 christos Aborted 280 1.1.1.3 christos 281 1.1.1.3 christos Thus handling STV_PROTECTED function specially just fixes nothing: 282 1.1.1.3 christos adding -fvisibility=protected compiling t.c will not magically fix 283 1.1.1.3 christos the inequality. The only possible and correct fix is not to use 284 1.1.1.3 christos -mdirect-extern-access. 285 1.1.1.3 christos 286 1.1.1.3 christos So we should remove this special handling, because it's only an 287 1.1.1.3 christos unsuccessful workaround for invalid code and it's penalizing valid 288 1.1.1.3 christos code. */ 289 1.1.1.3 christos #define LARCH_REF_LOCAL(info, h) \ 290 1.1.1.3 christos (_bfd_elf_symbol_refs_local_p ((h), (info), true)) 291 1.1.1.3 christos 292 1.1 christos /* Generate a PLT header. */ 293 1.1 christos 294 1.1 christos static bool 295 1.1 christos loongarch_make_plt_header (bfd_vma got_plt_addr, bfd_vma plt_header_addr, 296 1.1 christos uint32_t *entry) 297 1.1 christos { 298 1.1 christos bfd_vma pcrel = got_plt_addr - plt_header_addr; 299 1.1 christos bfd_vma hi, lo; 300 1.1 christos 301 1.1 christos if (pcrel + 0x80000800 > 0xffffffff) 302 1.1 christos { 303 1.1 christos _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel); 304 1.1 christos bfd_set_error (bfd_error_bad_value); 305 1.1 christos return false; 306 1.1 christos } 307 1.1 christos hi = ((pcrel + 0x800) >> 12) & 0xfffff; 308 1.1 christos lo = pcrel & 0xfff; 309 1.1 christos 310 1.1 christos /* pcaddu12i $t2, %hi(%pcrel(.got.plt)) 311 1.1 christos sub.[wd] $t1, $t1, $t3 312 1.1 christos ld.[wd] $t3, $t2, %lo(%pcrel(.got.plt)) # _dl_runtime_resolve 313 1.1 christos addi.[wd] $t1, $t1, -(PLT_HEADER_SIZE + 12) 314 1.1 christos addi.[wd] $t0, $t2, %lo(%pcrel(.got.plt)) 315 1.1 christos srli.[wd] $t1, $t1, log2(16 / GOT_ENTRY_SIZE) 316 1.1 christos ld.[wd] $t0, $t0, GOT_ENTRY_SIZE 317 1.1 christos jirl $r0, $t3, 0 */ 318 1.1 christos 319 1.1 christos if (GOT_ENTRY_SIZE == 8) 320 1.1 christos { 321 1.1 christos entry[0] = 0x1c00000e | (hi & 0xfffff) << 5; 322 1.1 christos entry[1] = 0x0011bdad; 323 1.1 christos entry[2] = 0x28c001cf | (lo & 0xfff) << 10; 324 1.1 christos entry[3] = 0x02c001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10; 325 1.1 christos entry[4] = 0x02c001cc | (lo & 0xfff) << 10; 326 1.1 christos entry[5] = 0x004501ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10; 327 1.1 christos entry[6] = 0x28c0018c | GOT_ENTRY_SIZE << 10; 328 1.1 christos entry[7] = 0x4c0001e0; 329 1.1 christos } 330 1.1 christos else 331 1.1 christos { 332 1.1 christos entry[0] = 0x1c00000e | (hi & 0xfffff) << 5; 333 1.1 christos entry[1] = 0x00113dad; 334 1.1 christos entry[2] = 0x288001cf | (lo & 0xfff) << 10; 335 1.1 christos entry[3] = 0x028001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10; 336 1.1 christos entry[4] = 0x028001cc | (lo & 0xfff) << 10; 337 1.1 christos entry[5] = 0x004481ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10; 338 1.1 christos entry[6] = 0x2880018c | GOT_ENTRY_SIZE << 10; 339 1.1 christos entry[7] = 0x4c0001e0; 340 1.1 christos } 341 1.1 christos return true; 342 1.1 christos } 343 1.1 christos 344 1.1 christos /* Generate a PLT entry. */ 345 1.1 christos 346 1.1 christos static bool 347 1.1 christos loongarch_make_plt_entry (bfd_vma got_plt_entry_addr, bfd_vma plt_entry_addr, 348 1.1 christos uint32_t *entry) 349 1.1 christos { 350 1.1 christos bfd_vma pcrel = got_plt_entry_addr - plt_entry_addr; 351 1.1 christos bfd_vma hi, lo; 352 1.1 christos 353 1.1 christos if (pcrel + 0x80000800 > 0xffffffff) 354 1.1 christos { 355 1.1 christos _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel); 356 1.1 christos bfd_set_error (bfd_error_bad_value); 357 1.1 christos return false; 358 1.1 christos } 359 1.1 christos hi = ((pcrel + 0x800) >> 12) & 0xfffff; 360 1.1 christos lo = pcrel & 0xfff; 361 1.1 christos 362 1.1 christos entry[0] = 0x1c00000f | (hi & 0xfffff) << 5; 363 1.1 christos entry[1] = ((GOT_ENTRY_SIZE == 8 ? 0x28c001ef : 0x288001ef) 364 1.1 christos | (lo & 0xfff) << 10); 365 1.1 christos entry[2] = 0x4c0001ed; /* jirl $r13, $15, 0 */ 366 1.1 christos entry[3] = 0x03400000; /* nop */ 367 1.1 christos 368 1.1 christos return true; 369 1.1 christos } 370 1.1 christos 371 1.1 christos /* Create an entry in an LoongArch ELF linker hash table. */ 372 1.1 christos 373 1.1 christos static struct bfd_hash_entry * 374 1.1 christos link_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table, 375 1.1 christos const char *string) 376 1.1 christos { 377 1.1 christos struct loongarch_elf_link_hash_entry *eh; 378 1.1 christos 379 1.1 christos /* Allocate the structure if it has not already been allocated by a 380 1.1 christos subclass. */ 381 1.1 christos if (entry == NULL) 382 1.1 christos { 383 1.1 christos entry = bfd_hash_allocate (table, sizeof (*eh)); 384 1.1 christos if (entry == NULL) 385 1.1 christos return entry; 386 1.1 christos } 387 1.1 christos 388 1.1 christos /* Call the allocation method of the superclass. */ 389 1.1 christos entry = _bfd_elf_link_hash_newfunc (entry, table, string); 390 1.1 christos if (entry != NULL) 391 1.1 christos { 392 1.1 christos eh = (struct loongarch_elf_link_hash_entry *) entry; 393 1.1 christos eh->tls_type = GOT_UNKNOWN; 394 1.1 christos } 395 1.1 christos 396 1.1 christos return entry; 397 1.1 christos } 398 1.1 christos 399 1.1 christos /* Compute a hash of a local hash entry. We use elf_link_hash_entry 400 1.1 christos for local symbol so that we can handle local STT_GNU_IFUNC symbols 401 1.1 christos as global symbol. We reuse indx and dynstr_index for local symbol 402 1.1 christos hash since they aren't used by global symbols in this backend. */ 403 1.1 christos 404 1.1 christos static hashval_t 405 1.1 christos elfNN_loongarch_local_htab_hash (const void *ptr) 406 1.1 christos { 407 1.1 christos struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) ptr; 408 1.1 christos return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index); 409 1.1 christos } 410 1.1 christos 411 1.1 christos /* Compare local hash entries. */ 412 1.1 christos 413 1.1 christos static int 414 1.1 christos elfNN_loongarch_local_htab_eq (const void *ptr1, const void *ptr2) 415 1.1 christos { 416 1.1 christos struct elf_link_hash_entry *h1 = (struct elf_link_hash_entry *) ptr1; 417 1.1 christos struct elf_link_hash_entry *h2 = (struct elf_link_hash_entry *) ptr2; 418 1.1 christos 419 1.1 christos return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index; 420 1.1 christos } 421 1.1 christos 422 1.1 christos /* Find and/or create a hash entry for local symbol. */ 423 1.1 christos static struct elf_link_hash_entry * 424 1.1 christos elfNN_loongarch_get_local_sym_hash (struct loongarch_elf_link_hash_table *htab, 425 1.1 christos bfd *abfd, const Elf_Internal_Rela *rel, 426 1.1 christos bool create) 427 1.1 christos { 428 1.1 christos struct loongarch_elf_link_hash_entry e, *ret; 429 1.1 christos asection *sec = abfd->sections; 430 1.1 christos hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id, ELFNN_R_SYM (rel->r_info)); 431 1.1 christos void **slot; 432 1.1 christos 433 1.1 christos e.elf.indx = sec->id; 434 1.1 christos e.elf.dynstr_index = ELFNN_R_SYM (rel->r_info); 435 1.1 christos slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h, 436 1.1 christos create ? INSERT : NO_INSERT); 437 1.1 christos 438 1.1 christos if (!slot) 439 1.1 christos return NULL; 440 1.1 christos 441 1.1 christos if (*slot) 442 1.1 christos { 443 1.1 christos ret = (struct loongarch_elf_link_hash_entry *) *slot; 444 1.1 christos return &ret->elf; 445 1.1 christos } 446 1.1 christos 447 1.1 christos ret = ((struct loongarch_elf_link_hash_entry *) 448 1.1 christos objalloc_alloc ((struct objalloc *) htab->loc_hash_memory, 449 1.1 christos sizeof (struct loongarch_elf_link_hash_entry))); 450 1.1 christos if (ret) 451 1.1 christos { 452 1.1 christos memset (ret, 0, sizeof (*ret)); 453 1.1 christos ret->elf.indx = sec->id; 454 1.1 christos ret->elf.pointer_equality_needed = 0; 455 1.1 christos ret->elf.dynstr_index = ELFNN_R_SYM (rel->r_info); 456 1.1 christos ret->elf.dynindx = -1; 457 1.1 christos ret->elf.needs_plt = 0; 458 1.1 christos ret->elf.plt.refcount = -1; 459 1.1 christos ret->elf.got.refcount = -1; 460 1.1 christos ret->elf.def_dynamic = 0; 461 1.1 christos ret->elf.def_regular = 1; 462 1.1 christos ret->elf.ref_dynamic = 0; /* This should be always 0 for local. */ 463 1.1 christos ret->elf.ref_regular = 0; 464 1.1 christos ret->elf.forced_local = 1; 465 1.1 christos ret->elf.root.type = bfd_link_hash_defined; 466 1.1 christos *slot = ret; 467 1.1 christos } 468 1.1 christos return &ret->elf; 469 1.1 christos } 470 1.1 christos 471 1.1 christos /* Destroy an LoongArch elf linker hash table. */ 472 1.1 christos 473 1.1 christos static void 474 1.1 christos elfNN_loongarch_link_hash_table_free (bfd *obfd) 475 1.1 christos { 476 1.1 christos struct loongarch_elf_link_hash_table *ret; 477 1.1 christos ret = (struct loongarch_elf_link_hash_table *) obfd->link.hash; 478 1.1 christos 479 1.1 christos if (ret->loc_hash_table) 480 1.1 christos htab_delete (ret->loc_hash_table); 481 1.1 christos if (ret->loc_hash_memory) 482 1.1 christos objalloc_free ((struct objalloc *) ret->loc_hash_memory); 483 1.1 christos 484 1.1 christos _bfd_elf_link_hash_table_free (obfd); 485 1.1 christos } 486 1.1 christos 487 1.1 christos /* Create a LoongArch ELF linker hash table. */ 488 1.1 christos 489 1.1 christos static struct bfd_link_hash_table * 490 1.1 christos loongarch_elf_link_hash_table_create (bfd *abfd) 491 1.1 christos { 492 1.1 christos struct loongarch_elf_link_hash_table *ret; 493 1.1 christos bfd_size_type amt = sizeof (struct loongarch_elf_link_hash_table); 494 1.1 christos 495 1.1 christos ret = (struct loongarch_elf_link_hash_table *) bfd_zmalloc (amt); 496 1.1 christos if (ret == NULL) 497 1.1 christos return NULL; 498 1.1 christos 499 1.1 christos if (!_bfd_elf_link_hash_table_init 500 1.1 christos (&ret->elf, abfd, link_hash_newfunc, 501 1.1.1.3 christos sizeof (struct loongarch_elf_link_hash_entry))) 502 1.1 christos { 503 1.1 christos free (ret); 504 1.1 christos return NULL; 505 1.1 christos } 506 1.1 christos 507 1.1 christos ret->max_alignment = MINUS_ONE; 508 1.1 christos 509 1.1 christos ret->loc_hash_table = htab_try_create (1024, elfNN_loongarch_local_htab_hash, 510 1.1 christos elfNN_loongarch_local_htab_eq, NULL); 511 1.1 christos ret->loc_hash_memory = objalloc_create (); 512 1.1 christos if (!ret->loc_hash_table || !ret->loc_hash_memory) 513 1.1 christos { 514 1.1 christos elfNN_loongarch_link_hash_table_free (abfd); 515 1.1 christos return NULL; 516 1.1 christos } 517 1.1 christos ret->elf.root.hash_table_free = elfNN_loongarch_link_hash_table_free; 518 1.1 christos 519 1.1 christos return &ret->elf.root; 520 1.1 christos } 521 1.1 christos 522 1.1 christos /* Merge backend specific data from an object file to the output 523 1.1 christos object file when linking. */ 524 1.1 christos 525 1.1 christos static bool 526 1.1 christos elfNN_loongarch_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) 527 1.1 christos { 528 1.1 christos bfd *obfd = info->output_bfd; 529 1.1 christos flagword in_flags = elf_elfheader (ibfd)->e_flags; 530 1.1 christos flagword out_flags = elf_elfheader (obfd)->e_flags; 531 1.1 christos 532 1.1 christos if (!is_loongarch_elf (ibfd) || !is_loongarch_elf (obfd)) 533 1.1 christos return true; 534 1.1 christos 535 1.1 christos if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0) 536 1.1 christos { 537 1.1 christos _bfd_error_handler (_("%pB: ABI is incompatible with that of " 538 1.1 christos "the selected emulation:\n" 539 1.1 christos " target emulation `%s' does not match `%s'"), 540 1.1 christos ibfd, bfd_get_target (ibfd), bfd_get_target (obfd)); 541 1.1 christos return false; 542 1.1 christos } 543 1.1 christos 544 1.1 christos if (!_bfd_elf_merge_object_attributes (ibfd, info)) 545 1.1 christos return false; 546 1.1 christos 547 1.1 christos /* If the input BFD is not a dynamic object and it does not contain any 548 1.1 christos non-data sections, do not account its ABI. For example, various 549 1.1 christos packages produces such data-only relocatable objects with 550 1.1 christos `ld -r -b binary` or `objcopy`, and these objects have zero e_flags. 551 1.1 christos But they are compatible with all ABIs. */ 552 1.1 christos if (!(ibfd->flags & DYNAMIC)) 553 1.1 christos { 554 1.1 christos asection *sec; 555 1.1 christos bool have_code_sections = false; 556 1.1 christos for (sec = ibfd->sections; sec != NULL; sec = sec->next) 557 1.1 christos if ((bfd_section_flags (sec) 558 1.1 christos & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS)) 559 1.1 christos == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS)) 560 1.1 christos { 561 1.1 christos have_code_sections = true; 562 1.1 christos break; 563 1.1 christos } 564 1.1 christos if (!have_code_sections) 565 1.1 christos return true; 566 1.1 christos } 567 1.1 christos 568 1.1 christos if (!elf_flags_init (obfd)) 569 1.1 christos { 570 1.1 christos elf_flags_init (obfd) = true; 571 1.1 christos elf_elfheader (obfd)->e_flags = in_flags; 572 1.1 christos return true; 573 1.1 christos } 574 1.1.1.2 christos else if (out_flags != in_flags) 575 1.1.1.2 christos { 576 1.1.1.2 christos if ((EF_LOONGARCH_IS_OBJ_V0 (out_flags) 577 1.1.1.2 christos && EF_LOONGARCH_IS_OBJ_V1 (in_flags)) 578 1.1.1.2 christos || (EF_LOONGARCH_IS_OBJ_V0 (in_flags) 579 1.1.1.2 christos && EF_LOONGARCH_IS_OBJ_V1 (out_flags))) 580 1.1.1.2 christos { 581 1.1.1.2 christos elf_elfheader (obfd)->e_flags |= EF_LOONGARCH_OBJABI_V1; 582 1.1.1.2 christos out_flags = elf_elfheader (obfd)->e_flags; 583 1.1.1.2 christos in_flags = out_flags; 584 1.1.1.2 christos } 585 1.1.1.2 christos } 586 1.1 christos 587 1.1 christos /* Disallow linking different ABIs. */ 588 1.1.1.2 christos /* Only check relocation version. 589 1.1.1.2 christos The obj_v0 is compatible with obj_v1. */ 590 1.1 christos if (EF_LOONGARCH_ABI(out_flags ^ in_flags) & EF_LOONGARCH_ABI_MASK) 591 1.1 christos { 592 1.1 christos _bfd_error_handler (_("%pB: can't link different ABI object."), ibfd); 593 1.1 christos goto fail; 594 1.1 christos } 595 1.1 christos 596 1.1 christos return true; 597 1.1 christos 598 1.1 christos fail: 599 1.1 christos bfd_set_error (bfd_error_bad_value); 600 1.1 christos return false; 601 1.1 christos } 602 1.1 christos 603 1.1 christos /* Create the .got section. */ 604 1.1 christos 605 1.1 christos static bool 606 1.1 christos loongarch_elf_create_got_section (bfd *abfd, struct bfd_link_info *info) 607 1.1 christos { 608 1.1 christos flagword flags; 609 1.1 christos char *name; 610 1.1 christos asection *s, *s_got; 611 1.1 christos struct elf_link_hash_entry *h; 612 1.1 christos const struct elf_backend_data *bed = get_elf_backend_data (abfd); 613 1.1 christos struct elf_link_hash_table *htab = elf_hash_table (info); 614 1.1 christos 615 1.1 christos /* This function may be called more than once. */ 616 1.1 christos if (htab->sgot != NULL) 617 1.1 christos return true; 618 1.1 christos 619 1.1 christos flags = bed->dynamic_sec_flags; 620 1.1 christos name = bed->rela_plts_and_copies_p ? ".rela.got" : ".rel.got"; 621 1.1 christos s = bfd_make_section_anyway_with_flags (abfd, name, flags | SEC_READONLY); 622 1.1 christos 623 1.1 christos if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align)) 624 1.1 christos return false; 625 1.1 christos htab->srelgot = s; 626 1.1 christos 627 1.1 christos s = s_got = bfd_make_section_anyway_with_flags (abfd, ".got", flags); 628 1.1 christos if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align)) 629 1.1 christos return false; 630 1.1 christos htab->sgot = s; 631 1.1 christos 632 1.1 christos /* The first bit of the global offset table is the header. */ 633 1.1 christos s->size += bed->got_header_size; 634 1.1 christos 635 1.1 christos if (bed->want_got_plt) 636 1.1 christos { 637 1.1 christos s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags); 638 1.1 christos if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align)) 639 1.1 christos return false; 640 1.1 christos htab->sgotplt = s; 641 1.1 christos 642 1.1 christos /* Reserve room for the header. */ 643 1.1 christos s->size = GOTPLT_HEADER_SIZE; 644 1.1 christos } 645 1.1 christos 646 1.1 christos if (bed->want_got_sym) 647 1.1 christos { 648 1.1 christos /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got 649 1.1 christos section. We don't do this in the linker script because we don't want 650 1.1 christos to define the symbol if we are not creating a global offset table. */ 651 1.1 christos h = _bfd_elf_define_linkage_sym (abfd, info, s_got, 652 1.1 christos "_GLOBAL_OFFSET_TABLE_"); 653 1.1 christos elf_hash_table (info)->hgot = h; 654 1.1 christos if (h == NULL) 655 1.1 christos return false; 656 1.1 christos } 657 1.1 christos return true; 658 1.1 christos } 659 1.1 christos 660 1.1 christos /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and 661 1.1 christos .rela.bss sections in DYNOBJ, and set up shortcuts to them in our 662 1.1 christos hash table. */ 663 1.1 christos 664 1.1 christos static bool 665 1.1 christos loongarch_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info) 666 1.1 christos { 667 1.1 christos struct loongarch_elf_link_hash_table *htab; 668 1.1 christos 669 1.1 christos htab = loongarch_elf_hash_table (info); 670 1.1 christos BFD_ASSERT (htab != NULL); 671 1.1 christos 672 1.1 christos if (!loongarch_elf_create_got_section (dynobj, info)) 673 1.1 christos return false; 674 1.1 christos 675 1.1 christos if (!_bfd_elf_create_dynamic_sections (dynobj, info)) 676 1.1 christos return false; 677 1.1 christos 678 1.1 christos if (!bfd_link_pic (info)) 679 1.1 christos htab->sdyntdata 680 1.1 christos = bfd_make_section_anyway_with_flags (dynobj, ".tdata.dyn", 681 1.1 christos SEC_ALLOC | SEC_THREAD_LOCAL); 682 1.1 christos 683 1.1 christos if (!htab->elf.splt || !htab->elf.srelplt || !htab->elf.sdynbss 684 1.1 christos || (!bfd_link_pic (info) && (!htab->elf.srelbss || !htab->sdyntdata))) 685 1.1 christos abort (); 686 1.1 christos 687 1.1 christos return true; 688 1.1 christos } 689 1.1 christos 690 1.1 christos static bool 691 1.1 christos loongarch_elf_record_tls_and_got_reference (bfd *abfd, 692 1.1 christos struct bfd_link_info *info, 693 1.1 christos struct elf_link_hash_entry *h, 694 1.1 christos unsigned long symndx, 695 1.1.1.3 christos char tls_type, 696 1.1.1.3 christos bool with_relax_reloc) 697 1.1 christos { 698 1.1 christos struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info); 699 1.1 christos Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 700 1.1 christos 701 1.1 christos /* This is a global offset table entry for a local symbol. */ 702 1.1 christos if (elf_local_got_refcounts (abfd) == NULL) 703 1.1 christos { 704 1.1 christos bfd_size_type size = 705 1.1 christos symtab_hdr->sh_info * (sizeof (bfd_vma) + sizeof (tls_type)); 706 1.1 christos if (!(elf_local_got_refcounts (abfd) = bfd_zalloc (abfd, size))) 707 1.1 christos return false; 708 1.1 christos _bfd_loongarch_elf_local_got_tls_type (abfd) = 709 1.1 christos (char *) (elf_local_got_refcounts (abfd) + symtab_hdr->sh_info); 710 1.1 christos } 711 1.1 christos 712 1.1 christos switch (tls_type) 713 1.1 christos { 714 1.1 christos case GOT_NORMAL: 715 1.1 christos case GOT_TLS_GD: 716 1.1 christos case GOT_TLS_IE: 717 1.1.1.2 christos case GOT_TLS_GDESC: 718 1.1 christos /* Need GOT. */ 719 1.1 christos if (htab->elf.sgot == NULL 720 1.1 christos && !loongarch_elf_create_got_section (htab->elf.dynobj, info)) 721 1.1 christos return false; 722 1.1 christos if (h) 723 1.1 christos { 724 1.1 christos if (h->got.refcount < 0) 725 1.1 christos h->got.refcount = 0; 726 1.1 christos h->got.refcount++; 727 1.1 christos } 728 1.1 christos else 729 1.1 christos elf_local_got_refcounts (abfd)[symndx]++; 730 1.1 christos break; 731 1.1 christos case GOT_TLS_LE: 732 1.1 christos /* No need for GOT. */ 733 1.1 christos break; 734 1.1 christos default: 735 1.1 christos _bfd_error_handler (_("Internal error: unreachable.")); 736 1.1 christos return false; 737 1.1 christos } 738 1.1 christos 739 1.1 christos char *new_tls_type = &_bfd_loongarch_elf_tls_type (abfd, h, symndx); 740 1.1 christos *new_tls_type |= tls_type; 741 1.1.1.2 christos 742 1.1.1.3 christos /* If DESC relocs can do transitions and accessed by both IE and DESC, 743 1.1.1.3 christos transition DESC to IE. */ 744 1.1.1.3 christos if (with_relax_reloc 745 1.1.1.3 christos && (*new_tls_type & GOT_TLS_IE) && (*new_tls_type & GOT_TLS_GDESC)) 746 1.1.1.2 christos *new_tls_type &= ~ (GOT_TLS_GDESC); 747 1.1.1.3 christos 748 1.1 christos if ((*new_tls_type & GOT_NORMAL) && (*new_tls_type & ~GOT_NORMAL)) 749 1.1 christos { 750 1.1 christos _bfd_error_handler (_("%pB: `%s' accessed both as normal and " 751 1.1 christos "thread local symbol"), 752 1.1 christos abfd, 753 1.1 christos h ? h->root.root.string : "<local>"); 754 1.1 christos return false; 755 1.1 christos } 756 1.1 christos 757 1.1 christos return true; 758 1.1 christos } 759 1.1 christos 760 1.1.1.2 christos static unsigned int 761 1.1.1.2 christos loongarch_reloc_got_type (unsigned int r_type) 762 1.1.1.2 christos { 763 1.1.1.2 christos switch (r_type) 764 1.1.1.2 christos { 765 1.1.1.2 christos case R_LARCH_TLS_DESC_PC_HI20: 766 1.1.1.2 christos case R_LARCH_TLS_DESC_PC_LO12: 767 1.1.1.2 christos case R_LARCH_TLS_DESC_LD: 768 1.1.1.2 christos case R_LARCH_TLS_DESC_CALL: 769 1.1.1.2 christos return GOT_TLS_GDESC; 770 1.1.1.2 christos 771 1.1.1.2 christos case R_LARCH_TLS_IE_PC_HI20: 772 1.1.1.2 christos case R_LARCH_TLS_IE_PC_LO12: 773 1.1.1.2 christos return GOT_TLS_IE; 774 1.1.1.2 christos 775 1.1.1.2 christos default: 776 1.1.1.2 christos break; 777 1.1.1.2 christos } 778 1.1.1.2 christos return GOT_UNKNOWN; 779 1.1.1.2 christos } 780 1.1.1.2 christos 781 1.1.1.2 christos /* Return true if tls type transition can be performed. */ 782 1.1.1.2 christos static bool 783 1.1.1.2 christos loongarch_can_trans_tls (bfd *input_bfd, 784 1.1.1.3 christos struct bfd_link_info *info, 785 1.1.1.3 christos struct elf_link_hash_entry *h, 786 1.1.1.3 christos unsigned int r_symndx, 787 1.1.1.3 christos unsigned int r_type) 788 1.1.1.2 christos { 789 1.1.1.2 christos char symbol_tls_type; 790 1.1.1.2 christos unsigned int reloc_got_type; 791 1.1.1.2 christos 792 1.1.1.2 christos /* Only TLS DESC/IE in normal code mode will perform type 793 1.1.1.2 christos transition. */ 794 1.1.1.3 christos if (! IS_LOONGARCH_TLS_TRANS_RELOC (r_type)) 795 1.1.1.2 christos return false; 796 1.1.1.2 christos 797 1.1.1.3 christos /* Obtaining tls got type here may occur before 798 1.1.1.3 christos loongarch_elf_record_tls_and_got_reference, so it is necessary 799 1.1.1.3 christos to ensure that tls got type has been initialized, otherwise it 800 1.1.1.3 christos is set to GOT_UNKNOWN. */ 801 1.1.1.3 christos symbol_tls_type = GOT_UNKNOWN; 802 1.1.1.3 christos if (_bfd_loongarch_elf_local_got_tls_type (input_bfd) || h) 803 1.1.1.3 christos symbol_tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx); 804 1.1.1.3 christos 805 1.1.1.2 christos reloc_got_type = loongarch_reloc_got_type (r_type); 806 1.1.1.2 christos 807 1.1.1.2 christos if (symbol_tls_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (reloc_got_type)) 808 1.1.1.2 christos return true; 809 1.1.1.2 christos 810 1.1.1.2 christos if (! bfd_link_executable (info)) 811 1.1.1.2 christos return false; 812 1.1.1.2 christos 813 1.1.1.2 christos if (h && h->root.type == bfd_link_hash_undefweak) 814 1.1.1.2 christos return false; 815 1.1.1.2 christos 816 1.1.1.2 christos return true; 817 1.1.1.2 christos } 818 1.1.1.2 christos 819 1.1.1.2 christos /* The type of relocation that can be transitioned. */ 820 1.1.1.2 christos static unsigned int 821 1.1.1.2 christos loongarch_tls_transition_without_check (struct bfd_link_info *info, 822 1.1.1.2 christos unsigned int r_type, 823 1.1.1.2 christos struct elf_link_hash_entry *h) 824 1.1.1.2 christos { 825 1.1.1.2 christos bool local_exec = bfd_link_executable (info) 826 1.1.1.3 christos && LARCH_REF_LOCAL (info, h); 827 1.1.1.2 christos 828 1.1.1.2 christos switch (r_type) 829 1.1.1.2 christos { 830 1.1.1.2 christos case R_LARCH_TLS_DESC_PC_HI20: 831 1.1.1.2 christos return (local_exec 832 1.1.1.2 christos ? R_LARCH_TLS_LE_HI20 833 1.1.1.2 christos : R_LARCH_TLS_IE_PC_HI20); 834 1.1.1.2 christos 835 1.1.1.2 christos case R_LARCH_TLS_DESC_PC_LO12: 836 1.1.1.2 christos return (local_exec 837 1.1.1.2 christos ? R_LARCH_TLS_LE_LO12 838 1.1.1.2 christos : R_LARCH_TLS_IE_PC_LO12); 839 1.1.1.2 christos 840 1.1.1.2 christos case R_LARCH_TLS_DESC_LD: 841 1.1.1.2 christos case R_LARCH_TLS_DESC_CALL: 842 1.1.1.2 christos return R_LARCH_NONE; 843 1.1.1.2 christos 844 1.1.1.2 christos case R_LARCH_TLS_IE_PC_HI20: 845 1.1.1.2 christos return local_exec ? R_LARCH_TLS_LE_HI20 : r_type; 846 1.1.1.2 christos 847 1.1.1.2 christos case R_LARCH_TLS_IE_PC_LO12: 848 1.1.1.2 christos return local_exec ? R_LARCH_TLS_LE_LO12 : r_type; 849 1.1.1.2 christos 850 1.1.1.2 christos default: 851 1.1.1.2 christos break; 852 1.1.1.2 christos } 853 1.1.1.2 christos 854 1.1.1.2 christos return r_type; 855 1.1.1.2 christos } 856 1.1.1.2 christos 857 1.1.1.2 christos static unsigned int 858 1.1.1.2 christos loongarch_tls_transition (bfd *input_bfd, 859 1.1.1.2 christos struct bfd_link_info *info, 860 1.1.1.2 christos struct elf_link_hash_entry *h, 861 1.1.1.3 christos unsigned int r_symndx, 862 1.1.1.2 christos unsigned int r_type) 863 1.1.1.2 christos { 864 1.1.1.3 christos if (! loongarch_can_trans_tls (input_bfd, info, h, r_symndx, r_type)) 865 1.1.1.2 christos return r_type; 866 1.1.1.2 christos 867 1.1.1.2 christos return loongarch_tls_transition_without_check (info, r_type, h); 868 1.1.1.2 christos } 869 1.1.1.2 christos 870 1.1.1.3 christos static bool 871 1.1.1.3 christos bad_static_reloc (struct bfd_link_info *info, 872 1.1.1.3 christos bfd *abfd, const Elf_Internal_Rela *rel, 873 1.1.1.3 christos asection *sec, unsigned r_type, 874 1.1.1.3 christos struct elf_link_hash_entry *h, 875 1.1.1.3 christos Elf_Internal_Sym *isym) 876 1.1.1.3 christos { 877 1.1.1.3 christos reloc_howto_type * r = loongarch_elf_rtype_to_howto (abfd, r_type); 878 1.1.1.3 christos const char *object; 879 1.1.1.3 christos const char *pic_opt; 880 1.1.1.3 christos const char *name = NULL; 881 1.1.1.3 christos 882 1.1.1.3 christos /* If this, the problem is we are referring an external symbol in 883 1.1.1.3 christos a way only working for local symbols, not PC-relative vs. 884 1.1.1.3 christos absolute. */ 885 1.1.1.3 christos bool bad_extern_access = 886 1.1.1.3 christos (bfd_link_pde (info) 887 1.1.1.3 christos || r_type == R_LARCH_PCREL20_S2 888 1.1.1.3 christos || r_type == R_LARCH_PCALA_HI20); 889 1.1.1.3 christos 890 1.1.1.3 christos if (h) 891 1.1.1.3 christos name = h->root.root.string; 892 1.1.1.3 christos else if (isym) 893 1.1.1.3 christos name = bfd_elf_string_from_elf_section (abfd, 894 1.1.1.3 christos elf_symtab_hdr (abfd).sh_link, 895 1.1.1.3 christos isym->st_name); 896 1.1.1.3 christos if (name == NULL || *name == '\0') 897 1.1.1.3 christos name = "<nameless>"; 898 1.1.1.3 christos 899 1.1.1.3 christos if (bfd_link_dll (info)) 900 1.1.1.3 christos { 901 1.1.1.3 christos object = _("a shared object"); 902 1.1.1.3 christos pic_opt = "-fPIC"; 903 1.1.1.3 christos } 904 1.1.1.3 christos else 905 1.1.1.3 christos { 906 1.1.1.3 christos if (bfd_link_pie (info)) 907 1.1.1.3 christos object = _("a PIE object"); 908 1.1.1.3 christos else 909 1.1.1.3 christos object = _("a PDE object"); 910 1.1.1.3 christos 911 1.1.1.3 christos pic_opt = bad_extern_access ? "-mno-direct-extern-access" : "-fPIE"; 912 1.1.1.3 christos } 913 1.1.1.3 christos 914 1.1.1.3 christos (*_bfd_error_handler) 915 1.1.1.3 christos (_("%pB:(%pA+%#lx): relocation %s against `%s` can not be used when making " 916 1.1.1.3 christos "%s; recompile with %s%s"), 917 1.1.1.3 christos abfd, sec, (long) rel->r_offset, r ? r->name : _("<unknown>"), name, 918 1.1.1.3 christos object, pic_opt, 919 1.1.1.3 christos bad_extern_access ? _(" and check the symbol visibility") : ""); 920 1.1.1.3 christos bfd_set_error (bfd_error_bad_value); 921 1.1.1.3 christos return false; 922 1.1.1.3 christos } 923 1.1.1.3 christos 924 1.1 christos /* Look through the relocs for a section during the first phase, and 925 1.1 christos allocate space in the global offset table or procedure linkage 926 1.1 christos table. */ 927 1.1 christos 928 1.1 christos static bool 929 1.1 christos loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, 930 1.1 christos asection *sec, const Elf_Internal_Rela *relocs) 931 1.1 christos { 932 1.1 christos struct loongarch_elf_link_hash_table *htab; 933 1.1 christos Elf_Internal_Shdr *symtab_hdr; 934 1.1 christos struct elf_link_hash_entry **sym_hashes; 935 1.1 christos const Elf_Internal_Rela *rel; 936 1.1 christos asection *sreloc = NULL; 937 1.1 christos 938 1.1 christos if (bfd_link_relocatable (info)) 939 1.1 christos return true; 940 1.1 christos 941 1.1 christos htab = loongarch_elf_hash_table (info); 942 1.1 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 943 1.1 christos sym_hashes = elf_sym_hashes (abfd); 944 1.1 christos 945 1.1 christos if (htab->elf.dynobj == NULL) 946 1.1 christos htab->elf.dynobj = abfd; 947 1.1 christos 948 1.1 christos for (rel = relocs; rel < relocs + sec->reloc_count; rel++) 949 1.1 christos { 950 1.1 christos unsigned int r_type; 951 1.1 christos unsigned int r_symndx; 952 1.1 christos struct elf_link_hash_entry *h; 953 1.1.1.3 christos bool is_abs_symbol = false; 954 1.1 christos Elf_Internal_Sym *isym = NULL; 955 1.1 christos 956 1.1 christos r_symndx = ELFNN_R_SYM (rel->r_info); 957 1.1 christos r_type = ELFNN_R_TYPE (rel->r_info); 958 1.1 christos 959 1.1 christos if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr)) 960 1.1 christos { 961 1.1 christos _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd, r_symndx); 962 1.1 christos return false; 963 1.1 christos } 964 1.1 christos 965 1.1 christos if (r_symndx < symtab_hdr->sh_info) 966 1.1 christos { 967 1.1 christos /* A local symbol. */ 968 1.1.1.2 christos isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd, r_symndx); 969 1.1 christos if (isym == NULL) 970 1.1 christos return false; 971 1.1 christos 972 1.1.1.3 christos is_abs_symbol = isym->st_shndx == SHN_ABS; 973 1.1 christos if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC) 974 1.1 christos { 975 1.1 christos h = elfNN_loongarch_get_local_sym_hash (htab, abfd, rel, true); 976 1.1 christos if (h == NULL) 977 1.1 christos return false; 978 1.1 christos 979 1.1 christos h->type = STT_GNU_IFUNC; 980 1.1 christos h->ref_regular = 1; 981 1.1 christos } 982 1.1 christos else 983 1.1 christos h = NULL; 984 1.1 christos } 985 1.1 christos else 986 1.1 christos { 987 1.1 christos h = sym_hashes[r_symndx - symtab_hdr->sh_info]; 988 1.1 christos while (h->root.type == bfd_link_hash_indirect 989 1.1 christos || h->root.type == bfd_link_hash_warning) 990 1.1 christos h = (struct elf_link_hash_entry *) h->root.u.i.link; 991 1.1.1.3 christos is_abs_symbol = bfd_is_abs_symbol (&h->root); 992 1.1 christos } 993 1.1 christos 994 1.1 christos /* It is referenced by a non-shared object. */ 995 1.1 christos if (h != NULL) 996 1.1 christos h->ref_regular = 1; 997 1.1 christos 998 1.1 christos if (h && h->type == STT_GNU_IFUNC) 999 1.1 christos { 1000 1.1 christos if (htab->elf.dynobj == NULL) 1001 1.1 christos htab->elf.dynobj = abfd; 1002 1.1 christos 1003 1.1.1.2 christos /* Create 'irelifunc' in PIC object. */ 1004 1.1.1.2 christos if (bfd_link_pic (info) 1005 1.1.1.2 christos && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info)) 1006 1.1.1.2 christos return false; 1007 1.1.1.2 christos /* If '.plt' not represent, create '.iplt' to deal with ifunc. */ 1008 1.1.1.2 christos else if (!htab->elf.splt 1009 1.1.1.2 christos && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info)) 1010 1.1.1.2 christos return false; 1011 1.1 christos /* Create the ifunc sections, iplt and ipltgot, for static 1012 1.1 christos executables. */ 1013 1.1 christos if ((r_type == R_LARCH_64 || r_type == R_LARCH_32) 1014 1.1 christos && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info)) 1015 1.1 christos return false; 1016 1.1 christos 1017 1.1 christos if (h->plt.refcount < 0) 1018 1.1 christos h->plt.refcount = 0; 1019 1.1 christos h->plt.refcount++; 1020 1.1 christos h->needs_plt = 1; 1021 1.1 christos 1022 1.1 christos elf_tdata (info->output_bfd)->has_gnu_osabi |= elf_gnu_osabi_ifunc; 1023 1.1 christos } 1024 1.1 christos 1025 1.1.1.2 christos int need_dynreloc = 0; 1026 1.1.1.2 christos int only_need_pcrel = 0; 1027 1.1.1.2 christos 1028 1.1.1.2 christos /* Type transitions are only possible with relocations accompanied 1029 1.1.1.2 christos by R_LARCH_RELAX. */ 1030 1.1.1.3 christos bool with_relax_reloc = false; 1031 1.1.1.3 christos if (rel + 1 != relocs + sec->reloc_count 1032 1.1.1.3 christos && ELFNN_R_TYPE (rel[1].r_info) == R_LARCH_RELAX) 1033 1.1.1.3 christos { 1034 1.1.1.3 christos r_type = loongarch_tls_transition (abfd, info, h, r_symndx, r_type); 1035 1.1.1.3 christos with_relax_reloc = true; 1036 1.1.1.3 christos } 1037 1.1.1.3 christos 1038 1.1.1.3 christos /* I don't want to spend time supporting DT_RELR with old object 1039 1.1.1.3 christos files doing stack-based relocs. */ 1040 1.1.1.3 christos if (info->enable_dt_relr 1041 1.1.1.3 christos && r_type >= R_LARCH_SOP_PUSH_PCREL 1042 1.1.1.3 christos && r_type <= R_LARCH_SOP_POP_32_U) 1043 1.1.1.3 christos { 1044 1.1.1.3 christos /* xgettext:c-format */ 1045 1.1.1.3 christos _bfd_error_handler (_("%pB: stack based reloc type (%u) is not " 1046 1.1.1.3 christos "supported with -z pack-relative-relocs"), 1047 1.1.1.3 christos abfd, r_type); 1048 1.1.1.3 christos return false; 1049 1.1.1.3 christos } 1050 1.1.1.3 christos 1051 1.1 christos switch (r_type) 1052 1.1 christos { 1053 1.1.1.2 christos case R_LARCH_GOT_PC_HI20: 1054 1.1.1.2 christos case R_LARCH_GOT_HI20: 1055 1.1 christos case R_LARCH_SOP_PUSH_GPREL: 1056 1.1.1.2 christos /* For la.global. */ 1057 1.1.1.2 christos if (h) 1058 1.1.1.2 christos h->pointer_equality_needed = 1; 1059 1.1 christos if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h, 1060 1.1 christos r_symndx, 1061 1.1.1.3 christos GOT_NORMAL, 1062 1.1.1.3 christos with_relax_reloc)) 1063 1.1 christos return false; 1064 1.1 christos break; 1065 1.1 christos 1066 1.1.1.2 christos case R_LARCH_TLS_LD_PC_HI20: 1067 1.1.1.2 christos case R_LARCH_TLS_LD_HI20: 1068 1.1.1.2 christos case R_LARCH_TLS_GD_PC_HI20: 1069 1.1.1.2 christos case R_LARCH_TLS_GD_HI20: 1070 1.1 christos case R_LARCH_SOP_PUSH_TLS_GD: 1071 1.1 christos if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h, 1072 1.1 christos r_symndx, 1073 1.1.1.3 christos GOT_TLS_GD, 1074 1.1.1.3 christos with_relax_reloc)) 1075 1.1 christos return false; 1076 1.1 christos break; 1077 1.1 christos 1078 1.1.1.2 christos case R_LARCH_TLS_IE_PC_HI20: 1079 1.1.1.2 christos case R_LARCH_TLS_IE_HI20: 1080 1.1 christos case R_LARCH_SOP_PUSH_TLS_GOT: 1081 1.1 christos if (bfd_link_pic (info)) 1082 1.1 christos /* May fail for lazy-bind. */ 1083 1.1 christos info->flags |= DF_STATIC_TLS; 1084 1.1 christos 1085 1.1 christos if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h, 1086 1.1 christos r_symndx, 1087 1.1.1.3 christos GOT_TLS_IE, 1088 1.1.1.3 christos with_relax_reloc)) 1089 1.1 christos return false; 1090 1.1 christos break; 1091 1.1 christos 1092 1.1.1.2 christos case R_LARCH_TLS_LE_HI20: 1093 1.1.1.2 christos case R_LARCH_TLS_LE_HI20_R: 1094 1.1 christos case R_LARCH_SOP_PUSH_TLS_TPREL: 1095 1.1 christos if (!bfd_link_executable (info)) 1096 1.1.1.3 christos return bad_static_reloc (info, abfd, rel, sec, r_type, h, isym); 1097 1.1 christos 1098 1.1 christos if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h, 1099 1.1 christos r_symndx, 1100 1.1.1.3 christos GOT_TLS_LE, 1101 1.1.1.3 christos with_relax_reloc)) 1102 1.1 christos return false; 1103 1.1 christos break; 1104 1.1 christos 1105 1.1.1.2 christos case R_LARCH_TLS_DESC_PC_HI20: 1106 1.1.1.2 christos case R_LARCH_TLS_DESC_HI20: 1107 1.1.1.2 christos if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h, 1108 1.1.1.2 christos r_symndx, 1109 1.1.1.3 christos GOT_TLS_GDESC, 1110 1.1.1.3 christos with_relax_reloc)) 1111 1.1.1.2 christos return false; 1112 1.1.1.2 christos break; 1113 1.1.1.2 christos 1114 1.1.1.2 christos case R_LARCH_ABS_HI20: 1115 1.1.1.3 christos if (bfd_link_pic (info)) 1116 1.1.1.3 christos return bad_static_reloc (info, abfd, rel, sec, r_type, h, isym); 1117 1.1.1.3 christos 1118 1.1.1.3 christos /* Fall through. */ 1119 1.1 christos case R_LARCH_SOP_PUSH_ABSOLUTE: 1120 1.1 christos if (h != NULL) 1121 1.1 christos /* If this reloc is in a read-only section, we might 1122 1.1 christos need a copy reloc. We can't check reliably at this 1123 1.1 christos stage whether the section is read-only, as input 1124 1.1 christos sections have not yet been mapped to output sections. 1125 1.1 christos Tentatively set the flag for now, and correct in 1126 1.1 christos adjust_dynamic_symbol. */ 1127 1.1 christos h->non_got_ref = 1; 1128 1.1 christos break; 1129 1.1 christos 1130 1.1.1.3 christos /* Since shared library global symbols interpose, any 1131 1.1.1.3 christos PC-relative relocations against external symbols 1132 1.1.1.3 christos should not be used to build shared libraries. 1133 1.1.1.3 christos In static PIE undefined weak symbols may be allowed 1134 1.1.1.3 christos by rewriting pcaddi to addi.w if addend is in [-2048, 2048). */ 1135 1.1.1.3 christos case R_LARCH_PCREL20_S2: 1136 1.1.1.3 christos if (bfd_link_pic (info) 1137 1.1.1.3 christos && (sec->flags & SEC_ALLOC) != 0 1138 1.1.1.3 christos && (sec->flags & SEC_READONLY) != 0 1139 1.1.1.3 christos && ! LARCH_REF_LOCAL (info, h) 1140 1.1.1.3 christos && (!info->nointerp 1141 1.1.1.3 christos || h->root.type != bfd_link_hash_undefweak)) 1142 1.1.1.3 christos return bad_static_reloc (info, abfd, rel, sec, r_type, h, NULL); 1143 1.1.1.3 christos 1144 1.1.1.3 christos break; 1145 1.1.1.3 christos 1146 1.1.1.2 christos /* For normal cmodel, pcalau12i + addi.d/w used to data. 1147 1.1.1.2 christos For first version medium cmodel, pcalau12i + jirl are used to 1148 1.1.1.2 christos function call, it need to creat PLT entry for STT_FUNC and 1149 1.1.1.2 christos STT_GNU_IFUNC type symbol. */ 1150 1.1.1.2 christos case R_LARCH_PCALA_HI20: 1151 1.1.1.2 christos if (h != NULL && (STT_FUNC == h->type || STT_GNU_IFUNC == h->type)) 1152 1.1.1.2 christos { 1153 1.1.1.2 christos /* For pcalau12i + jirl. */ 1154 1.1.1.2 christos h->needs_plt = 1; 1155 1.1.1.2 christos if (h->plt.refcount < 0) 1156 1.1.1.2 christos h->plt.refcount = 0; 1157 1.1.1.2 christos h->plt.refcount++; 1158 1.1.1.2 christos 1159 1.1.1.2 christos h->non_got_ref = 1; 1160 1.1.1.2 christos h->pointer_equality_needed = 1; 1161 1.1.1.2 christos } 1162 1.1.1.2 christos 1163 1.1.1.3 christos /* PC-relative relocations are allowed For first version 1164 1.1.1.3 christos medium cmodel function call. Those against undefined 1165 1.1.1.3 christos weak symbol are allowed for static PIE by rewritting 1166 1.1.1.3 christos pcalau12i to lu12i.w. */ 1167 1.1.1.3 christos if (h != NULL && !h->needs_plt 1168 1.1.1.3 christos && bfd_link_pic (info) 1169 1.1.1.3 christos && (sec->flags & SEC_ALLOC) != 0 1170 1.1.1.3 christos && (sec->flags & SEC_READONLY) != 0 1171 1.1.1.3 christos && ! LARCH_REF_LOCAL (info, h) 1172 1.1.1.3 christos && (!info->nointerp 1173 1.1.1.3 christos || h->root.type != bfd_link_hash_undefweak)) 1174 1.1.1.3 christos return bad_static_reloc (info, abfd, rel, sec, r_type, h, NULL); 1175 1.1.1.3 christos 1176 1.1.1.2 christos break; 1177 1.1.1.2 christos 1178 1.1.1.2 christos case R_LARCH_B16: 1179 1.1.1.2 christos case R_LARCH_B21: 1180 1.1.1.2 christos case R_LARCH_B26: 1181 1.1.1.2 christos case R_LARCH_CALL36: 1182 1.1.1.2 christos if (h != NULL) 1183 1.1.1.2 christos { 1184 1.1.1.2 christos h->needs_plt = 1; 1185 1.1.1.2 christos if (!bfd_link_pic (info)) 1186 1.1.1.2 christos h->non_got_ref = 1; 1187 1.1.1.2 christos 1188 1.1.1.2 christos /* We try to create PLT stub for all non-local function. */ 1189 1.1.1.2 christos if (h->plt.refcount < 0) 1190 1.1.1.2 christos h->plt.refcount = 0; 1191 1.1.1.2 christos h->plt.refcount++; 1192 1.1.1.2 christos } 1193 1.1.1.2 christos 1194 1.1.1.2 christos break; 1195 1.1.1.2 christos 1196 1.1 christos case R_LARCH_SOP_PUSH_PCREL: 1197 1.1 christos if (h != NULL) 1198 1.1 christos { 1199 1.1.1.2 christos if (!bfd_link_pic (info)) 1200 1.1.1.2 christos h->non_got_ref = 1; 1201 1.1 christos 1202 1.1 christos /* We try to create PLT stub for all non-local function. */ 1203 1.1 christos if (h->plt.refcount < 0) 1204 1.1 christos h->plt.refcount = 0; 1205 1.1 christos h->plt.refcount++; 1206 1.1.1.2 christos h->pointer_equality_needed = 1; 1207 1.1 christos } 1208 1.1.1.2 christos 1209 1.1 christos break; 1210 1.1 christos 1211 1.1 christos case R_LARCH_SOP_PUSH_PLT_PCREL: 1212 1.1 christos /* This symbol requires a procedure linkage table entry. We 1213 1.1 christos actually build the entry in adjust_dynamic_symbol, 1214 1.1 christos because this might be a case of linking PIC code without 1215 1.1 christos linking in any dynamic objects, in which case we don't 1216 1.1 christos need to generate a procedure linkage table after all. */ 1217 1.1 christos if (h != NULL) 1218 1.1 christos { 1219 1.1 christos h->needs_plt = 1; 1220 1.1 christos if (h->plt.refcount < 0) 1221 1.1 christos h->plt.refcount = 0; 1222 1.1 christos h->plt.refcount++; 1223 1.1 christos } 1224 1.1 christos break; 1225 1.1 christos 1226 1.1 christos case R_LARCH_TLS_DTPREL32: 1227 1.1 christos case R_LARCH_TLS_DTPREL64: 1228 1.1 christos need_dynreloc = 1; 1229 1.1 christos only_need_pcrel = 1; 1230 1.1 christos break; 1231 1.1 christos 1232 1.1 christos case R_LARCH_32: 1233 1.1.1.3 christos if (ARCH_SIZE > 32 1234 1.1.1.3 christos && bfd_link_pic (info) 1235 1.1.1.3 christos && (sec->flags & SEC_ALLOC) != 0) 1236 1.1.1.3 christos { 1237 1.1.1.3 christos if (!is_abs_symbol) 1238 1.1.1.3 christos { 1239 1.1.1.3 christos _bfd_error_handler 1240 1.1.1.3 christos (_("%pB: relocation R_LARCH_32 against non-absolute " 1241 1.1.1.3 christos "symbol `%s' cannot be used in ELFCLASS64 when " 1242 1.1.1.3 christos "making a shared object or PIE"), 1243 1.1.1.3 christos abfd, h ? h->root.root.string : "a local symbol"); 1244 1.1.1.3 christos bfd_set_error (bfd_error_bad_value); 1245 1.1.1.3 christos return false; 1246 1.1.1.3 christos } 1247 1.1.1.3 christos } 1248 1.1.1.3 christos 1249 1.1.1.3 christos /* Fall through. */ 1250 1.1.1.3 christos case R_LARCH_JUMP_SLOT: 1251 1.1 christos case R_LARCH_64: 1252 1.1.1.2 christos 1253 1.1.1.3 christos /* Resolved to const. */ 1254 1.1.1.3 christos if (is_abs_symbol) 1255 1.1.1.3 christos break; 1256 1.1.1.3 christos 1257 1.1 christos need_dynreloc = 1; 1258 1.1 christos 1259 1.1 christos /* If resolved symbol is defined in this object, 1260 1.1 christos 1. Under pie, the symbol is known. We convert it 1261 1.1 christos into R_LARCH_RELATIVE and need load-addr still. 1262 1.1 christos 2. Under pde, the symbol is known and we can discard R_LARCH_NN. 1263 1.1 christos 3. Under dll, R_LARCH_NN can't be changed normally, since 1264 1.1 christos its defination could be covered by the one in executable. 1265 1.1 christos For symbolic, we convert it into R_LARCH_RELATIVE. 1266 1.1 christos Thus, only under pde, it needs pcrel only. We discard it. */ 1267 1.1 christos only_need_pcrel = bfd_link_pde (info); 1268 1.1 christos 1269 1.1 christos if (h != NULL 1270 1.1 christos && (!bfd_link_pic (info) 1271 1.1 christos || h->type == STT_GNU_IFUNC)) 1272 1.1 christos { 1273 1.1 christos /* This reloc might not bind locally. */ 1274 1.1 christos h->non_got_ref = 1; 1275 1.1 christos h->pointer_equality_needed = 1; 1276 1.1 christos 1277 1.1 christos if (!h->def_regular 1278 1.1 christos || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0) 1279 1.1 christos { 1280 1.1 christos /* We may need a .plt entry if the symbol is a function 1281 1.1 christos defined in a shared lib or is a function referenced 1282 1.1 christos from the code or read-only section. */ 1283 1.1 christos h->plt.refcount += 1; 1284 1.1 christos } 1285 1.1 christos } 1286 1.1 christos break; 1287 1.1 christos 1288 1.1 christos case R_LARCH_GNU_VTINHERIT: 1289 1.1 christos if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) 1290 1.1 christos return false; 1291 1.1 christos break; 1292 1.1 christos 1293 1.1 christos case R_LARCH_GNU_VTENTRY: 1294 1.1 christos if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) 1295 1.1 christos return false; 1296 1.1 christos break; 1297 1.1 christos 1298 1.1.1.3 christos case R_LARCH_ALIGN: 1299 1.1.1.3 christos /* Check against irrational R_LARCH_ALIGN relocs which may cause 1300 1.1.1.3 christos removing an odd number of bytes and disrupt DT_RELR. */ 1301 1.1.1.3 christos if (rel->r_offset % 4 != 0) 1302 1.1.1.3 christos { 1303 1.1.1.3 christos /* xgettext:c-format */ 1304 1.1.1.3 christos _bfd_error_handler ( 1305 1.1.1.3 christos _("%pB: R_LARCH_ALIGN with offset %" PRId64 " not aligned " 1306 1.1.1.3 christos "to instruction boundary"), 1307 1.1.1.3 christos abfd, (uint64_t) rel->r_offset); 1308 1.1.1.3 christos return false; 1309 1.1.1.3 christos } 1310 1.1.1.3 christos break; 1311 1.1.1.3 christos 1312 1.1 christos default: 1313 1.1 christos break; 1314 1.1 christos } 1315 1.1 christos 1316 1.1 christos /* Record some info for sizing and allocating dynamic entry. */ 1317 1.1 christos if (need_dynreloc && (sec->flags & SEC_ALLOC)) 1318 1.1 christos { 1319 1.1 christos /* When creating a shared object, we must copy these 1320 1.1 christos relocs into the output file. We create a reloc 1321 1.1 christos section in dynobj and make room for the reloc. */ 1322 1.1 christos struct elf_dyn_relocs *p; 1323 1.1 christos struct elf_dyn_relocs **head; 1324 1.1 christos 1325 1.1 christos if (sreloc == NULL) 1326 1.1 christos { 1327 1.1 christos sreloc 1328 1.1 christos = _bfd_elf_make_dynamic_reloc_section (sec, htab->elf.dynobj, 1329 1.1 christos LARCH_ELF_LOG_WORD_BYTES, 1330 1.1 christos abfd, /*rela?*/ true); 1331 1.1 christos if (sreloc == NULL) 1332 1.1 christos return false; 1333 1.1 christos } 1334 1.1 christos 1335 1.1 christos /* If this is a global symbol, we count the number of 1336 1.1 christos relocations we need for this symbol. */ 1337 1.1 christos if (h != NULL) 1338 1.1 christos head = &h->dyn_relocs; 1339 1.1 christos else 1340 1.1 christos { 1341 1.1 christos /* Track dynamic relocs needed for local syms too. 1342 1.1 christos We really need local syms available to do this 1343 1.1 christos easily. Oh well. */ 1344 1.1 christos 1345 1.1 christos asection *s; 1346 1.1 christos void *vpp; 1347 1.1 christos 1348 1.1 christos s = bfd_section_from_elf_index (abfd, isym->st_shndx); 1349 1.1 christos if (s == NULL) 1350 1.1 christos s = sec; 1351 1.1 christos 1352 1.1 christos vpp = &elf_section_data (s)->local_dynrel; 1353 1.1 christos head = (struct elf_dyn_relocs **) vpp; 1354 1.1 christos } 1355 1.1 christos 1356 1.1 christos p = *head; 1357 1.1 christos if (p == NULL || p->sec != sec) 1358 1.1 christos { 1359 1.1 christos bfd_size_type amt = sizeof *p; 1360 1.1 christos p = (struct elf_dyn_relocs *) bfd_alloc (htab->elf.dynobj, amt); 1361 1.1 christos if (p == NULL) 1362 1.1 christos return false; 1363 1.1 christos p->next = *head; 1364 1.1 christos *head = p; 1365 1.1 christos p->sec = sec; 1366 1.1 christos p->count = 0; 1367 1.1 christos p->pc_count = 0; 1368 1.1 christos } 1369 1.1 christos 1370 1.1 christos p->count++; 1371 1.1 christos p->pc_count += only_need_pcrel; 1372 1.1 christos } 1373 1.1 christos } 1374 1.1 christos 1375 1.1 christos return true; 1376 1.1 christos } 1377 1.1 christos 1378 1.1 christos /* Find dynamic relocs for H that apply to read-only sections. */ 1379 1.1 christos 1380 1.1 christos static asection * 1381 1.1 christos readonly_dynrelocs (struct elf_link_hash_entry *h) 1382 1.1 christos { 1383 1.1 christos struct elf_dyn_relocs *p; 1384 1.1 christos 1385 1.1 christos for (p = h->dyn_relocs; p != NULL; p = p->next) 1386 1.1 christos { 1387 1.1 christos asection *s = p->sec->output_section; 1388 1.1 christos 1389 1.1 christos if (s != NULL && (s->flags & SEC_READONLY) != 0) 1390 1.1 christos return p->sec; 1391 1.1 christos } 1392 1.1 christos return NULL; 1393 1.1 christos } 1394 1.1 christos 1395 1.1 christos /* Adjust a symbol defined by a dynamic object and referenced by a 1396 1.1 christos regular object. The current definition is in some section of the 1397 1.1 christos dynamic object, but we're not including those sections. We have to 1398 1.1 christos change the definition to something the rest of the link can 1399 1.1 christos understand. */ 1400 1.1 christos static bool 1401 1.1 christos loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info, 1402 1.1 christos struct elf_link_hash_entry *h) 1403 1.1 christos { 1404 1.1 christos struct loongarch_elf_link_hash_table *htab; 1405 1.1 christos bfd *dynobj; 1406 1.1 christos 1407 1.1 christos htab = loongarch_elf_hash_table (info); 1408 1.1 christos BFD_ASSERT (htab != NULL); 1409 1.1 christos 1410 1.1 christos dynobj = htab->elf.dynobj; 1411 1.1 christos 1412 1.1 christos /* Make sure we know what is going on here. */ 1413 1.1 christos BFD_ASSERT (dynobj != NULL 1414 1.1.1.2 christos && (h->needs_plt 1415 1.1.1.2 christos || h->type == STT_GNU_IFUNC 1416 1.1.1.2 christos || h->is_weakalias 1417 1.1.1.2 christos || (h->def_dynamic 1418 1.1.1.2 christos && h->ref_regular 1419 1.1.1.2 christos && !h->def_regular))); 1420 1.1 christos 1421 1.1 christos /* If this is a function, put it in the procedure linkage table. We 1422 1.1 christos will fill in the contents of the procedure linkage table later 1423 1.1 christos (although we could actually do it here). */ 1424 1.1 christos if (h->type == STT_FUNC || h->type == STT_GNU_IFUNC || h->needs_plt) 1425 1.1 christos { 1426 1.1.1.2 christos if (h->plt.refcount <= 0 1427 1.1 christos || (h->type != STT_GNU_IFUNC 1428 1.1.1.3 christos && (LARCH_REF_LOCAL (info, h) 1429 1.1 christos || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT 1430 1.1 christos && h->root.type == bfd_link_hash_undefweak)))) 1431 1.1 christos { 1432 1.1 christos /* This case can occur if we saw a R_LARCH_SOP_PUSH_PLT_PCREL reloc 1433 1.1 christos in an input file, but the symbol was never referred to by a 1434 1.1 christos dynamic object, or if all references were garbage collected. 1435 1.1 christos In such a case, we don't actually need to build a PLT entry. */ 1436 1.1 christos h->plt.offset = MINUS_ONE; 1437 1.1 christos h->needs_plt = 0; 1438 1.1 christos } 1439 1.1 christos 1440 1.1 christos return true; 1441 1.1 christos } 1442 1.1 christos else 1443 1.1 christos h->plt.offset = MINUS_ONE; 1444 1.1 christos 1445 1.1 christos /* If this is a weak symbol, and there is a real definition, the 1446 1.1 christos processor independent code will have arranged for us to see the 1447 1.1 christos real definition first, and we can just use the same value. */ 1448 1.1 christos if (h->is_weakalias) 1449 1.1 christos { 1450 1.1 christos struct elf_link_hash_entry *def = weakdef (h); 1451 1.1 christos BFD_ASSERT (def->root.type == bfd_link_hash_defined); 1452 1.1 christos h->root.u.def.section = def->root.u.def.section; 1453 1.1 christos h->root.u.def.value = def->root.u.def.value; 1454 1.1 christos return true; 1455 1.1 christos } 1456 1.1 christos 1457 1.1.1.2 christos /* R_LARCH_COPY is not adept glibc, not to generate. */ 1458 1.1.1.2 christos /* Can not print anything, because make check ld. */ 1459 1.1.1.2 christos return true; 1460 1.1 christos } 1461 1.1 christos 1462 1.1 christos /* Allocate space in .plt, .got and associated reloc sections for 1463 1.1 christos dynamic relocs. */ 1464 1.1 christos 1465 1.1 christos static bool 1466 1.1 christos allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) 1467 1.1 christos { 1468 1.1 christos struct bfd_link_info *info; 1469 1.1 christos struct loongarch_elf_link_hash_table *htab; 1470 1.1 christos struct elf_dyn_relocs *p; 1471 1.1 christos 1472 1.1 christos if (h->root.type == bfd_link_hash_indirect) 1473 1.1 christos return true; 1474 1.1 christos 1475 1.1 christos if (h->type == STT_GNU_IFUNC 1476 1.1 christos && h->def_regular) 1477 1.1 christos return true; 1478 1.1 christos 1479 1.1 christos info = (struct bfd_link_info *) inf; 1480 1.1 christos htab = loongarch_elf_hash_table (info); 1481 1.1.1.2 christos bool dyn = htab->elf.dynamic_sections_created; 1482 1.1 christos BFD_ASSERT (htab != NULL); 1483 1.1 christos 1484 1.1 christos do 1485 1.1 christos { 1486 1.1 christos asection *plt, *gotplt, *relplt; 1487 1.1 christos 1488 1.1 christos if (!h->needs_plt) 1489 1.1 christos break; 1490 1.1 christos 1491 1.1 christos h->needs_plt = 0; 1492 1.1 christos 1493 1.1 christos if (htab->elf.splt) 1494 1.1 christos { 1495 1.1.1.2 christos if (h->dynindx == -1 && !h->forced_local && dyn 1496 1.1.1.2 christos && h->root.type == bfd_link_hash_undefweak) 1497 1.1.1.2 christos { 1498 1.1.1.2 christos if (!bfd_elf_link_record_dynamic_symbol (info, h)) 1499 1.1.1.2 christos return false; 1500 1.1.1.2 christos } 1501 1.1 christos 1502 1.1 christos if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h) 1503 1.1 christos && h->type != STT_GNU_IFUNC) 1504 1.1 christos break; 1505 1.1 christos 1506 1.1 christos plt = htab->elf.splt; 1507 1.1 christos gotplt = htab->elf.sgotplt; 1508 1.1 christos relplt = htab->elf.srelplt; 1509 1.1 christos } 1510 1.1 christos else if (htab->elf.iplt) 1511 1.1 christos { 1512 1.1 christos /* .iplt only for IFUNC. */ 1513 1.1 christos if (h->type != STT_GNU_IFUNC) 1514 1.1 christos break; 1515 1.1 christos 1516 1.1 christos plt = htab->elf.iplt; 1517 1.1 christos gotplt = htab->elf.igotplt; 1518 1.1 christos relplt = htab->elf.irelplt; 1519 1.1 christos } 1520 1.1 christos else 1521 1.1 christos break; 1522 1.1 christos 1523 1.1 christos if (plt->size == 0) 1524 1.1 christos plt->size = PLT_HEADER_SIZE; 1525 1.1 christos 1526 1.1 christos h->plt.offset = plt->size; 1527 1.1 christos plt->size += PLT_ENTRY_SIZE; 1528 1.1 christos gotplt->size += GOT_ENTRY_SIZE; 1529 1.1 christos relplt->size += sizeof (ElfNN_External_Rela); 1530 1.1 christos 1531 1.1 christos /* If this symbol is not defined in a regular file, and we are 1532 1.1 christos not generating a shared library, then set the symbol to this 1533 1.1 christos location in the .plt. This is required to make function 1534 1.1 christos pointers compare as equal between the normal executable and 1535 1.1 christos the shared library. */ 1536 1.1.1.2 christos if (!bfd_link_pic (info) 1537 1.1 christos && !h->def_regular) 1538 1.1 christos { 1539 1.1 christos h->root.u.def.section = plt; 1540 1.1 christos h->root.u.def.value = h->plt.offset; 1541 1.1 christos } 1542 1.1 christos 1543 1.1 christos h->needs_plt = 1; 1544 1.1 christos } 1545 1.1 christos while (0); 1546 1.1 christos 1547 1.1 christos if (!h->needs_plt) 1548 1.1 christos h->plt.offset = MINUS_ONE; 1549 1.1 christos 1550 1.1 christos if (0 < h->got.refcount) 1551 1.1 christos { 1552 1.1 christos asection *s; 1553 1.1 christos int tls_type = loongarch_elf_hash_entry (h)->tls_type; 1554 1.1 christos 1555 1.1 christos /* Make sure this symbol is output as a dynamic symbol. 1556 1.1 christos Undefined weak syms won't yet be marked as dynamic. */ 1557 1.1.1.2 christos if (h->dynindx == -1 && !h->forced_local && dyn 1558 1.1.1.2 christos && h->root.type == bfd_link_hash_undefweak) 1559 1.1 christos { 1560 1.1.1.2 christos if (!bfd_elf_link_record_dynamic_symbol (info, h)) 1561 1.1.1.2 christos return false; 1562 1.1 christos } 1563 1.1 christos 1564 1.1 christos s = htab->elf.sgot; 1565 1.1 christos h->got.offset = s->size; 1566 1.1.1.2 christos if (tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC)) 1567 1.1 christos { 1568 1.1.1.3 christos int indx = 0; 1569 1.1.1.3 christos bool need_reloc = false; 1570 1.1.1.3 christos LARCH_TLS_GD_IE_NEED_DYN_RELOC (info, dyn, h, indx, 1571 1.1.1.3 christos need_reloc); 1572 1.1 christos /* TLS_GD needs two dynamic relocs and two GOT slots. */ 1573 1.1 christos if (tls_type & GOT_TLS_GD) 1574 1.1 christos { 1575 1.1 christos s->size += 2 * GOT_ENTRY_SIZE; 1576 1.1.1.3 christos if (need_reloc) 1577 1.1.1.3 christos htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela); 1578 1.1 christos } 1579 1.1 christos 1580 1.1 christos /* TLS_IE needs one dynamic reloc and one GOT slot. */ 1581 1.1 christos if (tls_type & GOT_TLS_IE) 1582 1.1 christos { 1583 1.1 christos s->size += GOT_ENTRY_SIZE; 1584 1.1.1.3 christos if (need_reloc) 1585 1.1.1.3 christos htab->elf.srelgot->size += sizeof (ElfNN_External_Rela); 1586 1.1.1.2 christos } 1587 1.1.1.2 christos 1588 1.1.1.2 christos /* TLS_DESC needs one dynamic reloc and two GOT slot. */ 1589 1.1.1.2 christos if (tls_type & GOT_TLS_GDESC) 1590 1.1.1.2 christos { 1591 1.1.1.2 christos s->size += GOT_ENTRY_SIZE * 2; 1592 1.1 christos htab->elf.srelgot->size += sizeof (ElfNN_External_Rela); 1593 1.1 christos } 1594 1.1 christos } 1595 1.1.1.2 christos 1596 1.1 christos else 1597 1.1 christos { 1598 1.1 christos s->size += GOT_ENTRY_SIZE; 1599 1.1.1.2 christos if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT 1600 1.1.1.2 christos || h->root.type != bfd_link_hash_undefweak) 1601 1.1.1.2 christos && (bfd_link_pic (info) 1602 1.1.1.2 christos || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), 1603 1.1.1.2 christos h)) 1604 1.1.1.2 christos && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) 1605 1.1.1.2 christos /* Undefined weak symbol in static PIE resolves to 0 without 1606 1.1.1.2 christos any dynamic relocations. */ 1607 1.1 christos htab->elf.srelgot->size += sizeof (ElfNN_External_Rela); 1608 1.1 christos } 1609 1.1 christos } 1610 1.1 christos else 1611 1.1 christos h->got.offset = MINUS_ONE; 1612 1.1 christos 1613 1.1 christos if (h->dyn_relocs == NULL) 1614 1.1 christos return true; 1615 1.1 christos 1616 1.1.1.2 christos /* Extra dynamic relocate, 1617 1.1.1.2 christos * R_LARCH_64 1618 1.1.1.2 christos * R_LARCH_TLS_DTPRELNN 1619 1.1.1.2 christos * R_LARCH_JUMP_SLOT 1620 1.1.1.2 christos * R_LARCH_NN. */ 1621 1.1.1.2 christos 1622 1.1.1.2 christos if (SYMBOL_CALLS_LOCAL (info, h)) 1623 1.1 christos { 1624 1.1 christos struct elf_dyn_relocs **pp; 1625 1.1 christos 1626 1.1 christos for (pp = &h->dyn_relocs; (p = *pp) != NULL;) 1627 1.1 christos { 1628 1.1 christos p->count -= p->pc_count; 1629 1.1 christos p->pc_count = 0; 1630 1.1 christos if (p->count == 0) 1631 1.1 christos *pp = p->next; 1632 1.1 christos else 1633 1.1 christos pp = &p->next; 1634 1.1 christos } 1635 1.1 christos } 1636 1.1 christos 1637 1.1 christos if (h->root.type == bfd_link_hash_undefweak) 1638 1.1 christos { 1639 1.1.1.2 christos if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h) 1640 1.1.1.2 christos || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT 1641 1.1.1.2 christos || (!bfd_link_pic (info) && h->non_got_ref)) 1642 1.1 christos h->dyn_relocs = NULL; 1643 1.1.1.2 christos else if (h->dynindx == -1 && !h->forced_local) 1644 1.1.1.2 christos { 1645 1.1.1.2 christos /* Make sure this symbol is output as a dynamic symbol. 1646 1.1.1.2 christos Undefined weak syms won't yet be marked as dynamic. */ 1647 1.1.1.2 christos if (!bfd_elf_link_record_dynamic_symbol (info, h)) 1648 1.1.1.2 christos return false; 1649 1.1.1.2 christos 1650 1.1.1.2 christos if (h->dynindx == -1) 1651 1.1.1.2 christos h->dyn_relocs = NULL; 1652 1.1.1.2 christos } 1653 1.1 christos } 1654 1.1 christos 1655 1.1 christos for (p = h->dyn_relocs; p != NULL; p = p->next) 1656 1.1 christos { 1657 1.1.1.3 christos if (discarded_section (p->sec)) 1658 1.1.1.3 christos continue; 1659 1.1 christos asection *sreloc = elf_section_data (p->sec)->sreloc; 1660 1.1 christos sreloc->size += p->count * sizeof (ElfNN_External_Rela); 1661 1.1 christos } 1662 1.1 christos 1663 1.1 christos return true; 1664 1.1 christos } 1665 1.1 christos 1666 1.1.1.2 christos /* A modified version of _bfd_elf_allocate_ifunc_dyn_relocs. 1667 1.1.1.2 christos For local def and ref ifunc, 1668 1.1.1.2 christos dynamic relocations are stored in 1669 1.1.1.2 christos 1. rela.srelgot section in dynamic object (dll or exec). 1670 1.1.1.2 christos 2. rela.irelplt section in static executable. 1671 1.1.1.2 christos Unlike _bfd_elf_allocate_ifunc_dyn_relocs, rela.srelgot is used 1672 1.1.1.2 christos instead of rela.srelplt. Glibc ELF loader will not support 1673 1.1.1.2 christos R_LARCH_IRELATIVE relocation in rela.plt. */ 1674 1.1.1.2 christos 1675 1.1.1.2 christos static bool 1676 1.1.1.2 christos local_allocate_ifunc_dyn_relocs (struct bfd_link_info *info, 1677 1.1.1.2 christos struct elf_link_hash_entry *h, 1678 1.1.1.2 christos struct elf_dyn_relocs **head, 1679 1.1.1.2 christos unsigned int plt_entry_size, 1680 1.1.1.2 christos unsigned int plt_header_size, 1681 1.1.1.2 christos unsigned int got_entry_size, 1682 1.1.1.2 christos bool avoid_plt) 1683 1.1.1.2 christos { 1684 1.1.1.2 christos asection *plt, *gotplt, *relplt; 1685 1.1.1.2 christos struct elf_dyn_relocs *p; 1686 1.1.1.2 christos unsigned int sizeof_reloc; 1687 1.1.1.2 christos const struct elf_backend_data *bed; 1688 1.1.1.2 christos struct elf_link_hash_table *htab; 1689 1.1.1.2 christos /* If AVOID_PLT is TRUE, don't use PLT if possible. */ 1690 1.1.1.2 christos bool use_plt = !avoid_plt || h->plt.refcount > 0; 1691 1.1.1.2 christos bool need_dynreloc = !use_plt || bfd_link_pic (info); 1692 1.1.1.2 christos 1693 1.1.1.2 christos /* When a PIC object references a STT_GNU_IFUNC symbol defined 1694 1.1.1.2 christos in executable or it isn't referenced via PLT, the address of 1695 1.1.1.2 christos the resolved function may be used. But in non-PIC executable, 1696 1.1.1.2 christos the address of its plt slot may be used. Pointer equality may 1697 1.1.1.2 christos not work correctly. PIE or non-PLT reference should be used if 1698 1.1.1.2 christos pointer equality is required here. 1699 1.1.1.2 christos 1700 1.1.1.2 christos If STT_GNU_IFUNC symbol is defined in position-dependent executable, 1701 1.1.1.2 christos backend should change it to the normal function and set its address 1702 1.1.1.2 christos to its PLT entry which should be resolved by R_*_IRELATIVE at 1703 1.1.1.2 christos run-time. All external references should be resolved to its PLT in 1704 1.1.1.2 christos executable. */ 1705 1.1.1.2 christos if (!need_dynreloc 1706 1.1.1.2 christos && !(bfd_link_pde (info) && h->def_regular) 1707 1.1.1.2 christos && (h->dynindx != -1 1708 1.1.1.2 christos || info->export_dynamic) 1709 1.1.1.2 christos && h->pointer_equality_needed) 1710 1.1.1.2 christos { 1711 1.1.1.3 christos info->callbacks->fatal 1712 1.1.1.2 christos /* xgettext:c-format. */ 1713 1.1.1.3 christos (_("%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer " 1714 1.1.1.2 christos "equality in `%pB' can not be used when making an " 1715 1.1.1.2 christos "executable; recompile with -fPIE and relink with -pie\n"), 1716 1.1.1.2 christos h->root.root.string, 1717 1.1.1.2 christos h->root.u.def.section->owner); 1718 1.1.1.2 christos bfd_set_error (bfd_error_bad_value); 1719 1.1.1.2 christos return false; 1720 1.1.1.2 christos } 1721 1.1.1.2 christos 1722 1.1.1.2 christos htab = elf_hash_table (info); 1723 1.1.1.2 christos 1724 1.1.1.2 christos /* When the symbol is marked with regular reference, if PLT isn't used 1725 1.1.1.2 christos or we are building a PIC object, we must keep dynamic relocation 1726 1.1.1.2 christos if there is non-GOT reference and use PLT if there is PC-relative 1727 1.1.1.2 christos reference. */ 1728 1.1.1.2 christos if (need_dynreloc && h->ref_regular) 1729 1.1.1.2 christos { 1730 1.1.1.2 christos bool keep = false; 1731 1.1.1.2 christos for (p = *head; p != NULL; p = p->next) 1732 1.1.1.2 christos if (p->count) 1733 1.1.1.2 christos { 1734 1.1.1.2 christos h->non_got_ref = 1; 1735 1.1.1.2 christos /* Need dynamic relocations for non-GOT reference. */ 1736 1.1.1.2 christos keep = true; 1737 1.1.1.2 christos if (p->pc_count) 1738 1.1.1.2 christos { 1739 1.1.1.2 christos /* Must use PLT for PC-relative reference. */ 1740 1.1.1.2 christos use_plt = true; 1741 1.1.1.2 christos need_dynreloc = bfd_link_pic (info); 1742 1.1.1.2 christos break; 1743 1.1.1.2 christos } 1744 1.1.1.2 christos } 1745 1.1.1.2 christos if (keep) 1746 1.1.1.2 christos goto keep; 1747 1.1.1.2 christos } 1748 1.1.1.2 christos 1749 1.1.1.2 christos /* Support garbage collection against STT_GNU_IFUNC symbols. */ 1750 1.1.1.2 christos if (h->plt.refcount <= 0 && h->got.refcount <= 0) 1751 1.1.1.2 christos { 1752 1.1.1.2 christos h->got = htab->init_got_offset; 1753 1.1.1.2 christos h->plt = htab->init_plt_offset; 1754 1.1.1.2 christos *head = NULL; 1755 1.1.1.2 christos return true; 1756 1.1.1.2 christos } 1757 1.1.1.2 christos 1758 1.1.1.2 christos /* Return and discard space for dynamic relocations against it if 1759 1.1.1.2 christos it is never referenced. */ 1760 1.1.1.2 christos if (!h->ref_regular) 1761 1.1.1.2 christos { 1762 1.1.1.2 christos if (h->plt.refcount > 0 1763 1.1.1.2 christos || h->got.refcount > 0) 1764 1.1.1.2 christos abort (); 1765 1.1.1.2 christos h->got = htab->init_got_offset; 1766 1.1.1.2 christos h->plt = htab->init_plt_offset; 1767 1.1.1.2 christos *head = NULL; 1768 1.1.1.2 christos return true; 1769 1.1.1.2 christos } 1770 1.1.1.2 christos 1771 1.1.1.2 christos keep: 1772 1.1.1.2 christos bed = get_elf_backend_data (info->output_bfd); 1773 1.1.1.2 christos if (bed->rela_plts_and_copies_p) 1774 1.1.1.2 christos sizeof_reloc = bed->s->sizeof_rela; 1775 1.1.1.2 christos else 1776 1.1.1.2 christos sizeof_reloc = bed->s->sizeof_rel; 1777 1.1.1.2 christos 1778 1.1.1.2 christos /* When building a static executable, use iplt, igot.plt and 1779 1.1.1.2 christos rela.iplt sections for STT_GNU_IFUNC symbols. */ 1780 1.1.1.2 christos if (htab->splt != NULL) 1781 1.1.1.2 christos { 1782 1.1.1.2 christos plt = htab->splt; 1783 1.1.1.2 christos gotplt = htab->sgotplt; 1784 1.1.1.2 christos /* Change dynamic info of ifunc gotplt from srelplt to srelgot. */ 1785 1.1.1.2 christos relplt = htab->srelgot; 1786 1.1.1.2 christos 1787 1.1.1.2 christos /* If this is the first plt entry and PLT is used, make room for 1788 1.1.1.2 christos the special first entry. */ 1789 1.1.1.2 christos if (plt->size == 0 && use_plt) 1790 1.1.1.2 christos plt->size += plt_header_size; 1791 1.1.1.2 christos } 1792 1.1.1.2 christos else 1793 1.1.1.2 christos { 1794 1.1.1.2 christos plt = htab->iplt; 1795 1.1.1.2 christos gotplt = htab->igotplt; 1796 1.1.1.2 christos relplt = htab->irelplt; 1797 1.1.1.2 christos } 1798 1.1.1.2 christos 1799 1.1.1.2 christos if (use_plt) 1800 1.1.1.2 christos { 1801 1.1.1.2 christos /* Don't update value of STT_GNU_IFUNC symbol to PLT. We need 1802 1.1.1.2 christos the original value for R_*_IRELATIVE. */ 1803 1.1.1.2 christos h->plt.offset = plt->size; 1804 1.1.1.2 christos 1805 1.1.1.2 christos /* Make room for this entry in the plt/iplt section. */ 1806 1.1.1.2 christos plt->size += plt_entry_size; 1807 1.1.1.2 christos 1808 1.1.1.2 christos /* We also need to make an entry in the got.plt/got.iplt section, 1809 1.1.1.2 christos which will be placed in the got section by the linker script. */ 1810 1.1.1.2 christos gotplt->size += got_entry_size; 1811 1.1.1.2 christos } 1812 1.1.1.2 christos 1813 1.1.1.2 christos /* We also need to make an entry in the rela.plt/.rela.iplt 1814 1.1.1.2 christos section for GOTPLT relocation if PLT is used. */ 1815 1.1.1.2 christos if (use_plt) 1816 1.1.1.2 christos { 1817 1.1.1.2 christos relplt->size += sizeof_reloc; 1818 1.1.1.2 christos relplt->reloc_count++; 1819 1.1.1.2 christos } 1820 1.1.1.2 christos 1821 1.1.1.2 christos /* We need dynamic relocation for STT_GNU_IFUNC symbol only when 1822 1.1.1.2 christos there is a non-GOT reference in a PIC object or PLT isn't used. */ 1823 1.1.1.2 christos if (!need_dynreloc || !h->non_got_ref) 1824 1.1.1.2 christos *head = NULL; 1825 1.1.1.2 christos 1826 1.1.1.2 christos /* Finally, allocate space. */ 1827 1.1.1.2 christos p = *head; 1828 1.1.1.2 christos if (p != NULL) 1829 1.1.1.2 christos { 1830 1.1.1.2 christos bfd_size_type count = 0; 1831 1.1.1.2 christos do 1832 1.1.1.2 christos { 1833 1.1.1.2 christos count += p->count; 1834 1.1.1.2 christos p = p->next; 1835 1.1.1.2 christos } 1836 1.1.1.2 christos while (p != NULL); 1837 1.1.1.2 christos 1838 1.1.1.2 christos htab->ifunc_resolvers = count != 0; 1839 1.1.1.2 christos 1840 1.1.1.2 christos /* Dynamic relocations are stored in 1841 1.1.1.2 christos 1. rela.srelgot section in PIC object. 1842 1.1.1.2 christos 2. rela.srelgot section in dynamic executable. 1843 1.1.1.2 christos 3. rela.irelplt section in static executable. */ 1844 1.1.1.2 christos if (htab->splt != NULL) 1845 1.1.1.2 christos htab->srelgot->size += count * sizeof_reloc; 1846 1.1.1.2 christos else 1847 1.1.1.2 christos { 1848 1.1.1.2 christos relplt->size += count * sizeof_reloc; 1849 1.1.1.2 christos relplt->reloc_count += count; 1850 1.1.1.2 christos } 1851 1.1.1.2 christos } 1852 1.1.1.2 christos 1853 1.1.1.2 christos /* For STT_GNU_IFUNC symbol, got.plt has the real function address 1854 1.1.1.2 christos and got has the PLT entry adddress. We will load the GOT entry 1855 1.1.1.2 christos with the PLT entry in finish_dynamic_symbol if it is used. For 1856 1.1.1.2 christos branch, it uses got.plt. For symbol value, if PLT is used, 1857 1.1.1.2 christos 1. Use got.plt in a PIC object if it is forced local or not 1858 1.1.1.2 christos dynamic. 1859 1.1.1.2 christos 2. Use got.plt in a non-PIC object if pointer equality isn't 1860 1.1.1.2 christos needed. 1861 1.1.1.2 christos 3. Use got.plt in PIE. 1862 1.1.1.2 christos 4. Use got.plt if got isn't used. 1863 1.1.1.2 christos 5. Otherwise use got so that it can be shared among different 1864 1.1.1.2 christos objects at run-time. 1865 1.1.1.2 christos If PLT isn't used, always use got for symbol value. 1866 1.1.1.2 christos We only need to relocate got entry in PIC object or in dynamic 1867 1.1.1.2 christos executable without PLT. */ 1868 1.1.1.2 christos if (use_plt 1869 1.1.1.2 christos && (h->got.refcount <= 0 1870 1.1.1.2 christos || (bfd_link_pic (info) 1871 1.1.1.2 christos && (h->dynindx == -1 1872 1.1.1.2 christos || h->forced_local)) 1873 1.1.1.2 christos || ( 1874 1.1.1.2 christos !h->pointer_equality_needed) 1875 1.1.1.2 christos || htab->sgot == NULL)) 1876 1.1.1.2 christos { 1877 1.1.1.2 christos /* Use got.plt. */ 1878 1.1.1.2 christos h->got.offset = (bfd_vma) -1; 1879 1.1.1.2 christos } 1880 1.1.1.2 christos else 1881 1.1.1.2 christos { 1882 1.1.1.2 christos if (!use_plt) 1883 1.1.1.2 christos { 1884 1.1.1.2 christos /* PLT isn't used. */ 1885 1.1.1.2 christos h->plt.offset = (bfd_vma) -1; 1886 1.1.1.2 christos } 1887 1.1.1.2 christos if (h->got.refcount <= 0) 1888 1.1.1.2 christos { 1889 1.1.1.2 christos /* GOT isn't need when there are only relocations for static 1890 1.1.1.2 christos pointers. */ 1891 1.1.1.2 christos h->got.offset = (bfd_vma) -1; 1892 1.1.1.2 christos } 1893 1.1.1.2 christos else 1894 1.1.1.2 christos { 1895 1.1.1.2 christos h->got.offset = htab->sgot->size; 1896 1.1.1.2 christos htab->sgot->size += got_entry_size; 1897 1.1.1.2 christos /* Need to relocate the GOT entry in a PIC object or PLT isn't 1898 1.1.1.2 christos used. Otherwise, the GOT entry will be filled with the PLT 1899 1.1.1.2 christos entry and dynamic GOT relocation isn't needed. */ 1900 1.1.1.2 christos if (need_dynreloc) 1901 1.1.1.2 christos { 1902 1.1.1.2 christos /* For non-static executable, dynamic GOT relocation is in 1903 1.1.1.2 christos rela.got section, but for static executable, it is 1904 1.1.1.2 christos in rela.iplt section. */ 1905 1.1.1.2 christos if (htab->splt != NULL) 1906 1.1.1.2 christos htab->srelgot->size += sizeof_reloc; 1907 1.1.1.2 christos else 1908 1.1.1.2 christos { 1909 1.1.1.2 christos relplt->size += sizeof_reloc; 1910 1.1.1.2 christos relplt->reloc_count++; 1911 1.1.1.2 christos } 1912 1.1.1.2 christos } 1913 1.1.1.2 christos } 1914 1.1.1.2 christos } 1915 1.1.1.2 christos 1916 1.1.1.2 christos return true; 1917 1.1.1.2 christos } 1918 1.1.1.2 christos 1919 1.1 christos /* Allocate space in .plt, .got and associated reloc sections for 1920 1.1 christos ifunc dynamic relocs. */ 1921 1.1 christos 1922 1.1 christos static bool 1923 1.1.1.3 christos elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, 1924 1.1.1.3 christos struct bfd_link_info *info, 1925 1.1.1.3 christos bool ref_local) 1926 1.1 christos { 1927 1.1 christos /* An example of a bfd_link_hash_indirect symbol is versioned 1928 1.1 christos symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect) 1929 1.1 christos -> __gxx_personality_v0(bfd_link_hash_defined) 1930 1.1 christos 1931 1.1 christos There is no need to process bfd_link_hash_indirect symbols here 1932 1.1 christos because we will also be presented with the concrete instance of 1933 1.1 christos the symbol and loongarch_elf_copy_indirect_symbol () will have been 1934 1.1 christos called to copy all relevant data from the generic to the concrete 1935 1.1 christos symbol instance. */ 1936 1.1 christos if (h->root.type == bfd_link_hash_indirect) 1937 1.1 christos return true; 1938 1.1 christos 1939 1.1 christos if (h->root.type == bfd_link_hash_warning) 1940 1.1 christos h = (struct elf_link_hash_entry *) h->root.u.i.link; 1941 1.1 christos 1942 1.1 christos /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it 1943 1.1 christos here if it is defined and referenced in a non-shared object. */ 1944 1.1.1.2 christos if (h->type == STT_GNU_IFUNC && h->def_regular) 1945 1.1.1.2 christos { 1946 1.1.1.3 christos if (ref_local && LARCH_REF_LOCAL (info, h)) 1947 1.1.1.2 christos return local_allocate_ifunc_dyn_relocs (info, h, 1948 1.1.1.2 christos &h->dyn_relocs, 1949 1.1.1.2 christos PLT_ENTRY_SIZE, 1950 1.1.1.2 christos PLT_HEADER_SIZE, 1951 1.1.1.2 christos GOT_ENTRY_SIZE, 1952 1.1.1.2 christos false); 1953 1.1.1.3 christos else if (!ref_local && !LARCH_REF_LOCAL (info, h)) 1954 1.1.1.2 christos return _bfd_elf_allocate_ifunc_dyn_relocs (info, h, 1955 1.1.1.2 christos &h->dyn_relocs, 1956 1.1.1.2 christos PLT_ENTRY_SIZE, 1957 1.1.1.2 christos PLT_HEADER_SIZE, 1958 1.1.1.2 christos GOT_ENTRY_SIZE, 1959 1.1.1.2 christos false); 1960 1.1.1.2 christos } 1961 1.1.1.2 christos 1962 1.1 christos return true; 1963 1.1 christos } 1964 1.1 christos 1965 1.1.1.3 christos static bool 1966 1.1.1.3 christos elfNN_allocate_ifunc_dynrelocs_ref_local (struct elf_link_hash_entry *h, 1967 1.1.1.3 christos void *info) 1968 1.1.1.3 christos { 1969 1.1.1.3 christos return elfNN_allocate_ifunc_dynrelocs (h, (struct bfd_link_info *) info, 1970 1.1.1.3 christos true); 1971 1.1.1.3 christos } 1972 1.1.1.3 christos 1973 1.1.1.3 christos static bool 1974 1.1.1.3 christos elfNN_allocate_ifunc_dynrelocs_ref_global (struct elf_link_hash_entry *h, 1975 1.1.1.3 christos void *info) 1976 1.1.1.3 christos { 1977 1.1.1.3 christos return elfNN_allocate_ifunc_dynrelocs (h, (struct bfd_link_info *) info, 1978 1.1.1.3 christos false); 1979 1.1.1.3 christos } 1980 1.1.1.3 christos 1981 1.1 christos /* Allocate space in .plt, .got and associated reloc sections for 1982 1.1 christos ifunc dynamic relocs. */ 1983 1.1 christos 1984 1.1.1.2 christos static int 1985 1.1.1.2 christos elfNN_allocate_local_ifunc_dynrelocs (void **slot, void *inf) 1986 1.1 christos { 1987 1.1 christos struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot; 1988 1.1 christos 1989 1.1 christos if (h->type != STT_GNU_IFUNC 1990 1.1 christos || !h->def_regular 1991 1.1 christos || !h->ref_regular 1992 1.1 christos || !h->forced_local 1993 1.1 christos || h->root.type != bfd_link_hash_defined) 1994 1.1 christos abort (); 1995 1.1 christos 1996 1.1.1.3 christos return elfNN_allocate_ifunc_dynrelocs_ref_local (h, inf); 1997 1.1 christos } 1998 1.1 christos 1999 1.1 christos /* Set DF_TEXTREL if we find any dynamic relocs that apply to 2000 1.1 christos read-only sections. */ 2001 1.1 christos 2002 1.1 christos static bool 2003 1.1 christos maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) 2004 1.1 christos { 2005 1.1 christos asection *sec; 2006 1.1 christos 2007 1.1 christos if (h->root.type == bfd_link_hash_indirect) 2008 1.1 christos return true; 2009 1.1 christos 2010 1.1 christos sec = readonly_dynrelocs (h); 2011 1.1 christos if (sec != NULL) 2012 1.1 christos { 2013 1.1 christos struct bfd_link_info *info = (struct bfd_link_info *) info_p; 2014 1.1 christos 2015 1.1 christos info->flags |= DF_TEXTREL; 2016 1.1 christos info->callbacks->minfo (_("%pB: dynamic relocation against `%pT' in " 2017 1.1 christos "read-only section `%pA'\n"), 2018 1.1 christos sec->owner, h->root.root.string, sec); 2019 1.1 christos 2020 1.1 christos /* Not an error, just cut short the traversal. */ 2021 1.1 christos return false; 2022 1.1 christos } 2023 1.1 christos return true; 2024 1.1 christos } 2025 1.1 christos 2026 1.1 christos static bool 2027 1.1.1.3 christos record_relr (struct loongarch_elf_link_hash_table *htab, asection *sec, 2028 1.1.1.3 christos bfd_vma off, asection *sreloc) 2029 1.1.1.3 christos { 2030 1.1.1.3 christos struct relr_entry **sec_relr = &loongarch_elf_section_data (sec)->relr; 2031 1.1.1.3 christos 2032 1.1.1.3 christos /* Undo the relocation section size accounting. */ 2033 1.1.1.3 christos BFD_ASSERT (sreloc->size >= sizeof (ElfNN_External_Rela)); 2034 1.1.1.3 christos sreloc->size -= sizeof (ElfNN_External_Rela); 2035 1.1.1.3 christos 2036 1.1.1.3 christos BFD_ASSERT (off % 2 == 0 && sec->alignment_power > 0); 2037 1.1.1.3 christos if (htab->relr_count >= htab->relr_alloc) 2038 1.1.1.3 christos { 2039 1.1.1.3 christos if (htab->relr_alloc == 0) 2040 1.1.1.3 christos htab->relr_alloc = 4096; 2041 1.1.1.3 christos else 2042 1.1.1.3 christos htab->relr_alloc *= 2; 2043 1.1.1.3 christos 2044 1.1.1.3 christos htab->relr = bfd_realloc (htab->relr, 2045 1.1.1.3 christos htab->relr_alloc * sizeof (*htab->relr)); 2046 1.1.1.3 christos if (!htab->relr) 2047 1.1.1.3 christos return false; 2048 1.1.1.3 christos } 2049 1.1.1.3 christos htab->relr[htab->relr_count].sec = sec; 2050 1.1.1.3 christos htab->relr[htab->relr_count].off = off; 2051 1.1.1.3 christos if (*sec_relr == NULL) 2052 1.1.1.3 christos *sec_relr = &htab->relr[htab->relr_count]; 2053 1.1.1.3 christos htab->relr_count++; 2054 1.1.1.3 christos return true; 2055 1.1.1.3 christos } 2056 1.1.1.3 christos 2057 1.1.1.3 christos static bool 2058 1.1.1.3 christos record_relr_local_got_relocs (bfd *input_bfd, struct bfd_link_info *info) 2059 1.1.1.3 christos { 2060 1.1.1.3 christos bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd); 2061 1.1.1.3 christos char *local_tls_type = _bfd_loongarch_elf_local_got_tls_type (input_bfd); 2062 1.1.1.3 christos Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd); 2063 1.1.1.3 christos struct loongarch_elf_link_hash_table *htab = 2064 1.1.1.3 christos loongarch_elf_hash_table (info); 2065 1.1.1.3 christos 2066 1.1.1.3 christos if (!local_got_offsets || !local_tls_type || !bfd_link_pic (info)) 2067 1.1.1.3 christos return true; 2068 1.1.1.3 christos 2069 1.1.1.3 christos for (unsigned i = 0; i < symtab_hdr->sh_info; i++) 2070 1.1.1.3 christos { 2071 1.1.1.3 christos bfd_vma off = local_got_offsets[i]; 2072 1.1.1.3 christos 2073 1.1.1.3 christos /* FIXME: If the local symbol is in SHN_ABS then emitting 2074 1.1.1.3 christos a relative relocation is not correct, but it seems to be wrong 2075 1.1.1.3 christos in loongarch_elf_relocate_section too. */ 2076 1.1.1.3 christos if (local_tls_type[i] == GOT_NORMAL 2077 1.1.1.3 christos && !record_relr (htab, htab->elf.sgot, off, htab->elf.srelgot)) 2078 1.1.1.3 christos return false; 2079 1.1.1.3 christos } 2080 1.1.1.3 christos 2081 1.1.1.3 christos return true; 2082 1.1.1.3 christos } 2083 1.1.1.3 christos 2084 1.1.1.3 christos static bool 2085 1.1.1.3 christos record_relr_dyn_got_relocs (struct elf_link_hash_entry *h, void *inf) 2086 1.1.1.3 christos { 2087 1.1.1.3 christos struct bfd_link_info *info = (struct bfd_link_info *) inf; 2088 1.1.1.3 christos struct loongarch_elf_link_hash_table *htab = 2089 1.1.1.3 christos loongarch_elf_hash_table (info); 2090 1.1.1.3 christos 2091 1.1.1.3 christos if (h->root.type == bfd_link_hash_indirect) 2092 1.1.1.3 christos return true; 2093 1.1.1.3 christos if (h->type == STT_GNU_IFUNC && h->def_regular) 2094 1.1.1.3 christos return true; 2095 1.1.1.3 christos if (h->got.refcount <= 0) 2096 1.1.1.3 christos return true; 2097 1.1.1.3 christos if (loongarch_elf_hash_entry (h)->tls_type 2098 1.1.1.3 christos & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC)) 2099 1.1.1.3 christos return true; 2100 1.1.1.3 christos if (!bfd_link_pic (info)) 2101 1.1.1.3 christos return true; 2102 1.1.1.3 christos 2103 1.1.1.3 christos /* On LoongArch a GOT entry for undefined weak symbol is never relocated 2104 1.1.1.3 christos with R_LARCH_RELATIVE: we don't have -z dynamic-undefined-weak, thus 2105 1.1.1.3 christos the GOT entry is either const 0 (if the symbol is LARCH_REF_LOCAL) or 2106 1.1.1.3 christos relocated with R_LARCH_NN (otherwise). */ 2107 1.1.1.3 christos if (h->root.type == bfd_link_hash_undefweak) 2108 1.1.1.3 christos return true; 2109 1.1.1.3 christos 2110 1.1.1.3 christos if (!LARCH_REF_LOCAL (info, h)) 2111 1.1.1.3 christos return true; 2112 1.1.1.3 christos if (bfd_is_abs_symbol (&h->root)) 2113 1.1.1.3 christos return true; 2114 1.1.1.3 christos 2115 1.1.1.3 christos if (!record_relr (htab, htab->elf.sgot, h->got.offset, 2116 1.1.1.3 christos htab->elf.srelgot)) 2117 1.1.1.3 christos return false; 2118 1.1.1.3 christos 2119 1.1.1.3 christos return true; 2120 1.1.1.3 christos } 2121 1.1.1.3 christos 2122 1.1.1.3 christos static bool 2123 1.1.1.3 christos record_relr_non_got_relocs (bfd *input_bfd, struct bfd_link_info *info, 2124 1.1.1.3 christos asection *sec) 2125 1.1.1.3 christos { 2126 1.1.1.3 christos asection *sreloc; 2127 1.1.1.3 christos struct loongarch_elf_link_hash_table *htab; 2128 1.1.1.3 christos Elf_Internal_Rela *relocs, *rel, *rel_end; 2129 1.1.1.3 christos Elf_Internal_Shdr *symtab_hdr; 2130 1.1.1.3 christos struct elf_link_hash_entry **sym_hashes; 2131 1.1.1.3 christos 2132 1.1.1.3 christos if (!bfd_link_pic (info)) 2133 1.1.1.3 christos return true; 2134 1.1.1.3 christos if (sec->reloc_count == 0) 2135 1.1.1.3 christos return true; 2136 1.1.1.3 christos if ((sec->flags & (SEC_RELOC | SEC_ALLOC | SEC_DEBUGGING)) 2137 1.1.1.3 christos != (SEC_RELOC | SEC_ALLOC)) 2138 1.1.1.3 christos return true; 2139 1.1.1.3 christos if (sec->alignment_power == 0) 2140 1.1.1.3 christos return true; 2141 1.1.1.3 christos if (discarded_section (sec)) 2142 1.1.1.3 christos return true; 2143 1.1.1.3 christos 2144 1.1.1.3 christos sreloc = elf_section_data (sec)->sreloc; 2145 1.1.1.3 christos if (sreloc == NULL) 2146 1.1.1.3 christos return true; 2147 1.1.1.3 christos 2148 1.1.1.3 christos htab = loongarch_elf_hash_table (info); 2149 1.1.1.3 christos symtab_hdr = &elf_symtab_hdr (input_bfd); 2150 1.1.1.3 christos sym_hashes = elf_sym_hashes (input_bfd); 2151 1.1.1.3 christos relocs = _bfd_elf_link_info_read_relocs (input_bfd, info, sec, NULL, 2152 1.1.1.3 christos NULL, info->keep_memory); 2153 1.1.1.3 christos BFD_ASSERT (relocs != NULL); 2154 1.1.1.3 christos rel_end = relocs + sec->reloc_count; 2155 1.1.1.3 christos for (rel = relocs; rel < rel_end; rel++) 2156 1.1.1.3 christos { 2157 1.1.1.3 christos unsigned r_symndx = ELFNN_R_SYM (rel->r_info); 2158 1.1.1.3 christos unsigned int r_type = ELFNN_R_TYPE (rel->r_info); 2159 1.1.1.3 christos struct elf_link_hash_entry *h = NULL; 2160 1.1.1.3 christos asection *def_sec = NULL; 2161 1.1.1.3 christos 2162 1.1.1.3 christos if ((r_type != R_LARCH_64 && r_type != R_LARCH_32) 2163 1.1.1.3 christos || rel->r_offset % 2 != 0) 2164 1.1.1.3 christos continue; 2165 1.1.1.3 christos 2166 1.1.1.3 christos /* The logical below must match loongarch_elf_relocate_section. */ 2167 1.1.1.3 christos if (r_symndx < symtab_hdr->sh_info) 2168 1.1.1.3 christos { 2169 1.1.1.3 christos /* A local symbol. */ 2170 1.1.1.3 christos Elf_Internal_Sym *isym; 2171 1.1.1.3 christos isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, input_bfd, 2172 1.1.1.3 christos r_symndx); 2173 1.1.1.3 christos BFD_ASSERT(isym != NULL); 2174 1.1.1.3 christos 2175 1.1.1.3 christos /* Local STT_GNU_IFUNC symbol uses R_LARCH_IRELATIVE for 2176 1.1.1.3 christos R_LARCH_NN, not R_LARCH_RELATIVE. */ 2177 1.1.1.3 christos if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC) 2178 1.1.1.3 christos continue; 2179 1.1.1.3 christos def_sec = bfd_section_from_elf_index (input_bfd, isym->st_shndx); 2180 1.1.1.3 christos } 2181 1.1.1.3 christos else 2182 1.1.1.3 christos { 2183 1.1.1.3 christos h = sym_hashes[r_symndx - symtab_hdr->sh_info]; 2184 1.1.1.3 christos while (h->root.type == bfd_link_hash_indirect 2185 1.1.1.3 christos || h->root.type == bfd_link_hash_warning) 2186 1.1.1.3 christos h = (struct elf_link_hash_entry *) h->root.u.i.link; 2187 1.1.1.3 christos 2188 1.1.1.3 christos /* Filter out symbols that cannot have a relative reloc. */ 2189 1.1.1.3 christos if (h->dyn_relocs == NULL) 2190 1.1.1.3 christos continue; 2191 1.1.1.3 christos if (bfd_is_abs_symbol (&h->root)) 2192 1.1.1.3 christos continue; 2193 1.1.1.3 christos if (h->type == STT_GNU_IFUNC) 2194 1.1.1.3 christos continue; 2195 1.1.1.3 christos 2196 1.1.1.3 christos if (h->root.type == bfd_link_hash_defined 2197 1.1.1.3 christos || h->root.type == bfd_link_hash_defweak) 2198 1.1.1.3 christos def_sec = h->root.u.def.section; 2199 1.1.1.3 christos 2200 1.1.1.3 christos /* On LoongArch an R_LARCH_NN against undefined weak symbol 2201 1.1.1.3 christos is never converted to R_LARCH_RELATIVE: we don't have 2202 1.1.1.3 christos -z dynamic-undefined-weak, thus the reloc is either removed 2203 1.1.1.3 christos (if the symbol is LARCH_REF_LOCAL) or kept (otherwise). */ 2204 1.1.1.3 christos if (h->root.type == bfd_link_hash_undefweak) 2205 1.1.1.3 christos continue; 2206 1.1.1.3 christos 2207 1.1.1.3 christos if (!LARCH_REF_LOCAL (info, h)) 2208 1.1.1.3 christos continue; 2209 1.1.1.3 christos } 2210 1.1.1.3 christos 2211 1.1.1.3 christos if (!def_sec || discarded_section (def_sec)) 2212 1.1.1.3 christos continue; 2213 1.1.1.3 christos 2214 1.1.1.3 christos if (!record_relr (htab, sec, rel->r_offset, sreloc)) 2215 1.1.1.3 christos return false; 2216 1.1.1.3 christos } 2217 1.1.1.3 christos 2218 1.1.1.3 christos return true; 2219 1.1.1.3 christos } 2220 1.1.1.3 christos 2221 1.1.1.3 christos static int 2222 1.1.1.3 christos cmp_relr_addr (const void *p, const void *q) 2223 1.1.1.3 christos { 2224 1.1.1.3 christos const bfd_vma *a = p, *b = q; 2225 1.1.1.3 christos return (*a > *b) - (*a < *b); 2226 1.1.1.3 christos } 2227 1.1.1.3 christos 2228 1.1.1.3 christos static bool 2229 1.1.1.3 christos sort_relr (struct bfd_link_info *info, 2230 1.1.1.3 christos struct loongarch_elf_link_hash_table *htab) 2231 1.1.1.3 christos { 2232 1.1.1.3 christos if (htab->relr_count == 0) 2233 1.1.1.3 christos return true; 2234 1.1.1.3 christos 2235 1.1.1.3 christos bfd_vma *addr = htab->relr_sorted; 2236 1.1.1.3 christos if (!addr) 2237 1.1.1.3 christos { 2238 1.1.1.3 christos addr = bfd_malloc (htab->relr_count * sizeof (*addr)); 2239 1.1.1.3 christos if (!addr) 2240 1.1.1.3 christos return false; 2241 1.1.1.3 christos htab->relr_sorted = addr; 2242 1.1.1.3 christos } 2243 1.1.1.3 christos 2244 1.1.1.3 christos for (bfd_size_type i = 0; i < htab->relr_count; i++) 2245 1.1.1.3 christos { 2246 1.1.1.3 christos bfd_vma off = _bfd_elf_section_offset (info->output_bfd, info, 2247 1.1.1.3 christos htab->relr[i].sec, 2248 1.1.1.3 christos htab->relr[i].off); 2249 1.1.1.3 christos addr[i] = htab->relr[i].sec->output_section->vma 2250 1.1.1.3 christos + htab->relr[i].sec->output_offset + off; 2251 1.1.1.3 christos } 2252 1.1.1.3 christos qsort(addr, htab->relr_count, sizeof (*addr), cmp_relr_addr); 2253 1.1.1.3 christos return true; 2254 1.1.1.3 christos } 2255 1.1.1.3 christos 2256 1.1.1.3 christos static bool 2257 1.1.1.3 christos loongarch_elf_size_relative_relocs (struct bfd_link_info *info, 2258 1.1.1.3 christos bool *need_layout) 2259 1.1.1.3 christos { 2260 1.1.1.3 christos struct loongarch_elf_link_hash_table *htab = 2261 1.1.1.3 christos loongarch_elf_hash_table (info); 2262 1.1.1.3 christos asection *srelrdyn = htab->elf.srelrdyn; 2263 1.1.1.3 christos 2264 1.1.1.3 christos *need_layout = false; 2265 1.1.1.3 christos 2266 1.1.1.3 christos if (!sort_relr (info, htab)) 2267 1.1.1.3 christos return false; 2268 1.1.1.3 christos bfd_vma *addr = htab->relr_sorted; 2269 1.1.1.3 christos 2270 1.1.1.3 christos BFD_ASSERT (srelrdyn != NULL); 2271 1.1.1.3 christos bfd_size_type oldsize = srelrdyn->size; 2272 1.1.1.3 christos srelrdyn->size = 0; 2273 1.1.1.3 christos for (bfd_size_type i = 0; i < htab->relr_count; ) 2274 1.1.1.3 christos { 2275 1.1.1.3 christos bfd_vma base = addr[i]; 2276 1.1.1.3 christos i++; 2277 1.1.1.3 christos srelrdyn->size += NN / 8; 2278 1.1.1.3 christos base += NN / 8; 2279 1.1.1.3 christos while (1) 2280 1.1.1.3 christos { 2281 1.1.1.3 christos bfd_size_type start_i = i; 2282 1.1.1.3 christos while (i < htab->relr_count 2283 1.1.1.3 christos && addr[i] - base < (NN - 1) * (NN / 8) 2284 1.1.1.3 christos && (addr[i] - base) % (NN / 8) == 0) 2285 1.1.1.3 christos i++; 2286 1.1.1.3 christos if (i == start_i) 2287 1.1.1.3 christos break; 2288 1.1.1.3 christos srelrdyn->size += NN / 8; 2289 1.1.1.3 christos base += (NN - 1) * (NN / 8); 2290 1.1.1.3 christos } 2291 1.1.1.3 christos } 2292 1.1.1.3 christos if (srelrdyn->size != oldsize) 2293 1.1.1.3 christos { 2294 1.1.1.3 christos *need_layout = true; 2295 1.1.1.3 christos /* Stop after a few iterations in case the layout does not converge, 2296 1.1.1.3 christos but we can only stop when the size would shrink (and pad the 2297 1.1.1.3 christos spare space with 1. */ 2298 1.1.1.3 christos if (htab->relr_layout_iter++ > 5 && srelrdyn->size < oldsize) 2299 1.1.1.3 christos { 2300 1.1.1.3 christos srelrdyn->size = oldsize; 2301 1.1.1.3 christos *need_layout = false; 2302 1.1.1.3 christos } 2303 1.1.1.3 christos } 2304 1.1.1.3 christos 2305 1.1.1.3 christos htab->layout_mutating_for_relr = *need_layout; 2306 1.1.1.3 christos return true; 2307 1.1.1.3 christos } 2308 1.1.1.3 christos 2309 1.1.1.3 christos static bool 2310 1.1.1.3 christos loongarch_elf_finish_relative_relocs (struct bfd_link_info *info) 2311 1.1.1.3 christos { 2312 1.1.1.3 christos struct loongarch_elf_link_hash_table *htab = 2313 1.1.1.3 christos loongarch_elf_hash_table (info); 2314 1.1.1.3 christos asection *srelrdyn = htab->elf.srelrdyn; 2315 1.1.1.3 christos bfd *dynobj = htab->elf.dynobj; 2316 1.1.1.3 christos 2317 1.1.1.3 christos if (!srelrdyn || srelrdyn->size == 0) 2318 1.1.1.3 christos return true; 2319 1.1.1.3 christos 2320 1.1.1.3 christos srelrdyn->contents = bfd_alloc (dynobj, srelrdyn->size); 2321 1.1.1.3 christos if (!srelrdyn->contents) 2322 1.1.1.3 christos return false; 2323 1.1.1.3 christos srelrdyn->alloced = 1; 2324 1.1.1.3 christos 2325 1.1.1.3 christos bfd_vma *addr = htab->relr_sorted; 2326 1.1.1.3 christos bfd_byte *loc = srelrdyn->contents; 2327 1.1.1.3 christos for (bfd_size_type i = 0; i < htab->relr_count; ) 2328 1.1.1.3 christos { 2329 1.1.1.3 christos bfd_vma base = addr[i]; 2330 1.1.1.3 christos i++; 2331 1.1.1.3 christos bfd_put_NN (dynobj, base, loc); 2332 1.1.1.3 christos loc += NN / 8; 2333 1.1.1.3 christos base += NN / 8; 2334 1.1.1.3 christos while (1) 2335 1.1.1.3 christos { 2336 1.1.1.3 christos uintNN_t bits = 0; 2337 1.1.1.3 christos while (i < htab->relr_count) 2338 1.1.1.3 christos { 2339 1.1.1.3 christos bfd_vma delta = addr[i] - base; 2340 1.1.1.3 christos if (delta >= (NN - 1) * (NN / 8) || delta % (NN / 8) != 0) 2341 1.1.1.3 christos break; 2342 1.1.1.3 christos bits |= (uintNN_t) 1 << (delta / (NN / 8)); 2343 1.1.1.3 christos i++; 2344 1.1.1.3 christos } 2345 1.1.1.3 christos if (bits == 0) 2346 1.1.1.3 christos break; 2347 1.1.1.3 christos bfd_put_NN (dynobj, (bits << 1) | 1, loc); 2348 1.1.1.3 christos loc += NN / 8; 2349 1.1.1.3 christos base += (NN - 1) * (NN / 8); 2350 1.1.1.3 christos } 2351 1.1.1.3 christos } 2352 1.1.1.3 christos 2353 1.1.1.3 christos free (addr); 2354 1.1.1.3 christos htab->relr_sorted = NULL; 2355 1.1.1.3 christos 2356 1.1.1.3 christos /* Pad any excess with 1's, a do-nothing encoding. */ 2357 1.1.1.3 christos while (loc < srelrdyn->contents + srelrdyn->size) 2358 1.1.1.3 christos { 2359 1.1.1.3 christos bfd_put_NN (dynobj, 1, loc); 2360 1.1.1.3 christos loc += NN / 8; 2361 1.1.1.3 christos } 2362 1.1.1.3 christos 2363 1.1.1.3 christos return true; 2364 1.1.1.3 christos } 2365 1.1.1.3 christos 2366 1.1.1.3 christos static bool 2367 1.1.1.3 christos loongarch_elf_late_size_sections (bfd *output_bfd, 2368 1.1.1.3 christos struct bfd_link_info *info) 2369 1.1 christos { 2370 1.1 christos struct loongarch_elf_link_hash_table *htab; 2371 1.1 christos bfd *dynobj; 2372 1.1 christos asection *s; 2373 1.1 christos bfd *ibfd; 2374 1.1 christos 2375 1.1 christos htab = loongarch_elf_hash_table (info); 2376 1.1 christos BFD_ASSERT (htab != NULL); 2377 1.1 christos dynobj = htab->elf.dynobj; 2378 1.1.1.3 christos if (dynobj == NULL) 2379 1.1.1.3 christos return true; 2380 1.1 christos 2381 1.1 christos if (htab->elf.dynamic_sections_created) 2382 1.1 christos { 2383 1.1 christos /* Set the contents of the .interp section to the interpreter. */ 2384 1.1 christos if (bfd_link_executable (info) && !info->nointerp) 2385 1.1 christos { 2386 1.1 christos const char *interpreter; 2387 1.1 christos s = bfd_get_linker_section (dynobj, ".interp"); 2388 1.1 christos BFD_ASSERT (s != NULL); 2389 1.1.1.2 christos 2390 1.1.1.2 christos if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS32) 2391 1.1 christos interpreter = "/lib32/ld.so.1"; 2392 1.1.1.2 christos else if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS64) 2393 1.1 christos interpreter = "/lib64/ld.so.1"; 2394 1.1 christos else 2395 1.1 christos interpreter = "/lib/ld.so.1"; 2396 1.1.1.2 christos 2397 1.1 christos s->contents = (unsigned char *) interpreter; 2398 1.1.1.3 christos s->alloced = 1; 2399 1.1 christos s->size = strlen (interpreter) + 1; 2400 1.1 christos } 2401 1.1 christos } 2402 1.1 christos 2403 1.1 christos /* Set up .got offsets for local syms, and space for local dynamic 2404 1.1 christos relocs. */ 2405 1.1 christos for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next) 2406 1.1 christos { 2407 1.1 christos bfd_signed_vma *local_got; 2408 1.1 christos bfd_signed_vma *end_local_got; 2409 1.1 christos char *local_tls_type; 2410 1.1 christos bfd_size_type locsymcount; 2411 1.1 christos Elf_Internal_Shdr *symtab_hdr; 2412 1.1 christos asection *srel; 2413 1.1 christos 2414 1.1 christos if (!is_loongarch_elf (ibfd)) 2415 1.1 christos continue; 2416 1.1 christos 2417 1.1 christos for (s = ibfd->sections; s != NULL; s = s->next) 2418 1.1 christos { 2419 1.1 christos struct elf_dyn_relocs *p; 2420 1.1 christos 2421 1.1 christos for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next) 2422 1.1 christos { 2423 1.1 christos p->count -= p->pc_count; 2424 1.1 christos if (!bfd_is_abs_section (p->sec) 2425 1.1 christos && bfd_is_abs_section (p->sec->output_section)) 2426 1.1 christos { 2427 1.1 christos /* Input section has been discarded, either because 2428 1.1 christos it is a copy of a linkonce section or due to 2429 1.1 christos linker script /DISCARD/, so we'll be discarding 2430 1.1 christos the relocs too. */ 2431 1.1 christos } 2432 1.1 christos else if (0 < p->count) 2433 1.1 christos { 2434 1.1 christos srel = elf_section_data (p->sec)->sreloc; 2435 1.1 christos srel->size += p->count * sizeof (ElfNN_External_Rela); 2436 1.1 christos if ((p->sec->output_section->flags & SEC_READONLY) != 0) 2437 1.1 christos info->flags |= DF_TEXTREL; 2438 1.1 christos } 2439 1.1 christos } 2440 1.1 christos } 2441 1.1 christos 2442 1.1 christos local_got = elf_local_got_refcounts (ibfd); 2443 1.1 christos if (!local_got) 2444 1.1 christos continue; 2445 1.1 christos 2446 1.1 christos symtab_hdr = &elf_symtab_hdr (ibfd); 2447 1.1 christos locsymcount = symtab_hdr->sh_info; 2448 1.1 christos end_local_got = local_got + locsymcount; 2449 1.1 christos local_tls_type = _bfd_loongarch_elf_local_got_tls_type (ibfd); 2450 1.1 christos s = htab->elf.sgot; 2451 1.1 christos srel = htab->elf.srelgot; 2452 1.1 christos for (; local_got < end_local_got; ++local_got, ++local_tls_type) 2453 1.1 christos { 2454 1.1 christos if (0 < *local_got) 2455 1.1 christos { 2456 1.1 christos *local_got = s->size; 2457 1.1.1.2 christos if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC)) 2458 1.1.1.2 christos { 2459 1.1.1.2 christos /* TLS gd use two got. */ 2460 1.1.1.2 christos if (*local_tls_type & GOT_TLS_GD) 2461 1.1.1.2 christos { 2462 1.1.1.2 christos s->size += 2 * GOT_ENTRY_SIZE; 2463 1.1.1.2 christos if (!bfd_link_executable (info)) 2464 1.1.1.2 christos srel->size += sizeof (ElfNN_External_Rela); 2465 1.1.1.2 christos } 2466 1.1 christos 2467 1.1.1.2 christos /* TLS_DESC use two got. */ 2468 1.1.1.2 christos if (*local_tls_type & GOT_TLS_GDESC) 2469 1.1.1.2 christos { 2470 1.1.1.2 christos s->size += 2 * GOT_ENTRY_SIZE; 2471 1.1.1.2 christos srel->size += sizeof (ElfNN_External_Rela); 2472 1.1.1.2 christos } 2473 1.1 christos 2474 1.1.1.2 christos /* TLS ie and use one got. */ 2475 1.1.1.2 christos if (*local_tls_type & GOT_TLS_IE) 2476 1.1.1.2 christos { 2477 1.1.1.2 christos s->size += GOT_ENTRY_SIZE; 2478 1.1.1.2 christos if (!bfd_link_executable (info)) 2479 1.1.1.2 christos srel->size += sizeof (ElfNN_External_Rela); 2480 1.1.1.2 christos } 2481 1.1.1.2 christos } 2482 1.1.1.2 christos else 2483 1.1.1.2 christos { 2484 1.1.1.2 christos s->size += GOT_ENTRY_SIZE; 2485 1.1.1.2 christos srel->size += sizeof (ElfNN_External_Rela); 2486 1.1.1.2 christos } 2487 1.1 christos } 2488 1.1 christos else 2489 1.1 christos *local_got = MINUS_ONE; 2490 1.1 christos } 2491 1.1 christos } 2492 1.1 christos 2493 1.1 christos /* Allocate global sym .plt and .got entries, and space for global 2494 1.1 christos sym dynamic relocs. */ 2495 1.1 christos elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info); 2496 1.1 christos 2497 1.1.1.3 christos /* Allocate global ifunc sym .plt and .got entries, and space for 2498 1.1.1.3 christos *preemptible* ifunc sym dynamic relocs. Note that we must do it 2499 1.1.1.3 christos for *all* preemptible ifunc (including local ifuncs and STV_HIDDEN 2500 1.1.1.3 christos ifuncs) before doing it for any non-preemptible ifunc symbol: 2501 1.1.1.3 christos assuming we are not so careful, when we link a shared library the 2502 1.1.1.3 christos correlation of .plt and .rela.plt might look like: 2503 1.1.1.3 christos 2504 1.1.1.3 christos idx in .plt idx in .rela.plt 2505 1.1.1.3 christos ext_func1@plt 0 0 2506 1.1.1.3 christos ext_func2@plt 1 1 2507 1.1.1.3 christos ext_func3@plt 2 2 2508 1.1.1.3 christos hidden_ifunc1@plt 3 None: it's in .rela.got 2509 1.1.1.3 christos hidden_ifunc2@plt 4 None: it's in .rela.got 2510 1.1.1.3 christos normal_ifunc1@plt 5 != 3 2511 1.1.1.3 christos normal_ifunc2@plt 6 != 4 2512 1.1.1.3 christos local_ifunc@plt 7 None: it's in .rela.got 2513 1.1.1.3 christos 2514 1.1.1.3 christos Now oops the indices for normal_ifunc{1,2} in .rela.plt were different 2515 1.1.1.3 christos from the indices in .plt :(. This would break finish_dynamic_symbol 2516 1.1.1.3 christos which assumes the index in .rela.plt matches the index in .plt. 2517 1.1.1.3 christos 2518 1.1.1.3 christos So let's be careful and make it correct: 2519 1.1.1.3 christos 2520 1.1.1.3 christos idx in .plt idx in .rela.plt 2521 1.1.1.3 christos ext_func1@plt 0 0 2522 1.1.1.3 christos ext_func2@plt 1 1 2523 1.1.1.3 christos ext_func3@plt 2 2 2524 1.1.1.3 christos normal_ifunc1@plt 3 3 2525 1.1.1.3 christos normal_ifunc2@plt 4 4 2526 1.1.1.3 christos hidden_ifunc1@plt 5 None: it's in .rela.got 2527 1.1.1.3 christos hidden_ifunc2@plt 6 None: it's in .rela.got 2528 1.1.1.3 christos local_ifunc@plt 7 None: it's in .rela.got 2529 1.1.1.3 christos 2530 1.1.1.3 christos Now normal_ifuncs first. */ 2531 1.1.1.3 christos elf_link_hash_traverse (&htab->elf, 2532 1.1.1.3 christos elfNN_allocate_ifunc_dynrelocs_ref_global, info); 2533 1.1.1.3 christos 2534 1.1.1.3 christos /* Next hidden_ifuncs follows. */ 2535 1.1.1.3 christos elf_link_hash_traverse (&htab->elf, 2536 1.1.1.3 christos elfNN_allocate_ifunc_dynrelocs_ref_local, info); 2537 1.1 christos 2538 1.1.1.3 christos /* Finally local_ifuncs. */ 2539 1.1 christos htab_traverse (htab->loc_hash_table, 2540 1.1.1.2 christos elfNN_allocate_local_ifunc_dynrelocs, info); 2541 1.1 christos 2542 1.1 christos /* Don't allocate .got.plt section if there are no PLT. */ 2543 1.1 christos if (htab->elf.sgotplt && htab->elf.sgotplt->size == GOTPLT_HEADER_SIZE 2544 1.1 christos && (htab->elf.splt == NULL || htab->elf.splt->size == 0)) 2545 1.1 christos htab->elf.sgotplt->size = 0; 2546 1.1 christos 2547 1.1.1.3 christos if (info->enable_dt_relr && !bfd_link_relocatable (info)) 2548 1.1.1.3 christos { 2549 1.1.1.3 christos elf_link_hash_traverse (&htab->elf, record_relr_dyn_got_relocs, info); 2550 1.1.1.3 christos 2551 1.1.1.3 christos for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next) 2552 1.1.1.3 christos { 2553 1.1.1.3 christos if (!is_loongarch_elf (ibfd)) 2554 1.1.1.3 christos continue; 2555 1.1.1.3 christos 2556 1.1.1.3 christos for (s = ibfd->sections; s != NULL; s = s->next) 2557 1.1.1.3 christos if (!record_relr_non_got_relocs (ibfd, info, s)) 2558 1.1.1.3 christos return false; 2559 1.1.1.3 christos 2560 1.1.1.3 christos if (!record_relr_local_got_relocs (ibfd, info)) 2561 1.1.1.3 christos return false; 2562 1.1.1.3 christos } 2563 1.1.1.3 christos } 2564 1.1.1.3 christos 2565 1.1 christos /* The check_relocs and adjust_dynamic_symbol entry points have 2566 1.1 christos determined the sizes of the various dynamic sections. Allocate 2567 1.1 christos memory for them. */ 2568 1.1 christos for (s = dynobj->sections; s != NULL; s = s->next) 2569 1.1 christos { 2570 1.1 christos if ((s->flags & SEC_LINKER_CREATED) == 0) 2571 1.1 christos continue; 2572 1.1 christos 2573 1.1 christos if (s == htab->elf.splt || s == htab->elf.iplt || s == htab->elf.sgot 2574 1.1 christos || s == htab->elf.sgotplt || s == htab->elf.igotplt 2575 1.1 christos || s == htab->elf.sdynbss || s == htab->elf.sdynrelro) 2576 1.1 christos { 2577 1.1 christos /* Strip this section if we don't need it; see the 2578 1.1 christos comment below. */ 2579 1.1 christos } 2580 1.1 christos else if (strncmp (s->name, ".rela", 5) == 0) 2581 1.1 christos { 2582 1.1 christos if (s->size != 0) 2583 1.1 christos { 2584 1.1 christos /* We use the reloc_count field as a counter if we need 2585 1.1 christos to copy relocs into the output file. */ 2586 1.1 christos s->reloc_count = 0; 2587 1.1 christos } 2588 1.1 christos } 2589 1.1.1.3 christos else if (s == htab->elf.srelrdyn && htab->relr_count == 0) 2590 1.1.1.3 christos { 2591 1.1.1.3 christos /* Remove .relr.dyn based on relr_count, not size, since 2592 1.1.1.3 christos it is not sized yet. */ 2593 1.1.1.3 christos s->flags |= SEC_EXCLUDE; 2594 1.1.1.3 christos /* Allocate contents later. */ 2595 1.1.1.3 christos continue; 2596 1.1.1.3 christos } 2597 1.1 christos else 2598 1.1 christos { 2599 1.1 christos /* It's not one of our sections. */ 2600 1.1 christos continue; 2601 1.1 christos } 2602 1.1 christos 2603 1.1 christos if (s->size == 0) 2604 1.1 christos { 2605 1.1 christos /* If we don't need this section, strip it from the 2606 1.1 christos output file. This is mostly to handle .rela.bss and 2607 1.1 christos .rela.plt. We must create both sections in 2608 1.1 christos create_dynamic_sections, because they must be created 2609 1.1 christos before the linker maps input sections to output 2610 1.1 christos sections. The linker does that before 2611 1.1 christos adjust_dynamic_symbol is called, and it is that 2612 1.1 christos function which decides whether anything needs to go 2613 1.1 christos into these sections. */ 2614 1.1 christos s->flags |= SEC_EXCLUDE; 2615 1.1 christos continue; 2616 1.1 christos } 2617 1.1 christos 2618 1.1 christos if ((s->flags & SEC_HAS_CONTENTS) == 0) 2619 1.1 christos continue; 2620 1.1 christos 2621 1.1 christos /* Allocate memory for the section contents. Zero the memory 2622 1.1 christos for the benefit of .rela.plt, which has 4 unused entries 2623 1.1 christos at the beginning, and we don't want garbage. */ 2624 1.1 christos s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size); 2625 1.1 christos if (s->contents == NULL) 2626 1.1 christos return false; 2627 1.1.1.3 christos s->alloced = 1; 2628 1.1 christos } 2629 1.1 christos 2630 1.1 christos if (elf_hash_table (info)->dynamic_sections_created) 2631 1.1 christos { 2632 1.1 christos /* Add some entries to the .dynamic section. We fill in the 2633 1.1 christos values later, in loongarch_elf_finish_dynamic_sections, but we 2634 1.1 christos must add the entries now so that we get the correct size for 2635 1.1 christos the .dynamic section. The DT_DEBUG entry is filled in by the 2636 1.1 christos dynamic linker and used by the debugger. */ 2637 1.1 christos #define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL) 2638 1.1 christos 2639 1.1 christos if (bfd_link_executable (info)) 2640 1.1 christos { 2641 1.1 christos if (!add_dynamic_entry (DT_DEBUG, 0)) 2642 1.1 christos return false; 2643 1.1 christos } 2644 1.1 christos 2645 1.1 christos if (htab->elf.srelplt->size != 0) 2646 1.1 christos { 2647 1.1 christos if (!add_dynamic_entry (DT_PLTGOT, 0) 2648 1.1 christos || !add_dynamic_entry (DT_PLTRELSZ, 0) 2649 1.1 christos || !add_dynamic_entry (DT_PLTREL, DT_RELA) 2650 1.1 christos || !add_dynamic_entry (DT_JMPREL, 0)) 2651 1.1 christos return false; 2652 1.1 christos } 2653 1.1 christos 2654 1.1 christos if (!add_dynamic_entry (DT_RELA, 0) 2655 1.1 christos || !add_dynamic_entry (DT_RELASZ, 0) 2656 1.1 christos || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela))) 2657 1.1 christos return false; 2658 1.1 christos 2659 1.1 christos /* If any dynamic relocs apply to a read-only section, 2660 1.1 christos then we need a DT_TEXTREL entry. */ 2661 1.1 christos if ((info->flags & DF_TEXTREL) == 0) 2662 1.1 christos elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info); 2663 1.1 christos 2664 1.1 christos if (info->flags & DF_TEXTREL) 2665 1.1 christos { 2666 1.1 christos if (!add_dynamic_entry (DT_TEXTREL, 0)) 2667 1.1 christos return false; 2668 1.1 christos /* Clear the DF_TEXTREL flag. It will be set again if we 2669 1.1 christos write out an actual text relocation; we may not, because 2670 1.1 christos at this point we do not know whether e.g. any .eh_frame 2671 1.1 christos absolute relocations have been converted to PC-relative. */ 2672 1.1 christos info->flags &= ~DF_TEXTREL; 2673 1.1 christos } 2674 1.1 christos } 2675 1.1 christos #undef add_dynamic_entry 2676 1.1 christos 2677 1.1 christos return true; 2678 1.1 christos } 2679 1.1 christos 2680 1.1 christos #define LARCH_LD_STACK_DEPTH 16 2681 1.1 christos static int64_t larch_opc_stack[LARCH_LD_STACK_DEPTH]; 2682 1.1 christos static size_t larch_stack_top = 0; 2683 1.1 christos 2684 1.1 christos static bfd_reloc_status_type 2685 1.1 christos loongarch_push (int64_t val) 2686 1.1 christos { 2687 1.1 christos if (LARCH_LD_STACK_DEPTH <= larch_stack_top) 2688 1.1 christos return bfd_reloc_outofrange; 2689 1.1 christos larch_opc_stack[larch_stack_top++] = val; 2690 1.1 christos return bfd_reloc_ok; 2691 1.1 christos } 2692 1.1 christos 2693 1.1 christos static bfd_reloc_status_type 2694 1.1 christos loongarch_pop (int64_t *val) 2695 1.1 christos { 2696 1.1 christos if (larch_stack_top == 0) 2697 1.1 christos return bfd_reloc_outofrange; 2698 1.1 christos BFD_ASSERT (val); 2699 1.1 christos *val = larch_opc_stack[--larch_stack_top]; 2700 1.1 christos return bfd_reloc_ok; 2701 1.1 christos } 2702 1.1 christos 2703 1.1 christos static bfd_reloc_status_type 2704 1.1 christos loongarch_top (int64_t *val) 2705 1.1 christos { 2706 1.1 christos if (larch_stack_top == 0) 2707 1.1 christos return bfd_reloc_outofrange; 2708 1.1 christos BFD_ASSERT (val); 2709 1.1 christos *val = larch_opc_stack[larch_stack_top - 1]; 2710 1.1 christos return bfd_reloc_ok; 2711 1.1 christos } 2712 1.1 christos 2713 1.1 christos static void 2714 1.1 christos loongarch_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel) 2715 1.1 christos { 2716 1.1.1.2 christos BFD_ASSERT (s && s->contents); 2717 1.1 christos const struct elf_backend_data *bed; 2718 1.1 christos bfd_byte *loc; 2719 1.1 christos 2720 1.1 christos bed = get_elf_backend_data (abfd); 2721 1.1.1.2 christos if (!(s->size > s->reloc_count * bed->s->sizeof_rela)) 2722 1.1.1.2 christos BFD_ASSERT (s->size > s->reloc_count * bed->s->sizeof_rela); 2723 1.1 christos loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela); 2724 1.1 christos bed->s->swap_reloca_out (abfd, rel, loc); 2725 1.1 christos } 2726 1.1 christos 2727 1.1 christos /* Check rel->r_offset in range of contents. */ 2728 1.1 christos static bfd_reloc_status_type 2729 1.1 christos loongarch_check_offset (const Elf_Internal_Rela *rel, 2730 1.1 christos const asection *input_section) 2731 1.1 christos { 2732 1.1 christos if (0 == strcmp(input_section->name, ".text") 2733 1.1 christos && rel->r_offset > input_section->size) 2734 1.1 christos return bfd_reloc_overflow; 2735 1.1 christos 2736 1.1 christos return bfd_reloc_ok; 2737 1.1 christos } 2738 1.1 christos 2739 1.1 christos #define LARCH_RELOC_PERFORM_3OP(op1, op2, op3) \ 2740 1.1 christos ({ \ 2741 1.1 christos bfd_reloc_status_type ret = loongarch_pop (&op2); \ 2742 1.1 christos if (ret == bfd_reloc_ok) \ 2743 1.1 christos { \ 2744 1.1 christos ret = loongarch_pop (&op1); \ 2745 1.1 christos if (ret == bfd_reloc_ok) \ 2746 1.1 christos ret = loongarch_push (op3); \ 2747 1.1 christos } \ 2748 1.1 christos ret; \ 2749 1.1 christos }) 2750 1.1 christos 2751 1.1.1.2 christos /* Write immediate to instructions. */ 2752 1.1.1.2 christos 2753 1.1 christos static bfd_reloc_status_type 2754 1.1 christos loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela *rel, 2755 1.1 christos const asection *input_section ATTRIBUTE_UNUSED, 2756 1.1 christos reloc_howto_type *howto, bfd *input_bfd, 2757 1.1 christos bfd_byte *contents, bfd_vma reloc_val) 2758 1.1 christos { 2759 1.1.1.2 christos /* Adjust the immediate based on alignment and 2760 1.1.1.2 christos its position in the instruction. */ 2761 1.1.1.2 christos if (!loongarch_adjust_reloc_bitsfield (input_bfd, howto, &reloc_val)) 2762 1.1 christos return bfd_reloc_overflow; 2763 1.1 christos 2764 1.1.1.2 christos int bits = bfd_get_reloc_size (howto) * 8; 2765 1.1.1.2 christos uint64_t insn = bfd_get (bits, input_bfd, contents + rel->r_offset); 2766 1.1.1.2 christos 2767 1.1.1.2 christos /* Write immediate to instruction. */ 2768 1.1.1.2 christos insn = (insn & ~howto->dst_mask) | (reloc_val & howto->dst_mask); 2769 1.1 christos 2770 1.1 christos bfd_put (bits, input_bfd, insn, contents + rel->r_offset); 2771 1.1 christos 2772 1.1 christos return bfd_reloc_ok; 2773 1.1 christos } 2774 1.1 christos 2775 1.1 christos static bfd_reloc_status_type 2776 1.1 christos perform_relocation (const Elf_Internal_Rela *rel, asection *input_section, 2777 1.1 christos reloc_howto_type *howto, bfd_vma value, 2778 1.1 christos bfd *input_bfd, bfd_byte *contents) 2779 1.1 christos { 2780 1.1 christos int64_t opr1, opr2, opr3; 2781 1.1 christos bfd_reloc_status_type r = bfd_reloc_ok; 2782 1.1 christos int bits = bfd_get_reloc_size (howto) * 8; 2783 1.1 christos 2784 1.1 christos switch (ELFNN_R_TYPE (rel->r_info)) 2785 1.1 christos { 2786 1.1 christos case R_LARCH_SOP_PUSH_PCREL: 2787 1.1 christos case R_LARCH_SOP_PUSH_ABSOLUTE: 2788 1.1 christos case R_LARCH_SOP_PUSH_GPREL: 2789 1.1 christos case R_LARCH_SOP_PUSH_TLS_TPREL: 2790 1.1 christos case R_LARCH_SOP_PUSH_TLS_GOT: 2791 1.1 christos case R_LARCH_SOP_PUSH_TLS_GD: 2792 1.1 christos case R_LARCH_SOP_PUSH_PLT_PCREL: 2793 1.1 christos r = loongarch_push (value); 2794 1.1 christos break; 2795 1.1 christos 2796 1.1 christos case R_LARCH_SOP_PUSH_DUP: 2797 1.1 christos r = loongarch_pop (&opr1); 2798 1.1 christos if (r == bfd_reloc_ok) 2799 1.1 christos { 2800 1.1 christos r = loongarch_push (opr1); 2801 1.1 christos if (r == bfd_reloc_ok) 2802 1.1 christos r = loongarch_push (opr1); 2803 1.1 christos } 2804 1.1 christos break; 2805 1.1 christos 2806 1.1 christos case R_LARCH_SOP_ASSERT: 2807 1.1 christos r = loongarch_pop (&opr1); 2808 1.1 christos if (r != bfd_reloc_ok || !opr1) 2809 1.1 christos r = bfd_reloc_notsupported; 2810 1.1 christos break; 2811 1.1 christos 2812 1.1 christos case R_LARCH_SOP_NOT: 2813 1.1 christos r = loongarch_pop (&opr1); 2814 1.1 christos if (r == bfd_reloc_ok) 2815 1.1 christos r = loongarch_push (!opr1); 2816 1.1 christos break; 2817 1.1 christos 2818 1.1 christos case R_LARCH_SOP_SUB: 2819 1.1 christos r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 - opr2); 2820 1.1 christos break; 2821 1.1 christos 2822 1.1 christos case R_LARCH_SOP_SL: 2823 1.1 christos r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 << opr2); 2824 1.1 christos break; 2825 1.1 christos 2826 1.1 christos case R_LARCH_SOP_SR: 2827 1.1 christos r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 >> opr2); 2828 1.1 christos break; 2829 1.1 christos 2830 1.1 christos case R_LARCH_SOP_AND: 2831 1.1 christos r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 & opr2); 2832 1.1 christos break; 2833 1.1 christos 2834 1.1 christos case R_LARCH_SOP_ADD: 2835 1.1 christos r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 + opr2); 2836 1.1 christos break; 2837 1.1 christos 2838 1.1 christos case R_LARCH_SOP_IF_ELSE: 2839 1.1 christos r = loongarch_pop (&opr3); 2840 1.1 christos if (r == bfd_reloc_ok) 2841 1.1 christos { 2842 1.1 christos r = loongarch_pop (&opr2); 2843 1.1 christos if (r == bfd_reloc_ok) 2844 1.1 christos { 2845 1.1 christos r = loongarch_pop (&opr1); 2846 1.1 christos if (r == bfd_reloc_ok) 2847 1.1 christos r = loongarch_push (opr1 ? opr2 : opr3); 2848 1.1 christos } 2849 1.1 christos } 2850 1.1 christos break; 2851 1.1 christos 2852 1.1 christos case R_LARCH_SOP_POP_32_S_10_5: 2853 1.1 christos case R_LARCH_SOP_POP_32_S_10_12: 2854 1.1 christos case R_LARCH_SOP_POP_32_S_10_16: 2855 1.1 christos case R_LARCH_SOP_POP_32_S_10_16_S2: 2856 1.1.1.2 christos case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: 2857 1.1.1.2 christos case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: 2858 1.1 christos case R_LARCH_SOP_POP_32_S_5_20: 2859 1.1 christos case R_LARCH_SOP_POP_32_U_10_12: 2860 1.1 christos case R_LARCH_SOP_POP_32_U: 2861 1.1 christos r = loongarch_pop (&opr1); 2862 1.1 christos if (r != bfd_reloc_ok) 2863 1.1 christos break; 2864 1.1 christos r = loongarch_check_offset (rel, input_section); 2865 1.1 christos if (r != bfd_reloc_ok) 2866 1.1 christos break; 2867 1.1 christos 2868 1.1 christos r = loongarch_reloc_rewrite_imm_insn (rel, input_section, 2869 1.1 christos howto, input_bfd, 2870 1.1 christos contents, (bfd_vma)opr1); 2871 1.1 christos break; 2872 1.1 christos 2873 1.1.1.2 christos case R_LARCH_TLS_DTPREL32: 2874 1.1.1.2 christos case R_LARCH_32: 2875 1.1.1.2 christos case R_LARCH_TLS_DTPREL64: 2876 1.1.1.2 christos case R_LARCH_64: 2877 1.1.1.2 christos r = loongarch_check_offset (rel, input_section); 2878 1.1.1.2 christos if (r != bfd_reloc_ok) 2879 1.1.1.2 christos break; 2880 1.1 christos 2881 1.1.1.2 christos bfd_put (bits, input_bfd, value, contents + rel->r_offset); 2882 1.1.1.2 christos break; 2883 1.1 christos 2884 1.1.1.2 christos /* LoongArch only has add/sub reloc pair, not has set/sub reloc pair. 2885 1.1.1.2 christos Because set/sub reloc pair not support multi-thread. While add/sub 2886 1.1.1.2 christos reloc pair process order not affect the final result. 2887 1.1.1.2 christos 2888 1.1.1.2 christos For add/sub reloc, the original value will be involved in the 2889 1.1.1.2 christos calculation. In order not to add/sub extra value, we write 0 to symbol 2890 1.1.1.2 christos address at assembly time. 2891 1.1.1.2 christos 2892 1.1.1.2 christos add/sub reloc bits determined by the value after symbol subtraction, 2893 1.1.1.2 christos not symbol value. 2894 1.1.1.2 christos 2895 1.1.1.2 christos add/sub reloc save part of the symbol value, so we only need to 2896 1.1.1.2 christos save howto->dst_mask bits. */ 2897 1.1.1.2 christos case R_LARCH_ADD6: 2898 1.1.1.2 christos case R_LARCH_SUB6: 2899 1.1 christos { 2900 1.1.1.2 christos bfd_vma word = bfd_get (howto->bitsize, input_bfd, 2901 1.1.1.2 christos contents + rel->r_offset); 2902 1.1.1.2 christos word = (word & ~howto->dst_mask) | (value & howto->dst_mask); 2903 1.1.1.2 christos bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset); 2904 1.1.1.2 christos r = bfd_reloc_ok; 2905 1.1 christos break; 2906 1.1 christos } 2907 1.1 christos 2908 1.1.1.2 christos /* Not need to read the original value, just write the new value. */ 2909 1.1 christos case R_LARCH_ADD8: 2910 1.1 christos case R_LARCH_ADD16: 2911 1.1 christos case R_LARCH_ADD24: 2912 1.1 christos case R_LARCH_ADD32: 2913 1.1 christos case R_LARCH_ADD64: 2914 1.1 christos case R_LARCH_SUB8: 2915 1.1 christos case R_LARCH_SUB16: 2916 1.1 christos case R_LARCH_SUB24: 2917 1.1 christos case R_LARCH_SUB32: 2918 1.1 christos case R_LARCH_SUB64: 2919 1.1.1.2 christos { 2920 1.1.1.2 christos /* Because add/sub reloc is processed separately, 2921 1.1.1.2 christos so the high bits is invalid. */ 2922 1.1.1.2 christos bfd_vma word = value & howto->dst_mask; 2923 1.1.1.2 christos bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset); 2924 1.1.1.2 christos r = bfd_reloc_ok; 2925 1.1.1.2 christos break; 2926 1.1.1.2 christos } 2927 1.1.1.2 christos 2928 1.1.1.2 christos case R_LARCH_ADD_ULEB128: 2929 1.1.1.2 christos case R_LARCH_SUB_ULEB128: 2930 1.1.1.2 christos { 2931 1.1.1.2 christos unsigned int len = 0; 2932 1.1.1.2 christos /* Before write uleb128, first read it to get it's length. */ 2933 1.1.1.2 christos _bfd_read_unsigned_leb128 (input_bfd, contents + rel->r_offset, &len); 2934 1.1.1.2 christos loongarch_write_unsigned_leb128 (contents + rel->r_offset, len, value); 2935 1.1.1.2 christos r = bfd_reloc_ok; 2936 1.1.1.2 christos break; 2937 1.1.1.2 christos } 2938 1.1.1.2 christos 2939 1.1.1.2 christos /* For eh_frame and debug info. */ 2940 1.1.1.2 christos case R_LARCH_32_PCREL: 2941 1.1.1.2 christos case R_LARCH_64_PCREL: 2942 1.1.1.2 christos { 2943 1.1.1.2 christos value -= sec_addr (input_section) + rel->r_offset; 2944 1.1.1.2 christos value += rel->r_addend; 2945 1.1.1.3 christos /* Check overflow. */ 2946 1.1.1.3 christos if (ELFNN_R_TYPE (rel->r_info) == R_LARCH_32_PCREL) 2947 1.1.1.3 christos { 2948 1.1.1.3 christos r = loongarch_reloc_rewrite_imm_insn (rel, input_section, 2949 1.1.1.3 christos howto, input_bfd, 2950 1.1.1.3 christos contents, value); 2951 1.1.1.3 christos } 2952 1.1.1.3 christos else 2953 1.1.1.3 christos { 2954 1.1.1.3 christos bfd_vma word = bfd_get (howto->bitsize, input_bfd, 2955 1.1.1.3 christos contents + rel->r_offset); 2956 1.1.1.3 christos word = (word & ~howto->dst_mask) | (value & howto->dst_mask); 2957 1.1.1.3 christos bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset); 2958 1.1.1.3 christos r = bfd_reloc_ok; 2959 1.1.1.3 christos } 2960 1.1.1.2 christos break; 2961 1.1.1.2 christos } 2962 1.1.1.2 christos 2963 1.1.1.2 christos /* New reloc type. 2964 1.1.1.2 christos R_LARCH_B16 ~ R_LARCH_TLS_GD_HI20. */ 2965 1.1.1.2 christos case R_LARCH_B16: 2966 1.1.1.2 christos case R_LARCH_B21: 2967 1.1.1.2 christos case R_LARCH_B26: 2968 1.1.1.2 christos case R_LARCH_ABS_HI20: 2969 1.1.1.2 christos case R_LARCH_ABS_LO12: 2970 1.1.1.2 christos case R_LARCH_ABS64_LO20: 2971 1.1.1.2 christos case R_LARCH_ABS64_HI12: 2972 1.1.1.2 christos case R_LARCH_PCALA_HI20: 2973 1.1.1.2 christos case R_LARCH_PCALA_LO12: 2974 1.1.1.2 christos case R_LARCH_PCALA64_LO20: 2975 1.1.1.2 christos case R_LARCH_PCALA64_HI12: 2976 1.1.1.2 christos case R_LARCH_GOT_PC_HI20: 2977 1.1.1.2 christos case R_LARCH_GOT_PC_LO12: 2978 1.1.1.2 christos case R_LARCH_GOT64_PC_LO20: 2979 1.1.1.2 christos case R_LARCH_GOT64_PC_HI12: 2980 1.1.1.2 christos case R_LARCH_GOT_HI20: 2981 1.1.1.2 christos case R_LARCH_GOT_LO12: 2982 1.1.1.2 christos case R_LARCH_GOT64_LO20: 2983 1.1.1.2 christos case R_LARCH_GOT64_HI12: 2984 1.1.1.2 christos case R_LARCH_TLS_LE_HI20: 2985 1.1.1.2 christos case R_LARCH_TLS_LE_LO12: 2986 1.1.1.2 christos case R_LARCH_TLS_LE_HI20_R: 2987 1.1.1.2 christos case R_LARCH_TLS_LE_LO12_R: 2988 1.1.1.2 christos case R_LARCH_TLS_LE64_LO20: 2989 1.1.1.2 christos case R_LARCH_TLS_LE64_HI12: 2990 1.1.1.2 christos case R_LARCH_TLS_IE_PC_HI20: 2991 1.1.1.2 christos case R_LARCH_TLS_IE_PC_LO12: 2992 1.1.1.2 christos case R_LARCH_TLS_IE64_PC_LO20: 2993 1.1.1.2 christos case R_LARCH_TLS_IE64_PC_HI12: 2994 1.1.1.2 christos case R_LARCH_TLS_IE_HI20: 2995 1.1.1.2 christos case R_LARCH_TLS_IE_LO12: 2996 1.1.1.2 christos case R_LARCH_TLS_IE64_LO20: 2997 1.1.1.2 christos case R_LARCH_TLS_IE64_HI12: 2998 1.1.1.2 christos case R_LARCH_TLS_LD_PC_HI20: 2999 1.1.1.2 christos case R_LARCH_TLS_LD_HI20: 3000 1.1.1.2 christos case R_LARCH_TLS_GD_PC_HI20: 3001 1.1.1.2 christos case R_LARCH_TLS_GD_HI20: 3002 1.1.1.2 christos case R_LARCH_PCREL20_S2: 3003 1.1.1.2 christos case R_LARCH_CALL36: 3004 1.1.1.2 christos case R_LARCH_TLS_DESC_PC_HI20: 3005 1.1.1.2 christos case R_LARCH_TLS_DESC_PC_LO12: 3006 1.1.1.2 christos case R_LARCH_TLS_DESC64_PC_LO20: 3007 1.1.1.2 christos case R_LARCH_TLS_DESC64_PC_HI12: 3008 1.1.1.2 christos case R_LARCH_TLS_DESC_HI20: 3009 1.1.1.2 christos case R_LARCH_TLS_DESC_LO12: 3010 1.1.1.2 christos case R_LARCH_TLS_DESC64_LO20: 3011 1.1.1.2 christos case R_LARCH_TLS_DESC64_HI12: 3012 1.1.1.2 christos case R_LARCH_TLS_LD_PCREL20_S2: 3013 1.1.1.2 christos case R_LARCH_TLS_GD_PCREL20_S2: 3014 1.1.1.2 christos case R_LARCH_TLS_DESC_PCREL20_S2: 3015 1.1 christos r = loongarch_check_offset (rel, input_section); 3016 1.1 christos if (r != bfd_reloc_ok) 3017 1.1 christos break; 3018 1.1 christos 3019 1.1.1.2 christos r = loongarch_reloc_rewrite_imm_insn (rel, input_section, 3020 1.1.1.2 christos howto, input_bfd, 3021 1.1.1.2 christos contents, value); 3022 1.1.1.2 christos break; 3023 1.1.1.2 christos 3024 1.1.1.2 christos case R_LARCH_TLS_DESC_LD: 3025 1.1.1.2 christos case R_LARCH_TLS_DESC_CALL: 3026 1.1.1.2 christos r = bfd_reloc_ok; 3027 1.1.1.2 christos break; 3028 1.1.1.2 christos 3029 1.1.1.2 christos case R_LARCH_RELAX: 3030 1.1.1.2 christos case R_LARCH_TLS_LE_ADD_R: 3031 1.1 christos break; 3032 1.1 christos 3033 1.1 christos default: 3034 1.1 christos r = bfd_reloc_notsupported; 3035 1.1 christos } 3036 1.1 christos return r; 3037 1.1 christos } 3038 1.1 christos 3039 1.1 christos #define LARCH_RECENT_RELOC_QUEUE_LENGTH 72 3040 1.1 christos static struct 3041 1.1 christos { 3042 1.1 christos bfd *bfd; 3043 1.1 christos asection *section; 3044 1.1 christos bfd_vma r_offset; 3045 1.1 christos int r_type; 3046 1.1 christos bfd_vma relocation; 3047 1.1 christos Elf_Internal_Sym *sym; 3048 1.1 christos struct elf_link_hash_entry *h; 3049 1.1 christos bfd_vma addend; 3050 1.1 christos int64_t top_then; 3051 1.1 christos } larch_reloc_queue[LARCH_RECENT_RELOC_QUEUE_LENGTH]; 3052 1.1 christos static size_t larch_reloc_queue_head = 0; 3053 1.1 christos static size_t larch_reloc_queue_tail = 0; 3054 1.1 christos 3055 1.1 christos static const char * 3056 1.1 christos loongarch_sym_name (bfd *input_bfd, struct elf_link_hash_entry *h, 3057 1.1 christos Elf_Internal_Sym *sym) 3058 1.1 christos { 3059 1.1 christos const char *ret = NULL; 3060 1.1 christos if (sym) 3061 1.1 christos ret = bfd_elf_string_from_elf_section (input_bfd, 3062 1.1 christos elf_symtab_hdr (input_bfd).sh_link, 3063 1.1 christos sym->st_name); 3064 1.1 christos else if (h) 3065 1.1 christos ret = h->root.root.string; 3066 1.1 christos 3067 1.1 christos if (ret == NULL || *ret == '\0') 3068 1.1 christos ret = "<nameless>"; 3069 1.1 christos return ret; 3070 1.1 christos } 3071 1.1 christos 3072 1.1 christos static void 3073 1.1 christos loongarch_record_one_reloc (bfd *abfd, asection *section, int r_type, 3074 1.1 christos bfd_vma r_offset, Elf_Internal_Sym *sym, 3075 1.1 christos struct elf_link_hash_entry *h, bfd_vma addend) 3076 1.1 christos { 3077 1.1 christos if ((larch_reloc_queue_head == 0 3078 1.1 christos && larch_reloc_queue_tail == LARCH_RECENT_RELOC_QUEUE_LENGTH - 1) 3079 1.1 christos || larch_reloc_queue_head == larch_reloc_queue_tail + 1) 3080 1.1 christos larch_reloc_queue_head = 3081 1.1 christos (larch_reloc_queue_head + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH; 3082 1.1 christos larch_reloc_queue[larch_reloc_queue_tail].bfd = abfd; 3083 1.1 christos larch_reloc_queue[larch_reloc_queue_tail].section = section; 3084 1.1 christos larch_reloc_queue[larch_reloc_queue_tail].r_offset = r_offset; 3085 1.1 christos larch_reloc_queue[larch_reloc_queue_tail].r_type = r_type; 3086 1.1 christos larch_reloc_queue[larch_reloc_queue_tail].sym = sym; 3087 1.1 christos larch_reloc_queue[larch_reloc_queue_tail].h = h; 3088 1.1 christos larch_reloc_queue[larch_reloc_queue_tail].addend = addend; 3089 1.1 christos loongarch_top (&larch_reloc_queue[larch_reloc_queue_tail].top_then); 3090 1.1 christos larch_reloc_queue_tail = 3091 1.1 christos (larch_reloc_queue_tail + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH; 3092 1.1 christos } 3093 1.1 christos 3094 1.1 christos static void 3095 1.1 christos loongarch_dump_reloc_record (void (*p) (const char *fmt, ...)) 3096 1.1 christos { 3097 1.1 christos size_t i = larch_reloc_queue_head; 3098 1.1 christos bfd *a_bfd = NULL; 3099 1.1 christos asection *section = NULL; 3100 1.1 christos bfd_vma r_offset = 0; 3101 1.1 christos int inited = 0; 3102 1.1 christos p ("Dump relocate record:\n"); 3103 1.1 christos p ("stack top\t\trelocation name\t\tsymbol"); 3104 1.1 christos while (i != larch_reloc_queue_tail) 3105 1.1 christos { 3106 1.1 christos if (a_bfd != larch_reloc_queue[i].bfd 3107 1.1 christos || section != larch_reloc_queue[i].section 3108 1.1 christos || r_offset != larch_reloc_queue[i].r_offset) 3109 1.1 christos { 3110 1.1 christos a_bfd = larch_reloc_queue[i].bfd; 3111 1.1 christos section = larch_reloc_queue[i].section; 3112 1.1 christos r_offset = larch_reloc_queue[i].r_offset; 3113 1.1 christos p ("\nat %pB(%pA+0x%v):\n", larch_reloc_queue[i].bfd, 3114 1.1 christos larch_reloc_queue[i].section, larch_reloc_queue[i].r_offset); 3115 1.1 christos } 3116 1.1 christos 3117 1.1 christos if (!inited) 3118 1.1 christos inited = 1, p ("...\n"); 3119 1.1 christos 3120 1.1 christos reloc_howto_type *howto = 3121 1.1 christos loongarch_elf_rtype_to_howto (larch_reloc_queue[i].bfd, 3122 1.1 christos larch_reloc_queue[i].r_type); 3123 1.1 christos p ("0x%V %s\t`%s'", (bfd_vma) larch_reloc_queue[i].top_then, 3124 1.1 christos howto ? howto->name : "<unknown reloc>", 3125 1.1 christos loongarch_sym_name (larch_reloc_queue[i].bfd, larch_reloc_queue[i].h, 3126 1.1 christos larch_reloc_queue[i].sym)); 3127 1.1 christos 3128 1.1 christos long addend = larch_reloc_queue[i].addend; 3129 1.1 christos if (addend < 0) 3130 1.1 christos p (" - %ld", -addend); 3131 1.1 christos else if (0 < addend) 3132 1.1 christos p (" + %ld(0x%v)", addend, larch_reloc_queue[i].addend); 3133 1.1 christos 3134 1.1 christos p ("\n"); 3135 1.1 christos i = (i + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH; 3136 1.1 christos } 3137 1.1 christos p ("\n" 3138 1.1 christos "-- Record dump end --\n\n"); 3139 1.1 christos } 3140 1.1 christos 3141 1.1 christos static bool 3142 1.1 christos loongarch_reloc_is_fatal (struct bfd_link_info *info, 3143 1.1 christos bfd *input_bfd, 3144 1.1 christos asection *input_section, 3145 1.1 christos Elf_Internal_Rela *rel, 3146 1.1 christos reloc_howto_type *howto, 3147 1.1 christos bfd_reloc_status_type rtype, 3148 1.1 christos bool is_undefweak, 3149 1.1 christos const char *name, 3150 1.1 christos const char *msg) 3151 1.1 christos { 3152 1.1 christos bool fatal = true; 3153 1.1 christos switch (rtype) 3154 1.1 christos { 3155 1.1 christos /* 'dangerous' means we do it but can't promise it's ok 3156 1.1 christos 'unsupport' means out of ability of relocation type 3157 1.1 christos 'undefined' means we can't deal with the undefined symbol. */ 3158 1.1 christos case bfd_reloc_undefined: 3159 1.1 christos info->callbacks->undefined_symbol (info, name, input_bfd, input_section, 3160 1.1 christos rel->r_offset, true); 3161 1.1 christos info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n", 3162 1.1 christos input_bfd, input_section, rel->r_offset, 3163 1.1 christos howto->name, 3164 1.1 christos is_undefweak ? "[undefweak] " : "", name, msg); 3165 1.1 christos break; 3166 1.1 christos case bfd_reloc_dangerous: 3167 1.1 christos info->callbacks->info ("%pB(%pA+0x%v): warning: %s against %s`%s':\n%s\n", 3168 1.1 christos input_bfd, input_section, rel->r_offset, 3169 1.1 christos howto->name, 3170 1.1 christos is_undefweak ? "[undefweak] " : "", name, msg); 3171 1.1 christos fatal = false; 3172 1.1 christos break; 3173 1.1 christos case bfd_reloc_notsupported: 3174 1.1 christos info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n", 3175 1.1 christos input_bfd, input_section, rel->r_offset, 3176 1.1 christos howto->name, 3177 1.1 christos is_undefweak ? "[undefweak] " : "", name, msg); 3178 1.1 christos break; 3179 1.1 christos default: 3180 1.1 christos break; 3181 1.1 christos } 3182 1.1 christos return fatal; 3183 1.1 christos } 3184 1.1 christos 3185 1.1.1.2 christos /* If lo12 immediate > 0x7ff, because sign-extend caused by addi.d/ld.d, 3186 1.1.1.2 christos hi20 immediate need to add 0x1. 3187 1.1.1.2 christos For example: pc 0x120000000, symbol 0x120000812 3188 1.1.1.2 christos lo12 immediate is 0x812, 0x120000812 & 0xfff = 0x812 3189 1.1.1.2 christos hi20 immediate is 1, because lo12 imm > 0x7ff, symbol need to add 0x1000 3190 1.1.1.2 christos (((0x120000812 + 0x1000) & ~0xfff) - (0x120000000 & ~0xfff)) >> 12 = 0x1 3191 1.1.1.2 christos 3192 1.1.1.2 christos At run: 3193 1.1.1.2 christos pcalau12i $t0, hi20 (0x1) 3194 1.1.1.2 christos $t0 = 0x120000000 + (0x1 << 12) = 0x120001000 3195 1.1.1.2 christos addi.d $t0, $t0, lo12 (0x812) 3196 1.1.1.2 christos $t0 = 0x120001000 + 0xfffffffffffff812 (-(0x1000 - 0x812) = -0x7ee) 3197 1.1.1.2 christos = 0x120001000 - 0x7ee (0x1000 - 0x7ee = 0x812) 3198 1.1.1.2 christos = 0x120000812 3199 1.1.1.2 christos Without hi20 add 0x1000, the result 0x120000000 - 0x7ee = 0x11ffff812 is 3200 1.1.1.2 christos error. 3201 1.1.1.2 christos 0x1000 + sign-extend-to64(0x8xx) = 0x8xx. */ 3202 1.1.1.2 christos #define RELOCATE_CALC_PC32_HI20(relocation, pc) \ 3203 1.1.1.2 christos ({ \ 3204 1.1.1.2 christos bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \ 3205 1.1.1.2 christos relocation = (relocation & ~(bfd_vma)0xfff) \ 3206 1.1.1.2 christos - (pc & ~(bfd_vma)0xfff); \ 3207 1.1.1.2 christos if (__lo > 0x7ff) \ 3208 1.1.1.2 christos relocation += 0x1000; \ 3209 1.1.1.2 christos }) 3210 1.1.1.2 christos 3211 1.1.1.2 christos /* Handle problems caused by symbol extensions in TLS LE, The processing 3212 1.1.1.2 christos is similar to the macro RELOCATE_CALC_PC32_HI20 method. */ 3213 1.1.1.2 christos #define RELOCATE_TLS_TP32_HI20(relocation) \ 3214 1.1.1.2 christos ({ \ 3215 1.1.1.2 christos bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \ 3216 1.1.1.2 christos if (__lo > 0x7ff) \ 3217 1.1.1.2 christos relocation += 0x800; \ 3218 1.1.1.2 christos relocation = relocation & ~(bfd_vma)0xfff; \ 3219 1.1.1.2 christos }) 3220 1.1.1.2 christos 3221 1.1.1.2 christos /* For example: pc is 0x11000010000100, symbol is 0x1812348ffff812 3222 1.1.1.2 christos offset = (0x1812348ffff812 & ~0xfff) - (0x11000010000100 & ~0xfff) 3223 1.1.1.2 christos = 0x712347ffff000 3224 1.1.1.2 christos lo12: 0x1812348ffff812 & 0xfff = 0x812 3225 1.1.1.2 christos hi20: 0x7ffff + 0x1(lo12 > 0x7ff) = 0x80000 3226 1.1.1.2 christos lo20: 0x71234 - 0x1(lo12 > 0x7ff) + 0x1(hi20 > 0x7ffff) 3227 1.1.1.2 christos hi12: 0x0 3228 1.1.1.2 christos 3229 1.1.1.2 christos pcalau12i $t1, hi20 (0x80000) 3230 1.1.1.2 christos $t1 = 0x11000010000100 + sign-extend(0x80000 << 12) 3231 1.1.1.2 christos = 0x11000010000100 + 0xffffffff80000000 3232 1.1.1.2 christos = 0x10ffff90000000 3233 1.1.1.2 christos addi.d $t0, $zero, lo12 (0x812) 3234 1.1.1.2 christos $t0 = 0xfffffffffffff812 (if lo12 > 0x7ff, because sign-extend, 3235 1.1.1.2 christos lo20 need to sub 0x1) 3236 1.1.1.2 christos lu32i.d $t0, lo20 (0x71234) 3237 1.1.1.2 christos $t0 = {0x71234, 0xfffff812} 3238 1.1.1.2 christos = 0x71234fffff812 3239 1.1.1.2 christos lu52i.d $t0, hi12 (0x0) 3240 1.1.1.2 christos $t0 = {0x0, 0x71234fffff812} 3241 1.1.1.2 christos = 0x71234fffff812 3242 1.1.1.2 christos add.d $t1, $t1, $t0 3243 1.1.1.2 christos $t1 = 0x10ffff90000000 + 0x71234fffff812 3244 1.1.1.2 christos = 0x1812348ffff812. */ 3245 1.1.1.2 christos #define RELOCATE_CALC_PC64_HI32(relocation, pc) \ 3246 1.1.1.2 christos ({ \ 3247 1.1.1.2 christos bfd_vma __lo = (relocation & (bfd_vma)0xfff); \ 3248 1.1.1.2 christos relocation = (relocation & ~(bfd_vma)0xfff) \ 3249 1.1.1.2 christos - ((pc) & ~(bfd_vma)0xfff); \ 3250 1.1.1.2 christos if (__lo > 0x7ff) \ 3251 1.1.1.2 christos relocation += (0x1000 - 0x100000000); \ 3252 1.1.1.2 christos if (relocation & 0x80000000) \ 3253 1.1.1.2 christos relocation += 0x100000000; \ 3254 1.1.1.2 christos }) 3255 1.1.1.2 christos 3256 1.1 christos 3257 1.1.1.3 christos /* Compute the tp/dtp offset of a tls symbol. 3258 1.1.1.3 christos It is dtp offset in dynamic tls model (gd/ld) and tp 3259 1.1.1.3 christos offset in static tls model (ie/le). Both offsets are 3260 1.1.1.3 christos calculated the same way on LoongArch, so the same 3261 1.1.1.3 christos function is used. */ 3262 1.1.1.3 christos static bfd_vma 3263 1.1.1.3 christos tlsoff (struct bfd_link_info *info, bfd_vma addr) 3264 1.1.1.3 christos { 3265 1.1.1.3 christos /* If tls_sec is NULL, we should have signalled an error already. */ 3266 1.1.1.3 christos if (elf_hash_table (info)->tls_sec == NULL) 3267 1.1.1.3 christos return 0; 3268 1.1.1.3 christos return addr - elf_hash_table (info)->tls_sec->vma; 3269 1.1.1.2 christos } 3270 1.1 christos 3271 1.1 christos static int 3272 1.1 christos loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, 3273 1.1 christos bfd *input_bfd, asection *input_section, 3274 1.1 christos bfd_byte *contents, Elf_Internal_Rela *relocs, 3275 1.1 christos Elf_Internal_Sym *local_syms, 3276 1.1 christos asection **local_sections) 3277 1.1 christos { 3278 1.1 christos Elf_Internal_Rela *rel; 3279 1.1 christos Elf_Internal_Rela *relend; 3280 1.1 christos bool fatal = false; 3281 1.1 christos asection *sreloc = elf_section_data (input_section)->sreloc; 3282 1.1 christos struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info); 3283 1.1 christos Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd); 3284 1.1 christos struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd); 3285 1.1 christos bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd); 3286 1.1 christos bool is_pic = bfd_link_pic (info); 3287 1.1 christos bool is_dyn = elf_hash_table (info)->dynamic_sections_created; 3288 1.1 christos asection *plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt; 3289 1.1 christos asection *got = htab->elf.sgot; 3290 1.1 christos 3291 1.1 christos relend = relocs + input_section->reloc_count; 3292 1.1 christos for (rel = relocs; rel < relend; rel++) 3293 1.1 christos { 3294 1.1.1.2 christos unsigned int r_type = ELFNN_R_TYPE (rel->r_info); 3295 1.1 christos unsigned long r_symndx = ELFNN_R_SYM (rel->r_info); 3296 1.1 christos bfd_vma pc = sec_addr (input_section) + rel->r_offset; 3297 1.1 christos reloc_howto_type *howto = NULL; 3298 1.1 christos asection *sec = NULL; 3299 1.1 christos Elf_Internal_Sym *sym = NULL; 3300 1.1 christos struct elf_link_hash_entry *h = NULL; 3301 1.1 christos const char *name; 3302 1.1 christos bfd_reloc_status_type r = bfd_reloc_ok; 3303 1.1.1.2 christos bool is_ie, is_desc, is_undefweak, unresolved_reloc, defined_local; 3304 1.1 christos bool resolved_local, resolved_dynly, resolved_to_const; 3305 1.1 christos char tls_type; 3306 1.1.1.2 christos bfd_vma relocation, off, ie_off, desc_off; 3307 1.1 christos int i, j; 3308 1.1.1.3 christos bool resolve_pcrel_undef_weak = false; 3309 1.1 christos 3310 1.1.1.3 christos /* When an unrecognized relocation is encountered, which usually 3311 1.1.1.3 christos occurs when using a newer assembler but an older linker, an error 3312 1.1.1.3 christos should be reported instead of continuing to the next relocation. */ 3313 1.1 christos howto = loongarch_elf_rtype_to_howto (input_bfd, r_type); 3314 1.1.1.3 christos if (howto == NULL) 3315 1.1.1.3 christos return _bfd_unrecognized_reloc (input_bfd, input_section, r_type); 3316 1.1.1.3 christos 3317 1.1.1.3 christos if (r_type == R_LARCH_GNU_VTINHERIT || r_type == R_LARCH_GNU_VTENTRY) 3318 1.1 christos continue; 3319 1.1 christos 3320 1.1 christos /* This is a final link. */ 3321 1.1 christos if (r_symndx < symtab_hdr->sh_info) 3322 1.1 christos { 3323 1.1 christos is_undefweak = false; 3324 1.1 christos unresolved_reloc = false; 3325 1.1 christos sym = local_syms + r_symndx; 3326 1.1 christos sec = local_sections[r_symndx]; 3327 1.1 christos relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); 3328 1.1 christos 3329 1.1 christos /* Relocate against local STT_GNU_IFUNC symbol. */ 3330 1.1 christos if (!bfd_link_relocatable (info) 3331 1.1 christos && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC) 3332 1.1 christos { 3333 1.1 christos h = elfNN_loongarch_get_local_sym_hash (htab, input_bfd, rel, 3334 1.1 christos false); 3335 1.1 christos if (h == NULL) 3336 1.1 christos abort (); 3337 1.1 christos 3338 1.1 christos /* Set STT_GNU_IFUNC symbol value. */ 3339 1.1 christos h->root.u.def.value = sym->st_value; 3340 1.1 christos h->root.u.def.section = sec; 3341 1.1 christos } 3342 1.1 christos defined_local = true; 3343 1.1 christos resolved_local = true; 3344 1.1 christos resolved_dynly = false; 3345 1.1 christos resolved_to_const = false; 3346 1.1.1.2 christos 3347 1.1.1.2 christos /* Calc in funtion elf_link_input_bfd, 3348 1.1.1.2 christos * if #define elf_backend_rela_normal to 1. */ 3349 1.1 christos if (bfd_link_relocatable (info) 3350 1.1 christos && ELF_ST_TYPE (sym->st_info) == STT_SECTION) 3351 1.1.1.2 christos continue; 3352 1.1 christos } 3353 1.1 christos else 3354 1.1 christos { 3355 1.1 christos bool warned, ignored; 3356 1.1 christos 3357 1.1 christos RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 3358 1.1 christos r_symndx, symtab_hdr, sym_hashes, 3359 1.1 christos h, sec, relocation, 3360 1.1 christos unresolved_reloc, warned, ignored); 3361 1.1 christos /* Here means symbol isn't local symbol only and 'h != NULL'. */ 3362 1.1 christos 3363 1.1 christos /* The 'unresolved_syms_in_objects' specify how to deal with undefined 3364 1.1 christos symbol. And 'dynamic_undefined_weak' specify what to do when 3365 1.1 christos meeting undefweak. */ 3366 1.1 christos 3367 1.1 christos if ((is_undefweak = h->root.type == bfd_link_hash_undefweak)) 3368 1.1 christos { 3369 1.1 christos defined_local = false; 3370 1.1 christos resolved_local = false; 3371 1.1 christos resolved_to_const = (!is_dyn || h->dynindx == -1 3372 1.1 christos || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)); 3373 1.1 christos resolved_dynly = !resolved_local && !resolved_to_const; 3374 1.1 christos } 3375 1.1 christos else if (warned) 3376 1.1 christos { 3377 1.1 christos /* Symbol undefined offen means failed already. I don't know why 3378 1.1 christos 'warned' here but I guess it want to continue relocating as if 3379 1.1 christos no error occures to find other errors as more as possible. */ 3380 1.1 christos 3381 1.1 christos /* To avoid generating warning messages about truncated 3382 1.1 christos relocations, set the relocation's address to be the same as 3383 1.1 christos the start of this section. */ 3384 1.1 christos relocation = (input_section->output_section 3385 1.1 christos ? input_section->output_section->vma 3386 1.1 christos : 0); 3387 1.1 christos 3388 1.1 christos defined_local = relocation != 0; 3389 1.1 christos resolved_local = defined_local; 3390 1.1 christos resolved_to_const = !resolved_local; 3391 1.1 christos resolved_dynly = false; 3392 1.1 christos } 3393 1.1 christos else 3394 1.1 christos { 3395 1.1 christos defined_local = !unresolved_reloc && !ignored; 3396 1.1 christos resolved_local = 3397 1.1.1.3 christos defined_local && LARCH_REF_LOCAL (info, h); 3398 1.1 christos resolved_dynly = !resolved_local; 3399 1.1 christos resolved_to_const = !resolved_local && !resolved_dynly; 3400 1.1 christos } 3401 1.1 christos } 3402 1.1 christos 3403 1.1 christos name = loongarch_sym_name (input_bfd, h, sym); 3404 1.1 christos 3405 1.1 christos if (sec != NULL && discarded_section (sec)) 3406 1.1 christos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, 3407 1.1 christos 1, relend, howto, 0, contents); 3408 1.1 christos 3409 1.1 christos if (bfd_link_relocatable (info)) 3410 1.1 christos continue; 3411 1.1 christos 3412 1.1 christos /* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols 3413 1.1 christos from removed linkonce sections, or sections discarded by a linker 3414 1.1 christos script. Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const. */ 3415 1.1.1.3 christos if (r_symndx == STN_UNDEF) 3416 1.1 christos { 3417 1.1 christos defined_local = false; 3418 1.1 christos resolved_local = false; 3419 1.1 christos resolved_dynly = false; 3420 1.1 christos resolved_to_const = true; 3421 1.1 christos } 3422 1.1 christos 3423 1.1.1.2 christos /* The ifunc reference generate plt. */ 3424 1.1 christos if (h && h->type == STT_GNU_IFUNC && h->plt.offset != MINUS_ONE) 3425 1.1 christos { 3426 1.1 christos defined_local = true; 3427 1.1 christos resolved_local = true; 3428 1.1 christos resolved_dynly = false; 3429 1.1 christos resolved_to_const = false; 3430 1.1 christos relocation = sec_addr (plt) + h->plt.offset; 3431 1.1 christos } 3432 1.1 christos 3433 1.1 christos unresolved_reloc = resolved_dynly; 3434 1.1 christos 3435 1.1 christos BFD_ASSERT (resolved_local + resolved_dynly + resolved_to_const == 1); 3436 1.1 christos 3437 1.1 christos /* BFD_ASSERT (!resolved_dynly || (h && h->dynindx != -1));. */ 3438 1.1 christos 3439 1.1 christos BFD_ASSERT (!resolved_local || defined_local); 3440 1.1 christos 3441 1.1.1.2 christos is_desc = false; 3442 1.1 christos is_ie = false; 3443 1.1 christos switch (r_type) 3444 1.1 christos { 3445 1.1 christos case R_LARCH_MARK_PCREL: 3446 1.1 christos case R_LARCH_MARK_LA: 3447 1.1 christos case R_LARCH_NONE: 3448 1.1 christos r = bfd_reloc_continue; 3449 1.1 christos unresolved_reloc = false; 3450 1.1 christos break; 3451 1.1 christos 3452 1.1 christos case R_LARCH_32: 3453 1.1 christos case R_LARCH_64: 3454 1.1 christos if (resolved_dynly || (is_pic && resolved_local)) 3455 1.1 christos { 3456 1.1 christos Elf_Internal_Rela outrel; 3457 1.1 christos 3458 1.1 christos /* When generating a shared object, these relocations are copied 3459 1.1 christos into the output file to be resolved at run time. */ 3460 1.1 christos 3461 1.1 christos outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, 3462 1.1 christos input_section, 3463 1.1 christos rel->r_offset); 3464 1.1 christos 3465 1.1 christos unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset) 3466 1.1 christos && (input_section->flags & SEC_ALLOC)); 3467 1.1 christos 3468 1.1 christos outrel.r_offset += sec_addr (input_section); 3469 1.1 christos 3470 1.1.1.2 christos /* A pointer point to a ifunc symbol. */ 3471 1.1.1.2 christos if (h && h->type == STT_GNU_IFUNC) 3472 1.1.1.2 christos { 3473 1.1.1.2 christos if (h->dynindx == -1) 3474 1.1.1.2 christos { 3475 1.1.1.2 christos outrel.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE); 3476 1.1.1.2 christos outrel.r_addend = (h->root.u.def.value 3477 1.1.1.2 christos + h->root.u.def.section->output_section->vma 3478 1.1.1.2 christos + h->root.u.def.section->output_offset); 3479 1.1.1.2 christos } 3480 1.1.1.2 christos else 3481 1.1.1.2 christos { 3482 1.1.1.2 christos outrel.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN); 3483 1.1.1.2 christos outrel.r_addend = 0; 3484 1.1.1.2 christos } 3485 1.1.1.2 christos 3486 1.1.1.3 christos if (LARCH_REF_LOCAL (info, h)) 3487 1.1.1.2 christos { 3488 1.1.1.2 christos 3489 1.1.1.2 christos if (htab->elf.splt != NULL) 3490 1.1.1.2 christos sreloc = htab->elf.srelgot; 3491 1.1.1.2 christos else 3492 1.1.1.2 christos sreloc = htab->elf.irelplt; 3493 1.1.1.2 christos } 3494 1.1 christos else 3495 1.1.1.2 christos { 3496 1.1.1.2 christos 3497 1.1.1.2 christos if (bfd_link_pic (info)) 3498 1.1.1.2 christos sreloc = htab->elf.irelifunc; 3499 1.1.1.2 christos else if (htab->elf.splt != NULL) 3500 1.1.1.2 christos sreloc = htab->elf.srelgot; 3501 1.1.1.2 christos else 3502 1.1.1.2 christos sreloc = htab->elf.irelplt; 3503 1.1.1.2 christos } 3504 1.1 christos } 3505 1.1 christos else if (resolved_dynly) 3506 1.1 christos { 3507 1.1.1.2 christos if (h->dynindx == -1) 3508 1.1.1.3 christos outrel.r_info = ELFNN_R_INFO (0, r_type); 3509 1.1.1.2 christos else 3510 1.1.1.2 christos outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type); 3511 1.1.1.2 christos 3512 1.1 christos outrel.r_addend = rel->r_addend; 3513 1.1 christos } 3514 1.1 christos else 3515 1.1 christos { 3516 1.1 christos outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE); 3517 1.1 christos outrel.r_addend = relocation + rel->r_addend; 3518 1.1 christos } 3519 1.1 christos 3520 1.1.1.3 christos /* No alloc space of func allocate_dynrelocs. 3521 1.1.1.3 christos No alloc space of invalid R_LARCH_32 in ELFCLASS64. */ 3522 1.1.1.2 christos if (unresolved_reloc 3523 1.1.1.3 christos && (ARCH_SIZE == 32 || r_type != R_LARCH_32) 3524 1.1.1.2 christos && !(h && (h->is_weakalias || !h->dyn_relocs))) 3525 1.1.1.3 christos { 3526 1.1.1.3 christos if (info->enable_dt_relr 3527 1.1.1.3 christos && (ELFNN_R_TYPE (outrel.r_info) == R_LARCH_RELATIVE) 3528 1.1.1.3 christos && input_section->alignment_power != 0 3529 1.1.1.3 christos && rel->r_offset % 2 == 0) 3530 1.1.1.3 christos /* Don't emit a relative relocation that is packed, 3531 1.1.1.3 christos only apply the addend (as if we are applying the 3532 1.1.1.3 christos original R_LARCH_NN reloc in a PDE). */ 3533 1.1.1.3 christos r = perform_relocation (rel, input_section, howto, 3534 1.1.1.3 christos relocation, input_bfd, 3535 1.1.1.3 christos contents); 3536 1.1.1.3 christos else 3537 1.1.1.3 christos loongarch_elf_append_rela (output_bfd, sreloc, 3538 1.1.1.3 christos &outrel); 3539 1.1.1.3 christos } 3540 1.1 christos } 3541 1.1 christos 3542 1.1 christos relocation += rel->r_addend; 3543 1.1 christos break; 3544 1.1 christos 3545 1.1.1.2 christos case R_LARCH_ADD6: 3546 1.1 christos case R_LARCH_ADD8: 3547 1.1 christos case R_LARCH_ADD16: 3548 1.1 christos case R_LARCH_ADD24: 3549 1.1 christos case R_LARCH_ADD32: 3550 1.1 christos case R_LARCH_ADD64: 3551 1.1.1.2 christos { 3552 1.1.1.2 christos bfd_vma old_value = bfd_get (howto->bitsize, input_bfd, 3553 1.1.1.2 christos contents + rel->r_offset); 3554 1.1.1.2 christos relocation = old_value + relocation + rel->r_addend; 3555 1.1.1.2 christos break; 3556 1.1.1.2 christos } 3557 1.1.1.2 christos 3558 1.1.1.2 christos case R_LARCH_SUB6: 3559 1.1 christos case R_LARCH_SUB8: 3560 1.1 christos case R_LARCH_SUB16: 3561 1.1 christos case R_LARCH_SUB24: 3562 1.1 christos case R_LARCH_SUB32: 3563 1.1 christos case R_LARCH_SUB64: 3564 1.1.1.2 christos { 3565 1.1.1.2 christos bfd_vma old_value = bfd_get (howto->bitsize, input_bfd, 3566 1.1.1.2 christos contents + rel->r_offset); 3567 1.1.1.2 christos relocation = old_value - relocation - rel->r_addend; 3568 1.1.1.2 christos break; 3569 1.1.1.2 christos } 3570 1.1.1.2 christos 3571 1.1.1.2 christos case R_LARCH_ADD_ULEB128: 3572 1.1.1.2 christos case R_LARCH_SUB_ULEB128: 3573 1.1.1.2 christos { 3574 1.1.1.2 christos /* Get the value and length of the uleb128 data. */ 3575 1.1.1.2 christos unsigned int len = 0; 3576 1.1.1.2 christos bfd_vma old_value = _bfd_read_unsigned_leb128 (input_bfd, 3577 1.1.1.2 christos contents + rel->r_offset, &len); 3578 1.1.1.2 christos 3579 1.1.1.2 christos if (R_LARCH_ADD_ULEB128 == ELFNN_R_TYPE (rel->r_info)) 3580 1.1.1.2 christos relocation = old_value + relocation + rel->r_addend; 3581 1.1.1.2 christos else if (R_LARCH_SUB_ULEB128 == ELFNN_R_TYPE (rel->r_info)) 3582 1.1.1.2 christos relocation = old_value - relocation - rel->r_addend; 3583 1.1.1.2 christos 3584 1.1.1.2 christos bfd_vma mask = (1 << (7 * len)) - 1; 3585 1.1.1.2 christos relocation &= mask; 3586 1.1.1.2 christos break; 3587 1.1.1.2 christos } 3588 1.1 christos 3589 1.1 christos case R_LARCH_TLS_DTPREL32: 3590 1.1 christos case R_LARCH_TLS_DTPREL64: 3591 1.1 christos if (resolved_dynly) 3592 1.1 christos { 3593 1.1 christos Elf_Internal_Rela outrel; 3594 1.1 christos 3595 1.1 christos outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, 3596 1.1 christos input_section, 3597 1.1 christos rel->r_offset); 3598 1.1 christos unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset) 3599 1.1 christos && (input_section->flags & SEC_ALLOC)); 3600 1.1 christos outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type); 3601 1.1 christos outrel.r_offset += sec_addr (input_section); 3602 1.1 christos outrel.r_addend = rel->r_addend; 3603 1.1 christos if (unresolved_reloc) 3604 1.1 christos loongarch_elf_append_rela (output_bfd, sreloc, &outrel); 3605 1.1 christos break; 3606 1.1 christos } 3607 1.1 christos 3608 1.1 christos if (resolved_to_const) 3609 1.1 christos fatal = loongarch_reloc_is_fatal (info, input_bfd, input_section, 3610 1.1 christos rel, howto, 3611 1.1 christos bfd_reloc_notsupported, 3612 1.1 christos is_undefweak, name, 3613 1.1 christos "Internal:"); 3614 1.1 christos if (resolved_local) 3615 1.1 christos { 3616 1.1 christos if (!elf_hash_table (info)->tls_sec) 3617 1.1 christos { 3618 1.1 christos fatal = loongarch_reloc_is_fatal (info, input_bfd, 3619 1.1 christos input_section, rel, howto, bfd_reloc_notsupported, 3620 1.1 christos is_undefweak, name, "TLS section not be created"); 3621 1.1 christos } 3622 1.1 christos else 3623 1.1.1.3 christos relocation = tlsoff (info, relocation); 3624 1.1 christos } 3625 1.1 christos else 3626 1.1 christos { 3627 1.1 christos fatal = loongarch_reloc_is_fatal (info, input_bfd, 3628 1.1 christos input_section, rel, howto, bfd_reloc_undefined, 3629 1.1 christos is_undefweak, name, 3630 1.1 christos "TLS LE just can be resolved local only."); 3631 1.1 christos } 3632 1.1 christos 3633 1.1 christos break; 3634 1.1 christos 3635 1.1 christos case R_LARCH_SOP_PUSH_TLS_TPREL: 3636 1.1 christos if (resolved_local) 3637 1.1 christos { 3638 1.1 christos if (!elf_hash_table (info)->tls_sec) 3639 1.1 christos fatal = (loongarch_reloc_is_fatal 3640 1.1 christos (info, input_bfd, input_section, rel, howto, 3641 1.1 christos bfd_reloc_notsupported, is_undefweak, name, 3642 1.1 christos "TLS section not be created")); 3643 1.1 christos else 3644 1.1.1.3 christos relocation = tlsoff (info, relocation); 3645 1.1 christos } 3646 1.1 christos else 3647 1.1 christos fatal = (loongarch_reloc_is_fatal 3648 1.1 christos (info, input_bfd, input_section, rel, howto, 3649 1.1 christos bfd_reloc_undefined, is_undefweak, name, 3650 1.1 christos "TLS LE just can be resolved local only.")); 3651 1.1 christos break; 3652 1.1 christos 3653 1.1 christos case R_LARCH_SOP_PUSH_ABSOLUTE: 3654 1.1 christos if (is_undefweak) 3655 1.1 christos { 3656 1.1 christos if (resolved_dynly) 3657 1.1 christos fatal = (loongarch_reloc_is_fatal 3658 1.1 christos (info, input_bfd, input_section, rel, howto, 3659 1.1 christos bfd_reloc_dangerous, is_undefweak, name, 3660 1.1 christos "Someone require us to resolve undefweak " 3661 1.1 christos "symbol dynamically. \n" 3662 1.1 christos "But this reloc can't be done. " 3663 1.1 christos "I think I can't throw error " 3664 1.1 christos "for this\n" 3665 1.1 christos "so I resolved it to 0. " 3666 1.1 christos "I suggest to re-compile with '-fpic'.")); 3667 1.1 christos 3668 1.1 christos relocation = 0; 3669 1.1 christos unresolved_reloc = false; 3670 1.1 christos break; 3671 1.1 christos } 3672 1.1 christos 3673 1.1 christos if (resolved_to_const) 3674 1.1 christos { 3675 1.1 christos relocation += rel->r_addend; 3676 1.1 christos break; 3677 1.1 christos } 3678 1.1 christos 3679 1.1 christos if (is_pic) 3680 1.1 christos { 3681 1.1 christos fatal = (loongarch_reloc_is_fatal 3682 1.1 christos (info, input_bfd, input_section, rel, howto, 3683 1.1 christos bfd_reloc_notsupported, is_undefweak, name, 3684 1.1 christos "Under PIC we don't know load address. Re-compile " 3685 1.1 christos "with '-fpic'?")); 3686 1.1 christos break; 3687 1.1 christos } 3688 1.1 christos 3689 1.1 christos if (resolved_dynly) 3690 1.1 christos { 3691 1.1 christos if (!(plt && h && h->plt.offset != MINUS_ONE)) 3692 1.1 christos { 3693 1.1 christos fatal = (loongarch_reloc_is_fatal 3694 1.1 christos (info, input_bfd, input_section, rel, howto, 3695 1.1 christos bfd_reloc_undefined, is_undefweak, name, 3696 1.1 christos "Can't be resolved dynamically. Try to re-compile " 3697 1.1 christos "with '-fpic'?")); 3698 1.1 christos break; 3699 1.1 christos } 3700 1.1 christos 3701 1.1 christos if (rel->r_addend != 0) 3702 1.1 christos { 3703 1.1 christos fatal = (loongarch_reloc_is_fatal 3704 1.1 christos (info, input_bfd, input_section, rel, howto, 3705 1.1 christos bfd_reloc_notsupported, is_undefweak, name, 3706 1.1 christos "Shouldn't be with r_addend.")); 3707 1.1 christos break; 3708 1.1 christos } 3709 1.1 christos 3710 1.1 christos relocation = sec_addr (plt) + h->plt.offset; 3711 1.1 christos unresolved_reloc = false; 3712 1.1 christos break; 3713 1.1 christos } 3714 1.1 christos 3715 1.1 christos if (resolved_local) 3716 1.1 christos { 3717 1.1 christos relocation += rel->r_addend; 3718 1.1 christos break; 3719 1.1 christos } 3720 1.1 christos 3721 1.1 christos break; 3722 1.1 christos 3723 1.1 christos case R_LARCH_SOP_PUSH_PCREL: 3724 1.1 christos case R_LARCH_SOP_PUSH_PLT_PCREL: 3725 1.1 christos unresolved_reloc = false; 3726 1.1 christos 3727 1.1.1.2 christos if (is_undefweak) 3728 1.1 christos { 3729 1.1 christos i = 0, j = 0; 3730 1.1 christos relocation = 0; 3731 1.1 christos if (resolved_dynly) 3732 1.1 christos { 3733 1.1 christos if (h && h->plt.offset != MINUS_ONE) 3734 1.1 christos i = 1, j = 2; 3735 1.1 christos else 3736 1.1 christos fatal = (loongarch_reloc_is_fatal 3737 1.1 christos (info, input_bfd, input_section, rel, howto, 3738 1.1 christos bfd_reloc_dangerous, is_undefweak, name, 3739 1.1 christos "Undefweak need to be resolved dynamically, " 3740 1.1 christos "but PLT stub doesn't represent.")); 3741 1.1 christos } 3742 1.1 christos } 3743 1.1 christos else 3744 1.1 christos { 3745 1.1 christos if (!(defined_local || (h && h->plt.offset != MINUS_ONE))) 3746 1.1 christos { 3747 1.1 christos fatal = (loongarch_reloc_is_fatal 3748 1.1 christos (info, input_bfd, input_section, rel, howto, 3749 1.1 christos bfd_reloc_undefined, is_undefweak, name, 3750 1.1 christos "PLT stub does not represent and " 3751 1.1 christos "symbol not defined.")); 3752 1.1 christos break; 3753 1.1 christos } 3754 1.1 christos 3755 1.1 christos if (resolved_local) 3756 1.1 christos i = 0, j = 2; 3757 1.1 christos else /* if (resolved_dynly) */ 3758 1.1 christos { 3759 1.1 christos if (!(h && h->plt.offset != MINUS_ONE)) 3760 1.1 christos fatal = (loongarch_reloc_is_fatal 3761 1.1 christos (info, input_bfd, input_section, rel, howto, 3762 1.1 christos bfd_reloc_dangerous, is_undefweak, name, 3763 1.1 christos "Internal: PLT stub doesn't represent. " 3764 1.1 christos "Resolve it with pcrel")); 3765 1.1 christos i = 1, j = 3; 3766 1.1 christos } 3767 1.1 christos } 3768 1.1 christos 3769 1.1 christos for (; i < j; i++) 3770 1.1 christos { 3771 1.1 christos if ((i & 1) == 0 && defined_local) 3772 1.1 christos { 3773 1.1 christos relocation -= pc; 3774 1.1 christos relocation += rel->r_addend; 3775 1.1 christos break; 3776 1.1 christos } 3777 1.1 christos 3778 1.1 christos if ((i & 1) && h && h->plt.offset != MINUS_ONE) 3779 1.1 christos { 3780 1.1 christos if (rel->r_addend != 0) 3781 1.1 christos { 3782 1.1 christos fatal = (loongarch_reloc_is_fatal 3783 1.1 christos (info, input_bfd, input_section, rel, howto, 3784 1.1 christos bfd_reloc_notsupported, is_undefweak, name, 3785 1.1 christos "PLT shouldn't be with r_addend.")); 3786 1.1 christos break; 3787 1.1 christos } 3788 1.1 christos relocation = sec_addr (plt) + h->plt.offset - pc; 3789 1.1 christos break; 3790 1.1 christos } 3791 1.1 christos } 3792 1.1 christos break; 3793 1.1 christos 3794 1.1 christos case R_LARCH_SOP_PUSH_GPREL: 3795 1.1 christos unresolved_reloc = false; 3796 1.1 christos 3797 1.1 christos if (rel->r_addend != 0) 3798 1.1 christos { 3799 1.1 christos fatal = (loongarch_reloc_is_fatal 3800 1.1 christos (info, input_bfd, input_section, rel, howto, 3801 1.1 christos bfd_reloc_notsupported, is_undefweak, name, 3802 1.1 christos "Shouldn't be with r_addend.")); 3803 1.1 christos break; 3804 1.1 christos } 3805 1.1 christos 3806 1.1 christos if (h != NULL) 3807 1.1 christos { 3808 1.1.1.2 christos off = h->got.offset & (~1); 3809 1.1 christos 3810 1.1.1.2 christos if (h->got.offset == MINUS_ONE && h->type != STT_GNU_IFUNC) 3811 1.1 christos { 3812 1.1 christos fatal = (loongarch_reloc_is_fatal 3813 1.1 christos (info, input_bfd, input_section, rel, howto, 3814 1.1 christos bfd_reloc_notsupported, is_undefweak, name, 3815 1.1 christos "Internal: GOT entry doesn't represent.")); 3816 1.1 christos break; 3817 1.1 christos } 3818 1.1 christos 3819 1.1 christos /* Hidden symbol not has .got entry, only .got.plt entry 3820 1.1 christos so gprel is (plt - got). */ 3821 1.1.1.2 christos if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC) 3822 1.1 christos { 3823 1.1 christos if (h->plt.offset == (bfd_vma) -1) 3824 1.1 christos { 3825 1.1 christos abort(); 3826 1.1 christos } 3827 1.1 christos 3828 1.1 christos bfd_vma plt_index = h->plt.offset / PLT_ENTRY_SIZE; 3829 1.1 christos off = plt_index * GOT_ENTRY_SIZE; 3830 1.1 christos 3831 1.1 christos if (htab->elf.splt != NULL) 3832 1.1 christos { 3833 1.1 christos /* Section .plt header is 2 times of plt entry. */ 3834 1.1.1.2 christos off = sec_addr (htab->elf.sgotplt) + off 3835 1.1.1.2 christos - sec_addr (htab->elf.sgot); 3836 1.1 christos } 3837 1.1 christos else 3838 1.1 christos { 3839 1.1 christos /* Section iplt not has plt header. */ 3840 1.1.1.2 christos off = sec_addr (htab->elf.igotplt) + off 3841 1.1.1.2 christos - sec_addr (htab->elf.sgot); 3842 1.1 christos } 3843 1.1 christos } 3844 1.1 christos 3845 1.1.1.2 christos if ((h->got.offset & 1) == 0) 3846 1.1 christos { 3847 1.1.1.2 christos if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn, 3848 1.1.1.2 christos bfd_link_pic (info), h) 3849 1.1.1.2 christos && ((bfd_link_pic (info) 3850 1.1.1.3 christos && LARCH_REF_LOCAL (info, h)))) 3851 1.1 christos { 3852 1.1.1.2 christos /* This is actually a static link, or it is a 3853 1.1.1.2 christos -Bsymbolic link and the symbol is defined 3854 1.1.1.2 christos locally, or the symbol was forced to be local 3855 1.1.1.2 christos because of a version file. We must initialize 3856 1.1.1.2 christos this entry in the global offset table. Since the 3857 1.1.1.2 christos offset must always be a multiple of the word size, 3858 1.1.1.2 christos we use the least significant bit to record whether 3859 1.1.1.2 christos we have initialized it already. 3860 1.1.1.2 christos 3861 1.1.1.2 christos When doing a dynamic link, we create a rela.got 3862 1.1.1.2 christos relocation entry to initialize the value. This 3863 1.1.1.2 christos is done in the finish_dynamic_symbol routine. */ 3864 1.1 christos 3865 1.1.1.2 christos if (resolved_dynly) 3866 1.1.1.2 christos { 3867 1.1.1.2 christos fatal = (loongarch_reloc_is_fatal 3868 1.1.1.2 christos (info, input_bfd, input_section, rel, howto, 3869 1.1.1.2 christos bfd_reloc_dangerous, is_undefweak, name, 3870 1.1.1.2 christos "Internal: here shouldn't dynamic.")); 3871 1.1.1.2 christos } 3872 1.1 christos 3873 1.1.1.2 christos if (!(defined_local || resolved_to_const)) 3874 1.1 christos { 3875 1.1.1.2 christos fatal = (loongarch_reloc_is_fatal 3876 1.1.1.2 christos (info, input_bfd, input_section, rel, howto, 3877 1.1.1.2 christos bfd_reloc_undefined, is_undefweak, name, 3878 1.1.1.2 christos "Internal: ")); 3879 1.1.1.2 christos break; 3880 1.1 christos } 3881 1.1.1.2 christos 3882 1.1.1.2 christos asection *s; 3883 1.1.1.2 christos Elf_Internal_Rela outrel; 3884 1.1.1.2 christos /* We need to generate a R_LARCH_RELATIVE reloc 3885 1.1.1.2 christos for the dynamic linker. */ 3886 1.1.1.2 christos s = htab->elf.srelgot; 3887 1.1.1.2 christos if (!s) 3888 1.1.1.2 christos { 3889 1.1.1.2 christos fatal = loongarch_reloc_is_fatal 3890 1.1.1.2 christos (info, input_bfd, 3891 1.1.1.2 christos input_section, rel, howto, 3892 1.1.1.2 christos bfd_reloc_notsupported, is_undefweak, name, 3893 1.1.1.2 christos "Internal: '.rel.got' not represent"); 3894 1.1.1.2 christos break; 3895 1.1.1.2 christos } 3896 1.1.1.2 christos 3897 1.1.1.2 christos outrel.r_offset = sec_addr (got) + off; 3898 1.1.1.2 christos outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE); 3899 1.1.1.2 christos outrel.r_addend = relocation; /* Link-time addr. */ 3900 1.1.1.2 christos loongarch_elf_append_rela (output_bfd, s, &outrel); 3901 1.1 christos } 3902 1.1.1.2 christos bfd_put_NN (output_bfd, relocation, got->contents + off); 3903 1.1.1.2 christos h->got.offset |= 1; 3904 1.1 christos } 3905 1.1 christos } 3906 1.1 christos else 3907 1.1 christos { 3908 1.1 christos if (!local_got_offsets) 3909 1.1 christos { 3910 1.1 christos fatal = (loongarch_reloc_is_fatal 3911 1.1 christos (info, input_bfd, input_section, rel, howto, 3912 1.1 christos bfd_reloc_notsupported, is_undefweak, name, 3913 1.1 christos "Internal: local got offsets not reporesent.")); 3914 1.1 christos break; 3915 1.1 christos } 3916 1.1 christos 3917 1.1.1.2 christos off = local_got_offsets[r_symndx] & (~1); 3918 1.1 christos 3919 1.1.1.2 christos if (local_got_offsets[r_symndx] == MINUS_ONE) 3920 1.1 christos { 3921 1.1 christos fatal = (loongarch_reloc_is_fatal 3922 1.1 christos (info, input_bfd, input_section, rel, howto, 3923 1.1 christos bfd_reloc_notsupported, is_undefweak, name, 3924 1.1 christos "Internal: GOT entry doesn't represent.")); 3925 1.1 christos break; 3926 1.1 christos } 3927 1.1 christos 3928 1.1 christos /* The offset must always be a multiple of the word size. 3929 1.1 christos So, we can use the least significant bit to record 3930 1.1 christos whether we have already processed this entry. */ 3931 1.1.1.2 christos if ((local_got_offsets[r_symndx] & 1) == 0) 3932 1.1 christos { 3933 1.1 christos if (is_pic) 3934 1.1 christos { 3935 1.1 christos asection *s; 3936 1.1 christos Elf_Internal_Rela outrel; 3937 1.1 christos /* We need to generate a R_LARCH_RELATIVE reloc 3938 1.1 christos for the dynamic linker. */ 3939 1.1 christos s = htab->elf.srelgot; 3940 1.1 christos if (!s) 3941 1.1 christos { 3942 1.1 christos fatal = (loongarch_reloc_is_fatal 3943 1.1 christos (info, input_bfd, input_section, rel, howto, 3944 1.1 christos bfd_reloc_notsupported, is_undefweak, name, 3945 1.1 christos "Internal: '.rel.got' not represent")); 3946 1.1 christos break; 3947 1.1 christos } 3948 1.1 christos 3949 1.1 christos outrel.r_offset = sec_addr (got) + off; 3950 1.1 christos outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE); 3951 1.1 christos outrel.r_addend = relocation; /* Link-time addr. */ 3952 1.1 christos loongarch_elf_append_rela (output_bfd, s, &outrel); 3953 1.1 christos } 3954 1.1 christos 3955 1.1 christos bfd_put_NN (output_bfd, relocation, got->contents + off); 3956 1.1 christos local_got_offsets[r_symndx] |= 1; 3957 1.1 christos } 3958 1.1 christos } 3959 1.1 christos relocation = off; 3960 1.1.1.2 christos 3961 1.1 christos break; 3962 1.1 christos 3963 1.1 christos case R_LARCH_SOP_PUSH_TLS_GOT: 3964 1.1 christos case R_LARCH_SOP_PUSH_TLS_GD: 3965 1.1.1.2 christos { 3966 1.1.1.2 christos unresolved_reloc = false; 3967 1.1.1.2 christos if (r_type == R_LARCH_SOP_PUSH_TLS_GOT) 3968 1.1.1.2 christos is_ie = true; 3969 1.1.1.2 christos 3970 1.1.1.2 christos bfd_vma got_off = 0; 3971 1.1.1.2 christos if (h != NULL) 3972 1.1.1.2 christos { 3973 1.1.1.2 christos got_off = h->got.offset; 3974 1.1.1.2 christos h->got.offset |= 1; 3975 1.1.1.2 christos } 3976 1.1.1.2 christos else 3977 1.1.1.2 christos { 3978 1.1.1.2 christos got_off = local_got_offsets[r_symndx]; 3979 1.1.1.2 christos local_got_offsets[r_symndx] |= 1; 3980 1.1.1.2 christos } 3981 1.1.1.2 christos 3982 1.1.1.2 christos BFD_ASSERT (got_off != MINUS_ONE); 3983 1.1.1.2 christos 3984 1.1.1.2 christos ie_off = 0; 3985 1.1.1.2 christos tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx); 3986 1.1.1.2 christos if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE)) 3987 1.1.1.2 christos ie_off = 2 * GOT_ENTRY_SIZE; 3988 1.1.1.2 christos 3989 1.1.1.2 christos if ((got_off & 1) == 0) 3990 1.1.1.2 christos { 3991 1.1.1.2 christos Elf_Internal_Rela rela; 3992 1.1.1.2 christos asection *srel = htab->elf.srelgot; 3993 1.1 christos 3994 1.1.1.3 christos int indx = 0; 3995 1.1.1.3 christos bool need_reloc = false; 3996 1.1.1.3 christos LARCH_TLS_GD_IE_NEED_DYN_RELOC (info, is_dyn, h, indx, 3997 1.1.1.3 christos need_reloc); 3998 1.1 christos 3999 1.1.1.2 christos if (tls_type & GOT_TLS_GD) 4000 1.1.1.2 christos { 4001 1.1.1.3 christos if (need_reloc) 4002 1.1.1.2 christos { 4003 1.1.1.3 christos /* Dynamic resolved Module ID. */ 4004 1.1.1.3 christos rela.r_offset = sec_addr (got) + got_off; 4005 1.1.1.3 christos rela.r_addend = 0; 4006 1.1.1.3 christos rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_DTPMODNN); 4007 1.1.1.3 christos bfd_put_NN (output_bfd, 0, got->contents + got_off); 4008 1.1.1.3 christos loongarch_elf_append_rela (output_bfd, srel, &rela); 4009 1.1.1.3 christos 4010 1.1.1.3 christos if (indx == 0) 4011 1.1.1.3 christos { 4012 1.1.1.3 christos /* Local symbol, tp offset has been known. */ 4013 1.1.1.3 christos BFD_ASSERT (! unresolved_reloc); 4014 1.1.1.3 christos bfd_put_NN (output_bfd, 4015 1.1.1.3 christos tlsoff (info, relocation), 4016 1.1.1.3 christos (got->contents + got_off + GOT_ENTRY_SIZE)); 4017 1.1.1.3 christos } 4018 1.1.1.2 christos else 4019 1.1.1.2 christos { 4020 1.1.1.3 christos /* Dynamic resolved block offset. */ 4021 1.1.1.3 christos bfd_put_NN (output_bfd, 0, 4022 1.1.1.3 christos got->contents + got_off + GOT_ENTRY_SIZE); 4023 1.1.1.3 christos rela.r_info = ELFNN_R_INFO (indx, 4024 1.1.1.3 christos R_LARCH_TLS_DTPRELNN); 4025 1.1.1.3 christos rela.r_offset += GOT_ENTRY_SIZE; 4026 1.1.1.2 christos loongarch_elf_append_rela (output_bfd, srel, &rela); 4027 1.1.1.2 christos } 4028 1.1.1.2 christos } 4029 1.1.1.2 christos else 4030 1.1.1.2 christos { 4031 1.1.1.3 christos /* In a static link or an executable link with the symbol 4032 1.1.1.3 christos binding locally. Mark it as belonging to module 1. */ 4033 1.1.1.3 christos bfd_put_NN (output_bfd, 1, got->contents + got_off); 4034 1.1.1.3 christos bfd_put_NN (output_bfd, tlsoff (info, relocation), 4035 1.1.1.3 christos got->contents + got_off + GOT_ENTRY_SIZE); 4036 1.1.1.2 christos } 4037 1.1.1.2 christos } 4038 1.1.1.2 christos if (tls_type & GOT_TLS_IE) 4039 1.1.1.2 christos { 4040 1.1.1.3 christos if (need_reloc) 4041 1.1.1.2 christos { 4042 1.1.1.3 christos bfd_put_NN (output_bfd, 0, 4043 1.1.1.3 christos got->contents + got_off + ie_off); 4044 1.1.1.3 christos rela.r_offset = sec_addr (got) + got_off + ie_off; 4045 1.1.1.3 christos rela.r_addend = 0; 4046 1.1.1.2 christos 4047 1.1.1.3 christos if (indx == 0) 4048 1.1.1.3 christos rela.r_addend = tlsoff (info, relocation); 4049 1.1.1.3 christos rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_TPRELNN); 4050 1.1.1.3 christos loongarch_elf_append_rela (output_bfd, srel, &rela); 4051 1.1.1.2 christos } 4052 1.1.1.2 christos else 4053 1.1.1.2 christos { 4054 1.1.1.3 christos /* In a static link or an executable link with the symbol 4055 1.1.1.3 christos binding locally, compute offset directly. */ 4056 1.1.1.3 christos bfd_put_NN (output_bfd, tlsoff (info, relocation), 4057 1.1.1.3 christos got->contents + got_off + ie_off); 4058 1.1.1.2 christos } 4059 1.1.1.2 christos } 4060 1.1.1.2 christos } 4061 1.1 christos 4062 1.1.1.2 christos relocation = (got_off & (~(bfd_vma)1)) + (is_ie ? ie_off : 0); 4063 1.1.1.2 christos } 4064 1.1.1.2 christos break; 4065 1.1 christos 4066 1.1.1.2 christos /* New reloc types. */ 4067 1.1.1.2 christos case R_LARCH_B16: 4068 1.1.1.2 christos case R_LARCH_B21: 4069 1.1.1.2 christos case R_LARCH_B26: 4070 1.1.1.2 christos case R_LARCH_CALL36: 4071 1.1.1.2 christos unresolved_reloc = false; 4072 1.1.1.3 christos bool via_plt = 4073 1.1.1.3 christos plt != NULL && h != NULL && h->plt.offset != (bfd_vma) - 1; 4074 1.1.1.3 christos 4075 1.1.1.2 christos if (is_undefweak) 4076 1.1 christos { 4077 1.1.1.2 christos relocation = 0; 4078 1.1.1.3 christos 4079 1.1.1.3 christos /* A call to an undefined weak symbol is converted to 0. */ 4080 1.1.1.3 christos if (!via_plt && IS_CALL_RELOC (r_type)) 4081 1.1.1.3 christos { 4082 1.1.1.3 christos /* call36 fn1 => pcaddu18i $ra,0+jirl $ra,$zero,0 4083 1.1.1.3 christos tail36 $t0,fn1 => pcaddi18i $t0,0+jirl $zero,$zero,0 */ 4084 1.1.1.3 christos if (R_LARCH_CALL36 == r_type) 4085 1.1.1.3 christos { 4086 1.1.1.3 christos uint32_t jirl = bfd_get (32, input_bfd, 4087 1.1.1.3 christos contents + rel->r_offset + 4); 4088 1.1.1.3 christos uint32_t rd = LARCH_GET_RD (jirl); 4089 1.1.1.3 christos jirl = LARCH_OP_JIRL | rd; 4090 1.1.1.3 christos 4091 1.1.1.3 christos bfd_put (32, input_bfd, jirl, 4092 1.1.1.3 christos contents + rel->r_offset + 4); 4093 1.1.1.3 christos } 4094 1.1.1.3 christos else 4095 1.1.1.3 christos { 4096 1.1.1.3 christos uint32_t b_bl = bfd_get (32, input_bfd, 4097 1.1.1.3 christos contents + rel->r_offset); 4098 1.1.1.3 christos /* b %plt(fn1) => jirl $zero,zero,0. */ 4099 1.1.1.3 christos if (LARCH_INSN_B (b_bl)) 4100 1.1.1.3 christos bfd_put (32, input_bfd, LARCH_OP_JIRL, 4101 1.1.1.3 christos contents + rel->r_offset); 4102 1.1.1.3 christos else 4103 1.1.1.3 christos /* bl %plt(fn1) => jirl $ra,zero,0. */ 4104 1.1.1.3 christos bfd_put (32, input_bfd, LARCH_OP_JIRL | 0x1, 4105 1.1.1.3 christos contents + rel->r_offset); 4106 1.1.1.3 christos } 4107 1.1.1.3 christos r = bfd_reloc_continue; 4108 1.1.1.3 christos break; 4109 1.1.1.3 christos } 4110 1.1 christos } 4111 1.1 christos 4112 1.1.1.2 christos if (resolved_local) 4113 1.1 christos { 4114 1.1.1.2 christos relocation -= pc; 4115 1.1.1.2 christos relocation += rel->r_addend; 4116 1.1 christos } 4117 1.1.1.2 christos else if (resolved_dynly) 4118 1.1 christos { 4119 1.1.1.2 christos BFD_ASSERT (h 4120 1.1.1.2 christos && (h->plt.offset != MINUS_ONE 4121 1.1.1.2 christos || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) 4122 1.1.1.2 christos && rel->r_addend == 0); 4123 1.1.1.2 christos if (h && h->plt.offset == MINUS_ONE 4124 1.1.1.2 christos && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) 4125 1.1.1.2 christos { 4126 1.1.1.2 christos relocation -= pc; 4127 1.1.1.2 christos relocation += rel->r_addend; 4128 1.1.1.2 christos } 4129 1.1.1.2 christos else 4130 1.1.1.2 christos relocation = sec_addr (plt) + h->plt.offset - pc; 4131 1.1 christos } 4132 1.1 christos 4133 1.1.1.2 christos break; 4134 1.1.1.2 christos 4135 1.1.1.2 christos case R_LARCH_ABS_HI20: 4136 1.1.1.2 christos case R_LARCH_ABS_LO12: 4137 1.1.1.2 christos case R_LARCH_ABS64_LO20: 4138 1.1.1.2 christos case R_LARCH_ABS64_HI12: 4139 1.1.1.2 christos 4140 1.1.1.2 christos if (is_undefweak) 4141 1.1 christos { 4142 1.1.1.2 christos BFD_ASSERT (resolved_dynly); 4143 1.1.1.2 christos relocation = 0; 4144 1.1 christos break; 4145 1.1 christos } 4146 1.1.1.2 christos else if (resolved_to_const || resolved_local) 4147 1.1.1.2 christos { 4148 1.1.1.2 christos relocation += rel->r_addend; 4149 1.1.1.2 christos } 4150 1.1.1.2 christos else if (resolved_dynly) 4151 1.1.1.2 christos { 4152 1.1.1.2 christos unresolved_reloc = false; 4153 1.1.1.2 christos BFD_ASSERT ((plt && h && h->plt.offset != MINUS_ONE) 4154 1.1.1.2 christos && rel->r_addend == 0); 4155 1.1.1.2 christos relocation = sec_addr (plt) + h->plt.offset; 4156 1.1.1.2 christos } 4157 1.1 christos 4158 1.1.1.2 christos break; 4159 1.1 christos 4160 1.1.1.3 christos case R_LARCH_PCALA64_HI12: 4161 1.1.1.3 christos pc -= 4; 4162 1.1.1.3 christos /* Fall through. */ 4163 1.1.1.3 christos case R_LARCH_PCALA64_LO20: 4164 1.1.1.3 christos pc -= 8; 4165 1.1.1.3 christos /* Fall through. */ 4166 1.1.1.2 christos case R_LARCH_PCREL20_S2: 4167 1.1.1.2 christos case R_LARCH_PCALA_HI20: 4168 1.1.1.2 christos unresolved_reloc = false; 4169 1.1.1.3 christos 4170 1.1.1.3 christos /* If sym is undef weak and it's hidden or we are doing a static 4171 1.1.1.3 christos link, (sym + addend) should be resolved to runtime address 4172 1.1.1.3 christos (0 + addend). */ 4173 1.1.1.3 christos resolve_pcrel_undef_weak = 4174 1.1.1.3 christos ((info->nointerp 4175 1.1.1.3 christos || (h && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)) 4176 1.1.1.3 christos && is_undefweak); 4177 1.1.1.3 christos 4178 1.1.1.3 christos if (resolve_pcrel_undef_weak) 4179 1.1.1.3 christos pc = 0; 4180 1.1.1.3 christos 4181 1.1.1.2 christos if (h && h->plt.offset != MINUS_ONE) 4182 1.1.1.2 christos relocation = sec_addr (plt) + h->plt.offset; 4183 1.1 christos else 4184 1.1.1.2 christos relocation += rel->r_addend; 4185 1.1 christos 4186 1.1.1.3 christos switch (r_type) 4187 1.1.1.3 christos { 4188 1.1.1.3 christos case R_LARCH_PCREL20_S2: 4189 1.1.1.3 christos relocation -= pc; 4190 1.1.1.3 christos if (resolve_pcrel_undef_weak) 4191 1.1.1.3 christos { 4192 1.1.1.3 christos bfd_signed_vma addr = (bfd_signed_vma) relocation; 4193 1.1.1.3 christos if (addr >= 2048 || addr < -2048) 4194 1.1.1.3 christos { 4195 1.1.1.3 christos const char *msg = 4196 1.1.1.3 christos _("cannot resolve R_LARCH_PCREL20_S2 against " 4197 1.1.1.3 christos "undefined weak symbol with addend out of " 4198 1.1.1.3 christos "[-2048, 2048)"); 4199 1.1.1.3 christos fatal = 4200 1.1.1.3 christos loongarch_reloc_is_fatal (info, input_bfd, 4201 1.1.1.3 christos input_section, rel, 4202 1.1.1.3 christos howto, 4203 1.1.1.3 christos bfd_reloc_notsupported, 4204 1.1.1.3 christos is_undefweak, name, msg); 4205 1.1.1.3 christos break; 4206 1.1.1.3 christos } 4207 1.1.1.3 christos 4208 1.1.1.3 christos uint32_t insn = bfd_get (32, input_bfd, 4209 1.1.1.3 christos contents + rel->r_offset); 4210 1.1.1.3 christos insn = LARCH_GET_RD (insn) | LARCH_OP_ADDI_W; 4211 1.1.1.3 christos insn |= (relocation & 0xfff) << 10; 4212 1.1.1.3 christos bfd_put_32 (input_bfd, insn, contents + rel->r_offset); 4213 1.1.1.3 christos r = bfd_reloc_continue; 4214 1.1.1.3 christos } 4215 1.1.1.3 christos break; 4216 1.1.1.3 christos case R_LARCH_PCALA_HI20: 4217 1.1.1.3 christos RELOCATE_CALC_PC32_HI20 (relocation, pc); 4218 1.1.1.3 christos if (resolve_pcrel_undef_weak) 4219 1.1.1.3 christos { 4220 1.1.1.3 christos uint32_t insn = bfd_get (32, input_bfd, 4221 1.1.1.3 christos contents + rel->r_offset); 4222 1.1.1.3 christos insn = LARCH_GET_RD (insn) | LARCH_OP_LU12I_W; 4223 1.1.1.3 christos bfd_put_32 (input_bfd, insn, contents + rel->r_offset); 4224 1.1.1.3 christos } 4225 1.1.1.3 christos break; 4226 1.1.1.3 christos default: 4227 1.1.1.3 christos RELOCATE_CALC_PC64_HI32 (relocation, pc); 4228 1.1.1.3 christos } 4229 1.1.1.2 christos break; 4230 1.1 christos 4231 1.1.1.2 christos case R_LARCH_TLS_LE_HI20_R: 4232 1.1.1.2 christos relocation += rel->r_addend; 4233 1.1.1.3 christos relocation = tlsoff (info, relocation); 4234 1.1.1.2 christos RELOCATE_TLS_TP32_HI20 (relocation); 4235 1.1.1.2 christos break; 4236 1.1 christos 4237 1.1.1.2 christos case R_LARCH_PCALA_LO12: 4238 1.1.1.2 christos /* Not support if sym_addr in 2k page edge. 4239 1.1.1.2 christos pcalau12i pc_hi20 (sym_addr) 4240 1.1.1.2 christos ld.w/d pc_lo12 (sym_addr) 4241 1.1.1.2 christos ld.w/d pc_lo12 (sym_addr + x) 4242 1.1.1.2 christos ... 4243 1.1.1.2 christos can not calc correct address 4244 1.1.1.2 christos if sym_addr < 0x800 && sym_addr + x >= 0x800. */ 4245 1.1.1.2 christos 4246 1.1.1.2 christos if (h && h->plt.offset != MINUS_ONE) 4247 1.1.1.2 christos relocation = sec_addr (plt) + h->plt.offset; 4248 1.1.1.2 christos else 4249 1.1.1.2 christos relocation += rel->r_addend; 4250 1.1.1.2 christos 4251 1.1.1.2 christos /* For 2G jump, generate pcalau12i, jirl. */ 4252 1.1.1.2 christos /* If use jirl, turns to R_LARCH_B16. */ 4253 1.1.1.2 christos uint32_t insn = bfd_get (32, input_bfd, contents + rel->r_offset); 4254 1.1.1.3 christos if (LARCH_INSN_JIRL (insn)) 4255 1.1.1.2 christos { 4256 1.1.1.2 christos relocation &= 0xfff; 4257 1.1.1.2 christos /* Signed extend. */ 4258 1.1.1.2 christos relocation = (relocation ^ 0x800) - 0x800; 4259 1.1.1.2 christos 4260 1.1.1.2 christos rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_B16); 4261 1.1.1.2 christos howto = loongarch_elf_rtype_to_howto (input_bfd, R_LARCH_B16); 4262 1.1.1.2 christos } 4263 1.1.1.2 christos break; 4264 1.1.1.2 christos 4265 1.1.1.2 christos case R_LARCH_GOT_PC_HI20: 4266 1.1.1.2 christos case R_LARCH_GOT_HI20: 4267 1.1.1.2 christos /* Calc got offset. */ 4268 1.1.1.2 christos { 4269 1.1.1.2 christos unresolved_reloc = false; 4270 1.1.1.2 christos BFD_ASSERT (rel->r_addend == 0); 4271 1.1.1.2 christos 4272 1.1.1.2 christos bfd_vma got_off = 0; 4273 1.1.1.2 christos if (h != NULL) 4274 1.1 christos { 4275 1.1.1.2 christos /* GOT ref or ifunc. */ 4276 1.1.1.2 christos BFD_ASSERT (h->got.offset != MINUS_ONE 4277 1.1.1.2 christos || h->type == STT_GNU_IFUNC); 4278 1.1.1.2 christos 4279 1.1.1.2 christos got_off = h->got.offset & (~(bfd_vma)1); 4280 1.1.1.2 christos /* Hidden symbol not has got entry, 4281 1.1.1.2 christos * only got.plt entry so it is (plt - got). */ 4282 1.1.1.2 christos if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC) 4283 1.1.1.2 christos { 4284 1.1.1.2 christos bfd_vma idx; 4285 1.1.1.2 christos if (htab->elf.splt != NULL) 4286 1.1.1.2 christos { 4287 1.1.1.2 christos idx = (h->plt.offset - PLT_HEADER_SIZE) 4288 1.1.1.2 christos / PLT_ENTRY_SIZE; 4289 1.1.1.2 christos got_off = sec_addr (htab->elf.sgotplt) 4290 1.1.1.2 christos + GOTPLT_HEADER_SIZE 4291 1.1.1.2 christos + (idx * GOT_ENTRY_SIZE) 4292 1.1.1.2 christos - sec_addr (htab->elf.sgot); 4293 1.1.1.2 christos } 4294 1.1.1.2 christos else 4295 1.1.1.2 christos { 4296 1.1.1.2 christos idx = h->plt.offset / PLT_ENTRY_SIZE; 4297 1.1.1.2 christos got_off = sec_addr (htab->elf.sgotplt) 4298 1.1.1.2 christos + (idx * GOT_ENTRY_SIZE) 4299 1.1.1.2 christos - sec_addr (htab->elf.sgot); 4300 1.1.1.2 christos } 4301 1.1.1.2 christos } 4302 1.1.1.2 christos 4303 1.1.1.2 christos if ((h->got.offset & 1) == 0) 4304 1.1.1.2 christos { 4305 1.1.1.2 christos /* We need to generate a R_LARCH_RELATIVE reloc once 4306 1.1.1.2 christos * in loongarch_elf_finish_dynamic_symbol or now, 4307 1.1.1.2 christos * call finish_dyn && nopic 4308 1.1.1.2 christos * or !call finish_dyn && pic. */ 4309 1.1.1.2 christos if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn, 4310 1.1.1.2 christos bfd_link_pic (info), 4311 1.1.1.2 christos h) 4312 1.1.1.3 christos && !bfd_is_abs_section(h->root.u.def.section) 4313 1.1.1.2 christos && bfd_link_pic (info) 4314 1.1.1.3 christos && LARCH_REF_LOCAL (info, h) 4315 1.1.1.3 christos && !info->enable_dt_relr) 4316 1.1.1.2 christos { 4317 1.1.1.2 christos Elf_Internal_Rela rela; 4318 1.1.1.2 christos rela.r_offset = sec_addr (got) + got_off; 4319 1.1.1.2 christos rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE); 4320 1.1.1.2 christos rela.r_addend = relocation; 4321 1.1.1.2 christos loongarch_elf_append_rela (output_bfd, 4322 1.1.1.2 christos htab->elf.srelgot, &rela); 4323 1.1.1.2 christos } 4324 1.1.1.2 christos h->got.offset |= 1; 4325 1.1.1.2 christos bfd_put_NN (output_bfd, relocation, 4326 1.1.1.2 christos got->contents + got_off); 4327 1.1 christos } 4328 1.1.1.2 christos } 4329 1.1.1.2 christos else 4330 1.1.1.2 christos { 4331 1.1.1.2 christos BFD_ASSERT (local_got_offsets 4332 1.1.1.2 christos && local_got_offsets[r_symndx] != MINUS_ONE); 4333 1.1.1.2 christos 4334 1.1.1.2 christos got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1); 4335 1.1.1.3 christos if (sym->st_shndx != SHN_ABS 4336 1.1.1.3 christos && (local_got_offsets[r_symndx] & 1) == 0) 4337 1.1 christos { 4338 1.1.1.3 christos if (bfd_link_pic (info) && !info->enable_dt_relr) 4339 1.1 christos { 4340 1.1.1.2 christos Elf_Internal_Rela rela; 4341 1.1.1.2 christos rela.r_offset = sec_addr (got) + got_off; 4342 1.1.1.2 christos rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE); 4343 1.1.1.2 christos rela.r_addend = relocation; 4344 1.1.1.2 christos loongarch_elf_append_rela (output_bfd, 4345 1.1.1.2 christos htab->elf.srelgot, &rela); 4346 1.1 christos } 4347 1.1.1.2 christos local_got_offsets[r_symndx] |= 1; 4348 1.1.1.2 christos } 4349 1.1.1.2 christos bfd_put_NN (output_bfd, relocation, got->contents + got_off); 4350 1.1.1.2 christos } 4351 1.1.1.2 christos 4352 1.1.1.2 christos relocation = got_off + sec_addr (got); 4353 1.1.1.2 christos } 4354 1.1.1.2 christos 4355 1.1.1.2 christos if (r_type == R_LARCH_GOT_PC_HI20) 4356 1.1.1.2 christos RELOCATE_CALC_PC32_HI20 (relocation, pc); 4357 1.1.1.2 christos 4358 1.1.1.2 christos break; 4359 1.1.1.2 christos 4360 1.1.1.2 christos case R_LARCH_GOT_PC_LO12: 4361 1.1.1.2 christos case R_LARCH_GOT64_PC_LO20: 4362 1.1.1.2 christos case R_LARCH_GOT64_PC_HI12: 4363 1.1.1.2 christos case R_LARCH_GOT_LO12: 4364 1.1.1.2 christos case R_LARCH_GOT64_LO20: 4365 1.1.1.2 christos case R_LARCH_GOT64_HI12: 4366 1.1.1.2 christos { 4367 1.1.1.2 christos unresolved_reloc = false; 4368 1.1.1.2 christos bfd_vma got_off; 4369 1.1.1.2 christos if (h) 4370 1.1.1.2 christos got_off = h->got.offset & (~(bfd_vma)1); 4371 1.1.1.2 christos else 4372 1.1.1.2 christos got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1); 4373 1.1.1.2 christos 4374 1.1.1.2 christos if (h && h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC) 4375 1.1.1.2 christos { 4376 1.1.1.2 christos bfd_vma idx; 4377 1.1.1.2 christos if (htab->elf.splt != NULL) 4378 1.1.1.2 christos idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE; 4379 1.1.1.2 christos else 4380 1.1.1.2 christos idx = h->plt.offset / PLT_ENTRY_SIZE; 4381 1.1.1.2 christos 4382 1.1.1.2 christos got_off = sec_addr (htab->elf.sgotplt) 4383 1.1.1.2 christos + GOTPLT_HEADER_SIZE 4384 1.1.1.2 christos + (idx * GOT_ENTRY_SIZE) 4385 1.1.1.2 christos - sec_addr (htab->elf.sgot); 4386 1.1.1.2 christos } 4387 1.1.1.2 christos 4388 1.1.1.2 christos relocation = got_off + sec_addr (got); 4389 1.1.1.2 christos } 4390 1.1.1.2 christos 4391 1.1.1.2 christos if (r_type == R_LARCH_GOT64_PC_HI12) 4392 1.1.1.2 christos RELOCATE_CALC_PC64_HI32 (relocation, pc - 12); 4393 1.1.1.2 christos else if (r_type == R_LARCH_GOT64_PC_LO20) 4394 1.1.1.2 christos RELOCATE_CALC_PC64_HI32 (relocation, pc - 8); 4395 1.1.1.2 christos 4396 1.1.1.2 christos break; 4397 1.1.1.2 christos 4398 1.1.1.2 christos case R_LARCH_TLS_LE_HI20: 4399 1.1.1.2 christos case R_LARCH_TLS_LE_LO12: 4400 1.1.1.2 christos case R_LARCH_TLS_LE_LO12_R: 4401 1.1.1.2 christos case R_LARCH_TLS_LE64_LO20: 4402 1.1.1.2 christos case R_LARCH_TLS_LE64_HI12: 4403 1.1.1.2 christos BFD_ASSERT (resolved_local && elf_hash_table (info)->tls_sec); 4404 1.1.1.2 christos 4405 1.1.1.2 christos relocation += rel->r_addend; 4406 1.1.1.3 christos relocation = tlsoff (info, relocation); 4407 1.1.1.2 christos break; 4408 1.1.1.2 christos 4409 1.1.1.2 christos /* TLS IE LD/GD process separately is troublesome. 4410 1.1.1.2 christos When a symbol is both ie and LD/GD, h->got.off |= 1 4411 1.1.1.2 christos make only one type be relocated. We must use 4412 1.1.1.2 christos h->got.offset |= 1 and h->got.offset |= 2 4413 1.1.1.2 christos diff IE and LD/GD. And all (got_off & (~(bfd_vma)1)) 4414 1.1.1.2 christos (IE LD/GD and reusable GOT reloc) must change to 4415 1.1.1.2 christos (got_off & (~(bfd_vma)3)), beause we use lowest 2 bits 4416 1.1.1.2 christos as a tag. 4417 1.1.1.2 christos Now, LD and GD is both GOT_TLS_GD type, LD seems to 4418 1.1.1.2 christos can be omitted. */ 4419 1.1.1.2 christos case R_LARCH_TLS_IE_PC_HI20: 4420 1.1.1.2 christos case R_LARCH_TLS_IE_HI20: 4421 1.1.1.2 christos case R_LARCH_TLS_LD_PC_HI20: 4422 1.1.1.2 christos case R_LARCH_TLS_LD_HI20: 4423 1.1.1.2 christos case R_LARCH_TLS_GD_PC_HI20: 4424 1.1.1.2 christos case R_LARCH_TLS_GD_HI20: 4425 1.1.1.2 christos case R_LARCH_TLS_DESC_PC_HI20: 4426 1.1.1.2 christos case R_LARCH_TLS_DESC_HI20: 4427 1.1.1.2 christos case R_LARCH_TLS_LD_PCREL20_S2: 4428 1.1.1.2 christos case R_LARCH_TLS_GD_PCREL20_S2: 4429 1.1.1.2 christos case R_LARCH_TLS_DESC_PCREL20_S2: 4430 1.1.1.2 christos BFD_ASSERT (rel->r_addend == 0); 4431 1.1.1.2 christos unresolved_reloc = false; 4432 1.1.1.2 christos 4433 1.1.1.2 christos if (r_type == R_LARCH_TLS_IE_PC_HI20 4434 1.1.1.2 christos || r_type == R_LARCH_TLS_IE_HI20) 4435 1.1.1.2 christos is_ie = true; 4436 1.1.1.2 christos 4437 1.1.1.2 christos if (r_type == R_LARCH_TLS_DESC_PC_HI20 4438 1.1.1.2 christos || r_type == R_LARCH_TLS_DESC_HI20 4439 1.1.1.2 christos || r_type == R_LARCH_TLS_DESC_PCREL20_S2) 4440 1.1.1.2 christos is_desc = true; 4441 1.1.1.2 christos 4442 1.1.1.2 christos bfd_vma got_off = 0; 4443 1.1.1.2 christos if (h != NULL) 4444 1.1.1.2 christos { 4445 1.1.1.2 christos got_off = h->got.offset; 4446 1.1.1.2 christos h->got.offset |= 1; 4447 1.1.1.2 christos } 4448 1.1.1.2 christos else 4449 1.1.1.2 christos { 4450 1.1.1.2 christos got_off = local_got_offsets[r_symndx]; 4451 1.1.1.2 christos local_got_offsets[r_symndx] |= 1; 4452 1.1.1.2 christos } 4453 1.1.1.2 christos 4454 1.1.1.2 christos BFD_ASSERT (got_off != MINUS_ONE); 4455 1.1.1.2 christos 4456 1.1.1.2 christos tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx); 4457 1.1.1.2 christos 4458 1.1.1.2 christos /* If a tls variable is accessed in multiple ways, GD uses 4459 1.1.1.2 christos the first two slots of GOT, desc follows with two slots, 4460 1.1.1.2 christos and IE uses one slot at the end. */ 4461 1.1.1.3 christos off = 0; 4462 1.1.1.3 christos if (tls_type & GOT_TLS_GD) 4463 1.1.1.3 christos off += 2 * GOT_ENTRY_SIZE; 4464 1.1.1.3 christos desc_off = off; 4465 1.1.1.3 christos if (tls_type & GOT_TLS_GDESC) 4466 1.1.1.3 christos off += 2 * GOT_ENTRY_SIZE; 4467 1.1.1.3 christos ie_off = off; 4468 1.1.1.2 christos 4469 1.1.1.2 christos if ((got_off & 1) == 0) 4470 1.1.1.2 christos { 4471 1.1.1.2 christos Elf_Internal_Rela rela; 4472 1.1.1.2 christos asection *relgot = htab->elf.srelgot; 4473 1.1.1.2 christos 4474 1.1.1.3 christos int indx = 0; 4475 1.1.1.3 christos bool need_reloc = false; 4476 1.1.1.3 christos LARCH_TLS_GD_IE_NEED_DYN_RELOC (info, is_dyn, h, indx, 4477 1.1.1.3 christos need_reloc); 4478 1.1.1.2 christos 4479 1.1.1.2 christos if (tls_type & GOT_TLS_GD) 4480 1.1.1.2 christos { 4481 1.1.1.3 christos if (need_reloc) 4482 1.1.1.2 christos { 4483 1.1.1.3 christos /* Dynamic resolved Module ID. */ 4484 1.1.1.3 christos rela.r_offset = sec_addr (got) + got_off; 4485 1.1.1.3 christos rela.r_addend = 0; 4486 1.1.1.3 christos rela.r_info = ELFNN_R_INFO (indx,R_LARCH_TLS_DTPMODNN); 4487 1.1.1.3 christos bfd_put_NN (output_bfd, 0, got->contents + got_off); 4488 1.1.1.3 christos loongarch_elf_append_rela (output_bfd, relgot, &rela); 4489 1.1.1.3 christos 4490 1.1.1.3 christos if (indx == 0) 4491 1.1.1.3 christos { 4492 1.1.1.3 christos /* Local symbol, tp offset has been known. */ 4493 1.1.1.3 christos BFD_ASSERT (! unresolved_reloc); 4494 1.1.1.3 christos bfd_put_NN (output_bfd, 4495 1.1.1.3 christos tlsoff (info, relocation), 4496 1.1.1.3 christos (got->contents + got_off + GOT_ENTRY_SIZE)); 4497 1.1.1.3 christos } 4498 1.1 christos else 4499 1.1 christos { 4500 1.1.1.3 christos /* Dynamic resolved block offset. */ 4501 1.1.1.3 christos bfd_put_NN (output_bfd, 0, 4502 1.1.1.3 christos got->contents + got_off + GOT_ENTRY_SIZE); 4503 1.1.1.3 christos rela.r_info = ELFNN_R_INFO (indx, 4504 1.1.1.3 christos R_LARCH_TLS_DTPRELNN); 4505 1.1.1.3 christos rela.r_offset += GOT_ENTRY_SIZE; 4506 1.1.1.2 christos loongarch_elf_append_rela (output_bfd, relgot, &rela); 4507 1.1.1.2 christos } 4508 1.1.1.2 christos } 4509 1.1.1.2 christos else 4510 1.1.1.2 christos { 4511 1.1.1.3 christos /* In a static link or an executable link with the symbol 4512 1.1.1.3 christos binding locally. Mark it as belonging to module 1. */ 4513 1.1.1.3 christos bfd_put_NN (output_bfd, 1, got->contents + got_off); 4514 1.1.1.3 christos bfd_put_NN (output_bfd, tlsoff (info, relocation), 4515 1.1.1.3 christos got->contents + got_off + GOT_ENTRY_SIZE); 4516 1.1.1.2 christos } 4517 1.1.1.2 christos } 4518 1.1.1.2 christos if (tls_type & GOT_TLS_GDESC) 4519 1.1.1.2 christos { 4520 1.1.1.2 christos /* Unless it is a static link, DESC always emits a 4521 1.1.1.2 christos dynamic relocation. */ 4522 1.1.1.3 christos indx = h && h->dynindx != -1 ? h->dynindx : 0; 4523 1.1.1.2 christos rela.r_offset = sec_addr (got) + got_off + desc_off; 4524 1.1.1.2 christos rela.r_addend = 0; 4525 1.1.1.2 christos if (indx == 0) 4526 1.1.1.3 christos rela.r_addend = tlsoff (info, relocation); 4527 1.1.1.2 christos 4528 1.1.1.2 christos rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_DESCNN); 4529 1.1.1.2 christos loongarch_elf_append_rela (output_bfd, relgot, &rela); 4530 1.1.1.2 christos bfd_put_NN (output_bfd, 0, 4531 1.1.1.2 christos got->contents + got_off + desc_off); 4532 1.1.1.2 christos } 4533 1.1.1.2 christos if (tls_type & GOT_TLS_IE) 4534 1.1.1.2 christos { 4535 1.1.1.3 christos if (need_reloc) 4536 1.1.1.2 christos { 4537 1.1.1.3 christos bfd_put_NN (output_bfd, 0, 4538 1.1.1.3 christos got->contents + got_off + ie_off); 4539 1.1.1.3 christos rela.r_offset = sec_addr (got) + got_off + ie_off; 4540 1.1.1.3 christos rela.r_addend = 0; 4541 1.1.1.2 christos 4542 1.1.1.3 christos if (indx == 0) 4543 1.1.1.3 christos rela.r_addend = tlsoff (info, relocation); 4544 1.1.1.3 christos rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_TPRELNN); 4545 1.1.1.3 christos loongarch_elf_append_rela (output_bfd, relgot, &rela); 4546 1.1.1.2 christos } 4547 1.1.1.2 christos else 4548 1.1.1.2 christos { 4549 1.1.1.3 christos /* In a static link or an executable link with the symbol 4550 1.1.1.3 christos bindinglocally, compute offset directly. */ 4551 1.1.1.3 christos bfd_put_NN (output_bfd, tlsoff (info, relocation), 4552 1.1.1.3 christos got->contents + got_off + ie_off); 4553 1.1 christos } 4554 1.1 christos } 4555 1.1 christos } 4556 1.1.1.2 christos relocation = (got_off & (~(bfd_vma)1)) + sec_addr (got); 4557 1.1.1.2 christos if (is_desc) 4558 1.1.1.2 christos relocation += desc_off; 4559 1.1.1.2 christos else if (is_ie) 4560 1.1.1.2 christos relocation += ie_off; 4561 1.1.1.2 christos 4562 1.1.1.2 christos if (r_type == R_LARCH_TLS_LD_PC_HI20 4563 1.1.1.2 christos || r_type == R_LARCH_TLS_GD_PC_HI20 4564 1.1.1.2 christos || r_type == R_LARCH_TLS_IE_PC_HI20 4565 1.1.1.2 christos || r_type == R_LARCH_TLS_DESC_PC_HI20) 4566 1.1.1.2 christos RELOCATE_CALC_PC32_HI20 (relocation, pc); 4567 1.1.1.2 christos else if (r_type == R_LARCH_TLS_LD_PCREL20_S2 4568 1.1.1.2 christos || r_type == R_LARCH_TLS_GD_PCREL20_S2 4569 1.1.1.2 christos || r_type == R_LARCH_TLS_DESC_PCREL20_S2) 4570 1.1.1.2 christos relocation -= pc; 4571 1.1.1.2 christos /* else {} ABS relocations. */ 4572 1.1.1.2 christos break; 4573 1.1.1.2 christos 4574 1.1.1.2 christos case R_LARCH_TLS_DESC_PC_LO12: 4575 1.1.1.2 christos case R_LARCH_TLS_DESC64_PC_LO20: 4576 1.1.1.2 christos case R_LARCH_TLS_DESC64_PC_HI12: 4577 1.1.1.2 christos case R_LARCH_TLS_DESC_LO12: 4578 1.1.1.2 christos case R_LARCH_TLS_DESC64_LO20: 4579 1.1.1.2 christos case R_LARCH_TLS_DESC64_HI12: 4580 1.1.1.2 christos { 4581 1.1.1.2 christos unresolved_reloc = false; 4582 1.1.1.2 christos 4583 1.1.1.2 christos if (h) 4584 1.1.1.2 christos relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)1)); 4585 1.1.1.2 christos else 4586 1.1.1.2 christos relocation = sec_addr (got) 4587 1.1.1.2 christos + (local_got_offsets[r_symndx] & (~(bfd_vma)1)); 4588 1.1.1.2 christos 4589 1.1.1.2 christos tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx); 4590 1.1.1.2 christos /* Use both TLS_GD and TLS_DESC. */ 4591 1.1.1.3 christos if (GOT_TLS_GD_BOTH_P (tls_type)) 4592 1.1.1.2 christos relocation += 2 * GOT_ENTRY_SIZE; 4593 1.1.1.2 christos 4594 1.1.1.2 christos if (r_type == R_LARCH_TLS_DESC64_PC_LO20) 4595 1.1.1.2 christos RELOCATE_CALC_PC64_HI32 (relocation, pc - 8); 4596 1.1.1.2 christos else if (r_type == R_LARCH_TLS_DESC64_PC_HI12) 4597 1.1.1.2 christos RELOCATE_CALC_PC64_HI32 (relocation, pc - 12); 4598 1.1.1.2 christos 4599 1.1.1.2 christos break; 4600 1.1.1.2 christos } 4601 1.1.1.2 christos 4602 1.1.1.2 christos case R_LARCH_TLS_DESC_LD: 4603 1.1.1.2 christos case R_LARCH_TLS_DESC_CALL: 4604 1.1.1.2 christos unresolved_reloc = false; 4605 1.1.1.2 christos break; 4606 1.1 christos 4607 1.1.1.2 christos case R_LARCH_TLS_IE_PC_LO12: 4608 1.1.1.2 christos case R_LARCH_TLS_IE64_PC_LO20: 4609 1.1.1.2 christos case R_LARCH_TLS_IE64_PC_HI12: 4610 1.1.1.2 christos case R_LARCH_TLS_IE_LO12: 4611 1.1.1.2 christos case R_LARCH_TLS_IE64_LO20: 4612 1.1.1.2 christos case R_LARCH_TLS_IE64_HI12: 4613 1.1.1.2 christos unresolved_reloc = false; 4614 1.1.1.2 christos 4615 1.1.1.2 christos if (h) 4616 1.1.1.2 christos relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)1)); 4617 1.1.1.2 christos else 4618 1.1.1.2 christos relocation = sec_addr (got) 4619 1.1.1.2 christos + (local_got_offsets[r_symndx] & (~(bfd_vma)1)); 4620 1.1.1.2 christos 4621 1.1.1.2 christos tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx); 4622 1.1.1.2 christos /* Use TLS_GD TLS_DESC and TLS_IE. */ 4623 1.1.1.2 christos if (GOT_TLS_GD_BOTH_P (tls_type) && (tls_type & GOT_TLS_IE)) 4624 1.1.1.2 christos relocation += 4 * GOT_ENTRY_SIZE; 4625 1.1.1.2 christos /* Use GOT_TLS_GD_ANY_P (tls_type) and TLS_IE. */ 4626 1.1.1.2 christos else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE)) 4627 1.1.1.2 christos relocation += 2 * GOT_ENTRY_SIZE; 4628 1.1.1.2 christos 4629 1.1.1.2 christos if (r_type == R_LARCH_TLS_IE64_PC_LO20) 4630 1.1.1.2 christos RELOCATE_CALC_PC64_HI32 (relocation, pc - 8); 4631 1.1.1.2 christos else if (r_type == R_LARCH_TLS_IE64_PC_HI12) 4632 1.1.1.2 christos RELOCATE_CALC_PC64_HI32 (relocation, pc - 12); 4633 1.1.1.2 christos 4634 1.1.1.2 christos break; 4635 1.1.1.2 christos 4636 1.1.1.2 christos case R_LARCH_RELAX: 4637 1.1.1.2 christos case R_LARCH_ALIGN: 4638 1.1.1.2 christos r = bfd_reloc_continue; 4639 1.1.1.2 christos unresolved_reloc = false; 4640 1.1 christos break; 4641 1.1 christos 4642 1.1 christos default: 4643 1.1 christos break; 4644 1.1 christos } 4645 1.1 christos 4646 1.1 christos if (fatal) 4647 1.1 christos break; 4648 1.1 christos 4649 1.1 christos do 4650 1.1 christos { 4651 1.1 christos /* 'unresolved_reloc' means we haven't done it yet. 4652 1.1 christos We need help of dynamic linker to fix this memory location up. */ 4653 1.1 christos if (!unresolved_reloc) 4654 1.1 christos break; 4655 1.1 christos 4656 1.1 christos if (_bfd_elf_section_offset (output_bfd, info, input_section, 4657 1.1 christos rel->r_offset) == MINUS_ONE) 4658 1.1 christos /* WHY? May because it's invalid so skip checking. 4659 1.1.1.2 christos But why dynamic reloc a invalid section? */ 4660 1.1 christos break; 4661 1.1 christos 4662 1.1 christos if (input_section->output_section->flags & SEC_DEBUGGING) 4663 1.1 christos { 4664 1.1 christos fatal = (loongarch_reloc_is_fatal 4665 1.1 christos (info, input_bfd, input_section, rel, howto, 4666 1.1 christos bfd_reloc_dangerous, is_undefweak, name, 4667 1.1 christos "Seems dynamic linker not process " 4668 1.1 christos "sections 'SEC_DEBUGGING'.")); 4669 1.1 christos } 4670 1.1 christos if (!is_dyn) 4671 1.1 christos break; 4672 1.1 christos 4673 1.1 christos if ((info->flags & DF_TEXTREL) == 0) 4674 1.1 christos if (input_section->output_section->flags & SEC_READONLY) 4675 1.1 christos info->flags |= DF_TEXTREL; 4676 1.1 christos } 4677 1.1 christos while (0); 4678 1.1 christos 4679 1.1 christos if (fatal) 4680 1.1 christos break; 4681 1.1 christos 4682 1.1 christos loongarch_record_one_reloc (input_bfd, input_section, r_type, 4683 1.1 christos rel->r_offset, sym, h, rel->r_addend); 4684 1.1 christos 4685 1.1 christos if (r != bfd_reloc_continue) 4686 1.1 christos r = perform_relocation (rel, input_section, howto, relocation, 4687 1.1 christos input_bfd, contents); 4688 1.1 christos 4689 1.1 christos switch (r) 4690 1.1 christos { 4691 1.1 christos case bfd_reloc_dangerous: 4692 1.1 christos case bfd_reloc_continue: 4693 1.1 christos case bfd_reloc_ok: 4694 1.1 christos continue; 4695 1.1 christos 4696 1.1 christos case bfd_reloc_overflow: 4697 1.1 christos /* Overflow value can't be filled in. */ 4698 1.1 christos loongarch_dump_reloc_record (info->callbacks->info); 4699 1.1 christos info->callbacks->reloc_overflow 4700 1.1 christos (info, h ? &h->root : NULL, name, howto->name, rel->r_addend, 4701 1.1 christos input_bfd, input_section, rel->r_offset); 4702 1.1.1.3 christos if (r_type == R_LARCH_PCREL20_S2 4703 1.1.1.3 christos || r_type == R_LARCH_TLS_LD_PCREL20_S2 4704 1.1.1.3 christos || r_type == R_LARCH_TLS_GD_PCREL20_S2 4705 1.1.1.3 christos || r_type == R_LARCH_TLS_DESC_PCREL20_S2) 4706 1.1.1.3 christos _bfd_error_handler (_("recompile with 'gcc -mno-relax' or" 4707 1.1.1.3 christos " 'as -mno-relax' or 'ld --no-relax'")); 4708 1.1 christos break; 4709 1.1 christos 4710 1.1 christos case bfd_reloc_outofrange: 4711 1.1 christos /* Stack state incorrect. */ 4712 1.1 christos loongarch_dump_reloc_record (info->callbacks->info); 4713 1.1 christos info->callbacks->info 4714 1.1 christos ("%X%H: Internal stack state is incorrect.\n" 4715 1.1 christos "Want to push to full stack or pop from empty stack?\n", 4716 1.1 christos input_bfd, input_section, rel->r_offset); 4717 1.1 christos break; 4718 1.1 christos 4719 1.1 christos case bfd_reloc_notsupported: 4720 1.1 christos info->callbacks->info ("%X%H: Unknown relocation type.\n", input_bfd, 4721 1.1 christos input_section, rel->r_offset); 4722 1.1 christos break; 4723 1.1 christos 4724 1.1 christos default: 4725 1.1 christos info->callbacks->info ("%X%H: Internal: unknown error.\n", input_bfd, 4726 1.1 christos input_section, rel->r_offset); 4727 1.1 christos break; 4728 1.1 christos } 4729 1.1 christos 4730 1.1 christos fatal = true; 4731 1.1 christos } 4732 1.1 christos 4733 1.1 christos return !fatal; 4734 1.1 christos } 4735 1.1 christos 4736 1.1.1.3 christos /* A pending delete op during a linker relaxation trip, to be stored in a 4737 1.1.1.3 christos splay tree. 4738 1.1.1.3 christos The key is the starting offset of this op's deletion range, interpreted 4739 1.1.1.3 christos as if no delete op were executed for this trip. */ 4740 1.1.1.3 christos struct pending_delete_op 4741 1.1.1.3 christos { 4742 1.1.1.3 christos /* Number of bytes to delete at the address. */ 4743 1.1.1.3 christos bfd_size_type size; 4744 1.1.1.3 christos 4745 1.1.1.3 christos /* The total offset adjustment at the address as if all preceding delete 4746 1.1.1.3 christos ops had been executed. Used for calculating expected addresses after 4747 1.1.1.3 christos relaxation without actually adjusting anything. */ 4748 1.1.1.3 christos bfd_size_type cumulative_offset; 4749 1.1.1.3 christos }; 4750 1.1.1.3 christos 4751 1.1.1.3 christos static int 4752 1.1.1.3 christos pending_delete_op_compare (splay_tree_key a, splay_tree_key b) 4753 1.1.1.3 christos { 4754 1.1.1.3 christos bfd_vma off_a = (bfd_vma)a; 4755 1.1.1.3 christos bfd_vma off_b = (bfd_vma)b; 4756 1.1.1.3 christos 4757 1.1.1.3 christos if (off_a < off_b) 4758 1.1.1.3 christos return -1; 4759 1.1.1.3 christos else if (off_a > off_b) 4760 1.1.1.3 christos return 1; 4761 1.1.1.3 christos else 4762 1.1.1.3 christos return 0; 4763 1.1.1.3 christos } 4764 1.1.1.3 christos 4765 1.1.1.3 christos static void * 4766 1.1.1.3 christos _allocate_on_bfd (int wanted, void *data) 4767 1.1.1.3 christos { 4768 1.1.1.3 christos bfd *abfd = (bfd *)data; 4769 1.1.1.3 christos return bfd_alloc (abfd, wanted); 4770 1.1.1.3 christos } 4771 1.1.1.3 christos 4772 1.1.1.3 christos static void 4773 1.1.1.3 christos _deallocate_on_bfd (void *p ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED) 4774 1.1.1.3 christos { 4775 1.1.1.3 christos /* Nothing to do; the data will get released along with the associated BFD 4776 1.1.1.3 christos or an early bfd_release call. */ 4777 1.1.1.3 christos } 4778 1.1.1.3 christos 4779 1.1.1.3 christos static splay_tree 4780 1.1.1.3 christos pending_delete_ops_new (bfd *abfd) 4781 1.1.1.3 christos { 4782 1.1.1.3 christos /* The node values are allocated with bfd_zalloc, so they are automatically 4783 1.1.1.3 christos taken care of at BFD release time. */ 4784 1.1.1.3 christos return splay_tree_new_with_allocator (pending_delete_op_compare, NULL, NULL, 4785 1.1.1.3 christos _allocate_on_bfd, _deallocate_on_bfd, abfd); 4786 1.1.1.3 christos } 4787 1.1.1.3 christos 4788 1.1.1.3 christos static bfd_vma 4789 1.1.1.3 christos loongarch_calc_relaxed_addr (struct bfd_link_info *info, bfd_vma offset) 4790 1.1.1.3 christos { 4791 1.1.1.3 christos struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info); 4792 1.1.1.3 christos splay_tree pdops = htab->pending_delete_ops; 4793 1.1.1.3 christos struct pending_delete_op *op; 4794 1.1.1.3 christos splay_tree_node node; 4795 1.1.1.3 christos 4796 1.1.1.3 christos if (!pdops) 4797 1.1.1.3 christos /* Currently this means we are past the stages where byte deletion could 4798 1.1.1.3 christos possibly happen. */ 4799 1.1.1.3 christos return offset; 4800 1.1.1.3 christos 4801 1.1.1.3 christos /* Find the op that starts just before the given address. */ 4802 1.1.1.3 christos node = splay_tree_predecessor (pdops, (splay_tree_key)offset); 4803 1.1.1.3 christos if (node == NULL) 4804 1.1.1.3 christos /* Nothing has been deleted yet. */ 4805 1.1.1.3 christos return offset; 4806 1.1.1.3 christos BFD_ASSERT (((bfd_vma)node->key) < offset); 4807 1.1.1.3 christos op = (struct pending_delete_op *)node->value; 4808 1.1.1.3 christos 4809 1.1.1.3 christos /* If offset is inside this op's range, it is actually one of the deleted 4810 1.1.1.3 christos bytes, so the adjusted node->key should be returned in this case. */ 4811 1.1.1.3 christos bfd_vma op_end_off = (bfd_vma)node->key + op->size; 4812 1.1.1.3 christos if (offset < op_end_off) 4813 1.1.1.3 christos { 4814 1.1.1.3 christos offset = (bfd_vma)node->key; 4815 1.1.1.3 christos node = splay_tree_predecessor (pdops, node->key); 4816 1.1.1.3 christos op = node ? (struct pending_delete_op *)node->value : NULL; 4817 1.1.1.3 christos } 4818 1.1.1.3 christos 4819 1.1.1.3 christos return offset - (op ? op->cumulative_offset : 0); 4820 1.1.1.3 christos } 4821 1.1.1.3 christos 4822 1.1.1.3 christos static void 4823 1.1.1.2 christos loongarch_relax_delete_bytes (bfd *abfd, 4824 1.1.1.3 christos bfd_vma addr, 4825 1.1.1.3 christos size_t count, 4826 1.1.1.3 christos struct bfd_link_info *link_info) 4827 1.1.1.2 christos { 4828 1.1.1.3 christos struct loongarch_elf_link_hash_table *htab 4829 1.1.1.3 christos = loongarch_elf_hash_table (link_info); 4830 1.1.1.3 christos splay_tree pdops = htab->pending_delete_ops; 4831 1.1.1.3 christos splay_tree_node node; 4832 1.1.1.3 christos struct pending_delete_op *op = NULL, *new_op = NULL; 4833 1.1.1.3 christos bool need_new_node = true; 4834 1.1.1.2 christos 4835 1.1.1.3 christos if (count == 0) 4836 1.1.1.3 christos return; 4837 1.1.1.2 christos 4838 1.1.1.3 christos BFD_ASSERT (pdops != NULL); 4839 1.1.1.2 christos 4840 1.1.1.3 christos node = splay_tree_predecessor (pdops, addr); 4841 1.1.1.3 christos if (node) 4842 1.1.1.2 christos { 4843 1.1.1.3 christos op = (struct pending_delete_op *)node->value; 4844 1.1.1.3 christos if ((bfd_vma)node->key + op->size >= addr) 4845 1.1.1.2 christos { 4846 1.1.1.3 christos /* The previous op already covers this offset, coalesce the new op 4847 1.1.1.3 christos into it. */ 4848 1.1.1.3 christos op->size += count; 4849 1.1.1.3 christos op->cumulative_offset += count; 4850 1.1.1.3 christos need_new_node = false; 4851 1.1.1.2 christos } 4852 1.1.1.2 christos } 4853 1.1.1.2 christos 4854 1.1.1.3 christos if (need_new_node) 4855 1.1.1.2 christos { 4856 1.1.1.3 christos new_op = bfd_zalloc (abfd, sizeof (struct pending_delete_op)); 4857 1.1.1.3 christos new_op->size = count; 4858 1.1.1.3 christos new_op->cumulative_offset = (op ? op->cumulative_offset : 0) + count; 4859 1.1.1.3 christos node = splay_tree_insert (pdops, (splay_tree_key)addr, 4860 1.1.1.3 christos (splay_tree_value)new_op); 4861 1.1.1.3 christos } 4862 1.1.1.3 christos 4863 1.1.1.3 christos /* Adjust all cumulative offsets after this op. At this point either: 4864 1.1.1.3 christos - a new node is created, in which case `node` has been updated with the 4865 1.1.1.3 christos new value, or 4866 1.1.1.3 christos - an existing node is to be reused, in which case `node` is untouched by 4867 1.1.1.3 christos the new node logic above and appropriate to use, 4868 1.1.1.3 christos so we can just re-use `node` here. */ 4869 1.1.1.3 christos for (node = splay_tree_successor (pdops, node->key); node != NULL; 4870 1.1.1.3 christos node = splay_tree_successor (pdops, node->key)) 4871 1.1.1.3 christos { 4872 1.1.1.3 christos op = (struct pending_delete_op *)node->value; 4873 1.1.1.3 christos op->cumulative_offset += count; 4874 1.1.1.3 christos } 4875 1.1.1.3 christos } 4876 1.1.1.3 christos 4877 1.1.1.3 christos static void 4878 1.1.1.3 christos loongarch_relax_delete_or_nop (bfd *abfd, 4879 1.1.1.3 christos asection *sec, 4880 1.1.1.3 christos bfd_vma addr, 4881 1.1.1.3 christos size_t count, 4882 1.1.1.3 christos struct bfd_link_info *link_info) 4883 1.1.1.3 christos { 4884 1.1.1.3 christos struct bfd_elf_section_data *data = elf_section_data (sec); 4885 1.1.1.3 christos bfd_byte *contents = data->this_hdr.contents; 4886 1.1.1.3 christos 4887 1.1.1.3 christos BFD_ASSERT (count % 4 == 0); 4888 1.1.1.3 christos 4889 1.1.1.3 christos if (!loongarch_sec_closed_for_deletion (sec)) 4890 1.1.1.3 christos { 4891 1.1.1.3 christos /* Deletions are still possible within the section. */ 4892 1.1.1.3 christos loongarch_relax_delete_bytes (abfd, addr, count, link_info); 4893 1.1.1.3 christos return; 4894 1.1.1.3 christos } 4895 1.1.1.3 christos 4896 1.1.1.3 christos /* We can no longer delete bytes in the section after enforcing alignment. 4897 1.1.1.3 christos But as the resulting shrinkage may open up a few more relaxation chances, 4898 1.1.1.3 christos allowing unnecessary instructions to be replaced with NOPs instead of 4899 1.1.1.3 christos being removed altogether may still benefit performance to a lesser 4900 1.1.1.3 christos extent. */ 4901 1.1.1.3 christos for (; count; addr += 4, count -= 4) 4902 1.1.1.3 christos bfd_put (32, abfd, LARCH_NOP, contents + addr); 4903 1.1.1.3 christos } 4904 1.1.1.3 christos 4905 1.1.1.3 christos static void 4906 1.1.1.3 christos loongarch_relax_perform_deletes (bfd *abfd, asection *sec, 4907 1.1.1.3 christos struct bfd_link_info *link_info) 4908 1.1.1.3 christos { 4909 1.1.1.3 christos unsigned int i, symcount; 4910 1.1.1.3 christos bfd_vma toaddr = sec->size; 4911 1.1.1.3 christos struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd); 4912 1.1.1.3 christos Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 4913 1.1.1.3 christos unsigned int sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); 4914 1.1.1.3 christos struct bfd_elf_section_data *data = elf_section_data (sec); 4915 1.1.1.3 christos bfd_byte *contents = data->this_hdr.contents, *contents_end = NULL; 4916 1.1.1.3 christos struct relr_entry *relr = loongarch_elf_section_data (sec)->relr; 4917 1.1.1.3 christos struct loongarch_elf_link_hash_table *htab = 4918 1.1.1.3 christos loongarch_elf_hash_table (link_info); 4919 1.1.1.3 christos struct relr_entry *relr_end = NULL; 4920 1.1.1.3 christos splay_tree pdops = htab->pending_delete_ops; 4921 1.1.1.3 christos splay_tree_node node1 = NULL, node2 = NULL; 4922 1.1.1.3 christos 4923 1.1.1.3 christos if (htab->relr_count) 4924 1.1.1.3 christos relr_end = htab->relr + htab->relr_count; 4925 1.1.1.3 christos 4926 1.1.1.3 christos BFD_ASSERT (pdops != NULL); 4927 1.1.1.3 christos node1 = splay_tree_min (pdops); 4928 1.1.1.3 christos 4929 1.1.1.3 christos if (node1 == NULL) 4930 1.1.1.3 christos /* No pending delete ops, nothing to do. */ 4931 1.1.1.3 christos return; 4932 1.1.1.3 christos 4933 1.1.1.3 christos /* Actually delete the bytes. For each delete op the pointer arithmetics 4934 1.1.1.3 christos look like this: 4935 1.1.1.3 christos 4936 1.1.1.3 christos node1->key -\ /- node2->key 4937 1.1.1.3 christos |<- op1->size ->| | 4938 1.1.1.3 christos v v v 4939 1.1.1.3 christos ...-DDDDDD-------xxxxxxxxxxxxxxxxxSSSSSSxxxxxxxxxx----... 4940 1.1.1.3 christos ^ ^ ^ 4941 1.1.1.3 christos contents_end node1->key + op1->size 4942 1.1.1.3 christos | 4943 1.1.1.3 christos contents_end after this memmove 4944 1.1.1.3 christos 4945 1.1.1.3 christos where the "S" and "D" bytes are the memmove's source and destination 4946 1.1.1.3 christos respectively. In case node1 is the first op, contents_end is initialized 4947 1.1.1.3 christos to the op's start; in case node2 == NULL, the chunk's end is the section's 4948 1.1.1.3 christos end. The contents_end pointer will be bumped to the new end of content 4949 1.1.1.3 christos after each memmove. As no byte is added during the process, it is 4950 1.1.1.3 christos guaranteed to trail behind the delete ops, and all bytes overwritten are 4951 1.1.1.3 christos either already copied by an earlier memmove or meant to be discarded. 4952 1.1.1.3 christos 4953 1.1.1.3 christos For memmove, we need to translate offsets to pointers by adding them to 4954 1.1.1.3 christos `contents`. */ 4955 1.1.1.3 christos for (; node1; node1 = node2) 4956 1.1.1.3 christos { 4957 1.1.1.3 christos struct pending_delete_op *op1 = (struct pending_delete_op *)node1->value; 4958 1.1.1.3 christos bfd_vma op1_start_off = (bfd_vma)node1->key; 4959 1.1.1.3 christos bfd_vma op1_end_off = op1_start_off + op1->size; 4960 1.1.1.3 christos node2 = splay_tree_successor (pdops, node1->key); 4961 1.1.1.3 christos bfd_vma op2_start_off = node2 ? (bfd_vma)node2->key : toaddr; 4962 1.1.1.3 christos bfd_size_type count = op2_start_off - op1_end_off; 4963 1.1.1.3 christos 4964 1.1.1.3 christos if (count) 4965 1.1.1.3 christos { 4966 1.1.1.3 christos if (contents_end == NULL) 4967 1.1.1.3 christos /* Start from the end of the first unmodified content chunk. */ 4968 1.1.1.3 christos contents_end = contents + op1_start_off; 4969 1.1.1.3 christos 4970 1.1.1.3 christos memmove (contents_end, contents + op1_end_off, count); 4971 1.1.1.3 christos contents_end += count; 4972 1.1.1.3 christos } 4973 1.1.1.3 christos 4974 1.1.1.3 christos /* Adjust the section size once, when we have reached the end. */ 4975 1.1.1.3 christos if (node2 == NULL) 4976 1.1.1.3 christos sec->size -= op1->cumulative_offset; 4977 1.1.1.3 christos } 4978 1.1.1.3 christos 4979 1.1.1.3 christos /* Adjust the location of all of the relocs. Note that we need not 4980 1.1.1.3 christos adjust the addends, since all PC-relative references must be against 4981 1.1.1.3 christos symbols, which we will adjust below. */ 4982 1.1.1.3 christos for (i = 0; i < sec->reloc_count; i++) 4983 1.1.1.3 christos if (data->relocs[i].r_offset < toaddr) 4984 1.1.1.3 christos data->relocs[i].r_offset = loongarch_calc_relaxed_addr ( 4985 1.1.1.3 christos link_info, data->relocs[i].r_offset); 4986 1.1.1.3 christos 4987 1.1.1.3 christos /* Likewise for relative relocs to be packed into .relr. */ 4988 1.1.1.3 christos for (; relr && relr < relr_end && relr->sec == sec; relr++) 4989 1.1.1.3 christos if (relr->off < toaddr) 4990 1.1.1.3 christos relr->off = loongarch_calc_relaxed_addr (link_info, relr->off); 4991 1.1.1.3 christos 4992 1.1.1.3 christos /* Adjust the local symbols defined in this section. */ 4993 1.1.1.3 christos for (i = 0; i < symtab_hdr->sh_info; i++) 4994 1.1.1.3 christos { 4995 1.1.1.3 christos Elf_Internal_Sym *sym = (Elf_Internal_Sym *) symtab_hdr->contents + i; 4996 1.1.1.3 christos if (sym->st_shndx == sec_shndx) 4997 1.1.1.3 christos { 4998 1.1.1.3 christos bfd_vma orig_value = sym->st_value; 4999 1.1.1.3 christos if (orig_value <= toaddr) 5000 1.1.1.3 christos sym->st_value 5001 1.1.1.3 christos = loongarch_calc_relaxed_addr (link_info, orig_value); 5002 1.1.1.3 christos 5003 1.1.1.3 christos /* If the symbol *spans* some deleted bytes, that is its *end* is in 5004 1.1.1.3 christos the moved bytes but its *start* isn't, then we must adjust its 5005 1.1.1.3 christos size. 5006 1.1.1.3 christos 5007 1.1.1.3 christos This test needs to use the original value of st_value, otherwise 5008 1.1.1.3 christos we might accidentally decrease size when deleting bytes right 5009 1.1.1.3 christos before the symbol. */ 5010 1.1.1.3 christos bfd_vma sym_end = orig_value + sym->st_size; 5011 1.1.1.3 christos if (sym_end <= toaddr) 5012 1.1.1.3 christos { 5013 1.1.1.3 christos splay_tree_node node = splay_tree_predecessor ( 5014 1.1.1.3 christos pdops, (splay_tree_key)orig_value); 5015 1.1.1.3 christos for (; node; node = splay_tree_successor (pdops, node->key)) 5016 1.1.1.3 christos { 5017 1.1.1.3 christos bfd_vma addr = (bfd_vma)node->key; 5018 1.1.1.3 christos struct pending_delete_op *op 5019 1.1.1.3 christos = (struct pending_delete_op *)node->value; 5020 1.1.1.3 christos 5021 1.1.1.3 christos if (addr >= sym_end) 5022 1.1.1.3 christos break; 5023 1.1.1.3 christos if (orig_value <= addr && sym_end > addr) 5024 1.1.1.3 christos sym->st_size -= op->size; 5025 1.1.1.3 christos } 5026 1.1.1.3 christos } 5027 1.1.1.3 christos } 5028 1.1.1.3 christos } 5029 1.1.1.3 christos 5030 1.1.1.3 christos /* Now adjust the global symbols defined in this section. */ 5031 1.1.1.3 christos symcount = ((symtab_hdr->sh_size / sizeof (ElfNN_External_Sym)) 5032 1.1.1.3 christos - symtab_hdr->sh_info); 5033 1.1.1.3 christos 5034 1.1.1.3 christos for (i = 0; i < symcount; i++) 5035 1.1.1.3 christos { 5036 1.1.1.3 christos struct elf_link_hash_entry *sym_hash = sym_hashes[i]; 5037 1.1.1.2 christos 5038 1.1.1.2 christos /* The '--wrap SYMBOL' option is causing a pain when the object file, 5039 1.1.1.2 christos containing the definition of __wrap_SYMBOL, includes a direct 5040 1.1.1.2 christos call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference 5041 1.1.1.2 christos the same symbol (which is __wrap_SYMBOL), but still exist as two 5042 1.1.1.2 christos different symbols in 'sym_hashes', we don't want to adjust 5043 1.1.1.2 christos the global symbol __wrap_SYMBOL twice. 5044 1.1.1.2 christos 5045 1.1.1.2 christos The same problem occurs with symbols that are versioned_hidden, as 5046 1.1.1.2 christos foo becomes an alias for foo@BAR, and hence they need the same 5047 1.1.1.2 christos treatment. */ 5048 1.1.1.2 christos if (link_info->wrap_hash != NULL 5049 1.1.1.2 christos || sym_hash->versioned != unversioned) 5050 1.1.1.2 christos { 5051 1.1.1.2 christos struct elf_link_hash_entry **cur_sym_hashes; 5052 1.1.1.2 christos 5053 1.1.1.2 christos /* Loop only over the symbols which have already been checked. */ 5054 1.1.1.2 christos for (cur_sym_hashes = sym_hashes; cur_sym_hashes < &sym_hashes[i]; 5055 1.1.1.2 christos cur_sym_hashes++) 5056 1.1.1.2 christos { 5057 1.1.1.2 christos /* If the current symbol is identical to 'sym_hash', that means 5058 1.1.1.2 christos the symbol was already adjusted (or at least checked). */ 5059 1.1.1.2 christos if (*cur_sym_hashes == sym_hash) 5060 1.1.1.2 christos break; 5061 1.1.1.2 christos } 5062 1.1.1.2 christos /* Don't adjust the symbol again. */ 5063 1.1.1.2 christos if (cur_sym_hashes < &sym_hashes[i]) 5064 1.1.1.2 christos continue; 5065 1.1.1.2 christos } 5066 1.1.1.2 christos 5067 1.1.1.2 christos if ((sym_hash->root.type == bfd_link_hash_defined 5068 1.1.1.2 christos || sym_hash->root.type == bfd_link_hash_defweak) 5069 1.1.1.2 christos && sym_hash->root.u.def.section == sec) 5070 1.1.1.2 christos { 5071 1.1.1.3 christos bfd_vma orig_value = sym_hash->root.u.def.value; 5072 1.1.1.3 christos 5073 1.1.1.3 christos /* As above, adjust the value. */ 5074 1.1.1.3 christos if (orig_value <= toaddr) 5075 1.1.1.3 christos sym_hash->root.u.def.value 5076 1.1.1.3 christos = loongarch_calc_relaxed_addr (link_info, orig_value); 5077 1.1.1.2 christos 5078 1.1.1.2 christos /* As above, adjust the size if needed. */ 5079 1.1.1.3 christos bfd_vma sym_end = orig_value + sym_hash->size; 5080 1.1.1.3 christos if (sym_end <= toaddr) 5081 1.1.1.3 christos { 5082 1.1.1.3 christos splay_tree_node node = splay_tree_predecessor ( 5083 1.1.1.3 christos pdops, (splay_tree_key)orig_value); 5084 1.1.1.3 christos for (; node; node = splay_tree_successor (pdops, node->key)) 5085 1.1.1.3 christos { 5086 1.1.1.3 christos bfd_vma addr = (bfd_vma)node->key; 5087 1.1.1.3 christos struct pending_delete_op *op 5088 1.1.1.3 christos = (struct pending_delete_op *)node->value; 5089 1.1.1.3 christos 5090 1.1.1.3 christos if (addr >= sym_end) 5091 1.1.1.3 christos break; 5092 1.1.1.3 christos if (orig_value <= addr && sym_end > addr) 5093 1.1.1.3 christos sym_hash->size -= op->size; 5094 1.1.1.3 christos } 5095 1.1.1.3 christos } 5096 1.1.1.2 christos } 5097 1.1.1.2 christos } 5098 1.1.1.3 christos } 5099 1.1.1.2 christos 5100 1.1.1.3 christos /* Start perform TLS type transition. 5101 1.1.1.3 christos Currently there are three cases of relocation handled here: 5102 1.1.1.3 christos DESC -> IE, DEC -> LE and IE -> LE. */ 5103 1.1.1.3 christos static bool 5104 1.1.1.3 christos loongarch_tls_perform_trans (bfd *abfd, asection *sec, 5105 1.1.1.3 christos Elf_Internal_Rela *rel, 5106 1.1.1.3 christos struct elf_link_hash_entry *h, 5107 1.1.1.3 christos struct bfd_link_info *info) 5108 1.1.1.3 christos { 5109 1.1.1.3 christos unsigned long insn; 5110 1.1.1.3 christos bool local_exec = bfd_link_executable (info) 5111 1.1.1.3 christos && LARCH_REF_LOCAL (info, h); 5112 1.1.1.3 christos bfd_byte *contents = elf_section_data (sec)->this_hdr.contents; 5113 1.1.1.3 christos unsigned long r_type = ELFNN_R_TYPE (rel->r_info); 5114 1.1.1.3 christos unsigned long r_symndx = ELFNN_R_SYM (rel->r_info); 5115 1.1.1.3 christos 5116 1.1.1.3 christos switch (r_type) 5117 1.1.1.3 christos { 5118 1.1.1.3 christos case R_LARCH_TLS_DESC_PC_HI20: 5119 1.1.1.3 christos if (local_exec) 5120 1.1.1.3 christos { 5121 1.1.1.3 christos /* DESC -> LE relaxation: 5122 1.1.1.3 christos pcalalau12i $a0,%desc_pc_hi20(var) => 5123 1.1.1.3 christos lu12i.w $a0,%le_hi20(var) 5124 1.1.1.3 christos */ 5125 1.1.1.3 christos bfd_put (32, abfd, LARCH_OP_LU12I_W | LARCH_RD_A0, 5126 1.1.1.3 christos contents + rel->r_offset); 5127 1.1.1.3 christos rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_LE_HI20); 5128 1.1.1.3 christos } 5129 1.1.1.3 christos else 5130 1.1.1.3 christos { 5131 1.1.1.3 christos /* DESC -> IE relaxation: 5132 1.1.1.3 christos pcalalau12i $a0,%desc_pc_hi20(var) => 5133 1.1.1.3 christos pcalalau12i $a0,%ie_pc_hi20(var) 5134 1.1.1.3 christos */ 5135 1.1.1.3 christos rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_IE_PC_HI20); 5136 1.1.1.3 christos } 5137 1.1.1.3 christos return true; 5138 1.1.1.3 christos 5139 1.1.1.3 christos case R_LARCH_TLS_DESC_PC_LO12: 5140 1.1.1.3 christos if (local_exec) 5141 1.1.1.3 christos { 5142 1.1.1.3 christos /* DESC -> LE relaxation: 5143 1.1.1.3 christos addi.d $a0,$a0,%desc_pc_lo12(var) => 5144 1.1.1.3 christos ori $a0,$a0,le_lo12(var) 5145 1.1.1.3 christos */ 5146 1.1.1.3 christos insn = LARCH_OP_ORI | LARCH_RD_RJ_A0; 5147 1.1.1.3 christos bfd_put (32, abfd, LARCH_OP_ORI | LARCH_RD_RJ_A0, 5148 1.1.1.3 christos contents + rel->r_offset); 5149 1.1.1.3 christos rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_LE_LO12); 5150 1.1.1.3 christos } 5151 1.1.1.3 christos else 5152 1.1.1.3 christos { 5153 1.1.1.3 christos /* DESC -> IE relaxation: 5154 1.1.1.3 christos addi.d $a0,$a0,%desc_pc_lo12(var) => 5155 1.1.1.3 christos ld.d $a0,$a0,%ie_pc_lo12(var) 5156 1.1.1.3 christos */ 5157 1.1.1.3 christos bfd_put (32, abfd, LARCH_OP_LD_D | LARCH_RD_RJ_A0, 5158 1.1.1.3 christos contents + rel->r_offset); 5159 1.1.1.3 christos rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_IE_PC_LO12); 5160 1.1.1.3 christos } 5161 1.1.1.3 christos return true; 5162 1.1.1.3 christos 5163 1.1.1.3 christos case R_LARCH_TLS_DESC_LD: 5164 1.1.1.3 christos case R_LARCH_TLS_DESC_CALL: 5165 1.1.1.3 christos /* DESC -> LE/IE relaxation: 5166 1.1.1.3 christos ld.d $ra,$a0,%desc_ld(var) => NOP 5167 1.1.1.3 christos jirl $ra,$ra,%desc_call(var) => NOP 5168 1.1.1.3 christos */ 5169 1.1.1.3 christos rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE); 5170 1.1.1.3 christos bfd_put (32, abfd, LARCH_NOP, contents + rel->r_offset); 5171 1.1.1.3 christos /* link with -relax option will delete NOP. */ 5172 1.1.1.3 christos if (!info->disable_target_specific_optimizations) 5173 1.1.1.3 christos loongarch_relax_delete_or_nop (abfd, sec, rel->r_offset, 4, info); 5174 1.1.1.3 christos return true; 5175 1.1.1.3 christos 5176 1.1.1.3 christos case R_LARCH_TLS_IE_PC_HI20: 5177 1.1.1.3 christos if (local_exec) 5178 1.1.1.3 christos { 5179 1.1.1.3 christos /* IE -> LE relaxation: 5180 1.1.1.3 christos pcalalau12i $rd,%ie_pc_hi20(var) => 5181 1.1.1.3 christos lu12i.w $rd,%le_hi20(var) 5182 1.1.1.3 christos */ 5183 1.1.1.3 christos insn = bfd_getl32 (contents + rel->r_offset); 5184 1.1.1.3 christos bfd_put (32, abfd, LARCH_OP_LU12I_W | LARCH_GET_RD(insn), 5185 1.1.1.3 christos contents + rel->r_offset); 5186 1.1.1.3 christos rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_LE_HI20); 5187 1.1.1.3 christos } 5188 1.1.1.3 christos return true; 5189 1.1.1.3 christos 5190 1.1.1.3 christos case R_LARCH_TLS_IE_PC_LO12: 5191 1.1.1.3 christos if (local_exec) 5192 1.1.1.3 christos { 5193 1.1.1.3 christos /* IE -> LE relaxation: 5194 1.1.1.3 christos ld.d $rd,$rj,%%ie_pc_lo12(var) => 5195 1.1.1.3 christos ori $rd,$rj,le_lo12(var) 5196 1.1.1.3 christos */ 5197 1.1.1.3 christos insn = bfd_getl32 (contents + rel->r_offset); 5198 1.1.1.3 christos bfd_put (32, abfd, LARCH_OP_ORI | (insn & 0x3ff), 5199 1.1.1.3 christos contents + rel->r_offset); 5200 1.1.1.3 christos rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_LE_LO12); 5201 1.1.1.3 christos } 5202 1.1.1.3 christos return true; 5203 1.1.1.3 christos } 5204 1.1.1.3 christos 5205 1.1.1.3 christos return false; 5206 1.1.1.2 christos } 5207 1.1.1.3 christos 5208 1.1.1.3 christos 5209 1.1.1.2 christos /* Relax tls le, mainly relax the process of getting TLS le symbolic addresses. 5210 1.1.1.2 christos there are three situations in which an assembly instruction sequence needs to 5211 1.1.1.2 christos be relaxed: 5212 1.1.1.2 christos symbol address = tp + offset (symbol),offset (symbol) = le_hi20_r + le_lo12_r 5213 1.1.1.2 christos 5214 1.1.1.2 christos Case 1: 5215 1.1.1.2 christos in this case, the rd register in the st.{w/d} instruction does not store the 5216 1.1.1.2 christos full tls symbolic address, but tp + le_hi20_r, which is a part of the tls 5217 1.1.1.2 christos symbolic address, and then obtains the rd + le_lo12_r address through the 5218 1.1.1.2 christos st.w instruction feature. 5219 1.1.1.2 christos this is the full tls symbolic address (tp + le_hi20_r + le_lo12_r). 5220 1.1.1.2 christos 5221 1.1.1.2 christos before relax: after relax: 5222 1.1.1.2 christos 5223 1.1.1.2 christos lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted) 5224 1.1.1.2 christos add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted) 5225 1.1.1.2 christos st.{w/d} $rs,$rd,%le_lo12_r (sym) ==> st.{w/d} $rs,$tp,%le_lo12_r (sym) 5226 1.1.1.2 christos 5227 1.1.1.2 christos Case 2: 5228 1.1.1.2 christos in this case, ld.{w/d} is similar to st.{w/d} in case1. 5229 1.1.1.2 christos 5230 1.1.1.2 christos before relax: after relax: 5231 1.1.1.2 christos 5232 1.1.1.2 christos lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted) 5233 1.1.1.2 christos add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted) 5234 1.1.1.2 christos ld.{w/d} $rs,$rd,%le_lo12_r (sym) ==> ld.{w/d} $rs,$tp,%le_lo12_r (sym) 5235 1.1.1.2 christos 5236 1.1.1.2 christos Case 3: 5237 1.1.1.2 christos in this case,the rs register in addi.{w/d} stores the full address of the tls 5238 1.1.1.2 christos symbol (tp + le_hi20_r + le_lo12_r). 5239 1.1.1.2 christos 5240 1.1.1.2 christos before relax: after relax: 5241 1.1.1.2 christos 5242 1.1.1.2 christos lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted) 5243 1.1.1.2 christos add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted) 5244 1.1.1.2 christos addi.{w/d} $rs,$rd,%le_lo12_r (sym) ==> addi.{w/d} $rs,$tp,%le_lo12_r (sym) 5245 1.1.1.3 christos 5246 1.1.1.3 christos 5247 1.1.1.3 christos For relocation of all old LE instruction sequences, whether it is 5248 1.1.1.3 christos a normal code model or an extreme code model, relaxation will be 5249 1.1.1.3 christos performed when the relaxation conditions are met. 5250 1.1.1.3 christos 5251 1.1.1.3 christos nomal code model: 5252 1.1.1.3 christos lu12i.w $rd,%le_hi20(sym) => (deleted) 5253 1.1.1.3 christos ori $rd,$rd,le_lo12(sym) => ori $rd,$zero,le_lo12(sym) 5254 1.1.1.3 christos 5255 1.1.1.3 christos extreme code model: 5256 1.1.1.3 christos lu12i.w $rd,%le_hi20(sym) => (deleted) 5257 1.1.1.3 christos ori $rd,$rd,%le_lo12(sym) => ori $rd,$zero,le_lo12(sym) 5258 1.1.1.3 christos lu32i.d $rd,%le64_lo20(sym) => (deleted) 5259 1.1.1.3 christos lu52i.d $rd,$rd,%le64_hi12(sym) => (deleted) 5260 1.1.1.2 christos */ 5261 1.1.1.2 christos static bool 5262 1.1.1.3 christos loongarch_relax_tls_le (bfd *abfd, asection *sec, asection *sym_sec, 5263 1.1.1.3 christos Elf_Internal_Rela *rel, bfd_vma symval, 5264 1.1.1.2 christos struct bfd_link_info *link_info, 5265 1.1.1.3 christos bool *agin ATTRIBUTE_UNUSED, 5266 1.1.1.3 christos bfd_vma max_alignment ATTRIBUTE_UNUSED) 5267 1.1.1.2 christos { 5268 1.1.1.2 christos bfd_byte *contents = elf_section_data (sec)->this_hdr.contents; 5269 1.1.1.2 christos uint32_t insn = bfd_get (32, abfd, contents + rel->r_offset); 5270 1.1.1.2 christos static uint32_t insn_rj,insn_rd; 5271 1.1.1.2 christos symval = symval - elf_hash_table (link_info)->tls_sec->vma; 5272 1.1.1.3 christos if (sym_sec == sec) 5273 1.1.1.3 christos symval = loongarch_calc_relaxed_addr (link_info, symval); 5274 1.1.1.3 christos /* The old LE instruction sequence can be relaxed when the symbol offset 5275 1.1.1.3 christos is smaller than the 12-bit range. */ 5276 1.1.1.3 christos if (symval <= 0xfff) 5277 1.1.1.2 christos { 5278 1.1.1.2 christos switch (ELFNN_R_TYPE (rel->r_info)) 5279 1.1.1.2 christos { 5280 1.1.1.3 christos /*if offset < 0x800, then perform the new le instruction 5281 1.1.1.3 christos sequence relax. */ 5282 1.1.1.3 christos case R_LARCH_TLS_LE_HI20_R: 5283 1.1.1.3 christos case R_LARCH_TLS_LE_ADD_R: 5284 1.1.1.3 christos /* delete insn. */ 5285 1.1.1.3 christos if (symval < 0x800) 5286 1.1.1.3 christos { 5287 1.1.1.3 christos rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE); 5288 1.1.1.3 christos loongarch_relax_delete_or_nop (abfd, sec, rel->r_offset, 5289 1.1.1.3 christos 4, link_info); 5290 1.1.1.3 christos } 5291 1.1.1.3 christos break; 5292 1.1.1.3 christos 5293 1.1.1.3 christos case R_LARCH_TLS_LE_LO12_R: 5294 1.1.1.3 christos if (symval < 0x800) 5295 1.1.1.3 christos { 5296 1.1.1.3 christos /* Change rj to $tp. */ 5297 1.1.1.3 christos insn_rj = 0x2 << 5; 5298 1.1.1.3 christos /* Get rd register. */ 5299 1.1.1.3 christos insn_rd = LARCH_GET_RD (insn); 5300 1.1.1.3 christos /* Write symbol offset. */ 5301 1.1.1.3 christos symval <<= 10; 5302 1.1.1.3 christos /* Writes the modified instruction. */ 5303 1.1.1.3 christos insn = insn & LARCH_MK_ADDI_D; 5304 1.1.1.3 christos insn = insn | symval | insn_rj | insn_rd; 5305 1.1.1.3 christos bfd_put (32, abfd, insn, contents + rel->r_offset); 5306 1.1.1.3 christos } 5307 1.1.1.3 christos break; 5308 1.1.1.3 christos 5309 1.1.1.3 christos case R_LARCH_TLS_LE_HI20: 5310 1.1.1.3 christos case R_LARCH_TLS_LE64_LO20: 5311 1.1.1.3 christos case R_LARCH_TLS_LE64_HI12: 5312 1.1.1.3 christos rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE); 5313 1.1.1.3 christos loongarch_relax_delete_or_nop (abfd, sec, rel->r_offset, 5314 1.1.1.3 christos 4, link_info); 5315 1.1.1.3 christos break; 5316 1.1.1.3 christos 5317 1.1.1.3 christos case R_LARCH_TLS_LE_LO12: 5318 1.1.1.3 christos bfd_put (32, abfd, LARCH_OP_ORI | LARCH_GET_RD (insn), 5319 1.1.1.3 christos contents + rel->r_offset); 5320 1.1.1.3 christos break; 5321 1.1.1.3 christos 5322 1.1.1.3 christos default: 5323 1.1.1.3 christos break; 5324 1.1.1.2 christos } 5325 1.1.1.2 christos } 5326 1.1.1.2 christos return true; 5327 1.1.1.2 christos } 5328 1.1.1.2 christos 5329 1.1.1.3 christos /* Whether two sections in the same segment. */ 5330 1.1.1.3 christos static bool 5331 1.1.1.3 christos loongarch_two_sections_in_same_segment (bfd *abfd, asection *a, asection *b) 5332 1.1.1.3 christos { 5333 1.1.1.3 christos struct elf_segment_map *m; 5334 1.1.1.3 christos for (m = elf_seg_map (abfd); m != NULL; m = m->next) 5335 1.1.1.3 christos { 5336 1.1.1.3 christos int i; 5337 1.1.1.3 christos int j = 0; 5338 1.1.1.3 christos for (i = m->count - 1; i >= 0; i--) 5339 1.1.1.3 christos { 5340 1.1.1.3 christos if (m->sections[i] == a) 5341 1.1.1.3 christos j++; 5342 1.1.1.3 christos if (m->sections[i] == b) 5343 1.1.1.3 christos j++; 5344 1.1.1.3 christos } 5345 1.1.1.3 christos if (1 == j) 5346 1.1.1.3 christos return false; 5347 1.1.1.3 christos if (2 == j) 5348 1.1.1.3 christos return true; 5349 1.1.1.3 christos } 5350 1.1.1.3 christos return false; 5351 1.1.1.3 christos } 5352 1.1.1.3 christos 5353 1.1.1.2 christos /* Relax pcalau12i,addi.d => pcaddi. */ 5354 1.1.1.2 christos static bool 5355 1.1.1.2 christos loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec, 5356 1.1.1.2 christos Elf_Internal_Rela *rel_hi, bfd_vma symval, 5357 1.1.1.2 christos struct bfd_link_info *info, bool *again, 5358 1.1.1.2 christos bfd_vma max_alignment) 5359 1.1.1.2 christos { 5360 1.1.1.2 christos bfd_byte *contents = elf_section_data (sec)->this_hdr.contents; 5361 1.1.1.2 christos Elf_Internal_Rela *rel_lo = rel_hi + 2; 5362 1.1.1.2 christos uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset); 5363 1.1.1.2 christos uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset); 5364 1.1.1.3 christos uint32_t rd = LARCH_GET_RD (pca); 5365 1.1.1.2 christos 5366 1.1.1.2 christos /* This section's output_offset need to subtract the bytes of instructions 5367 1.1.1.2 christos relaxed by the previous sections, so it needs to be updated beforehand. 5368 1.1.1.2 christos size_input_section already took care of updating it after relaxation, 5369 1.1.1.2 christos so we additionally update once here. */ 5370 1.1.1.2 christos sec->output_offset = sec->output_section->size; 5371 1.1.1.3 christos bfd_vma pc = sec_addr (sec) 5372 1.1.1.3 christos + loongarch_calc_relaxed_addr (info, rel_hi->r_offset); 5373 1.1.1.3 christos if (sym_sec == sec) 5374 1.1.1.3 christos symval = sec_addr (sec) 5375 1.1.1.3 christos + loongarch_calc_relaxed_addr (info, symval - sec_addr (sec)); 5376 1.1.1.3 christos 5377 1.1.1.3 christos /* If pc and symbol not in the same segment, add/sub segment alignment. */ 5378 1.1.1.3 christos if (!loongarch_two_sections_in_same_segment (info->output_bfd, 5379 1.1.1.3 christos sec->output_section, 5380 1.1.1.3 christos sym_sec->output_section)) 5381 1.1.1.3 christos max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize 5382 1.1.1.3 christos : max_alignment; 5383 1.1.1.3 christos 5384 1.1.1.3 christos if (symval > pc) 5385 1.1.1.3 christos pc -= (max_alignment > 4 ? max_alignment : 0); 5386 1.1.1.3 christos else if (symval < pc) 5387 1.1.1.3 christos pc += (max_alignment > 4 ? max_alignment : 0); 5388 1.1.1.2 christos 5389 1.1.1.3 christos const uint32_t pcaddi = LARCH_OP_PCADDI; 5390 1.1.1.2 christos 5391 1.1.1.2 christos /* Is pcalau12i + addi.d insns? */ 5392 1.1.1.2 christos if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_PCALA_LO12) 5393 1.1.1.3 christos || !LARCH_INSN_ADDI_D (add) 5394 1.1.1.2 christos /* Is pcalau12i $rd + addi.d $rd,$rd? */ 5395 1.1.1.3 christos || (LARCH_GET_RD (add) != rd) 5396 1.1.1.3 christos || (LARCH_GET_RJ (add) != rd) 5397 1.1.1.2 christos /* Can be relaxed to pcaddi? */ 5398 1.1.1.2 christos || (symval & 0x3) /* 4 bytes align. */ 5399 1.1.1.2 christos || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xffe00000) 5400 1.1.1.2 christos || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x1ffffc)) 5401 1.1.1.2 christos return false; 5402 1.1.1.2 christos 5403 1.1.1.2 christos /* Continue next relax trip. */ 5404 1.1.1.2 christos *again = true; 5405 1.1.1.2 christos 5406 1.1.1.2 christos pca = pcaddi | rd; 5407 1.1.1.2 christos bfd_put (32, abfd, pca, contents + rel_hi->r_offset); 5408 1.1.1.2 christos 5409 1.1.1.2 christos /* Adjust relocations. */ 5410 1.1.1.2 christos rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info), 5411 1.1.1.2 christos R_LARCH_PCREL20_S2); 5412 1.1.1.2 christos rel_lo->r_info = ELFNN_R_INFO (0, R_LARCH_NONE); 5413 1.1.1.2 christos 5414 1.1.1.3 christos loongarch_relax_delete_or_nop (abfd, sec, rel_lo->r_offset, 4, info); 5415 1.1.1.2 christos 5416 1.1.1.2 christos return true; 5417 1.1.1.2 christos } 5418 1.1.1.2 christos 5419 1.1.1.3 christos /* call36 f -> bl f 5420 1.1.1.3 christos tail36 $t0, f -> b f. */ 5421 1.1.1.3 christos static bool 5422 1.1.1.3 christos loongarch_relax_call36 (bfd *abfd, asection *sec, asection *sym_sec, 5423 1.1.1.3 christos Elf_Internal_Rela *rel, bfd_vma symval, 5424 1.1.1.3 christos struct bfd_link_info *info, bool *again, 5425 1.1.1.3 christos bfd_vma max_alignment) 5426 1.1.1.3 christos { 5427 1.1.1.3 christos bfd_byte *contents = elf_section_data (sec)->this_hdr.contents; 5428 1.1.1.3 christos uint32_t jirl = bfd_get (32, abfd, contents + rel->r_offset + 4); 5429 1.1.1.3 christos uint32_t rd = LARCH_GET_RD (jirl); 5430 1.1.1.3 christos 5431 1.1.1.3 christos /* This section's output_offset need to subtract the bytes of instructions 5432 1.1.1.3 christos relaxed by the previous sections, so it needs to be updated beforehand. 5433 1.1.1.3 christos size_input_section already took care of updating it after relaxation, 5434 1.1.1.3 christos so we additionally update once here. */ 5435 1.1.1.3 christos sec->output_offset = sec->output_section->size; 5436 1.1.1.3 christos bfd_vma pc = sec_addr (sec) 5437 1.1.1.3 christos + loongarch_calc_relaxed_addr (info, rel->r_offset); 5438 1.1.1.3 christos if (sym_sec == sec) 5439 1.1.1.3 christos symval = sec_addr (sec) 5440 1.1.1.3 christos + loongarch_calc_relaxed_addr (info, symval - sec_addr (sec)); 5441 1.1.1.3 christos 5442 1.1.1.3 christos /* If pc and symbol not in the same segment, add/sub segment alignment. */ 5443 1.1.1.3 christos if (!loongarch_two_sections_in_same_segment (info->output_bfd, 5444 1.1.1.3 christos sec->output_section, 5445 1.1.1.3 christos sym_sec->output_section)) 5446 1.1.1.3 christos max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize 5447 1.1.1.3 christos : max_alignment; 5448 1.1.1.3 christos 5449 1.1.1.3 christos if (symval > pc) 5450 1.1.1.3 christos pc -= (max_alignment > 4 ? max_alignment : 0); 5451 1.1.1.3 christos else if (symval < pc) 5452 1.1.1.3 christos pc += (max_alignment > 4 ? max_alignment : 0); 5453 1.1.1.3 christos 5454 1.1.1.3 christos /* Is pcalau12i + addi.d insns? */ 5455 1.1.1.3 christos if (!LARCH_INSN_JIRL (jirl) 5456 1.1.1.3 christos || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xf8000000) 5457 1.1.1.3 christos || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x7fffffc)) 5458 1.1.1.3 christos return false; 5459 1.1.1.3 christos 5460 1.1.1.3 christos /* Continue next relax trip. */ 5461 1.1.1.3 christos *again = true; 5462 1.1.1.3 christos 5463 1.1.1.3 christos const uint32_t bl = LARCH_OP_BL; 5464 1.1.1.3 christos const uint32_t b = LARCH_OP_B; 5465 1.1.1.3 christos 5466 1.1.1.3 christos if (rd) 5467 1.1.1.3 christos bfd_put (32, abfd, bl, contents + rel->r_offset); 5468 1.1.1.3 christos else 5469 1.1.1.3 christos bfd_put (32, abfd, b, contents + rel->r_offset); 5470 1.1.1.3 christos 5471 1.1.1.3 christos /* Adjust relocations. */ 5472 1.1.1.3 christos rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), R_LARCH_B26); 5473 1.1.1.3 christos /* Delete jirl instruction. */ 5474 1.1.1.3 christos loongarch_relax_delete_or_nop (abfd, sec, rel->r_offset + 4, 4, info); 5475 1.1.1.3 christos return true; 5476 1.1.1.3 christos } 5477 1.1.1.3 christos 5478 1.1.1.2 christos /* Relax pcalau12i,ld.d => pcalau12i,addi.d. */ 5479 1.1.1.2 christos static bool 5480 1.1.1.2 christos loongarch_relax_pcala_ld (bfd *abfd, asection *sec, 5481 1.1.1.3 christos asection *sym_sec, 5482 1.1.1.3 christos Elf_Internal_Rela *rel_hi, 5483 1.1.1.3 christos bfd_vma symval, 5484 1.1.1.3 christos struct bfd_link_info *info, 5485 1.1.1.3 christos bool *again ATTRIBUTE_UNUSED, 5486 1.1.1.3 christos bfd_vma max_alignment) 5487 1.1.1.2 christos { 5488 1.1.1.2 christos bfd_byte *contents = elf_section_data (sec)->this_hdr.contents; 5489 1.1.1.2 christos Elf_Internal_Rela *rel_lo = rel_hi + 2; 5490 1.1.1.2 christos uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset); 5491 1.1.1.2 christos uint32_t ld = bfd_get (32, abfd, contents + rel_lo->r_offset); 5492 1.1.1.3 christos uint32_t rd = LARCH_GET_RD (pca); 5493 1.1.1.3 christos uint32_t addi_d = LARCH_OP_ADDI_D; 5494 1.1.1.3 christos 5495 1.1.1.3 christos /* This section's output_offset need to subtract the bytes of instructions 5496 1.1.1.3 christos relaxed by the previous sections, so it needs to be updated beforehand. 5497 1.1.1.3 christos size_input_section already took care of updating it after relaxation, 5498 1.1.1.3 christos so we additionally update once here. */ 5499 1.1.1.3 christos sec->output_offset = sec->output_section->size; 5500 1.1.1.3 christos bfd_vma pc = sec_addr (sec) 5501 1.1.1.3 christos + loongarch_calc_relaxed_addr (info, rel_hi->r_offset); 5502 1.1.1.3 christos if (sym_sec == sec) 5503 1.1.1.3 christos symval = sec_addr (sec) 5504 1.1.1.3 christos + loongarch_calc_relaxed_addr (info, symval - sec_addr (sec)); 5505 1.1.1.3 christos 5506 1.1.1.3 christos /* If pc and symbol not in the same segment, add/sub segment alignment. */ 5507 1.1.1.3 christos if (!loongarch_two_sections_in_same_segment (info->output_bfd, 5508 1.1.1.3 christos sec->output_section, 5509 1.1.1.3 christos sym_sec->output_section)) 5510 1.1.1.3 christos max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize 5511 1.1.1.3 christos : max_alignment; 5512 1.1.1.3 christos 5513 1.1.1.3 christos if (symval > pc) 5514 1.1.1.3 christos pc -= (max_alignment > 4 ? max_alignment : 0); 5515 1.1.1.3 christos else if (symval < pc) 5516 1.1.1.3 christos pc += (max_alignment > 4 ? max_alignment : 0); 5517 1.1.1.2 christos 5518 1.1.1.2 christos if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12) 5519 1.1.1.3 christos || (LARCH_GET_RD (ld) != rd) 5520 1.1.1.3 christos || (LARCH_GET_RJ (ld) != rd) 5521 1.1.1.3 christos || !LARCH_INSN_LD_D (ld) 5522 1.1.1.3 christos /* Within +-2G addressing range. */ 5523 1.1.1.3 christos || (bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0x80000000 5524 1.1.1.3 christos || (bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x7fffffff) 5525 1.1.1.2 christos return false; 5526 1.1.1.2 christos 5527 1.1.1.2 christos addi_d = addi_d | (rd << 5) | rd; 5528 1.1.1.2 christos bfd_put (32, abfd, addi_d, contents + rel_lo->r_offset); 5529 1.1.1.2 christos 5530 1.1.1.2 christos rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info), 5531 1.1.1.2 christos R_LARCH_PCALA_HI20); 5532 1.1.1.2 christos rel_lo->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_lo->r_info), 5533 1.1.1.2 christos R_LARCH_PCALA_LO12); 5534 1.1.1.2 christos return true; 5535 1.1.1.2 christos } 5536 1.1.1.2 christos 5537 1.1.1.2 christos /* Called by after_allocation to set the information of data segment 5538 1.1.1.2 christos before relaxing. */ 5539 1.1.1.2 christos 5540 1.1.1.2 christos void 5541 1.1.1.2 christos bfd_elfNN_loongarch_set_data_segment_info (struct bfd_link_info *info, 5542 1.1.1.2 christos int *data_segment_phase) 5543 1.1.1.2 christos { 5544 1.1.1.3 christos if (is_elf_hash_table (info->hash) 5545 1.1.1.3 christos && elf_hash_table_id (elf_hash_table (info)) == LARCH_ELF_DATA) 5546 1.1.1.3 christos loongarch_elf_hash_table (info)->data_segment_phase = data_segment_phase; 5547 1.1.1.2 christos } 5548 1.1.1.2 christos 5549 1.1.1.3 christos /* Honor R_LARCH_ALIGN requests by deleting excess alignment NOPs. 5550 1.1.1.3 christos Once we've handled an R_LARCH_ALIGN, we can't relax anything else by deleting 5551 1.1.1.3 christos bytes, or alignment will be disrupted. */ 5552 1.1.1.2 christos static bool 5553 1.1.1.3 christos loongarch_relax_align (bfd *abfd, asection *sec, asection *sym_sec, 5554 1.1.1.2 christos Elf_Internal_Rela *rel, 5555 1.1.1.3 christos bfd_vma symval, 5556 1.1.1.3 christos struct bfd_link_info *link_info, 5557 1.1.1.3 christos bool *again ATTRIBUTE_UNUSED, 5558 1.1.1.3 christos bfd_vma max_alignment ATTRIBUTE_UNUSED) 5559 1.1.1.2 christos { 5560 1.1.1.2 christos bfd_vma addend, max = 0, alignment = 1; 5561 1.1.1.2 christos 5562 1.1.1.2 christos int sym_index = ELFNN_R_SYM (rel->r_info); 5563 1.1.1.2 christos if (sym_index > 0) 5564 1.1.1.2 christos { 5565 1.1.1.2 christos alignment = 1 << (rel->r_addend & 0xff); 5566 1.1.1.2 christos max = rel->r_addend >> 8; 5567 1.1.1.2 christos } 5568 1.1.1.2 christos else 5569 1.1.1.2 christos alignment = rel->r_addend + 4; 5570 1.1.1.2 christos 5571 1.1.1.3 christos if (sym_sec == sec) 5572 1.1.1.3 christos symval = sec_addr (sec) 5573 1.1.1.3 christos + loongarch_calc_relaxed_addr (link_info, symval - sec_addr (sec)); 5574 1.1.1.3 christos 5575 1.1.1.2 christos addend = alignment - 4; /* The bytes of NOPs added by R_LARCH_ALIGN. */ 5576 1.1.1.2 christos symval -= addend; /* The address of first NOP added by R_LARCH_ALIGN. */ 5577 1.1.1.2 christos bfd_vma aligned_addr = ((symval - 1) & ~(alignment - 1)) + alignment; 5578 1.1.1.2 christos bfd_vma need_nop_bytes = aligned_addr - symval; /* */ 5579 1.1.1.2 christos 5580 1.1.1.2 christos /* Make sure there are enough NOPs to actually achieve the alignment. */ 5581 1.1.1.2 christos if (addend < need_nop_bytes) 5582 1.1.1.2 christos { 5583 1.1.1.2 christos _bfd_error_handler 5584 1.1.1.2 christos (_("%pB(%pA+%#" PRIx64 "): %" PRId64 " bytes required for alignment " 5585 1.1.1.2 christos "to %" PRId64 "-byte boundary, but only %" PRId64 " present"), 5586 1.1.1.2 christos abfd, sym_sec, (uint64_t) rel->r_offset, 5587 1.1.1.2 christos (int64_t) need_nop_bytes, (int64_t) alignment, (int64_t) addend); 5588 1.1.1.2 christos bfd_set_error (bfd_error_bad_value); 5589 1.1.1.2 christos return false; 5590 1.1.1.2 christos } 5591 1.1.1.2 christos 5592 1.1.1.3 christos /* Once we've handled an R_LARCH_ALIGN in a section, we can't relax anything 5593 1.1.1.3 christos else by deleting bytes, or alignment will be disrupted. */ 5594 1.1.1.3 christos loongarch_sec_closed_for_deletion (sec) = true; 5595 1.1.1.2 christos rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE); 5596 1.1.1.2 christos 5597 1.1.1.2 christos /* If skipping more bytes than the specified maximum, 5598 1.1.1.2 christos then the alignment is not done at all and delete all NOPs. */ 5599 1.1.1.2 christos if (max > 0 && need_nop_bytes > max) 5600 1.1.1.3 christos { 5601 1.1.1.3 christos loongarch_relax_delete_bytes (abfd, rel->r_offset, addend, link_info); 5602 1.1.1.3 christos return true; 5603 1.1.1.3 christos } 5604 1.1.1.2 christos 5605 1.1.1.2 christos /* If the number of NOPs is already correct, there's nothing to do. */ 5606 1.1.1.2 christos if (need_nop_bytes == addend) 5607 1.1.1.2 christos return true; 5608 1.1.1.2 christos 5609 1.1.1.2 christos /* Delete the excess NOPs. */ 5610 1.1.1.3 christos loongarch_relax_delete_bytes (abfd, rel->r_offset + need_nop_bytes, 5611 1.1.1.3 christos addend - need_nop_bytes, link_info); 5612 1.1.1.3 christos return true; 5613 1.1.1.2 christos } 5614 1.1.1.2 christos 5615 1.1.1.2 christos /* Relax pcalau12i + addi.d of TLS LD/GD/DESC to pcaddi. */ 5616 1.1.1.2 christos static bool 5617 1.1.1.2 christos loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec, 5618 1.1.1.2 christos Elf_Internal_Rela *rel_hi, bfd_vma symval, 5619 1.1.1.2 christos struct bfd_link_info *info, bool *again, 5620 1.1.1.2 christos bfd_vma max_alignment) 5621 1.1.1.2 christos { 5622 1.1.1.2 christos bfd_byte *contents = elf_section_data (sec)->this_hdr.contents; 5623 1.1.1.2 christos Elf_Internal_Rela *rel_lo = rel_hi + 2; 5624 1.1.1.2 christos uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset); 5625 1.1.1.2 christos uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset); 5626 1.1.1.3 christos uint32_t rd = LARCH_GET_RD (pca); 5627 1.1.1.2 christos 5628 1.1.1.2 christos /* This section's output_offset need to subtract the bytes of instructions 5629 1.1.1.2 christos relaxed by the previous sections, so it needs to be updated beforehand. 5630 1.1.1.2 christos size_input_section already took care of updating it after relaxation, 5631 1.1.1.2 christos so we additionally update once here. */ 5632 1.1.1.2 christos sec->output_offset = sec->output_section->size; 5633 1.1.1.3 christos bfd_vma pc = sec_addr (sec) 5634 1.1.1.3 christos + loongarch_calc_relaxed_addr (info, rel_hi->r_offset); 5635 1.1.1.3 christos if (sym_sec == sec) 5636 1.1.1.3 christos symval = sec_addr (sec) 5637 1.1.1.3 christos + loongarch_calc_relaxed_addr (info, symval - sec_addr (sec)); 5638 1.1.1.3 christos 5639 1.1.1.3 christos /* If pc and symbol not in the same segment, add/sub segment alignment. */ 5640 1.1.1.3 christos if (!loongarch_two_sections_in_same_segment (info->output_bfd, 5641 1.1.1.3 christos sec->output_section, 5642 1.1.1.3 christos sym_sec->output_section)) 5643 1.1.1.3 christos max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize 5644 1.1.1.3 christos : max_alignment; 5645 1.1.1.3 christos 5646 1.1.1.3 christos if (symval > pc) 5647 1.1.1.3 christos pc -= (max_alignment > 4 ? max_alignment : 0); 5648 1.1.1.3 christos else if (symval < pc) 5649 1.1.1.3 christos pc += (max_alignment > 4 ? max_alignment : 0); 5650 1.1.1.2 christos 5651 1.1.1.3 christos const uint32_t pcaddi = LARCH_OP_PCADDI; 5652 1.1.1.2 christos 5653 1.1.1.2 christos /* Is pcalau12i + addi.d insns? */ 5654 1.1.1.2 christos if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12 5655 1.1.1.2 christos && ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_TLS_DESC_PC_LO12) 5656 1.1.1.3 christos || !LARCH_INSN_ADDI_D (add) 5657 1.1.1.2 christos /* Is pcalau12i $rd + addi.d $rd,$rd? */ 5658 1.1.1.3 christos || (LARCH_GET_RD (add) != rd) 5659 1.1.1.3 christos || (LARCH_GET_RJ (add) != rd) 5660 1.1.1.2 christos /* Can be relaxed to pcaddi? */ 5661 1.1.1.2 christos || (symval & 0x3) /* 4 bytes align. */ 5662 1.1.1.2 christos || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xffe00000) 5663 1.1.1.2 christos || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x1ffffc)) 5664 1.1.1.2 christos return false; 5665 1.1.1.2 christos 5666 1.1.1.2 christos /* Continue next relax trip. */ 5667 1.1.1.2 christos *again = true; 5668 1.1.1.2 christos 5669 1.1.1.2 christos pca = pcaddi | rd; 5670 1.1.1.2 christos bfd_put (32, abfd, pca, contents + rel_hi->r_offset); 5671 1.1.1.2 christos 5672 1.1.1.2 christos /* Adjust relocations. */ 5673 1.1.1.2 christos switch (ELFNN_R_TYPE (rel_hi->r_info)) 5674 1.1.1.2 christos { 5675 1.1.1.2 christos case R_LARCH_TLS_LD_PC_HI20: 5676 1.1.1.2 christos rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info), 5677 1.1.1.2 christos R_LARCH_TLS_LD_PCREL20_S2); 5678 1.1.1.2 christos break; 5679 1.1.1.2 christos case R_LARCH_TLS_GD_PC_HI20: 5680 1.1.1.2 christos rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info), 5681 1.1.1.2 christos R_LARCH_TLS_GD_PCREL20_S2); 5682 1.1.1.2 christos break; 5683 1.1.1.2 christos case R_LARCH_TLS_DESC_PC_HI20: 5684 1.1.1.2 christos rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info), 5685 1.1.1.2 christos R_LARCH_TLS_DESC_PCREL20_S2); 5686 1.1.1.2 christos break; 5687 1.1.1.2 christos default: 5688 1.1.1.2 christos break; 5689 1.1.1.2 christos } 5690 1.1.1.2 christos rel_lo->r_info = ELFNN_R_INFO (0, R_LARCH_NONE); 5691 1.1.1.2 christos 5692 1.1.1.3 christos loongarch_relax_delete_or_nop (abfd, sec, rel_lo->r_offset, 4, info); 5693 1.1.1.2 christos 5694 1.1.1.2 christos return true; 5695 1.1.1.2 christos } 5696 1.1.1.2 christos 5697 1.1.1.2 christos /* Traverse all output sections and return the max alignment. */ 5698 1.1.1.2 christos 5699 1.1.1.2 christos static bfd_vma 5700 1.1.1.2 christos loongarch_get_max_alignment (asection *sec) 5701 1.1.1.2 christos { 5702 1.1.1.2 christos asection *o; 5703 1.1.1.2 christos unsigned int max_alignment_power = 0; 5704 1.1.1.2 christos 5705 1.1.1.2 christos for (o = sec->output_section->owner->sections; o != NULL; o = o->next) 5706 1.1.1.2 christos if (o->alignment_power > max_alignment_power) 5707 1.1.1.2 christos max_alignment_power = o->alignment_power; 5708 1.1.1.2 christos 5709 1.1.1.2 christos return (bfd_vma) 1 << max_alignment_power; 5710 1.1.1.2 christos } 5711 1.1.1.2 christos 5712 1.1.1.3 christos typedef bool (*relax_func_t) (bfd *, asection *, asection *, 5713 1.1.1.3 christos Elf_Internal_Rela *, bfd_vma, 5714 1.1.1.3 christos struct bfd_link_info *, bool *, 5715 1.1.1.3 christos bfd_vma); 5716 1.1.1.3 christos 5717 1.1.1.2 christos static bool 5718 1.1.1.2 christos loongarch_elf_relax_section (bfd *abfd, asection *sec, 5719 1.1.1.3 christos struct bfd_link_info *info, 5720 1.1.1.3 christos bool *again) 5721 1.1.1.2 christos { 5722 1.1.1.2 christos *again = false; 5723 1.1.1.2 christos 5724 1.1.1.3 christos if (!is_elf_hash_table (info->hash) 5725 1.1.1.3 christos || elf_hash_table_id (elf_hash_table (info)) != LARCH_ELF_DATA) 5726 1.1.1.3 christos return true; 5727 1.1.1.3 christos 5728 1.1.1.3 christos struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info); 5729 1.1.1.3 christos 5730 1.1.1.3 christos /* It may happen that some sections have updated vma but the others do 5731 1.1.1.3 christos not. Go to the next relax trip (size_relative_relocs should have 5732 1.1.1.3 christos been demending another relax trip anyway). */ 5733 1.1.1.3 christos if (htab->layout_mutating_for_relr) 5734 1.1.1.3 christos return true; 5735 1.1.1.3 christos 5736 1.1.1.3 christos /* Definition of LoongArch linker relaxation passes: 5737 1.1.1.3 christos 5738 1.1.1.3 christos - Pass 0: relaxes everything except R_LARCH_ALIGN, byte deletions are 5739 1.1.1.3 christos performed; skipped if disable_target_specific_optimizations. 5740 1.1.1.3 christos - Pass 1: handles alignment, byte deletions are performed. Sections with 5741 1.1.1.3 christos R_LARCH_ALIGN relocations are marked closed for further byte 5742 1.1.1.3 christos deletion in order to not disturb alignment. This pass is NOT 5743 1.1.1.3 christos skipped even if disable_target_specific_optimizations is true. 5744 1.1.1.3 christos - Pass 2: identical to Pass 0, but replacing relaxed insns with NOP in case 5745 1.1.1.3 christos the containing section is closed for deletion; skip condition 5746 1.1.1.3 christos also same as Pass 0. */ 5747 1.1.1.3 christos bool is_alignment_pass = info->relax_pass == 1; 5748 1.1.1.2 christos if (bfd_link_relocatable (info) 5749 1.1.1.2 christos || sec->reloc_count == 0 5750 1.1.1.3 christos || (sec->flags & SEC_RELOC) == 0 5751 1.1.1.3 christos || (sec->flags & SEC_HAS_CONTENTS) == 0 5752 1.1.1.3 christos /* The exp_seg_relro_adjust is enum phase_enum (0x4). */ 5753 1.1.1.3 christos || *(htab->data_segment_phase) == 4 5754 1.1.1.3 christos || (info->disable_target_specific_optimizations && !is_alignment_pass)) 5755 1.1.1.2 christos return true; 5756 1.1.1.2 christos 5757 1.1.1.3 christos struct bfd_elf_section_data *data = elf_section_data (sec); 5758 1.1.1.3 christos Elf_Internal_Rela *relocs; 5759 1.1.1.2 christos if (data->relocs) 5760 1.1.1.2 christos relocs = data->relocs; 5761 1.1.1.2 christos else if (!(relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, 5762 1.1.1.2 christos info->keep_memory))) 5763 1.1.1.2 christos return true; 5764 1.1.1.3 christos data->relocs = relocs; 5765 1.1.1.2 christos 5766 1.1.1.3 christos /* Read this BFD's contents if we haven't done so already. */ 5767 1.1.1.2 christos if (!data->this_hdr.contents 5768 1.1.1.2 christos && !bfd_malloc_and_get_section (abfd, sec, &data->this_hdr.contents)) 5769 1.1.1.2 christos return true; 5770 1.1.1.2 christos 5771 1.1.1.3 christos /* Read this BFD's symbols if we haven't done so already. */ 5772 1.1.1.3 christos Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd); 5773 1.1.1.2 christos if (symtab_hdr->sh_info != 0 5774 1.1.1.2 christos && !symtab_hdr->contents 5775 1.1.1.2 christos && !(symtab_hdr->contents = 5776 1.1.1.2 christos (unsigned char *) bfd_elf_get_elf_syms (abfd, symtab_hdr, 5777 1.1.1.2 christos symtab_hdr->sh_info, 5778 1.1.1.2 christos 0, NULL, NULL, NULL))) 5779 1.1.1.2 christos return true; 5780 1.1.1.2 christos 5781 1.1.1.2 christos /* Estimate the maximum alignment for all output sections once time 5782 1.1.1.2 christos should be enough. */ 5783 1.1.1.3 christos bfd_vma max_alignment = htab->max_alignment; 5784 1.1.1.2 christos if (max_alignment == (bfd_vma) -1) 5785 1.1.1.2 christos { 5786 1.1.1.2 christos max_alignment = loongarch_get_max_alignment (sec); 5787 1.1.1.2 christos htab->max_alignment = max_alignment; 5788 1.1.1.2 christos } 5789 1.1.1.2 christos 5790 1.1.1.3 christos splay_tree pdops = NULL; 5791 1.1.1.3 christos if (!loongarch_sec_closed_for_deletion (sec)) 5792 1.1.1.3 christos pdops = pending_delete_ops_new (abfd); 5793 1.1.1.3 christos 5794 1.1.1.3 christos htab->pending_delete_ops = pdops; 5795 1.1.1.3 christos 5796 1.1.1.2 christos for (unsigned int i = 0; i < sec->reloc_count; i++) 5797 1.1.1.2 christos { 5798 1.1.1.2 christos char symtype; 5799 1.1.1.2 christos bfd_vma symval; 5800 1.1.1.2 christos asection *sym_sec; 5801 1.1.1.2 christos bool local_got = false; 5802 1.1.1.2 christos Elf_Internal_Rela *rel = relocs + i; 5803 1.1.1.2 christos struct elf_link_hash_entry *h = NULL; 5804 1.1.1.2 christos unsigned long r_type = ELFNN_R_TYPE (rel->r_info); 5805 1.1.1.2 christos unsigned long r_symndx = ELFNN_R_SYM (rel->r_info); 5806 1.1.1.2 christos 5807 1.1.1.3 christos if (r_symndx >= symtab_hdr->sh_info) 5808 1.1.1.3 christos { 5809 1.1.1.3 christos h = elf_sym_hashes (abfd)[r_symndx - symtab_hdr->sh_info]; 5810 1.1.1.3 christos while (h->root.type == bfd_link_hash_indirect 5811 1.1.1.3 christos || h->root.type == bfd_link_hash_warning) 5812 1.1.1.3 christos h = (struct elf_link_hash_entry *) h->root.u.i.link; 5813 1.1.1.3 christos } 5814 1.1.1.3 christos 5815 1.1.1.3 christos /* If the conditions for tls type transition are met, type 5816 1.1.1.3 christos transition is performed instead of relax. 5817 1.1.1.3 christos During the transition from DESC->IE/LE, there are 2 situations 5818 1.1.1.3 christos depending on the different configurations of the relax/norelax 5819 1.1.1.3 christos option. 5820 1.1.1.3 christos If the -relax option is used, the extra nops will be removed, 5821 1.1.1.3 christos and this transition is performed in pass 0. 5822 1.1.1.3 christos If the --no-relax option is used, nop will be retained, and 5823 1.1.1.3 christos this transition is performed in pass 1. */ 5824 1.1.1.3 christos if (IS_LOONGARCH_TLS_TRANS_RELOC (r_type) 5825 1.1.1.3 christos && (i + 1 != sec->reloc_count) 5826 1.1.1.3 christos && ELFNN_R_TYPE (rel[1].r_info) == R_LARCH_RELAX 5827 1.1.1.3 christos && rel->r_offset == rel[1].r_offset 5828 1.1.1.3 christos && loongarch_can_trans_tls (abfd, info, h, r_symndx, r_type)) 5829 1.1.1.3 christos { 5830 1.1.1.3 christos loongarch_tls_perform_trans (abfd, sec, rel, h, info); 5831 1.1.1.3 christos r_type = ELFNN_R_TYPE (rel->r_info); 5832 1.1.1.3 christos } 5833 1.1.1.3 christos 5834 1.1.1.3 christos relax_func_t relax_func = NULL; 5835 1.1.1.3 christos if (is_alignment_pass) 5836 1.1.1.3 christos { 5837 1.1.1.3 christos if (r_type != R_LARCH_ALIGN) 5838 1.1.1.3 christos continue; 5839 1.1.1.3 christos relax_func = loongarch_relax_align; 5840 1.1.1.3 christos } 5841 1.1.1.3 christos else 5842 1.1.1.3 christos { 5843 1.1.1.3 christos switch (r_type) 5844 1.1.1.3 christos { 5845 1.1.1.3 christos case R_LARCH_PCALA_HI20: 5846 1.1.1.3 christos relax_func = loongarch_relax_pcala_addi; 5847 1.1.1.3 christos break; 5848 1.1.1.3 christos case R_LARCH_GOT_PC_HI20: 5849 1.1.1.3 christos relax_func = loongarch_relax_pcala_ld; 5850 1.1.1.3 christos break; 5851 1.1.1.3 christos case R_LARCH_CALL36: 5852 1.1.1.3 christos relax_func = loongarch_relax_call36; 5853 1.1.1.3 christos break; 5854 1.1.1.3 christos case R_LARCH_TLS_LE_HI20_R: 5855 1.1.1.3 christos case R_LARCH_TLS_LE_LO12_R: 5856 1.1.1.3 christos case R_LARCH_TLS_LE_ADD_R: 5857 1.1.1.3 christos case R_LARCH_TLS_LE_HI20: 5858 1.1.1.3 christos case R_LARCH_TLS_LE_LO12: 5859 1.1.1.3 christos case R_LARCH_TLS_LE64_LO20: 5860 1.1.1.3 christos case R_LARCH_TLS_LE64_HI12: 5861 1.1.1.3 christos relax_func = loongarch_relax_tls_le; 5862 1.1.1.3 christos break; 5863 1.1.1.3 christos case R_LARCH_TLS_LD_PC_HI20: 5864 1.1.1.3 christos case R_LARCH_TLS_GD_PC_HI20: 5865 1.1.1.3 christos case R_LARCH_TLS_DESC_PC_HI20: 5866 1.1.1.3 christos relax_func = loongarch_relax_tls_ld_gd_desc; 5867 1.1.1.3 christos break; 5868 1.1.1.3 christos default: 5869 1.1.1.3 christos continue; 5870 1.1.1.3 christos } 5871 1.1.1.3 christos 5872 1.1.1.3 christos /* Only relax this reloc if it is paired with R_RISCV_RELAX. */ 5873 1.1.1.3 christos if (r_type == R_LARCH_TLS_LD_PC_HI20 5874 1.1.1.3 christos || r_type == R_LARCH_TLS_GD_PC_HI20 5875 1.1.1.3 christos || r_type == R_LARCH_TLS_DESC_PC_HI20 5876 1.1.1.3 christos || r_type == R_LARCH_PCALA_HI20 5877 1.1.1.3 christos || r_type == R_LARCH_GOT_PC_HI20) 5878 1.1.1.3 christos { 5879 1.1.1.3 christos if ((i + 2) == sec->reloc_count - 1 5880 1.1.1.3 christos || ELFNN_R_TYPE ((rel + 1)->r_info) != R_LARCH_RELAX 5881 1.1.1.3 christos || ELFNN_R_TYPE ((rel + 3)->r_info) != R_LARCH_RELAX 5882 1.1.1.3 christos || rel->r_offset != (rel + 1)->r_offset 5883 1.1.1.3 christos || (rel + 2)->r_offset != (rel + 3)->r_offset 5884 1.1.1.3 christos || rel->r_offset + 4 != (rel + 2)->r_offset) 5885 1.1.1.3 christos continue; 5886 1.1.1.3 christos } 5887 1.1.1.3 christos else 5888 1.1.1.3 christos { 5889 1.1.1.3 christos if (i == sec->reloc_count - 1 5890 1.1.1.3 christos || ELFNN_R_TYPE ((rel + 1)->r_info) != R_LARCH_RELAX 5891 1.1.1.3 christos || rel->r_offset != (rel + 1)->r_offset) 5892 1.1.1.3 christos continue; 5893 1.1.1.3 christos } 5894 1.1.1.3 christos } 5895 1.1.1.3 christos 5896 1.1.1.2 christos /* Four kind of relocations: 5897 1.1.1.2 christos Normal: symval is the symbol address. 5898 1.1.1.2 christos R_LARCH_ALIGN: symval is the address of the last NOP instruction 5899 1.1.1.2 christos added by this relocation, and then adds 4 more. 5900 1.1.1.2 christos R_LARCH_CALL36: symval is the symbol address for local symbols, 5901 1.1.1.2 christos or the PLT entry address of the symbol. (Todo) 5902 1.1.1.2 christos R_LARCHL_TLS_LD/GD/DESC_PC_HI20: symval is the GOT entry address 5903 1.1.1.3 christos of the symbol if transition is not possible. */ 5904 1.1.1.2 christos if (r_symndx < symtab_hdr->sh_info) 5905 1.1.1.2 christos { 5906 1.1.1.2 christos Elf_Internal_Sym *sym = (Elf_Internal_Sym *)symtab_hdr->contents 5907 1.1.1.2 christos + r_symndx; 5908 1.1.1.3 christos 5909 1.1.1.3 christos if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC 5910 1.1.1.3 christos && r_type != R_LARCH_CALL36) 5911 1.1.1.3 christos || sym->st_shndx == SHN_ABS) 5912 1.1.1.2 christos continue; 5913 1.1.1.2 christos 5914 1.1.1.3 christos /* Only TLS instruction sequences that are accompanied by 5915 1.1.1.3 christos R_LARCH_RELAX and cannot perform type transition can be 5916 1.1.1.3 christos relaxed. */ 5917 1.1.1.3 christos if (r_type == R_LARCH_TLS_LD_PC_HI20 5918 1.1.1.3 christos || r_type == R_LARCH_TLS_GD_PC_HI20 5919 1.1.1.3 christos || r_type == R_LARCH_TLS_DESC_PC_HI20) 5920 1.1.1.2 christos { 5921 1.1.1.3 christos sym_sec = htab->elf.sgot; 5922 1.1.1.3 christos symval = elf_local_got_offsets (abfd)[r_symndx]; 5923 1.1.1.3 christos char tls_type = _bfd_loongarch_elf_tls_type (abfd, h, 5924 1.1.1.3 christos r_symndx); 5925 1.1.1.3 christos if (r_type == R_LARCH_TLS_DESC_PC_HI20 5926 1.1.1.3 christos && GOT_TLS_GD_BOTH_P (tls_type)) 5927 1.1.1.3 christos symval += 2 * GOT_ENTRY_SIZE; 5928 1.1.1.2 christos } 5929 1.1.1.3 christos else if (sym->st_shndx == SHN_UNDEF || r_type == R_LARCH_ALIGN) 5930 1.1.1.2 christos { 5931 1.1.1.2 christos sym_sec = sec; 5932 1.1.1.2 christos symval = rel->r_offset; 5933 1.1.1.2 christos } 5934 1.1.1.2 christos else 5935 1.1.1.2 christos { 5936 1.1.1.2 christos sym_sec = elf_elfsections (abfd)[sym->st_shndx]->bfd_section; 5937 1.1.1.2 christos symval = sym->st_value; 5938 1.1.1.2 christos } 5939 1.1.1.2 christos symtype = ELF_ST_TYPE (sym->st_info); 5940 1.1.1.2 christos } 5941 1.1.1.2 christos else 5942 1.1.1.2 christos { 5943 1.1.1.3 christos /* Do not relax __[start|stop]_SECNAME, since the symbol value 5944 1.1.1.3 christos is not set yet. */ 5945 1.1.1.3 christos if (h != NULL 5946 1.1.1.3 christos && ((h->type == STT_GNU_IFUNC 5947 1.1.1.3 christos && r_type != R_LARCH_CALL36) 5948 1.1.1.3 christos || bfd_is_abs_section (h->root.u.def.section) 5949 1.1.1.3 christos || h->start_stop)) 5950 1.1.1.2 christos continue; 5951 1.1.1.2 christos 5952 1.1.1.2 christos /* The GOT entry of tls symbols must in current execute file or 5953 1.1.1.2 christos shared object. */ 5954 1.1.1.3 christos if (r_type == R_LARCH_TLS_LD_PC_HI20 5955 1.1.1.3 christos || r_type == R_LARCH_TLS_GD_PC_HI20 5956 1.1.1.3 christos || r_type == R_LARCH_TLS_DESC_PC_HI20) 5957 1.1.1.2 christos { 5958 1.1.1.3 christos sym_sec = htab->elf.sgot; 5959 1.1.1.3 christos symval = h->got.offset; 5960 1.1.1.3 christos char tls_type = _bfd_loongarch_elf_tls_type (abfd, h, 5961 1.1.1.3 christos r_symndx); 5962 1.1.1.3 christos if (r_type == R_LARCH_TLS_DESC_PC_HI20 5963 1.1.1.3 christos && GOT_TLS_GD_BOTH_P (tls_type)) 5964 1.1.1.3 christos symval += 2 * GOT_ENTRY_SIZE; 5965 1.1.1.3 christos } 5966 1.1.1.3 christos else if (h->plt.offset != MINUS_ONE) 5967 1.1.1.3 christos { 5968 1.1.1.3 christos sym_sec = htab->elf.splt ? htab->elf.splt : htab->elf.iplt; 5969 1.1.1.3 christos symval = h->plt.offset; 5970 1.1.1.3 christos } 5971 1.1.1.3 christos /* Like loongarch_elf_relocate_section, set relocation(offset) to 0. 5972 1.1.1.3 christos Undefweak for other relocations handing in the future. */ 5973 1.1.1.3 christos else if (h->root.type == bfd_link_hash_undefweak 5974 1.1.1.3 christos && !h->root.linker_def 5975 1.1.1.3 christos && r_type == R_LARCH_CALL36) 5976 1.1.1.3 christos { 5977 1.1.1.3 christos sym_sec = sec; 5978 1.1.1.3 christos symval = rel->r_offset; 5979 1.1.1.2 christos } 5980 1.1.1.2 christos else if ((h->root.type == bfd_link_hash_defined 5981 1.1.1.2 christos || h->root.type == bfd_link_hash_defweak) 5982 1.1.1.2 christos && h->root.u.def.section != NULL 5983 1.1.1.2 christos && h->root.u.def.section->output_section != NULL) 5984 1.1.1.2 christos { 5985 1.1.1.2 christos sym_sec = h->root.u.def.section; 5986 1.1.1.3 christos symval = h->root.u.def.value; 5987 1.1.1.2 christos } 5988 1.1.1.2 christos else 5989 1.1.1.2 christos continue; 5990 1.1.1.2 christos 5991 1.1.1.3 christos if (h && LARCH_REF_LOCAL (info, h)) 5992 1.1.1.2 christos local_got = true; 5993 1.1.1.2 christos symtype = h->type; 5994 1.1.1.2 christos } 5995 1.1.1.2 christos 5996 1.1.1.2 christos if (sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE 5997 1.1.1.2 christos && (sym_sec->flags & SEC_MERGE)) 5998 1.1.1.2 christos { 5999 1.1.1.2 christos if (symtype == STT_SECTION) 6000 1.1.1.2 christos symval += rel->r_addend; 6001 1.1.1.2 christos 6002 1.1.1.2 christos symval = _bfd_merged_section_offset (abfd, &sym_sec, 6003 1.1.1.2 christos elf_section_data (sym_sec)->sec_info, 6004 1.1.1.2 christos symval); 6005 1.1.1.2 christos 6006 1.1.1.2 christos if (symtype != STT_SECTION) 6007 1.1.1.2 christos symval += rel->r_addend; 6008 1.1.1.2 christos } 6009 1.1.1.2 christos /* For R_LARCH_ALIGN, symval is sec_addr (sec) + rel->r_offset 6010 1.1.1.2 christos + (alingmeng - 4). 6011 1.1.1.2 christos If r_symndx is 0, alignmeng-4 is r_addend. 6012 1.1.1.2 christos If r_symndx > 0, alignment-4 is 2^(r_addend & 0xff)-4. */ 6013 1.1.1.3 christos else if (r_type == R_LARCH_ALIGN) 6014 1.1.1.2 christos if (r_symndx > 0) 6015 1.1.1.2 christos symval += ((1 << (rel->r_addend & 0xff)) - 4); 6016 1.1.1.2 christos else 6017 1.1.1.2 christos symval += rel->r_addend; 6018 1.1.1.2 christos else 6019 1.1.1.2 christos symval += rel->r_addend; 6020 1.1.1.2 christos 6021 1.1.1.2 christos symval += sec_addr (sym_sec); 6022 1.1.1.2 christos 6023 1.1.1.3 christos if (r_type == R_LARCH_GOT_PC_HI20 && !local_got) 6024 1.1.1.3 christos continue; 6025 1.1.1.2 christos 6026 1.1.1.3 christos if (relax_func (abfd, sec, sym_sec, rel, symval, 6027 1.1.1.3 christos info, again, max_alignment) 6028 1.1.1.3 christos && relax_func == loongarch_relax_pcala_ld) 6029 1.1.1.3 christos loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval, 6030 1.1.1.3 christos info, again, max_alignment); 6031 1.1.1.3 christos } 6032 1.1.1.2 christos 6033 1.1.1.3 christos if (pdops) 6034 1.1.1.3 christos { 6035 1.1.1.3 christos loongarch_relax_perform_deletes (abfd, sec, info); 6036 1.1.1.3 christos htab->pending_delete_ops = NULL; 6037 1.1.1.3 christos splay_tree_delete (pdops); 6038 1.1.1.2 christos } 6039 1.1.1.2 christos 6040 1.1.1.2 christos return true; 6041 1.1.1.2 christos } 6042 1.1.1.2 christos 6043 1.1 christos /* Finish up dynamic symbol handling. We set the contents of various 6044 1.1 christos dynamic sections here. */ 6045 1.1 christos 6046 1.1 christos static bool 6047 1.1 christos loongarch_elf_finish_dynamic_symbol (bfd *output_bfd, 6048 1.1 christos struct bfd_link_info *info, 6049 1.1 christos struct elf_link_hash_entry *h, 6050 1.1 christos Elf_Internal_Sym *sym) 6051 1.1 christos { 6052 1.1 christos struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info); 6053 1.1 christos const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); 6054 1.1 christos 6055 1.1 christos if (h->plt.offset != MINUS_ONE) 6056 1.1 christos { 6057 1.1 christos size_t i, plt_idx; 6058 1.1 christos asection *plt, *gotplt, *relplt; 6059 1.1 christos bfd_vma got_address; 6060 1.1 christos uint32_t plt_entry[PLT_ENTRY_INSNS]; 6061 1.1 christos bfd_byte *loc; 6062 1.1 christos Elf_Internal_Rela rela; 6063 1.1 christos 6064 1.1 christos if (htab->elf.splt) 6065 1.1 christos { 6066 1.1 christos BFD_ASSERT ((h->type == STT_GNU_IFUNC 6067 1.1.1.3 christos && LARCH_REF_LOCAL (info, h)) 6068 1.1 christos || h->dynindx != -1); 6069 1.1 christos 6070 1.1 christos plt = htab->elf.splt; 6071 1.1 christos gotplt = htab->elf.sgotplt; 6072 1.1.1.3 christos if (h->type == STT_GNU_IFUNC && LARCH_REF_LOCAL (info, h)) 6073 1.1.1.2 christos relplt = htab->elf.srelgot; 6074 1.1.1.2 christos else 6075 1.1.1.2 christos relplt = htab->elf.srelplt; 6076 1.1 christos plt_idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE; 6077 1.1 christos got_address = 6078 1.1 christos sec_addr (gotplt) + GOTPLT_HEADER_SIZE + plt_idx * GOT_ENTRY_SIZE; 6079 1.1 christos } 6080 1.1 christos else /* if (htab->elf.iplt) */ 6081 1.1 christos { 6082 1.1 christos BFD_ASSERT (h->type == STT_GNU_IFUNC 6083 1.1.1.3 christos && LARCH_REF_LOCAL (info, h)); 6084 1.1 christos 6085 1.1 christos plt = htab->elf.iplt; 6086 1.1 christos gotplt = htab->elf.igotplt; 6087 1.1 christos relplt = htab->elf.irelplt; 6088 1.1 christos plt_idx = h->plt.offset / PLT_ENTRY_SIZE; 6089 1.1 christos got_address = sec_addr (gotplt) + plt_idx * GOT_ENTRY_SIZE; 6090 1.1 christos } 6091 1.1 christos 6092 1.1 christos /* Find out where the .plt entry should go. */ 6093 1.1 christos loc = plt->contents + h->plt.offset; 6094 1.1 christos 6095 1.1 christos /* Fill in the PLT entry itself. */ 6096 1.1 christos if (!loongarch_make_plt_entry (got_address, 6097 1.1 christos sec_addr (plt) + h->plt.offset, 6098 1.1 christos plt_entry)) 6099 1.1 christos return false; 6100 1.1 christos 6101 1.1 christos for (i = 0; i < PLT_ENTRY_INSNS; i++) 6102 1.1 christos bfd_put_32 (output_bfd, plt_entry[i], loc + 4 * i); 6103 1.1 christos 6104 1.1.1.2 christos /* Fill in the initial value of the got.plt entry. */ 6105 1.1 christos loc = gotplt->contents + (got_address - sec_addr (gotplt)); 6106 1.1 christos bfd_put_NN (output_bfd, sec_addr (plt), loc); 6107 1.1 christos 6108 1.1 christos rela.r_offset = got_address; 6109 1.1 christos 6110 1.1 christos /* TRUE if this is a PLT reference to a local IFUNC. */ 6111 1.1.1.2 christos if (PLT_LOCAL_IFUNC_P (info, h) 6112 1.1.1.2 christos && (relplt == htab->elf.srelgot 6113 1.1.1.2 christos || relplt == htab->elf.irelplt)) 6114 1.1 christos { 6115 1.1 christos rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE); 6116 1.1 christos rela.r_addend = (h->root.u.def.value 6117 1.1.1.2 christos + h->root.u.def.section->output_section->vma 6118 1.1.1.2 christos + h->root.u.def.section->output_offset); 6119 1.1.1.2 christos 6120 1.1.1.2 christos loongarch_elf_append_rela (output_bfd, relplt, &rela); 6121 1.1 christos } 6122 1.1 christos else 6123 1.1 christos { 6124 1.1.1.2 christos /* Fill in the entry in the rela.plt section. */ 6125 1.1 christos rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_JUMP_SLOT); 6126 1.1 christos rela.r_addend = 0; 6127 1.1.1.2 christos loc = relplt->contents + plt_idx * sizeof (ElfNN_External_Rela); 6128 1.1.1.2 christos bed->s->swap_reloca_out (output_bfd, &rela, loc); 6129 1.1 christos } 6130 1.1 christos 6131 1.1 christos if (!h->def_regular) 6132 1.1 christos { 6133 1.1 christos /* Mark the symbol as undefined, rather than as defined in 6134 1.1 christos the .plt section. Leave the value alone. */ 6135 1.1 christos sym->st_shndx = SHN_UNDEF; 6136 1.1 christos /* If the symbol is weak, we do need to clear the value. 6137 1.1 christos Otherwise, the PLT entry would provide a definition for 6138 1.1 christos the symbol even if the symbol wasn't defined anywhere, 6139 1.1 christos and so the symbol would never be NULL. */ 6140 1.1 christos if (!h->ref_regular_nonweak) 6141 1.1 christos sym->st_value = 0; 6142 1.1 christos } 6143 1.1 christos } 6144 1.1 christos 6145 1.1 christos if (h->got.offset != MINUS_ONE 6146 1.1 christos /* TLS got entry have been handled in elf_relocate_section. */ 6147 1.1.1.2 christos && !(loongarch_elf_hash_entry (h)->tls_type 6148 1.1.1.2 christos & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC)) 6149 1.1.1.2 christos /* Have allocated got entry but not allocated rela before. */ 6150 1.1 christos && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) 6151 1.1 christos { 6152 1.1 christos asection *sgot, *srela; 6153 1.1 christos Elf_Internal_Rela rela; 6154 1.1.1.2 christos bfd_vma off = h->got.offset & ~(bfd_vma)1; 6155 1.1 christos 6156 1.1 christos /* This symbol has an entry in the GOT. Set it up. */ 6157 1.1 christos sgot = htab->elf.sgot; 6158 1.1 christos srela = htab->elf.srelgot; 6159 1.1 christos BFD_ASSERT (sgot && srela); 6160 1.1 christos 6161 1.1 christos rela.r_offset = sec_addr (sgot) + off; 6162 1.1 christos 6163 1.1 christos if (h->def_regular 6164 1.1 christos && h->type == STT_GNU_IFUNC) 6165 1.1 christos { 6166 1.1 christos if(h->plt.offset == MINUS_ONE) 6167 1.1 christos { 6168 1.1 christos if (htab->elf.splt == NULL) 6169 1.1 christos srela = htab->elf.irelplt; 6170 1.1 christos 6171 1.1.1.3 christos if (LARCH_REF_LOCAL (info, h)) 6172 1.1 christos { 6173 1.1 christos asection *sec = h->root.u.def.section; 6174 1.1 christos rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE); 6175 1.1 christos rela.r_addend = h->root.u.def.value + sec->output_section->vma 6176 1.1 christos + sec->output_offset; 6177 1.1 christos bfd_put_NN (output_bfd, 0, sgot->contents + off); 6178 1.1 christos } 6179 1.1 christos else 6180 1.1 christos { 6181 1.1 christos BFD_ASSERT (h->dynindx != -1); 6182 1.1 christos rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN); 6183 1.1 christos rela.r_addend = 0; 6184 1.1 christos bfd_put_NN (output_bfd, (bfd_vma) 0, sgot->contents + off); 6185 1.1 christos } 6186 1.1 christos } 6187 1.1 christos else if(bfd_link_pic (info)) 6188 1.1 christos { 6189 1.1 christos rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN); 6190 1.1 christos rela.r_addend = 0; 6191 1.1 christos bfd_put_NN (output_bfd, rela.r_addend, sgot->contents + off); 6192 1.1 christos } 6193 1.1 christos else 6194 1.1 christos { 6195 1.1 christos asection *plt; 6196 1.1 christos /* For non-shared object, we can't use .got.plt, which 6197 1.1 christos contains the real function address if we need pointer 6198 1.1 christos equality. We load the GOT entry with the PLT entry. */ 6199 1.1 christos plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt; 6200 1.1 christos bfd_put_NN (output_bfd, 6201 1.1 christos (plt->output_section->vma 6202 1.1 christos + plt->output_offset 6203 1.1 christos + h->plt.offset), 6204 1.1 christos sgot->contents + off); 6205 1.1 christos return true; 6206 1.1 christos } 6207 1.1 christos } 6208 1.1.1.3 christos else if (bfd_link_pic (info) && LARCH_REF_LOCAL (info, h)) 6209 1.1 christos { 6210 1.1 christos asection *sec = h->root.u.def.section; 6211 1.1.1.3 christos bfd_vma linkaddr = h->root.u.def.value + sec->output_section->vma 6212 1.1.1.3 christos + sec->output_offset; 6213 1.1.1.3 christos 6214 1.1.1.3 christos /* Don't emit relative relocs if they are packed, but we need 6215 1.1.1.3 christos to write the addend (link-time addr) into the GOT then. */ 6216 1.1.1.3 christos if (info->enable_dt_relr) 6217 1.1.1.3 christos { 6218 1.1.1.3 christos bfd_put_NN (output_bfd, linkaddr, sgot->contents + off); 6219 1.1.1.3 christos goto skip_got_reloc; 6220 1.1.1.3 christos } 6221 1.1 christos rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE); 6222 1.1.1.3 christos rela.r_addend = linkaddr; 6223 1.1 christos } 6224 1.1 christos else 6225 1.1 christos { 6226 1.1 christos BFD_ASSERT (h->dynindx != -1); 6227 1.1 christos rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN); 6228 1.1 christos rela.r_addend = 0; 6229 1.1 christos } 6230 1.1 christos 6231 1.1 christos loongarch_elf_append_rela (output_bfd, srela, &rela); 6232 1.1 christos } 6233 1.1.1.3 christos skip_got_reloc: 6234 1.1 christos 6235 1.1 christos /* Mark some specially defined symbols as absolute. */ 6236 1.1 christos if (h == htab->elf.hdynamic || h == htab->elf.hgot || h == htab->elf.hplt) 6237 1.1 christos sym->st_shndx = SHN_ABS; 6238 1.1 christos 6239 1.1 christos return true; 6240 1.1 christos } 6241 1.1 christos 6242 1.1 christos /* Finish up the dynamic sections. */ 6243 1.1 christos 6244 1.1 christos static bool 6245 1.1 christos loongarch_finish_dyn (bfd *output_bfd, struct bfd_link_info *info, bfd *dynobj, 6246 1.1 christos asection *sdyn) 6247 1.1 christos { 6248 1.1 christos struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info); 6249 1.1 christos const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); 6250 1.1 christos size_t dynsize = bed->s->sizeof_dyn, skipped_size = 0; 6251 1.1 christos bfd_byte *dyncon, *dynconend; 6252 1.1 christos 6253 1.1 christos dynconend = sdyn->contents + sdyn->size; 6254 1.1 christos for (dyncon = sdyn->contents; dyncon < dynconend; dyncon += dynsize) 6255 1.1 christos { 6256 1.1 christos Elf_Internal_Dyn dyn; 6257 1.1 christos asection *s; 6258 1.1 christos int skipped = 0; 6259 1.1 christos 6260 1.1 christos bed->s->swap_dyn_in (dynobj, dyncon, &dyn); 6261 1.1 christos 6262 1.1 christos switch (dyn.d_tag) 6263 1.1 christos { 6264 1.1 christos case DT_PLTGOT: 6265 1.1 christos s = htab->elf.sgotplt; 6266 1.1 christos dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; 6267 1.1 christos break; 6268 1.1 christos case DT_JMPREL: 6269 1.1 christos s = htab->elf.srelplt; 6270 1.1 christos dyn.d_un.d_ptr = s->output_section->vma + s->output_offset; 6271 1.1 christos break; 6272 1.1 christos case DT_PLTRELSZ: 6273 1.1 christos s = htab->elf.srelplt; 6274 1.1 christos dyn.d_un.d_val = s->size; 6275 1.1 christos break; 6276 1.1 christos case DT_TEXTREL: 6277 1.1 christos if ((info->flags & DF_TEXTREL) == 0) 6278 1.1 christos skipped = 1; 6279 1.1 christos break; 6280 1.1 christos case DT_FLAGS: 6281 1.1 christos if ((info->flags & DF_TEXTREL) == 0) 6282 1.1 christos dyn.d_un.d_val &= ~DF_TEXTREL; 6283 1.1 christos break; 6284 1.1 christos } 6285 1.1 christos if (skipped) 6286 1.1 christos skipped_size += dynsize; 6287 1.1 christos else 6288 1.1 christos bed->s->swap_dyn_out (output_bfd, &dyn, dyncon - skipped_size); 6289 1.1 christos } 6290 1.1 christos /* Wipe out any trailing entries if we shifted down a dynamic tag. */ 6291 1.1 christos memset (dyncon - skipped_size, 0, skipped_size); 6292 1.1 christos return true; 6293 1.1 christos } 6294 1.1 christos 6295 1.1 christos /* Finish up local dynamic symbol handling. We set the contents of 6296 1.1 christos various dynamic sections here. */ 6297 1.1 christos 6298 1.1.1.2 christos static int 6299 1.1 christos elfNN_loongarch_finish_local_dynamic_symbol (void **slot, void *inf) 6300 1.1 christos { 6301 1.1 christos struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot; 6302 1.1 christos struct bfd_link_info *info = (struct bfd_link_info *) inf; 6303 1.1 christos 6304 1.1 christos return loongarch_elf_finish_dynamic_symbol (info->output_bfd, info, h, NULL); 6305 1.1 christos } 6306 1.1 christos 6307 1.1.1.2 christos /* Value of struct elf_backend_data->elf_backend_output_arch_local_syms, 6308 1.1.1.2 christos this function is called before elf_link_sort_relocs. 6309 1.1.1.2 christos So relocation R_LARCH_IRELATIVE for local ifunc can be append to 6310 1.1.1.2 christos .rela.dyn (.rela.got) by loongarch_elf_append_rela. */ 6311 1.1.1.2 christos 6312 1.1.1.2 christos static bool 6313 1.1.1.2 christos elf_loongarch_output_arch_local_syms 6314 1.1.1.2 christos (bfd *output_bfd ATTRIBUTE_UNUSED, 6315 1.1.1.2 christos struct bfd_link_info *info, 6316 1.1.1.2 christos void *flaginfo ATTRIBUTE_UNUSED, 6317 1.1.1.2 christos int (*func) (void *, const char *, 6318 1.1.1.2 christos Elf_Internal_Sym *, 6319 1.1.1.2 christos asection *, 6320 1.1.1.2 christos struct elf_link_hash_entry *) ATTRIBUTE_UNUSED) 6321 1.1.1.2 christos { 6322 1.1.1.2 christos struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info); 6323 1.1.1.2 christos if (htab == NULL) 6324 1.1.1.2 christos return false; 6325 1.1.1.2 christos 6326 1.1.1.2 christos /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */ 6327 1.1.1.2 christos htab_traverse (htab->loc_hash_table, 6328 1.1.1.2 christos elfNN_loongarch_finish_local_dynamic_symbol, 6329 1.1.1.2 christos info); 6330 1.1.1.2 christos 6331 1.1.1.2 christos return true; 6332 1.1.1.2 christos } 6333 1.1.1.2 christos 6334 1.1 christos static bool 6335 1.1 christos loongarch_elf_finish_dynamic_sections (bfd *output_bfd, 6336 1.1 christos struct bfd_link_info *info) 6337 1.1 christos { 6338 1.1 christos bfd *dynobj; 6339 1.1 christos asection *sdyn, *plt, *gotplt = NULL; 6340 1.1 christos struct loongarch_elf_link_hash_table *htab; 6341 1.1 christos 6342 1.1 christos htab = loongarch_elf_hash_table (info); 6343 1.1 christos BFD_ASSERT (htab); 6344 1.1 christos dynobj = htab->elf.dynobj; 6345 1.1 christos sdyn = bfd_get_linker_section (dynobj, ".dynamic"); 6346 1.1 christos 6347 1.1 christos if (elf_hash_table (info)->dynamic_sections_created) 6348 1.1 christos { 6349 1.1 christos BFD_ASSERT (htab->elf.splt && sdyn); 6350 1.1 christos 6351 1.1 christos if (!loongarch_finish_dyn (output_bfd, info, dynobj, sdyn)) 6352 1.1 christos return false; 6353 1.1 christos } 6354 1.1 christos 6355 1.1 christos plt = htab->elf.splt; 6356 1.1 christos gotplt = htab->elf.sgotplt; 6357 1.1 christos 6358 1.1 christos if (plt && 0 < plt->size) 6359 1.1 christos { 6360 1.1 christos size_t i; 6361 1.1 christos uint32_t plt_header[PLT_HEADER_INSNS]; 6362 1.1 christos if (!loongarch_make_plt_header (sec_addr (gotplt), sec_addr (plt), 6363 1.1 christos plt_header)) 6364 1.1 christos return false; 6365 1.1 christos 6366 1.1 christos for (i = 0; i < PLT_HEADER_INSNS; i++) 6367 1.1 christos bfd_put_32 (output_bfd, plt_header[i], plt->contents + 4 * i); 6368 1.1 christos 6369 1.1 christos elf_section_data (plt->output_section)->this_hdr.sh_entsize = 6370 1.1 christos PLT_ENTRY_SIZE; 6371 1.1 christos } 6372 1.1 christos 6373 1.1 christos if (htab->elf.sgotplt) 6374 1.1 christos { 6375 1.1 christos asection *output_section = htab->elf.sgotplt->output_section; 6376 1.1 christos 6377 1.1 christos if (bfd_is_abs_section (output_section)) 6378 1.1 christos { 6379 1.1 christos _bfd_error_handler (_("discarded output section: `%pA'"), 6380 1.1 christos htab->elf.sgotplt); 6381 1.1 christos return false; 6382 1.1 christos } 6383 1.1 christos 6384 1.1 christos if (0 < htab->elf.sgotplt->size) 6385 1.1 christos { 6386 1.1 christos /* Write the first two entries in .got.plt, needed for the dynamic 6387 1.1 christos linker. */ 6388 1.1 christos bfd_put_NN (output_bfd, MINUS_ONE, htab->elf.sgotplt->contents); 6389 1.1 christos 6390 1.1 christos bfd_put_NN (output_bfd, (bfd_vma) 0, 6391 1.1 christos htab->elf.sgotplt->contents + GOT_ENTRY_SIZE); 6392 1.1 christos } 6393 1.1 christos 6394 1.1 christos elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE; 6395 1.1 christos } 6396 1.1 christos 6397 1.1 christos if (htab->elf.sgot) 6398 1.1 christos { 6399 1.1 christos asection *output_section = htab->elf.sgot->output_section; 6400 1.1 christos 6401 1.1 christos if (0 < htab->elf.sgot->size) 6402 1.1 christos { 6403 1.1 christos /* Set the first entry in the global offset table to the address of 6404 1.1 christos the dynamic section. */ 6405 1.1 christos bfd_vma val = sdyn ? sec_addr (sdyn) : 0; 6406 1.1 christos bfd_put_NN (output_bfd, val, htab->elf.sgot->contents); 6407 1.1 christos } 6408 1.1 christos 6409 1.1 christos elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE; 6410 1.1 christos } 6411 1.1 christos 6412 1.1 christos return true; 6413 1.1 christos } 6414 1.1 christos 6415 1.1 christos /* Return address for Ith PLT stub in section PLT, for relocation REL 6416 1.1 christos or (bfd_vma) -1 if it should not be included. */ 6417 1.1 christos 6418 1.1 christos static bfd_vma 6419 1.1 christos loongarch_elf_plt_sym_val (bfd_vma i, const asection *plt, 6420 1.1 christos const arelent *rel ATTRIBUTE_UNUSED) 6421 1.1 christos { 6422 1.1 christos return plt->vma + PLT_HEADER_SIZE + i * PLT_ENTRY_SIZE; 6423 1.1 christos } 6424 1.1 christos 6425 1.1 christos static enum elf_reloc_type_class 6426 1.1 christos loongarch_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED, 6427 1.1 christos const asection *rel_sec ATTRIBUTE_UNUSED, 6428 1.1 christos const Elf_Internal_Rela *rela) 6429 1.1 christos { 6430 1.1 christos struct loongarch_elf_link_hash_table *htab; 6431 1.1 christos htab = loongarch_elf_hash_table (info); 6432 1.1 christos 6433 1.1 christos if (htab->elf.dynsym != NULL && htab->elf.dynsym->contents != NULL) 6434 1.1 christos { 6435 1.1 christos /* Check relocation against STT_GNU_IFUNC symbol if there are 6436 1.1 christos dynamic symbols. */ 6437 1.1 christos bfd *abfd = info->output_bfd; 6438 1.1 christos const struct elf_backend_data *bed = get_elf_backend_data (abfd); 6439 1.1 christos unsigned long r_symndx = ELFNN_R_SYM (rela->r_info); 6440 1.1 christos if (r_symndx != STN_UNDEF) 6441 1.1 christos { 6442 1.1 christos Elf_Internal_Sym sym; 6443 1.1 christos if (!bed->s->swap_symbol_in (abfd, 6444 1.1 christos htab->elf.dynsym->contents 6445 1.1 christos + r_symndx * bed->s->sizeof_sym, 6446 1.1 christos 0, &sym)) 6447 1.1 christos { 6448 1.1 christos /* xgettext:c-format */ 6449 1.1 christos _bfd_error_handler (_("%pB symbol number %lu references" 6450 1.1 christos " nonexistent SHT_SYMTAB_SHNDX section"), 6451 1.1 christos abfd, r_symndx); 6452 1.1 christos /* Ideally an error class should be returned here. */ 6453 1.1 christos } 6454 1.1 christos else if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC) 6455 1.1 christos return reloc_class_ifunc; 6456 1.1 christos } 6457 1.1 christos } 6458 1.1 christos 6459 1.1 christos switch (ELFNN_R_TYPE (rela->r_info)) 6460 1.1 christos { 6461 1.1 christos case R_LARCH_IRELATIVE: 6462 1.1 christos return reloc_class_ifunc; 6463 1.1 christos case R_LARCH_RELATIVE: 6464 1.1 christos return reloc_class_relative; 6465 1.1 christos case R_LARCH_JUMP_SLOT: 6466 1.1 christos return reloc_class_plt; 6467 1.1 christos case R_LARCH_COPY: 6468 1.1 christos return reloc_class_copy; 6469 1.1 christos default: 6470 1.1 christos return reloc_class_normal; 6471 1.1 christos } 6472 1.1 christos } 6473 1.1 christos 6474 1.1 christos /* Copy the extra info we tack onto an elf_link_hash_entry. */ 6475 1.1 christos 6476 1.1 christos static void 6477 1.1 christos loongarch_elf_copy_indirect_symbol (struct bfd_link_info *info, 6478 1.1 christos struct elf_link_hash_entry *dir, 6479 1.1 christos struct elf_link_hash_entry *ind) 6480 1.1 christos { 6481 1.1 christos struct elf_link_hash_entry *edir, *eind; 6482 1.1 christos 6483 1.1 christos edir = dir; 6484 1.1 christos eind = ind; 6485 1.1 christos 6486 1.1 christos if (eind->dyn_relocs != NULL) 6487 1.1 christos { 6488 1.1 christos if (edir->dyn_relocs != NULL) 6489 1.1 christos { 6490 1.1 christos struct elf_dyn_relocs **pp; 6491 1.1 christos struct elf_dyn_relocs *p; 6492 1.1 christos 6493 1.1 christos /* Add reloc counts against the indirect sym to the direct sym 6494 1.1 christos list. Merge any entries against the same section. */ 6495 1.1 christos for (pp = &eind->dyn_relocs; (p = *pp) != NULL;) 6496 1.1 christos { 6497 1.1 christos struct elf_dyn_relocs *q; 6498 1.1 christos 6499 1.1 christos for (q = edir->dyn_relocs; q != NULL; q = q->next) 6500 1.1 christos if (q->sec == p->sec) 6501 1.1 christos { 6502 1.1 christos q->pc_count += p->pc_count; 6503 1.1 christos q->count += p->count; 6504 1.1 christos *pp = p->next; 6505 1.1 christos break; 6506 1.1 christos } 6507 1.1 christos if (q == NULL) 6508 1.1 christos pp = &p->next; 6509 1.1 christos } 6510 1.1 christos *pp = edir->dyn_relocs; 6511 1.1 christos } 6512 1.1 christos 6513 1.1 christos edir->dyn_relocs = eind->dyn_relocs; 6514 1.1 christos eind->dyn_relocs = NULL; 6515 1.1 christos } 6516 1.1 christos 6517 1.1 christos if (ind->root.type == bfd_link_hash_indirect && dir->got.refcount < 0) 6518 1.1 christos { 6519 1.1 christos loongarch_elf_hash_entry(edir)->tls_type 6520 1.1 christos = loongarch_elf_hash_entry(eind)->tls_type; 6521 1.1 christos loongarch_elf_hash_entry(eind)->tls_type = GOT_UNKNOWN; 6522 1.1 christos } 6523 1.1 christos _bfd_elf_link_hash_copy_indirect (info, dir, ind); 6524 1.1 christos } 6525 1.1 christos 6526 1.1 christos #define PRSTATUS_SIZE 0x1d8 6527 1.1 christos #define PRSTATUS_OFFSET_PR_CURSIG 0xc 6528 1.1 christos #define PRSTATUS_OFFSET_PR_PID 0x20 6529 1.1 christos #define ELF_GREGSET_T_SIZE 0x168 6530 1.1 christos #define PRSTATUS_OFFSET_PR_REG 0x70 6531 1.1 christos 6532 1.1 christos /* Support for core dump NOTE sections. */ 6533 1.1 christos 6534 1.1 christos static bool 6535 1.1 christos loongarch_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) 6536 1.1 christos { 6537 1.1 christos switch (note->descsz) 6538 1.1 christos { 6539 1.1 christos default: 6540 1.1 christos return false; 6541 1.1 christos 6542 1.1 christos /* The sizeof (struct elf_prstatus) on Linux/LoongArch. */ 6543 1.1 christos case PRSTATUS_SIZE: 6544 1.1 christos /* pr_cursig */ 6545 1.1 christos elf_tdata (abfd)->core->signal = 6546 1.1 christos bfd_get_16 (abfd, note->descdata + PRSTATUS_OFFSET_PR_CURSIG); 6547 1.1 christos 6548 1.1 christos /* pr_pid */ 6549 1.1 christos elf_tdata (abfd)->core->lwpid = 6550 1.1 christos bfd_get_32 (abfd, note->descdata + PRSTATUS_OFFSET_PR_PID); 6551 1.1 christos break; 6552 1.1 christos } 6553 1.1 christos 6554 1.1 christos /* Make a ".reg/999" section. */ 6555 1.1 christos return _bfd_elfcore_make_pseudosection (abfd, ".reg", ELF_GREGSET_T_SIZE, 6556 1.1 christos note->descpos 6557 1.1 christos + PRSTATUS_OFFSET_PR_REG); 6558 1.1 christos } 6559 1.1 christos 6560 1.1 christos #define PRPSINFO_SIZE 0x88 6561 1.1 christos #define PRPSINFO_OFFSET_PR_PID 0x18 6562 1.1 christos #define PRPSINFO_OFFSET_PR_FNAME 0x28 6563 1.1 christos #define PRPSINFO_SIZEOF_PR_FNAME 0x10 6564 1.1 christos #define PRPSINFO_OFFSET_PR_PS_ARGS 0x38 6565 1.1 christos #define PRPSINFO_SIZEOF_PR_PS_ARGS 0x50 6566 1.1 christos 6567 1.1 christos static bool 6568 1.1 christos loongarch_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) 6569 1.1 christos { 6570 1.1 christos switch (note->descsz) 6571 1.1 christos { 6572 1.1 christos default: 6573 1.1 christos return false; 6574 1.1 christos 6575 1.1 christos /* The sizeof (prpsinfo_t) on Linux/LoongArch. */ 6576 1.1 christos case PRPSINFO_SIZE: 6577 1.1 christos /* pr_pid */ 6578 1.1 christos elf_tdata (abfd)->core->pid = 6579 1.1 christos bfd_get_32 (abfd, note->descdata + PRPSINFO_OFFSET_PR_PID); 6580 1.1 christos 6581 1.1 christos /* pr_fname */ 6582 1.1 christos elf_tdata (abfd)->core->program = 6583 1.1 christos _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_FNAME, 6584 1.1 christos PRPSINFO_SIZEOF_PR_FNAME); 6585 1.1 christos 6586 1.1 christos /* pr_psargs */ 6587 1.1 christos elf_tdata (abfd)->core->command = 6588 1.1 christos _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_PS_ARGS, 6589 1.1 christos PRPSINFO_SIZEOF_PR_PS_ARGS); 6590 1.1 christos break; 6591 1.1 christos } 6592 1.1 christos 6593 1.1 christos /* Note that for some reason, a spurious space is tacked 6594 1.1 christos onto the end of the args in some (at least one anyway) 6595 1.1 christos implementations, so strip it off if it exists. */ 6596 1.1 christos 6597 1.1 christos { 6598 1.1 christos char *command = elf_tdata (abfd)->core->command; 6599 1.1 christos int n = strlen (command); 6600 1.1 christos 6601 1.1 christos if (0 < n && command[n - 1] == ' ') 6602 1.1 christos command[n - 1] = '\0'; 6603 1.1 christos } 6604 1.1 christos 6605 1.1 christos return true; 6606 1.1 christos } 6607 1.1 christos 6608 1.1 christos /* Set the right mach type. */ 6609 1.1 christos static bool 6610 1.1 christos loongarch_elf_object_p (bfd *abfd) 6611 1.1 christos { 6612 1.1 christos /* There are only two mach types in LoongArch currently. */ 6613 1.1 christos if (strcmp (abfd->xvec->name, "elf64-loongarch") == 0) 6614 1.1 christos bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch64); 6615 1.1 christos else 6616 1.1 christos bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch32); 6617 1.1 christos return true; 6618 1.1 christos } 6619 1.1 christos 6620 1.1 christos static asection * 6621 1.1 christos loongarch_elf_gc_mark_hook (asection *sec, struct bfd_link_info *info, 6622 1.1 christos Elf_Internal_Rela *rel, 6623 1.1 christos struct elf_link_hash_entry *h, 6624 1.1 christos Elf_Internal_Sym *sym) 6625 1.1 christos { 6626 1.1 christos if (h != NULL) 6627 1.1 christos switch (ELFNN_R_TYPE (rel->r_info)) 6628 1.1 christos { 6629 1.1 christos case R_LARCH_GNU_VTINHERIT: 6630 1.1 christos case R_LARCH_GNU_VTENTRY: 6631 1.1 christos return NULL; 6632 1.1 christos } 6633 1.1 christos 6634 1.1 christos return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym); 6635 1.1 christos } 6636 1.1 christos 6637 1.1 christos /* Return TRUE if symbol H should be hashed in the `.gnu.hash' section. For 6638 1.1 christos executable PLT slots where the executable never takes the address of those 6639 1.1 christos functions, the function symbols are not added to the hash table. */ 6640 1.1 christos 6641 1.1 christos static bool 6642 1.1 christos elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h) 6643 1.1 christos { 6644 1.1 christos if (h->plt.offset != (bfd_vma) -1 6645 1.1 christos && !h->def_regular 6646 1.1 christos && !h->pointer_equality_needed) 6647 1.1 christos return false; 6648 1.1 christos 6649 1.1 christos return _bfd_elf_hash_symbol (h); 6650 1.1 christos } 6651 1.1 christos 6652 1.1 christos #define TARGET_LITTLE_SYM loongarch_elfNN_vec 6653 1.1 christos #define TARGET_LITTLE_NAME "elfNN-loongarch" 6654 1.1 christos #define ELF_ARCH bfd_arch_loongarch 6655 1.1 christos #define ELF_TARGET_ID LARCH_ELF_DATA 6656 1.1 christos #define ELF_MACHINE_CODE EM_LOONGARCH 6657 1.1.1.3 christos #define ELF_MINPAGESIZE 0x1000 6658 1.1.1.3 christos #define ELF_MAXPAGESIZE 0x10000 6659 1.1.1.3 christos #define ELF_COMMONPAGESIZE 0x4000 6660 1.1 christos #define bfd_elfNN_bfd_reloc_type_lookup loongarch_reloc_type_lookup 6661 1.1 christos #define bfd_elfNN_bfd_link_hash_table_create \ 6662 1.1 christos loongarch_elf_link_hash_table_create 6663 1.1 christos #define bfd_elfNN_bfd_reloc_name_lookup loongarch_reloc_name_lookup 6664 1.1 christos #define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto. */ 6665 1.1 christos #define elf_info_to_howto loongarch_info_to_howto_rela 6666 1.1.1.3 christos #define bfd_elfNN_mkobject \ 6667 1.1.1.3 christos elfNN_loongarch_object 6668 1.1 christos #define bfd_elfNN_bfd_merge_private_bfd_data \ 6669 1.1 christos elfNN_loongarch_merge_private_bfd_data 6670 1.1 christos 6671 1.1 christos #define elf_backend_reloc_type_class loongarch_reloc_type_class 6672 1.1 christos #define elf_backend_copy_indirect_symbol loongarch_elf_copy_indirect_symbol 6673 1.1 christos #define elf_backend_create_dynamic_sections \ 6674 1.1 christos loongarch_elf_create_dynamic_sections 6675 1.1 christos #define elf_backend_check_relocs loongarch_elf_check_relocs 6676 1.1 christos #define elf_backend_adjust_dynamic_symbol loongarch_elf_adjust_dynamic_symbol 6677 1.1.1.3 christos #define elf_backend_late_size_sections loongarch_elf_late_size_sections 6678 1.1 christos #define elf_backend_relocate_section loongarch_elf_relocate_section 6679 1.1 christos #define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol 6680 1.1.1.2 christos #define elf_backend_output_arch_local_syms \ 6681 1.1.1.2 christos elf_loongarch_output_arch_local_syms 6682 1.1 christos #define elf_backend_finish_dynamic_sections \ 6683 1.1 christos loongarch_elf_finish_dynamic_sections 6684 1.1 christos #define elf_backend_object_p loongarch_elf_object_p 6685 1.1 christos #define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook 6686 1.1 christos #define elf_backend_plt_sym_val loongarch_elf_plt_sym_val 6687 1.1 christos #define elf_backend_grok_prstatus loongarch_elf_grok_prstatus 6688 1.1 christos #define elf_backend_grok_psinfo loongarch_elf_grok_psinfo 6689 1.1 christos #define elf_backend_hash_symbol elf_loongarch64_hash_symbol 6690 1.1.1.2 christos #define bfd_elfNN_bfd_relax_section loongarch_elf_relax_section 6691 1.1.1.3 christos #define elf_backend_size_relative_relocs loongarch_elf_size_relative_relocs 6692 1.1.1.3 christos #define elf_backend_finish_relative_relocs \ 6693 1.1.1.3 christos loongarch_elf_finish_relative_relocs 6694 1.1.1.3 christos #define bfd_elfNN_new_section_hook loongarch_elf_new_section_hook 6695 1.1.1.2 christos 6696 1.1.1.2 christos #define elf_backend_dtrel_excludes_plt 1 6697 1.1 christos 6698 1.1 christos #include "elfNN-target.h" 6699