1 /* LoongArch-specific support for ELF. 2 Copyright (C) 2021-2022 Free Software Foundation, Inc. 3 Contributed by Loongson Ltd. 4 5 Based on RISC-V target. 6 7 This file is part of BFD, the Binary File Descriptor library. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; see the file COPYING3. If not, 21 see <http://www.gnu.org/licenses/>. */ 22 23 #include "sysdep.h" 24 #include "bfd.h" 25 #include "libbfd.h" 26 #include "elf-bfd.h" 27 #include "elf/loongarch.h" 28 #include "elfxx-loongarch.h" 29 30 #define ALL_ONES (~ (bfd_vma) 0) 31 32 typedef struct loongarch_reloc_howto_type_struct 33 { 34 /* The first must be reloc_howto_type! */ 35 reloc_howto_type howto; 36 bfd_reloc_code_real_type bfd_type; 37 bool (*adjust_reloc_bits)(reloc_howto_type *, bfd_vma *); 38 const char *larch_reloc_type_name; 39 } loongarch_reloc_howto_type; 40 41 #define LOONGARCH_DEFAULT_HOWTO(r_name) \ 42 { HOWTO (R_LARCH_##r_name, 0, 4, 32, false, 0, complain_overflow_signed, \ 43 bfd_elf_generic_reloc, "R_LARCH_" #r_name, false, 0, ALL_ONES, \ 44 false), BFD_RELOC_LARCH_##r_name, NULL, NULL } 45 46 #define LOONGARCH_HOWTO(type, right, size, bits, pcrel, left, ovf, func, \ 47 name, inplace, src_mask, dst_mask, pcrel_off, btype, afunc,lname) \ 48 { HOWTO(type, right, size, bits, pcrel, left, ovf, func, name, \ 49 inplace, src_mask, dst_mask, pcrel_off), btype, afunc, lname } 50 51 #define LOONGARCH_EMPTY_HOWTO(C) \ 52 { EMPTY_HOWTO (C), BFD_RELOC_NONE, NULL, NULL } 53 54 static bool 55 reloc_bits (reloc_howto_type *howto, bfd_vma *val); 56 static bool 57 reloc_bits_b16 (reloc_howto_type *howto, bfd_vma *fix_val); 58 static bool 59 reloc_bits_b21 (reloc_howto_type *howto, bfd_vma *fix_val); 60 static bool 61 reloc_bits_b26 (reloc_howto_type *howto, bfd_vma *val); 62 63 /* This does not include any relocation information, but should be 64 good enough for GDB or objdump to read the file. */ 65 static loongarch_reloc_howto_type loongarch_howto_table[] = 66 { 67 /* No relocation. */ 68 LOONGARCH_HOWTO (R_LARCH_NONE, /* type (0). */ 69 0, /* rightshift */ 70 0, /* size */ 71 0, /* bitsize */ 72 false, /* pc_relative */ 73 0, /* bitpos */ 74 complain_overflow_dont, /* complain_on_overflow */ 75 bfd_elf_generic_reloc, /* special_function */ 76 "R_LARCH_NONE", /* name */ 77 false, /* partial_inplace */ 78 0, /* src_mask */ 79 0, /* dst_mask */ 80 false, /* pcrel_offset */ 81 BFD_RELOC_NONE, /* bfd_reloc_code_real_type */ 82 NULL, /* adjust_reloc_bits */ 83 NULL), /* larch_reloc_type_name */ 84 85 /* 32 bit relocation. */ 86 LOONGARCH_HOWTO (R_LARCH_32, /* type (1). */ 87 0, /* rightshift */ 88 4, /* size */ 89 32, /* bitsize */ 90 false, /* pc_relative */ 91 0, /* bitpos */ 92 complain_overflow_dont, /* complain_on_overflow */ 93 bfd_elf_generic_reloc, /* special_function */ 94 "R_LARCH_32", /* name */ 95 false, /* partial_inplace */ 96 0, /* src_mask */ 97 ALL_ONES, /* dst_mask */ 98 false, /* pcrel_offset */ 99 BFD_RELOC_32, /* bfd_reloc_code_real_type */ 100 NULL, /* adjust_reloc_bits */ 101 NULL), /* larch_reloc_type_name */ 102 103 /* 64 bit relocation. */ 104 LOONGARCH_HOWTO (R_LARCH_64, /* type (2). */ 105 0, /* rightshift */ 106 8, /* size */ 107 64, /* bitsize */ 108 false, /* pc_relative */ 109 0, /* bitpos */ 110 complain_overflow_dont, /* complain_on_overflow */ 111 bfd_elf_generic_reloc, /* special_function */ 112 "R_LARCH_64", /* name */ 113 false, /* partial_inplace */ 114 0, /* src_mask */ 115 ALL_ONES, /* dst_mask */ 116 false, /* pcrel_offset */ 117 BFD_RELOC_64, /* bfd_reloc_code_real_type */ 118 NULL, /* adjust_reloc_bits */ 119 NULL), /* larch_reloc_type_name */ 120 121 LOONGARCH_HOWTO (R_LARCH_RELATIVE, /* type (3). */ 122 0, /* rightshift */ 123 4, /* size */ 124 32, /* bitsize */ 125 false, /* pc_relative */ 126 0, /* bitpos */ 127 complain_overflow_dont, /* complain_on_overflow */ 128 bfd_elf_generic_reloc, /* special_function */ 129 "R_LARCH_RELATIVE", /* name */ 130 false, /* partial_inplace */ 131 0, /* src_mask */ 132 ALL_ONES, /* dst_mask */ 133 false, /* pcrel_offset */ 134 BFD_RELOC_NONE, /* undefined? */ 135 NULL, /* adjust_reloc_bits */ 136 NULL), /* larch_reloc_type_name */ 137 138 LOONGARCH_HOWTO (R_LARCH_COPY, /* type (4). */ 139 0, /* rightshift */ 140 0, /* this one is variable size */ 141 0, /* bitsize */ 142 false, /* pc_relative */ 143 0, /* bitpos */ 144 complain_overflow_bitfield, /* complain_on_overflow */ 145 bfd_elf_generic_reloc, /* special_function */ 146 "R_LARCH_COPY", /* name */ 147 false, /* partial_inplace */ 148 0, /* src_mask */ 149 0, /* dst_mask */ 150 false, /* pcrel_offset */ 151 BFD_RELOC_NONE, /* undefined? */ 152 NULL, /* adjust_reloc_bits */ 153 NULL), /* larch_reloc_type_name */ 154 155 LOONGARCH_HOWTO (R_LARCH_JUMP_SLOT, /* type (5). */ 156 0, /* rightshift */ 157 8, /* size */ 158 64, /* bitsize */ 159 false, /* pc_relative */ 160 0, /* bitpos */ 161 complain_overflow_bitfield, /* complain_on_overflow */ 162 bfd_elf_generic_reloc, /* special_function */ 163 "R_LARCH_JUMP_SLOT", /* name */ 164 false, /* partial_inplace */ 165 0, /* src_mask */ 166 0, /* dst_mask */ 167 false, /* pcrel_offset */ 168 BFD_RELOC_NONE, /* undefined? */ 169 NULL, /* adjust_reloc_bits */ 170 NULL), /* larch_reloc_type_name */ 171 172 /* Dynamic TLS relocations. */ 173 LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD32, /* type (6). */ 174 0, /* rightshift */ 175 4, /* size */ 176 32, /* bitsize */ 177 false, /* pc_relative */ 178 0, /* bitpos */ 179 complain_overflow_dont, /* complain_on_overflow */ 180 bfd_elf_generic_reloc, /* special_function */ 181 "R_LARCH_TLS_DTPMOD32", /* name */ 182 false, /* partial_inplace */ 183 0, /* src_mask */ 184 ALL_ONES, /* dst_mask */ 185 false, /* pcrel_offset */ 186 BFD_RELOC_LARCH_TLS_DTPMOD32, /* bfd_reloc_code_real_type */ 187 NULL, /* adjust_reloc_bits */ 188 NULL), /* larch_reloc_type_name */ 189 190 LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD64, /* type (7). */ 191 0, /* rightshift */ 192 8, /* size */ 193 64, /* bitsize */ 194 false, /* pc_relative */ 195 0, /* bitpos */ 196 complain_overflow_dont, /* complain_on_overflow */ 197 bfd_elf_generic_reloc, /* special_function */ 198 "R_LARCH_TLS_DTPMOD64", /* name */ 199 false, /* partial_inplace */ 200 0, /* src_mask */ 201 ALL_ONES, /* dst_mask */ 202 false, /* pcrel_offset */ 203 BFD_RELOC_LARCH_TLS_DTPMOD64, /* bfd_reloc_code_real_type */ 204 NULL, /* adjust_reloc_bits */ 205 NULL), /* larch_reloc_type_name */ 206 207 LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL32, /* type (8). */ 208 0, /* rightshift */ 209 4, /* size */ 210 32, /* bitsize */ 211 false, /* pc_relative */ 212 0, /* bitpos */ 213 complain_overflow_dont, /* complain_on_overflow */ 214 bfd_elf_generic_reloc, /* special_function */ 215 "R_LARCH_TLS_DTPREL32", /* name */ 216 true, /* partial_inplace */ 217 0, /* src_mask */ 218 ALL_ONES, /* dst_mask */ 219 false, /* pcrel_offset */ 220 BFD_RELOC_LARCH_TLS_DTPREL32, /* bfd_reloc_code_real_type */ 221 NULL, /* adjust_reloc_bits */ 222 NULL), /* larch_reloc_type_name */ 223 224 LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL64, /* type (9). */ 225 0, /* rightshift */ 226 8, /* size */ 227 64, /* bitsize */ 228 false, /* pc_relative */ 229 0, /* bitpos */ 230 complain_overflow_dont, /* complain_on_overflow */ 231 bfd_elf_generic_reloc, /* special_function */ 232 "R_LARCH_TLS_DTPREL64", /* name */ 233 true, /* partial_inplace */ 234 0, /* src_mask */ 235 ALL_ONES, /* dst_mask */ 236 false, /* pcrel_offset */ 237 BFD_RELOC_LARCH_TLS_DTPREL64, /* bfd_reloc_code_real_type */ 238 NULL, /* adjust_reloc_bits */ 239 NULL), /* larch_reloc_type_name */ 240 241 LOONGARCH_HOWTO (R_LARCH_TLS_TPREL32, /* type (10). */ 242 0, /* rightshift */ 243 4, /* size */ 244 32, /* bitsize */ 245 false, /* pc_relative */ 246 0, /* bitpos */ 247 complain_overflow_dont, /* complain_on_overflow */ 248 bfd_elf_generic_reloc, /* special_function */ 249 "R_LARCH_TLS_TPREL32", /* name */ 250 false, /* partial_inplace */ 251 0, /* src_mask */ 252 ALL_ONES, /* dst_mask */ 253 false, /* pcrel_offset */ 254 BFD_RELOC_LARCH_TLS_TPREL32, /* bfd_reloc_code_real_type */ 255 NULL, /* adjust_reloc_bits */ 256 NULL), /* larch_reloc_type_name */ 257 258 LOONGARCH_HOWTO (R_LARCH_TLS_TPREL64, /* type (11). */ 259 0, /* rightshift */ 260 8, /* size */ 261 64, /* bitsize */ 262 false, /* pc_relative */ 263 0, /* bitpos */ 264 complain_overflow_dont, /* complain_on_overflow */ 265 bfd_elf_generic_reloc, /* special_function */ 266 "R_LARCH_TLS_TPREL64", /* name */ 267 false, /* partial_inplace */ 268 0, /* src_mask */ 269 ALL_ONES, /* dst_mask */ 270 false, /* pcrel_offset */ 271 BFD_RELOC_LARCH_TLS_TPREL64, /* bfd_reloc_code_real_type */ 272 NULL, /* adjust_reloc_bits */ 273 NULL), /* larch_reloc_type_name */ 274 275 LOONGARCH_HOWTO (R_LARCH_IRELATIVE, /* type (12). */ 276 0, /* rightshift */ 277 4, /* size */ 278 32, /* bitsize */ 279 false, /* pc_relative */ 280 0, /* bitpos */ 281 complain_overflow_dont, /* complain_on_overflow */ 282 bfd_elf_generic_reloc, /* special_function */ 283 "R_LARCH_IRELATIVE", /* name */ 284 false, /* partial_inplace */ 285 0, /* src_mask */ 286 ALL_ONES, /* dst_mask */ 287 false, /* pcrel_offset */ 288 BFD_RELOC_NONE, /* undefined? */ 289 NULL, /* adjust_reloc_bits */ 290 NULL), /* larch_reloc_type_name */ 291 292 LOONGARCH_EMPTY_HOWTO (13), 293 LOONGARCH_EMPTY_HOWTO (14), 294 LOONGARCH_EMPTY_HOWTO (15), 295 LOONGARCH_EMPTY_HOWTO (16), 296 LOONGARCH_EMPTY_HOWTO (17), 297 LOONGARCH_EMPTY_HOWTO (18), 298 LOONGARCH_EMPTY_HOWTO (19), 299 300 LOONGARCH_HOWTO (R_LARCH_MARK_LA, /* type (20). */ 301 0, /* rightshift. */ 302 0, /* size. */ 303 0, /* bitsize. */ 304 false, /* pc_relative. */ 305 0, /* bitpos. */ 306 complain_overflow_signed, /* complain_on_overflow. */ 307 bfd_elf_generic_reloc, /* special_function. */ 308 "R_LARCH_MARK_LA", /* name. */ 309 false, /* partial_inplace. */ 310 0, /* src_mask. */ 311 0, /* dst_mask. */ 312 false, /* pcrel_offset */ 313 BFD_RELOC_LARCH_MARK_LA, /* bfd_reloc_code_real_type */ 314 NULL, /* adjust_reloc_bits */ 315 NULL), /* larch_reloc_type_name */ 316 317 LOONGARCH_HOWTO (R_LARCH_MARK_PCREL, /* type (21). */ 318 0, /* rightshift. */ 319 0, /* size. */ 320 0, /* bitsize. */ 321 false, /* pc_relative. */ 322 0, /* bitpos. */ 323 complain_overflow_signed, /* complain_on_overflow. */ 324 bfd_elf_generic_reloc, /* special_function. */ 325 "R_LARCH_MARK_PCREL", /* name. */ 326 false, /* partial_inplace. */ 327 0, /* src_mask. */ 328 0, /* dst_mask. */ 329 false, /* pcrel_offset */ 330 BFD_RELOC_LARCH_MARK_PCREL, /* bfd_reloc_code_real_type */ 331 NULL, /* adjust_reloc_bits */ 332 NULL), /* larch_reloc_type_name */ 333 334 LOONGARCH_HOWTO (R_LARCH_SOP_PUSH_PCREL, /* type (22). */ 335 2, /* rightshift. */ 336 4, /* size. */ 337 32, /* bitsize. */ 338 true /* FIXME: somewhat use this. */, /* pc_relative. */ 339 0, /* bitpos. */ 340 complain_overflow_signed, /* complain_on_overflow. */ 341 bfd_elf_generic_reloc, /* special_function. */ 342 "R_LARCH_SOP_PUSH_PCREL", /* name. */ 343 false, /* partial_inplace. */ 344 0x03ffffff, /* src_mask. */ 345 0x03ffffff, /* dst_mask. */ 346 false, /* pcrel_offset */ 347 BFD_RELOC_LARCH_SOP_PUSH_PCREL, /* bfd_reloc_code_real_type */ 348 NULL, /* adjust_reloc_bits */ 349 NULL), /* larch_reloc_type_name */ 350 351 /* type 23-37. */ 352 LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_ABSOLUTE), 353 LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_DUP), 354 LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_GPREL), 355 LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_TLS_TPREL), 356 LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_TLS_GOT), 357 LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_TLS_GD), 358 LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_PLT_PCREL), 359 LOONGARCH_DEFAULT_HOWTO (SOP_ASSERT), 360 LOONGARCH_DEFAULT_HOWTO (SOP_NOT), 361 LOONGARCH_DEFAULT_HOWTO (SOP_SUB), 362 LOONGARCH_DEFAULT_HOWTO (SOP_SL), 363 LOONGARCH_DEFAULT_HOWTO (SOP_SR), 364 LOONGARCH_DEFAULT_HOWTO (SOP_ADD), 365 LOONGARCH_DEFAULT_HOWTO (SOP_AND), 366 LOONGARCH_DEFAULT_HOWTO (SOP_IF_ELSE), 367 368 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_5, /* type (38). */ 369 0, /* rightshift. */ 370 4, /* size. */ 371 5, /* bitsize. */ 372 false, /* pc_relative. */ 373 10, /* bitpos. */ 374 complain_overflow_signed, /* complain_on_overflow. */ 375 bfd_elf_generic_reloc, /* special_function. */ 376 "R_LARCH_SOP_POP_32_S_10_5", /* name. */ 377 false, /* partial_inplace. */ 378 0, /* src_mask */ 379 0x7c00, /* dst_mask */ 380 false, /* pcrel_offset */ 381 BFD_RELOC_LARCH_SOP_POP_32_S_10_5, /* bfd_reloc_code_real_type */ 382 reloc_bits, /* adjust_reloc_bits */ 383 NULL), /* larch_reloc_type_name */ 384 385 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U_10_12, /* type (39). */ 386 0, /* rightshift. */ 387 4, /* size. */ 388 12, /* bitsize. */ 389 false, /* pc_relative. */ 390 10, /* bitpos. */ 391 complain_overflow_unsigned, /* complain_on_overflow. */ 392 bfd_elf_generic_reloc, /* special_function. */ 393 "R_LARCH_SOP_POP_32_U_10_12", /* name. */ 394 false, /* partial_inplace. */ 395 0, /* src_mask */ 396 0x3ffc00, /* dst_mask */ 397 false, /* pcrel_offset */ 398 BFD_RELOC_LARCH_SOP_POP_32_U_10_12, /* bfd_reloc_code_real_type */ 399 reloc_bits, /* adjust_reloc_bits */ 400 NULL), /* larch_reloc_type_name */ 401 402 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_12, /* type (40). */ 403 0, /* rightshift. */ 404 4, /* size. */ 405 12, /* bitsize. */ 406 false, /* pc_relative. */ 407 10, /* bitpos. */ 408 complain_overflow_signed, /* complain_on_overflow. */ 409 bfd_elf_generic_reloc, /* special_function. */ 410 "R_LARCH_SOP_POP_32_S_10_12", /* name. */ 411 false, /* partial_inplace. */ 412 0, /* src_mask */ 413 0x3ffc00, /* dst_mask */ 414 false, /* pcrel_offset */ 415 BFD_RELOC_LARCH_SOP_POP_32_S_10_12, /* bfd_reloc_code_real_type */ 416 reloc_bits, /* adjust_reloc_bits */ 417 NULL), /* larch_reloc_type_name */ 418 419 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16, /* type (41). */ 420 0, /* rightshift. */ 421 4, /* size. */ 422 16, /* bitsize. */ 423 false, /* pc_relative. */ 424 10, /* bitpos. */ 425 complain_overflow_signed, /* complain_on_overflow. */ 426 bfd_elf_generic_reloc, /* special_function. */ 427 "R_LARCH_SOP_POP_32_S_10_16", /* name. */ 428 false, /* partial_inplace. */ 429 0, /* src_mask */ 430 0x3fffc00, /* dst_mask */ 431 false, /* pcrel_offset */ 432 BFD_RELOC_LARCH_SOP_POP_32_S_10_16, /* bfd_reloc_code_real_type */ 433 reloc_bits, /* adjust_reloc_bits */ 434 NULL), /* larch_reloc_type_name */ 435 436 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16_S2, /* type (42). */ 437 2, /* rightshift. */ 438 4, /* size. */ 439 16, /* bitsize. */ 440 false, /* pc_relative. */ 441 10, /* bitpos. */ 442 complain_overflow_signed, /* complain_on_overflow. */ 443 bfd_elf_generic_reloc, /* special_function. */ 444 "R_LARCH_SOP_POP_32_S_10_16_S2", /* name. */ 445 false, /* partial_inplace. */ 446 0, /* src_mask */ 447 0x3fffc00, /* dst_mask */ 448 false, /* pcrel_offset */ 449 BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2, /* bfd_reloc_code_real_type */ 450 reloc_bits_b16, /* adjust_reloc_bits */ 451 NULL), /* larch_reloc_type_name */ 452 453 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_5_20, /* type (43). */ 454 0, /* rightshift. */ 455 4, /* size. */ 456 20, /* bitsize. */ 457 false, /* pc_relative. */ 458 5, /* bitpos. */ 459 complain_overflow_signed, /* complain_on_overflow. */ 460 bfd_elf_generic_reloc, /* special_function. */ 461 "R_LARCH_SOP_POP_32_S_5_20", /* name. */ 462 false, /* partial_inplace. */ 463 0, /* src_mask */ 464 0x1ffffe0, /* dst_mask */ 465 false, /* pcrel_offset */ 466 BFD_RELOC_LARCH_SOP_POP_32_S_5_20, /* bfd_reloc_code_real_type */ 467 reloc_bits, /* adjust_reloc_bits */ 468 NULL), /* larch_reloc_type_name */ 469 470 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_5_10_16_S2, 471 /* type (44). */ 472 2, /* rightshift. */ 473 4, /* size. */ 474 21, /* bitsize. */ 475 false, /* pc_relative. */ 476 0, /* bitpos. */ 477 complain_overflow_signed, /* complain_on_overflow. */ 478 bfd_elf_generic_reloc, /* special_function. */ 479 "R_LARCH_SOP_POP_32_S_0_5_10_16_S2", /* name. */ 480 false, /* partial_inplace. */ 481 0xfc0003e0, /* src_mask */ 482 0xfc0003e0, /* dst_mask */ 483 false, /* pcrel_offset */ 484 BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2, 485 /* bfd_reloc_code_real_type */ 486 reloc_bits_b21, /* adjust_reloc_bits */ 487 NULL), /* larch_reloc_type_name */ 488 489 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_10_10_16_S2, /* type (45). */ 490 2, /* rightshift. */ 491 4, /* size. */ 492 26, /* bitsize. */ 493 false, /* pc_relative. */ 494 0, /* bitpos. */ 495 complain_overflow_signed, /* complain_on_overflow. */ 496 bfd_elf_generic_reloc, /* special_function. */ 497 "R_LARCH_SOP_POP_32_S_0_10_10_16_S2", /* name. */ 498 false, /* partial_inplace. */ 499 0, /* src_mask */ 500 0x03ffffff, /* dst_mask */ 501 false, /* pcrel_offset */ 502 BFD_RELOC_LARCH_SOP_POP_32_S_0_10_10_16_S2, 503 /* bfd_reloc_code_real_type */ 504 reloc_bits_b26, /* adjust_reloc_bits */ 505 NULL), /* larch_reloc_type_name */ 506 507 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U, /* type (46). */ 508 0, /* rightshift. */ 509 4, /* size. */ 510 32, /* bitsize. */ 511 false, /* pc_relative. */ 512 0, /* bitpos. */ 513 complain_overflow_unsigned, /* complain_on_overflow. */ 514 bfd_elf_generic_reloc, /* special_function. */ 515 "R_LARCH_SOP_POP_32_S_U", /* name. */ 516 false, /* partial_inplace. */ 517 0xffffffff00000000, /* src_mask */ 518 0x00000000ffffffff, /* dst_mask */ 519 false, /* pcrel_offset */ 520 BFD_RELOC_LARCH_SOP_POP_32_U, /* bfd_reloc_code_real_type */ 521 reloc_bits, /* adjust_reloc_bits */ 522 NULL), /* larch_reloc_type_name */ 523 524 LOONGARCH_HOWTO (R_LARCH_ADD8, /* type (47). */ 525 0, /* rightshift. */ 526 4, /* size. */ 527 8, /* bitsize. */ 528 false, /* pc_relative. */ 529 0, /* bitpos. */ 530 complain_overflow_signed, /* complain_on_overflow. */ 531 bfd_elf_generic_reloc, /* special_function. */ 532 "R_LARCH_ADD8", /* name. */ 533 false, /* partial_inplace. */ 534 0, /* src_mask */ 535 ALL_ONES, /* dst_mask */ 536 false, /* pcrel_offset */ 537 BFD_RELOC_LARCH_ADD8, /* bfd_reloc_code_real_type */ 538 NULL, /* adjust_reloc_bits */ 539 NULL), /* larch_reloc_type_name */ 540 541 LOONGARCH_HOWTO (R_LARCH_ADD16, /* type (48). */ 542 0, /* rightshift. */ 543 4, /* size. */ 544 16, /* bitsize. */ 545 false, /* pc_relative. */ 546 0, /* bitpos. */ 547 complain_overflow_signed, /* complain_on_overflow. */ 548 bfd_elf_generic_reloc, /* special_function. */ 549 "R_LARCH_ADD16", /* name. */ 550 false, /* partial_inplace. */ 551 0, /* src_mask */ 552 ALL_ONES, /* dst_mask */ 553 false, /* pcrel_offset */ 554 BFD_RELOC_LARCH_ADD16, /* bfd_reloc_code_real_type */ 555 NULL, /* adjust_reloc_bits */ 556 NULL), /* larch_reloc_type_name */ 557 558 LOONGARCH_HOWTO (R_LARCH_ADD24, /* type (49). */ 559 0, /* rightshift. */ 560 4, /* size. */ 561 24, /* bitsize. */ 562 false, /* pc_relative. */ 563 0, /* bitpos. */ 564 complain_overflow_signed, /* complain_on_overflow. */ 565 bfd_elf_generic_reloc, /* special_function. */ 566 "R_LARCH_ADD24", /* name. */ 567 false, /* partial_inplace. */ 568 0, /* src_mask */ 569 ALL_ONES, /* dst_mask */ 570 false, /* pcrel_offset */ 571 BFD_RELOC_LARCH_ADD24, /* bfd_reloc_code_real_type */ 572 NULL, /* adjust_reloc_bits */ 573 NULL), /* larch_reloc_type_name */ 574 575 LOONGARCH_HOWTO (R_LARCH_ADD32, /* type (50). */ 576 0, /* rightshift. */ 577 4, /* size. */ 578 32, /* bitsize. */ 579 false, /* pc_relative. */ 580 0, /* bitpos. */ 581 complain_overflow_signed, /* complain_on_overflow. */ 582 bfd_elf_generic_reloc, /* special_function. */ 583 "R_LARCH_ADD32", /* name. */ 584 false, /* partial_inplace. */ 585 0, /* src_mask */ 586 ALL_ONES, /* dst_mask */ 587 false, /* pcrel_offset */ 588 BFD_RELOC_LARCH_ADD32, /* bfd_reloc_code_real_type */ 589 NULL, /* adjust_reloc_bits */ 590 NULL), /* larch_reloc_type_name */ 591 592 LOONGARCH_HOWTO (R_LARCH_ADD64, /* type (51). */ 593 0, /* rightshift. */ 594 8, /* size. */ 595 64, /* bitsize. */ 596 false, /* pc_relative. */ 597 0, /* bitpos. */ 598 complain_overflow_signed, /* complain_on_overflow. */ 599 bfd_elf_generic_reloc, /* special_function. */ 600 "R_LARCH_ADD64", /* name. */ 601 false, /* partial_inplace. */ 602 0, /* src_mask */ 603 ALL_ONES, /* dst_mask */ 604 false, /* pcrel_offset */ 605 BFD_RELOC_LARCH_ADD64, /* bfd_reloc_code_real_type */ 606 NULL, /* adjust_reloc_bits */ 607 NULL), /* larch_reloc_type_name */ 608 609 LOONGARCH_HOWTO (R_LARCH_SUB8, /* type (52). */ 610 0, /* rightshift. */ 611 4, /* size. */ 612 8, /* bitsize. */ 613 false, /* pc_relative. */ 614 0, /* bitpos. */ 615 complain_overflow_signed, /* complain_on_overflow. */ 616 bfd_elf_generic_reloc, /* special_function. */ 617 "R_LARCH_SUB8", /* name. */ 618 false, /* partial_inplace. */ 619 0, /* src_mask */ 620 ALL_ONES, /* dst_mask */ 621 false, /* pcrel_offset */ 622 BFD_RELOC_LARCH_SUB8, /* bfd_reloc_code_real_type */ 623 NULL, /* adjust_reloc_bits */ 624 NULL), /* larch_reloc_type_name */ 625 626 LOONGARCH_HOWTO (R_LARCH_SUB16, /* type (53). */ 627 0, /* rightshift. */ 628 4, /* size. */ 629 16, /* bitsize. */ 630 false, /* pc_relative. */ 631 0, /* bitpos. */ 632 complain_overflow_signed, /* complain_on_overflow. */ 633 bfd_elf_generic_reloc, /* special_function. */ 634 "R_LARCH_SUB16", /* name. */ 635 false, /* partial_inplace. */ 636 0, /* src_mask */ 637 ALL_ONES, /* dst_mask */ 638 false, /* pcrel_offset */ 639 BFD_RELOC_LARCH_SUB16, /* bfd_reloc_code_real_type */ 640 NULL, /* adjust_reloc_bits */ 641 NULL), /* larch_reloc_type_name */ 642 643 LOONGARCH_HOWTO (R_LARCH_SUB24, /* type (54). */ 644 0, /* rightshift. */ 645 4, /* size. */ 646 24, /* bitsize. */ 647 false, /* pc_relative. */ 648 0, /* bitpos. */ 649 complain_overflow_signed, /* complain_on_overflow. */ 650 bfd_elf_generic_reloc, /* special_function. */ 651 "R_LARCH_SUB24", /* name. */ 652 false, /* partial_inplace. */ 653 0, /* src_mask */ 654 ALL_ONES, /* dst_mask */ 655 false, /* pcrel_offset */ 656 BFD_RELOC_LARCH_SUB24, /* bfd_reloc_code_real_type */ 657 NULL, /* adjust_reloc_bits */ 658 NULL), /* larch_reloc_type_name */ 659 660 LOONGARCH_HOWTO (R_LARCH_SUB32, /* type (55). */ 661 0, /* rightshift. */ 662 4, /* size. */ 663 32, /* bitsize. */ 664 false, /* pc_relative. */ 665 0, /* bitpos. */ 666 complain_overflow_signed, /* complain_on_overflow. */ 667 bfd_elf_generic_reloc, /* special_function. */ 668 "R_LARCH_SUB32", /* name. */ 669 false, /* partial_inplace. */ 670 0, /* src_mask */ 671 ALL_ONES, /* dst_mask */ 672 false, /* pcrel_offset */ 673 BFD_RELOC_LARCH_SUB32, /* bfd_reloc_code_real_type */ 674 NULL, /* adjust_reloc_bits */ 675 NULL), /* larch_reloc_type_name */ 676 677 LOONGARCH_HOWTO (R_LARCH_SUB64, /* type (56). */ 678 0, /* rightshift. */ 679 8, /* size. */ 680 64, /* bitsize. */ 681 false, /* pc_relative. */ 682 0, /* bitpos. */ 683 complain_overflow_signed, /* complain_on_overflow. */ 684 bfd_elf_generic_reloc, /* special_function. */ 685 "R_LARCH_SUB64", /* name. */ 686 false, /* partial_inplace. */ 687 0, /* src_mask */ 688 ALL_ONES, /* dst_mask */ 689 false, /* pcrel_offset */ 690 BFD_RELOC_LARCH_SUB64, /* bfd_reloc_code_real_type */ 691 NULL, /* adjust_reloc_bits */ 692 NULL), /* larch_reloc_type_name */ 693 694 LOONGARCH_HOWTO (R_LARCH_GNU_VTINHERIT, /* type (57). */ 695 0, /* rightshift. */ 696 0, /* size. */ 697 0, /* bitsize. */ 698 false, /* pc_relative. */ 699 0, /* bitpos. */ 700 complain_overflow_signed, /* complain_on_overflow. */ 701 bfd_elf_generic_reloc, /* special_function. */ 702 "R_LARCH_GNU_VTINHERIT", /* name. */ 703 false, /* partial_inplace. */ 704 0, /* src_mask */ 705 0, /* dst_mask */ 706 false, /* pcrel_offset */ 707 BFD_RELOC_NONE, /* bfd_reloc_code_real_type */ 708 NULL, /* adjust_reloc_bits */ 709 NULL), /* larch_reloc_type_name */ 710 711 LOONGARCH_HOWTO (R_LARCH_GNU_VTENTRY, /* type (58). */ 712 0, /* rightshift. */ 713 0, /* size. */ 714 0, /* bitsize. */ 715 false, /* pc_relative. */ 716 0, /* bitpos. */ 717 complain_overflow_signed, /* complain_on_overflow. */ 718 NULL, /* special_function. */ 719 "R_LARCH_GNU_VTENTRY", /* name. */ 720 false, /* partial_inplace. */ 721 0, /* src_mask */ 722 0, /* dst_mask */ 723 false, /* pcrel_offset */ 724 BFD_RELOC_NONE, /* bfd_reloc_code_real_type */ 725 NULL, /* adjust_reloc_bits */ 726 NULL), /* larch_reloc_type_name */ 727 728 LOONGARCH_EMPTY_HOWTO (59), 729 LOONGARCH_EMPTY_HOWTO (60), 730 LOONGARCH_EMPTY_HOWTO (61), 731 LOONGARCH_EMPTY_HOWTO (62), 732 LOONGARCH_EMPTY_HOWTO (63), 733 734 /* New reloc types. */ 735 LOONGARCH_HOWTO (R_LARCH_B16, /* type (64). */ 736 2, /* rightshift. */ 737 4, /* size. */ 738 16, /* bitsize. */ 739 false, /* pc_relative. */ 740 10, /* bitpos. */ 741 complain_overflow_signed, /* complain_on_overflow. */ 742 bfd_elf_generic_reloc, /* special_function. */ 743 "R_LARCH_B16", /* name. */ 744 false, /* partial_inplace. */ 745 0x3fffc00, /* src_mask */ 746 0x3fffc00, /* dst_mask */ 747 false, /* pcrel_offset */ 748 BFD_RELOC_LARCH_B16, /* bfd_reloc_code_real_type */ 749 reloc_bits_b16, /* adjust_reloc_bits */ 750 "b16"), /* larch_reloc_type_name */ 751 752 LOONGARCH_HOWTO (R_LARCH_B21, /* type (65). */ 753 2, /* rightshift. */ 754 4, /* size. */ 755 21, /* bitsize. */ 756 false, /* pc_relative. */ 757 0, /* bitpos. */ 758 complain_overflow_signed, /* complain_on_overflow. */ 759 bfd_elf_generic_reloc, /* special_function. */ 760 "R_LARCH_B21", /* name. */ 761 false, /* partial_inplace. */ 762 0xfc0003e0, /* src_mask */ 763 0xfc0003e0, /* dst_mask */ 764 false, /* pcrel_offset */ 765 BFD_RELOC_LARCH_B21, /* bfd_reloc_code_real_type */ 766 reloc_bits_b21, /* adjust_reloc_bits */ 767 "b21"), /* larch_reloc_type_name */ 768 769 LOONGARCH_HOWTO (R_LARCH_B26, /* type (66). */ 770 2, /* rightshift. */ 771 4, /* size. */ 772 26, /* bitsize. */ 773 false, /* pc_relative. */ 774 0, /* bitpos. */ 775 complain_overflow_signed, /* complain_on_overflow. */ 776 bfd_elf_generic_reloc, /* special_function. */ 777 "R_LARCH_B26", /* name. */ 778 false, /* partial_inplace. */ 779 0, /* src_mask */ 780 0x03ffffff, /* dst_mask */ 781 false, /* pcrel_offset */ 782 BFD_RELOC_LARCH_B26, /* bfd_reloc_code_real_type */ 783 reloc_bits_b26, /* adjust_reloc_bits */ 784 "b26"), /* larch_reloc_type_name */ 785 786 LOONGARCH_HOWTO (R_LARCH_ABS_HI20, /* type (67). */ 787 12, /* rightshift. */ 788 4, /* size. */ 789 20, /* bitsize. */ 790 false, /* pc_relative. */ 791 5, /* bitpos. */ 792 complain_overflow_signed, /* complain_on_overflow. */ 793 bfd_elf_generic_reloc, /* special_function. */ 794 "R_LARCH_ABS_HI20", /* name. */ 795 false, /* partial_inplace. */ 796 0, /* src_mask */ 797 0x1ffffe0, /* dst_mask */ 798 false, /* pcrel_offset */ 799 BFD_RELOC_LARCH_ABS_HI20, /* bfd_reloc_code_real_type */ 800 reloc_bits, /* adjust_reloc_bits */ 801 "abs_hi20"), /* larch_reloc_type_name */ 802 803 LOONGARCH_HOWTO (R_LARCH_ABS_LO12, /* type (68). */ 804 0, /* rightshift. */ 805 4, /* size. */ 806 12, /* bitsize. */ 807 false, /* pc_relative. */ 808 10, /* bitpos. */ 809 complain_overflow_unsigned, /* complain_on_overflow. */ 810 bfd_elf_generic_reloc, /* special_function. */ 811 "R_LARCH_ABS_LO12", /* name. */ 812 false, /* partial_inplace. */ 813 0, /* src_mask */ 814 0x3ffc00, /* dst_mask */ 815 false, /* pcrel_offset */ 816 BFD_RELOC_LARCH_ABS_LO12, /* bfd_reloc_code_real_type */ 817 reloc_bits, /* adjust_reloc_bits */ 818 "abs_lo12"), /* larch_reloc_type_name */ 819 820 LOONGARCH_HOWTO (R_LARCH_ABS64_LO20, /* type (69). */ 821 32, /* rightshift. */ 822 4, /* size. */ 823 20, /* bitsize. */ 824 false, /* pc_relative. */ 825 5, /* bitpos. */ 826 complain_overflow_signed, /* complain_on_overflow. */ 827 bfd_elf_generic_reloc, /* special_function. */ 828 "R_LARCH_ABS64_LO20", /* name. */ 829 false, /* partial_inplace. */ 830 0, /* src_mask */ 831 0x1ffffe0, /* dst_mask */ 832 false, /* pcrel_offset */ 833 BFD_RELOC_LARCH_ABS64_LO20, /* bfd_reloc_code_real_type */ 834 reloc_bits, /* adjust_reloc_bits */ 835 "abs64_lo20"), /* larch_reloc_type_name */ 836 837 LOONGARCH_HOWTO (R_LARCH_ABS64_HI12, /* type (70). */ 838 52, /* rightshift. */ 839 4, /* size. */ 840 12, /* bitsize. */ 841 false, /* pc_relative. */ 842 10, /* bitpos. */ 843 complain_overflow_signed, /* complain_on_overflow. */ 844 bfd_elf_generic_reloc, /* special_function. */ 845 "R_LARCH_ABS64_HI12", /* name. */ 846 false, /* partial_inplace. */ 847 0, /* src_mask */ 848 0x3ffc00, /* dst_mask */ 849 false, /* pcrel_offset */ 850 BFD_RELOC_LARCH_ABS64_HI12, /* bfd_reloc_code_real_type */ 851 reloc_bits, /* adjust_reloc_bits */ 852 "abs64_hi12"), /* larch_reloc_type_name */ 853 854 LOONGARCH_HOWTO (R_LARCH_PCALA_HI20, /* type (71). */ 855 12, /* rightshift. */ 856 4, /* size. */ 857 20, /* bitsize. */ 858 false, /* pc_relative. */ 859 5, /* bitpos. */ 860 complain_overflow_signed, /* complain_on_overflow. */ 861 bfd_elf_generic_reloc, /* special_function. */ 862 "R_LARCH_PCALA_HI20", /* name. */ 863 false, /* partial_inplace. */ 864 0, /* src_mask */ 865 0x1ffffe0, /* dst_mask */ 866 false, /* pcrel_offset */ 867 BFD_RELOC_LARCH_PCALA_HI20, /* bfd_reloc_code_real_type */ 868 reloc_bits, /* adjust_reloc_bits */ 869 "pc_hi20"), /* larch_reloc_type_name */ 870 871 LOONGARCH_HOWTO (R_LARCH_PCALA_LO12, /* type (72). */ 872 0, /* rightshift. */ 873 4, /* size. */ 874 12, /* bitsize. */ 875 false, /* pc_relative. */ 876 10, /* bitpos. */ 877 complain_overflow_signed, /* complain_on_overflow. */ 878 bfd_elf_generic_reloc, /* special_function. */ 879 "R_LARCH_PCALA_LO12", /* name. */ 880 false, /* partial_inplace. */ 881 0, /* src_mask */ 882 0x3ffc00, /* dst_mask */ 883 false, /* pcrel_offset */ 884 BFD_RELOC_LARCH_PCALA_LO12, /* bfd_reloc_code_real_type */ 885 reloc_bits, /* adjust_reloc_bits */ 886 "pc_lo12"), /* larch_reloc_type_name */ 887 888 LOONGARCH_HOWTO (R_LARCH_PCALA64_LO20, /* type (73). */ 889 32, /* rightshift. */ 890 4, /* size. */ 891 20, /* bitsize. */ 892 false, /* pc_relative. */ 893 5, /* bitpos. */ 894 complain_overflow_signed, /* complain_on_overflow. */ 895 bfd_elf_generic_reloc, /* special_function. */ 896 "R_LARCH_PCALA64_LO20", /* name. */ 897 false, /* partial_inplace. */ 898 0, /* src_mask */ 899 0x1ffffe0, /* dst_mask */ 900 false, /* pcrel_offset */ 901 BFD_RELOC_LARCH_PCALA64_LO20, /* bfd_reloc_code_real_type */ 902 reloc_bits, /* adjust_reloc_bits */ 903 "pc64_lo20"), /* larch_reloc_type_name */ 904 905 LOONGARCH_HOWTO (R_LARCH_PCALA64_HI12, /* type (74). */ 906 52, /* rightshift. */ 907 4, /* size. */ 908 12, /* bitsize. */ 909 false, /* pc_relative. */ 910 10, /* bitpos. */ 911 complain_overflow_signed, /* complain_on_overflow. */ 912 bfd_elf_generic_reloc, /* special_function. */ 913 "R_LARCH_PCALA64_HI12", /* name. */ 914 false, /* partial_inplace. */ 915 0, /* src_mask */ 916 0x3ffc00, /* dst_mask */ 917 false, /* pcrel_offset */ 918 BFD_RELOC_LARCH_PCALA64_HI12, /* bfd_reloc_code_real_type */ 919 reloc_bits, /* adjust_reloc_bits */ 920 "pc64_hi12"), /* larch_reloc_type_name */ 921 922 LOONGARCH_HOWTO (R_LARCH_GOT_PC_HI20, /* type (75). */ 923 12, /* rightshift. */ 924 4, /* size. */ 925 20, /* bitsize. */ 926 false, /* pc_relative. */ 927 5, /* bitpos. */ 928 complain_overflow_signed, /* complain_on_overflow. */ 929 bfd_elf_generic_reloc, /* special_function. */ 930 "R_LARCH_GOT_PC_HI20", /* name. */ 931 false, /* partial_inplace. */ 932 0, /* src_mask */ 933 0x1ffffe0, /* dst_mask */ 934 false, /* pcrel_offset */ 935 BFD_RELOC_LARCH_GOT_PC_HI20, /* bfd_reloc_code_real_type */ 936 reloc_bits, /* adjust_reloc_bits */ 937 "got_pc_hi20"), /* larch_reloc_type_name */ 938 939 LOONGARCH_HOWTO (R_LARCH_GOT_PC_LO12, /* type (76). */ 940 0, /* rightshift. */ 941 4, /* size. */ 942 12, /* bitsize. */ 943 false, /* pc_relative. */ 944 10, /* bitpos. */ 945 complain_overflow_signed, /* complain_on_overflow. */ 946 bfd_elf_generic_reloc, /* special_function. */ 947 "R_LARCH_GOT_PC_LO12", /* name. */ 948 false, /* partial_inplace. */ 949 0, /* src_mask */ 950 0x3ffc00, /* dst_mask */ 951 false, /* pcrel_offset */ 952 BFD_RELOC_LARCH_GOT_PC_LO12, /* bfd_reloc_code_real_type */ 953 reloc_bits, /* adjust_reloc_bits */ 954 "got_pc_lo12"), /* larch_reloc_type_name */ 955 956 LOONGARCH_HOWTO (R_LARCH_GOT64_PC_LO20, /* type (77). */ 957 32, /* rightshift. */ 958 4, /* size. */ 959 20, /* bitsize. */ 960 false, /* pc_relative. */ 961 5, /* bitpos. */ 962 complain_overflow_signed, /* complain_on_overflow. */ 963 bfd_elf_generic_reloc, /* special_function. */ 964 "R_LARCH_GOT64_PC_LO20", /* name. */ 965 false, /* partial_inplace. */ 966 0, /* src_mask */ 967 0x1ffffe0, /* dst_mask */ 968 false, /* pcrel_offset */ 969 BFD_RELOC_LARCH_GOT64_PC_LO20, /* bfd_reloc_code_real_type */ 970 reloc_bits, /* adjust_reloc_bits */ 971 "got64_pc_lo20"), /* larch_reloc_type_name */ 972 973 LOONGARCH_HOWTO (R_LARCH_GOT64_PC_HI12, /* type (78). */ 974 52, /* rightshift. */ 975 4, /* size. */ 976 12, /* bitsize. */ 977 false, /* pc_relative. */ 978 10, /* bitpos. */ 979 complain_overflow_signed, /* complain_on_overflow. */ 980 bfd_elf_generic_reloc, /* special_function. */ 981 "R_LARCH_GOT64_PC_HI12", /* name. */ 982 false, /* partial_inplace. */ 983 0, /* src_mask */ 984 0x3ffc00, /* dst_mask */ 985 false, /* pcrel_offset */ 986 BFD_RELOC_LARCH_GOT64_PC_HI12, /* bfd_reloc_code_real_type */ 987 reloc_bits, /* adjust_reloc_bits */ 988 "got64_pc_hi12"), /* larch_reloc_type_name */ 989 990 LOONGARCH_HOWTO (R_LARCH_GOT_HI20, /* type (79). */ 991 12, /* rightshift. */ 992 4, /* size. */ 993 20, /* bitsize. */ 994 false, /* pc_relative. */ 995 5, /* bitpos. */ 996 complain_overflow_signed, /* complain_on_overflow. */ 997 bfd_elf_generic_reloc, /* special_function. */ 998 "R_LARCH_GOT_HI20", /* name. */ 999 false, /* partial_inplace. */ 1000 0, /* src_mask */ 1001 0x1ffffe0, /* dst_mask */ 1002 false, /* pcrel_offset */ 1003 BFD_RELOC_LARCH_GOT_HI20, /* bfd_reloc_code_real_type */ 1004 reloc_bits, /* adjust_reloc_bits */ 1005 "got_hi20"), /* larch_reloc_type_name */ 1006 1007 LOONGARCH_HOWTO (R_LARCH_GOT_LO12, /* type (80). */ 1008 0, /* rightshift. */ 1009 4, /* size. */ 1010 12, /* bitsize. */ 1011 false, /* pc_relative. */ 1012 10, /* bitpos. */ 1013 complain_overflow_signed, /* complain_on_overflow. */ 1014 bfd_elf_generic_reloc, /* special_function. */ 1015 "R_LARCH_GOT_LO12", /* name. */ 1016 false, /* partial_inplace. */ 1017 0, /* src_mask */ 1018 0x3ffc00, /* dst_mask */ 1019 false, /* pcrel_offset */ 1020 BFD_RELOC_LARCH_GOT_LO12, /* bfd_reloc_code_real_type */ 1021 reloc_bits, /* adjust_reloc_bits */ 1022 "got_lo12"), /* larch_reloc_type_name */ 1023 1024 LOONGARCH_HOWTO (R_LARCH_GOT64_LO20, /* type (81). */ 1025 32, /* rightshift. */ 1026 4, /* size. */ 1027 20, /* bitsize. */ 1028 false, /* pc_relative. */ 1029 5, /* bitpos. */ 1030 complain_overflow_signed, /* complain_on_overflow. */ 1031 bfd_elf_generic_reloc, /* special_function. */ 1032 "R_LARCH_GOT64_LO20", /* name. */ 1033 false, /* partial_inplace. */ 1034 0, /* src_mask */ 1035 0x1ffffe0, /* dst_mask */ 1036 false, /* pcrel_offset */ 1037 BFD_RELOC_LARCH_GOT64_LO20, /* bfd_reloc_code_real_type */ 1038 reloc_bits, /* adjust_reloc_bits */ 1039 "got64_lo20"), /* larch_reloc_type_name */ 1040 1041 LOONGARCH_HOWTO (R_LARCH_GOT64_HI12, /* type (82). */ 1042 52, /* rightshift. */ 1043 4, /* size. */ 1044 12, /* bitsize. */ 1045 false, /* pc_relative. */ 1046 10, /* bitpos. */ 1047 complain_overflow_signed, /* complain_on_overflow. */ 1048 bfd_elf_generic_reloc, /* special_function. */ 1049 "R_LARCH_GOT64_HI12", /* name. */ 1050 false, /* partial_inplace. */ 1051 0, /* src_mask */ 1052 0x3ffc00, /* dst_mask */ 1053 false, /* pcrel_offset */ 1054 BFD_RELOC_LARCH_GOT64_HI12, /* bfd_reloc_code_real_type */ 1055 reloc_bits, /* adjust_reloc_bits */ 1056 "got64_hi12"), /* larch_reloc_type_name */ 1057 1058 LOONGARCH_HOWTO (R_LARCH_TLS_LE_HI20, /* type (83). */ 1059 12, /* rightshift. */ 1060 4, /* size. */ 1061 20, /* bitsize. */ 1062 false, /* pc_relative. */ 1063 5, /* bitpos. */ 1064 complain_overflow_signed, /* complain_on_overflow. */ 1065 bfd_elf_generic_reloc, /* special_function. */ 1066 "R_LARCH_TLS_LE_HI20", /* name. */ 1067 false, /* partial_inplace. */ 1068 0, /* src_mask */ 1069 0x1ffffe0, /* dst_mask */ 1070 false, /* pcrel_offset */ 1071 BFD_RELOC_LARCH_TLS_LE_HI20, /* bfd_reloc_code_real_type */ 1072 reloc_bits, /* adjust_reloc_bits */ 1073 "le_hi20"), /* larch_reloc_type_name */ 1074 1075 LOONGARCH_HOWTO (R_LARCH_TLS_LE_LO12, /* type (84). */ 1076 0, /* rightshift. */ 1077 4, /* size. */ 1078 12, /* bitsize. */ 1079 false, /* pc_relative. */ 1080 10, /* bitpos. */ 1081 complain_overflow_signed, /* complain_on_overflow. */ 1082 bfd_elf_generic_reloc, /* special_function. */ 1083 "R_LARCH_TLS_LE_LO12", /* name. */ 1084 false, /* partial_inplace. */ 1085 0, /* src_mask */ 1086 0x3ffc00, /* dst_mask */ 1087 false, /* pcrel_offset */ 1088 BFD_RELOC_LARCH_TLS_LE_LO12, /* bfd_reloc_code_real_type */ 1089 reloc_bits, /* adjust_reloc_bits */ 1090 "le_lo12"), /* larch_reloc_type_name */ 1091 1092 LOONGARCH_HOWTO (R_LARCH_TLS_LE64_LO20, /* type (85). */ 1093 32, /* rightshift. */ 1094 4, /* size. */ 1095 20, /* bitsize. */ 1096 false, /* pc_relative. */ 1097 5, /* bitpos. */ 1098 complain_overflow_signed, /* complain_on_overflow. */ 1099 bfd_elf_generic_reloc, /* special_function. */ 1100 "R_LARCH_TLS_LE64_LO20", /* name. */ 1101 false, /* partial_inplace. */ 1102 0, /* src_mask */ 1103 0x1ffffe0, /* dst_mask */ 1104 false, /* pcrel_offset */ 1105 BFD_RELOC_LARCH_TLS_LE64_LO20, /* bfd_reloc_code_real_type */ 1106 reloc_bits, /* adjust_reloc_bits */ 1107 "le64_lo20"), /* larch_reloc_type_name */ 1108 1109 LOONGARCH_HOWTO (R_LARCH_TLS_LE64_HI12, /* type (86). */ 1110 52, /* rightshift. */ 1111 4, /* size. */ 1112 12, /* bitsize. */ 1113 false, /* pc_relative. */ 1114 10, /* bitpos. */ 1115 complain_overflow_signed, /* complain_on_overflow. */ 1116 bfd_elf_generic_reloc, /* special_function. */ 1117 "R_LARCH_TLS_LE64_HI12", /* name. */ 1118 false, /* partial_inplace. */ 1119 0, /* src_mask */ 1120 0x3ffc00, /* dst_mask */ 1121 false, /* pcrel_offset */ 1122 BFD_RELOC_LARCH_TLS_LE64_HI12, /* bfd_reloc_code_real_type */ 1123 reloc_bits, /* adjust_reloc_bits */ 1124 "le64_hi12"), /* larch_reloc_type_name */ 1125 1126 LOONGARCH_HOWTO (R_LARCH_TLS_IE_PC_HI20, /* type (87). */ 1127 12, /* rightshift. */ 1128 4, /* size. */ 1129 20, /* bitsize. */ 1130 false, /* pc_relative. */ 1131 5, /* bitpos. */ 1132 complain_overflow_signed, /* complain_on_overflow. */ 1133 bfd_elf_generic_reloc, /* special_function. */ 1134 "R_LARCH_TLS_IE_PC_HI20", /* name. */ 1135 false, /* partial_inplace. */ 1136 0, /* src_mask */ 1137 0x1ffffe0, /* dst_mask */ 1138 false, /* pcrel_offset */ 1139 BFD_RELOC_LARCH_TLS_IE_PC_HI20, /* bfd_reloc_code_real_type */ 1140 reloc_bits, /* adjust_reloc_bits */ 1141 "ie_pc_hi20"), /* larch_reloc_type_name */ 1142 1143 LOONGARCH_HOWTO (R_LARCH_TLS_IE_PC_LO12, /* type (88). */ 1144 0, /* rightshift. */ 1145 4, /* size. */ 1146 12, /* bitsize. */ 1147 false, /* pc_relative. */ 1148 10, /* bitpos. */ 1149 complain_overflow_unsigned, /* complain_on_overflow. */ 1150 bfd_elf_generic_reloc, /* special_function. */ 1151 "R_LARCH_TLS_IE_PC_LO12", /* name. */ 1152 false, /* partial_inplace. */ 1153 0, /* src_mask */ 1154 0x3ffc00, /* dst_mask */ 1155 false, /* pcrel_offset */ 1156 BFD_RELOC_LARCH_TLS_IE_PC_LO12, /* bfd_reloc_code_real_type */ 1157 reloc_bits, /* adjust_reloc_bits */ 1158 "ie_pc_lo12"), /* larch_reloc_type_name */ 1159 1160 LOONGARCH_HOWTO (R_LARCH_TLS_IE64_PC_LO20, /* type (89). */ 1161 32, /* rightshift. */ 1162 4, /* size. */ 1163 20, /* bitsize. */ 1164 false, /* pc_relative. */ 1165 5, /* bitpos. */ 1166 complain_overflow_signed, /* complain_on_overflow. */ 1167 bfd_elf_generic_reloc, /* special_function. */ 1168 "R_LARCH_TLS_IE64_PC_LO20", /* name. */ 1169 false, /* partial_inplace. */ 1170 0, /* src_mask */ 1171 0x1ffffe0, /* dst_mask */ 1172 false, /* pcrel_offset */ 1173 BFD_RELOC_LARCH_TLS_IE64_PC_LO20, /* bfd_reloc_code_real_type */ 1174 reloc_bits, /* adjust_reloc_bits */ 1175 "ie64_pc_lo20"), /* larch_reloc_type_name */ 1176 1177 LOONGARCH_HOWTO (R_LARCH_TLS_IE64_PC_HI12, /* type (90). */ 1178 52, /* rightshift. */ 1179 4, /* size. */ 1180 12, /* bitsize. */ 1181 false, /* pc_relative. */ 1182 10, /* bitpos. */ 1183 complain_overflow_signed, /* complain_on_overflow. */ 1184 bfd_elf_generic_reloc, /* special_function. */ 1185 "R_LARCH_TLS_IE64_PC_HI12", /* name. */ 1186 false, /* partial_inplace. */ 1187 0, /* src_mask */ 1188 0x3ffc00, /* dst_mask */ 1189 false, /* pcrel_offset */ 1190 BFD_RELOC_LARCH_TLS_IE64_PC_HI12, /* bfd_reloc_code_real_type */ 1191 reloc_bits, /* adjust_reloc_bits */ 1192 "ie64_pc_hi12"), /* larch_reloc_type_name */ 1193 1194 LOONGARCH_HOWTO (R_LARCH_TLS_IE_HI20, /* type (91). */ 1195 12, /* rightshift. */ 1196 4, /* size. */ 1197 20, /* bitsize. */ 1198 false, /* pc_relative. */ 1199 5, /* bitpos. */ 1200 complain_overflow_signed, /* complain_on_overflow. */ 1201 bfd_elf_generic_reloc, /* special_function. */ 1202 "R_LARCH_TLS_IE_HI20", /* name. */ 1203 false, /* partial_inplace. */ 1204 0, /* src_mask */ 1205 0x1ffffe0, /* dst_mask */ 1206 false, /* pcrel_offset */ 1207 BFD_RELOC_LARCH_TLS_IE_HI20, /* bfd_reloc_code_real_type */ 1208 reloc_bits, /* adjust_reloc_bits */ 1209 "ie_hi20"), /* larch_reloc_type_name */ 1210 1211 LOONGARCH_HOWTO (R_LARCH_TLS_IE_LO12, /* type (92). */ 1212 0, /* rightshift. */ 1213 4, /* size. */ 1214 12, /* bitsize. */ 1215 false, /* pc_relative. */ 1216 10, /* bitpos. */ 1217 complain_overflow_signed, /* complain_on_overflow. */ 1218 bfd_elf_generic_reloc, /* special_function. */ 1219 "R_LARCH_TLS_IE_LO12", /* name. */ 1220 false, /* partial_inplace. */ 1221 0, /* src_mask */ 1222 0x3ffc00, /* dst_mask */ 1223 false, /* pcrel_offset */ 1224 BFD_RELOC_LARCH_TLS_IE_LO12, /* bfd_reloc_code_real_type */ 1225 reloc_bits, /* adjust_reloc_bits */ 1226 "ie_lo12"), /* larch_reloc_type_name */ 1227 1228 LOONGARCH_HOWTO (R_LARCH_TLS_IE64_LO20, /* type (93). */ 1229 32, /* rightshift. */ 1230 4, /* size. */ 1231 20, /* bitsize. */ 1232 false, /* pc_relative. */ 1233 5, /* bitpos. */ 1234 complain_overflow_signed, /* complain_on_overflow. */ 1235 bfd_elf_generic_reloc, /* special_function. */ 1236 "R_LARCH_TLS_IE64_LO20", /* name. */ 1237 false, /* partial_inplace. */ 1238 0, /* src_mask */ 1239 0x1ffffe0, /* dst_mask */ 1240 false, /* pcrel_offset */ 1241 BFD_RELOC_LARCH_TLS_IE64_LO20, /* bfd_reloc_code_real_type */ 1242 reloc_bits, /* adjust_reloc_bits */ 1243 "ie64_lo20"), /* larch_reloc_type_name */ 1244 1245 LOONGARCH_HOWTO (R_LARCH_TLS_IE64_HI12, /* type (94). */ 1246 52, /* rightshift. */ 1247 4, /* size. */ 1248 12, /* bitsize. */ 1249 false, /* pc_relative. */ 1250 10, /* bitpos. */ 1251 complain_overflow_signed, /* complain_on_overflow. */ 1252 bfd_elf_generic_reloc, /* special_function. */ 1253 "R_LARCH_TLS_IE64_HI12", /* name. */ 1254 false, /* partial_inplace. */ 1255 0, /* src_mask */ 1256 0x3ffc00, /* dst_mask */ 1257 false, /* pcrel_offset */ 1258 BFD_RELOC_LARCH_TLS_IE64_HI12, /* bfd_reloc_code_real_type */ 1259 reloc_bits, /* adjust_reloc_bits */ 1260 "ie64_hi12"), /* larch_reloc_type_name */ 1261 1262 LOONGARCH_HOWTO (R_LARCH_TLS_LD_PC_HI20, /* type (95). */ 1263 12, /* rightshift. */ 1264 4, /* size. */ 1265 20, /* bitsize. */ 1266 false, /* pc_relative. */ 1267 5, /* bitpos. */ 1268 complain_overflow_signed, /* complain_on_overflow. */ 1269 bfd_elf_generic_reloc, /* special_function. */ 1270 "R_LARCH_TLS_LD_PC_HI20", /* name. */ 1271 false, /* partial_inplace. */ 1272 0, /* src_mask */ 1273 0x1ffffe0, /* dst_mask */ 1274 false, /* pcrel_offset */ 1275 BFD_RELOC_LARCH_TLS_LD_PC_HI20, /* bfd_reloc_code_real_type */ 1276 reloc_bits, /* adjust_reloc_bits */ 1277 "ld_pc_hi20"), /* larch_reloc_type_name */ 1278 1279 LOONGARCH_HOWTO (R_LARCH_TLS_LD_HI20, /* type (96). */ 1280 12, /* rightshift. */ 1281 4, /* size. */ 1282 20, /* bitsize. */ 1283 false, /* pc_relative. */ 1284 5, /* bitpos. */ 1285 complain_overflow_signed, /* complain_on_overflow. */ 1286 bfd_elf_generic_reloc, /* special_function. */ 1287 "R_LARCH_TLS_LD_HI20", /* name. */ 1288 false, /* partial_inplace. */ 1289 0, /* src_mask */ 1290 0x1ffffe0, /* dst_mask */ 1291 false, /* pcrel_offset */ 1292 BFD_RELOC_LARCH_TLS_LD_HI20, /* bfd_reloc_code_real_type */ 1293 reloc_bits, /* adjust_reloc_bits */ 1294 "ld_hi20"), /* larch_reloc_type_name */ 1295 1296 LOONGARCH_HOWTO (R_LARCH_TLS_GD_PC_HI20, /* type (97). */ 1297 12, /* rightshift. */ 1298 4, /* size. */ 1299 20, /* bitsize. */ 1300 false, /* pc_relative. */ 1301 5, /* bitpos. */ 1302 complain_overflow_signed, /* complain_on_overflow. */ 1303 bfd_elf_generic_reloc, /* special_function. */ 1304 "R_LARCH_TLS_GD_PC_HI20", /* name. */ 1305 false, /* partial_inplace. */ 1306 0, /* src_mask */ 1307 0x1ffffe0, /* dst_mask */ 1308 false, /* pcrel_offset */ 1309 BFD_RELOC_LARCH_TLS_GD_PC_HI20, /* bfd_reloc_code_real_type */ 1310 reloc_bits, /* adjust_reloc_bits */ 1311 "gd_pc_hi20"), /* larch_reloc_type_name */ 1312 1313 LOONGARCH_HOWTO (R_LARCH_TLS_GD_HI20, /* type (98). */ 1314 12, /* rightshift. */ 1315 4, /* size. */ 1316 20, /* bitsize. */ 1317 false, /* pc_relative. */ 1318 5, /* bitpos. */ 1319 complain_overflow_signed, /* complain_on_overflow. */ 1320 bfd_elf_generic_reloc, /* special_function. */ 1321 "R_LARCH_TLS_GD_HI20", /* name. */ 1322 false, /* partial_inplace. */ 1323 0, /* src_mask */ 1324 0x1ffffe0, /* dst_mask */ 1325 false, /* pcrel_offset */ 1326 BFD_RELOC_LARCH_TLS_GD_HI20, /* bfd_reloc_code_real_type */ 1327 reloc_bits, /* adjust_reloc_bits */ 1328 "gd_hi20"), /* larch_reloc_type_name */ 1329 1330 LOONGARCH_HOWTO (R_LARCH_32_PCREL, /* type (99). */ 1331 0, /* rightshift. */ 1332 4, /* size. */ 1333 32, /* bitsize. */ 1334 true, /* pc_relative. */ 1335 0, /* bitpos. */ 1336 complain_overflow_dont, /* complain_on_overflow. */ 1337 bfd_elf_generic_reloc, /* special_function. */ 1338 "R_LARCH_32_PCREL", /* name. */ 1339 false, /* partial_inplace. */ 1340 0, /* src_mask */ 1341 0xffffffff, /* dst_mask */ 1342 false, /* pcrel_offset */ 1343 BFD_RELOC_LARCH_32_PCREL, /* bfd_reloc_code_real_type */ 1344 NULL, /* adjust_reloc_bits */ 1345 NULL), /* larch_reloc_type_name */ 1346 1347 LOONGARCH_HOWTO (R_LARCH_RELAX, /* type (100). */ 1348 0, /* rightshift */ 1349 1, /* size */ 1350 0, /* bitsize */ 1351 false, /* pc_relative */ 1352 0, /* bitpos */ 1353 complain_overflow_dont, /* complain_on_overflow */ 1354 bfd_elf_generic_reloc, /* special_function */ 1355 "R_LARCH_RELAX", /* name */ 1356 false, /* partial_inplace */ 1357 0, /* src_mask */ 1358 0, /* dst_mask */ 1359 false, /* pcrel_offset */ 1360 BFD_RELOC_LARCH_RELAX, /* bfd_reloc_code_real_type */ 1361 NULL, /* adjust_reloc_bits */ 1362 NULL), /* larch_reloc_type_name */ 1363 1364 }; 1365 1366 reloc_howto_type * 1367 loongarch_elf_rtype_to_howto (bfd *abfd, unsigned int r_type) 1368 { 1369 if(r_type < R_LARCH_count) 1370 { 1371 /* For search table fast. */ 1372 BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count); 1373 1374 if (loongarch_howto_table[r_type].howto.type == r_type) 1375 return (reloc_howto_type *)&loongarch_howto_table[r_type]; 1376 1377 for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++) 1378 if (loongarch_howto_table[i].howto.type == r_type) 1379 return (reloc_howto_type *)&loongarch_howto_table[i]; 1380 } 1381 1382 (*_bfd_error_handler) (_("%pB: unsupported relocation type %#x"), 1383 abfd, r_type); 1384 bfd_set_error (bfd_error_bad_value); 1385 return NULL; 1386 } 1387 1388 reloc_howto_type * 1389 loongarch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name) 1390 { 1391 BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count); 1392 1393 for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++) 1394 if (loongarch_howto_table[i].howto.name 1395 && strcasecmp (loongarch_howto_table[i].howto.name, r_name) == 0) 1396 return (reloc_howto_type *)&loongarch_howto_table[i]; 1397 1398 (*_bfd_error_handler) (_("%pB: unsupported relocation type %s"), 1399 abfd, r_name); 1400 bfd_set_error (bfd_error_bad_value); 1401 1402 return NULL; 1403 } 1404 1405 /* Cost so much. */ 1406 reloc_howto_type * 1407 loongarch_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 1408 bfd_reloc_code_real_type code) 1409 { 1410 BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count); 1411 1412 /* Fast search for new reloc types. */ 1413 if (BFD_RELOC_LARCH_B16 <= code && code < BFD_RELOC_LARCH_RELAX) 1414 { 1415 BFD_ASSERT (BFD_RELOC_LARCH_RELAX - BFD_RELOC_LARCH_B16 1416 == R_LARCH_RELAX - R_LARCH_B16); 1417 loongarch_reloc_howto_type *ht = NULL; 1418 ht = &loongarch_howto_table[code - BFD_RELOC_LARCH_B16 + R_LARCH_B16]; 1419 BFD_ASSERT (ht->bfd_type == code); 1420 return (reloc_howto_type *)ht; 1421 } 1422 1423 for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++) 1424 if (loongarch_howto_table[i].bfd_type == code) 1425 return (reloc_howto_type *)&loongarch_howto_table[i]; 1426 1427 (*_bfd_error_handler) (_("%pB: unsupported bfd relocation type %#x"), 1428 abfd, code); 1429 bfd_set_error (bfd_error_bad_value); 1430 1431 return NULL; 1432 } 1433 1434 bfd_reloc_code_real_type 1435 loongarch_larch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, 1436 const char *l_r_name) 1437 { 1438 for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++) 1439 { 1440 loongarch_reloc_howto_type *lht = &loongarch_howto_table[i]; 1441 if ((NULL != lht->larch_reloc_type_name) 1442 && (0 == strcmp (lht->larch_reloc_type_name, l_r_name))) 1443 return lht->bfd_type; 1444 } 1445 1446 (*_bfd_error_handler) (_("%pB: unsupported relocation type name %s"), 1447 abfd, l_r_name); 1448 bfd_set_error (bfd_error_bad_value); 1449 return BFD_RELOC_NONE; 1450 } 1451 1452 1453 /* Functions for reloc bits field. 1454 1. Signed extend *fix_val. 1455 2. Return false if overflow. */ 1456 1457 #define LARCH_RELOC_BFD_VMA_BIT_MASK(bitsize) \ 1458 (~((((bfd_vma)0x1) << (bitsize)) - 1)) 1459 1460 /* Adjust val to perform insn 1461 BFD_RELOC_LARCH_SOP_POP_32_S_10_5 1462 BFD_RELOC_LARCH_SOP_POP_32_S_10_12 1463 BFD_RELOC_LARCH_SOP_POP_32_U_10_12 1464 BFD_RELOC_LARCH_SOP_POP_32_S_10_16 1465 BFD_RELOC_LARCH_SOP_POP_32_S_5_20 1466 BFD_RELOC_LARCH_SOP_POP_32_U. */ 1467 static bool 1468 reloc_bits (reloc_howto_type *howto, bfd_vma *fix_val) 1469 { 1470 bfd_signed_vma val = ((bfd_signed_vma)(*fix_val)) >> howto->rightshift; 1471 1472 /* Perform insn bits field. */ 1473 val = val & (((bfd_vma)0x1 << howto->bitsize) - 1); 1474 val <<= howto->bitpos; 1475 1476 *fix_val = (bfd_vma)val; 1477 1478 return true; 1479 } 1480 1481 /* Adjust val to perform insn 1482 R_LARCH_SOP_POP_32_S_10_16_S2 1483 R_LARCH_B16. */ 1484 static bool 1485 reloc_bits_b16 (reloc_howto_type *howto, bfd_vma *fix_val) 1486 { 1487 if (howto->complain_on_overflow != complain_overflow_signed) 1488 return false; 1489 1490 bfd_signed_vma val = *fix_val; 1491 1492 /* Judge whether 4 bytes align. */ 1493 if (val & ((0x1UL << howto->rightshift) - 1)) 1494 return false; 1495 1496 int bitsize = howto->bitsize + howto->rightshift; 1497 bfd_signed_vma sig_bit = (val >> (bitsize - 1)) & 0x1; 1498 1499 /* If val < 0, sign bit is 1. */ 1500 if (sig_bit) 1501 { 1502 /* Signed bits is 1. */ 1503 if ((LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val) 1504 != LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1)) 1505 return false; 1506 } 1507 else 1508 { 1509 /* Signed bits is 0. */ 1510 if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize) & val) 1511 return false; 1512 } 1513 1514 /* Perform insn bits field. */ 1515 val >>= howto->rightshift; 1516 val = val & (((bfd_vma)0x1 << howto->bitsize) - 1); 1517 val <<= howto->bitpos; 1518 1519 *fix_val = val; 1520 1521 return true; 1522 } 1523 1524 /* Reloc type : 1525 R_LARCH_SOP_POP_32_S_0_5_10_16_S2 1526 R_LARCH_B21. */ 1527 static bool 1528 reloc_bits_b21 (reloc_howto_type *howto, 1529 bfd_vma *fix_val) 1530 { 1531 if (howto->complain_on_overflow != complain_overflow_signed) 1532 return false; 1533 1534 bfd_signed_vma val = *fix_val; 1535 1536 if (val & ((0x1UL << howto->rightshift) - 1)) 1537 return false; 1538 1539 int bitsize = howto->bitsize + howto->rightshift; 1540 bfd_signed_vma sig_bit = (val >> (bitsize - 1)) & 0x1; 1541 1542 /* If val < 0. */ 1543 if (sig_bit) 1544 { 1545 if ((LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val) 1546 != LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1)) 1547 return false; 1548 } 1549 else 1550 { 1551 if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize) & val) 1552 return false; 1553 } 1554 1555 /* Perform insn bits field. */ 1556 val >>= howto->rightshift; 1557 val = val & (((bfd_vma)0x1 << howto->bitsize) - 1); 1558 1559 /* Perform insn bits field. 15:0<<10, 20:16>>16. */ 1560 val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f); 1561 1562 *fix_val = val; 1563 1564 return true; 1565 } 1566 1567 /* Reloc type: 1568 R_LARCH_SOP_POP_32_S_0_10_10_16_S2 1569 R_LARCH_B26. */ 1570 static bool 1571 reloc_bits_b26 (reloc_howto_type *howto, 1572 bfd_vma *fix_val) 1573 { 1574 /* Return false if overflow. */ 1575 if (howto->complain_on_overflow != complain_overflow_signed) 1576 return false; 1577 1578 bfd_signed_vma val = *fix_val; 1579 1580 if (val & ((0x1UL << howto->rightshift) - 1)) 1581 return false; 1582 1583 int bitsize = howto->bitsize + howto->rightshift; 1584 bfd_signed_vma sig_bit = (val >> (bitsize - 1)) & 0x1; 1585 1586 /* If val < 0. */ 1587 if (sig_bit) 1588 { 1589 if ((LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val) 1590 != LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1)) 1591 return false; 1592 } 1593 else 1594 { 1595 if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize) & val) 1596 return false; 1597 } 1598 1599 /* Perform insn bits field. */ 1600 val >>= howto->rightshift; 1601 val = val & (((bfd_vma)0x1 << howto->bitsize) - 1); 1602 1603 /* Perform insn bits field. 25:16>>16, 15:0<<10. */ 1604 val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff); 1605 1606 *fix_val = val; 1607 1608 return true; 1609 } 1610 1611 bool 1612 loongarch_adjust_reloc_bitsfield (reloc_howto_type *howto, 1613 bfd_vma *fix_val) 1614 { 1615 BFD_ASSERT (((loongarch_reloc_howto_type *)howto)->adjust_reloc_bits); 1616 return ((loongarch_reloc_howto_type *) 1617 howto)->adjust_reloc_bits(howto, fix_val); 1618 } 1619