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