Coverage Report

Created: 2023-08-28 06:25

/src/binutils-gdb/bfd/elfxx-loongarch.c
Line
Count
Source (jump to first uncovered line)
1
/* LoongArch-specific support for ELF.
2
   Copyright (C) 2021-2023 Free Software Foundation, Inc.
3
   Contributed by Loongson Ltd.
4
5
   Based on RISC-V target.
6
7
   This file is part of BFD, the Binary File Descriptor library.
8
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
19
   You should have received a copy of the GNU General Public License
20
   along with this program; see the file COPYING3.  If not,
21
   see <http://www.gnu.org/licenses/>.  */
22
23
#include "sysdep.h"
24
#include "bfd.h"
25
#include "libbfd.h"
26
#include "elf-bfd.h"
27
#include "elf/loongarch.h"
28
#include "elfxx-loongarch.h"
29
30
#define ALL_ONES (~ (bfd_vma) 0)
31
32
typedef 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)(bfd *, reloc_howto_type *, bfd_vma *);
38
  const char *larch_reloc_type_name;
39
} loongarch_reloc_howto_type;
40
41
#define LOONGARCH_DEFAULT_HOWTO(r_name)             \
42
  { HOWTO (R_LARCH_##r_name, 0, 4, 32, false, 0, complain_overflow_signed,  \
43
  bfd_elf_generic_reloc, "R_LARCH_" #r_name, false, 0, ALL_ONES,      \
44
  false), BFD_RELOC_LARCH_##r_name, NULL, NULL }
45
46
#define LOONGARCH_HOWTO(type, right, size, bits, pcrel, left, ovf, func,  \
47
      name, inplace, src_mask, dst_mask, pcrel_off, btype, afunc,lname) \
48
  { HOWTO(type, right, size, bits, pcrel, left, ovf, func, name,    \
49
    inplace, src_mask, dst_mask, pcrel_off), btype, afunc, lname }
50
51
#define LOONGARCH_EMPTY_HOWTO(C) \
52
  { EMPTY_HOWTO (C), BFD_RELOC_NONE, NULL, NULL }
53
54
static bool
55
reloc_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *val);
56
static bool
57
reloc_sign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val);
58
59
static bfd_reloc_status_type
60
loongarch_elf_add_sub_reloc (bfd *, arelent *, asymbol *, void *,
61
            asection *, bfd *, char **);
62
63
static bfd_reloc_status_type
64
loongarch_elf_add_sub_reloc_uleb128 (bfd *, arelent *, asymbol *, void *,
65
              asection *, bfd *, char **);
66
67
/* This does not include any relocation information, but should be
68
   good enough for GDB or objdump to read the file.  */
69
static loongarch_reloc_howto_type loongarch_howto_table[] =
70
{
71
  /* No relocation.  */
72
    LOONGARCH_HOWTO (R_LARCH_NONE,    /* type (0).  */
73
   0,         /* rightshift */
74
   0,         /* size */
75
   0,         /* bitsize */
76
   false,         /* pc_relative */
77
   0,         /* bitpos */
78
   complain_overflow_dont,    /* complain_on_overflow */
79
   bfd_elf_generic_reloc,     /* special_function */
80
   "R_LARCH_NONE",      /* name */
81
   false,         /* partial_inplace */
82
   0,         /* src_mask */
83
   0,         /* dst_mask */
84
   false,         /* pcrel_offset */
85
   BFD_RELOC_NONE,      /* bfd_reloc_code_real_type */
86
   NULL,          /* adjust_reloc_bits */
87
   NULL),         /* larch_reloc_type_name */
88
89
  /* 32 bit relocation.  */
90
  LOONGARCH_HOWTO (R_LARCH_32,      /* type (1).  */
91
   0,         /* rightshift */
92
   4,         /* size */
93
   32,          /* bitsize */
94
   false,         /* pc_relative */
95
   0,         /* bitpos */
96
   complain_overflow_dont,    /* complain_on_overflow */
97
   bfd_elf_generic_reloc,     /* special_function */
98
   "R_LARCH_32",        /* name */
99
   false,         /* partial_inplace */
100
   0,         /* src_mask */
101
   ALL_ONES,        /* dst_mask */
102
   false,         /* pcrel_offset */
103
   BFD_RELOC_32,        /* bfd_reloc_code_real_type */
104
   NULL,          /* adjust_reloc_bits */
105
   NULL),         /* larch_reloc_type_name */
106
107
  /* 64 bit relocation.  */
108
  LOONGARCH_HOWTO (R_LARCH_64,      /* type (2).  */
109
   0,         /* rightshift */
110
   8,         /* size */
111
   64,          /* bitsize */
112
   false,         /* pc_relative */
113
   0,         /* bitpos */
114
   complain_overflow_dont,    /* complain_on_overflow */
115
   bfd_elf_generic_reloc,     /* special_function */
116
   "R_LARCH_64",        /* name */
117
   false,         /* partial_inplace */
118
   0,         /* src_mask */
119
   ALL_ONES,        /* dst_mask */
120
   false,         /* pcrel_offset */
121
   BFD_RELOC_64,        /* bfd_reloc_code_real_type */
122
   NULL,          /* adjust_reloc_bits */
123
   NULL),         /* larch_reloc_type_name */
124
125
  LOONGARCH_HOWTO (R_LARCH_RELATIVE,    /* type (3).  */
126
   0,         /* rightshift */
127
   4,         /* size */
128
   32,          /* bitsize */
129
   false,         /* pc_relative */
130
   0,         /* bitpos */
131
   complain_overflow_dont,    /* complain_on_overflow */
132
   bfd_elf_generic_reloc,     /* special_function */
133
   "R_LARCH_RELATIVE",      /* name */
134
   false,         /* partial_inplace */
135
   0,         /* src_mask */
136
   ALL_ONES,        /* dst_mask */
137
   false,         /* pcrel_offset */
138
   BFD_RELOC_NONE,      /* undefined?  */
139
   NULL,          /* adjust_reloc_bits */
140
   NULL),         /* larch_reloc_type_name */
141
142
  LOONGARCH_HOWTO (R_LARCH_COPY,    /* type (4).  */
143
   0,         /* rightshift */
144
   0,         /* this one is variable size */
145
   0,         /* bitsize */
146
   false,         /* pc_relative */
147
   0,         /* bitpos */
148
   complain_overflow_bitfield,    /* complain_on_overflow */
149
   bfd_elf_generic_reloc,     /* special_function */
150
   "R_LARCH_COPY",      /* name */
151
   false,         /* partial_inplace */
152
   0,         /* src_mask */
153
   0,         /* dst_mask */
154
   false,         /* pcrel_offset */
155
   BFD_RELOC_NONE,      /* undefined?  */
156
   NULL,          /* adjust_reloc_bits */
157
   NULL),         /* larch_reloc_type_name */
158
159
  LOONGARCH_HOWTO (R_LARCH_JUMP_SLOT,   /* type (5).  */
160
   0,         /* rightshift */
161
   8,         /* size */
162
   64,          /* bitsize */
163
   false,         /* pc_relative */
164
   0,         /* bitpos */
165
   complain_overflow_bitfield,    /* complain_on_overflow */
166
   bfd_elf_generic_reloc,     /* special_function */
167
   "R_LARCH_JUMP_SLOT",     /* name */
168
   false,         /* partial_inplace */
169
   0,         /* src_mask */
170
   0,         /* dst_mask */
171
   false,         /* pcrel_offset */
172
   BFD_RELOC_NONE,      /* undefined?  */
173
   NULL,          /* adjust_reloc_bits */
174
   NULL),         /* larch_reloc_type_name */
175
176
  /* Dynamic TLS relocations.  */
177
  LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD32,  /* type (6).  */
178
   0,         /* rightshift */
179
   4,         /* size */
180
   32,          /* bitsize */
181
   false,         /* pc_relative */
182
   0,         /* bitpos */
183
   complain_overflow_dont,    /* complain_on_overflow */
184
   bfd_elf_generic_reloc,     /* special_function */
185
   "R_LARCH_TLS_DTPMOD32",    /* name */
186
   false,         /* partial_inplace */
187
   0,         /* src_mask */
188
   ALL_ONES,        /* dst_mask */
189
   false,         /* pcrel_offset */
190
   BFD_RELOC_LARCH_TLS_DTPMOD32,    /* bfd_reloc_code_real_type */
191
   NULL,          /* adjust_reloc_bits */
192
   NULL),         /* larch_reloc_type_name */
193
194
  LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD64,  /* type (7).  */
195
   0,         /* rightshift */
196
   8,         /* size */
197
   64,          /* bitsize */
198
   false,         /* pc_relative */
199
   0,         /* bitpos */
200
   complain_overflow_dont,    /* complain_on_overflow */
201
   bfd_elf_generic_reloc,     /* special_function */
202
   "R_LARCH_TLS_DTPMOD64",    /* name */
203
   false,         /* partial_inplace */
204
   0,         /* src_mask */
205
   ALL_ONES,        /* dst_mask */
206
   false,         /* pcrel_offset */
207
   BFD_RELOC_LARCH_TLS_DTPMOD64,    /* bfd_reloc_code_real_type */
208
   NULL,          /* adjust_reloc_bits */
209
   NULL),         /* larch_reloc_type_name */
210
211
  LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL32,  /* type (8). */
212
   0,         /* rightshift */
213
   4,         /* size */
214
   32,          /* bitsize */
215
   false,         /* pc_relative */
216
   0,         /* bitpos */
217
   complain_overflow_dont,    /* complain_on_overflow */
218
   bfd_elf_generic_reloc,     /* special_function */
219
   "R_LARCH_TLS_DTPREL32",    /* name */
220
   true,          /* partial_inplace */
221
   0,         /* src_mask */
222
   ALL_ONES,        /* dst_mask */
223
   false,         /* pcrel_offset */
224
   BFD_RELOC_LARCH_TLS_DTPREL32,    /* bfd_reloc_code_real_type */
225
   NULL,          /* adjust_reloc_bits */
226
   NULL),         /* larch_reloc_type_name */
227
228
  LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL64,  /* type (9).  */
229
   0,         /* rightshift */
230
   8,         /* size */
231
   64,          /* bitsize */
232
   false,         /* pc_relative */
233
   0,         /* bitpos */
234
   complain_overflow_dont,    /* complain_on_overflow */
235
   bfd_elf_generic_reloc,     /* special_function */
236
   "R_LARCH_TLS_DTPREL64",    /* name */
237
   true,          /* partial_inplace */
238
   0,         /* src_mask */
239
   ALL_ONES,        /* dst_mask */
240
   false,         /* pcrel_offset */
241
   BFD_RELOC_LARCH_TLS_DTPREL64,    /* bfd_reloc_code_real_type */
242
   NULL,          /* adjust_reloc_bits */
243
   NULL),         /* larch_reloc_type_name */
244
245
  LOONGARCH_HOWTO (R_LARCH_TLS_TPREL32,   /* type (10).  */
246
   0,         /* rightshift */
247
   4,         /* size */
248
   32,          /* bitsize */
249
   false,         /* pc_relative */
250
   0,         /* bitpos */
251
   complain_overflow_dont,    /* complain_on_overflow */
252
   bfd_elf_generic_reloc,     /* special_function */
253
   "R_LARCH_TLS_TPREL32",     /* name */
254
   false,         /* partial_inplace */
255
   0,         /* src_mask */
256
   ALL_ONES,        /* dst_mask */
257
   false,         /* pcrel_offset */
258
   BFD_RELOC_LARCH_TLS_TPREL32,   /* bfd_reloc_code_real_type */
259
   NULL,          /* adjust_reloc_bits */
260
   NULL),         /* larch_reloc_type_name */
261
262
  LOONGARCH_HOWTO (R_LARCH_TLS_TPREL64,   /* type (11).  */
263
   0,         /* rightshift */
264
   8,         /* size */
265
   64,          /* bitsize */
266
   false,         /* pc_relative */
267
   0,         /* bitpos */
268
   complain_overflow_dont,    /* complain_on_overflow */
269
   bfd_elf_generic_reloc,     /* special_function */
270
   "R_LARCH_TLS_TPREL64",     /* name */
271
   false,         /* partial_inplace */
272
   0,         /* src_mask */
273
   ALL_ONES,        /* dst_mask */
274
   false,         /* pcrel_offset */
275
   BFD_RELOC_LARCH_TLS_TPREL64,   /* bfd_reloc_code_real_type */
276
   NULL,          /* adjust_reloc_bits */
277
   NULL),         /* larch_reloc_type_name */
278
279
  LOONGARCH_HOWTO (R_LARCH_IRELATIVE,   /* type (12).  */
280
   0,         /* rightshift */
281
   4,         /* size */
282
   32,          /* bitsize */
283
   false,         /* pc_relative */
284
   0,         /* bitpos */
285
   complain_overflow_dont,    /* complain_on_overflow */
286
   bfd_elf_generic_reloc,     /* special_function */
287
   "R_LARCH_IRELATIVE",     /* name */
288
   false,         /* partial_inplace */
289
   0,         /* src_mask */
290
   ALL_ONES,        /* dst_mask */
291
   false,         /* pcrel_offset */
292
   BFD_RELOC_NONE,      /* undefined?  */
293
   NULL,          /* adjust_reloc_bits */
294
   NULL),         /* larch_reloc_type_name */
295
296
  LOONGARCH_EMPTY_HOWTO (13),
297
  LOONGARCH_EMPTY_HOWTO (14),
298
  LOONGARCH_EMPTY_HOWTO (15),
299
  LOONGARCH_EMPTY_HOWTO (16),
300
  LOONGARCH_EMPTY_HOWTO (17),
301
  LOONGARCH_EMPTY_HOWTO (18),
302
  LOONGARCH_EMPTY_HOWTO (19),
303
304
  LOONGARCH_HOWTO (R_LARCH_MARK_LA,   /* type (20).  */
305
   0,         /* rightshift.  */
306
   0,         /* size.  */
307
   0,         /* bitsize.  */
308
   false,         /* pc_relative.  */
309
   0,         /* bitpos.  */
310
   complain_overflow_signed,    /* complain_on_overflow.  */
311
   bfd_elf_generic_reloc,     /* special_function.  */
312
   "R_LARCH_MARK_LA",     /* name.  */
313
   false,         /* partial_inplace.  */
314
   0,         /* src_mask.  */
315
   0,         /* dst_mask.  */
316
   false,         /* pcrel_offset */
317
   BFD_RELOC_LARCH_MARK_LA,   /* bfd_reloc_code_real_type */
318
   NULL,          /* adjust_reloc_bits */
319
   NULL),         /* larch_reloc_type_name */
320
321
  LOONGARCH_HOWTO (R_LARCH_MARK_PCREL,    /* type (21).  */
322
   0,         /* rightshift.  */
323
   0,         /* size.  */
324
   0,         /* bitsize.  */
325
   false,         /* pc_relative.  */
326
   0,         /* bitpos.  */
327
   complain_overflow_signed,    /* complain_on_overflow.  */
328
   bfd_elf_generic_reloc,     /* special_function.  */
329
   "R_LARCH_MARK_PCREL",      /* name.  */
330
   false,         /* partial_inplace.  */
331
   0,         /* src_mask.  */
332
   0,         /* dst_mask.  */
333
   false,         /* pcrel_offset */
334
   BFD_RELOC_LARCH_MARK_PCREL,    /* bfd_reloc_code_real_type */
335
   NULL,          /* adjust_reloc_bits */
336
   NULL),         /* larch_reloc_type_name */
337
338
  LOONGARCH_HOWTO (R_LARCH_SOP_PUSH_PCREL,  /* type (22).  */
339
   2,         /* rightshift.  */
340
   4,         /* size.  */
341
   32,          /* bitsize.  */
342
   true /* FIXME: somewhat use this.  */, /* pc_relative.  */
343
   0,         /* bitpos.  */
344
   complain_overflow_signed,    /* complain_on_overflow.  */
345
   bfd_elf_generic_reloc,     /* special_function.  */
346
   "R_LARCH_SOP_PUSH_PCREL",    /* name.  */
347
   false,         /* partial_inplace.  */
348
   0x03ffffff,        /* src_mask.  */
349
   0x03ffffff,        /* dst_mask.  */
350
   false,         /* pcrel_offset */
351
   BFD_RELOC_LARCH_SOP_PUSH_PCREL,  /* bfd_reloc_code_real_type */
352
   NULL,          /* adjust_reloc_bits */
353
   NULL),         /* larch_reloc_type_name */
354
355
  /* type 23-37.  */
356
  LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_ABSOLUTE),
357
  LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_DUP),
358
  LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_GPREL),
359
  LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_TLS_TPREL),
360
  LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_TLS_GOT),
361
  LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_TLS_GD),
362
  LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_PLT_PCREL),
363
  LOONGARCH_DEFAULT_HOWTO (SOP_ASSERT),
364
  LOONGARCH_DEFAULT_HOWTO (SOP_NOT),
365
  LOONGARCH_DEFAULT_HOWTO (SOP_SUB),
366
  LOONGARCH_DEFAULT_HOWTO (SOP_SL),
367
  LOONGARCH_DEFAULT_HOWTO (SOP_SR),
368
  LOONGARCH_DEFAULT_HOWTO (SOP_ADD),
369
  LOONGARCH_DEFAULT_HOWTO (SOP_AND),
370
  LOONGARCH_DEFAULT_HOWTO (SOP_IF_ELSE),
371
372
  LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_5,   /* type (38).  */
373
   0,           /* rightshift.  */
374
   4,           /* size.  */
375
   5,           /* bitsize.  */
376
   false,           /* pc_relative.  */
377
   10,            /* bitpos.  */
378
   complain_overflow_signed,      /* complain_on_overflow.  */
379
   bfd_elf_generic_reloc,       /* special_function.  */
380
   "R_LARCH_SOP_POP_32_S_10_5",     /* name.  */
381
   false,           /* partial_inplace.  */
382
   0,           /* src_mask */
383
   0x7c00,          /* dst_mask */
384
   false,           /* pcrel_offset */
385
   BFD_RELOC_LARCH_SOP_POP_32_S_10_5,   /* bfd_reloc_code_real_type */
386
   reloc_bits,          /* adjust_reloc_bits */
387
   NULL),           /* larch_reloc_type_name */
388
389
  LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U_10_12,    /* type (39).  */
390
   0,           /* rightshift.  */
391
   4,           /* size.  */
392
   12,            /* bitsize.  */
393
   false,           /* pc_relative.  */
394
   10,            /* bitpos.  */
395
   complain_overflow_unsigned,      /* complain_on_overflow.  */
396
   bfd_elf_generic_reloc,       /* special_function.  */
397
   "R_LARCH_SOP_POP_32_U_10_12",      /* name.  */
398
   false,           /* partial_inplace.  */
399
   0,           /* src_mask */
400
   0x3ffc00,          /* dst_mask */
401
   false,           /* pcrel_offset */
402
   BFD_RELOC_LARCH_SOP_POP_32_U_10_12,    /* bfd_reloc_code_real_type */
403
   reloc_bits,          /* adjust_reloc_bits */
404
   NULL),           /* larch_reloc_type_name */
405
406
  LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_12,    /* type (40).  */
407
   0,           /* rightshift.  */
408
   4,           /* size.  */
409
   12,            /* bitsize.  */
410
   false,           /* pc_relative.  */
411
   10,            /* bitpos.  */
412
   complain_overflow_signed,      /* complain_on_overflow.  */
413
   bfd_elf_generic_reloc,       /* special_function.  */
414
   "R_LARCH_SOP_POP_32_S_10_12",      /* name.  */
415
   false,           /* partial_inplace.  */
416
   0,           /* src_mask */
417
   0x3ffc00,          /* dst_mask */
418
   false,           /* pcrel_offset */
419
   BFD_RELOC_LARCH_SOP_POP_32_S_10_12,    /* bfd_reloc_code_real_type */
420
   reloc_bits,          /* adjust_reloc_bits */
421
   NULL),           /* larch_reloc_type_name */
422
423
  LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16,    /* type (41).  */
424
   0,           /* rightshift.  */
425
   4,           /* size.  */
426
   16,            /* bitsize.  */
427
   false,           /* pc_relative.  */
428
   10,            /* bitpos.  */
429
   complain_overflow_signed,      /* complain_on_overflow.  */
430
   bfd_elf_generic_reloc,       /* special_function.  */
431
   "R_LARCH_SOP_POP_32_S_10_16",      /* name.  */
432
   false,           /* partial_inplace.  */
433
   0,           /* src_mask */
434
   0x3fffc00,         /* dst_mask */
435
   false,           /* pcrel_offset */
436
   BFD_RELOC_LARCH_SOP_POP_32_S_10_16,    /* bfd_reloc_code_real_type */
437
   reloc_bits,          /* adjust_reloc_bits */
438
   NULL),           /* larch_reloc_type_name */
439
440
  LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16_S2, /* type (42).  */
441
   2,           /* rightshift.  */
442
   4,           /* size.  */
443
   16,            /* bitsize.  */
444
   false,           /* pc_relative.  */
445
   10,            /* bitpos.  */
446
   complain_overflow_signed,      /* complain_on_overflow.  */
447
   bfd_elf_generic_reloc,       /* special_function.  */
448
   "R_LARCH_SOP_POP_32_S_10_16_S2",   /* name.  */
449
   false,           /* partial_inplace.  */
450
   0,           /* src_mask */
451
   0x3fffc00,         /* dst_mask */
452
   false,           /* pcrel_offset */
453
   BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2,   /* bfd_reloc_code_real_type */
454
   reloc_sign_bits,       /* adjust_reloc_bits */
455
   NULL),           /* larch_reloc_type_name */
456
457
  LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_5_20,   /* type (43).  */
458
   0,           /* rightshift.  */
459
   4,           /* size.  */
460
   20,            /* bitsize.  */
461
   false,           /* pc_relative.  */
462
   5,           /* bitpos.  */
463
   complain_overflow_signed,      /* complain_on_overflow.  */
464
   bfd_elf_generic_reloc,       /* special_function.  */
465
   "R_LARCH_SOP_POP_32_S_5_20",     /* name.  */
466
   false,           /* partial_inplace.  */
467
   0,           /* src_mask */
468
   0x1ffffe0,         /* dst_mask */
469
   false,           /* pcrel_offset */
470
   BFD_RELOC_LARCH_SOP_POP_32_S_5_20,   /* bfd_reloc_code_real_type */
471
   reloc_bits,          /* adjust_reloc_bits */
472
   NULL),           /* larch_reloc_type_name */
473
474
  LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_5_10_16_S2,
475
              /* type (44).  */
476
   2,           /* rightshift.  */
477
   4,           /* size.  */
478
   21,            /* bitsize.  */
479
   false,           /* pc_relative.  */
480
   0,           /* bitpos.  */
481
   complain_overflow_signed,      /* complain_on_overflow.  */
482
   bfd_elf_generic_reloc,       /* special_function.  */
483
   "R_LARCH_SOP_POP_32_S_0_5_10_16_S2",   /* name.  */
484
   false,           /* partial_inplace.  */
485
   0xfc0003e0,          /* src_mask */
486
   0xfc0003e0,          /* dst_mask */
487
   false,           /* pcrel_offset */
488
   BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2,
489
              /* bfd_reloc_code_real_type */
490
   reloc_sign_bits,       /* adjust_reloc_bits */
491
   NULL),           /* larch_reloc_type_name */
492
493
  LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_10_10_16_S2,  /* type (45).  */
494
   2,         /* rightshift.  */
495
   4,         /* size.  */
496
   26,          /* bitsize.  */
497
   false,         /* pc_relative.  */
498
   0,         /* bitpos.  */
499
   complain_overflow_signed,    /* complain_on_overflow.  */
500
   bfd_elf_generic_reloc,     /* special_function.  */
501
   "R_LARCH_SOP_POP_32_S_0_10_10_16_S2",  /* name.  */
502
   false,         /* partial_inplace.  */
503
   0,         /* src_mask */
504
   0x03ffffff,        /* dst_mask */
505
   false,         /* pcrel_offset */
506
   BFD_RELOC_LARCH_SOP_POP_32_S_0_10_10_16_S2,
507
            /* bfd_reloc_code_real_type */
508
   reloc_sign_bits,     /* adjust_reloc_bits */
509
   NULL),         /* larch_reloc_type_name */
510
511
  LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U,  /* type (46).  */
512
   0,         /* rightshift.  */
513
   4,         /* size.  */
514
   32,          /* bitsize.  */
515
   false,         /* pc_relative.  */
516
   0,         /* bitpos.  */
517
   complain_overflow_unsigned,    /* complain_on_overflow.  */
518
   bfd_elf_generic_reloc,     /* special_function.  */
519
   "R_LARCH_SOP_POP_32_S_U",    /* name.  */
520
   false,         /* partial_inplace.  */
521
   0xffffffff00000000,      /* src_mask */
522
   0x00000000ffffffff,      /* dst_mask */
523
   false,         /* pcrel_offset */
524
   BFD_RELOC_LARCH_SOP_POP_32_U,    /* bfd_reloc_code_real_type */
525
   reloc_bits,        /* adjust_reloc_bits */
526
   NULL),         /* larch_reloc_type_name */
527
528
  /* 8-bit in-place addition, for local label subtraction.  */
529
  LOONGARCH_HOWTO (R_LARCH_ADD8,    /* type (47).  */
530
   0,         /* rightshift.  */
531
   1,         /* size.  */
532
   8,         /* bitsize.  */
533
   false,         /* pc_relative.  */
534
   0,         /* bitpos.  */
535
   complain_overflow_dont,    /* complain_on_overflow.  */
536
   loongarch_elf_add_sub_reloc,   /* special_function.  */
537
   "R_LARCH_ADD8",      /* name.  */
538
   false,         /* partial_inplace.  */
539
   0,         /* src_mask.  */
540
   0xff,          /* dst_mask.  */
541
   false,         /* pcrel_offset.  */
542
   BFD_RELOC_LARCH_ADD8,      /* bfd_reloc_code_real_type.  */
543
   NULL,          /* adjust_reloc_bits.  */
544
   NULL),         /* larch_reloc_type_name.  */
545
546
  /* 16-bit in-place addition, for local label subtraction.  */
547
  LOONGARCH_HOWTO (R_LARCH_ADD16,   /* type (48).  */
548
   0,         /* rightshift.  */
549
   2,         /* size.  */
550
   16,          /* bitsize.  */
551
   false,         /* pc_relative.  */
552
   0,         /* bitpos.  */
553
   complain_overflow_dont,    /* complain_on_overflow.  */
554
   loongarch_elf_add_sub_reloc,   /* special_function.  */
555
   "R_LARCH_ADD16",     /* name.  */
556
   false,         /* partial_inplace.  */
557
   0,         /* src_mask.  */
558
   0xffff,        /* dst_mask.  */
559
   false,         /* pcrel_offset.  */
560
   BFD_RELOC_LARCH_ADD16,     /* bfd_reloc_code_real_type.  */
561
   NULL,          /* adjust_reloc_bits.  */
562
   NULL),         /* larch_reloc_type_name.  */
563
564
  /* 24-bit in-place addition, for local label subtraction.  */
565
  LOONGARCH_HOWTO (R_LARCH_ADD24,   /* type (49).  */
566
   0,         /* rightshift.  */
567
   3,         /* size.  */
568
   24,          /* bitsize.  */
569
   false,         /* pc_relative.  */
570
   0,         /* bitpos.  */
571
   complain_overflow_dont,    /* complain_on_overflow.  */
572
   loongarch_elf_add_sub_reloc,   /* special_function.  */
573
   "R_LARCH_ADD24",     /* name.  */
574
   false,         /* partial_inplace.  */
575
   0,         /* src_mask.  */
576
   0xffffff,        /* dst_mask.  */
577
   false,         /* pcrel_offset.  */
578
   BFD_RELOC_LARCH_ADD24,     /* bfd_reloc_code_real_type.  */
579
   NULL,          /* adjust_reloc_bits.  */
580
   NULL),         /* larch_reloc_type_name.  */
581
582
  /* 32-bit in-place addition, for local label subtraction.  */
583
  LOONGARCH_HOWTO (R_LARCH_ADD32,   /* type (50).  */
584
   0,         /* rightshift.  */
585
   4,         /* size.  */
586
   32,          /* bitsize.  */
587
   false,         /* pc_relative.  */
588
   0,         /* bitpos.  */
589
   complain_overflow_dont,    /* complain_on_overflow.  */
590
   loongarch_elf_add_sub_reloc,   /* special_function.  */
591
   "R_LARCH_ADD32",     /* name.  */
592
   false,         /* partial_inplace.  */
593
   0,         /* src_mask.  */
594
   0xffffffff,        /* dst_mask.  */
595
   false,         /* pcrel_offset.  */
596
   BFD_RELOC_LARCH_ADD32,     /* bfd_reloc_code_real_type.  */
597
   NULL,          /* adjust_reloc_bits.  */
598
   NULL),         /* larch_reloc_type_name.  */
599
600
  /* 64-bit in-place addition, for local label subtraction.  */
601
  LOONGARCH_HOWTO (R_LARCH_ADD64,   /* type (51).  */
602
   0,         /* rightshift.  */
603
   8,         /* size.  */
604
   64,          /* bitsize.  */
605
   false,         /* pc_relative.  */
606
   0,         /* bitpos.  */
607
   complain_overflow_dont,    /* complain_on_overflow.  */
608
   loongarch_elf_add_sub_reloc,   /* special_function.  */
609
   "R_LARCH_ADD64",     /* name.  */
610
   false,         /* partial_inplace.  */
611
   0,         /* src_mask.  */
612
   ALL_ONES,        /* dst_mask.  */
613
   false,         /* pcrel_offset.  */
614
   BFD_RELOC_LARCH_ADD64,     /* bfd_reloc_code_real_type.  */
615
   NULL,          /* adjust_reloc_bits.  */
616
   NULL),         /* larch_reloc_type_name.  */
617
618
  /* 8-bit in-place subtraction, for local label subtraction.  */
619
  LOONGARCH_HOWTO (R_LARCH_SUB8,    /* type (52).  */
620
   0,         /* rightshift.  */
621
   1,         /* size.  */
622
   8,         /* bitsize.  */
623
   false,         /* pc_relative.  */
624
   0,         /* bitpos.  */
625
   complain_overflow_dont,    /* complain_on_overflow.  */
626
   loongarch_elf_add_sub_reloc,   /* special_function.  */
627
   "R_LARCH_SUB8",      /* name.  */
628
   false,         /* partial_inplace.  */
629
   0,         /* src_mask.  */
630
   0xff,          /* dst_mask.  */
631
   false,         /* pcrel_offset.  */
632
   BFD_RELOC_LARCH_SUB8,      /* bfd_reloc_code_real_type.  */
633
   NULL,          /* adjust_reloc_bits.  */
634
   NULL),         /* larch_reloc_type_name.  */
635
636
  /* 16-bit in-place subtraction, for local label subtraction.  */
637
  LOONGARCH_HOWTO (R_LARCH_SUB16,   /* type (53).  */
638
   0,         /* rightshift.  */
639
   2,         /* size.  */
640
   16,          /* bitsize.  */
641
   false,         /* pc_relative.  */
642
   0,         /* bitpos.  */
643
   complain_overflow_dont,    /* complain_on_overflow.  */
644
   loongarch_elf_add_sub_reloc,   /* special_function.  */
645
   "R_LARCH_SUB16",     /* name.  */
646
   false,         /* partial_inplace.  */
647
   0,         /* src_mask.  */
648
   0xffff,        /* dst_mask.  */
649
   false,         /* pcrel_offset.  */
650
   BFD_RELOC_LARCH_SUB16,     /* bfd_reloc_code_real_type.  */
651
   NULL,          /* adjust_reloc_bits.  */
652
   NULL),         /* larch_reloc_type_name.  */
653
654
  /* 24-bit in-place subtraction, for local label subtraction.  */
655
  LOONGARCH_HOWTO (R_LARCH_SUB24,   /* type (54).  */
656
   0,         /* rightshift.  */
657
   3,         /* size.  */
658
   24,          /* bitsize.  */
659
   false,         /* pc_relative.  */
660
   0,         /* bitpos.  */
661
   complain_overflow_dont,    /* complain_on_overflow.  */
662
   loongarch_elf_add_sub_reloc,   /* special_function.  */
663
   "R_LARCH_SUB24",     /* name.  */
664
   false,         /* partial_inplace.  */
665
   0,         /* src_mask.  */
666
   0xffffff,        /* dst_mask.  */
667
   false,         /* pcrel_offset.  */
668
   BFD_RELOC_LARCH_SUB24,     /* bfd_reloc_code_real_type.  */
669
   NULL,          /* adjust_reloc_bits.  */
670
   NULL),         /* larch_reloc_type_name.  */
671
672
  /* 32-bit in-place subtraction, for local label subtraction.  */
673
  LOONGARCH_HOWTO (R_LARCH_SUB32,   /* type (55).  */
674
   0,         /* rightshift.  */
675
   4,         /* size.  */
676
   32,          /* bitsize.  */
677
   false,         /* pc_relative.  */
678
   0,         /* bitpos.  */
679
   complain_overflow_dont,    /* complain_on_overflow.  */
680
   loongarch_elf_add_sub_reloc,   /* special_function.  */
681
   "R_LARCH_SUB32",     /* name.  */
682
   false,         /* partial_inplace.  */
683
   0,         /* src_mask.  */
684
   0xffffffff,        /* dst_mask.  */
685
   false,         /* pcrel_offset.  */
686
   BFD_RELOC_LARCH_SUB32,     /* bfd_reloc_code_real_type.  */
687
   NULL,          /* adjust_reloc_bits.  */
688
   NULL),         /* larch_reloc_type_name.  */
689
690
  /* 64-bit in-place subtraction, for local label subtraction.  */
691
  LOONGARCH_HOWTO (R_LARCH_SUB64,   /* type (56).  */
692
   0,         /* rightshift.  */
693
   8,         /* size.  */
694
   64,          /* bitsize.  */
695
   false,         /* pc_relative.  */
696
   0,         /* bitpos.  */
697
   complain_overflow_dont,    /* complain_on_overflow.  */
698
   loongarch_elf_add_sub_reloc,   /* special_function.  */
699
   "R_LARCH_SUB64",     /* name.  */
700
   false,         /* partial_inplace.  */
701
   0,         /* src_mask.  */
702
   ALL_ONES,        /* dst_mask.  */
703
   false,         /* pcrel_offset.  */
704
   BFD_RELOC_LARCH_SUB64,     /* bfd_reloc_code_real_type.  */
705
   NULL,          /* adjust_reloc_bits.  */
706
   NULL),         /* larch_reloc_type_name.  */
707
708
  LOONGARCH_HOWTO (R_LARCH_GNU_VTINHERIT, /* type (57).  */
709
   0,         /* rightshift.  */
710
   0,         /* size.  */
711
   0,         /* bitsize.  */
712
   false,         /* pc_relative.  */
713
   0,         /* bitpos.  */
714
   complain_overflow_signed,    /* complain_on_overflow.  */
715
   bfd_elf_generic_reloc,     /* special_function.  */
716
   "R_LARCH_GNU_VTINHERIT",   /* name.  */
717
   false,         /* partial_inplace.  */
718
   0,         /* src_mask */
719
   0,         /* dst_mask */
720
   false,         /* pcrel_offset */
721
   BFD_RELOC_NONE,      /* bfd_reloc_code_real_type */
722
   NULL,          /* adjust_reloc_bits */
723
   NULL),         /* larch_reloc_type_name */
724
725
  LOONGARCH_HOWTO (R_LARCH_GNU_VTENTRY,   /* type (58).  */
726
   0,         /* rightshift.  */
727
   0,         /* size.  */
728
   0,         /* bitsize.  */
729
   false,         /* pc_relative.  */
730
   0,         /* bitpos.  */
731
   complain_overflow_signed,    /* complain_on_overflow.  */
732
   NULL,          /* special_function.  */
733
   "R_LARCH_GNU_VTENTRY",     /* name.  */
734
   false,         /* partial_inplace.  */
735
   0,         /* src_mask */
736
   0,         /* dst_mask */
737
   false,         /* pcrel_offset */
738
   BFD_RELOC_NONE,      /* bfd_reloc_code_real_type */
739
   NULL,          /* adjust_reloc_bits */
740
   NULL),         /* larch_reloc_type_name */
741
742
  LOONGARCH_EMPTY_HOWTO (59),
743
  LOONGARCH_EMPTY_HOWTO (60),
744
  LOONGARCH_EMPTY_HOWTO (61),
745
  LOONGARCH_EMPTY_HOWTO (62),
746
  LOONGARCH_EMPTY_HOWTO (63),
747
748
  /* New reloc types.  */
749
  LOONGARCH_HOWTO (R_LARCH_B16,     /* type (64).  */
750
   2,         /* rightshift.  */
751
   4,         /* size.  */
752
   16,          /* bitsize.  */
753
   false,         /* pc_relative.  */
754
   10,          /* bitpos.  */
755
   complain_overflow_signed,    /* complain_on_overflow.  */
756
   bfd_elf_generic_reloc,     /* special_function.  */
757
   "R_LARCH_B16",       /* name.  */
758
   false,         /* partial_inplace.  */
759
   0,         /* src_mask.  */
760
   0x3fffc00,       /* dst_mask.  */
761
   false,         /* pcrel_offset.  */
762
   BFD_RELOC_LARCH_B16,     /* bfd_reloc_code_real_type.  */
763
   reloc_sign_bits,     /* adjust_reloc_bits.  */
764
   "b16"),        /* larch_reloc_type_name.  */
765
766
  LOONGARCH_HOWTO (R_LARCH_B21,     /* type (65).  */
767
   2,         /* rightshift.  */
768
   4,         /* size.  */
769
   21,          /* bitsize.  */
770
   false,         /* pc_relative.  */
771
   0,         /* bitpos.  */
772
   complain_overflow_signed,    /* complain_on_overflow.  */
773
   bfd_elf_generic_reloc,     /* special_function.  */
774
   "R_LARCH_B21",       /* name.  */
775
   false,         /* partial_inplace.  */
776
   0,         /* src_mask.  */
777
   0x3fffc1f,       /* dst_mask.  */
778
   false,         /* pcrel_offset.  */
779
   BFD_RELOC_LARCH_B21,     /* bfd_reloc_code_real_type.  */
780
   reloc_sign_bits,     /* adjust_reloc_bits.  */
781
   "b21"),        /* larch_reloc_type_name.  */
782
783
  LOONGARCH_HOWTO (R_LARCH_B26,     /* type (66).  */
784
   2,         /* rightshift.  */
785
   4,         /* size.  */
786
   26,          /* bitsize.  */
787
   false,         /* pc_relative.  */
788
   0,         /* bitpos.  */
789
   complain_overflow_signed,    /* complain_on_overflow.  */
790
   bfd_elf_generic_reloc,     /* special_function.  */
791
   "R_LARCH_B26",       /* name.  */
792
   false,         /* partial_inplace.  */
793
   0,         /* src_mask.  */
794
   0x03ffffff,        /* dst_mask.  */
795
   false,         /* pcrel_offset.  */
796
   BFD_RELOC_LARCH_B26,     /* bfd_reloc_code_real_type.  */
797
   reloc_sign_bits,     /* adjust_reloc_bits.  */
798
   "b26"),        /* larch_reloc_type_name.  */
799
800
  LOONGARCH_HOWTO (R_LARCH_ABS_HI20,    /* type (67).  */
801
   12,          /* rightshift.  */
802
   4,         /* size.  */
803
   20,          /* bitsize.  */
804
   false,         /* pc_relative.  */
805
   5,         /* bitpos.  */
806
   complain_overflow_signed,    /* complain_on_overflow.  */
807
   bfd_elf_generic_reloc,     /* special_function.  */
808
   "R_LARCH_ABS_HI20",      /* name.  */
809
   false,         /* partial_inplace.  */
810
   0,         /* src_mask */
811
   0x1ffffe0,       /* dst_mask */
812
   false,         /* pcrel_offset */
813
   BFD_RELOC_LARCH_ABS_HI20,    /* bfd_reloc_code_real_type */
814
   reloc_bits,        /* adjust_reloc_bits */
815
   "abs_hi20"),       /* larch_reloc_type_name */
816
817
  LOONGARCH_HOWTO (R_LARCH_ABS_LO12,    /* type (68).  */
818
   0,         /* rightshift.  */
819
   4,         /* size.  */
820
   12,          /* bitsize.  */
821
   false,         /* pc_relative.  */
822
   10,          /* bitpos.  */
823
   complain_overflow_unsigned,    /* complain_on_overflow.  */
824
   bfd_elf_generic_reloc,     /* special_function.  */
825
   "R_LARCH_ABS_LO12",      /* name.  */
826
   false,         /* partial_inplace.  */
827
   0,         /* src_mask */
828
   0x3ffc00,        /* dst_mask */
829
   false,         /* pcrel_offset */
830
   BFD_RELOC_LARCH_ABS_LO12,    /* bfd_reloc_code_real_type */
831
   reloc_bits,        /* adjust_reloc_bits */
832
   "abs_lo12"),       /* larch_reloc_type_name */
833
834
  LOONGARCH_HOWTO (R_LARCH_ABS64_LO20,    /* type (69).  */
835
   32,          /* 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_ABS64_LO20",      /* name.  */
843
   false,         /* partial_inplace.  */
844
   0,         /* src_mask */
845
   0x1ffffe0,       /* dst_mask */
846
   false,         /* pcrel_offset */
847
   BFD_RELOC_LARCH_ABS64_LO20,    /* bfd_reloc_code_real_type */
848
   reloc_bits,        /* adjust_reloc_bits */
849
   "abs64_lo20"),       /* larch_reloc_type_name */
850
851
  LOONGARCH_HOWTO (R_LARCH_ABS64_HI12,    /* type (70).  */
852
   52,          /* rightshift.  */
853
   4,         /* size.  */
854
   12,          /* bitsize.  */
855
   false,         /* pc_relative.  */
856
   10,          /* bitpos.  */
857
   complain_overflow_signed,    /* complain_on_overflow.  */
858
   bfd_elf_generic_reloc,     /* special_function.  */
859
   "R_LARCH_ABS64_HI12",      /* name.  */
860
   false,         /* partial_inplace.  */
861
   0,         /* src_mask */
862
   0x3ffc00,        /* dst_mask */
863
   false,         /* pcrel_offset */
864
   BFD_RELOC_LARCH_ABS64_HI12,    /* bfd_reloc_code_real_type */
865
   reloc_bits,        /* adjust_reloc_bits */
866
   "abs64_hi12"),       /* larch_reloc_type_name */
867
868
  LOONGARCH_HOWTO (R_LARCH_PCALA_HI20,    /* type (71).  */
869
   12,          /* 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_PCALA_HI20",      /* name.  */
877
   false,         /* partial_inplace.  */
878
   0,         /* src_mask */
879
   0x1ffffe0,       /* dst_mask */
880
   false,         /* pcrel_offset */
881
   BFD_RELOC_LARCH_PCALA_HI20,    /* bfd_reloc_code_real_type */
882
   reloc_bits,        /* adjust_reloc_bits */
883
   "pc_hi20"),        /* larch_reloc_type_name */
884
885
  LOONGARCH_HOWTO (R_LARCH_PCALA_LO12,    /* type (72).  */
886
   0,         /* 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_PCALA_LO12",      /* name.  */
894
   false,         /* partial_inplace.  */
895
   0,         /* src_mask */
896
   0x3ffc00,        /* dst_mask */
897
   false,         /* pcrel_offset */
898
   BFD_RELOC_LARCH_PCALA_LO12,    /* bfd_reloc_code_real_type */
899
   reloc_bits,        /* adjust_reloc_bits */
900
   "pc_lo12"),        /* larch_reloc_type_name */
901
902
  LOONGARCH_HOWTO (R_LARCH_PCALA64_LO20,  /* type (73).  */
903
   32,          /* 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_PCALA64_LO20",    /* name.  */
911
   false,         /* partial_inplace.  */
912
   0,         /* src_mask */
913
   0x1ffffe0,       /* dst_mask */
914
   false,         /* pcrel_offset */
915
   BFD_RELOC_LARCH_PCALA64_LO20,    /* bfd_reloc_code_real_type */
916
   reloc_bits,        /* adjust_reloc_bits */
917
   "pc64_lo20"),        /* larch_reloc_type_name */
918
919
  LOONGARCH_HOWTO (R_LARCH_PCALA64_HI12,  /* type (74).  */
920
   52,          /* 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_PCALA64_HI12",    /* name.  */
928
   false,         /* partial_inplace.  */
929
   0,         /* src_mask */
930
   0x3ffc00,        /* dst_mask */
931
   false,         /* pcrel_offset */
932
   BFD_RELOC_LARCH_PCALA64_HI12,    /* bfd_reloc_code_real_type */
933
   reloc_bits,        /* adjust_reloc_bits */
934
   "pc64_hi12"),        /* larch_reloc_type_name */
935
936
  LOONGARCH_HOWTO (R_LARCH_GOT_PC_HI20,   /* type (75).  */
937
   12,          /* 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_GOT_PC_HI20",     /* name.  */
945
   false,         /* partial_inplace.  */
946
   0,         /* src_mask */
947
   0x1ffffe0,       /* dst_mask */
948
   false,         /* pcrel_offset */
949
   BFD_RELOC_LARCH_GOT_PC_HI20,   /* bfd_reloc_code_real_type */
950
   reloc_bits,        /* adjust_reloc_bits */
951
   "got_pc_hi20"),      /* larch_reloc_type_name */
952
953
  LOONGARCH_HOWTO (R_LARCH_GOT_PC_LO12,   /* type (76).  */
954
   0,         /* 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_GOT_PC_LO12",     /* name.  */
962
   false,         /* partial_inplace.  */
963
   0,         /* src_mask */
964
   0x3ffc00,        /* dst_mask */
965
   false,         /* pcrel_offset */
966
   BFD_RELOC_LARCH_GOT_PC_LO12,   /* bfd_reloc_code_real_type */
967
   reloc_bits,        /* adjust_reloc_bits */
968
   "got_pc_lo12"),      /* larch_reloc_type_name */
969
970
  LOONGARCH_HOWTO (R_LARCH_GOT64_PC_LO20, /* type (77).  */
971
   32,          /* 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_GOT64_PC_LO20",   /* name.  */
979
   false,         /* partial_inplace.  */
980
   0,         /* src_mask */
981
   0x1ffffe0,       /* dst_mask */
982
   false,         /* pcrel_offset */
983
   BFD_RELOC_LARCH_GOT64_PC_LO20,   /* bfd_reloc_code_real_type */
984
   reloc_bits,        /* adjust_reloc_bits */
985
   "got64_pc_lo20"),      /* larch_reloc_type_name */
986
987
  LOONGARCH_HOWTO (R_LARCH_GOT64_PC_HI12, /* type (78).  */
988
   52,          /* 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_GOT64_PC_HI12",   /* name.  */
996
   false,         /* partial_inplace.  */
997
   0,         /* src_mask */
998
   0x3ffc00,        /* dst_mask */
999
   false,         /* pcrel_offset */
1000
   BFD_RELOC_LARCH_GOT64_PC_HI12,   /* bfd_reloc_code_real_type */
1001
   reloc_bits,        /* adjust_reloc_bits */
1002
   "got64_pc_hi12"),      /* larch_reloc_type_name */
1003
1004
  LOONGARCH_HOWTO (R_LARCH_GOT_HI20,    /* type (79).  */
1005
   12,          /* 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_GOT_HI20",      /* name.  */
1013
   false,         /* partial_inplace.  */
1014
   0,         /* src_mask */
1015
   0x1ffffe0,       /* dst_mask */
1016
   false,         /* pcrel_offset */
1017
   BFD_RELOC_LARCH_GOT_HI20,    /* bfd_reloc_code_real_type */
1018
   reloc_bits,        /* adjust_reloc_bits */
1019
   "got_hi20"),       /* larch_reloc_type_name */
1020
1021
  LOONGARCH_HOWTO (R_LARCH_GOT_LO12,    /* type (80).  */
1022
   0,         /* 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_GOT_LO12",      /* name.  */
1030
   false,         /* partial_inplace.  */
1031
   0,         /* src_mask */
1032
   0x3ffc00,        /* dst_mask */
1033
   false,         /* pcrel_offset */
1034
   BFD_RELOC_LARCH_GOT_LO12,    /* bfd_reloc_code_real_type */
1035
   reloc_bits,        /* adjust_reloc_bits */
1036
   "got_lo12"),       /* larch_reloc_type_name */
1037
1038
  LOONGARCH_HOWTO (R_LARCH_GOT64_LO20,    /* type (81).  */
1039
   32,          /* 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_GOT64_LO20",      /* name.  */
1047
   false,         /* partial_inplace.  */
1048
   0,         /* src_mask */
1049
   0x1ffffe0,       /* dst_mask */
1050
   false,         /* pcrel_offset */
1051
   BFD_RELOC_LARCH_GOT64_LO20,    /* bfd_reloc_code_real_type */
1052
   reloc_bits,        /* adjust_reloc_bits */
1053
   "got64_lo20"),       /* larch_reloc_type_name */
1054
1055
  LOONGARCH_HOWTO (R_LARCH_GOT64_HI12,    /* type (82).  */
1056
   52,          /* 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_GOT64_HI12",      /* name.  */
1064
   false,         /* partial_inplace.  */
1065
   0,         /* src_mask */
1066
   0x3ffc00,        /* dst_mask */
1067
   false,         /* pcrel_offset */
1068
   BFD_RELOC_LARCH_GOT64_HI12,    /* bfd_reloc_code_real_type */
1069
   reloc_bits,        /* adjust_reloc_bits */
1070
   "got64_hi12"),       /* larch_reloc_type_name */
1071
1072
  LOONGARCH_HOWTO (R_LARCH_TLS_LE_HI20,   /* type (83).  */
1073
   12,          /* 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_TLS_LE_HI20",     /* name.  */
1081
   false,         /* partial_inplace.  */
1082
   0,         /* src_mask */
1083
   0x1ffffe0,       /* dst_mask */
1084
   false,         /* pcrel_offset */
1085
   BFD_RELOC_LARCH_TLS_LE_HI20,   /* bfd_reloc_code_real_type */
1086
   reloc_bits,        /* adjust_reloc_bits */
1087
   "le_hi20"),        /* larch_reloc_type_name */
1088
1089
  LOONGARCH_HOWTO (R_LARCH_TLS_LE_LO12,   /* type (84).  */
1090
   0,         /* rightshift.  */
1091
   4,         /* size.  */
1092
   12,          /* bitsize.  */
1093
   false,         /* pc_relative.  */
1094
   10,          /* bitpos.  */
1095
   complain_overflow_unsigned,    /* complain_on_overflow.  */
1096
   bfd_elf_generic_reloc,     /* special_function.  */
1097
   "R_LARCH_TLS_LE_LO12",     /* name.  */
1098
   false,         /* partial_inplace.  */
1099
   0,         /* src_mask */
1100
   0x3ffc00,        /* dst_mask */
1101
   false,         /* pcrel_offset */
1102
   BFD_RELOC_LARCH_TLS_LE_LO12,   /* bfd_reloc_code_real_type */
1103
   reloc_bits,        /* adjust_reloc_bits */
1104
   "le_lo12"),        /* larch_reloc_type_name */
1105
1106
  LOONGARCH_HOWTO (R_LARCH_TLS_LE64_LO20, /* type (85).  */
1107
   32,          /* 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_LE64_LO20",   /* name.  */
1115
   false,         /* partial_inplace.  */
1116
   0,         /* src_mask */
1117
   0x1ffffe0,       /* dst_mask */
1118
   false,         /* pcrel_offset */
1119
   BFD_RELOC_LARCH_TLS_LE64_LO20,   /* bfd_reloc_code_real_type */
1120
   reloc_bits,        /* adjust_reloc_bits */
1121
   "le64_lo20"),        /* larch_reloc_type_name */
1122
1123
  LOONGARCH_HOWTO (R_LARCH_TLS_LE64_HI12, /* type (86).  */
1124
   52,          /* rightshift.  */
1125
   4,         /* size.  */
1126
   12,          /* bitsize.  */
1127
   false,         /* pc_relative.  */
1128
   10,          /* bitpos.  */
1129
   complain_overflow_signed,    /* complain_on_overflow.  */
1130
   bfd_elf_generic_reloc,     /* special_function.  */
1131
   "R_LARCH_TLS_LE64_HI12",   /* name.  */
1132
   false,         /* partial_inplace.  */
1133
   0,         /* src_mask */
1134
   0x3ffc00,        /* dst_mask */
1135
   false,         /* pcrel_offset */
1136
   BFD_RELOC_LARCH_TLS_LE64_HI12,   /* bfd_reloc_code_real_type */
1137
   reloc_bits,        /* adjust_reloc_bits */
1138
   "le64_hi12"),        /* larch_reloc_type_name */
1139
1140
  LOONGARCH_HOWTO (R_LARCH_TLS_IE_PC_HI20,  /* type (87).  */
1141
   12,          /* 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_IE_PC_HI20",    /* name.  */
1149
   false,         /* partial_inplace.  */
1150
   0,         /* src_mask */
1151
   0x1ffffe0,       /* dst_mask */
1152
   false,         /* pcrel_offset */
1153
   BFD_RELOC_LARCH_TLS_IE_PC_HI20,  /* bfd_reloc_code_real_type */
1154
   reloc_bits,        /* adjust_reloc_bits */
1155
   "ie_pc_hi20"),       /* larch_reloc_type_name */
1156
1157
  LOONGARCH_HOWTO (R_LARCH_TLS_IE_PC_LO12,  /* type (88).  */
1158
   0,         /* 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_IE_PC_LO12",    /* name.  */
1166
   false,         /* partial_inplace.  */
1167
   0,         /* src_mask */
1168
   0x3ffc00,        /* dst_mask */
1169
   false,         /* pcrel_offset */
1170
   BFD_RELOC_LARCH_TLS_IE_PC_LO12,  /* bfd_reloc_code_real_type */
1171
   reloc_bits,        /* adjust_reloc_bits */
1172
   "ie_pc_lo12"),       /* larch_reloc_type_name */
1173
1174
  LOONGARCH_HOWTO (R_LARCH_TLS_IE64_PC_LO20,  /* type (89).  */
1175
   32,          /* 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_IE64_PC_LO20",    /* name.  */
1183
   false,         /* partial_inplace.  */
1184
   0,         /* src_mask */
1185
   0x1ffffe0,       /* dst_mask */
1186
   false,         /* pcrel_offset */
1187
   BFD_RELOC_LARCH_TLS_IE64_PC_LO20,  /* bfd_reloc_code_real_type */
1188
   reloc_bits,        /* adjust_reloc_bits */
1189
   "ie64_pc_lo20"),     /* larch_reloc_type_name */
1190
1191
  LOONGARCH_HOWTO (R_LARCH_TLS_IE64_PC_HI12,  /* type (90).  */
1192
   52,          /* rightshift.  */
1193
   4,         /* size.  */
1194
   12,          /* bitsize.  */
1195
   false,         /* pc_relative.  */
1196
   10,          /* bitpos.  */
1197
   complain_overflow_signed,    /* complain_on_overflow.  */
1198
   bfd_elf_generic_reloc,     /* special_function.  */
1199
   "R_LARCH_TLS_IE64_PC_HI12",    /* name.  */
1200
   false,         /* partial_inplace.  */
1201
   0,         /* src_mask */
1202
   0x3ffc00,        /* dst_mask */
1203
   false,         /* pcrel_offset */
1204
   BFD_RELOC_LARCH_TLS_IE64_PC_HI12,  /* bfd_reloc_code_real_type */
1205
   reloc_bits,        /* adjust_reloc_bits */
1206
   "ie64_pc_hi12"),     /* larch_reloc_type_name */
1207
1208
  LOONGARCH_HOWTO (R_LARCH_TLS_IE_HI20,   /* type (91).  */
1209
   12,          /* 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_IE_HI20",     /* name.  */
1217
   false,         /* partial_inplace.  */
1218
   0,         /* src_mask */
1219
   0x1ffffe0,       /* dst_mask */
1220
   false,         /* pcrel_offset */
1221
   BFD_RELOC_LARCH_TLS_IE_HI20,   /* bfd_reloc_code_real_type */
1222
   reloc_bits,        /* adjust_reloc_bits */
1223
   "ie_hi20"),        /* larch_reloc_type_name */
1224
1225
  LOONGARCH_HOWTO (R_LARCH_TLS_IE_LO12,   /* type (92).  */
1226
   0,         /* 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_IE_LO12",     /* name.  */
1234
   false,         /* partial_inplace.  */
1235
   0,         /* src_mask */
1236
   0x3ffc00,        /* dst_mask */
1237
   false,         /* pcrel_offset */
1238
   BFD_RELOC_LARCH_TLS_IE_LO12,   /* bfd_reloc_code_real_type */
1239
   reloc_bits,        /* adjust_reloc_bits */
1240
   "ie_lo12"),        /* larch_reloc_type_name */
1241
1242
  LOONGARCH_HOWTO (R_LARCH_TLS_IE64_LO20, /* type (93).  */
1243
   32,          /* 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_IE64_LO20",   /* name.  */
1251
   false,         /* partial_inplace.  */
1252
   0,         /* src_mask */
1253
   0x1ffffe0,       /* dst_mask */
1254
   false,         /* pcrel_offset */
1255
   BFD_RELOC_LARCH_TLS_IE64_LO20,   /* bfd_reloc_code_real_type */
1256
   reloc_bits,        /* adjust_reloc_bits */
1257
   "ie64_lo20"),        /* larch_reloc_type_name */
1258
1259
  LOONGARCH_HOWTO (R_LARCH_TLS_IE64_HI12, /* type (94).  */
1260
   52,          /* 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_IE64_HI12",   /* name.  */
1268
   false,         /* partial_inplace.  */
1269
   0,         /* src_mask */
1270
   0x3ffc00,        /* dst_mask */
1271
   false,         /* pcrel_offset */
1272
   BFD_RELOC_LARCH_TLS_IE64_HI12,   /* bfd_reloc_code_real_type */
1273
   reloc_bits,        /* adjust_reloc_bits */
1274
   "ie64_hi12"),        /* larch_reloc_type_name */
1275
1276
  LOONGARCH_HOWTO (R_LARCH_TLS_LD_PC_HI20,  /* type (95).  */
1277
   12,          /* 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_LD_PC_HI20",    /* name.  */
1285
   false,         /* partial_inplace.  */
1286
   0,         /* src_mask */
1287
   0x1ffffe0,       /* dst_mask */
1288
   false,         /* pcrel_offset */
1289
   BFD_RELOC_LARCH_TLS_LD_PC_HI20,  /* bfd_reloc_code_real_type */
1290
   reloc_bits,        /* adjust_reloc_bits */
1291
   "ld_pc_hi20"),       /* larch_reloc_type_name */
1292
1293
  LOONGARCH_HOWTO (R_LARCH_TLS_LD_HI20,   /* type (96).  */
1294
   12,          /* rightshift.  */
1295
   4,         /* size.  */
1296
   20,          /* bitsize.  */
1297
   false,         /* pc_relative.  */
1298
   5,         /* bitpos.  */
1299
   complain_overflow_signed,    /* complain_on_overflow.  */
1300
   bfd_elf_generic_reloc,     /* special_function.  */
1301
   "R_LARCH_TLS_LD_HI20",     /* name.  */
1302
   false,         /* partial_inplace.  */
1303
   0,         /* src_mask */
1304
   0x1ffffe0,       /* dst_mask */
1305
   false,         /* pcrel_offset */
1306
   BFD_RELOC_LARCH_TLS_LD_HI20,   /* bfd_reloc_code_real_type */
1307
   reloc_bits,        /* adjust_reloc_bits */
1308
   "ld_hi20"),        /* larch_reloc_type_name */
1309
1310
  LOONGARCH_HOWTO (R_LARCH_TLS_GD_PC_HI20,  /* type (97).  */
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_GD_PC_HI20",    /* name.  */
1319
   false,         /* partial_inplace.  */
1320
   0,         /* src_mask */
1321
   0x1ffffe0,       /* dst_mask */
1322
   false,         /* pcrel_offset */
1323
   BFD_RELOC_LARCH_TLS_GD_PC_HI20,  /* bfd_reloc_code_real_type */
1324
   reloc_bits,        /* adjust_reloc_bits */
1325
   "gd_pc_hi20"),       /* larch_reloc_type_name */
1326
1327
  LOONGARCH_HOWTO (R_LARCH_TLS_GD_HI20,   /* type (98).  */
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_GD_HI20",     /* name.  */
1336
   false,         /* partial_inplace.  */
1337
   0,         /* src_mask */
1338
   0x1ffffe0,       /* dst_mask */
1339
   false,         /* pcrel_offset */
1340
   BFD_RELOC_LARCH_TLS_GD_HI20,   /* bfd_reloc_code_real_type */
1341
   reloc_bits,        /* adjust_reloc_bits */
1342
   "gd_hi20"),        /* larch_reloc_type_name */
1343
1344
  /* 32-bit PC relative.  */
1345
  LOONGARCH_HOWTO (R_LARCH_32_PCREL,    /* type (99).  */
1346
   0,         /* rightshift.  */
1347
   4,         /* size.  */
1348
   32,          /* bitsize.  */
1349
   true,          /* pc_relative.  */
1350
   0,         /* bitpos.  */
1351
   complain_overflow_signed,    /* complain_on_overflow.  */
1352
   bfd_elf_generic_reloc,     /* special_function.  */
1353
   "R_LARCH_32_PCREL",      /* name.  */
1354
   false,         /* partial_inplace.  */
1355
   0,         /* src_mask */
1356
   0xffffffff,        /* dst_mask */
1357
   false,         /* pcrel_offset */
1358
   BFD_RELOC_LARCH_32_PCREL,    /* bfd_reloc_code_real_type */
1359
   NULL,          /* adjust_reloc_bits */
1360
   NULL),         /* larch_reloc_type_name */
1361
1362
  /* The paired relocation may be relaxed.  */
1363
  LOONGARCH_HOWTO (R_LARCH_RELAX,   /* type (100).  */
1364
   0,         /* rightshift */
1365
   1,         /* size */
1366
   0,         /* bitsize */
1367
   false,         /* pc_relative */
1368
   0,         /* bitpos */
1369
   complain_overflow_dont,    /* complain_on_overflow */
1370
   bfd_elf_generic_reloc,     /* special_function */
1371
   "R_LARCH_RELAX",     /* name */
1372
   false,         /* partial_inplace */
1373
   0,         /* src_mask */
1374
   0,         /* dst_mask */
1375
   false,         /* pcrel_offset */
1376
   BFD_RELOC_LARCH_RELAX,     /* bfd_reloc_code_real_type */
1377
   NULL,          /* adjust_reloc_bits */
1378
   NULL),         /* larch_reloc_type_name */
1379
1380
  /* Delete relaxed instruction.  */
1381
  LOONGARCH_HOWTO (R_LARCH_DELETE,    /* type (101).  */
1382
   0,         /* rightshift.  */
1383
   0,         /* size.  */
1384
   0,         /* bitsize.  */
1385
   false,         /* pc_relative.  */
1386
   0,         /* bitpos.  */
1387
   complain_overflow_dont,    /* complain_on_overflow.  */
1388
   bfd_elf_generic_reloc,     /* special_function.  */
1389
   "R_LARCH_DELETE",      /* name.  */
1390
   false,         /* partial_inplace.  */
1391
   0,         /* src_mask.  */
1392
   0,         /* dst_mask.  */
1393
   false,         /* pcrel_offset.  */
1394
   BFD_RELOC_LARCH_DELETE,    /* bfd_reloc_code_real_type.  */
1395
   NULL,          /* adjust_reloc_bits.  */
1396
   NULL),         /* larch_reloc_type_name.  */
1397
1398
  /* Indicates an alignment statement.  The addend field encodes how many
1399
     bytes of NOPs follow the statement.  The desired alignment is the
1400
     addend rounded up to the next power of two.  */
1401
  LOONGARCH_HOWTO (R_LARCH_ALIGN,   /* type (102).  */
1402
   0,         /* rightshift.  */
1403
   0,         /* size.  */
1404
   0,         /* bitsize.  */
1405
   false,         /* pc_relative.  */
1406
   0,         /* bitpos.  */
1407
   complain_overflow_dont,    /* complain_on_overflow.  */
1408
   bfd_elf_generic_reloc,     /* special_function.  */
1409
   "R_LARCH_ALIGN",     /* name.  */
1410
   false,         /* partial_inplace.  */
1411
   0,         /* src_mask.  */
1412
   0,         /* dst_mask.  */
1413
   false,         /* pcrel_offset.  */
1414
   BFD_RELOC_LARCH_ALIGN,     /* bfd_reloc_code_real_type.  */
1415
   NULL,          /* adjust_reloc_bits.  */
1416
   NULL),         /* larch_reloc_type_name.  */
1417
1418
  /* pcala_hi20 + pcala_lo12 relaxed to pcrel20_s2.  */
1419
  LOONGARCH_HOWTO (R_LARCH_PCREL20_S2,    /* type (103).  */
1420
   2,         /* rightshift.  */
1421
   4,         /* size.  */
1422
   20,          /* bitsize.  */
1423
   false,         /* pc_relative.  */
1424
   5,         /* bitpos.  */
1425
   complain_overflow_signed,    /* complain_on_overflow.  */
1426
   bfd_elf_generic_reloc,     /* special_function.  */
1427
   "R_LARCH_PCREL20_S2",      /* name.  */
1428
   false,         /* partial_inplace.  */
1429
   0,         /* src_mask.  */
1430
   0x1ffffe0,       /* dst_mask.  */
1431
   false,         /* pcrel_offset.  */
1432
   BFD_RELOC_LARCH_PCREL20_S2,    /* bfd_reloc_code_real_type.  */
1433
   reloc_sign_bits,     /* adjust_reloc_bits.  */
1434
   NULL),         /* larch_reloc_type_name.  */
1435
1436
  /* Canonical Frame Address.  */
1437
  LOONGARCH_HOWTO (R_LARCH_CFA,     /* type (104).  */
1438
   0,         /* rightshift.  */
1439
   0,         /* size.  */
1440
   0,         /* bitsize.  */
1441
   false,         /* pc_relative.  */
1442
   0,         /* bitpos.  */
1443
   complain_overflow_dont,    /* complain_on_overflow.  */
1444
   bfd_elf_generic_reloc,     /* special_function.  */
1445
   "R_LARCH_CFA",       /* name.  */
1446
   false,         /* partial_inplace.  */
1447
   0,         /* src_mask.  */
1448
   0,         /* dst_mask.  */
1449
   false,         /* pcrel_offset.  */
1450
   BFD_RELOC_LARCH_CFA,     /* bfd_reloc_code_real_type.  */
1451
   NULL,          /* adjust_reloc_bits.  */
1452
   NULL),         /* larch_reloc_type_name.  */
1453
1454
  /* 6-bit in-place addition, for local label subtraction
1455
     to calculate DW_CFA_advance_loc.  */
1456
  LOONGARCH_HOWTO (R_LARCH_ADD6,    /* type (105).  */
1457
   0,         /* rightshift.  */
1458
   1,         /* size.  */
1459
   8,         /* bitsize.  */
1460
   false,         /* pc_relative.  */
1461
   0,         /* bitpos.  */
1462
   complain_overflow_dont,    /* complain_on_overflow.  */
1463
   loongarch_elf_add_sub_reloc,   /* special_function.  */
1464
   "R_LARCH_ADD6",      /* name.  */
1465
   false,         /* partial_inplace.  */
1466
   0,         /* src_mask.  */
1467
   0x3f,          /* dst_mask.  */
1468
   false,         /* pcrel_offset.  */
1469
   BFD_RELOC_LARCH_ADD6,      /* bfd_reloc_code_real_type.  */
1470
   reloc_bits,        /* adjust_reloc_bits.  */
1471
   NULL),         /* larch_reloc_type_name.  */
1472
1473
  /* 6-bit in-place subtraction, for local label subtraction
1474
     to calculate DW_CFA_advance_loc.  */
1475
  LOONGARCH_HOWTO (R_LARCH_SUB6,    /* type (106).  */
1476
   0,         /* rightshift.  */
1477
   1,         /* size.  */
1478
   8,         /* bitsize.  */
1479
   false,         /* pc_relative.  */
1480
   0,         /* bitpos.  */
1481
   complain_overflow_dont,    /* complain_on_overflow.  */
1482
   loongarch_elf_add_sub_reloc,   /* special_function.  */
1483
   "R_LARCH_SUB6",      /* name.  */
1484
   false,         /* partial_inplace.  */
1485
   0,         /* src_mask.  */
1486
   0x3f,          /* dst_mask.  */
1487
   false,         /* pcrel_offset.  */
1488
   BFD_RELOC_LARCH_SUB6,      /* bfd_reloc_code_real_type.  */
1489
   reloc_bits,        /* adjust_reloc_bits.  */
1490
   NULL),         /* larch_reloc_type_name.  */
1491
1492
  /* The length of unsigned-leb128 is variable, just assume the
1493
     size is one byte here.
1494
     uleb128 in-place addition, for local label subtraction.  */
1495
  LOONGARCH_HOWTO (R_LARCH_ADD_ULEB128,   /* type (107).  */
1496
   0,         /* rightshift.  */
1497
   1,         /* size.  */
1498
   0,         /* bitsize.  */
1499
   false,         /* pc_relative.  */
1500
   0,         /* bitpos.  */
1501
   complain_overflow_dont,    /* complain_on_overflow.  */
1502
   loongarch_elf_add_sub_reloc_uleb128, /* special_function.  */
1503
   "R_LARCH_ADD_ULEB128",     /* name.  */
1504
   false,         /* partial_inplace.  */
1505
   0,         /* src_mask.  */
1506
   0,         /* dst_mask.  */
1507
   false,         /* pcrel_offset.  */
1508
   BFD_RELOC_LARCH_ADD_ULEB128,   /* bfd_reloc_code_real_type.  */
1509
   NULL,          /* adjust_reloc_bits.  */
1510
   NULL),         /* larch_reloc_type_name.  */
1511
1512
  /* The length of unsigned-leb128 is variable, just assume the
1513
     size is one byte here.
1514
     uleb128 in-place subtraction, for local label subtraction.  */
1515
  LOONGARCH_HOWTO (R_LARCH_SUB_ULEB128,   /* type (108).  */
1516
   0,         /* rightshift.  */
1517
   1,         /* size.  */
1518
   0,         /* bitsize.  */
1519
   false,         /* pc_relative.  */
1520
   0,         /* bitpos.  */
1521
   complain_overflow_dont,    /* complain_on_overflow.  */
1522
   loongarch_elf_add_sub_reloc_uleb128, /* special_function.  */
1523
   "R_LARCH_SUB_ULEB128",     /* name.  */
1524
   false,         /* partial_inplace.  */
1525
   0,         /* src_mask.  */
1526
   0,         /* dst_mask.  */
1527
   false,         /* pcrel_offset.  */
1528
   BFD_RELOC_LARCH_SUB_ULEB128,   /* bfd_reloc_code_real_type.  */
1529
   NULL,          /* adjust_reloc_bits.  */
1530
   NULL),         /* larch_reloc_type_name.  */
1531
1532
  /* 64-bit PC relative.  */
1533
  LOONGARCH_HOWTO (R_LARCH_64_PCREL,    /* type (109).  */
1534
   0,         /* rightshift.  */
1535
   8,         /* size.  */
1536
   64,          /* bitsize.  */
1537
   true,          /* pc_relative.  */
1538
   0,         /* bitpos.  */
1539
   complain_overflow_signed,    /* complain_on_overflow.  */
1540
   bfd_elf_generic_reloc,     /* special_function.  */
1541
   "R_LARCH_64_PCREL",      /* name.  */
1542
   false,         /* partial_inplace.  */
1543
   0,         /* src_mask */
1544
   0xffffffffffffffff,      /* dst_mask */
1545
   false,         /* pcrel_offset */
1546
   BFD_RELOC_LARCH_64_PCREL,    /* bfd_reloc_code_real_type */
1547
   NULL,          /* adjust_reloc_bits */
1548
   NULL),         /* larch_reloc_type_name */
1549
1550
};
1551
1552
reloc_howto_type *
1553
loongarch_elf_rtype_to_howto (bfd *abfd, unsigned int r_type)
1554
30
{
1555
30
  if(r_type < R_LARCH_count)
1556
19
    {
1557
      /* For search table fast.  */
1558
19
      BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count);
1559
1560
19
      if (loongarch_howto_table[r_type].howto.type == r_type)
1561
19
  return (reloc_howto_type *)&loongarch_howto_table[r_type];
1562
1563
0
      for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++)
1564
0
  if (loongarch_howto_table[i].howto.type == r_type)
1565
0
    return (reloc_howto_type *)&loongarch_howto_table[i];
1566
0
    }
1567
1568
11
  (*_bfd_error_handler) (_("%pB: unsupported relocation type %#x"),
1569
11
       abfd, r_type);
1570
11
  bfd_set_error (bfd_error_bad_value);
1571
11
  return NULL;
1572
30
}
1573
1574
reloc_howto_type *
1575
loongarch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
1576
0
{
1577
0
  BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count);
1578
1579
0
  for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++)
1580
0
    if (loongarch_howto_table[i].howto.name
1581
0
  && strcasecmp (loongarch_howto_table[i].howto.name, r_name) == 0)
1582
0
      return (reloc_howto_type *)&loongarch_howto_table[i];
1583
1584
0
  (*_bfd_error_handler) (_("%pB: unsupported relocation type %s"),
1585
0
       abfd, r_name);
1586
0
  bfd_set_error (bfd_error_bad_value);
1587
1588
0
  return NULL;
1589
0
}
1590
1591
/* Cost so much.  */
1592
reloc_howto_type *
1593
loongarch_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1594
           bfd_reloc_code_real_type code)
1595
0
{
1596
0
  BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count);
1597
1598
  /* Fast search for new reloc types.  */
1599
0
  if (BFD_RELOC_LARCH_B16 <= code && code < BFD_RELOC_LARCH_RELAX)
1600
0
    {
1601
0
      BFD_ASSERT (BFD_RELOC_LARCH_RELAX - BFD_RELOC_LARCH_B16
1602
0
      == R_LARCH_RELAX - R_LARCH_B16);
1603
0
      loongarch_reloc_howto_type *ht = NULL;
1604
0
      ht = &loongarch_howto_table[code - BFD_RELOC_LARCH_B16 + R_LARCH_B16];
1605
0
      BFD_ASSERT (ht->bfd_type == code);
1606
0
      return (reloc_howto_type *)ht;
1607
0
    }
1608
1609
0
  for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++)
1610
0
    if (loongarch_howto_table[i].bfd_type == code)
1611
0
      return (reloc_howto_type *)&loongarch_howto_table[i];
1612
1613
0
  (*_bfd_error_handler) (_("%pB: unsupported bfd relocation type %#x"),
1614
0
       abfd, code);
1615
0
  bfd_set_error (bfd_error_bad_value);
1616
1617
0
  return NULL;
1618
0
}
1619
1620
bfd_reloc_code_real_type
1621
loongarch_larch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1622
           const char *l_r_name)
1623
0
{
1624
0
  for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++)
1625
0
    {
1626
0
      loongarch_reloc_howto_type *lht = &loongarch_howto_table[i];
1627
0
      if ((NULL != lht->larch_reloc_type_name)
1628
0
    && (0 == strcmp (lht->larch_reloc_type_name, l_r_name)))
1629
0
  return lht->bfd_type;
1630
0
    }
1631
1632
0
  (*_bfd_error_handler) (_("%pB: unsupported relocation type name %s"),
1633
0
       abfd, l_r_name);
1634
0
  bfd_set_error (bfd_error_bad_value);
1635
0
  return BFD_RELOC_NONE;
1636
0
}
1637
1638
1639
/* Functions for reloc bits field.
1640
   1.  Signed extend *fix_val.
1641
   2.  Return false if overflow.  */
1642
1643
#define LARCH_RELOC_BFD_VMA_BIT_MASK(bitsize) \
1644
  (~((((bfd_vma)0x1) << (bitsize)) - 1))
1645
1646
/* Adjust val to perform insn
1647
   BFD_RELOC_LARCH_SOP_POP_32_S_10_5
1648
   BFD_RELOC_LARCH_SOP_POP_32_S_10_12
1649
   BFD_RELOC_LARCH_SOP_POP_32_U_10_12
1650
   BFD_RELOC_LARCH_SOP_POP_32_S_10_16
1651
   BFD_RELOC_LARCH_SOP_POP_32_S_5_20
1652
   BFD_RELOC_LARCH_SOP_POP_32_U.  */
1653
1654
static bool
1655
reloc_bits (bfd *abfd ATTRIBUTE_UNUSED,
1656
      reloc_howto_type *howto,
1657
      bfd_vma *fix_val)
1658
0
{
1659
0
  bfd_signed_vma val = (bfd_signed_vma)(*fix_val);
1660
0
  bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1;
1661
1662
0
  val = val >> howto->rightshift;
1663
1664
  /* Perform insn bits field.  */
1665
0
  val = val & mask;
1666
0
  val <<= howto->bitpos;
1667
1668
0
  *fix_val = (bfd_vma)val;
1669
1670
0
  return true;
1671
0
}
1672
1673
static bool
1674
reloc_sign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val)
1675
0
{
1676
0
  if (howto->complain_on_overflow != complain_overflow_signed)
1677
0
    return false;
1678
1679
0
  bfd_signed_vma val = (bfd_signed_vma)(*fix_val);
1680
1681
  /* Check alignment. FIXME: if rightshift is not alingment.  */
1682
0
  if (howto->rightshift
1683
0
      && (val & ((((bfd_signed_vma) 1) << howto->rightshift) - 1)))
1684
0
    {
1685
0
      (*_bfd_error_handler) (_("%pB: relocation %s right shift %d error 0x%lx"),
1686
0
           abfd, howto->name, howto->rightshift, (long) val);
1687
0
      bfd_set_error (bfd_error_bad_value);
1688
0
      return false;
1689
0
    }
1690
1691
0
  bfd_signed_vma mask = ((bfd_signed_vma)0x1 << (howto->bitsize
1692
0
        + howto->rightshift - 1)) - 1;
1693
1694
  /* Positive number: high part is all 0;
1695
     Negative number: if high part is not all 0, high part must be all 1.
1696
     high part: from sign bit to highest bit.  */
1697
0
  if ((val & ~mask) && ((val & ~mask) != ~mask))
1698
0
    {
1699
0
      (*_bfd_error_handler) (_("%pB: relocation %s overflow 0x%lx"),
1700
0
           abfd, howto->name, (long) val);
1701
0
      bfd_set_error (bfd_error_bad_value);
1702
0
      return false;
1703
0
    }
1704
1705
0
  val = val >> howto->rightshift;
1706
  /* can delete? */
1707
0
  mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1;
1708
0
  val = val & mask;
1709
1710
0
  switch (howto->type)
1711
0
    {
1712
0
    case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
1713
0
    case R_LARCH_B26:
1714
      /* Perform insn bits field. 15:0<<10, 25:16>>16.  */
1715
0
      val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff);
1716
0
      break;
1717
0
    case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
1718
0
    case R_LARCH_B21:
1719
      /* Perform insn bits field. 15:0<<10, 20:16>>16.  */
1720
0
      val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f);
1721
0
      break;
1722
0
    default:
1723
0
      val <<= howto->bitpos;
1724
0
      break;
1725
0
    }
1726
1727
0
  *fix_val = val;
1728
0
  return true;
1729
0
}
1730
1731
bool
1732
loongarch_adjust_reloc_bitsfield (bfd *abfd, reloc_howto_type *howto,
1733
          bfd_vma *fix_val)
1734
0
{
1735
0
  BFD_ASSERT (((loongarch_reloc_howto_type *)howto)->adjust_reloc_bits);
1736
0
  return ((loongarch_reloc_howto_type *)
1737
0
    howto)->adjust_reloc_bits (abfd, howto, fix_val);
1738
0
}
1739
1740
static bfd_reloc_status_type
1741
loongarch_elf_add_sub_reloc (bfd *abfd,
1742
         arelent *reloc_entry,
1743
         asymbol *symbol,
1744
         void *data,
1745
         asection *input_section,
1746
         bfd *output_bfd,
1747
         char **error_message ATTRIBUTE_UNUSED)
1748
0
{
1749
0
  reloc_howto_type *howto = reloc_entry->howto;
1750
0
  bfd_vma relocation;
1751
1752
0
  if (output_bfd != NULL
1753
0
      && (symbol->flags & BSF_SECTION_SYM) == 0
1754
0
      && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
1755
0
    {
1756
0
      reloc_entry->address += input_section->output_offset;
1757
0
      return bfd_reloc_ok;
1758
0
    }
1759
1760
0
  if (output_bfd != NULL)
1761
0
    return bfd_reloc_continue;
1762
1763
0
  relocation = symbol->value + symbol->section->output_section->vma
1764
0
    + symbol->section->output_offset + reloc_entry->addend;
1765
1766
0
  bfd_size_type octets = reloc_entry->address
1767
0
    * bfd_octets_per_byte (abfd, input_section);
1768
0
  if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
1769
0
          input_section, octets))
1770
0
    return bfd_reloc_outofrange;
1771
1772
0
  bfd_vma old_value = bfd_get (howto->bitsize, abfd,
1773
0
             data + reloc_entry->address);
1774
1775
0
  switch (howto->type)
1776
0
    {
1777
0
    case R_LARCH_ADD6:
1778
0
    case R_LARCH_ADD8:
1779
0
    case R_LARCH_ADD16:
1780
0
    case R_LARCH_ADD32:
1781
0
    case R_LARCH_ADD64:
1782
0
      relocation = old_value + relocation;
1783
0
      break;
1784
1785
0
    case R_LARCH_SUB6:
1786
0
    case R_LARCH_SUB8:
1787
0
    case R_LARCH_SUB16:
1788
0
    case R_LARCH_SUB32:
1789
0
    case R_LARCH_SUB64:
1790
0
      relocation = old_value - relocation;
1791
0
      break;
1792
0
    }
1793
1794
0
  bfd_put (howto->bitsize, abfd, relocation, data + reloc_entry->address);
1795
1796
0
  return bfd_reloc_ok;
1797
0
}
1798
1799
static bfd_reloc_status_type
1800
loongarch_elf_add_sub_reloc_uleb128 (bfd *abfd,
1801
         arelent *reloc_entry,
1802
         asymbol *symbol,
1803
         void *data,
1804
         asection *input_section,
1805
         bfd *output_bfd,
1806
         char **error_message ATTRIBUTE_UNUSED)
1807
0
{
1808
0
  reloc_howto_type *howto = reloc_entry->howto;
1809
0
  bfd_vma relocation;
1810
1811
0
 if (output_bfd != NULL
1812
0
     && (symbol->flags & BSF_SECTION_SYM) == 0
1813
0
     && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
1814
0
   {
1815
0
     reloc_entry->address += input_section->output_offset;
1816
0
     return bfd_reloc_ok;
1817
0
   }
1818
1819
0
  if (output_bfd != NULL)
1820
0
    return bfd_reloc_continue;
1821
1822
0
  relocation = symbol->value + symbol->section->output_section->vma
1823
0
    + symbol->section->output_offset + reloc_entry->addend;
1824
1825
0
  bfd_size_type octets = reloc_entry->address
1826
0
    * bfd_octets_per_byte (abfd, input_section);
1827
0
  if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
1828
0
          input_section, octets))
1829
0
    return bfd_reloc_outofrange;
1830
1831
0
  unsigned int len = 0;
1832
0
  bfd_byte *p = data + reloc_entry->address;
1833
0
  bfd_vma old_value = _bfd_read_unsigned_leb128 (abfd, p, &len);
1834
1835
0
  switch (howto->type)
1836
0
    {
1837
0
    case R_LARCH_ADD_ULEB128:
1838
0
      relocation = old_value + relocation;
1839
0
      break;
1840
1841
0
    case R_LARCH_SUB_ULEB128:
1842
0
      relocation = old_value - relocation;
1843
0
      break;
1844
0
    }
1845
1846
0
  bfd_vma mask = (1 << (7 * len)) - 1;
1847
0
  relocation = relocation & mask;
1848
0
  loongarch_write_unsigned_leb128 (p, len, relocation);
1849
0
  return bfd_reloc_ok;
1850
0
}
1851
1852
/* Write VALUE in uleb128 format to P.
1853
   LEN is the uleb128 value length.
1854
   Return a pointer to the byte following the last byte that was written.  */
1855
bfd_byte *
1856
loongarch_write_unsigned_leb128 (bfd_byte *p, unsigned int len, bfd_vma value)
1857
0
{
1858
0
  bfd_byte c;
1859
0
  do
1860
0
    {
1861
0
      c = value & 0x7f;
1862
0
      if (len > 1)
1863
0
  c |= 0x80;
1864
0
      *(p++) = c;
1865
0
      value >>= 7;
1866
0
      len--;
1867
0
    }
1868
0
  while (len);
1869
0
  return p;
1870
0
}
1871
1872
int loongarch_get_uleb128_length (bfd_byte *buf)
1873
0
{
1874
0
  unsigned int len = 0;
1875
0
  _bfd_read_unsigned_leb128 (NULL, buf, &len);
1876
0
  return len;
1877
0
}