]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/elfxx-loongarch.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / bfd / elfxx-loongarch.c
CommitLineData
e214f8db 1/* LoongArch-specific support for ELF.
a2c58332 2 Copyright (C) 2021-2022 Free Software Foundation, Inc.
e214f8db 3 Contributed by Loongson Ltd.
4
5 Based on RISC-V target.
6
7 This file is part of BFD, the Binary File Descriptor library.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; see the file COPYING3. If not,
21 see <http://www.gnu.org/licenses/>. */
22
23#include "sysdep.h"
24#include "bfd.h"
25#include "libbfd.h"
26#include "elf-bfd.h"
27#include "elf/loongarch.h"
28#include "elfxx-loongarch.h"
29
30#define ALL_ONES (~ (bfd_vma) 0)
31
32/* This does not include any relocation information, but should be
33 good enough for GDB or objdump to read the file. */
34
35static reloc_howto_type howto_table[] =
36{
37#define LOONGARCH_HOWTO(r_name) \
38 HOWTO (R_LARCH_##r_name, 0, 2, 32, false, 0, complain_overflow_signed, \
39 bfd_elf_generic_reloc, "R_LARCH_" #r_name, false, 0, 0xffffffff, false)
40
41 /* No relocation. */
42 HOWTO (R_LARCH_NONE, /* type (0). */
43 0, /* rightshift */
44 3, /* size */
45 0, /* bitsize */
46 false, /* pc_relative */
47 0, /* bitpos */
48 complain_overflow_dont, /* complain_on_overflow */
49 bfd_elf_generic_reloc, /* special_function */
50 "R_LARCH_NONE", /* name */
51 false, /* partial_inplace */
52 0, /* src_mask */
53 0, /* dst_mask */
54 false), /* pcrel_offset */
55
56 /* 32 bit relocation. */
57 HOWTO (R_LARCH_32, /* type (1). */
58 0, /* rightshift */
59 2, /* size */
60 32, /* bitsize */
61 false, /* pc_relative */
62 0, /* bitpos */
63 complain_overflow_dont, /* complain_on_overflow */
64 bfd_elf_generic_reloc, /* special_function */
65 "R_LARCH_32", /* name */
66 false, /* partial_inplace */
67 0, /* src_mask */
68 0xffffffff, /* dst_mask */
69 false), /* pcrel_offset */
70
71 /* 64 bit relocation. */
72 HOWTO (R_LARCH_64, /* type (2). */
73 0, /* rightshift */
74 4, /* size */
75 64, /* bitsize */
76 false, /* pc_relative */
77 0, /* bitpos */
78 complain_overflow_dont, /* complain_on_overflow */
79 bfd_elf_generic_reloc, /* special_function */
80 "R_LARCH_64", /* name */
81 false, /* partial_inplace */
82 0, /* src_mask */
83 ALL_ONES, /* dst_mask */
84 false), /* pcrel_offset */
85
86 HOWTO (R_LARCH_RELATIVE, /* type (3). */
87 0, /* rightshift */
88 2, /* size */
89 32, /* bitsize */
90 false, /* pc_relative */
91 0, /* bitpos */
92 complain_overflow_dont, /* complain_on_overflow */
93 bfd_elf_generic_reloc, /* special_function */
94 "R_LARCH_RELATIVE", /* name */
95 false, /* partial_inplace */
96 0, /* src_mask */
97 0xffffffff, /* dst_mask */
98 false), /* pcrel_offset */
99
100 HOWTO (R_LARCH_COPY, /* type (4). */
101 0, /* rightshift */
102 0, /* this one is variable size */
103 0, /* bitsize */
104 false, /* pc_relative */
105 0, /* bitpos */
106 complain_overflow_bitfield, /* complain_on_overflow */
107 bfd_elf_generic_reloc, /* special_function */
108 "R_LARCH_COPY", /* name */
109 false, /* partial_inplace */
110 0, /* src_mask */
111 0, /* dst_mask */
112 false), /* pcrel_offset */
113
114 HOWTO (R_LARCH_JUMP_SLOT, /* type (5). */
115 0, /* rightshift */
116 4, /* size */
117 64, /* bitsize */
118 false, /* pc_relative */
119 0, /* bitpos */
120 complain_overflow_bitfield, /* complain_on_overflow */
121 bfd_elf_generic_reloc, /* special_function */
122 "R_LARCH_JUMP_SLOT", /* name */
123 false, /* partial_inplace */
124 0, /* src_mask */
125 0, /* dst_mask */
126 false), /* pcrel_offset */
127
128 /* Dynamic TLS relocations. */
129 HOWTO (R_LARCH_TLS_DTPMOD32, /* type (6). */
130 0, /* rightshift */
131 2, /* size */
132 32, /* bitsize */
133 false, /* pc_relative */
134 0, /* bitpos */
135 complain_overflow_dont, /* complain_on_overflow */
136 bfd_elf_generic_reloc, /* special_function */
137 "R_LARCH_TLS_DTPMOD32", /* name */
138 false, /* partial_inplace */
139 0, /* src_mask */
140 0xffffffff, /* dst_mask */
141 false), /* pcrel_offset */
142
143 HOWTO (R_LARCH_TLS_DTPMOD64, /* type (7). */
144 0, /* rightshift */
145 4, /* size */
146 64, /* bitsize */
147 false, /* pc_relative */
148 0, /* bitpos */
149 complain_overflow_dont, /* complain_on_overflow */
150 bfd_elf_generic_reloc, /* special_function */
151 "R_LARCH_TLS_DTPMOD64", /* name */
152 false, /* partial_inplace */
153 0, /* src_mask */
154 ALL_ONES, /* dst_mask */
155 false), /* pcrel_offset */
156
157 HOWTO (R_LARCH_TLS_DTPREL32, /* type (8). */
158 0, /* rightshift */
159 2, /* size */
160 32, /* bitsize */
161 false, /* pc_relative */
162 0, /* bitpos */
163 complain_overflow_dont, /* complain_on_overflow */
164 bfd_elf_generic_reloc, /* special_function */
165 "R_LARCH_TLS_DTPREL32", /* name */
166 true, /* partial_inplace */
167 0, /* src_mask */
168 0xffffffff, /* dst_mask */
169 false), /* pcrel_offset */
170
171 HOWTO (R_LARCH_TLS_DTPREL64, /* type (9). */
172 0, /* rightshift */
173 4, /* size */
174 64, /* bitsize */
175 false, /* pc_relative */
176 0, /* bitpos */
177 complain_overflow_dont, /* complain_on_overflow */
178 bfd_elf_generic_reloc, /* special_function */
179 "R_LARCH_TLS_DTPREL64", /* name */
180 true, /* partial_inplace */
181 0, /* src_mask */
182 ALL_ONES, /* dst_mask */
183 false), /* pcrel_offset */
184
185 HOWTO (R_LARCH_TLS_TPREL32, /* type (10). */
186 0, /* rightshift */
187 2, /* size */
188 32, /* bitsize */
189 false, /* pc_relative */
190 0, /* bitpos */
191 complain_overflow_dont, /* complain_on_overflow */
192 bfd_elf_generic_reloc, /* special_function */
193 "R_LARCH_TLS_TPREL32", /* name */
194 false, /* partial_inplace */
195 0, /* src_mask */
196 0xffffffff, /* dst_mask */
197 false), /* pcrel_offset */
198
199 HOWTO (R_LARCH_TLS_TPREL64, /* type (11). */
200 0, /* rightshift */
201 4, /* size */
202 64, /* bitsize */
203 false, /* pc_relative */
204 0, /* bitpos */
205 complain_overflow_dont, /* complain_on_overflow */
206 bfd_elf_generic_reloc, /* special_function */
207 "R_LARCH_TLS_TPREL64", /* name */
208 false, /* partial_inplace */
209 0, /* src_mask */
210 ALL_ONES, /* dst_mask */
211 false), /* pcrel_offset */
212
213 HOWTO (R_LARCH_IRELATIVE, /* type (12). */
214 0, /* rightshift */
215 2, /* 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_IRELATIVE", /* name */
222 false, /* partial_inplace */
223 0, /* src_mask */
224 0xffffffff, /* dst_mask */
225 false), /* pcrel_offset */
226
227 EMPTY_HOWTO(13),
228 EMPTY_HOWTO(14),
229 EMPTY_HOWTO(15),
230 EMPTY_HOWTO(16),
231 EMPTY_HOWTO(17),
232 EMPTY_HOWTO(18),
233 EMPTY_HOWTO(19),
234
235 HOWTO (R_LARCH_MARK_LA, /* type (20). */
236 0, /* rightshift. */
237 3, /* size. */
238 0, /* bitsize. */
239 false, /* pc_relative. */
240 0, /* bitpos. */
241 complain_overflow_signed, /* complain_on_overflow. */
242 bfd_elf_generic_reloc, /* special_function. */
243 "R_LARCH_MARK_LA", /* name. */
244 false, /* partial_inplace. */
245 0, /* src_mask. */
246 0, /* dst_mask. */
247 false), /* pcrel_offset. */
248
249 HOWTO (R_LARCH_MARK_PCREL, /* type (21). */
250 0, /* rightshift. */
251 3, /* size. */
252 0, /* bitsize. */
253 false, /* pc_relative. */
254 0, /* bitpos. */
255 complain_overflow_signed, /* complain_on_overflow. */
256 bfd_elf_generic_reloc, /* special_function. */
257 "R_LARCH_MARK_PCREL", /* name. */
258 false, /* partial_inplace. */
259 0, /* src_mask. */
260 0, /* dst_mask. */
261 false), /* pcrel_offset. */
262
263 HOWTO (R_LARCH_SOP_PUSH_PCREL, /* type (22). */
264 2, /* rightshift. */
265 2, /* size. */
266 32, /* bitsize. */
267 true /* FIXME: somewhat use this. */, /* pc_relative. */
268 0, /* bitpos. */
269 complain_overflow_signed, /* complain_on_overflow. */
270 bfd_elf_generic_reloc, /* special_function. */
271 "R_LARCH_SOP_PUSH_PCREL", /* name. */
272 false, /* partial_inplace. */
273 0x03ffffff, /* src_mask. */
274 0x03ffffff, /* dst_mask. */
275 false), /* pcrel_offset. */
276
277 /* type 23-37. */
278 LOONGARCH_HOWTO (SOP_PUSH_ABSOLUTE),
279 LOONGARCH_HOWTO (SOP_PUSH_DUP),
280 LOONGARCH_HOWTO (SOP_PUSH_GPREL),
281 LOONGARCH_HOWTO (SOP_PUSH_TLS_TPREL),
282 LOONGARCH_HOWTO (SOP_PUSH_TLS_GOT),
283 LOONGARCH_HOWTO (SOP_PUSH_TLS_GD),
284 LOONGARCH_HOWTO (SOP_PUSH_PLT_PCREL),
285 LOONGARCH_HOWTO (SOP_ASSERT),
286 LOONGARCH_HOWTO (SOP_NOT),
287 LOONGARCH_HOWTO (SOP_SUB),
288 LOONGARCH_HOWTO (SOP_SL),
289 LOONGARCH_HOWTO (SOP_SR),
290 LOONGARCH_HOWTO (SOP_ADD),
291 LOONGARCH_HOWTO (SOP_AND),
292 LOONGARCH_HOWTO (SOP_IF_ELSE),
293
294 HOWTO (R_LARCH_SOP_POP_32_S_10_5, /* type (38). */
295 0, /* rightshift. */
296 2, /* size. */
297 5, /* bitsize. */
298 false, /* pc_relative. */
299 10, /* bitpos. */
300 complain_overflow_signed, /* complain_on_overflow. */
301 bfd_elf_generic_reloc, /* special_function. */
302 "R_LARCH_SOP_POP_32_S_10_5", /* name. */
303 false, /* partial_inplace. */
304 0, /* src_mask */
305 0x7c00, /* dst_mask */
306 false), /* pcrel_offset. */
307
308 HOWTO (R_LARCH_SOP_POP_32_U_10_12, /* type (39). */
309 0, /* rightshift. */
310 2, /* size. */
311 12, /* bitsize. */
312 false, /* pc_relative. */
313 10, /* bitpos. */
314 complain_overflow_signed, /* complain_on_overflow. */
315 bfd_elf_generic_reloc, /* special_function. */
316 "R_LARCH_SOP_POP_32_U_10_12", /* name. */
317 false, /* partial_inplace. */
318 0, /* src_mask */
319 0x3ffc00, /* dst_mask */
320 false), /* pcrel_offset. */
321
322 HOWTO (R_LARCH_SOP_POP_32_S_10_12, /* type (40). */
323 0, /* rightshift. */
324 2, /* size. */
325 12, /* bitsize. */
326 false, /* pc_relative. */
327 10, /* bitpos. */
328 complain_overflow_signed, /* complain_on_overflow. */
329 bfd_elf_generic_reloc, /* special_function. */
330 "R_LARCH_SOP_POP_32_S_10_12", /* name. */
331 false, /* partial_inplace. */
332 0, /* src_mask */
333 0x3ffc00, /* dst_mask */
334 false), /* pcrel_offset. */
335
336 HOWTO (R_LARCH_SOP_POP_32_S_10_16, /* type (41). */
337 0, /* rightshift. */
338 2, /* size. */
339 16, /* bitsize. */
340 false, /* pc_relative. */
341 10, /* bitpos. */
342 complain_overflow_signed, /* complain_on_overflow. */
343 bfd_elf_generic_reloc, /* special_function. */
344 "R_LARCH_SOP_POP_32_S_10_16", /* name. */
345 false, /* partial_inplace. */
346 0, /* src_mask */
347 0x3fffc00, /* dst_mask */
348 false), /* pcrel_offset. */
349
350 HOWTO (R_LARCH_SOP_POP_32_S_10_16_S2, /* type (42). */
351 2, /* rightshift. */
352 2, /* size. */
353 16, /* bitsize. */
354 false, /* pc_relative. */
355 10, /* bitpos. */
356 complain_overflow_signed, /* complain_on_overflow. */
357 bfd_elf_generic_reloc, /* special_function. */
358 "R_LARCH_SOP_POP_32_S_10_16_S2", /* name. */
359 false, /* partial_inplace. */
360 0, /* src_mask */
361 0x3fffc00, /* dst_mask */
362 false), /* pcrel_offset. */
363
364 HOWTO (R_LARCH_SOP_POP_32_S_5_20, /* type (43). */
365 0, /* rightshift. */
366 2, /* size. */
367 20, /* bitsize. */
368 false, /* pc_relative. */
369 5, /* bitpos. */
370 complain_overflow_signed, /* complain_on_overflow. */
371 bfd_elf_generic_reloc, /* special_function. */
372 "R_LARCH_SOP_POP_32_S_5_20", /* name. */
373 false, /* partial_inplace. */
374 0, /* src_mask */
375 0x1fffe0, /* dst_mask */
376 false), /* pcrel_offset. */
377
378 HOWTO (R_LARCH_SOP_POP_32_S_0_5_10_16_S2, /* type (44). */
379 2, /* rightshift. */
380 2, /* size. */
381 21, /* bitsize. */
382 false, /* pc_relative. */
383 0, /* bitpos. */
384 complain_overflow_signed, /* complain_on_overflow. */
385 bfd_elf_generic_reloc, /* special_function. */
386 "R_LARCH_SOP_POP_32_S_0_5_10_16_S2", /* name. */
387 false, /* partial_inplace. */
388 0xfc0003e0, /* src_mask */
389 0xfc0003e0, /* dst_mask */
390 false), /* pcrel_offset. */
391
392 HOWTO (R_LARCH_SOP_POP_32_S_0_10_10_16_S2, /* type (45). */
393 2, /* rightshift. */
394 2, /* size. */
395 26, /* bitsize. */
396 false, /* pc_relative. */
397 0, /* bitpos. */
398 complain_overflow_signed, /* complain_on_overflow. */
399 bfd_elf_generic_reloc, /* special_function. */
400 "R_LARCH_SOP_POP_32_S_0_10_10_16_S2", /* name. */
401 false, /* partial_inplace. */
402 0xfc000000, /* src_mask */
403 0xfc000000, /* dst_mask */
404 false), /* pcrel_offset. */
405
406 HOWTO (R_LARCH_SOP_POP_32_U, /* type (46). */
407 0, /* rightshift. */
408 2, /* size. */
409 32, /* bitsize. */
410 false, /* pc_relative. */
411 0, /* bitpos. */
412 complain_overflow_signed, /* complain_on_overflow. */
413 bfd_elf_generic_reloc, /* special_function. */
414 "R_LARCH_SOP_POP_32_S_U", /* name. */
415 false, /* partial_inplace. */
416 0, /* src_mask */
417 0, /* dst_mask */
418 false), /* pcrel_offset. */
419
420 HOWTO (R_LARCH_ADD8, /* type (47). */
421 0, /* rightshift. */
422 2, /* size. */
423 8, /* bitsize. */
424 false, /* pc_relative. */
425 0, /* bitpos. */
426 complain_overflow_signed, /* complain_on_overflow. */
427 bfd_elf_generic_reloc, /* special_function. */
428 "R_LARCH_ADD8", /* name. */
429 false, /* partial_inplace. */
430 0, /* src_mask */
431 0xffffffff, /* dst_mask */
432 false), /* pcrel_offset. */
433
434 HOWTO (R_LARCH_ADD16, /* type (48). */
435 0, /* rightshift. */
436 2, /* size. */
437 16, /* bitsize. */
438 false, /* pc_relative. */
439 0, /* bitpos. */
440 complain_overflow_signed, /* complain_on_overflow. */
441 bfd_elf_generic_reloc, /* special_function. */
442 "R_LARCH_ADD16", /* name. */
443 false, /* partial_inplace. */
444 0, /* src_mask */
445 0xffffffff, /* dst_mask */
446 false), /* pcrel_offset. */
447
448 HOWTO (R_LARCH_ADD24, /* type (49). */
449 0, /* rightshift. */
450 2, /* size. */
451 24, /* bitsize. */
452 false, /* pc_relative. */
453 0, /* bitpos. */
454 complain_overflow_signed, /* complain_on_overflow. */
455 bfd_elf_generic_reloc, /* special_function. */
456 "R_LARCH_ADD24", /* name. */
457 false, /* partial_inplace. */
458 0, /* src_mask */
459 0xffffffff, /* dst_mask */
460 false), /* pcrel_offset. */
461
462 HOWTO (R_LARCH_ADD32, /* type (50). */
463 0, /* rightshift. */
464 2, /* size. */
465 32, /* bitsize. */
466 false, /* pc_relative. */
467 0, /* bitpos. */
468 complain_overflow_signed, /* complain_on_overflow. */
469 bfd_elf_generic_reloc, /* special_function. */
470 "R_LARCH_ADD32", /* name. */
471 false, /* partial_inplace. */
472 0, /* src_mask */
473 0xffffffff, /* dst_mask */
474 false), /* pcrel_offset. */
475
476 HOWTO (R_LARCH_ADD64, /* type (51). */
477 0, /* rightshift. */
478 4, /* size. */
479 64, /* bitsize. */
480 false, /* pc_relative. */
481 0, /* bitpos. */
482 complain_overflow_signed, /* complain_on_overflow. */
483 bfd_elf_generic_reloc, /* special_function. */
484 "R_LARCH_ADD64", /* name. */
485 false, /* partial_inplace. */
486 0, /* src_mask */
487 ALL_ONES, /* dst_mask */
488 false), /* pcrel_offset. */
489
490 HOWTO (R_LARCH_SUB8, /* type (52). */
491 0, /* rightshift. */
492 2, /* size. */
493 8, /* bitsize. */
494 false, /* pc_relative. */
495 0, /* bitpos. */
496 complain_overflow_signed, /* complain_on_overflow. */
497 bfd_elf_generic_reloc, /* special_function. */
498 "R_LARCH_SUB8", /* name. */
499 false, /* partial_inplace. */
500 0, /* src_mask */
501 0xffffffff, /* dst_mask */
502 false), /* pcrel_offset. */
503
504 HOWTO (R_LARCH_SUB16, /* type (53). */
505 0, /* rightshift. */
506 2, /* size. */
507 16, /* bitsize. */
508 false, /* pc_relative. */
509 0, /* bitpos. */
510 complain_overflow_signed, /* complain_on_overflow. */
511 bfd_elf_generic_reloc, /* special_function. */
512 "R_LARCH_SUB16", /* name. */
513 false, /* partial_inplace. */
514 0, /* src_mask */
515 0xffffffff, /* dst_mask */
516 false), /* pcrel_offset. */
517
518 HOWTO (R_LARCH_SUB24, /* type (54). */
519 0, /* rightshift. */
520 2, /* size. */
521 24, /* bitsize. */
522 false, /* pc_relative. */
523 0, /* bitpos. */
524 complain_overflow_signed, /* complain_on_overflow. */
525 bfd_elf_generic_reloc, /* special_function. */
526 "R_LARCH_SUB24", /* name. */
527 false, /* partial_inplace. */
528 0, /* src_mask */
529 0xffffffff, /* dst_mask */
530 false), /* pcrel_offset. */
531
532 HOWTO (R_LARCH_SUB32, /* type (55). */
533 0, /* rightshift. */
534 2, /* size. */
535 32, /* bitsize. */
536 false, /* pc_relative. */
537 0, /* bitpos. */
538 complain_overflow_signed, /* complain_on_overflow. */
539 bfd_elf_generic_reloc, /* special_function. */
540 "R_LARCH_SUB32", /* name. */
541 false, /* partial_inplace. */
542 0, /* src_mask */
543 0xffffffff, /* dst_mask */
544 false), /* pcrel_offset. */
545
546 HOWTO (R_LARCH_SUB64, /* type (56). */
547 0, /* rightshift. */
548 4, /* size. */
549 64, /* bitsize. */
550 false, /* pc_relative. */
551 0, /* bitpos. */
552 complain_overflow_signed, /* complain_on_overflow. */
553 bfd_elf_generic_reloc, /* special_function. */
554 "R_LARCH_SUB64", /* name. */
555 false, /* partial_inplace. */
556 0, /* src_mask */
557 ALL_ONES, /* dst_mask */
558 false), /* pcrel_offset. */
559
560};
561
562struct elf_reloc_map
563{
564 bfd_reloc_code_real_type bfd_val;
565 enum elf_loongarch_reloc_type elf_val;
566};
567
568static const struct elf_reloc_map larch_reloc_map[] =
569{
570 { BFD_RELOC_NONE, R_LARCH_NONE },
571 { BFD_RELOC_32, R_LARCH_32 },
572 { BFD_RELOC_64, R_LARCH_64 },
573
574#define LOONGARCH_reloc_map(r_name) \
575 { \
576 BFD_RELOC_LARCH_##r_name, R_LARCH_##r_name \
577 }
578 LOONGARCH_reloc_map (TLS_DTPMOD32),
579 LOONGARCH_reloc_map (TLS_DTPMOD64),
580 LOONGARCH_reloc_map (TLS_DTPREL32),
581 LOONGARCH_reloc_map (TLS_DTPREL64),
582 LOONGARCH_reloc_map (TLS_TPREL32),
583 LOONGARCH_reloc_map (TLS_TPREL64),
584
585 LOONGARCH_reloc_map (MARK_LA),
586 LOONGARCH_reloc_map (MARK_PCREL),
587 LOONGARCH_reloc_map (SOP_PUSH_PCREL),
588 LOONGARCH_reloc_map (SOP_PUSH_ABSOLUTE),
589 LOONGARCH_reloc_map (SOP_PUSH_DUP),
590 LOONGARCH_reloc_map (SOP_PUSH_GPREL),
591 LOONGARCH_reloc_map (SOP_PUSH_TLS_TPREL),
592 LOONGARCH_reloc_map (SOP_PUSH_TLS_GOT),
593 LOONGARCH_reloc_map (SOP_PUSH_TLS_GD),
594 LOONGARCH_reloc_map (SOP_PUSH_PLT_PCREL),
595 LOONGARCH_reloc_map (SOP_ASSERT),
596 LOONGARCH_reloc_map (SOP_NOT),
597 LOONGARCH_reloc_map (SOP_SUB),
598 LOONGARCH_reloc_map (SOP_SL),
599 LOONGARCH_reloc_map (SOP_SR),
600 LOONGARCH_reloc_map (SOP_ADD),
601 LOONGARCH_reloc_map (SOP_AND),
602 LOONGARCH_reloc_map (SOP_IF_ELSE),
603 LOONGARCH_reloc_map (SOP_POP_32_S_10_5),
604 LOONGARCH_reloc_map (SOP_POP_32_U_10_12),
605 LOONGARCH_reloc_map (SOP_POP_32_S_10_12),
606 LOONGARCH_reloc_map (SOP_POP_32_S_10_16),
607 LOONGARCH_reloc_map (SOP_POP_32_S_10_16_S2),
608 LOONGARCH_reloc_map (SOP_POP_32_S_5_20),
609 LOONGARCH_reloc_map (SOP_POP_32_S_0_5_10_16_S2),
610 LOONGARCH_reloc_map (SOP_POP_32_S_0_10_10_16_S2),
611 LOONGARCH_reloc_map (SOP_POP_32_U),
612 LOONGARCH_reloc_map (ADD8),
613 LOONGARCH_reloc_map (ADD16),
614 LOONGARCH_reloc_map (ADD24),
615 LOONGARCH_reloc_map (ADD32),
616 LOONGARCH_reloc_map (ADD64),
617 LOONGARCH_reloc_map (SUB8),
618 LOONGARCH_reloc_map (SUB16),
619 LOONGARCH_reloc_map (SUB24),
620 LOONGARCH_reloc_map (SUB32),
621 LOONGARCH_reloc_map (SUB64),
622};
623
624reloc_howto_type *
625loongarch_elf_rtype_to_howto (bfd *abfd, unsigned int r_type)
626{
627 size_t i;
628 for (i = 0; i < ARRAY_SIZE (howto_table); i++)
629 if (howto_table[i].type == r_type)
630 return &howto_table[i];
631
632 (*_bfd_error_handler) (_("%pB: unsupported relocation type %#x"),
633 abfd, r_type);
634 bfd_set_error (bfd_error_bad_value);
635 return NULL;
636}
637
638reloc_howto_type *
639loongarch_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
640 bfd_reloc_code_real_type code)
641{
642 unsigned int i;
643 for (i = 0; i < ARRAY_SIZE (larch_reloc_map); i++)
644 if (larch_reloc_map[i].bfd_val == code)
645 return loongarch_elf_rtype_to_howto (abfd,
646 (int) larch_reloc_map[i].elf_val);
647
648 return NULL;
649}
650
651reloc_howto_type *
652loongarch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
653{
654 unsigned int i;
655
656 for (i = 0; i < ARRAY_SIZE (howto_table); i++)
657 if (howto_table[i].name && strcasecmp (howto_table[i].name, r_name) == 0)
658 return &howto_table[i];
659
660 return NULL;
661}