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