]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/elfxx-loongarch.c
[gdb/tdep] Fix ARM_LINUX_JB_PC_EABI
[thirdparty/binutils-gdb.git] / bfd / elfxx-loongarch.c
CommitLineData
e214f8db 1/* LoongArch-specific support for ELF.
fd67aa11 2 Copyright (C) 2021-2024 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
748594bc 32typedef struct loongarch_reloc_howto_type_struct
33{
34 /* The first must be reloc_howto_type! */
35 reloc_howto_type howto;
36 bfd_reloc_code_real_type bfd_type;
1b6fccd2 37 bool (*adjust_reloc_bits)(bfd *, reloc_howto_type *, bfd_vma *);
6d13722a 38 const char *larch_reloc_type_name;
39} loongarch_reloc_howto_type;
748594bc 40
41#define LOONGARCH_DEFAULT_HOWTO(r_name) \
c94cb026 42 { HOWTO (R_LARCH_##r_name, 0, 4, 32, false, 0, complain_overflow_signed, \
748594bc 43 bfd_elf_generic_reloc, "R_LARCH_" #r_name, false, 0, ALL_ONES, \
6d13722a 44 false), BFD_RELOC_LARCH_##r_name, NULL, NULL }
748594bc 45
46#define LOONGARCH_HOWTO(type, right, size, bits, pcrel, left, ovf, func, \
6d13722a 47 name, inplace, src_mask, dst_mask, pcrel_off, btype, afunc,lname) \
748594bc 48 { HOWTO(type, right, size, bits, pcrel, left, ovf, func, name, \
6d13722a 49 inplace, src_mask, dst_mask, pcrel_off), btype, afunc, lname }
748594bc 50
51#define LOONGARCH_EMPTY_HOWTO(C) \
6d13722a 52 { EMPTY_HOWTO (C), BFD_RELOC_NONE, NULL, NULL }
748594bc 53
6d13722a 54static bool
1b6fccd2 55reloc_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *val);
6d13722a 56static bool
a38b0c05 57reloc_sign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val);
b98da858
JH
58static bool
59reloc_unsign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val);
1b6fccd2 60
61static bfd_reloc_status_type
62loongarch_elf_add_sub_reloc (bfd *, arelent *, asymbol *, void *,
63 asection *, bfd *, char **);
64
65static bfd_reloc_status_type
66loongarch_elf_add_sub_reloc_uleb128 (bfd *, arelent *, asymbol *, void *,
67 asection *, bfd *, char **);
748594bc 68
e214f8db 69/* This does not include any relocation information, but should be
70 good enough for GDB or objdump to read the file. */
748594bc 71static loongarch_reloc_howto_type loongarch_howto_table[] =
e214f8db 72{
e214f8db 73 /* No relocation. */
748594bc 74 LOONGARCH_HOWTO (R_LARCH_NONE, /* type (0). */
75 0, /* rightshift */
c94cb026 76 0, /* size */
748594bc 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 */
6d13722a 88 NULL, /* adjust_reloc_bits */
89 NULL), /* larch_reloc_type_name */
e214f8db 90
91 /* 32 bit relocation. */
748594bc 92 LOONGARCH_HOWTO (R_LARCH_32, /* type (1). */
93 0, /* rightshift */
c94cb026 94 4, /* size */
748594bc 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 */
6d13722a 106 NULL, /* adjust_reloc_bits */
107 NULL), /* larch_reloc_type_name */
e214f8db 108
109 /* 64 bit relocation. */
748594bc 110 LOONGARCH_HOWTO (R_LARCH_64, /* type (2). */
111 0, /* rightshift */
c94cb026 112 8, /* size */
748594bc 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 */
6d13722a 124 NULL, /* adjust_reloc_bits */
125 NULL), /* larch_reloc_type_name */
748594bc 126
127 LOONGARCH_HOWTO (R_LARCH_RELATIVE, /* type (3). */
128 0, /* rightshift */
c94cb026 129 4, /* size */
748594bc 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? */
6d13722a 141 NULL, /* adjust_reloc_bits */
142 NULL), /* larch_reloc_type_name */
748594bc 143
144 LOONGARCH_HOWTO (R_LARCH_COPY, /* type (4). */
145 0, /* rightshift */
5d0feb98 146 0, /* this one is variable size */
748594bc 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 */
6d13722a 157 BFD_RELOC_NONE, /* undefined? */
158 NULL, /* adjust_reloc_bits */
159 NULL), /* larch_reloc_type_name */
748594bc 160
161 LOONGARCH_HOWTO (R_LARCH_JUMP_SLOT, /* type (5). */
162 0, /* rightshift */
c94cb026 163 8, /* size */
748594bc 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 */
6d13722a 174 BFD_RELOC_NONE, /* undefined? */
175 NULL, /* adjust_reloc_bits */
176 NULL), /* larch_reloc_type_name */
e214f8db 177
178 /* Dynamic TLS relocations. */
748594bc 179 LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD32, /* type (6). */
180 0, /* rightshift */
c94cb026 181 4, /* size */
748594bc 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 */
6d13722a 193 NULL, /* adjust_reloc_bits */
194 NULL), /* larch_reloc_type_name */
748594bc 195
196 LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD64, /* type (7). */
197 0, /* rightshift */
c94cb026 198 8, /* size */
748594bc 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 */
6d13722a 210 NULL, /* adjust_reloc_bits */
211 NULL), /* larch_reloc_type_name */
748594bc 212
213 LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL32, /* type (8). */
214 0, /* rightshift */
c94cb026 215 4, /* size */
748594bc 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 */
6d13722a 227 NULL, /* adjust_reloc_bits */
228 NULL), /* larch_reloc_type_name */
748594bc 229
230 LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL64, /* type (9). */
231 0, /* rightshift */
c94cb026 232 8, /* size */
748594bc 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 */
6d13722a 244 NULL, /* adjust_reloc_bits */
245 NULL), /* larch_reloc_type_name */
748594bc 246
247 LOONGARCH_HOWTO (R_LARCH_TLS_TPREL32, /* type (10). */
248 0, /* rightshift */
c94cb026 249 4, /* size */
748594bc 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 */
6d13722a 261 NULL, /* adjust_reloc_bits */
262 NULL), /* larch_reloc_type_name */
748594bc 263
264 LOONGARCH_HOWTO (R_LARCH_TLS_TPREL64, /* type (11). */
265 0, /* rightshift */
c94cb026 266 8, /* size */
748594bc 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 */
6d13722a 278 NULL, /* adjust_reloc_bits */
279 NULL), /* larch_reloc_type_name */
748594bc 280
281 LOONGARCH_HOWTO (R_LARCH_IRELATIVE, /* type (12). */
282 0, /* rightshift */
6ae2890f 283 8, /* size */
284 64, /* bitsize */
748594bc 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? */
6d13722a 295 NULL, /* adjust_reloc_bits */
296 NULL), /* larch_reloc_type_name */
748594bc 297
26265e7f
LC
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. */
314
315 LOONGARCH_HOWTO (R_LARCH_TLS_DESC64, /* type (14). */
316 0, /* rightshift. */
6ae2890f 317 8, /* size. */
26265e7f
LC
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. */
331
6d13722a 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),
748594bc 337
338 LOONGARCH_HOWTO (R_LARCH_MARK_LA, /* type (20). */
6d13722a 339 0, /* rightshift. */
340 0, /* size. */
341 0, /* bitsize. */
e214f8db 342 false, /* pc_relative. */
6d13722a 343 0, /* bitpos. */
344 complain_overflow_signed, /* complain_on_overflow. */
345 bfd_elf_generic_reloc, /* special_function. */
e214f8db 346 "R_LARCH_MARK_LA", /* name. */
6d13722a 347 false, /* partial_inplace. */
e214f8db 348 0, /* src_mask. */
349 0, /* dst_mask. */
748594bc 350 false, /* pcrel_offset */
351 BFD_RELOC_LARCH_MARK_LA, /* bfd_reloc_code_real_type */
6d13722a 352 NULL, /* adjust_reloc_bits */
353 NULL), /* larch_reloc_type_name */
e214f8db 354
748594bc 355 LOONGARCH_HOWTO (R_LARCH_MARK_PCREL, /* type (21). */
6d13722a 356 0, /* rightshift. */
357 0, /* size. */
358 0, /* bitsize. */
e214f8db 359 false, /* pc_relative. */
6d13722a 360 0, /* bitpos. */
361 complain_overflow_signed, /* complain_on_overflow. */
362 bfd_elf_generic_reloc, /* special_function. */
e214f8db 363 "R_LARCH_MARK_PCREL", /* name. */
6d13722a 364 false, /* partial_inplace. */
e214f8db 365 0, /* src_mask. */
366 0, /* dst_mask. */
748594bc 367 false, /* pcrel_offset */
368 BFD_RELOC_LARCH_MARK_PCREL, /* bfd_reloc_code_real_type */
6d13722a 369 NULL, /* adjust_reloc_bits */
370 NULL), /* larch_reloc_type_name */
e214f8db 371
748594bc 372 LOONGARCH_HOWTO (R_LARCH_SOP_PUSH_PCREL, /* type (22). */
6d13722a 373 2, /* rightshift. */
374 4, /* size. */
375 32, /* bitsize. */
e214f8db 376 true /* FIXME: somewhat use this. */, /* pc_relative. */
6d13722a 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. */
748594bc 382 0x03ffffff, /* src_mask. */
383 0x03ffffff, /* dst_mask. */
384 false, /* pcrel_offset */
385 BFD_RELOC_LARCH_SOP_PUSH_PCREL, /* bfd_reloc_code_real_type */
6d13722a 386 NULL, /* adjust_reloc_bits */
387 NULL), /* larch_reloc_type_name */
e214f8db 388
389 /* type 23-37. */
748594bc 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),
405
406 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_5, /* type (38). */
6d13722a 407 0, /* rightshift. */
408 4, /* size. */
409 5, /* bitsize. */
748594bc 410 false, /* pc_relative. */
6d13722a 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. */
748594bc 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 */
b98da858 420 reloc_sign_bits, /* adjust_reloc_bits */
6d13722a 421 NULL), /* larch_reloc_type_name */
748594bc 422
423 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U_10_12, /* type (39). */
6d13722a 424 0, /* rightshift. */
425 4, /* size. */
426 12, /* bitsize. */
748594bc 427 false, /* pc_relative. */
6d13722a 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. */
748594bc 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 */
b98da858 437 reloc_unsign_bits, /* adjust_reloc_bits */
6d13722a 438 NULL), /* larch_reloc_type_name */
748594bc 439
440 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_12, /* type (40). */
6d13722a 441 0, /* rightshift. */
442 4, /* size. */
443 12, /* bitsize. */
748594bc 444 false, /* pc_relative. */
6d13722a 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. */
748594bc 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 */
b98da858 454 reloc_sign_bits, /* adjust_reloc_bits */
6d13722a 455 NULL), /* larch_reloc_type_name */
748594bc 456
457 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16, /* type (41). */
6d13722a 458 0, /* rightshift. */
459 4, /* size. */
460 16, /* bitsize. */
748594bc 461 false, /* pc_relative. */
6d13722a 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. */
748594bc 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 */
b98da858 471 reloc_sign_bits, /* adjust_reloc_bits */
6d13722a 472 NULL), /* larch_reloc_type_name */
748594bc 473
474 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16_S2, /* type (42). */
475 2, /* rightshift. */
6d13722a 476 4, /* size. */
477 16, /* bitsize. */
748594bc 478 false, /* pc_relative. */
6d13722a 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. */
748594bc 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 */
a38b0c05 488 reloc_sign_bits, /* adjust_reloc_bits */
6d13722a 489 NULL), /* larch_reloc_type_name */
748594bc 490
491 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_5_20, /* type (43). */
6d13722a 492 0, /* rightshift. */
493 4, /* size. */
494 20, /* bitsize. */
748594bc 495 false, /* pc_relative. */
6d13722a 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. */
748594bc 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 */
b98da858 505 reloc_sign_bits, /* adjust_reloc_bits */
6d13722a 506 NULL), /* larch_reloc_type_name */
748594bc 507
508 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_5_10_16_S2,
509 /* type (44). */
510 2, /* rightshift. */
c94cb026 511 4, /* size. */
6d13722a 512 21, /* bitsize. */
748594bc 513 false, /* pc_relative. */
6d13722a 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. */
6ae2890f 519 0x0, /* src_mask */
520 0x03fffc1f, /* dst_mask */
748594bc 521 false, /* pcrel_offset */
522 BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2,
523 /* bfd_reloc_code_real_type */
a38b0c05 524 reloc_sign_bits, /* adjust_reloc_bits */
6d13722a 525 NULL), /* larch_reloc_type_name */
748594bc 526
527 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_10_10_16_S2, /* type (45). */
6d13722a 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 */
748594bc 539 false, /* pcrel_offset */
540 BFD_RELOC_LARCH_SOP_POP_32_S_0_10_10_16_S2,
541 /* bfd_reloc_code_real_type */
a38b0c05 542 reloc_sign_bits, /* adjust_reloc_bits */
6d13722a 543 NULL), /* larch_reloc_type_name */
e214f8db 544
748594bc 545 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U, /* type (46). */
6d13722a 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. */
29c238c5 553 "R_LARCH_SOP_POP_32_U", /* name. */
6d13722a 554 false, /* partial_inplace. */
748594bc 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 */
b98da858 559 reloc_unsign_bits, /* adjust_reloc_bits */
6d13722a 560 NULL), /* larch_reloc_type_name */
e214f8db 561
1b6fccd2 562 /* 8-bit in-place addition, for local label subtraction. */
6d13722a 563 LOONGARCH_HOWTO (R_LARCH_ADD8, /* type (47). */
564 0, /* rightshift. */
1b6fccd2 565 1, /* size. */
6d13722a 566 8, /* bitsize. */
e214f8db 567 false, /* pc_relative. */
6d13722a 568 0, /* bitpos. */
1b6fccd2 569 complain_overflow_dont, /* complain_on_overflow. */
570 loongarch_elf_add_sub_reloc, /* special_function. */
6d13722a 571 "R_LARCH_ADD8", /* name. */
572 false, /* partial_inplace. */
1b6fccd2 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. */
e214f8db 579
1b6fccd2 580 /* 16-bit in-place addition, for local label subtraction. */
6d13722a 581 LOONGARCH_HOWTO (R_LARCH_ADD16, /* type (48). */
582 0, /* rightshift. */
1b6fccd2 583 2, /* size. */
6d13722a 584 16, /* bitsize. */
e214f8db 585 false, /* pc_relative. */
6d13722a 586 0, /* bitpos. */
1b6fccd2 587 complain_overflow_dont, /* complain_on_overflow. */
588 loongarch_elf_add_sub_reloc, /* special_function. */
6d13722a 589 "R_LARCH_ADD16", /* name. */
590 false, /* partial_inplace. */
1b6fccd2 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. */
e214f8db 597
1b6fccd2 598 /* 24-bit in-place addition, for local label subtraction. */
6d13722a 599 LOONGARCH_HOWTO (R_LARCH_ADD24, /* type (49). */
600 0, /* rightshift. */
1b6fccd2 601 3, /* size. */
6d13722a 602 24, /* bitsize. */
e214f8db 603 false, /* pc_relative. */
6d13722a 604 0, /* bitpos. */
1b6fccd2 605 complain_overflow_dont, /* complain_on_overflow. */
606 loongarch_elf_add_sub_reloc, /* special_function. */
6d13722a 607 "R_LARCH_ADD24", /* name. */
608 false, /* partial_inplace. */
1b6fccd2 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. */
e214f8db 615
1b6fccd2 616 /* 32-bit in-place addition, for local label subtraction. */
6d13722a 617 LOONGARCH_HOWTO (R_LARCH_ADD32, /* type (50). */
618 0, /* rightshift. */
619 4, /* size. */
620 32, /* bitsize. */
e214f8db 621 false, /* pc_relative. */
6d13722a 622 0, /* bitpos. */
1b6fccd2 623 complain_overflow_dont, /* complain_on_overflow. */
624 loongarch_elf_add_sub_reloc, /* special_function. */
6d13722a 625 "R_LARCH_ADD32", /* name. */
626 false, /* partial_inplace. */
1b6fccd2 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. */
e214f8db 633
1b6fccd2 634 /* 64-bit in-place addition, for local label subtraction. */
6d13722a 635 LOONGARCH_HOWTO (R_LARCH_ADD64, /* type (51). */
636 0, /* rightshift. */
637 8, /* size. */
638 64, /* bitsize. */
e214f8db 639 false, /* pc_relative. */
6d13722a 640 0, /* bitpos. */
1b6fccd2 641 complain_overflow_dont, /* complain_on_overflow. */
642 loongarch_elf_add_sub_reloc, /* special_function. */
6d13722a 643 "R_LARCH_ADD64", /* name. */
644 false, /* partial_inplace. */
1b6fccd2 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. */
e214f8db 651
1b6fccd2 652 /* 8-bit in-place subtraction, for local label subtraction. */
6d13722a 653 LOONGARCH_HOWTO (R_LARCH_SUB8, /* type (52). */
654 0, /* rightshift. */
1b6fccd2 655 1, /* size. */
6d13722a 656 8, /* bitsize. */
e214f8db 657 false, /* pc_relative. */
6d13722a 658 0, /* bitpos. */
1b6fccd2 659 complain_overflow_dont, /* complain_on_overflow. */
660 loongarch_elf_add_sub_reloc, /* special_function. */
6d13722a 661 "R_LARCH_SUB8", /* name. */
662 false, /* partial_inplace. */
1b6fccd2 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. */
e214f8db 669
1b6fccd2 670 /* 16-bit in-place subtraction, for local label subtraction. */
6d13722a 671 LOONGARCH_HOWTO (R_LARCH_SUB16, /* type (53). */
672 0, /* rightshift. */
1b6fccd2 673 2, /* size. */
6d13722a 674 16, /* bitsize. */
e214f8db 675 false, /* pc_relative. */
6d13722a 676 0, /* bitpos. */
1b6fccd2 677 complain_overflow_dont, /* complain_on_overflow. */
678 loongarch_elf_add_sub_reloc, /* special_function. */
6d13722a 679 "R_LARCH_SUB16", /* name. */
680 false, /* partial_inplace. */
1b6fccd2 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. */
e214f8db 687
1b6fccd2 688 /* 24-bit in-place subtraction, for local label subtraction. */
6d13722a 689 LOONGARCH_HOWTO (R_LARCH_SUB24, /* type (54). */
690 0, /* rightshift. */
1b6fccd2 691 3, /* size. */
6d13722a 692 24, /* bitsize. */
e214f8db 693 false, /* pc_relative. */
6d13722a 694 0, /* bitpos. */
1b6fccd2 695 complain_overflow_dont, /* complain_on_overflow. */
696 loongarch_elf_add_sub_reloc, /* special_function. */
6d13722a 697 "R_LARCH_SUB24", /* name. */
698 false, /* partial_inplace. */
1b6fccd2 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. */
e214f8db 705
1b6fccd2 706 /* 32-bit in-place subtraction, for local label subtraction. */
6d13722a 707 LOONGARCH_HOWTO (R_LARCH_SUB32, /* type (55). */
708 0, /* rightshift. */
709 4, /* size. */
710 32, /* bitsize. */
e214f8db 711 false, /* pc_relative. */
6d13722a 712 0, /* bitpos. */
1b6fccd2 713 complain_overflow_dont, /* complain_on_overflow. */
714 loongarch_elf_add_sub_reloc, /* special_function. */
6d13722a 715 "R_LARCH_SUB32", /* name. */
716 false, /* partial_inplace. */
1b6fccd2 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. */
e214f8db 723
1b6fccd2 724 /* 64-bit in-place subtraction, for local label subtraction. */
6d13722a 725 LOONGARCH_HOWTO (R_LARCH_SUB64, /* type (56). */
726 0, /* rightshift. */
727 8, /* size. */
728 64, /* bitsize. */
e214f8db 729 false, /* pc_relative. */
6d13722a 730 0, /* bitpos. */
1b6fccd2 731 complain_overflow_dont, /* complain_on_overflow. */
732 loongarch_elf_add_sub_reloc, /* special_function. */
6d13722a 733 "R_LARCH_SUB64", /* name. */
734 false, /* partial_inplace. */
1b6fccd2 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. */
e214f8db 741
6d13722a 742 LOONGARCH_HOWTO (R_LARCH_GNU_VTINHERIT, /* type (57). */
743 0, /* rightshift. */
744 0, /* size. */
745 0, /* bitsize. */
748594bc 746 false, /* pc_relative. */
6d13722a 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. */
748594bc 752 0, /* src_mask */
753 0, /* dst_mask */
754 false, /* pcrel_offset */
755 BFD_RELOC_NONE, /* bfd_reloc_code_real_type */
6d13722a 756 NULL, /* adjust_reloc_bits */
757 NULL), /* larch_reloc_type_name */
e214f8db 758
6d13722a 759 LOONGARCH_HOWTO (R_LARCH_GNU_VTENTRY, /* type (58). */
760 0, /* rightshift. */
761 0, /* size. */
762 0, /* bitsize. */
748594bc 763 false, /* pc_relative. */
6d13722a 764 0, /* bitpos. */
765 complain_overflow_signed, /* complain_on_overflow. */
748594bc 766 NULL, /* special_function. */
6d13722a 767 "R_LARCH_GNU_VTENTRY", /* name. */
768 false, /* partial_inplace. */
748594bc 769 0, /* src_mask */
770 0, /* dst_mask */
771 false, /* pcrel_offset */
772 BFD_RELOC_NONE, /* bfd_reloc_code_real_type */
6d13722a 773 NULL, /* adjust_reloc_bits */
774 NULL), /* larch_reloc_type_name */
775
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),
781
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. */
1b6fccd2 793 0, /* src_mask. */
794 0x3fffc00, /* dst_mask. */
795 false, /* pcrel_offset. */
796 BFD_RELOC_LARCH_B16, /* bfd_reloc_code_real_type. */
a38b0c05 797 reloc_sign_bits, /* adjust_reloc_bits. */
1b6fccd2 798 "b16"), /* larch_reloc_type_name. */
6d13722a 799
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. */
1b6fccd2 810 0, /* src_mask. */
811 0x3fffc1f, /* dst_mask. */
812 false, /* pcrel_offset. */
813 BFD_RELOC_LARCH_B21, /* bfd_reloc_code_real_type. */
a38b0c05 814 reloc_sign_bits, /* adjust_reloc_bits. */
1b6fccd2 815 "b21"), /* larch_reloc_type_name. */
6d13722a 816
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. */
1b6fccd2 827 0, /* src_mask. */
828 0x03ffffff, /* dst_mask. */
829 false, /* pcrel_offset. */
830 BFD_RELOC_LARCH_B26, /* bfd_reloc_code_real_type. */
a38b0c05 831 reloc_sign_bits, /* adjust_reloc_bits. */
1b6fccd2 832 "b26"), /* larch_reloc_type_name. */
6d13722a 833
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 */
850
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 */
867
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 */
884
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 */
901
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 */
918
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 */
935
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 */
952
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 */
969
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 */
986
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 */
1003
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 */
1020
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 */
1037
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 */
1054
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 */
1071
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 */
1088
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 */
1105
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 */
1122
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. */
1b6fccd2 1129 complain_overflow_unsigned, /* complain_on_overflow. */
6d13722a 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 */
1139
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 */
1156
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 */
1173
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 */
1190
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. */
1b6fccd2 1197 complain_overflow_signed, /* complain_on_overflow. */
6d13722a 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 */
1207
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 */
1224
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 */
1241
1b6fccd2 1242 LOONGARCH_HOWTO (R_LARCH_TLS_IE_HI20, /* type (91). */
6d13722a 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 */
1258
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 */
1275
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 */
1292
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 */
1309
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 */
1326
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 */
1343
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 */
1360
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 */
1377
1b6fccd2 1378 /* 32-bit PC relative. */
98011207 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. */
1b6fccd2 1385 complain_overflow_signed, /* complain_on_overflow. */
98011207 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 */
1395
1b6fccd2 1396 /* The paired relocation may be relaxed. */
98011207 1397 LOONGARCH_HOWTO (R_LARCH_RELAX, /* type (100). */
6d13722a 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 */
1413
1b6fccd2 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. */
1431
c3d507ab 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. */
1b6fccd2 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. */
1455
f07dd5f7 1456 /* For pcaddi and pcala_hi20 + pcala_lo12 can relax to pcrel_20. */
1b6fccd2 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. */
a38b0c05 1471 reloc_sign_bits, /* adjust_reloc_bits. */
f07dd5f7 1472 "pcrel_20"), /* larch_reloc_type_name. */
1b6fccd2 1473
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. */
1491
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. */
1510
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. */
1529
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. */
1549
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. */
1569
be1ebb67 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 */
1587
dc5f359e 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. */
26265e7f
LC
1606
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. */
1624
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. */
1641
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. */
1659
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. */
1676
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. */
1694
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. */
1711
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. */
1729
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. */
1746
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. */
1763
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. */
ae296cc4 1780
aae8784c 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. */
1797
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. */
1814
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. */
3bb1944a 1831
ae296cc4 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. */
1849
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. */
1867
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. */
e214f8db 1885};
1886
1887reloc_howto_type *
1888loongarch_elf_rtype_to_howto (bfd *abfd, unsigned int r_type)
1889{
3bb1944a 1890 if (r_type < R_LARCH_count)
748594bc 1891 {
748594bc 1892 BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count);
3bb1944a
AM
1893 BFD_ASSERT (loongarch_howto_table[r_type].howto.type == r_type);
1894 return &loongarch_howto_table[r_type].howto;
748594bc 1895 }
e214f8db 1896
1897 (*_bfd_error_handler) (_("%pB: unsupported relocation type %#x"),
1898 abfd, r_type);
1899 bfd_set_error (bfd_error_bad_value);
1900 return NULL;
1901}
1902
1903reloc_howto_type *
748594bc 1904loongarch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
e214f8db 1905{
748594bc 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)
3bb1944a 1909 return &loongarch_howto_table[i].howto;
748594bc 1910
1911 (*_bfd_error_handler) (_("%pB: unsupported relocation type %s"),
1912 abfd, r_name);
1913 bfd_set_error (bfd_error_bad_value);
e214f8db 1914 return NULL;
1915}
1916
748594bc 1917/* Cost so much. */
e214f8db 1918reloc_howto_type *
748594bc 1919loongarch_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1920 bfd_reloc_code_real_type code)
e214f8db 1921{
748594bc 1922 BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count);
e214f8db 1923
6d13722a 1924 /* Fast search for new reloc types. */
1925 if (BFD_RELOC_LARCH_B16 <= code && code < BFD_RELOC_LARCH_RELAX)
1926 {
1927 BFD_ASSERT (BFD_RELOC_LARCH_RELAX - BFD_RELOC_LARCH_B16
1928 == R_LARCH_RELAX - R_LARCH_B16);
3bb1944a 1929 loongarch_reloc_howto_type *ht;
6d13722a 1930 ht = &loongarch_howto_table[code - BFD_RELOC_LARCH_B16 + R_LARCH_B16];
1931 BFD_ASSERT (ht->bfd_type == code);
3bb1944a 1932 return &ht->howto;
6d13722a 1933 }
1934
748594bc 1935 for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++)
1936 if (loongarch_howto_table[i].bfd_type == code)
3bb1944a 1937 return &loongarch_howto_table[i].howto;
748594bc 1938
1939 (*_bfd_error_handler) (_("%pB: unsupported bfd relocation type %#x"),
1940 abfd, code);
1941 bfd_set_error (bfd_error_bad_value);
e214f8db 1942 return NULL;
1943}
748594bc 1944
6d13722a 1945bfd_reloc_code_real_type
1946loongarch_larch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1947 const char *l_r_name)
1948{
1949 for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++)
1950 {
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;
1955 }
1956
6d13722a 1957 return BFD_RELOC_NONE;
1958}
1959
1960
1961/* Functions for reloc bits field.
1962 1. Signed extend *fix_val.
1963 2. Return false if overflow. */
1964
748594bc 1965#define LARCH_RELOC_BFD_VMA_BIT_MASK(bitsize) \
1966 (~((((bfd_vma)0x1) << (bitsize)) - 1))
1967
1968/* Adjust val to perform insn
6d13722a 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. */
1b6fccd2 1975
1976static bool
1977reloc_bits (bfd *abfd ATTRIBUTE_UNUSED,
1978 reloc_howto_type *howto,
1979 bfd_vma *fix_val)
1980{
1981 bfd_signed_vma val = (bfd_signed_vma)(*fix_val);
1982 bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1;
1983
1984 val = val >> howto->rightshift;
1985
1986 /* Perform insn bits field. */
1987 val = val & mask;
1988 val <<= howto->bitpos;
1989
1990 *fix_val = (bfd_vma)val;
1991
1992 return true;
1993}
1994
6d13722a 1995static bool
b98da858
JH
1996reloc_bits_sanity (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val,
1997 unsigned int sign)
748594bc 1998{
b98da858
JH
1999 if ((sign && howto->complain_on_overflow != complain_overflow_signed)
2000 || (!sign && howto->complain_on_overflow != complain_overflow_unsigned))
a38b0c05 2001 return false;
2002
1b6fccd2 2003 bfd_signed_vma val = (bfd_signed_vma)(*fix_val);
1b6fccd2 2004
a38b0c05 2005 /* Check alignment. FIXME: if rightshift is not alingment. */
1b6fccd2 2006 if (howto->rightshift
2007 && (val & ((((bfd_signed_vma) 1) << howto->rightshift) - 1)))
2008 {
f87cf663
LC
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)
2012 {
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);
2016 }
1b6fccd2 2017 return false;
2018 }
2019
a38b0c05 2020 bfd_signed_vma mask = ((bfd_signed_vma)0x1 << (howto->bitsize
b98da858 2021 + howto->rightshift - sign)) - 1;
1b6fccd2 2022
a38b0c05 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. */
1b6fccd2 2026 if ((val & ~mask) && ((val & ~mask) != ~mask))
2027 {
f87cf663
LC
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)
2031 {
2032 (*_bfd_error_handler) (_("%pB: relocation %s overflow 0x%lx"),
2033 abfd, howto->name, (long) val);
2034 bfd_set_error (bfd_error_bad_value);
2035 }
1b6fccd2 2036 return false;
2037 }
6d13722a 2038
1b6fccd2 2039 val = val >> howto->rightshift;
a38b0c05 2040 /* can delete? */
2041 mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1;
1b6fccd2 2042 val = val & mask;
748594bc 2043
a38b0c05 2044 switch (howto->type)
748594bc 2045 {
a38b0c05 2046 case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
2047 case R_LARCH_B26:
b5c37946 2048 /* Perform insn bits field. 15:0<<10, 25:16>>16. */
a38b0c05 2049 val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff);
2050 break;
b5c37946 2051 case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
a38b0c05 2052 case R_LARCH_B21:
b5c37946 2053 /* Perform insn bits field. 15:0<<10, 20:16>>16. */
a38b0c05 2054 val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f);
2055 break;
dc5f359e 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;
a38b0c05 2062 default:
2063 val <<= howto->bitpos;
2064 break;
748594bc 2065 }
2066
748594bc 2067 *fix_val = val;
748594bc 2068 return true;
2069}
2070
b98da858
JH
2071static bool
2072reloc_sign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val)
2073{
2074 return reloc_bits_sanity (abfd, howto, fix_val, 1);
2075}
2076
2077static bool
2078reloc_unsign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val)
2079{
2080 return reloc_bits_sanity (abfd, howto, fix_val, 0);
2081}
2082
6d13722a 2083bool
1b6fccd2 2084loongarch_adjust_reloc_bitsfield (bfd *abfd, reloc_howto_type *howto,
6d13722a 2085 bfd_vma *fix_val)
748594bc 2086{
2087 BFD_ASSERT (((loongarch_reloc_howto_type *)howto)->adjust_reloc_bits);
2088 return ((loongarch_reloc_howto_type *)
1b6fccd2 2089 howto)->adjust_reloc_bits (abfd, howto, fix_val);
2090}
2091
2092static bfd_reloc_status_type
2093loongarch_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)
2100{
2101 reloc_howto_type *howto = reloc_entry->howto;
2102 bfd_vma relocation;
2103
2104 if (output_bfd != NULL
2105 && (symbol->flags & BSF_SECTION_SYM) == 0
2106 && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
2107 {
2108 reloc_entry->address += input_section->output_offset;
2109 return bfd_reloc_ok;
2110 }
2111
2112 if (output_bfd != NULL)
2113 return bfd_reloc_continue;
2114
2115 relocation = symbol->value + symbol->section->output_section->vma
2116 + symbol->section->output_offset + reloc_entry->addend;
2117
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;
2123
2124 bfd_vma old_value = bfd_get (howto->bitsize, abfd,
2125 data + reloc_entry->address);
2126
2127 switch (howto->type)
2128 {
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;
2136
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;
2144 }
2145
2146 bfd_put (howto->bitsize, abfd, relocation, data + reloc_entry->address);
2147
2148 return bfd_reloc_ok;
2149}
2150
2151static bfd_reloc_status_type
2152loongarch_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)
2159{
2160 reloc_howto_type *howto = reloc_entry->howto;
2161 bfd_vma relocation;
2162
2163 if (output_bfd != NULL
2164 && (symbol->flags & BSF_SECTION_SYM) == 0
2165 && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
2166 {
2167 reloc_entry->address += input_section->output_offset;
2168 return bfd_reloc_ok;
2169 }
2170
2171 if (output_bfd != NULL)
2172 return bfd_reloc_continue;
2173
2174 relocation = symbol->value + symbol->section->output_section->vma
2175 + symbol->section->output_offset + reloc_entry->addend;
2176
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;
2182
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);
2186
2187 switch (howto->type)
2188 {
2189 case R_LARCH_ADD_ULEB128:
2190 relocation = old_value + relocation;
2191 break;
2192
2193 case R_LARCH_SUB_ULEB128:
2194 relocation = old_value - relocation;
2195 break;
2196 }
2197
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;
2202}
2203
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. */
2207bfd_byte *
2208loongarch_write_unsigned_leb128 (bfd_byte *p, unsigned int len, bfd_vma value)
2209{
2210 bfd_byte c;
2211 do
2212 {
2213 c = value & 0x7f;
2214 if (len > 1)
2215 c |= 0x80;
2216 *(p++) = c;
2217 value >>= 7;
2218 len--;
2219 }
2220 while (len);
2221 return p;
748594bc 2222}
d2fddb6d 2223
2224int loongarch_get_uleb128_length (bfd_byte *buf)
2225{
2226 unsigned int len = 0;
2227 _bfd_read_unsigned_leb128 (NULL, buf, &len);
2228 return len;
2229}