1 /* LoongArch-specific support for ELF.
2 Copyright (C) 2021-2022 Free Software Foundation, Inc.
3 Contributed by Loongson Ltd.
5 Based on RISC-V target.
7 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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/>. */
27 #include "elf/loongarch.h"
28 #include "elfxx-loongarch.h"
30 #define ALL_ONES (~ (bfd_vma) 0)
32 typedef struct loongarch_reloc_howto_type_struct
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
;
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 }
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 }
51 #define LOONGARCH_EMPTY_HOWTO(C) \
52 { EMPTY_HOWTO (C), BFD_RELOC_NONE, NULL, NULL }
55 reloc_bits (reloc_howto_type
*howto
, bfd_vma
*val
);
57 reloc_bits_b16 (reloc_howto_type
*howto
, bfd_vma
*fix_val
);
59 reloc_bits_b21 (reloc_howto_type
*howto
, bfd_vma
*fix_val
);
61 reloc_bits_b26 (reloc_howto_type
*howto
, bfd_vma
*val
);
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
[] =
68 LOONGARCH_HOWTO (R_LARCH_NONE
, /* type (0). */
72 false, /* pc_relative */
74 complain_overflow_dont
, /* complain_on_overflow */
75 bfd_elf_generic_reloc
, /* special_function */
76 "R_LARCH_NONE", /* name */
77 false, /* partial_inplace */
80 false, /* pcrel_offset */
81 BFD_RELOC_NONE
, /* bfd_reloc_code_real_type */
82 NULL
, /* adjust_reloc_bits */
83 NULL
), /* larch_reloc_type_name */
85 /* 32 bit relocation. */
86 LOONGARCH_HOWTO (R_LARCH_32
, /* type (1). */
90 false, /* pc_relative */
92 complain_overflow_dont
, /* complain_on_overflow */
93 bfd_elf_generic_reloc
, /* special_function */
94 "R_LARCH_32", /* name */
95 false, /* partial_inplace */
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 */
103 /* 64 bit relocation. */
104 LOONGARCH_HOWTO (R_LARCH_64
, /* type (2). */
108 false, /* pc_relative */
110 complain_overflow_dont
, /* complain_on_overflow */
111 bfd_elf_generic_reloc
, /* special_function */
112 "R_LARCH_64", /* name */
113 false, /* partial_inplace */
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 */
121 LOONGARCH_HOWTO (R_LARCH_RELATIVE
, /* type (3). */
125 false, /* pc_relative */
127 complain_overflow_dont
, /* complain_on_overflow */
128 bfd_elf_generic_reloc
, /* special_function */
129 "R_LARCH_RELATIVE", /* name */
130 false, /* partial_inplace */
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 */
138 LOONGARCH_HOWTO (R_LARCH_COPY
, /* type (4). */
140 0, /* this one is variable size */
142 false, /* pc_relative */
144 complain_overflow_bitfield
, /* complain_on_overflow */
145 bfd_elf_generic_reloc
, /* special_function */
146 "R_LARCH_COPY", /* name */
147 false, /* partial_inplace */
150 false, /* pcrel_offset */
151 BFD_RELOC_NONE
, /* undefined? */
152 NULL
, /* adjust_reloc_bits */
153 NULL
), /* larch_reloc_type_name */
155 LOONGARCH_HOWTO (R_LARCH_JUMP_SLOT
, /* type (5). */
159 false, /* pc_relative */
161 complain_overflow_bitfield
, /* complain_on_overflow */
162 bfd_elf_generic_reloc
, /* special_function */
163 "R_LARCH_JUMP_SLOT", /* name */
164 false, /* partial_inplace */
167 false, /* pcrel_offset */
168 BFD_RELOC_NONE
, /* undefined? */
169 NULL
, /* adjust_reloc_bits */
170 NULL
), /* larch_reloc_type_name */
172 /* Dynamic TLS relocations. */
173 LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD32
, /* type (6). */
177 false, /* pc_relative */
179 complain_overflow_dont
, /* complain_on_overflow */
180 bfd_elf_generic_reloc
, /* special_function */
181 "R_LARCH_TLS_DTPMOD32", /* name */
182 false, /* partial_inplace */
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 */
190 LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD64
, /* type (7). */
194 false, /* pc_relative */
196 complain_overflow_dont
, /* complain_on_overflow */
197 bfd_elf_generic_reloc
, /* special_function */
198 "R_LARCH_TLS_DTPMOD64", /* name */
199 false, /* partial_inplace */
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 */
207 LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL32
, /* type (8). */
211 false, /* pc_relative */
213 complain_overflow_dont
, /* complain_on_overflow */
214 bfd_elf_generic_reloc
, /* special_function */
215 "R_LARCH_TLS_DTPREL32", /* name */
216 true, /* partial_inplace */
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 */
224 LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL64
, /* type (9). */
228 false, /* pc_relative */
230 complain_overflow_dont
, /* complain_on_overflow */
231 bfd_elf_generic_reloc
, /* special_function */
232 "R_LARCH_TLS_DTPREL64", /* name */
233 true, /* partial_inplace */
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 */
241 LOONGARCH_HOWTO (R_LARCH_TLS_TPREL32
, /* type (10). */
245 false, /* pc_relative */
247 complain_overflow_dont
, /* complain_on_overflow */
248 bfd_elf_generic_reloc
, /* special_function */
249 "R_LARCH_TLS_TPREL32", /* name */
250 false, /* partial_inplace */
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 */
258 LOONGARCH_HOWTO (R_LARCH_TLS_TPREL64
, /* type (11). */
262 false, /* pc_relative */
264 complain_overflow_dont
, /* complain_on_overflow */
265 bfd_elf_generic_reloc
, /* special_function */
266 "R_LARCH_TLS_TPREL64", /* name */
267 false, /* partial_inplace */
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 */
275 LOONGARCH_HOWTO (R_LARCH_IRELATIVE
, /* type (12). */
279 false, /* pc_relative */
281 complain_overflow_dont
, /* complain_on_overflow */
282 bfd_elf_generic_reloc
, /* special_function */
283 "R_LARCH_IRELATIVE", /* name */
284 false, /* partial_inplace */
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 */
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),
300 LOONGARCH_HOWTO (R_LARCH_MARK_LA
, /* type (20). */
304 false, /* pc_relative. */
306 complain_overflow_signed
, /* complain_on_overflow. */
307 bfd_elf_generic_reloc
, /* special_function. */
308 "R_LARCH_MARK_LA", /* name. */
309 false, /* partial_inplace. */
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 */
317 LOONGARCH_HOWTO (R_LARCH_MARK_PCREL
, /* type (21). */
321 false, /* pc_relative. */
323 complain_overflow_signed
, /* complain_on_overflow. */
324 bfd_elf_generic_reloc
, /* special_function. */
325 "R_LARCH_MARK_PCREL", /* name. */
326 false, /* partial_inplace. */
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 */
334 LOONGARCH_HOWTO (R_LARCH_SOP_PUSH_PCREL
, /* type (22). */
338 true /* FIXME: somewhat use this. */, /* pc_relative. */
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 */
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
),
368 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_5
, /* type (38). */
372 false, /* pc_relative. */
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. */
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 */
385 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U_10_12
, /* type (39). */
389 false, /* pc_relative. */
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. */
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 */
402 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_12
, /* type (40). */
406 false, /* pc_relative. */
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. */
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 */
419 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16
, /* type (41). */
423 false, /* pc_relative. */
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. */
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 */
436 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16_S2
, /* type (42). */
440 false, /* pc_relative. */
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. */
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 */
453 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_5_20
, /* type (43). */
457 false, /* pc_relative. */
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. */
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 */
470 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_5_10_16_S2
,
475 false, /* pc_relative. */
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 */
489 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_10_10_16_S2
, /* type (45). */
493 false, /* pc_relative. */
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. */
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 */
507 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U
, /* type (46). */
511 false, /* pc_relative. */
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 */
524 LOONGARCH_HOWTO (R_LARCH_ADD8
, /* type (47). */
528 false, /* pc_relative. */
530 complain_overflow_signed
, /* complain_on_overflow. */
531 bfd_elf_generic_reloc
, /* special_function. */
532 "R_LARCH_ADD8", /* name. */
533 false, /* partial_inplace. */
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 */
541 LOONGARCH_HOWTO (R_LARCH_ADD16
, /* type (48). */
545 false, /* pc_relative. */
547 complain_overflow_signed
, /* complain_on_overflow. */
548 bfd_elf_generic_reloc
, /* special_function. */
549 "R_LARCH_ADD16", /* name. */
550 false, /* partial_inplace. */
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 */
558 LOONGARCH_HOWTO (R_LARCH_ADD24
, /* type (49). */
562 false, /* pc_relative. */
564 complain_overflow_signed
, /* complain_on_overflow. */
565 bfd_elf_generic_reloc
, /* special_function. */
566 "R_LARCH_ADD24", /* name. */
567 false, /* partial_inplace. */
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 */
575 LOONGARCH_HOWTO (R_LARCH_ADD32
, /* type (50). */
579 false, /* pc_relative. */
581 complain_overflow_signed
, /* complain_on_overflow. */
582 bfd_elf_generic_reloc
, /* special_function. */
583 "R_LARCH_ADD32", /* name. */
584 false, /* partial_inplace. */
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 */
592 LOONGARCH_HOWTO (R_LARCH_ADD64
, /* type (51). */
596 false, /* pc_relative. */
598 complain_overflow_signed
, /* complain_on_overflow. */
599 bfd_elf_generic_reloc
, /* special_function. */
600 "R_LARCH_ADD64", /* name. */
601 false, /* partial_inplace. */
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 */
609 LOONGARCH_HOWTO (R_LARCH_SUB8
, /* type (52). */
613 false, /* pc_relative. */
615 complain_overflow_signed
, /* complain_on_overflow. */
616 bfd_elf_generic_reloc
, /* special_function. */
617 "R_LARCH_SUB8", /* name. */
618 false, /* partial_inplace. */
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 */
626 LOONGARCH_HOWTO (R_LARCH_SUB16
, /* type (53). */
630 false, /* pc_relative. */
632 complain_overflow_signed
, /* complain_on_overflow. */
633 bfd_elf_generic_reloc
, /* special_function. */
634 "R_LARCH_SUB16", /* name. */
635 false, /* partial_inplace. */
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 */
643 LOONGARCH_HOWTO (R_LARCH_SUB24
, /* type (54). */
647 false, /* pc_relative. */
649 complain_overflow_signed
, /* complain_on_overflow. */
650 bfd_elf_generic_reloc
, /* special_function. */
651 "R_LARCH_SUB24", /* name. */
652 false, /* partial_inplace. */
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 */
660 LOONGARCH_HOWTO (R_LARCH_SUB32
, /* type (55). */
664 false, /* pc_relative. */
666 complain_overflow_signed
, /* complain_on_overflow. */
667 bfd_elf_generic_reloc
, /* special_function. */
668 "R_LARCH_SUB32", /* name. */
669 false, /* partial_inplace. */
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 */
677 LOONGARCH_HOWTO (R_LARCH_SUB64
, /* type (56). */
681 false, /* pc_relative. */
683 complain_overflow_signed
, /* complain_on_overflow. */
684 bfd_elf_generic_reloc
, /* special_function. */
685 "R_LARCH_SUB64", /* name. */
686 false, /* partial_inplace. */
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 */
694 LOONGARCH_HOWTO (R_LARCH_GNU_VTINHERIT
, /* type (57). */
698 false, /* pc_relative. */
700 complain_overflow_signed
, /* complain_on_overflow. */
701 bfd_elf_generic_reloc
, /* special_function. */
702 "R_LARCH_GNU_VTINHERIT", /* name. */
703 false, /* partial_inplace. */
706 false, /* pcrel_offset */
707 BFD_RELOC_NONE
, /* bfd_reloc_code_real_type */
708 NULL
, /* adjust_reloc_bits */
709 NULL
), /* larch_reloc_type_name */
711 LOONGARCH_HOWTO (R_LARCH_GNU_VTENTRY
, /* type (58). */
715 false, /* pc_relative. */
717 complain_overflow_signed
, /* complain_on_overflow. */
718 NULL
, /* special_function. */
719 "R_LARCH_GNU_VTENTRY", /* name. */
720 false, /* partial_inplace. */
723 false, /* pcrel_offset */
724 BFD_RELOC_NONE
, /* bfd_reloc_code_real_type */
725 NULL
, /* adjust_reloc_bits */
726 NULL
), /* larch_reloc_type_name */
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),
734 /* New reloc types. */
735 LOONGARCH_HOWTO (R_LARCH_B16
, /* type (64). */
739 false, /* pc_relative. */
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 */
752 LOONGARCH_HOWTO (R_LARCH_B21
, /* type (65). */
756 false, /* pc_relative. */
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 */
769 LOONGARCH_HOWTO (R_LARCH_B26
, /* type (66). */
773 false, /* pc_relative. */
775 complain_overflow_signed
, /* complain_on_overflow. */
776 bfd_elf_generic_reloc
, /* special_function. */
777 "R_LARCH_B26", /* name. */
778 false, /* partial_inplace. */
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 */
786 LOONGARCH_HOWTO (R_LARCH_ABS_HI20
, /* type (67). */
787 12, /* rightshift. */
790 false, /* pc_relative. */
792 complain_overflow_signed
, /* complain_on_overflow. */
793 bfd_elf_generic_reloc
, /* special_function. */
794 "R_LARCH_ABS_HI20", /* name. */
795 false, /* partial_inplace. */
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 */
803 LOONGARCH_HOWTO (R_LARCH_ABS_LO12
, /* type (68). */
807 false, /* pc_relative. */
809 complain_overflow_unsigned
, /* complain_on_overflow. */
810 bfd_elf_generic_reloc
, /* special_function. */
811 "R_LARCH_ABS_LO12", /* name. */
812 false, /* partial_inplace. */
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 */
820 LOONGARCH_HOWTO (R_LARCH_ABS64_LO20
, /* type (69). */
821 32, /* rightshift. */
824 false, /* pc_relative. */
826 complain_overflow_signed
, /* complain_on_overflow. */
827 bfd_elf_generic_reloc
, /* special_function. */
828 "R_LARCH_ABS64_LO20", /* name. */
829 false, /* partial_inplace. */
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 */
837 LOONGARCH_HOWTO (R_LARCH_ABS64_HI12
, /* type (70). */
838 52, /* rightshift. */
841 false, /* pc_relative. */
843 complain_overflow_signed
, /* complain_on_overflow. */
844 bfd_elf_generic_reloc
, /* special_function. */
845 "R_LARCH_ABS64_HI12", /* name. */
846 false, /* partial_inplace. */
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 */
854 LOONGARCH_HOWTO (R_LARCH_PCALA_HI20
, /* type (71). */
855 12, /* rightshift. */
858 false, /* pc_relative. */
860 complain_overflow_signed
, /* complain_on_overflow. */
861 bfd_elf_generic_reloc
, /* special_function. */
862 "R_LARCH_PCALA_HI20", /* name. */
863 false, /* partial_inplace. */
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 */
871 LOONGARCH_HOWTO (R_LARCH_PCALA_LO12
, /* type (72). */
875 false, /* pc_relative. */
877 complain_overflow_signed
, /* complain_on_overflow. */
878 bfd_elf_generic_reloc
, /* special_function. */
879 "R_LARCH_PCALA_LO12", /* name. */
880 false, /* partial_inplace. */
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 */
888 LOONGARCH_HOWTO (R_LARCH_PCALA64_LO20
, /* type (73). */
889 32, /* rightshift. */
892 false, /* pc_relative. */
894 complain_overflow_signed
, /* complain_on_overflow. */
895 bfd_elf_generic_reloc
, /* special_function. */
896 "R_LARCH_PCALA64_LO20", /* name. */
897 false, /* partial_inplace. */
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 */
905 LOONGARCH_HOWTO (R_LARCH_PCALA64_HI12
, /* type (74). */
906 52, /* rightshift. */
909 false, /* pc_relative. */
911 complain_overflow_signed
, /* complain_on_overflow. */
912 bfd_elf_generic_reloc
, /* special_function. */
913 "R_LARCH_PCALA64_HI12", /* name. */
914 false, /* partial_inplace. */
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 */
922 LOONGARCH_HOWTO (R_LARCH_GOT_PC_HI20
, /* type (75). */
923 12, /* rightshift. */
926 false, /* pc_relative. */
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. */
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 */
939 LOONGARCH_HOWTO (R_LARCH_GOT_PC_LO12
, /* type (76). */
943 false, /* pc_relative. */
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. */
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 */
956 LOONGARCH_HOWTO (R_LARCH_GOT64_PC_LO20
, /* type (77). */
957 32, /* rightshift. */
960 false, /* pc_relative. */
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. */
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 */
973 LOONGARCH_HOWTO (R_LARCH_GOT64_PC_HI12
, /* type (78). */
974 52, /* rightshift. */
977 false, /* pc_relative. */
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. */
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 */
990 LOONGARCH_HOWTO (R_LARCH_GOT_HI20
, /* type (79). */
991 12, /* rightshift. */
994 false, /* pc_relative. */
996 complain_overflow_signed
, /* complain_on_overflow. */
997 bfd_elf_generic_reloc
, /* special_function. */
998 "R_LARCH_GOT_HI20", /* name. */
999 false, /* partial_inplace. */
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 */
1007 LOONGARCH_HOWTO (R_LARCH_GOT_LO12
, /* type (80). */
1008 0, /* rightshift. */
1011 false, /* pc_relative. */
1013 complain_overflow_signed
, /* complain_on_overflow. */
1014 bfd_elf_generic_reloc
, /* special_function. */
1015 "R_LARCH_GOT_LO12", /* name. */
1016 false, /* partial_inplace. */
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 */
1024 LOONGARCH_HOWTO (R_LARCH_GOT64_LO20
, /* type (81). */
1025 32, /* rightshift. */
1028 false, /* pc_relative. */
1030 complain_overflow_signed
, /* complain_on_overflow. */
1031 bfd_elf_generic_reloc
, /* special_function. */
1032 "R_LARCH_GOT64_LO20", /* name. */
1033 false, /* partial_inplace. */
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 */
1041 LOONGARCH_HOWTO (R_LARCH_GOT64_HI12
, /* type (82). */
1042 52, /* rightshift. */
1045 false, /* pc_relative. */
1047 complain_overflow_signed
, /* complain_on_overflow. */
1048 bfd_elf_generic_reloc
, /* special_function. */
1049 "R_LARCH_GOT64_HI12", /* name. */
1050 false, /* partial_inplace. */
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 */
1058 LOONGARCH_HOWTO (R_LARCH_TLS_LE_HI20
, /* type (83). */
1059 12, /* rightshift. */
1062 false, /* pc_relative. */
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. */
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 */
1075 LOONGARCH_HOWTO (R_LARCH_TLS_LE_LO12
, /* type (84). */
1076 0, /* rightshift. */
1079 false, /* pc_relative. */
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. */
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 */
1092 LOONGARCH_HOWTO (R_LARCH_TLS_LE64_LO20
, /* type (85). */
1093 32, /* rightshift. */
1096 false, /* pc_relative. */
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. */
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 */
1109 LOONGARCH_HOWTO (R_LARCH_TLS_LE64_HI12
, /* type (86). */
1110 52, /* rightshift. */
1113 false, /* pc_relative. */
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. */
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 */
1126 LOONGARCH_HOWTO (R_LARCH_TLS_IE_PC_HI20
, /* type (87). */
1127 12, /* rightshift. */
1130 false, /* pc_relative. */
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. */
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 */
1143 LOONGARCH_HOWTO (R_LARCH_TLS_IE_PC_LO12
, /* type (88). */
1144 0, /* rightshift. */
1147 false, /* pc_relative. */
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. */
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 */
1160 LOONGARCH_HOWTO (R_LARCH_TLS_IE64_PC_LO20
, /* type (89). */
1161 32, /* rightshift. */
1164 false, /* pc_relative. */
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. */
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 */
1177 LOONGARCH_HOWTO (R_LARCH_TLS_IE64_PC_HI12
, /* type (90). */
1178 52, /* rightshift. */
1181 false, /* pc_relative. */
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. */
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 */
1194 LOONGARCH_HOWTO (R_LARCH_TLS_IE_HI20
, /* type (91). */
1195 12, /* rightshift. */
1198 false, /* pc_relative. */
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. */
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 */
1211 LOONGARCH_HOWTO (R_LARCH_TLS_IE_LO12
, /* type (92). */
1212 0, /* rightshift. */
1215 false, /* pc_relative. */
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. */
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 */
1228 LOONGARCH_HOWTO (R_LARCH_TLS_IE64_LO20
, /* type (93). */
1229 32, /* rightshift. */
1232 false, /* pc_relative. */
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. */
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 */
1245 LOONGARCH_HOWTO (R_LARCH_TLS_IE64_HI12
, /* type (94). */
1246 52, /* rightshift. */
1249 false, /* pc_relative. */
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. */
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 */
1262 LOONGARCH_HOWTO (R_LARCH_TLS_LD_PC_HI20
, /* type (95). */
1263 12, /* rightshift. */
1266 false, /* pc_relative. */
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. */
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 */
1279 LOONGARCH_HOWTO (R_LARCH_TLS_LD_HI20
, /* type (96). */
1280 12, /* rightshift. */
1283 false, /* pc_relative. */
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. */
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 */
1296 LOONGARCH_HOWTO (R_LARCH_TLS_GD_PC_HI20
, /* type (97). */
1297 12, /* rightshift. */
1300 false, /* pc_relative. */
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. */
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 */
1313 LOONGARCH_HOWTO (R_LARCH_TLS_GD_HI20
, /* type (98). */
1314 12, /* rightshift. */
1317 false, /* pc_relative. */
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. */
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 */
1330 LOONGARCH_HOWTO (R_LARCH_32_PCREL
, /* type (99). */
1331 0, /* rightshift. */
1334 true, /* pc_relative. */
1336 complain_overflow_dont
, /* complain_on_overflow. */
1337 bfd_elf_generic_reloc
, /* special_function. */
1338 "R_LARCH_32_PCREL", /* name. */
1339 false, /* partial_inplace. */
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 */
1347 LOONGARCH_HOWTO (R_LARCH_RELAX
, /* type (100). */
1351 false, /* pc_relative */
1353 complain_overflow_dont
, /* complain_on_overflow */
1354 bfd_elf_generic_reloc
, /* special_function */
1355 "R_LARCH_RELAX", /* name */
1356 false, /* partial_inplace */
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 */
1367 loongarch_elf_rtype_to_howto (bfd
*abfd
, unsigned int r_type
)
1369 if(r_type
< R_LARCH_count
)
1371 /* For search table fast. */
1372 BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table
) == R_LARCH_count
);
1374 if (loongarch_howto_table
[r_type
].howto
.type
== r_type
)
1375 return (reloc_howto_type
*)&loongarch_howto_table
[r_type
];
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
];
1382 (*_bfd_error_handler
) (_("%pB: unsupported relocation type %#x"),
1384 bfd_set_error (bfd_error_bad_value
);
1389 loongarch_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
, const char *r_name
)
1391 BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table
) == R_LARCH_count
);
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
];
1398 (*_bfd_error_handler
) (_("%pB: unsupported relocation type %s"),
1400 bfd_set_error (bfd_error_bad_value
);
1407 loongarch_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
1408 bfd_reloc_code_real_type code
)
1410 BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table
) == R_LARCH_count
);
1412 /* Fast search for new reloc types. */
1413 if (BFD_RELOC_LARCH_B16
<= code
&& code
< BFD_RELOC_LARCH_RELAX
)
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
;
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
];
1427 (*_bfd_error_handler
) (_("%pB: unsupported bfd relocation type %#x"),
1429 bfd_set_error (bfd_error_bad_value
);
1434 bfd_reloc_code_real_type
1435 loongarch_larch_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
1436 const char *l_r_name
)
1438 for (size_t i
= 0; i
< ARRAY_SIZE (loongarch_howto_table
); i
++)
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
;
1446 (*_bfd_error_handler
) (_("%pB: unsupported relocation type name %s"),
1448 bfd_set_error (bfd_error_bad_value
);
1449 return BFD_RELOC_NONE
;
1453 /* Functions for reloc bits field.
1454 1. Signed extend *fix_val.
1455 2. Return false if overflow. */
1457 #define LARCH_RELOC_BFD_VMA_BIT_MASK(bitsize) \
1458 (~((((bfd_vma)0x1) << (bitsize)) - 1))
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. */
1468 reloc_bits (reloc_howto_type
*howto
, bfd_vma
*fix_val
)
1470 bfd_signed_vma val
= ((bfd_signed_vma
)(*fix_val
)) >> howto
->rightshift
;
1472 /* Perform insn bits field. */
1473 val
= val
& (((bfd_vma
)0x1 << howto
->bitsize
) - 1);
1474 val
<<= howto
->bitpos
;
1476 *fix_val
= (bfd_vma
)val
;
1481 /* Adjust val to perform insn
1482 R_LARCH_SOP_POP_32_S_10_16_S2
1485 reloc_bits_b16 (reloc_howto_type
*howto
, bfd_vma
*fix_val
)
1487 if (howto
->complain_on_overflow
!= complain_overflow_signed
)
1490 bfd_signed_vma val
= *fix_val
;
1492 /* Judge whether 4 bytes align. */
1493 if (val
& ((0x1UL
<< howto
->rightshift
) - 1))
1496 int bitsize
= howto
->bitsize
+ howto
->rightshift
;
1497 bfd_signed_vma sig_bit
= (val
>> (bitsize
- 1)) & 0x1;
1499 /* If val < 0, sign bit is 1. */
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))
1509 /* Signed bits is 0. */
1510 if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize
) & val
)
1514 /* Perform insn bits field. */
1515 val
>>= howto
->rightshift
;
1516 val
= val
& (((bfd_vma
)0x1 << howto
->bitsize
) - 1);
1517 val
<<= howto
->bitpos
;
1525 R_LARCH_SOP_POP_32_S_0_5_10_16_S2
1528 reloc_bits_b21 (reloc_howto_type
*howto
,
1531 if (howto
->complain_on_overflow
!= complain_overflow_signed
)
1534 bfd_signed_vma val
= *fix_val
;
1536 if (val
& ((0x1UL
<< howto
->rightshift
) - 1))
1539 int bitsize
= howto
->bitsize
+ howto
->rightshift
;
1540 bfd_signed_vma sig_bit
= (val
>> (bitsize
- 1)) & 0x1;
1545 if ((LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize
- 1) & val
)
1546 != LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize
- 1))
1551 if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize
) & val
)
1555 /* Perform insn bits field. */
1556 val
>>= howto
->rightshift
;
1557 val
= val
& (((bfd_vma
)0x1 << howto
->bitsize
) - 1);
1559 /* Perform insn bits field. 15:0<<10, 20:16>>16. */
1560 val
= ((val
& 0xffff) << 10) | ((val
>> 16) & 0x1f);
1568 R_LARCH_SOP_POP_32_S_0_10_10_16_S2
1571 reloc_bits_b26 (reloc_howto_type
*howto
,
1574 /* Return false if overflow. */
1575 if (howto
->complain_on_overflow
!= complain_overflow_signed
)
1578 bfd_signed_vma val
= *fix_val
;
1580 if (val
& ((0x1UL
<< howto
->rightshift
) - 1))
1583 int bitsize
= howto
->bitsize
+ howto
->rightshift
;
1584 bfd_signed_vma sig_bit
= (val
>> (bitsize
- 1)) & 0x1;
1589 if ((LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize
- 1) & val
)
1590 != LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize
- 1))
1595 if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize
) & val
)
1599 /* Perform insn bits field. */
1600 val
>>= howto
->rightshift
;
1601 val
= val
& (((bfd_vma
)0x1 << howto
->bitsize
) - 1);
1603 /* Perform insn bits field. 25:16>>16, 15:0<<10. */
1604 val
= ((val
& 0xffff) << 10) | ((val
>> 16) & 0x3ff);
1612 loongarch_adjust_reloc_bitsfield (reloc_howto_type
*howto
,
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
);