Automatic date update in version.in
[binutils-gdb.git] / bfd / elfxx-loongarch.c
blobe1d3b65bb6961402105832aad49a10955d6555e5
1 /* LoongArch-specific support for ELF.
2 Copyright (C) 2021-2024 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/>. */
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"
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)(bfd *, 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 }
54 static bool
55 reloc_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *val);
56 static bool
57 reloc_sign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val);
58 static bool
59 reloc_unsign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val);
61 static bfd_reloc_status_type
62 loongarch_elf_add_sub_reloc (bfd *, arelent *, asymbol *, void *,
63 asection *, bfd *, char **);
65 static bfd_reloc_status_type
66 loongarch_elf_add_sub_reloc_uleb128 (bfd *, arelent *, asymbol *, void *,
67 asection *, bfd *, char **);
69 /* This does not include any relocation information, but should be
70 good enough for GDB or objdump to read the file. */
71 static loongarch_reloc_howto_type loongarch_howto_table[] =
73 /* No relocation. */
74 LOONGARCH_HOWTO (R_LARCH_NONE, /* type (0). */
75 0, /* rightshift */
76 0, /* size */
77 0, /* bitsize */
78 false, /* pc_relative */
79 0, /* bitpos */
80 complain_overflow_dont, /* complain_on_overflow */
81 bfd_elf_generic_reloc, /* special_function */
82 "R_LARCH_NONE", /* name */
83 false, /* partial_inplace */
84 0, /* src_mask */
85 0, /* dst_mask */
86 false, /* pcrel_offset */
87 BFD_RELOC_NONE, /* bfd_reloc_code_real_type */
88 NULL, /* adjust_reloc_bits */
89 NULL), /* larch_reloc_type_name */
91 /* 32 bit relocation. */
92 LOONGARCH_HOWTO (R_LARCH_32, /* type (1). */
93 0, /* rightshift */
94 4, /* size */
95 32, /* bitsize */
96 false, /* pc_relative */
97 0, /* bitpos */
98 complain_overflow_dont, /* complain_on_overflow */
99 bfd_elf_generic_reloc, /* special_function */
100 "R_LARCH_32", /* name */
101 false, /* partial_inplace */
102 0, /* src_mask */
103 ALL_ONES, /* dst_mask */
104 false, /* pcrel_offset */
105 BFD_RELOC_32, /* bfd_reloc_code_real_type */
106 NULL, /* adjust_reloc_bits */
107 NULL), /* larch_reloc_type_name */
109 /* 64 bit relocation. */
110 LOONGARCH_HOWTO (R_LARCH_64, /* type (2). */
111 0, /* rightshift */
112 8, /* size */
113 64, /* bitsize */
114 false, /* pc_relative */
115 0, /* bitpos */
116 complain_overflow_dont, /* complain_on_overflow */
117 bfd_elf_generic_reloc, /* special_function */
118 "R_LARCH_64", /* name */
119 false, /* partial_inplace */
120 0, /* src_mask */
121 ALL_ONES, /* dst_mask */
122 false, /* pcrel_offset */
123 BFD_RELOC_64, /* bfd_reloc_code_real_type */
124 NULL, /* adjust_reloc_bits */
125 NULL), /* larch_reloc_type_name */
127 LOONGARCH_HOWTO (R_LARCH_RELATIVE, /* type (3). */
128 0, /* rightshift */
129 4, /* size */
130 32, /* bitsize */
131 false, /* pc_relative */
132 0, /* bitpos */
133 complain_overflow_dont, /* complain_on_overflow */
134 bfd_elf_generic_reloc, /* special_function */
135 "R_LARCH_RELATIVE", /* name */
136 false, /* partial_inplace */
137 0, /* src_mask */
138 ALL_ONES, /* dst_mask */
139 false, /* pcrel_offset */
140 BFD_RELOC_NONE, /* undefined? */
141 NULL, /* adjust_reloc_bits */
142 NULL), /* larch_reloc_type_name */
144 LOONGARCH_HOWTO (R_LARCH_COPY, /* type (4). */
145 0, /* rightshift */
146 0, /* this one is variable size */
147 0, /* bitsize */
148 false, /* pc_relative */
149 0, /* bitpos */
150 complain_overflow_bitfield, /* complain_on_overflow */
151 bfd_elf_generic_reloc, /* special_function */
152 "R_LARCH_COPY", /* name */
153 false, /* partial_inplace */
154 0, /* src_mask */
155 0, /* dst_mask */
156 false, /* pcrel_offset */
157 BFD_RELOC_NONE, /* undefined? */
158 NULL, /* adjust_reloc_bits */
159 NULL), /* larch_reloc_type_name */
161 LOONGARCH_HOWTO (R_LARCH_JUMP_SLOT, /* type (5). */
162 0, /* rightshift */
163 8, /* size */
164 64, /* bitsize */
165 false, /* pc_relative */
166 0, /* bitpos */
167 complain_overflow_bitfield, /* complain_on_overflow */
168 bfd_elf_generic_reloc, /* special_function */
169 "R_LARCH_JUMP_SLOT", /* name */
170 false, /* partial_inplace */
171 0, /* src_mask */
172 0, /* dst_mask */
173 false, /* pcrel_offset */
174 BFD_RELOC_NONE, /* undefined? */
175 NULL, /* adjust_reloc_bits */
176 NULL), /* larch_reloc_type_name */
178 /* Dynamic TLS relocations. */
179 LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD32, /* type (6). */
180 0, /* rightshift */
181 4, /* size */
182 32, /* bitsize */
183 false, /* pc_relative */
184 0, /* bitpos */
185 complain_overflow_dont, /* complain_on_overflow */
186 bfd_elf_generic_reloc, /* special_function */
187 "R_LARCH_TLS_DTPMOD32", /* name */
188 false, /* partial_inplace */
189 0, /* src_mask */
190 ALL_ONES, /* dst_mask */
191 false, /* pcrel_offset */
192 BFD_RELOC_LARCH_TLS_DTPMOD32, /* bfd_reloc_code_real_type */
193 NULL, /* adjust_reloc_bits */
194 NULL), /* larch_reloc_type_name */
196 LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD64, /* type (7). */
197 0, /* rightshift */
198 8, /* size */
199 64, /* bitsize */
200 false, /* pc_relative */
201 0, /* bitpos */
202 complain_overflow_dont, /* complain_on_overflow */
203 bfd_elf_generic_reloc, /* special_function */
204 "R_LARCH_TLS_DTPMOD64", /* name */
205 false, /* partial_inplace */
206 0, /* src_mask */
207 ALL_ONES, /* dst_mask */
208 false, /* pcrel_offset */
209 BFD_RELOC_LARCH_TLS_DTPMOD64, /* bfd_reloc_code_real_type */
210 NULL, /* adjust_reloc_bits */
211 NULL), /* larch_reloc_type_name */
213 LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL32, /* type (8). */
214 0, /* rightshift */
215 4, /* size */
216 32, /* bitsize */
217 false, /* pc_relative */
218 0, /* bitpos */
219 complain_overflow_dont, /* complain_on_overflow */
220 bfd_elf_generic_reloc, /* special_function */
221 "R_LARCH_TLS_DTPREL32", /* name */
222 true, /* partial_inplace */
223 0, /* src_mask */
224 ALL_ONES, /* dst_mask */
225 false, /* pcrel_offset */
226 BFD_RELOC_LARCH_TLS_DTPREL32, /* bfd_reloc_code_real_type */
227 NULL, /* adjust_reloc_bits */
228 NULL), /* larch_reloc_type_name */
230 LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL64, /* type (9). */
231 0, /* rightshift */
232 8, /* size */
233 64, /* bitsize */
234 false, /* pc_relative */
235 0, /* bitpos */
236 complain_overflow_dont, /* complain_on_overflow */
237 bfd_elf_generic_reloc, /* special_function */
238 "R_LARCH_TLS_DTPREL64", /* name */
239 true, /* partial_inplace */
240 0, /* src_mask */
241 ALL_ONES, /* dst_mask */
242 false, /* pcrel_offset */
243 BFD_RELOC_LARCH_TLS_DTPREL64, /* bfd_reloc_code_real_type */
244 NULL, /* adjust_reloc_bits */
245 NULL), /* larch_reloc_type_name */
247 LOONGARCH_HOWTO (R_LARCH_TLS_TPREL32, /* type (10). */
248 0, /* rightshift */
249 4, /* size */
250 32, /* bitsize */
251 false, /* pc_relative */
252 0, /* bitpos */
253 complain_overflow_dont, /* complain_on_overflow */
254 bfd_elf_generic_reloc, /* special_function */
255 "R_LARCH_TLS_TPREL32", /* name */
256 false, /* partial_inplace */
257 0, /* src_mask */
258 ALL_ONES, /* dst_mask */
259 false, /* pcrel_offset */
260 BFD_RELOC_LARCH_TLS_TPREL32, /* bfd_reloc_code_real_type */
261 NULL, /* adjust_reloc_bits */
262 NULL), /* larch_reloc_type_name */
264 LOONGARCH_HOWTO (R_LARCH_TLS_TPREL64, /* type (11). */
265 0, /* rightshift */
266 8, /* size */
267 64, /* bitsize */
268 false, /* pc_relative */
269 0, /* bitpos */
270 complain_overflow_dont, /* complain_on_overflow */
271 bfd_elf_generic_reloc, /* special_function */
272 "R_LARCH_TLS_TPREL64", /* name */
273 false, /* partial_inplace */
274 0, /* src_mask */
275 ALL_ONES, /* dst_mask */
276 false, /* pcrel_offset */
277 BFD_RELOC_LARCH_TLS_TPREL64, /* bfd_reloc_code_real_type */
278 NULL, /* adjust_reloc_bits */
279 NULL), /* larch_reloc_type_name */
281 LOONGARCH_HOWTO (R_LARCH_IRELATIVE, /* type (12). */
282 0, /* rightshift */
283 8, /* size */
284 64, /* bitsize */
285 false, /* pc_relative */
286 0, /* bitpos */
287 complain_overflow_dont, /* complain_on_overflow */
288 bfd_elf_generic_reloc, /* special_function */
289 "R_LARCH_IRELATIVE", /* name */
290 false, /* partial_inplace */
291 0, /* src_mask */
292 ALL_ONES, /* dst_mask */
293 false, /* pcrel_offset */
294 BFD_RELOC_NONE, /* undefined? */
295 NULL, /* adjust_reloc_bits */
296 NULL), /* larch_reloc_type_name */
298 LOONGARCH_HOWTO (R_LARCH_TLS_DESC32, /* type (13). */
299 0, /* rightshift. */
300 4, /* size. */
301 32, /* bitsize. */
302 false, /* pc_relative. */
303 0, /* bitpos. */
304 complain_overflow_dont, /* complain_on_overflow. */
305 bfd_elf_generic_reloc, /* special_function. */
306 "R_LARCH_TLS_DESC32", /* name. */
307 false, /* partial_inplace. */
308 0, /* src_mask. */
309 ALL_ONES, /* dst_mask. */
310 false, /* pcrel_offset. */
311 BFD_RELOC_LARCH_TLS_DESC32, /* bfd_reloc_code_real_type. */
312 NULL, /* adjust_reloc_bits. */
313 NULL), /* larch_reloc_type_name. */
315 LOONGARCH_HOWTO (R_LARCH_TLS_DESC64, /* type (14). */
316 0, /* rightshift. */
317 8, /* size. */
318 64, /* bitsize. */
319 false, /* pc_relative. */
320 0, /* bitpos. */
321 complain_overflow_dont, /* complain_on_overflow. */
322 bfd_elf_generic_reloc, /* special_function. */
323 "R_LARCH_TLS_DESC64", /* name. */
324 false, /* partial_inplace. */
325 0, /* src_mask. */
326 ALL_ONES, /* dst_mask. */
327 false, /* pcrel_offset. */
328 BFD_RELOC_LARCH_TLS_DESC64, /* bfd_reloc_code_real_type. */
329 NULL, /* adjust_reloc_bits. */
330 NULL), /* larch_reloc_type_name. */
332 LOONGARCH_EMPTY_HOWTO (15),
333 LOONGARCH_EMPTY_HOWTO (16),
334 LOONGARCH_EMPTY_HOWTO (17),
335 LOONGARCH_EMPTY_HOWTO (18),
336 LOONGARCH_EMPTY_HOWTO (19),
338 LOONGARCH_HOWTO (R_LARCH_MARK_LA, /* type (20). */
339 0, /* rightshift. */
340 0, /* size. */
341 0, /* bitsize. */
342 false, /* pc_relative. */
343 0, /* bitpos. */
344 complain_overflow_signed, /* complain_on_overflow. */
345 bfd_elf_generic_reloc, /* special_function. */
346 "R_LARCH_MARK_LA", /* name. */
347 false, /* partial_inplace. */
348 0, /* src_mask. */
349 0, /* dst_mask. */
350 false, /* pcrel_offset */
351 BFD_RELOC_LARCH_MARK_LA, /* bfd_reloc_code_real_type */
352 NULL, /* adjust_reloc_bits */
353 NULL), /* larch_reloc_type_name */
355 LOONGARCH_HOWTO (R_LARCH_MARK_PCREL, /* type (21). */
356 0, /* rightshift. */
357 0, /* size. */
358 0, /* bitsize. */
359 false, /* pc_relative. */
360 0, /* bitpos. */
361 complain_overflow_signed, /* complain_on_overflow. */
362 bfd_elf_generic_reloc, /* special_function. */
363 "R_LARCH_MARK_PCREL", /* name. */
364 false, /* partial_inplace. */
365 0, /* src_mask. */
366 0, /* dst_mask. */
367 false, /* pcrel_offset */
368 BFD_RELOC_LARCH_MARK_PCREL, /* bfd_reloc_code_real_type */
369 NULL, /* adjust_reloc_bits */
370 NULL), /* larch_reloc_type_name */
372 LOONGARCH_HOWTO (R_LARCH_SOP_PUSH_PCREL, /* type (22). */
373 2, /* rightshift. */
374 4, /* size. */
375 32, /* bitsize. */
376 true /* FIXME: somewhat use this. */, /* pc_relative. */
377 0, /* bitpos. */
378 complain_overflow_signed, /* complain_on_overflow. */
379 bfd_elf_generic_reloc, /* special_function. */
380 "R_LARCH_SOP_PUSH_PCREL", /* name. */
381 false, /* partial_inplace. */
382 0x03ffffff, /* src_mask. */
383 0x03ffffff, /* dst_mask. */
384 false, /* pcrel_offset */
385 BFD_RELOC_LARCH_SOP_PUSH_PCREL, /* bfd_reloc_code_real_type */
386 NULL, /* adjust_reloc_bits */
387 NULL), /* larch_reloc_type_name */
389 /* type 23-37. */
390 LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_ABSOLUTE),
391 LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_DUP),
392 LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_GPREL),
393 LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_TLS_TPREL),
394 LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_TLS_GOT),
395 LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_TLS_GD),
396 LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_PLT_PCREL),
397 LOONGARCH_DEFAULT_HOWTO (SOP_ASSERT),
398 LOONGARCH_DEFAULT_HOWTO (SOP_NOT),
399 LOONGARCH_DEFAULT_HOWTO (SOP_SUB),
400 LOONGARCH_DEFAULT_HOWTO (SOP_SL),
401 LOONGARCH_DEFAULT_HOWTO (SOP_SR),
402 LOONGARCH_DEFAULT_HOWTO (SOP_ADD),
403 LOONGARCH_DEFAULT_HOWTO (SOP_AND),
404 LOONGARCH_DEFAULT_HOWTO (SOP_IF_ELSE),
406 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_5, /* type (38). */
407 0, /* rightshift. */
408 4, /* size. */
409 5, /* bitsize. */
410 false, /* pc_relative. */
411 10, /* bitpos. */
412 complain_overflow_signed, /* complain_on_overflow. */
413 bfd_elf_generic_reloc, /* special_function. */
414 "R_LARCH_SOP_POP_32_S_10_5", /* name. */
415 false, /* partial_inplace. */
416 0, /* src_mask */
417 0x7c00, /* dst_mask */
418 false, /* pcrel_offset */
419 BFD_RELOC_LARCH_SOP_POP_32_S_10_5, /* bfd_reloc_code_real_type */
420 reloc_sign_bits, /* adjust_reloc_bits */
421 NULL), /* larch_reloc_type_name */
423 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U_10_12, /* type (39). */
424 0, /* rightshift. */
425 4, /* size. */
426 12, /* bitsize. */
427 false, /* pc_relative. */
428 10, /* bitpos. */
429 complain_overflow_unsigned, /* complain_on_overflow. */
430 bfd_elf_generic_reloc, /* special_function. */
431 "R_LARCH_SOP_POP_32_U_10_12", /* name. */
432 false, /* partial_inplace. */
433 0, /* src_mask */
434 0x3ffc00, /* dst_mask */
435 false, /* pcrel_offset */
436 BFD_RELOC_LARCH_SOP_POP_32_U_10_12, /* bfd_reloc_code_real_type */
437 reloc_unsign_bits, /* adjust_reloc_bits */
438 NULL), /* larch_reloc_type_name */
440 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_12, /* type (40). */
441 0, /* rightshift. */
442 4, /* size. */
443 12, /* bitsize. */
444 false, /* pc_relative. */
445 10, /* bitpos. */
446 complain_overflow_signed, /* complain_on_overflow. */
447 bfd_elf_generic_reloc, /* special_function. */
448 "R_LARCH_SOP_POP_32_S_10_12", /* name. */
449 false, /* partial_inplace. */
450 0, /* src_mask */
451 0x3ffc00, /* dst_mask */
452 false, /* pcrel_offset */
453 BFD_RELOC_LARCH_SOP_POP_32_S_10_12, /* bfd_reloc_code_real_type */
454 reloc_sign_bits, /* adjust_reloc_bits */
455 NULL), /* larch_reloc_type_name */
457 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16, /* type (41). */
458 0, /* rightshift. */
459 4, /* size. */
460 16, /* bitsize. */
461 false, /* pc_relative. */
462 10, /* bitpos. */
463 complain_overflow_signed, /* complain_on_overflow. */
464 bfd_elf_generic_reloc, /* special_function. */
465 "R_LARCH_SOP_POP_32_S_10_16", /* name. */
466 false, /* partial_inplace. */
467 0, /* src_mask */
468 0x3fffc00, /* dst_mask */
469 false, /* pcrel_offset */
470 BFD_RELOC_LARCH_SOP_POP_32_S_10_16, /* bfd_reloc_code_real_type */
471 reloc_sign_bits, /* adjust_reloc_bits */
472 NULL), /* larch_reloc_type_name */
474 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16_S2, /* type (42). */
475 2, /* rightshift. */
476 4, /* size. */
477 16, /* bitsize. */
478 false, /* pc_relative. */
479 10, /* bitpos. */
480 complain_overflow_signed, /* complain_on_overflow. */
481 bfd_elf_generic_reloc, /* special_function. */
482 "R_LARCH_SOP_POP_32_S_10_16_S2", /* name. */
483 false, /* partial_inplace. */
484 0, /* src_mask */
485 0x3fffc00, /* dst_mask */
486 false, /* pcrel_offset */
487 BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2, /* bfd_reloc_code_real_type */
488 reloc_sign_bits, /* adjust_reloc_bits */
489 NULL), /* larch_reloc_type_name */
491 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_5_20, /* type (43). */
492 0, /* rightshift. */
493 4, /* size. */
494 20, /* bitsize. */
495 false, /* pc_relative. */
496 5, /* bitpos. */
497 complain_overflow_signed, /* complain_on_overflow. */
498 bfd_elf_generic_reloc, /* special_function. */
499 "R_LARCH_SOP_POP_32_S_5_20", /* name. */
500 false, /* partial_inplace. */
501 0, /* src_mask */
502 0x1ffffe0, /* dst_mask */
503 false, /* pcrel_offset */
504 BFD_RELOC_LARCH_SOP_POP_32_S_5_20, /* bfd_reloc_code_real_type */
505 reloc_sign_bits, /* adjust_reloc_bits */
506 NULL), /* larch_reloc_type_name */
508 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_5_10_16_S2,
509 /* type (44). */
510 2, /* rightshift. */
511 4, /* size. */
512 21, /* bitsize. */
513 false, /* pc_relative. */
514 0, /* bitpos. */
515 complain_overflow_signed, /* complain_on_overflow. */
516 bfd_elf_generic_reloc, /* special_function. */
517 "R_LARCH_SOP_POP_32_S_0_5_10_16_S2", /* name. */
518 false, /* partial_inplace. */
519 0x0, /* src_mask */
520 0x03fffc1f, /* dst_mask */
521 false, /* pcrel_offset */
522 BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2,
523 /* bfd_reloc_code_real_type */
524 reloc_sign_bits, /* adjust_reloc_bits */
525 NULL), /* larch_reloc_type_name */
527 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_10_10_16_S2, /* type (45). */
528 2, /* rightshift. */
529 4, /* size. */
530 26, /* bitsize. */
531 false, /* pc_relative. */
532 0, /* bitpos. */
533 complain_overflow_signed, /* complain_on_overflow. */
534 bfd_elf_generic_reloc, /* special_function. */
535 "R_LARCH_SOP_POP_32_S_0_10_10_16_S2", /* name. */
536 false, /* partial_inplace. */
537 0, /* src_mask */
538 0x03ffffff, /* dst_mask */
539 false, /* pcrel_offset */
540 BFD_RELOC_LARCH_SOP_POP_32_S_0_10_10_16_S2,
541 /* bfd_reloc_code_real_type */
542 reloc_sign_bits, /* adjust_reloc_bits */
543 NULL), /* larch_reloc_type_name */
545 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U, /* type (46). */
546 0, /* rightshift. */
547 4, /* size. */
548 32, /* bitsize. */
549 false, /* pc_relative. */
550 0, /* bitpos. */
551 complain_overflow_unsigned, /* complain_on_overflow. */
552 bfd_elf_generic_reloc, /* special_function. */
553 "R_LARCH_SOP_POP_32_U", /* name. */
554 false, /* partial_inplace. */
555 0xffffffff00000000, /* src_mask */
556 0x00000000ffffffff, /* dst_mask */
557 false, /* pcrel_offset */
558 BFD_RELOC_LARCH_SOP_POP_32_U, /* bfd_reloc_code_real_type */
559 reloc_unsign_bits, /* adjust_reloc_bits */
560 NULL), /* larch_reloc_type_name */
562 /* 8-bit in-place addition, for local label subtraction. */
563 LOONGARCH_HOWTO (R_LARCH_ADD8, /* type (47). */
564 0, /* rightshift. */
565 1, /* size. */
566 8, /* bitsize. */
567 false, /* pc_relative. */
568 0, /* bitpos. */
569 complain_overflow_dont, /* complain_on_overflow. */
570 loongarch_elf_add_sub_reloc, /* special_function. */
571 "R_LARCH_ADD8", /* name. */
572 false, /* partial_inplace. */
573 0, /* src_mask. */
574 0xff, /* dst_mask. */
575 false, /* pcrel_offset. */
576 BFD_RELOC_LARCH_ADD8, /* bfd_reloc_code_real_type. */
577 NULL, /* adjust_reloc_bits. */
578 NULL), /* larch_reloc_type_name. */
580 /* 16-bit in-place addition, for local label subtraction. */
581 LOONGARCH_HOWTO (R_LARCH_ADD16, /* type (48). */
582 0, /* rightshift. */
583 2, /* size. */
584 16, /* bitsize. */
585 false, /* pc_relative. */
586 0, /* bitpos. */
587 complain_overflow_dont, /* complain_on_overflow. */
588 loongarch_elf_add_sub_reloc, /* special_function. */
589 "R_LARCH_ADD16", /* name. */
590 false, /* partial_inplace. */
591 0, /* src_mask. */
592 0xffff, /* dst_mask. */
593 false, /* pcrel_offset. */
594 BFD_RELOC_LARCH_ADD16, /* bfd_reloc_code_real_type. */
595 NULL, /* adjust_reloc_bits. */
596 NULL), /* larch_reloc_type_name. */
598 /* 24-bit in-place addition, for local label subtraction. */
599 LOONGARCH_HOWTO (R_LARCH_ADD24, /* type (49). */
600 0, /* rightshift. */
601 3, /* size. */
602 24, /* bitsize. */
603 false, /* pc_relative. */
604 0, /* bitpos. */
605 complain_overflow_dont, /* complain_on_overflow. */
606 loongarch_elf_add_sub_reloc, /* special_function. */
607 "R_LARCH_ADD24", /* name. */
608 false, /* partial_inplace. */
609 0, /* src_mask. */
610 0xffffff, /* dst_mask. */
611 false, /* pcrel_offset. */
612 BFD_RELOC_LARCH_ADD24, /* bfd_reloc_code_real_type. */
613 NULL, /* adjust_reloc_bits. */
614 NULL), /* larch_reloc_type_name. */
616 /* 32-bit in-place addition, for local label subtraction. */
617 LOONGARCH_HOWTO (R_LARCH_ADD32, /* type (50). */
618 0, /* rightshift. */
619 4, /* size. */
620 32, /* bitsize. */
621 false, /* pc_relative. */
622 0, /* bitpos. */
623 complain_overflow_dont, /* complain_on_overflow. */
624 loongarch_elf_add_sub_reloc, /* special_function. */
625 "R_LARCH_ADD32", /* name. */
626 false, /* partial_inplace. */
627 0, /* src_mask. */
628 0xffffffff, /* dst_mask. */
629 false, /* pcrel_offset. */
630 BFD_RELOC_LARCH_ADD32, /* bfd_reloc_code_real_type. */
631 NULL, /* adjust_reloc_bits. */
632 NULL), /* larch_reloc_type_name. */
634 /* 64-bit in-place addition, for local label subtraction. */
635 LOONGARCH_HOWTO (R_LARCH_ADD64, /* type (51). */
636 0, /* rightshift. */
637 8, /* size. */
638 64, /* bitsize. */
639 false, /* pc_relative. */
640 0, /* bitpos. */
641 complain_overflow_dont, /* complain_on_overflow. */
642 loongarch_elf_add_sub_reloc, /* special_function. */
643 "R_LARCH_ADD64", /* name. */
644 false, /* partial_inplace. */
645 0, /* src_mask. */
646 ALL_ONES, /* dst_mask. */
647 false, /* pcrel_offset. */
648 BFD_RELOC_LARCH_ADD64, /* bfd_reloc_code_real_type. */
649 NULL, /* adjust_reloc_bits. */
650 NULL), /* larch_reloc_type_name. */
652 /* 8-bit in-place subtraction, for local label subtraction. */
653 LOONGARCH_HOWTO (R_LARCH_SUB8, /* type (52). */
654 0, /* rightshift. */
655 1, /* size. */
656 8, /* bitsize. */
657 false, /* pc_relative. */
658 0, /* bitpos. */
659 complain_overflow_dont, /* complain_on_overflow. */
660 loongarch_elf_add_sub_reloc, /* special_function. */
661 "R_LARCH_SUB8", /* name. */
662 false, /* partial_inplace. */
663 0, /* src_mask. */
664 0xff, /* dst_mask. */
665 false, /* pcrel_offset. */
666 BFD_RELOC_LARCH_SUB8, /* bfd_reloc_code_real_type. */
667 NULL, /* adjust_reloc_bits. */
668 NULL), /* larch_reloc_type_name. */
670 /* 16-bit in-place subtraction, for local label subtraction. */
671 LOONGARCH_HOWTO (R_LARCH_SUB16, /* type (53). */
672 0, /* rightshift. */
673 2, /* size. */
674 16, /* bitsize. */
675 false, /* pc_relative. */
676 0, /* bitpos. */
677 complain_overflow_dont, /* complain_on_overflow. */
678 loongarch_elf_add_sub_reloc, /* special_function. */
679 "R_LARCH_SUB16", /* name. */
680 false, /* partial_inplace. */
681 0, /* src_mask. */
682 0xffff, /* dst_mask. */
683 false, /* pcrel_offset. */
684 BFD_RELOC_LARCH_SUB16, /* bfd_reloc_code_real_type. */
685 NULL, /* adjust_reloc_bits. */
686 NULL), /* larch_reloc_type_name. */
688 /* 24-bit in-place subtraction, for local label subtraction. */
689 LOONGARCH_HOWTO (R_LARCH_SUB24, /* type (54). */
690 0, /* rightshift. */
691 3, /* size. */
692 24, /* bitsize. */
693 false, /* pc_relative. */
694 0, /* bitpos. */
695 complain_overflow_dont, /* complain_on_overflow. */
696 loongarch_elf_add_sub_reloc, /* special_function. */
697 "R_LARCH_SUB24", /* name. */
698 false, /* partial_inplace. */
699 0, /* src_mask. */
700 0xffffff, /* dst_mask. */
701 false, /* pcrel_offset. */
702 BFD_RELOC_LARCH_SUB24, /* bfd_reloc_code_real_type. */
703 NULL, /* adjust_reloc_bits. */
704 NULL), /* larch_reloc_type_name. */
706 /* 32-bit in-place subtraction, for local label subtraction. */
707 LOONGARCH_HOWTO (R_LARCH_SUB32, /* type (55). */
708 0, /* rightshift. */
709 4, /* size. */
710 32, /* bitsize. */
711 false, /* pc_relative. */
712 0, /* bitpos. */
713 complain_overflow_dont, /* complain_on_overflow. */
714 loongarch_elf_add_sub_reloc, /* special_function. */
715 "R_LARCH_SUB32", /* name. */
716 false, /* partial_inplace. */
717 0, /* src_mask. */
718 0xffffffff, /* dst_mask. */
719 false, /* pcrel_offset. */
720 BFD_RELOC_LARCH_SUB32, /* bfd_reloc_code_real_type. */
721 NULL, /* adjust_reloc_bits. */
722 NULL), /* larch_reloc_type_name. */
724 /* 64-bit in-place subtraction, for local label subtraction. */
725 LOONGARCH_HOWTO (R_LARCH_SUB64, /* type (56). */
726 0, /* rightshift. */
727 8, /* size. */
728 64, /* bitsize. */
729 false, /* pc_relative. */
730 0, /* bitpos. */
731 complain_overflow_dont, /* complain_on_overflow. */
732 loongarch_elf_add_sub_reloc, /* special_function. */
733 "R_LARCH_SUB64", /* name. */
734 false, /* partial_inplace. */
735 0, /* src_mask. */
736 ALL_ONES, /* dst_mask. */
737 false, /* pcrel_offset. */
738 BFD_RELOC_LARCH_SUB64, /* bfd_reloc_code_real_type. */
739 NULL, /* adjust_reloc_bits. */
740 NULL), /* larch_reloc_type_name. */
742 LOONGARCH_HOWTO (R_LARCH_GNU_VTINHERIT, /* type (57). */
743 0, /* rightshift. */
744 0, /* size. */
745 0, /* bitsize. */
746 false, /* pc_relative. */
747 0, /* bitpos. */
748 complain_overflow_signed, /* complain_on_overflow. */
749 bfd_elf_generic_reloc, /* special_function. */
750 "R_LARCH_GNU_VTINHERIT", /* name. */
751 false, /* partial_inplace. */
752 0, /* src_mask */
753 0, /* dst_mask */
754 false, /* pcrel_offset */
755 BFD_RELOC_NONE, /* bfd_reloc_code_real_type */
756 NULL, /* adjust_reloc_bits */
757 NULL), /* larch_reloc_type_name */
759 LOONGARCH_HOWTO (R_LARCH_GNU_VTENTRY, /* type (58). */
760 0, /* rightshift. */
761 0, /* size. */
762 0, /* bitsize. */
763 false, /* pc_relative. */
764 0, /* bitpos. */
765 complain_overflow_signed, /* complain_on_overflow. */
766 NULL, /* special_function. */
767 "R_LARCH_GNU_VTENTRY", /* name. */
768 false, /* partial_inplace. */
769 0, /* src_mask */
770 0, /* dst_mask */
771 false, /* pcrel_offset */
772 BFD_RELOC_NONE, /* bfd_reloc_code_real_type */
773 NULL, /* adjust_reloc_bits */
774 NULL), /* larch_reloc_type_name */
776 LOONGARCH_EMPTY_HOWTO (59),
777 LOONGARCH_EMPTY_HOWTO (60),
778 LOONGARCH_EMPTY_HOWTO (61),
779 LOONGARCH_EMPTY_HOWTO (62),
780 LOONGARCH_EMPTY_HOWTO (63),
782 /* New reloc types. */
783 LOONGARCH_HOWTO (R_LARCH_B16, /* type (64). */
784 2, /* rightshift. */
785 4, /* size. */
786 16, /* bitsize. */
787 false, /* pc_relative. */
788 10, /* bitpos. */
789 complain_overflow_signed, /* complain_on_overflow. */
790 bfd_elf_generic_reloc, /* special_function. */
791 "R_LARCH_B16", /* name. */
792 false, /* partial_inplace. */
793 0, /* src_mask. */
794 0x3fffc00, /* dst_mask. */
795 false, /* pcrel_offset. */
796 BFD_RELOC_LARCH_B16, /* bfd_reloc_code_real_type. */
797 reloc_sign_bits, /* adjust_reloc_bits. */
798 "b16"), /* larch_reloc_type_name. */
800 LOONGARCH_HOWTO (R_LARCH_B21, /* type (65). */
801 2, /* rightshift. */
802 4, /* size. */
803 21, /* bitsize. */
804 false, /* pc_relative. */
805 0, /* bitpos. */
806 complain_overflow_signed, /* complain_on_overflow. */
807 bfd_elf_generic_reloc, /* special_function. */
808 "R_LARCH_B21", /* name. */
809 false, /* partial_inplace. */
810 0, /* src_mask. */
811 0x3fffc1f, /* dst_mask. */
812 false, /* pcrel_offset. */
813 BFD_RELOC_LARCH_B21, /* bfd_reloc_code_real_type. */
814 reloc_sign_bits, /* adjust_reloc_bits. */
815 "b21"), /* larch_reloc_type_name. */
817 LOONGARCH_HOWTO (R_LARCH_B26, /* type (66). */
818 2, /* rightshift. */
819 4, /* size. */
820 26, /* bitsize. */
821 false, /* pc_relative. */
822 0, /* bitpos. */
823 complain_overflow_signed, /* complain_on_overflow. */
824 bfd_elf_generic_reloc, /* special_function. */
825 "R_LARCH_B26", /* name. */
826 false, /* partial_inplace. */
827 0, /* src_mask. */
828 0x03ffffff, /* dst_mask. */
829 false, /* pcrel_offset. */
830 BFD_RELOC_LARCH_B26, /* bfd_reloc_code_real_type. */
831 reloc_sign_bits, /* adjust_reloc_bits. */
832 "b26"), /* larch_reloc_type_name. */
834 LOONGARCH_HOWTO (R_LARCH_ABS_HI20, /* type (67). */
835 12, /* rightshift. */
836 4, /* size. */
837 20, /* bitsize. */
838 false, /* pc_relative. */
839 5, /* bitpos. */
840 complain_overflow_signed, /* complain_on_overflow. */
841 bfd_elf_generic_reloc, /* special_function. */
842 "R_LARCH_ABS_HI20", /* name. */
843 false, /* partial_inplace. */
844 0, /* src_mask */
845 0x1ffffe0, /* dst_mask */
846 false, /* pcrel_offset */
847 BFD_RELOC_LARCH_ABS_HI20, /* bfd_reloc_code_real_type */
848 reloc_bits, /* adjust_reloc_bits */
849 "abs_hi20"), /* larch_reloc_type_name */
851 LOONGARCH_HOWTO (R_LARCH_ABS_LO12, /* type (68). */
852 0, /* rightshift. */
853 4, /* size. */
854 12, /* bitsize. */
855 false, /* pc_relative. */
856 10, /* bitpos. */
857 complain_overflow_unsigned, /* complain_on_overflow. */
858 bfd_elf_generic_reloc, /* special_function. */
859 "R_LARCH_ABS_LO12", /* name. */
860 false, /* partial_inplace. */
861 0, /* src_mask */
862 0x3ffc00, /* dst_mask */
863 false, /* pcrel_offset */
864 BFD_RELOC_LARCH_ABS_LO12, /* bfd_reloc_code_real_type */
865 reloc_bits, /* adjust_reloc_bits */
866 "abs_lo12"), /* larch_reloc_type_name */
868 LOONGARCH_HOWTO (R_LARCH_ABS64_LO20, /* type (69). */
869 32, /* rightshift. */
870 4, /* size. */
871 20, /* bitsize. */
872 false, /* pc_relative. */
873 5, /* bitpos. */
874 complain_overflow_signed, /* complain_on_overflow. */
875 bfd_elf_generic_reloc, /* special_function. */
876 "R_LARCH_ABS64_LO20", /* name. */
877 false, /* partial_inplace. */
878 0, /* src_mask */
879 0x1ffffe0, /* dst_mask */
880 false, /* pcrel_offset */
881 BFD_RELOC_LARCH_ABS64_LO20, /* bfd_reloc_code_real_type */
882 reloc_bits, /* adjust_reloc_bits */
883 "abs64_lo20"), /* larch_reloc_type_name */
885 LOONGARCH_HOWTO (R_LARCH_ABS64_HI12, /* type (70). */
886 52, /* rightshift. */
887 4, /* size. */
888 12, /* bitsize. */
889 false, /* pc_relative. */
890 10, /* bitpos. */
891 complain_overflow_signed, /* complain_on_overflow. */
892 bfd_elf_generic_reloc, /* special_function. */
893 "R_LARCH_ABS64_HI12", /* name. */
894 false, /* partial_inplace. */
895 0, /* src_mask */
896 0x3ffc00, /* dst_mask */
897 false, /* pcrel_offset */
898 BFD_RELOC_LARCH_ABS64_HI12, /* bfd_reloc_code_real_type */
899 reloc_bits, /* adjust_reloc_bits */
900 "abs64_hi12"), /* larch_reloc_type_name */
902 LOONGARCH_HOWTO (R_LARCH_PCALA_HI20, /* type (71). */
903 12, /* rightshift. */
904 4, /* size. */
905 20, /* bitsize. */
906 false, /* pc_relative. */
907 5, /* bitpos. */
908 complain_overflow_signed, /* complain_on_overflow. */
909 bfd_elf_generic_reloc, /* special_function. */
910 "R_LARCH_PCALA_HI20", /* name. */
911 false, /* partial_inplace. */
912 0, /* src_mask */
913 0x1ffffe0, /* dst_mask */
914 false, /* pcrel_offset */
915 BFD_RELOC_LARCH_PCALA_HI20, /* bfd_reloc_code_real_type */
916 reloc_bits, /* adjust_reloc_bits */
917 "pc_hi20"), /* larch_reloc_type_name */
919 LOONGARCH_HOWTO (R_LARCH_PCALA_LO12, /* type (72). */
920 0, /* rightshift. */
921 4, /* size. */
922 12, /* bitsize. */
923 false, /* pc_relative. */
924 10, /* bitpos. */
925 complain_overflow_signed, /* complain_on_overflow. */
926 bfd_elf_generic_reloc, /* special_function. */
927 "R_LARCH_PCALA_LO12", /* name. */
928 false, /* partial_inplace. */
929 0, /* src_mask */
930 0x3ffc00, /* dst_mask */
931 false, /* pcrel_offset */
932 BFD_RELOC_LARCH_PCALA_LO12, /* bfd_reloc_code_real_type */
933 reloc_bits, /* adjust_reloc_bits */
934 "pc_lo12"), /* larch_reloc_type_name */
936 LOONGARCH_HOWTO (R_LARCH_PCALA64_LO20, /* type (73). */
937 32, /* rightshift. */
938 4, /* size. */
939 20, /* bitsize. */
940 false, /* pc_relative. */
941 5, /* bitpos. */
942 complain_overflow_signed, /* complain_on_overflow. */
943 bfd_elf_generic_reloc, /* special_function. */
944 "R_LARCH_PCALA64_LO20", /* name. */
945 false, /* partial_inplace. */
946 0, /* src_mask */
947 0x1ffffe0, /* dst_mask */
948 false, /* pcrel_offset */
949 BFD_RELOC_LARCH_PCALA64_LO20, /* bfd_reloc_code_real_type */
950 reloc_bits, /* adjust_reloc_bits */
951 "pc64_lo20"), /* larch_reloc_type_name */
953 LOONGARCH_HOWTO (R_LARCH_PCALA64_HI12, /* type (74). */
954 52, /* rightshift. */
955 4, /* size. */
956 12, /* bitsize. */
957 false, /* pc_relative. */
958 10, /* bitpos. */
959 complain_overflow_signed, /* complain_on_overflow. */
960 bfd_elf_generic_reloc, /* special_function. */
961 "R_LARCH_PCALA64_HI12", /* name. */
962 false, /* partial_inplace. */
963 0, /* src_mask */
964 0x3ffc00, /* dst_mask */
965 false, /* pcrel_offset */
966 BFD_RELOC_LARCH_PCALA64_HI12, /* bfd_reloc_code_real_type */
967 reloc_bits, /* adjust_reloc_bits */
968 "pc64_hi12"), /* larch_reloc_type_name */
970 LOONGARCH_HOWTO (R_LARCH_GOT_PC_HI20, /* type (75). */
971 12, /* rightshift. */
972 4, /* size. */
973 20, /* bitsize. */
974 false, /* pc_relative. */
975 5, /* bitpos. */
976 complain_overflow_signed, /* complain_on_overflow. */
977 bfd_elf_generic_reloc, /* special_function. */
978 "R_LARCH_GOT_PC_HI20", /* name. */
979 false, /* partial_inplace. */
980 0, /* src_mask */
981 0x1ffffe0, /* dst_mask */
982 false, /* pcrel_offset */
983 BFD_RELOC_LARCH_GOT_PC_HI20, /* bfd_reloc_code_real_type */
984 reloc_bits, /* adjust_reloc_bits */
985 "got_pc_hi20"), /* larch_reloc_type_name */
987 LOONGARCH_HOWTO (R_LARCH_GOT_PC_LO12, /* type (76). */
988 0, /* rightshift. */
989 4, /* size. */
990 12, /* bitsize. */
991 false, /* pc_relative. */
992 10, /* bitpos. */
993 complain_overflow_signed, /* complain_on_overflow. */
994 bfd_elf_generic_reloc, /* special_function. */
995 "R_LARCH_GOT_PC_LO12", /* name. */
996 false, /* partial_inplace. */
997 0, /* src_mask */
998 0x3ffc00, /* dst_mask */
999 false, /* pcrel_offset */
1000 BFD_RELOC_LARCH_GOT_PC_LO12, /* bfd_reloc_code_real_type */
1001 reloc_bits, /* adjust_reloc_bits */
1002 "got_pc_lo12"), /* larch_reloc_type_name */
1004 LOONGARCH_HOWTO (R_LARCH_GOT64_PC_LO20, /* type (77). */
1005 32, /* rightshift. */
1006 4, /* size. */
1007 20, /* bitsize. */
1008 false, /* pc_relative. */
1009 5, /* bitpos. */
1010 complain_overflow_signed, /* complain_on_overflow. */
1011 bfd_elf_generic_reloc, /* special_function. */
1012 "R_LARCH_GOT64_PC_LO20", /* name. */
1013 false, /* partial_inplace. */
1014 0, /* src_mask */
1015 0x1ffffe0, /* dst_mask */
1016 false, /* pcrel_offset */
1017 BFD_RELOC_LARCH_GOT64_PC_LO20, /* bfd_reloc_code_real_type */
1018 reloc_bits, /* adjust_reloc_bits */
1019 "got64_pc_lo20"), /* larch_reloc_type_name */
1021 LOONGARCH_HOWTO (R_LARCH_GOT64_PC_HI12, /* type (78). */
1022 52, /* rightshift. */
1023 4, /* size. */
1024 12, /* bitsize. */
1025 false, /* pc_relative. */
1026 10, /* bitpos. */
1027 complain_overflow_signed, /* complain_on_overflow. */
1028 bfd_elf_generic_reloc, /* special_function. */
1029 "R_LARCH_GOT64_PC_HI12", /* name. */
1030 false, /* partial_inplace. */
1031 0, /* src_mask */
1032 0x3ffc00, /* dst_mask */
1033 false, /* pcrel_offset */
1034 BFD_RELOC_LARCH_GOT64_PC_HI12, /* bfd_reloc_code_real_type */
1035 reloc_bits, /* adjust_reloc_bits */
1036 "got64_pc_hi12"), /* larch_reloc_type_name */
1038 LOONGARCH_HOWTO (R_LARCH_GOT_HI20, /* type (79). */
1039 12, /* rightshift. */
1040 4, /* size. */
1041 20, /* bitsize. */
1042 false, /* pc_relative. */
1043 5, /* bitpos. */
1044 complain_overflow_signed, /* complain_on_overflow. */
1045 bfd_elf_generic_reloc, /* special_function. */
1046 "R_LARCH_GOT_HI20", /* name. */
1047 false, /* partial_inplace. */
1048 0, /* src_mask */
1049 0x1ffffe0, /* dst_mask */
1050 false, /* pcrel_offset */
1051 BFD_RELOC_LARCH_GOT_HI20, /* bfd_reloc_code_real_type */
1052 reloc_bits, /* adjust_reloc_bits */
1053 "got_hi20"), /* larch_reloc_type_name */
1055 LOONGARCH_HOWTO (R_LARCH_GOT_LO12, /* type (80). */
1056 0, /* rightshift. */
1057 4, /* size. */
1058 12, /* bitsize. */
1059 false, /* pc_relative. */
1060 10, /* bitpos. */
1061 complain_overflow_signed, /* complain_on_overflow. */
1062 bfd_elf_generic_reloc, /* special_function. */
1063 "R_LARCH_GOT_LO12", /* name. */
1064 false, /* partial_inplace. */
1065 0, /* src_mask */
1066 0x3ffc00, /* dst_mask */
1067 false, /* pcrel_offset */
1068 BFD_RELOC_LARCH_GOT_LO12, /* bfd_reloc_code_real_type */
1069 reloc_bits, /* adjust_reloc_bits */
1070 "got_lo12"), /* larch_reloc_type_name */
1072 LOONGARCH_HOWTO (R_LARCH_GOT64_LO20, /* type (81). */
1073 32, /* rightshift. */
1074 4, /* size. */
1075 20, /* bitsize. */
1076 false, /* pc_relative. */
1077 5, /* bitpos. */
1078 complain_overflow_signed, /* complain_on_overflow. */
1079 bfd_elf_generic_reloc, /* special_function. */
1080 "R_LARCH_GOT64_LO20", /* name. */
1081 false, /* partial_inplace. */
1082 0, /* src_mask */
1083 0x1ffffe0, /* dst_mask */
1084 false, /* pcrel_offset */
1085 BFD_RELOC_LARCH_GOT64_LO20, /* bfd_reloc_code_real_type */
1086 reloc_bits, /* adjust_reloc_bits */
1087 "got64_lo20"), /* larch_reloc_type_name */
1089 LOONGARCH_HOWTO (R_LARCH_GOT64_HI12, /* type (82). */
1090 52, /* rightshift. */
1091 4, /* size. */
1092 12, /* bitsize. */
1093 false, /* pc_relative. */
1094 10, /* bitpos. */
1095 complain_overflow_signed, /* complain_on_overflow. */
1096 bfd_elf_generic_reloc, /* special_function. */
1097 "R_LARCH_GOT64_HI12", /* name. */
1098 false, /* partial_inplace. */
1099 0, /* src_mask */
1100 0x3ffc00, /* dst_mask */
1101 false, /* pcrel_offset */
1102 BFD_RELOC_LARCH_GOT64_HI12, /* bfd_reloc_code_real_type */
1103 reloc_bits, /* adjust_reloc_bits */
1104 "got64_hi12"), /* larch_reloc_type_name */
1106 LOONGARCH_HOWTO (R_LARCH_TLS_LE_HI20, /* type (83). */
1107 12, /* rightshift. */
1108 4, /* size. */
1109 20, /* bitsize. */
1110 false, /* pc_relative. */
1111 5, /* bitpos. */
1112 complain_overflow_signed, /* complain_on_overflow. */
1113 bfd_elf_generic_reloc, /* special_function. */
1114 "R_LARCH_TLS_LE_HI20", /* name. */
1115 false, /* partial_inplace. */
1116 0, /* src_mask */
1117 0x1ffffe0, /* dst_mask */
1118 false, /* pcrel_offset */
1119 BFD_RELOC_LARCH_TLS_LE_HI20, /* bfd_reloc_code_real_type */
1120 reloc_bits, /* adjust_reloc_bits */
1121 "le_hi20"), /* larch_reloc_type_name */
1123 LOONGARCH_HOWTO (R_LARCH_TLS_LE_LO12, /* type (84). */
1124 0, /* rightshift. */
1125 4, /* size. */
1126 12, /* bitsize. */
1127 false, /* pc_relative. */
1128 10, /* bitpos. */
1129 complain_overflow_unsigned, /* complain_on_overflow. */
1130 bfd_elf_generic_reloc, /* special_function. */
1131 "R_LARCH_TLS_LE_LO12", /* name. */
1132 false, /* partial_inplace. */
1133 0, /* src_mask */
1134 0x3ffc00, /* dst_mask */
1135 false, /* pcrel_offset */
1136 BFD_RELOC_LARCH_TLS_LE_LO12, /* bfd_reloc_code_real_type */
1137 reloc_bits, /* adjust_reloc_bits */
1138 "le_lo12"), /* larch_reloc_type_name */
1140 LOONGARCH_HOWTO (R_LARCH_TLS_LE64_LO20, /* type (85). */
1141 32, /* rightshift. */
1142 4, /* size. */
1143 20, /* bitsize. */
1144 false, /* pc_relative. */
1145 5, /* bitpos. */
1146 complain_overflow_signed, /* complain_on_overflow. */
1147 bfd_elf_generic_reloc, /* special_function. */
1148 "R_LARCH_TLS_LE64_LO20", /* name. */
1149 false, /* partial_inplace. */
1150 0, /* src_mask */
1151 0x1ffffe0, /* dst_mask */
1152 false, /* pcrel_offset */
1153 BFD_RELOC_LARCH_TLS_LE64_LO20, /* bfd_reloc_code_real_type */
1154 reloc_bits, /* adjust_reloc_bits */
1155 "le64_lo20"), /* larch_reloc_type_name */
1157 LOONGARCH_HOWTO (R_LARCH_TLS_LE64_HI12, /* type (86). */
1158 52, /* rightshift. */
1159 4, /* size. */
1160 12, /* bitsize. */
1161 false, /* pc_relative. */
1162 10, /* bitpos. */
1163 complain_overflow_signed, /* complain_on_overflow. */
1164 bfd_elf_generic_reloc, /* special_function. */
1165 "R_LARCH_TLS_LE64_HI12", /* name. */
1166 false, /* partial_inplace. */
1167 0, /* src_mask */
1168 0x3ffc00, /* dst_mask */
1169 false, /* pcrel_offset */
1170 BFD_RELOC_LARCH_TLS_LE64_HI12, /* bfd_reloc_code_real_type */
1171 reloc_bits, /* adjust_reloc_bits */
1172 "le64_hi12"), /* larch_reloc_type_name */
1174 LOONGARCH_HOWTO (R_LARCH_TLS_IE_PC_HI20, /* type (87). */
1175 12, /* rightshift. */
1176 4, /* size. */
1177 20, /* bitsize. */
1178 false, /* pc_relative. */
1179 5, /* bitpos. */
1180 complain_overflow_signed, /* complain_on_overflow. */
1181 bfd_elf_generic_reloc, /* special_function. */
1182 "R_LARCH_TLS_IE_PC_HI20", /* name. */
1183 false, /* partial_inplace. */
1184 0, /* src_mask */
1185 0x1ffffe0, /* dst_mask */
1186 false, /* pcrel_offset */
1187 BFD_RELOC_LARCH_TLS_IE_PC_HI20, /* bfd_reloc_code_real_type */
1188 reloc_bits, /* adjust_reloc_bits */
1189 "ie_pc_hi20"), /* larch_reloc_type_name */
1191 LOONGARCH_HOWTO (R_LARCH_TLS_IE_PC_LO12, /* type (88). */
1192 0, /* rightshift. */
1193 4, /* size. */
1194 12, /* bitsize. */
1195 false, /* pc_relative. */
1196 10, /* bitpos. */
1197 complain_overflow_signed, /* complain_on_overflow. */
1198 bfd_elf_generic_reloc, /* special_function. */
1199 "R_LARCH_TLS_IE_PC_LO12", /* name. */
1200 false, /* partial_inplace. */
1201 0, /* src_mask */
1202 0x3ffc00, /* dst_mask */
1203 false, /* pcrel_offset */
1204 BFD_RELOC_LARCH_TLS_IE_PC_LO12, /* bfd_reloc_code_real_type */
1205 reloc_bits, /* adjust_reloc_bits */
1206 "ie_pc_lo12"), /* larch_reloc_type_name */
1208 LOONGARCH_HOWTO (R_LARCH_TLS_IE64_PC_LO20, /* type (89). */
1209 32, /* rightshift. */
1210 4, /* size. */
1211 20, /* bitsize. */
1212 false, /* pc_relative. */
1213 5, /* bitpos. */
1214 complain_overflow_signed, /* complain_on_overflow. */
1215 bfd_elf_generic_reloc, /* special_function. */
1216 "R_LARCH_TLS_IE64_PC_LO20", /* name. */
1217 false, /* partial_inplace. */
1218 0, /* src_mask */
1219 0x1ffffe0, /* dst_mask */
1220 false, /* pcrel_offset */
1221 BFD_RELOC_LARCH_TLS_IE64_PC_LO20, /* bfd_reloc_code_real_type */
1222 reloc_bits, /* adjust_reloc_bits */
1223 "ie64_pc_lo20"), /* larch_reloc_type_name */
1225 LOONGARCH_HOWTO (R_LARCH_TLS_IE64_PC_HI12, /* type (90). */
1226 52, /* rightshift. */
1227 4, /* size. */
1228 12, /* bitsize. */
1229 false, /* pc_relative. */
1230 10, /* bitpos. */
1231 complain_overflow_signed, /* complain_on_overflow. */
1232 bfd_elf_generic_reloc, /* special_function. */
1233 "R_LARCH_TLS_IE64_PC_HI12", /* name. */
1234 false, /* partial_inplace. */
1235 0, /* src_mask */
1236 0x3ffc00, /* dst_mask */
1237 false, /* pcrel_offset */
1238 BFD_RELOC_LARCH_TLS_IE64_PC_HI12, /* bfd_reloc_code_real_type */
1239 reloc_bits, /* adjust_reloc_bits */
1240 "ie64_pc_hi12"), /* larch_reloc_type_name */
1242 LOONGARCH_HOWTO (R_LARCH_TLS_IE_HI20, /* type (91). */
1243 12, /* rightshift. */
1244 4, /* size. */
1245 20, /* bitsize. */
1246 false, /* pc_relative. */
1247 5, /* bitpos. */
1248 complain_overflow_signed, /* complain_on_overflow. */
1249 bfd_elf_generic_reloc, /* special_function. */
1250 "R_LARCH_TLS_IE_HI20", /* name. */
1251 false, /* partial_inplace. */
1252 0, /* src_mask */
1253 0x1ffffe0, /* dst_mask */
1254 false, /* pcrel_offset */
1255 BFD_RELOC_LARCH_TLS_IE_HI20, /* bfd_reloc_code_real_type */
1256 reloc_bits, /* adjust_reloc_bits */
1257 "ie_hi20"), /* larch_reloc_type_name */
1259 LOONGARCH_HOWTO (R_LARCH_TLS_IE_LO12, /* type (92). */
1260 0, /* rightshift. */
1261 4, /* size. */
1262 12, /* bitsize. */
1263 false, /* pc_relative. */
1264 10, /* bitpos. */
1265 complain_overflow_signed, /* complain_on_overflow. */
1266 bfd_elf_generic_reloc, /* special_function. */
1267 "R_LARCH_TLS_IE_LO12", /* name. */
1268 false, /* partial_inplace. */
1269 0, /* src_mask */
1270 0x3ffc00, /* dst_mask */
1271 false, /* pcrel_offset */
1272 BFD_RELOC_LARCH_TLS_IE_LO12, /* bfd_reloc_code_real_type */
1273 reloc_bits, /* adjust_reloc_bits */
1274 "ie_lo12"), /* larch_reloc_type_name */
1276 LOONGARCH_HOWTO (R_LARCH_TLS_IE64_LO20, /* type (93). */
1277 32, /* rightshift. */
1278 4, /* size. */
1279 20, /* bitsize. */
1280 false, /* pc_relative. */
1281 5, /* bitpos. */
1282 complain_overflow_signed, /* complain_on_overflow. */
1283 bfd_elf_generic_reloc, /* special_function. */
1284 "R_LARCH_TLS_IE64_LO20", /* name. */
1285 false, /* partial_inplace. */
1286 0, /* src_mask */
1287 0x1ffffe0, /* dst_mask */
1288 false, /* pcrel_offset */
1289 BFD_RELOC_LARCH_TLS_IE64_LO20, /* bfd_reloc_code_real_type */
1290 reloc_bits, /* adjust_reloc_bits */
1291 "ie64_lo20"), /* larch_reloc_type_name */
1293 LOONGARCH_HOWTO (R_LARCH_TLS_IE64_HI12, /* type (94). */
1294 52, /* rightshift. */
1295 4, /* size. */
1296 12, /* bitsize. */
1297 false, /* pc_relative. */
1298 10, /* bitpos. */
1299 complain_overflow_signed, /* complain_on_overflow. */
1300 bfd_elf_generic_reloc, /* special_function. */
1301 "R_LARCH_TLS_IE64_HI12", /* name. */
1302 false, /* partial_inplace. */
1303 0, /* src_mask */
1304 0x3ffc00, /* dst_mask */
1305 false, /* pcrel_offset */
1306 BFD_RELOC_LARCH_TLS_IE64_HI12, /* bfd_reloc_code_real_type */
1307 reloc_bits, /* adjust_reloc_bits */
1308 "ie64_hi12"), /* larch_reloc_type_name */
1310 LOONGARCH_HOWTO (R_LARCH_TLS_LD_PC_HI20, /* type (95). */
1311 12, /* rightshift. */
1312 4, /* size. */
1313 20, /* bitsize. */
1314 false, /* pc_relative. */
1315 5, /* bitpos. */
1316 complain_overflow_signed, /* complain_on_overflow. */
1317 bfd_elf_generic_reloc, /* special_function. */
1318 "R_LARCH_TLS_LD_PC_HI20", /* name. */
1319 false, /* partial_inplace. */
1320 0, /* src_mask */
1321 0x1ffffe0, /* dst_mask */
1322 false, /* pcrel_offset */
1323 BFD_RELOC_LARCH_TLS_LD_PC_HI20, /* bfd_reloc_code_real_type */
1324 reloc_bits, /* adjust_reloc_bits */
1325 "ld_pc_hi20"), /* larch_reloc_type_name */
1327 LOONGARCH_HOWTO (R_LARCH_TLS_LD_HI20, /* type (96). */
1328 12, /* rightshift. */
1329 4, /* size. */
1330 20, /* bitsize. */
1331 false, /* pc_relative. */
1332 5, /* bitpos. */
1333 complain_overflow_signed, /* complain_on_overflow. */
1334 bfd_elf_generic_reloc, /* special_function. */
1335 "R_LARCH_TLS_LD_HI20", /* name. */
1336 false, /* partial_inplace. */
1337 0, /* src_mask */
1338 0x1ffffe0, /* dst_mask */
1339 false, /* pcrel_offset */
1340 BFD_RELOC_LARCH_TLS_LD_HI20, /* bfd_reloc_code_real_type */
1341 reloc_bits, /* adjust_reloc_bits */
1342 "ld_hi20"), /* larch_reloc_type_name */
1344 LOONGARCH_HOWTO (R_LARCH_TLS_GD_PC_HI20, /* type (97). */
1345 12, /* rightshift. */
1346 4, /* size. */
1347 20, /* bitsize. */
1348 false, /* pc_relative. */
1349 5, /* bitpos. */
1350 complain_overflow_signed, /* complain_on_overflow. */
1351 bfd_elf_generic_reloc, /* special_function. */
1352 "R_LARCH_TLS_GD_PC_HI20", /* name. */
1353 false, /* partial_inplace. */
1354 0, /* src_mask */
1355 0x1ffffe0, /* dst_mask */
1356 false, /* pcrel_offset */
1357 BFD_RELOC_LARCH_TLS_GD_PC_HI20, /* bfd_reloc_code_real_type */
1358 reloc_bits, /* adjust_reloc_bits */
1359 "gd_pc_hi20"), /* larch_reloc_type_name */
1361 LOONGARCH_HOWTO (R_LARCH_TLS_GD_HI20, /* type (98). */
1362 12, /* rightshift. */
1363 4, /* size. */
1364 20, /* bitsize. */
1365 false, /* pc_relative. */
1366 5, /* bitpos. */
1367 complain_overflow_signed, /* complain_on_overflow. */
1368 bfd_elf_generic_reloc, /* special_function. */
1369 "R_LARCH_TLS_GD_HI20", /* name. */
1370 false, /* partial_inplace. */
1371 0, /* src_mask */
1372 0x1ffffe0, /* dst_mask */
1373 false, /* pcrel_offset */
1374 BFD_RELOC_LARCH_TLS_GD_HI20, /* bfd_reloc_code_real_type */
1375 reloc_bits, /* adjust_reloc_bits */
1376 "gd_hi20"), /* larch_reloc_type_name */
1378 /* 32-bit PC relative. */
1379 LOONGARCH_HOWTO (R_LARCH_32_PCREL, /* type (99). */
1380 0, /* rightshift. */
1381 4, /* size. */
1382 32, /* bitsize. */
1383 true, /* pc_relative. */
1384 0, /* bitpos. */
1385 complain_overflow_signed, /* complain_on_overflow. */
1386 bfd_elf_generic_reloc, /* special_function. */
1387 "R_LARCH_32_PCREL", /* name. */
1388 false, /* partial_inplace. */
1389 0, /* src_mask */
1390 0xffffffff, /* dst_mask */
1391 false, /* pcrel_offset */
1392 BFD_RELOC_LARCH_32_PCREL, /* bfd_reloc_code_real_type */
1393 NULL, /* adjust_reloc_bits */
1394 NULL), /* larch_reloc_type_name */
1396 /* The paired relocation may be relaxed. */
1397 LOONGARCH_HOWTO (R_LARCH_RELAX, /* type (100). */
1398 0, /* rightshift */
1399 1, /* size */
1400 0, /* bitsize */
1401 false, /* pc_relative */
1402 0, /* bitpos */
1403 complain_overflow_dont, /* complain_on_overflow */
1404 bfd_elf_generic_reloc, /* special_function */
1405 "R_LARCH_RELAX", /* name */
1406 false, /* partial_inplace */
1407 0, /* src_mask */
1408 0, /* dst_mask */
1409 false, /* pcrel_offset */
1410 BFD_RELOC_LARCH_RELAX, /* bfd_reloc_code_real_type */
1411 NULL, /* adjust_reloc_bits */
1412 NULL), /* larch_reloc_type_name */
1414 /* Delete relaxed instruction. */
1415 LOONGARCH_HOWTO (R_LARCH_DELETE, /* type (101). */
1416 0, /* rightshift. */
1417 0, /* size. */
1418 0, /* bitsize. */
1419 false, /* pc_relative. */
1420 0, /* bitpos. */
1421 complain_overflow_dont, /* complain_on_overflow. */
1422 bfd_elf_generic_reloc, /* special_function. */
1423 "R_LARCH_DELETE", /* name. */
1424 false, /* partial_inplace. */
1425 0, /* src_mask. */
1426 0, /* dst_mask. */
1427 false, /* pcrel_offset. */
1428 BFD_RELOC_LARCH_DELETE, /* bfd_reloc_code_real_type. */
1429 NULL, /* adjust_reloc_bits. */
1430 NULL), /* larch_reloc_type_name. */
1432 /* Indicates an alignment statement. f the symbol index is 0,
1433 the addend indicates the number of bytes occupied by nop instructions
1434 at the relocation offset. The alignment boundary is specified by the
1435 addend rounded up to the next power of two.
1436 If the symbol index is not 0, the addend indicates the first and third
1437 expressions of .align. The lowest 8 bits are used to represent the first
1438 expression, other bits are used to represent the third expression. */
1439 LOONGARCH_HOWTO (R_LARCH_ALIGN, /* type (102). */
1440 0, /* rightshift. */
1441 0, /* size. */
1442 0, /* bitsize. */
1443 false, /* pc_relative. */
1444 0, /* bitpos. */
1445 complain_overflow_dont, /* complain_on_overflow. */
1446 bfd_elf_generic_reloc, /* special_function. */
1447 "R_LARCH_ALIGN", /* name. */
1448 false, /* partial_inplace. */
1449 0, /* src_mask. */
1450 0, /* dst_mask. */
1451 false, /* pcrel_offset. */
1452 BFD_RELOC_LARCH_ALIGN, /* bfd_reloc_code_real_type. */
1453 NULL, /* adjust_reloc_bits. */
1454 NULL), /* larch_reloc_type_name. */
1456 /* For pcaddi and pcala_hi20 + pcala_lo12 can relax to pcrel_20. */
1457 LOONGARCH_HOWTO (R_LARCH_PCREL20_S2, /* type (103). */
1458 2, /* rightshift. */
1459 4, /* size. */
1460 20, /* bitsize. */
1461 false, /* pc_relative. */
1462 5, /* bitpos. */
1463 complain_overflow_signed, /* complain_on_overflow. */
1464 bfd_elf_generic_reloc, /* special_function. */
1465 "R_LARCH_PCREL20_S2", /* name. */
1466 false, /* partial_inplace. */
1467 0, /* src_mask. */
1468 0x1ffffe0, /* dst_mask. */
1469 false, /* pcrel_offset. */
1470 BFD_RELOC_LARCH_PCREL20_S2, /* bfd_reloc_code_real_type. */
1471 reloc_sign_bits, /* adjust_reloc_bits. */
1472 "pcrel_20"), /* larch_reloc_type_name. */
1474 /* Canonical Frame Address. */
1475 LOONGARCH_HOWTO (R_LARCH_CFA, /* type (104). */
1476 0, /* rightshift. */
1477 0, /* size. */
1478 0, /* bitsize. */
1479 false, /* pc_relative. */
1480 0, /* bitpos. */
1481 complain_overflow_dont, /* complain_on_overflow. */
1482 bfd_elf_generic_reloc, /* special_function. */
1483 "R_LARCH_CFA", /* name. */
1484 false, /* partial_inplace. */
1485 0, /* src_mask. */
1486 0, /* dst_mask. */
1487 false, /* pcrel_offset. */
1488 BFD_RELOC_LARCH_CFA, /* bfd_reloc_code_real_type. */
1489 NULL, /* adjust_reloc_bits. */
1490 NULL), /* larch_reloc_type_name. */
1492 /* 6-bit in-place addition, for local label subtraction
1493 to calculate DW_CFA_advance_loc. */
1494 LOONGARCH_HOWTO (R_LARCH_ADD6, /* type (105). */
1495 0, /* rightshift. */
1496 1, /* size. */
1497 8, /* bitsize. */
1498 false, /* pc_relative. */
1499 0, /* bitpos. */
1500 complain_overflow_dont, /* complain_on_overflow. */
1501 loongarch_elf_add_sub_reloc, /* special_function. */
1502 "R_LARCH_ADD6", /* name. */
1503 false, /* partial_inplace. */
1504 0, /* src_mask. */
1505 0x3f, /* dst_mask. */
1506 false, /* pcrel_offset. */
1507 BFD_RELOC_LARCH_ADD6, /* bfd_reloc_code_real_type. */
1508 reloc_bits, /* adjust_reloc_bits. */
1509 NULL), /* larch_reloc_type_name. */
1511 /* 6-bit in-place subtraction, for local label subtraction
1512 to calculate DW_CFA_advance_loc. */
1513 LOONGARCH_HOWTO (R_LARCH_SUB6, /* type (106). */
1514 0, /* rightshift. */
1515 1, /* size. */
1516 8, /* bitsize. */
1517 false, /* pc_relative. */
1518 0, /* bitpos. */
1519 complain_overflow_dont, /* complain_on_overflow. */
1520 loongarch_elf_add_sub_reloc, /* special_function. */
1521 "R_LARCH_SUB6", /* name. */
1522 false, /* partial_inplace. */
1523 0, /* src_mask. */
1524 0x3f, /* dst_mask. */
1525 false, /* pcrel_offset. */
1526 BFD_RELOC_LARCH_SUB6, /* bfd_reloc_code_real_type. */
1527 reloc_bits, /* adjust_reloc_bits. */
1528 NULL), /* larch_reloc_type_name. */
1530 /* The length of unsigned-leb128 is variable, just assume the
1531 size is one byte here.
1532 uleb128 in-place addition, for local label subtraction. */
1533 LOONGARCH_HOWTO (R_LARCH_ADD_ULEB128, /* type (107). */
1534 0, /* rightshift. */
1535 1, /* size. */
1536 0, /* bitsize. */
1537 false, /* pc_relative. */
1538 0, /* bitpos. */
1539 complain_overflow_dont, /* complain_on_overflow. */
1540 loongarch_elf_add_sub_reloc_uleb128, /* special_function. */
1541 "R_LARCH_ADD_ULEB128", /* name. */
1542 false, /* partial_inplace. */
1543 0, /* src_mask. */
1544 0, /* dst_mask. */
1545 false, /* pcrel_offset. */
1546 BFD_RELOC_LARCH_ADD_ULEB128, /* bfd_reloc_code_real_type. */
1547 NULL, /* adjust_reloc_bits. */
1548 NULL), /* larch_reloc_type_name. */
1550 /* The length of unsigned-leb128 is variable, just assume the
1551 size is one byte here.
1552 uleb128 in-place subtraction, for local label subtraction. */
1553 LOONGARCH_HOWTO (R_LARCH_SUB_ULEB128, /* type (108). */
1554 0, /* rightshift. */
1555 1, /* size. */
1556 0, /* bitsize. */
1557 false, /* pc_relative. */
1558 0, /* bitpos. */
1559 complain_overflow_dont, /* complain_on_overflow. */
1560 loongarch_elf_add_sub_reloc_uleb128, /* special_function. */
1561 "R_LARCH_SUB_ULEB128", /* name. */
1562 false, /* partial_inplace. */
1563 0, /* src_mask. */
1564 0, /* dst_mask. */
1565 false, /* pcrel_offset. */
1566 BFD_RELOC_LARCH_SUB_ULEB128, /* bfd_reloc_code_real_type. */
1567 NULL, /* adjust_reloc_bits. */
1568 NULL), /* larch_reloc_type_name. */
1570 /* 64-bit PC relative. */
1571 LOONGARCH_HOWTO (R_LARCH_64_PCREL, /* type (109). */
1572 0, /* rightshift. */
1573 8, /* size. */
1574 64, /* bitsize. */
1575 true, /* pc_relative. */
1576 0, /* bitpos. */
1577 complain_overflow_signed, /* complain_on_overflow. */
1578 bfd_elf_generic_reloc, /* special_function. */
1579 "R_LARCH_64_PCREL", /* name. */
1580 false, /* partial_inplace. */
1581 0, /* src_mask */
1582 0xffffffffffffffff, /* dst_mask */
1583 false, /* pcrel_offset */
1584 BFD_RELOC_LARCH_64_PCREL, /* bfd_reloc_code_real_type */
1585 NULL, /* adjust_reloc_bits */
1586 NULL), /* larch_reloc_type_name */
1588 /* Used for medium code model function call pcaddu18i+jirl,
1589 these two instructions must adjacent. */
1590 LOONGARCH_HOWTO (R_LARCH_CALL36, /* type (110). */
1591 2, /* rightshift. */
1592 8, /* size. */
1593 36, /* bitsize. */
1594 true, /* pc_relative. */
1595 0, /* bitpos. */
1596 complain_overflow_signed, /* complain_on_overflow. */
1597 bfd_elf_generic_reloc, /* special_function. */
1598 "R_LARCH_CALL36", /* name. */
1599 false, /* partial_inplace. */
1600 0, /* src_mask. */
1601 0x03fffc0001ffffe0, /* dst_mask. */
1602 false, /* pcrel_offset. */
1603 BFD_RELOC_LARCH_CALL36, /* bfd_reloc_code_real_type. */
1604 reloc_sign_bits, /* adjust_reloc_bits. */
1605 "call36"), /* larch_reloc_type_name. */
1607 /* TLS_DESC PCREL. */
1608 LOONGARCH_HOWTO (R_LARCH_TLS_DESC_PC_HI20, /* type (111). */
1609 12, /* rightshift. */
1610 4, /* size. */
1611 20, /* bitsize. */
1612 true, /* pc_relative. */
1613 5, /* bitpos. */
1614 complain_overflow_signed, /* complain_on_overflow. */
1615 bfd_elf_generic_reloc, /* special_function. */
1616 "R_LARCH_TLS_DESC_PC_HI20", /* name. */
1617 false, /* partial_inplace. */
1618 0, /* src_mask. */
1619 0x1ffffe0, /* dst_mask. */
1620 false, /* pcrel_offset. */
1621 BFD_RELOC_LARCH_TLS_DESC_PC_HI20, /* bfd_reloc_code_real_type. */
1622 reloc_bits, /* adjust_reloc_bits. */
1623 "desc_pc_hi20"), /* larch_reloc_type_name. */
1625 LOONGARCH_HOWTO (R_LARCH_TLS_DESC_PC_LO12, /* type (112). */
1626 0, /* rightshift. */
1627 4, /* size. */
1628 12, /* bitsize. */
1629 true, /* pc_relative. */
1630 10, /* bitpos. */
1631 complain_overflow_signed, /* complain_on_overflow. */
1632 bfd_elf_generic_reloc, /* special_function. */
1633 "R_LARCH_TLS_DESC_PC_LO12", /* name. */
1634 false, /* partial_inplace. */
1635 0, /* src_mask. */
1636 0x3ffc00, /* dst_mask. */
1637 false, /* pcrel_offset. */
1638 BFD_RELOC_LARCH_TLS_DESC_PC_LO12, /* bfd_reloc_code_real_type. */
1639 reloc_bits, /* adjust_reloc_bits. */
1640 "desc_pc_lo12"), /* larch_reloc_type_name. */
1642 /* TLS_DESC64 LARGE PCREL. */
1643 LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_PC_LO20, /* type (113). */
1644 32, /* rightshift. */
1645 8, /* size. */
1646 20, /* bitsize. */
1647 true, /* pc_relative. */
1648 5, /* bitpos. */
1649 complain_overflow_signed, /* complain_on_overflow. */
1650 bfd_elf_generic_reloc, /* special_function. */
1651 "R_LARCH_TLS_DESC64_PC_LO20", /* name. */
1652 false, /* partial_inplace. */
1653 0, /* src_mask. */
1654 0x1ffffe0, /* dst_mask. */
1655 false, /* pcrel_offset. */
1656 BFD_RELOC_LARCH_TLS_DESC64_PC_LO20, /* bfd_reloc_code_real_type. */
1657 reloc_bits, /* adjust_reloc_bits. */
1658 "desc64_pc_lo20"), /* larch_reloc_type_name. */
1660 LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_PC_HI12, /* type (114). */
1661 52, /* rightshift. */
1662 8, /* size. */
1663 12, /* bitsize. */
1664 true, /* pc_relative. */
1665 10, /* bitpos. */
1666 complain_overflow_signed, /* complain_on_overflow. */
1667 bfd_elf_generic_reloc, /* special_function. */
1668 "R_LARCH_TLS_DESC64_PC_HI12", /* name. */
1669 false, /* partial_inplace. */
1670 0, /* src_mask. */
1671 0x3ffc00, /* dst_mask. */
1672 false, /* pcrel_offset. */
1673 BFD_RELOC_LARCH_TLS_DESC64_PC_HI12, /* bfd_reloc_code_real_type. */
1674 reloc_bits, /* adjust_reloc_bits. */
1675 "desc64_pc_hi12"), /* larch_reloc_type_name. */
1677 /* TLS_DESC ABS. */
1678 LOONGARCH_HOWTO (R_LARCH_TLS_DESC_HI20, /* type (115). */
1679 12, /* rightshift. */
1680 4, /* size. */
1681 20, /* bitsize. */
1682 false, /* pc_relative. */
1683 5, /* bitpos. */
1684 complain_overflow_signed, /* complain_on_overflow. */
1685 bfd_elf_generic_reloc, /* special_function. */
1686 "R_LARCH_TLS_DESC_HI20", /* name. */
1687 false, /* partial_inplace. */
1688 0, /* src_mask. */
1689 0x1ffffe0, /* dst_mask. */
1690 false, /* pcrel_offset. */
1691 BFD_RELOC_LARCH_TLS_DESC_HI20, /* bfd_reloc_code_real_type. */
1692 reloc_bits, /* adjust_reloc_bits. */
1693 "desc_hi20"), /* larch_reloc_type_name. */
1695 LOONGARCH_HOWTO (R_LARCH_TLS_DESC_LO12, /* type (116). */
1696 0, /* rightshift. */
1697 4, /* size. */
1698 12, /* bitsize. */
1699 false, /* pc_relative. */
1700 10, /* bitpos. */
1701 complain_overflow_signed, /* complain_on_overflow. */
1702 bfd_elf_generic_reloc, /* special_function. */
1703 "R_LARCH_TLS_DESC_LO12", /* name. */
1704 false, /* partial_inplace. */
1705 0, /* src_mask. */
1706 0x3ffc00, /* dst_mask. */
1707 false, /* pcrel_offset. */
1708 BFD_RELOC_LARCH_TLS_DESC_LO12, /* bfd_reloc_code_real_type. */
1709 reloc_bits, /* adjust_reloc_bits. */
1710 "desc_lo12"), /* larch_reloc_type_name. */
1712 /* TLS_DESC64 LARGE ABS. */
1713 LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_LO20, /* type (117). */
1714 32, /* rightshift. */
1715 8, /* size. */
1716 20, /* bitsize. */
1717 false, /* pc_relative. */
1718 5, /* bitpos. */
1719 complain_overflow_signed, /* complain_on_overflow. */
1720 bfd_elf_generic_reloc, /* special_function. */
1721 "R_LARCH_TLS_DESC64_LO20", /* name. */
1722 false, /* partial_inplace. */
1723 0, /* src_mask. */
1724 0x1ffffe0, /* dst_mask. */
1725 false, /* pcrel_offset. */
1726 BFD_RELOC_LARCH_TLS_DESC64_LO20, /* bfd_reloc_code_real_type. */
1727 reloc_bits, /* adjust_reloc_bits. */
1728 "desc64_lo20"), /* larch_reloc_type_name. */
1730 LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_HI12, /* type (118). */
1731 52, /* rightshift. */
1732 8, /* size. */
1733 12, /* bitsize. */
1734 false, /* pc_relative. */
1735 10, /* bitpos. */
1736 complain_overflow_signed, /* complain_on_overflow. */
1737 bfd_elf_generic_reloc, /* special_function. */
1738 "R_LARCH_TLS_DESC64_HI12", /* name. */
1739 false, /* partial_inplace. */
1740 0, /* src_mask. */
1741 0x3ffc00, /* dst_mask. */
1742 false, /* pcrel_offset. */
1743 BFD_RELOC_LARCH_TLS_DESC64_HI12, /* bfd_reloc_code_real_type. */
1744 reloc_bits, /* adjust_reloc_bits. */
1745 "desc64_hi12"), /* larch_reloc_type_name. */
1747 LOONGARCH_HOWTO (R_LARCH_TLS_DESC_LD, /* type (119). */
1748 0, /* rightshift. */
1749 4, /* size. */
1750 0, /* bitsize. */
1751 true, /* pc_relative. */
1752 0, /* bitpos. */
1753 complain_overflow_signed, /* complain_on_overflow. */
1754 bfd_elf_generic_reloc, /* special_function. */
1755 "R_LARCH_TLS_DESC_LD", /* name. */
1756 false, /* partial_inplace. */
1757 0, /* src_mask. */
1758 0, /* dst_mask. */
1759 false, /* pcrel_offset. */
1760 BFD_RELOC_LARCH_TLS_DESC_LD, /* bfd_reloc_code_real_type. */
1761 NULL, /* adjust_reloc_bits. */
1762 "desc_ld"), /* larch_reloc_type_name. */
1764 LOONGARCH_HOWTO (R_LARCH_TLS_DESC_CALL, /* type (120). */
1765 0, /* rightshift. */
1766 4, /* size. */
1767 0, /* bitsize. */
1768 false, /* pc_relative. */
1769 0, /* bitpos. */
1770 complain_overflow_dont, /* complain_on_overflow. */
1771 bfd_elf_generic_reloc, /* special_function. */
1772 "R_LARCH_TLS_DESC_CALL", /* name. */
1773 false, /* partial_inplace. */
1774 0, /* src_mask. */
1775 0, /* dst_mask. */
1776 false, /* pcrel_offset. */
1777 BFD_RELOC_LARCH_TLS_DESC_CALL, /* bfd_reloc_code_real_type. */
1778 NULL, /* adjust_reloc_bits. */
1779 "desc_call"), /* larch_reloc_type_name. */
1781 LOONGARCH_HOWTO (R_LARCH_TLS_LE_HI20_R, /* type (121). */
1782 12, /* rightshift. */
1783 4, /* size. */
1784 20, /* bitsize. */
1785 false, /* pc_relative. */
1786 5, /* bitpos. */
1787 complain_overflow_signed, /* complain_on_overflow. */
1788 bfd_elf_generic_reloc, /* special_function. */
1789 "R_LARCH_TLS_LE_HI20_R", /* name. */
1790 false, /* partial_inplace. */
1791 0, /* src_mask. */
1792 0x1ffffe0, /* dst_mask. */
1793 false, /* pcrel_offset. */
1794 BFD_RELOC_LARCH_TLS_LE_HI20_R, /* bfd_reloc_code_real_type. */
1795 reloc_bits, /* adjust_reloc_bits. */
1796 "le_hi20_r"), /* larch_reloc_type_name. */
1798 LOONGARCH_HOWTO (R_LARCH_TLS_LE_ADD_R, /* type (122). */
1799 0, /* rightshift. */
1800 0, /* size. */
1801 0, /* bitsize. */
1802 false, /* pc_relative. */
1803 0, /* bitpos. */
1804 complain_overflow_dont, /* complain_on_overflow. */
1805 bfd_elf_generic_reloc, /* special_function. */
1806 "R_LARCH_TLS_LE_ADD_R", /* name. */
1807 false, /* partial_inplace. */
1808 0, /* src_mask. */
1809 0, /* dst_mask. */
1810 false, /* pcrel_offset. */
1811 BFD_RELOC_LARCH_TLS_LE_ADD_R, /* bfd_reloc_code_real_type. */
1812 NULL, /* adjust_reloc_bits. */
1813 "le_add_r"), /* larch_reloc_type_name. */
1815 LOONGARCH_HOWTO (R_LARCH_TLS_LE_LO12_R, /* type (123). */
1816 0, /* rightshift. */
1817 4, /* size. */
1818 12, /* bitsize. */
1819 false, /* pc_relative. */
1820 10, /* bitpos. */
1821 complain_overflow_signed, /* complain_on_overflow. */
1822 bfd_elf_generic_reloc, /* special_function. */
1823 "R_LARCH_TLS_LE_LO12_R", /* name. */
1824 false, /* partial_inplace. */
1825 0, /* src_mask. */
1826 0x3ffc00, /* dst_mask. */
1827 false, /* pcrel_offset. */
1828 BFD_RELOC_LARCH_TLS_LE_LO12_R, /* bfd_reloc_code_real_type. */
1829 reloc_bits, /* adjust_reloc_bits. */
1830 "le_lo12_r"), /* larch_reloc_type_name. */
1832 /* For pcaddi, ld_pc_hi20 + ld_pc_lo12 can relax to ld_pcrel20_s2. */
1833 LOONGARCH_HOWTO (R_LARCH_TLS_LD_PCREL20_S2, /* type (124). */
1834 2, /* rightshift. */
1835 4, /* size. */
1836 20, /* bitsize. */
1837 false, /* pc_relative. */
1838 5, /* bitpos. */
1839 complain_overflow_signed, /* complain_on_overflow. */
1840 bfd_elf_generic_reloc, /* special_function. */
1841 "R_LARCH_TLS_LD_PCREL20_S2", /* name. */
1842 false, /* partial_inplace. */
1843 0, /* src_mask. */
1844 0x1ffffe0, /* dst_mask. */
1845 true, /* pcrel_offset. */
1846 BFD_RELOC_LARCH_TLS_LD_PCREL20_S2, /* bfd_reloc_code_real_type. */
1847 reloc_sign_bits, /* adjust_reloc_bits. */
1848 "ld_pcrel_20"), /* larch_reloc_type_name. */
1850 /* For pcaddi, gd_pc_hi20 + gd_pc_lo12 can relax to gd_pcrel20_s2. */
1851 LOONGARCH_HOWTO (R_LARCH_TLS_GD_PCREL20_S2, /* type (125). */
1852 2, /* rightshift. */
1853 4, /* size. */
1854 20, /* bitsize. */
1855 false, /* pc_relative. */
1856 5, /* bitpos. */
1857 complain_overflow_signed, /* complain_on_overflow. */
1858 bfd_elf_generic_reloc, /* special_function. */
1859 "R_LARCH_TLS_GD_PCREL20_S2", /* name. */
1860 false, /* partial_inplace. */
1861 0, /* src_mask. */
1862 0x1ffffe0, /* dst_mask. */
1863 true, /* pcrel_offset. */
1864 BFD_RELOC_LARCH_TLS_GD_PCREL20_S2, /* bfd_reloc_code_real_type. */
1865 reloc_sign_bits, /* adjust_reloc_bits. */
1866 "gd_pcrel_20"), /* larch_reloc_type_name. */
1868 /* For pcaddi, desc_pc_hi20 + desc_pc_lo12 can relax to desc_pcrel20_s2. */
1869 LOONGARCH_HOWTO (R_LARCH_TLS_DESC_PCREL20_S2, /* type (126). */
1870 2, /* rightshift. */
1871 4, /* size. */
1872 20, /* bitsize. */
1873 false, /* pc_relative. */
1874 5, /* bitpos. */
1875 complain_overflow_signed, /* complain_on_overflow. */
1876 bfd_elf_generic_reloc, /* special_function. */
1877 "R_LARCH_TLS_DESC_PCREL20_S2", /* name. */
1878 false, /* partial_inplace. */
1879 0, /* src_mask. */
1880 0x1ffffe0, /* dst_mask. */
1881 true, /* pcrel_offset. */
1882 BFD_RELOC_LARCH_TLS_DESC_PCREL20_S2, /* bfd_reloc_code_real_type. */
1883 reloc_sign_bits, /* adjust_reloc_bits. */
1884 "desc_pcrel_20"), /* larch_reloc_type_name. */
1887 reloc_howto_type *
1888 loongarch_elf_rtype_to_howto (bfd *abfd, unsigned int r_type)
1890 if (r_type < R_LARCH_count)
1892 BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count);
1893 BFD_ASSERT (loongarch_howto_table[r_type].howto.type == r_type);
1894 return &loongarch_howto_table[r_type].howto;
1897 (*_bfd_error_handler) (_("%pB: unsupported relocation type %#x"),
1898 abfd, r_type);
1899 bfd_set_error (bfd_error_bad_value);
1900 return NULL;
1903 reloc_howto_type *
1904 loongarch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
1906 for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++)
1907 if (loongarch_howto_table[i].howto.name
1908 && strcasecmp (loongarch_howto_table[i].howto.name, r_name) == 0)
1909 return &loongarch_howto_table[i].howto;
1911 (*_bfd_error_handler) (_("%pB: unsupported relocation type %s"),
1912 abfd, r_name);
1913 bfd_set_error (bfd_error_bad_value);
1914 return NULL;
1917 /* Cost so much. */
1918 reloc_howto_type *
1919 loongarch_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1920 bfd_reloc_code_real_type code)
1922 BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count);
1924 /* Fast search for new reloc types. */
1925 if (BFD_RELOC_LARCH_B16 <= code && code < BFD_RELOC_LARCH_RELAX)
1927 BFD_ASSERT (BFD_RELOC_LARCH_RELAX - BFD_RELOC_LARCH_B16
1928 == R_LARCH_RELAX - R_LARCH_B16);
1929 loongarch_reloc_howto_type *ht;
1930 ht = &loongarch_howto_table[code - BFD_RELOC_LARCH_B16 + R_LARCH_B16];
1931 BFD_ASSERT (ht->bfd_type == code);
1932 return &ht->howto;
1935 for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++)
1936 if (loongarch_howto_table[i].bfd_type == code)
1937 return &loongarch_howto_table[i].howto;
1939 (*_bfd_error_handler) (_("%pB: unsupported bfd relocation type %#x"),
1940 abfd, code);
1941 bfd_set_error (bfd_error_bad_value);
1942 return NULL;
1945 bfd_reloc_code_real_type
1946 loongarch_larch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1947 const char *l_r_name)
1949 for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++)
1951 loongarch_reloc_howto_type *lht = &loongarch_howto_table[i];
1952 if ((NULL != lht->larch_reloc_type_name)
1953 && (0 == strcmp (lht->larch_reloc_type_name, l_r_name)))
1954 return lht->bfd_type;
1957 return BFD_RELOC_NONE;
1961 /* Functions for reloc bits field.
1962 1. Signed extend *fix_val.
1963 2. Return false if overflow. */
1965 #define LARCH_RELOC_BFD_VMA_BIT_MASK(bitsize) \
1966 (~((((bfd_vma)0x1) << (bitsize)) - 1))
1968 /* Adjust val to perform insn
1969 BFD_RELOC_LARCH_SOP_POP_32_S_10_5
1970 BFD_RELOC_LARCH_SOP_POP_32_S_10_12
1971 BFD_RELOC_LARCH_SOP_POP_32_U_10_12
1972 BFD_RELOC_LARCH_SOP_POP_32_S_10_16
1973 BFD_RELOC_LARCH_SOP_POP_32_S_5_20
1974 BFD_RELOC_LARCH_SOP_POP_32_U. */
1976 static bool
1977 reloc_bits (bfd *abfd ATTRIBUTE_UNUSED,
1978 reloc_howto_type *howto,
1979 bfd_vma *fix_val)
1981 bfd_signed_vma val = (bfd_signed_vma)(*fix_val);
1982 bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1;
1984 val = val >> howto->rightshift;
1986 /* Perform insn bits field. */
1987 val = val & mask;
1988 val <<= howto->bitpos;
1990 *fix_val = (bfd_vma)val;
1992 return true;
1995 static bool
1996 reloc_bits_sanity (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val,
1997 unsigned int sign)
1999 if ((sign && howto->complain_on_overflow != complain_overflow_signed)
2000 || (!sign && howto->complain_on_overflow != complain_overflow_unsigned))
2001 return false;
2003 bfd_signed_vma val = (bfd_signed_vma)(*fix_val);
2005 /* Check alignment. FIXME: if rightshift is not alingment. */
2006 if (howto->rightshift
2007 && (val & ((((bfd_signed_vma) 1) << howto->rightshift) - 1)))
2009 /* The as passes NULL casued internal error, so it can not use _bfd_error_handler
2010 output details, ld is not affected. */
2011 if (abfd != NULL)
2013 (*_bfd_error_handler) (_("%pB: relocation %s right shift %d error 0x%lx"),
2014 abfd, howto->name, howto->rightshift, (long) val);
2015 bfd_set_error (bfd_error_bad_value);
2017 return false;
2020 bfd_signed_vma mask = ((bfd_signed_vma)0x1 << (howto->bitsize
2021 + howto->rightshift - sign)) - 1;
2023 /* Positive number: high part is all 0;
2024 Negative number: if high part is not all 0, high part must be all 1.
2025 high part: from sign bit to highest bit. */
2026 if ((val & ~mask) && ((val & ~mask) != ~mask))
2028 /* The as passes NULL casued internal error, so it can not use _bfd_error_handler
2029 output details, ld is not affected. */
2030 if (abfd != NULL)
2032 (*_bfd_error_handler) (_("%pB: relocation %s overflow 0x%lx"),
2033 abfd, howto->name, (long) val);
2034 bfd_set_error (bfd_error_bad_value);
2036 return false;
2039 val = val >> howto->rightshift;
2040 /* can delete? */
2041 mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1;
2042 val = val & mask;
2044 switch (howto->type)
2046 case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
2047 case R_LARCH_B26:
2048 /* Perform insn bits field. 15:0<<10, 25:16>>16. */
2049 val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff);
2050 break;
2051 case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
2052 case R_LARCH_B21:
2053 /* Perform insn bits field. 15:0<<10, 20:16>>16. */
2054 val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f);
2055 break;
2056 case R_LARCH_CALL36:
2057 /* 0x8000: If low 16-bit immediate greater than 0x7fff,
2058 it become to a negative number due to sign-extended,
2059 so the high part need to add 0x8000. */
2060 val = (((val + 0x8000) >> 16) << 5) | (((val & 0xffff) << 10) << 32);
2061 break;
2062 default:
2063 val <<= howto->bitpos;
2064 break;
2067 *fix_val = val;
2068 return true;
2071 static bool
2072 reloc_sign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val)
2074 return reloc_bits_sanity (abfd, howto, fix_val, 1);
2077 static bool
2078 reloc_unsign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val)
2080 return reloc_bits_sanity (abfd, howto, fix_val, 0);
2083 bool
2084 loongarch_adjust_reloc_bitsfield (bfd *abfd, reloc_howto_type *howto,
2085 bfd_vma *fix_val)
2087 BFD_ASSERT (((loongarch_reloc_howto_type *)howto)->adjust_reloc_bits);
2088 return ((loongarch_reloc_howto_type *)
2089 howto)->adjust_reloc_bits (abfd, howto, fix_val);
2092 static bfd_reloc_status_type
2093 loongarch_elf_add_sub_reloc (bfd *abfd,
2094 arelent *reloc_entry,
2095 asymbol *symbol,
2096 void *data,
2097 asection *input_section,
2098 bfd *output_bfd,
2099 char **error_message ATTRIBUTE_UNUSED)
2101 reloc_howto_type *howto = reloc_entry->howto;
2102 bfd_vma relocation;
2104 if (output_bfd != NULL
2105 && (symbol->flags & BSF_SECTION_SYM) == 0
2106 && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
2108 reloc_entry->address += input_section->output_offset;
2109 return bfd_reloc_ok;
2112 if (output_bfd != NULL)
2113 return bfd_reloc_continue;
2115 relocation = symbol->value + symbol->section->output_section->vma
2116 + symbol->section->output_offset + reloc_entry->addend;
2118 bfd_size_type octets = reloc_entry->address
2119 * bfd_octets_per_byte (abfd, input_section);
2120 if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
2121 input_section, octets))
2122 return bfd_reloc_outofrange;
2124 bfd_vma old_value = bfd_get (howto->bitsize, abfd,
2125 data + reloc_entry->address);
2127 switch (howto->type)
2129 case R_LARCH_ADD6:
2130 case R_LARCH_ADD8:
2131 case R_LARCH_ADD16:
2132 case R_LARCH_ADD32:
2133 case R_LARCH_ADD64:
2134 relocation = old_value + relocation;
2135 break;
2137 case R_LARCH_SUB6:
2138 case R_LARCH_SUB8:
2139 case R_LARCH_SUB16:
2140 case R_LARCH_SUB32:
2141 case R_LARCH_SUB64:
2142 relocation = old_value - relocation;
2143 break;
2146 bfd_put (howto->bitsize, abfd, relocation, data + reloc_entry->address);
2148 return bfd_reloc_ok;
2151 static bfd_reloc_status_type
2152 loongarch_elf_add_sub_reloc_uleb128 (bfd *abfd,
2153 arelent *reloc_entry,
2154 asymbol *symbol,
2155 void *data,
2156 asection *input_section,
2157 bfd *output_bfd,
2158 char **error_message ATTRIBUTE_UNUSED)
2160 reloc_howto_type *howto = reloc_entry->howto;
2161 bfd_vma relocation;
2163 if (output_bfd != NULL
2164 && (symbol->flags & BSF_SECTION_SYM) == 0
2165 && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
2167 reloc_entry->address += input_section->output_offset;
2168 return bfd_reloc_ok;
2171 if (output_bfd != NULL)
2172 return bfd_reloc_continue;
2174 relocation = symbol->value + symbol->section->output_section->vma
2175 + symbol->section->output_offset + reloc_entry->addend;
2177 bfd_size_type octets = reloc_entry->address
2178 * bfd_octets_per_byte (abfd, input_section);
2179 if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
2180 input_section, octets))
2181 return bfd_reloc_outofrange;
2183 unsigned int len = 0;
2184 bfd_byte *p = data + reloc_entry->address;
2185 bfd_vma old_value = _bfd_read_unsigned_leb128 (abfd, p, &len);
2187 switch (howto->type)
2189 case R_LARCH_ADD_ULEB128:
2190 relocation = old_value + relocation;
2191 break;
2193 case R_LARCH_SUB_ULEB128:
2194 relocation = old_value - relocation;
2195 break;
2198 bfd_vma mask = (1 << (7 * len)) - 1;
2199 relocation = relocation & mask;
2200 loongarch_write_unsigned_leb128 (p, len, relocation);
2201 return bfd_reloc_ok;
2204 /* Write VALUE in uleb128 format to P.
2205 LEN is the uleb128 value length.
2206 Return a pointer to the byte following the last byte that was written. */
2207 bfd_byte *
2208 loongarch_write_unsigned_leb128 (bfd_byte *p, unsigned int len, bfd_vma value)
2210 bfd_byte c;
2213 c = value & 0x7f;
2214 if (len > 1)
2215 c |= 0x80;
2216 *(p++) = c;
2217 value >>= 7;
2218 len--;
2220 while (len);
2221 return p;
2224 int loongarch_get_uleb128_length (bfd_byte *buf)
2226 unsigned int len = 0;
2227 _bfd_read_unsigned_leb128 (NULL, buf, &len);
2228 return len;