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