Home | History | Annotate | Line # | Download | only in bfd
elfxx-loongarch.c revision 1.1.1.1
      1  1.1  christos /* LoongArch-specific support for ELF.
      2  1.1  christos    Copyright (C) 2021-2022 Free Software Foundation, Inc.
      3  1.1  christos    Contributed by Loongson Ltd.
      4  1.1  christos 
      5  1.1  christos    Based on RISC-V target.
      6  1.1  christos 
      7  1.1  christos    This file is part of BFD, the Binary File Descriptor library.
      8  1.1  christos 
      9  1.1  christos    This program is free software; you can redistribute it and/or modify
     10  1.1  christos    it under the terms of the GNU General Public License as published by
     11  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     12  1.1  christos    (at your option) any later version.
     13  1.1  christos 
     14  1.1  christos    This program is distributed in the hope that it will be useful,
     15  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17  1.1  christos    GNU General Public License for more details.
     18  1.1  christos 
     19  1.1  christos    You should have received a copy of the GNU General Public License
     20  1.1  christos    along with this program; see the file COPYING3.  If not,
     21  1.1  christos    see <http://www.gnu.org/licenses/>.  */
     22  1.1  christos 
     23  1.1  christos #include "sysdep.h"
     24  1.1  christos #include "bfd.h"
     25  1.1  christos #include "libbfd.h"
     26  1.1  christos #include "elf-bfd.h"
     27  1.1  christos #include "elf/loongarch.h"
     28  1.1  christos #include "elfxx-loongarch.h"
     29  1.1  christos 
     30  1.1  christos #define ALL_ONES (~ (bfd_vma) 0)
     31  1.1  christos 
     32  1.1  christos typedef struct loongarch_reloc_howto_type_struct
     33  1.1  christos {
     34  1.1  christos   /* The first must be reloc_howto_type!  */
     35  1.1  christos   reloc_howto_type howto;
     36  1.1  christos   bfd_reloc_code_real_type bfd_type;
     37  1.1  christos   bool (*adjust_reloc_bits)(reloc_howto_type *, bfd_vma *);
     38  1.1  christos }loongarch_reloc_howto_type;
     39  1.1  christos 
     40  1.1  christos #define LOONGARCH_DEFAULT_HOWTO(r_name)					    \
     41  1.1  christos   { HOWTO (R_LARCH_##r_name, 0, 4, 32, false, 0, complain_overflow_signed,  \
     42  1.1  christos 	bfd_elf_generic_reloc, "R_LARCH_" #r_name, false, 0, ALL_ONES,	    \
     43  1.1  christos 	false), BFD_RELOC_LARCH_##r_name, NULL }
     44  1.1  christos 
     45  1.1  christos #define LOONGARCH_HOWTO(type, right, size, bits, pcrel, left, ovf, func,  \
     46  1.1  christos 	    name, inplace, src_mask, dst_mask, pcrel_off, btype, afunc)	  \
     47  1.1  christos   { HOWTO(type, right, size, bits, pcrel, left, ovf, func, name,	  \
     48  1.1  christos 	  inplace, src_mask, dst_mask, pcrel_off), btype, afunc }
     49  1.1  christos 
     50  1.1  christos #define LOONGARCH_EMPTY_HOWTO(C) \
     51  1.1  christos   { EMPTY_HOWTO(C), BFD_RELOC_NONE, NULL }
     52  1.1  christos 
     53  1.1  christos bool loongarch_gen_adjust_reloc_bits (reloc_howto_type *howto, bfd_vma *val);
     54  1.1  christos bool loongarch_adjust_reloc_bits_l16_xx5_h5 (reloc_howto_type *howto,
     55  1.1  christos 					     bfd_vma *fix_val);
     56  1.1  christos bool loongarch_adjust_reloc_bits_l16_h10 (reloc_howto_type *howto,
     57  1.1  christos 					  bfd_vma *val);
     58  1.1  christos 
     59  1.1  christos 
     60  1.1  christos /* This does not include any relocation information, but should be
     61  1.1  christos    good enough for GDB or objdump to read the file.  */
     62  1.1  christos static loongarch_reloc_howto_type loongarch_howto_table[] =
     63  1.1  christos {
     64  1.1  christos   /* No relocation.  */
     65  1.1  christos     LOONGARCH_HOWTO (R_LARCH_NONE,	  /* type (0).  */
     66  1.1  christos 	 0,				  /* rightshift */
     67  1.1  christos 	 0,				  /* size */
     68  1.1  christos 	 0,				  /* bitsize */
     69  1.1  christos 	 false,				  /* pc_relative */
     70  1.1  christos 	 0,				  /* bitpos */
     71  1.1  christos 	 complain_overflow_dont,	  /* complain_on_overflow */
     72  1.1  christos 	 bfd_elf_generic_reloc,		  /* special_function */
     73  1.1  christos 	 "R_LARCH_NONE",		  /* name */
     74  1.1  christos 	 false,				  /* partial_inplace */
     75  1.1  christos 	 0,				  /* src_mask */
     76  1.1  christos 	 0,				  /* dst_mask */
     77  1.1  christos 	 false,				  /* pcrel_offset */
     78  1.1  christos 	 BFD_RELOC_NONE,		  /* bfd_reloc_code_real_type */
     79  1.1  christos 	 NULL),				  /* adjust_reloc_bits */
     80  1.1  christos 
     81  1.1  christos   /* 32 bit relocation.  */
     82  1.1  christos   LOONGARCH_HOWTO (R_LARCH_32,		  /* type (1).  */
     83  1.1  christos 	 0,				  /* rightshift */
     84  1.1  christos 	 4,				  /* size */
     85  1.1  christos 	 32,				  /* bitsize */
     86  1.1  christos 	 false,				  /* pc_relative */
     87  1.1  christos 	 0,				  /* bitpos */
     88  1.1  christos 	 complain_overflow_dont,	  /* complain_on_overflow */
     89  1.1  christos 	 bfd_elf_generic_reloc,		  /* special_function */
     90  1.1  christos 	 "R_LARCH_32",			  /* name */
     91  1.1  christos 	 false,				  /* partial_inplace */
     92  1.1  christos 	 0,				  /* src_mask */
     93  1.1  christos 	 ALL_ONES,			  /* dst_mask */
     94  1.1  christos 	 false,				  /* pcrel_offset */
     95  1.1  christos 	 BFD_RELOC_32,			  /* bfd_reloc_code_real_type */
     96  1.1  christos 	 NULL),				  /* adjust_reloc_bits */
     97  1.1  christos 
     98  1.1  christos   /* 64 bit relocation.  */
     99  1.1  christos   LOONGARCH_HOWTO (R_LARCH_64,		  /* type (2).  */
    100  1.1  christos 	 0,				  /* rightshift */
    101  1.1  christos 	 8,				  /* size */
    102  1.1  christos 	 64,				  /* bitsize */
    103  1.1  christos 	 false,				  /* pc_relative */
    104  1.1  christos 	 0,				  /* bitpos */
    105  1.1  christos 	 complain_overflow_dont,	  /* complain_on_overflow */
    106  1.1  christos 	 bfd_elf_generic_reloc,		  /* special_function */
    107  1.1  christos 	 "R_LARCH_64",			  /* name */
    108  1.1  christos 	 false,				  /* partial_inplace */
    109  1.1  christos 	 0,				  /* src_mask */
    110  1.1  christos 	 ALL_ONES,			  /* dst_mask */
    111  1.1  christos 	 false,				  /* pcrel_offset */
    112  1.1  christos 	 BFD_RELOC_64,			  /* bfd_reloc_code_real_type */
    113  1.1  christos 	 NULL),				  /* adjust_reloc_bits */
    114  1.1  christos 
    115  1.1  christos   LOONGARCH_HOWTO (R_LARCH_RELATIVE,	  /* type (3).  */
    116  1.1  christos 	 0,				  /* rightshift */
    117  1.1  christos 	 4,				  /* size */
    118  1.1  christos 	 32,				  /* bitsize */
    119  1.1  christos 	 false,				  /* pc_relative */
    120  1.1  christos 	 0,				  /* bitpos */
    121  1.1  christos 	 complain_overflow_dont,	  /* complain_on_overflow */
    122  1.1  christos 	 bfd_elf_generic_reloc,		  /* special_function */
    123  1.1  christos 	 "R_LARCH_RELATIVE",		  /* name */
    124  1.1  christos 	 false,				  /* partial_inplace */
    125  1.1  christos 	 0,				  /* src_mask */
    126  1.1  christos 	 ALL_ONES,			  /* dst_mask */
    127  1.1  christos 	 false,				  /* pcrel_offset */
    128  1.1  christos 	 BFD_RELOC_NONE,		  /* undefined?  */
    129  1.1  christos 	 NULL),				  /* adjust_reloc_bits */
    130  1.1  christos 
    131  1.1  christos   LOONGARCH_HOWTO (R_LARCH_COPY,	  /* type (4).  */
    132  1.1  christos 	 0,				  /* rightshift */
    133  1.1  christos 	 0,				  /* this one is variable size */
    134  1.1  christos 	 0,				  /* bitsize */
    135  1.1  christos 	 false,				  /* pc_relative */
    136  1.1  christos 	 0,				  /* bitpos */
    137  1.1  christos 	 complain_overflow_bitfield,	  /* complain_on_overflow */
    138  1.1  christos 	 bfd_elf_generic_reloc,		  /* special_function */
    139  1.1  christos 	 "R_LARCH_COPY",		  /* name */
    140  1.1  christos 	 false,				  /* partial_inplace */
    141  1.1  christos 	 0,				  /* src_mask */
    142  1.1  christos 	 0,				  /* dst_mask */
    143  1.1  christos 	 false,				  /* pcrel_offset */
    144  1.1  christos 	 BFD_RELOC_NONE,			  /* undefined?  */
    145  1.1  christos 	 NULL),				  /* adjust_reloc_bits */
    146  1.1  christos 
    147  1.1  christos   LOONGARCH_HOWTO (R_LARCH_JUMP_SLOT,	  /* type (5).  */
    148  1.1  christos 	 0,				  /* rightshift */
    149  1.1  christos 	 8,				  /* size */
    150  1.1  christos 	 64,				  /* bitsize */
    151  1.1  christos 	 false,				  /* pc_relative */
    152  1.1  christos 	 0,				  /* bitpos */
    153  1.1  christos 	 complain_overflow_bitfield,	  /* complain_on_overflow */
    154  1.1  christos 	 bfd_elf_generic_reloc,		  /* special_function */
    155  1.1  christos 	 "R_LARCH_JUMP_SLOT",		  /* name */
    156  1.1  christos 	 false,				  /* partial_inplace */
    157  1.1  christos 	 0,				  /* src_mask */
    158  1.1  christos 	 0,				  /* dst_mask */
    159  1.1  christos 	 false,				  /* pcrel_offset */
    160  1.1  christos 	 BFD_RELOC_NONE,			  /* undefined?  */
    161  1.1  christos 	 NULL),				  /* adjust_reloc_bits */
    162  1.1  christos 
    163  1.1  christos   /* Dynamic TLS relocations.  */
    164  1.1  christos   LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD32,  /* type (6).  */
    165  1.1  christos 	 0,				  /* rightshift */
    166  1.1  christos 	 4,				  /* size */
    167  1.1  christos 	 32,				  /* bitsize */
    168  1.1  christos 	 false,				  /* pc_relative */
    169  1.1  christos 	 0,				  /* bitpos */
    170  1.1  christos 	 complain_overflow_dont,	  /* complain_on_overflow */
    171  1.1  christos 	 bfd_elf_generic_reloc,		  /* special_function */
    172  1.1  christos 	 "R_LARCH_TLS_DTPMOD32",	  /* name */
    173  1.1  christos 	 false,				  /* partial_inplace */
    174  1.1  christos 	 0,				  /* src_mask */
    175  1.1  christos 	 ALL_ONES,			  /* dst_mask */
    176  1.1  christos 	 false,				  /* pcrel_offset */
    177  1.1  christos 	 BFD_RELOC_LARCH_TLS_DTPMOD32,	  /* bfd_reloc_code_real_type */
    178  1.1  christos 	 NULL),				  /* adjust_reloc_bits */
    179  1.1  christos 
    180  1.1  christos   LOONGARCH_HOWTO (R_LARCH_TLS_DTPMOD64,  /* type (7).  */
    181  1.1  christos 	 0,				  /* rightshift */
    182  1.1  christos 	 8,				  /* size */
    183  1.1  christos 	 64,				  /* bitsize */
    184  1.1  christos 	 false,				  /* pc_relative */
    185  1.1  christos 	 0,				  /* bitpos */
    186  1.1  christos 	 complain_overflow_dont,	  /* complain_on_overflow */
    187  1.1  christos 	 bfd_elf_generic_reloc,		  /* special_function */
    188  1.1  christos 	 "R_LARCH_TLS_DTPMOD64",	  /* name */
    189  1.1  christos 	 false,				  /* partial_inplace */
    190  1.1  christos 	 0,				  /* src_mask */
    191  1.1  christos 	 ALL_ONES,			  /* dst_mask */
    192  1.1  christos 	 false,				  /* pcrel_offset */
    193  1.1  christos 	 BFD_RELOC_LARCH_TLS_DTPMOD64,	  /* bfd_reloc_code_real_type */
    194  1.1  christos 	 NULL),				  /* adjust_reloc_bits */
    195  1.1  christos 
    196  1.1  christos   LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL32,  /* type (8). */
    197  1.1  christos 	 0,				  /* rightshift */
    198  1.1  christos 	 4,				  /* size */
    199  1.1  christos 	 32,				  /* bitsize */
    200  1.1  christos 	 false,				  /* pc_relative */
    201  1.1  christos 	 0,				  /* bitpos */
    202  1.1  christos 	 complain_overflow_dont,	  /* complain_on_overflow */
    203  1.1  christos 	 bfd_elf_generic_reloc,		  /* special_function */
    204  1.1  christos 	 "R_LARCH_TLS_DTPREL32",	  /* name */
    205  1.1  christos 	 true,				  /* partial_inplace */
    206  1.1  christos 	 0,				  /* src_mask */
    207  1.1  christos 	 ALL_ONES,			  /* dst_mask */
    208  1.1  christos 	 false,				  /* pcrel_offset */
    209  1.1  christos 	 BFD_RELOC_LARCH_TLS_DTPREL32,	  /* bfd_reloc_code_real_type */
    210  1.1  christos 	 NULL),				  /* adjust_reloc_bits */
    211  1.1  christos 
    212  1.1  christos   LOONGARCH_HOWTO (R_LARCH_TLS_DTPREL64,  /* type (9).  */
    213  1.1  christos 	 0,				  /* rightshift */
    214  1.1  christos 	 8,				  /* size */
    215  1.1  christos 	 64,				  /* bitsize */
    216  1.1  christos 	 false,				  /* pc_relative */
    217  1.1  christos 	 0,				  /* bitpos */
    218  1.1  christos 	 complain_overflow_dont,	  /* complain_on_overflow */
    219  1.1  christos 	 bfd_elf_generic_reloc,		  /* special_function */
    220  1.1  christos 	 "R_LARCH_TLS_DTPREL64",	  /* name */
    221  1.1  christos 	 true,				  /* partial_inplace */
    222  1.1  christos 	 0,				  /* src_mask */
    223  1.1  christos 	 ALL_ONES,			  /* dst_mask */
    224  1.1  christos 	 false,				  /* pcrel_offset */
    225  1.1  christos 	 BFD_RELOC_LARCH_TLS_DTPREL64,	  /* bfd_reloc_code_real_type */
    226  1.1  christos 	 NULL),				  /* adjust_reloc_bits */
    227  1.1  christos 
    228  1.1  christos   LOONGARCH_HOWTO (R_LARCH_TLS_TPREL32,	  /* type (10).  */
    229  1.1  christos 	 0,				  /* rightshift */
    230  1.1  christos 	 4,				  /* size */
    231  1.1  christos 	 32,				  /* bitsize */
    232  1.1  christos 	 false,				  /* pc_relative */
    233  1.1  christos 	 0,				  /* bitpos */
    234  1.1  christos 	 complain_overflow_dont,	  /* complain_on_overflow */
    235  1.1  christos 	 bfd_elf_generic_reloc,		  /* special_function */
    236  1.1  christos 	 "R_LARCH_TLS_TPREL32",		  /* name */
    237  1.1  christos 	 false,				  /* partial_inplace */
    238  1.1  christos 	 0,				  /* src_mask */
    239  1.1  christos 	 ALL_ONES,			  /* dst_mask */
    240  1.1  christos 	 false,				  /* pcrel_offset */
    241  1.1  christos 	 BFD_RELOC_LARCH_TLS_TPREL32,	  /* bfd_reloc_code_real_type */
    242  1.1  christos 	 NULL),				  /* adjust_reloc_bits */
    243  1.1  christos 
    244  1.1  christos   LOONGARCH_HOWTO (R_LARCH_TLS_TPREL64,	  /* type (11).  */
    245  1.1  christos 	 0,				  /* rightshift */
    246  1.1  christos 	 8,				  /* size */
    247  1.1  christos 	 64,				  /* bitsize */
    248  1.1  christos 	 false,				  /* pc_relative */
    249  1.1  christos 	 0,				  /* bitpos */
    250  1.1  christos 	 complain_overflow_dont,	  /* complain_on_overflow */
    251  1.1  christos 	 bfd_elf_generic_reloc,		  /* special_function */
    252  1.1  christos 	 "R_LARCH_TLS_TPREL64",		  /* name */
    253  1.1  christos 	 false,				  /* partial_inplace */
    254  1.1  christos 	 0,				  /* src_mask */
    255  1.1  christos 	 ALL_ONES,			  /* dst_mask */
    256  1.1  christos 	 false,				  /* pcrel_offset */
    257  1.1  christos 	 BFD_RELOC_LARCH_TLS_TPREL64,	  /* bfd_reloc_code_real_type */
    258  1.1  christos 	 NULL),				  /* adjust_reloc_bits */
    259  1.1  christos 
    260  1.1  christos   LOONGARCH_HOWTO (R_LARCH_IRELATIVE,	  /* type (12).  */
    261  1.1  christos 	 0,				  /* rightshift */
    262  1.1  christos 	 4,				  /* size */
    263  1.1  christos 	 32,				  /* bitsize */
    264  1.1  christos 	 false,				  /* pc_relative */
    265  1.1  christos 	 0,				  /* bitpos */
    266  1.1  christos 	 complain_overflow_dont,	  /* complain_on_overflow */
    267  1.1  christos 	 bfd_elf_generic_reloc,		  /* special_function */
    268  1.1  christos 	 "R_LARCH_IRELATIVE",		  /* name */
    269  1.1  christos 	 false,				  /* partial_inplace */
    270  1.1  christos 	 0,				  /* src_mask */
    271  1.1  christos 	 ALL_ONES,			  /* dst_mask */
    272  1.1  christos 	 false,				  /* pcrel_offset */
    273  1.1  christos 	 BFD_RELOC_NONE,		  /* undefined?  */
    274  1.1  christos 	 NULL),				  /* adjust_reloc_bits */
    275  1.1  christos 
    276  1.1  christos   LOONGARCH_EMPTY_HOWTO(13),
    277  1.1  christos   LOONGARCH_EMPTY_HOWTO(14),
    278  1.1  christos   LOONGARCH_EMPTY_HOWTO(15),
    279  1.1  christos   LOONGARCH_EMPTY_HOWTO(16),
    280  1.1  christos   LOONGARCH_EMPTY_HOWTO(17),
    281  1.1  christos   LOONGARCH_EMPTY_HOWTO(18),
    282  1.1  christos   LOONGARCH_EMPTY_HOWTO(19),
    283  1.1  christos 
    284  1.1  christos   LOONGARCH_HOWTO (R_LARCH_MARK_LA,		/* type (20).  */
    285  1.1  christos 	 0,				   	/* rightshift.  */
    286  1.1  christos 	 0,				   	/* size.  */
    287  1.1  christos 	 0,				  	/* bitsize.  */
    288  1.1  christos 	 false,					/* pc_relative.  */
    289  1.1  christos 	 0,				   	/* bitpos.  */
    290  1.1  christos 	 complain_overflow_signed,	    	/* complain_on_overflow.  */
    291  1.1  christos 	 bfd_elf_generic_reloc,	       		/* special_function.  */
    292  1.1  christos 	 "R_LARCH_MARK_LA",			/* name.  */
    293  1.1  christos 	 false,			       		/* partial_inplace.  */
    294  1.1  christos 	 0,					/* src_mask.  */
    295  1.1  christos 	 0,					/* dst_mask.  */
    296  1.1  christos 	 false,					/* pcrel_offset */
    297  1.1  christos 	 BFD_RELOC_LARCH_MARK_LA,		/* bfd_reloc_code_real_type */
    298  1.1  christos 	 NULL),					/* adjust_reloc_bits */
    299  1.1  christos 
    300  1.1  christos   LOONGARCH_HOWTO (R_LARCH_MARK_PCREL,		/* type (21).  */
    301  1.1  christos 	 0,				   	/* rightshift.  */
    302  1.1  christos 	 0,				   	/* size.  */
    303  1.1  christos 	 0,				  	/* bitsize.  */
    304  1.1  christos 	 false,					/* pc_relative.  */
    305  1.1  christos 	 0,				   	/* bitpos.  */
    306  1.1  christos 	 complain_overflow_signed,	    	/* complain_on_overflow.  */
    307  1.1  christos 	 bfd_elf_generic_reloc,	       		/* special_function.  */
    308  1.1  christos 	 "R_LARCH_MARK_PCREL",			/* name.  */
    309  1.1  christos 	 false,			       		/* partial_inplace.  */
    310  1.1  christos 	 0,					/* src_mask.  */
    311  1.1  christos 	 0,					/* dst_mask.  */
    312  1.1  christos 	 false,					/* pcrel_offset */
    313  1.1  christos 	 BFD_RELOC_LARCH_MARK_PCREL,		/* bfd_reloc_code_real_type */
    314  1.1  christos 	 NULL),					/* adjust_reloc_bits */
    315  1.1  christos 
    316  1.1  christos   LOONGARCH_HOWTO (R_LARCH_SOP_PUSH_PCREL,	/* type (22).  */
    317  1.1  christos 	 2,				   	/* rightshift.  */
    318  1.1  christos 	 4,				   	/* size.  */
    319  1.1  christos 	 32,				  	/* bitsize.  */
    320  1.1  christos 	 true /* FIXME: somewhat use this.  */,	/* pc_relative.  */
    321  1.1  christos 	 0,				   	/* bitpos.  */
    322  1.1  christos 	 complain_overflow_signed,	    	/* complain_on_overflow.  */
    323  1.1  christos 	 bfd_elf_generic_reloc,	       		/* special_function.  */
    324  1.1  christos 	 "R_LARCH_SOP_PUSH_PCREL",	    	/* name.  */
    325  1.1  christos 	 false,			       		/* partial_inplace.  */
    326  1.1  christos 	 0x03ffffff,				/* src_mask.  */
    327  1.1  christos 	 0x03ffffff,				/* dst_mask.  */
    328  1.1  christos 	 false,					/* pcrel_offset */
    329  1.1  christos 	 BFD_RELOC_LARCH_SOP_PUSH_PCREL,	/* bfd_reloc_code_real_type */
    330  1.1  christos 	 NULL),					/* adjust_reloc_bits */
    331  1.1  christos 
    332  1.1  christos   /* type 23-37.  */
    333  1.1  christos   LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_ABSOLUTE),
    334  1.1  christos   LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_DUP),
    335  1.1  christos   LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_GPREL),
    336  1.1  christos   LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_TLS_TPREL),
    337  1.1  christos   LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_TLS_GOT),
    338  1.1  christos   LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_TLS_GD),
    339  1.1  christos   LOONGARCH_DEFAULT_HOWTO (SOP_PUSH_PLT_PCREL),
    340  1.1  christos   LOONGARCH_DEFAULT_HOWTO (SOP_ASSERT),
    341  1.1  christos   LOONGARCH_DEFAULT_HOWTO (SOP_NOT),
    342  1.1  christos   LOONGARCH_DEFAULT_HOWTO (SOP_SUB),
    343  1.1  christos   LOONGARCH_DEFAULT_HOWTO (SOP_SL),
    344  1.1  christos   LOONGARCH_DEFAULT_HOWTO (SOP_SR),
    345  1.1  christos   LOONGARCH_DEFAULT_HOWTO (SOP_ADD),
    346  1.1  christos   LOONGARCH_DEFAULT_HOWTO (SOP_AND),
    347  1.1  christos   LOONGARCH_DEFAULT_HOWTO (SOP_IF_ELSE),
    348  1.1  christos 
    349  1.1  christos   LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_5,	  /* type (38).  */
    350  1.1  christos 	 0,				   	  /* rightshift.  */
    351  1.1  christos 	 4,				   	  /* size.  */
    352  1.1  christos 	 5,				  	  /* bitsize.  */
    353  1.1  christos 	 false,					  /* pc_relative.  */
    354  1.1  christos 	 10,				   	  /* bitpos.  */
    355  1.1  christos 	 complain_overflow_signed,	    	  /* complain_on_overflow.  */
    356  1.1  christos 	 bfd_elf_generic_reloc,	       		  /* special_function.  */
    357  1.1  christos 	 "R_LARCH_SOP_POP_32_S_10_5",	    	  /* name.  */
    358  1.1  christos 	 false,			       		  /* partial_inplace.  */
    359  1.1  christos 	 0,					  /* src_mask */
    360  1.1  christos 	 0x7c00,				  /* dst_mask */
    361  1.1  christos 	 false,					  /* pcrel_offset */
    362  1.1  christos 	 BFD_RELOC_LARCH_SOP_POP_32_S_10_5,	  /* bfd_reloc_code_real_type */
    363  1.1  christos 	 loongarch_gen_adjust_reloc_bits),	  /* adjust_reloc_bits */
    364  1.1  christos 
    365  1.1  christos   LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U_10_12,	  /* type (39).  */
    366  1.1  christos 	 0,				   	  /* rightshift.  */
    367  1.1  christos 	 4,				   	  /* size.  */
    368  1.1  christos 	 12,				  	  /* bitsize.  */
    369  1.1  christos 	 false,					  /* pc_relative.  */
    370  1.1  christos 	 10,				   	  /* bitpos.  */
    371  1.1  christos 	 complain_overflow_unsigned,	    	  /* complain_on_overflow.  */
    372  1.1  christos 	 bfd_elf_generic_reloc,	       		  /* special_function.  */
    373  1.1  christos 	 "R_LARCH_SOP_POP_32_U_10_12",	    	  /* name.  */
    374  1.1  christos 	 false,			       		  /* partial_inplace.  */
    375  1.1  christos 	 0,					  /* src_mask */
    376  1.1  christos 	 0x3ffc00,				  /* dst_mask */
    377  1.1  christos 	 false,					  /* pcrel_offset */
    378  1.1  christos 	 BFD_RELOC_LARCH_SOP_POP_32_U_10_12,	  /* bfd_reloc_code_real_type */
    379  1.1  christos 	 loongarch_gen_adjust_reloc_bits),	  /* adjust_reloc_bits */
    380  1.1  christos 
    381  1.1  christos   LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_12,	  /* type (40).  */
    382  1.1  christos 	 0,				   	  /* rightshift.  */
    383  1.1  christos 	 4,				   	  /* size.  */
    384  1.1  christos 	 12,				  	  /* bitsize.  */
    385  1.1  christos 	 false,					  /* pc_relative.  */
    386  1.1  christos 	 10,				   	  /* bitpos.  */
    387  1.1  christos 	 complain_overflow_signed,	    	  /* complain_on_overflow.  */
    388  1.1  christos 	 bfd_elf_generic_reloc,	       		  /* special_function.  */
    389  1.1  christos 	 "R_LARCH_SOP_POP_32_S_10_12",	    	  /* name.  */
    390  1.1  christos 	 false,			       		  /* partial_inplace.  */
    391  1.1  christos 	 0,					  /* src_mask */
    392  1.1  christos 	 0x3ffc00,				  /* dst_mask */
    393  1.1  christos 	 false,					  /* pcrel_offset */
    394  1.1  christos 	 BFD_RELOC_LARCH_SOP_POP_32_S_10_12,	  /* bfd_reloc_code_real_type */
    395  1.1  christos 	 loongarch_gen_adjust_reloc_bits),	  /* adjust_reloc_bits */
    396  1.1  christos 
    397  1.1  christos   LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16,	  /* type (41).  */
    398  1.1  christos 	 0,				   	  /* rightshift.  */
    399  1.1  christos 	 4,				   	  /* size.  */
    400  1.1  christos 	 16,				  	  /* bitsize.  */
    401  1.1  christos 	 false,					  /* pc_relative.  */
    402  1.1  christos 	 10,				   	  /* bitpos.  */
    403  1.1  christos 	 complain_overflow_signed,	    	  /* complain_on_overflow.  */
    404  1.1  christos 	 bfd_elf_generic_reloc,	       		  /* special_function.  */
    405  1.1  christos 	 "R_LARCH_SOP_POP_32_S_10_16",	    	  /* name.  */
    406  1.1  christos 	 false,			       		  /* partial_inplace.  */
    407  1.1  christos 	 0,					  /* src_mask */
    408  1.1  christos 	 0x3fffc00,				  /* dst_mask */
    409  1.1  christos 	 false,					  /* pcrel_offset */
    410  1.1  christos 	 BFD_RELOC_LARCH_SOP_POP_32_S_10_16,	  /* bfd_reloc_code_real_type */
    411  1.1  christos 	 loongarch_gen_adjust_reloc_bits),	  /* adjust_reloc_bits */
    412  1.1  christos 
    413  1.1  christos   LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_10_16_S2, /* type (42).  */
    414  1.1  christos 	 2,					  /* rightshift.  */
    415  1.1  christos 	 4,				   	  /* size.  */
    416  1.1  christos 	 16,				  	  /* bitsize.  */
    417  1.1  christos 	 false,					  /* pc_relative.  */
    418  1.1  christos 	 10,				   	  /* bitpos.  */
    419  1.1  christos 	 complain_overflow_signed,	    	  /* complain_on_overflow.  */
    420  1.1  christos 	 bfd_elf_generic_reloc,	       		  /* special_function.  */
    421  1.1  christos 	 "R_LARCH_SOP_POP_32_S_10_16_S2",    	  /* name.  */
    422  1.1  christos 	 false,			       		  /* partial_inplace.  */
    423  1.1  christos 	 0,					  /* src_mask */
    424  1.1  christos 	 0x3fffc00,				  /* dst_mask */
    425  1.1  christos 	 false,					  /* pcrel_offset */
    426  1.1  christos 	 BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2,	  /* bfd_reloc_code_real_type */
    427  1.1  christos 	 loongarch_gen_adjust_reloc_bits),	  /* adjust_reloc_bits */
    428  1.1  christos 
    429  1.1  christos   LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_5_20,	  /* type (43).  */
    430  1.1  christos 	 0,				   	  /* rightshift.  */
    431  1.1  christos 	 4,				   	  /* size.  */
    432  1.1  christos 	 20,				  	  /* bitsize.  */
    433  1.1  christos 	 false,					  /* pc_relative.  */
    434  1.1  christos 	 5,				   	  /* bitpos.  */
    435  1.1  christos 	 complain_overflow_signed,	    	  /* complain_on_overflow.  */
    436  1.1  christos 	 bfd_elf_generic_reloc,	       		  /* special_function.  */
    437  1.1  christos 	 "R_LARCH_SOP_POP_32_S_5_20",    	  /* name.  */
    438  1.1  christos 	 false,			       		  /* partial_inplace.  */
    439  1.1  christos 	 0,					  /* src_mask */
    440  1.1  christos 	 0x1ffffe0,				  /* dst_mask */
    441  1.1  christos 	 false,					  /* pcrel_offset */
    442  1.1  christos 	 BFD_RELOC_LARCH_SOP_POP_32_S_5_20,	  /* bfd_reloc_code_real_type */
    443  1.1  christos 	 loongarch_gen_adjust_reloc_bits),        /* adjust_reloc_bits */
    444  1.1  christos 
    445  1.1  christos   LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_5_10_16_S2,
    446  1.1  christos 						  /* type (44).  */
    447  1.1  christos 	 2,					  /* rightshift.  */
    448  1.1  christos 	 4,					  /* size.  */
    449  1.1  christos 	 21,				  	  /* bitsize.  */
    450  1.1  christos 	 false,					  /* pc_relative.  */
    451  1.1  christos 	 0,				   	  /* bitpos.  */
    452  1.1  christos 	 complain_overflow_signed,	    	  /* complain_on_overflow.  */
    453  1.1  christos 	 bfd_elf_generic_reloc,	       		  /* special_function.  */
    454  1.1  christos 	 "R_LARCH_SOP_POP_32_S_0_5_10_16_S2",  	  /* name.  */
    455  1.1  christos 	 false,			       		  /* partial_inplace.  */
    456  1.1  christos 	 0xfc0003e0,				  /* src_mask */
    457  1.1  christos 	 0xfc0003e0,				  /* dst_mask */
    458  1.1  christos 	 false,					  /* pcrel_offset */
    459  1.1  christos 	 BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2,
    460  1.1  christos 						  /* bfd_reloc_code_real_type */
    461  1.1  christos 	 loongarch_adjust_reloc_bits_l16_xx5_h5), /* adjust_reloc_bits */
    462  1.1  christos 
    463  1.1  christos   LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_10_10_16_S2,	/* type (45).  */
    464  1.1  christos 	 2,				   	/* rightshift.  */
    465  1.1  christos 	 4,				   	/* size.  */
    466  1.1  christos 	 26,				  	/* bitsize.  */
    467  1.1  christos 	 false,					/* pc_relative.  */
    468  1.1  christos 	 0,				   	/* bitpos.  */
    469  1.1  christos 	 complain_overflow_signed,	    	/* complain_on_overflow.  */
    470  1.1  christos 	 bfd_elf_generic_reloc,	       		/* special_function.  */
    471  1.1  christos 	 "R_LARCH_SOP_POP_32_S_0_10_10_16_S2", 	/* name.  */
    472  1.1  christos 	 false,			       		/* partial_inplace.  */
    473  1.1  christos 	 0xfc000000,				/* src_mask */
    474  1.1  christos 	 0xfc000000,				/* dst_mask */
    475  1.1  christos 	 false,					/* pcrel_offset */
    476  1.1  christos 	 BFD_RELOC_LARCH_SOP_POP_32_S_0_10_10_16_S2,
    477  1.1  christos 						/* bfd_reloc_code_real_type */
    478  1.1  christos 	 loongarch_adjust_reloc_bits_l16_h10),	/* adjust_reloc_bits */
    479  1.1  christos 
    480  1.1  christos   LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U,	/* type (46).  */
    481  1.1  christos 	 0,				   	/* rightshift.  */
    482  1.1  christos 	 4,				   	/* size.  */
    483  1.1  christos 	 32,				  	/* bitsize.  */
    484  1.1  christos 	 false,					/* pc_relative.  */
    485  1.1  christos 	 0,				   	/* bitpos.  */
    486  1.1  christos 	 complain_overflow_unsigned,	    	/* complain_on_overflow.  */
    487  1.1  christos 	 bfd_elf_generic_reloc,	       		/* special_function.  */
    488  1.1  christos 	 "R_LARCH_SOP_POP_32_S_U",    		/* name.  */
    489  1.1  christos 	 false,			       		/* partial_inplace.  */
    490  1.1  christos 	 0xffffffff00000000,			/* src_mask */
    491  1.1  christos 	 0x00000000ffffffff,			/* dst_mask */
    492  1.1  christos 	 false,					/* pcrel_offset */
    493  1.1  christos 	 BFD_RELOC_LARCH_SOP_POP_32_U,		/* bfd_reloc_code_real_type */
    494  1.1  christos 	 loongarch_gen_adjust_reloc_bits),	/* adjust_reloc_bits */
    495  1.1  christos 
    496  1.1  christos   LOONGARCH_HOWTO (R_LARCH_ADD8,	      	/* type (47).  */
    497  1.1  christos 	 0,				   	/* rightshift.  */
    498  1.1  christos 	 4,				   	/* size.  */
    499  1.1  christos 	 8,				  	/* bitsize.  */
    500  1.1  christos 	 false,					/* pc_relative.  */
    501  1.1  christos 	 0,				   	/* bitpos.  */
    502  1.1  christos 	 complain_overflow_signed,	    	/* complain_on_overflow.  */
    503  1.1  christos 	 bfd_elf_generic_reloc,	       		/* special_function.  */
    504  1.1  christos 	 "R_LARCH_ADD8",    			/* name.  */
    505  1.1  christos 	 false,			       		/* partial_inplace.  */
    506  1.1  christos 	 0,					/* src_mask */
    507  1.1  christos 	 ALL_ONES,				/* dst_mask */
    508  1.1  christos 	 false,					/* pcrel_offset */
    509  1.1  christos 	 BFD_RELOC_LARCH_ADD8,			/* bfd_reloc_code_real_type */
    510  1.1  christos 	 NULL),					/* adjust_reloc_bits */
    511  1.1  christos 
    512  1.1  christos   LOONGARCH_HOWTO (R_LARCH_ADD16,	      	/* type (48).  */
    513  1.1  christos 	 0,				   	/* rightshift.  */
    514  1.1  christos 	 4,				   	/* size.  */
    515  1.1  christos 	 16,				  	/* bitsize.  */
    516  1.1  christos 	 false,					/* pc_relative.  */
    517  1.1  christos 	 0,				   	/* bitpos.  */
    518  1.1  christos 	 complain_overflow_signed,	    	/* complain_on_overflow.  */
    519  1.1  christos 	 bfd_elf_generic_reloc,	       		/* special_function.  */
    520  1.1  christos 	 "R_LARCH_ADD16",    			/* name.  */
    521  1.1  christos 	 false,			       		/* partial_inplace.  */
    522  1.1  christos 	 0,					/* src_mask */
    523  1.1  christos 	 ALL_ONES,				/* dst_mask */
    524  1.1  christos 	 false,					/* pcrel_offset */
    525  1.1  christos 	 BFD_RELOC_LARCH_ADD16,			/* bfd_reloc_code_real_type */
    526  1.1  christos 	 NULL),					/* adjust_reloc_bits */
    527  1.1  christos 
    528  1.1  christos   LOONGARCH_HOWTO (R_LARCH_ADD24,	      	/* type (49).  */
    529  1.1  christos 	 0,				   	/* rightshift.  */
    530  1.1  christos 	 4,				   	/* size.  */
    531  1.1  christos 	 24,				  	/* bitsize.  */
    532  1.1  christos 	 false,					/* pc_relative.  */
    533  1.1  christos 	 0,				   	/* bitpos.  */
    534  1.1  christos 	 complain_overflow_signed,	    	/* complain_on_overflow.  */
    535  1.1  christos 	 bfd_elf_generic_reloc,	       		/* special_function.  */
    536  1.1  christos 	 "R_LARCH_ADD24",    			/* name.  */
    537  1.1  christos 	 false,			       		/* partial_inplace.  */
    538  1.1  christos 	 0,					/* src_mask */
    539  1.1  christos 	 ALL_ONES,				/* dst_mask */
    540  1.1  christos 	 false,					/* pcrel_offset */
    541  1.1  christos 	 BFD_RELOC_LARCH_ADD24,			/* bfd_reloc_code_real_type */
    542  1.1  christos 	 NULL),					/* adjust_reloc_bits */
    543  1.1  christos 
    544  1.1  christos   LOONGARCH_HOWTO (R_LARCH_ADD32,	      	/* type (50).  */
    545  1.1  christos 	 0,				   	/* rightshift.  */
    546  1.1  christos 	 4,				   	/* size.  */
    547  1.1  christos 	 32,				  	/* bitsize.  */
    548  1.1  christos 	 false,					/* pc_relative.  */
    549  1.1  christos 	 0,				   	/* bitpos.  */
    550  1.1  christos 	 complain_overflow_signed,	    	/* complain_on_overflow.  */
    551  1.1  christos 	 bfd_elf_generic_reloc,	       		/* special_function.  */
    552  1.1  christos 	 "R_LARCH_ADD32",    			/* name.  */
    553  1.1  christos 	 false,			       		/* partial_inplace.  */
    554  1.1  christos 	 0,					/* src_mask */
    555  1.1  christos 	 ALL_ONES,				/* dst_mask */
    556  1.1  christos 	 false,					/* pcrel_offset */
    557  1.1  christos 	 BFD_RELOC_LARCH_ADD32,			/* bfd_reloc_code_real_type */
    558  1.1  christos 	 NULL),					/* adjust_reloc_bits */
    559  1.1  christos 
    560  1.1  christos   LOONGARCH_HOWTO (R_LARCH_ADD64,	      	/* type (51).  */
    561  1.1  christos 	 0,				   	/* rightshift.  */
    562  1.1  christos 	 8,				   	/* size.  */
    563  1.1  christos 	 64,				  	/* bitsize.  */
    564  1.1  christos 	 false,					/* pc_relative.  */
    565  1.1  christos 	 0,				   	/* bitpos.  */
    566  1.1  christos 	 complain_overflow_signed,	    	/* complain_on_overflow.  */
    567  1.1  christos 	 bfd_elf_generic_reloc,	       		/* special_function.  */
    568  1.1  christos 	 "R_LARCH_ADD64",    			/* name.  */
    569  1.1  christos 	 false,			       		/* partial_inplace.  */
    570  1.1  christos 	 0,					/* src_mask */
    571  1.1  christos 	 ALL_ONES,				/* dst_mask */
    572  1.1  christos 	 false,					/* pcrel_offset */
    573  1.1  christos 	 BFD_RELOC_LARCH_ADD64,			/* bfd_reloc_code_real_type */
    574  1.1  christos 	 NULL),					/* adjust_reloc_bits */
    575  1.1  christos 
    576  1.1  christos   LOONGARCH_HOWTO (R_LARCH_SUB8,	      	/* type (52).  */
    577  1.1  christos 	 0,				   	/* rightshift.  */
    578  1.1  christos 	 4,				   	/* size.  */
    579  1.1  christos 	 8,				  	/* bitsize.  */
    580  1.1  christos 	 false,					/* pc_relative.  */
    581  1.1  christos 	 0,				   	/* bitpos.  */
    582  1.1  christos 	 complain_overflow_signed,	    	/* complain_on_overflow.  */
    583  1.1  christos 	 bfd_elf_generic_reloc,	       		/* special_function.  */
    584  1.1  christos 	 "R_LARCH_SUB8",    			/* name.  */
    585  1.1  christos 	 false,			       		/* partial_inplace.  */
    586  1.1  christos 	 0,					/* src_mask */
    587  1.1  christos 	 ALL_ONES,				/* dst_mask */
    588  1.1  christos 	 false,					/* pcrel_offset */
    589  1.1  christos 	 BFD_RELOC_LARCH_SUB8,			/* bfd_reloc_code_real_type */
    590  1.1  christos 	 NULL),					/* adjust_reloc_bits */
    591  1.1  christos 
    592  1.1  christos   LOONGARCH_HOWTO (R_LARCH_SUB16,	      	/* type (53).  */
    593  1.1  christos 	 0,				   	/* rightshift.  */
    594  1.1  christos 	 4,				   	/* size.  */
    595  1.1  christos 	 16,				  	/* bitsize.  */
    596  1.1  christos 	 false,					/* pc_relative.  */
    597  1.1  christos 	 0,				   	/* bitpos.  */
    598  1.1  christos 	 complain_overflow_signed,	    	/* complain_on_overflow.  */
    599  1.1  christos 	 bfd_elf_generic_reloc,	       		/* special_function.  */
    600  1.1  christos 	 "R_LARCH_SUB16",    			/* name.  */
    601  1.1  christos 	 false,			       		/* partial_inplace.  */
    602  1.1  christos 	 0,					/* src_mask */
    603  1.1  christos 	 ALL_ONES,				/* dst_mask */
    604  1.1  christos 	 false,					/* pcrel_offset */
    605  1.1  christos 	 BFD_RELOC_LARCH_SUB16,			/* bfd_reloc_code_real_type */
    606  1.1  christos 	 NULL),					/* adjust_reloc_bits */
    607  1.1  christos 
    608  1.1  christos   LOONGARCH_HOWTO (R_LARCH_SUB24,	      	/* type (54).  */
    609  1.1  christos 	 0,				   	/* rightshift.  */
    610  1.1  christos 	 4,				   	/* size.  */
    611  1.1  christos 	 24,				  	/* bitsize.  */
    612  1.1  christos 	 false,					/* pc_relative.  */
    613  1.1  christos 	 0,				   	/* bitpos.  */
    614  1.1  christos 	 complain_overflow_signed,	    	/* complain_on_overflow.  */
    615  1.1  christos 	 bfd_elf_generic_reloc,	       		/* special_function.  */
    616  1.1  christos 	 "R_LARCH_SUB24",    			/* name.  */
    617  1.1  christos 	 false,			       		/* partial_inplace.  */
    618  1.1  christos 	 0,					/* src_mask */
    619  1.1  christos 	 ALL_ONES,				/* dst_mask */
    620  1.1  christos 	 false,					/* pcrel_offset */
    621  1.1  christos 	 BFD_RELOC_LARCH_SUB24,			/* bfd_reloc_code_real_type */
    622  1.1  christos 	 NULL),					/* adjust_reloc_bits */
    623  1.1  christos 
    624  1.1  christos   LOONGARCH_HOWTO (R_LARCH_SUB32,	      	/* type (55).  */
    625  1.1  christos 	 0,				   	/* rightshift.  */
    626  1.1  christos 	 4,				   	/* size.  */
    627  1.1  christos 	 32,				  	/* bitsize.  */
    628  1.1  christos 	 false,					/* pc_relative.  */
    629  1.1  christos 	 0,				   	/* bitpos.  */
    630  1.1  christos 	 complain_overflow_signed,	    	/* complain_on_overflow.  */
    631  1.1  christos 	 bfd_elf_generic_reloc,	       		/* special_function.  */
    632  1.1  christos 	 "R_LARCH_SUB32",    			/* name.  */
    633  1.1  christos 	 false,			       		/* partial_inplace.  */
    634  1.1  christos 	 0,					/* src_mask */
    635  1.1  christos 	 ALL_ONES,				/* dst_mask */
    636  1.1  christos 	 false,					/* pcrel_offset */
    637  1.1  christos 	 BFD_RELOC_LARCH_SUB32,			/* bfd_reloc_code_real_type */
    638  1.1  christos 	 NULL),					/* adjust_reloc_bits */
    639  1.1  christos 
    640  1.1  christos   LOONGARCH_HOWTO (R_LARCH_SUB64,	      	/* type (56).  */
    641  1.1  christos 	 0,				   	/* rightshift.  */
    642  1.1  christos 	 8,				   	/* size.  */
    643  1.1  christos 	 64,				  	/* bitsize.  */
    644  1.1  christos 	 false,					/* pc_relative.  */
    645  1.1  christos 	 0,				   	/* bitpos.  */
    646  1.1  christos 	 complain_overflow_signed,	    	/* complain_on_overflow.  */
    647  1.1  christos 	 bfd_elf_generic_reloc,	       		/* special_function.  */
    648  1.1  christos 	 "R_LARCH_SUB64",    			/* name.  */
    649  1.1  christos 	 false,			       		/* partial_inplace.  */
    650  1.1  christos 	 0,					/* src_mask */
    651  1.1  christos 	 ALL_ONES,				/* dst_mask */
    652  1.1  christos 	 false,					/* pcrel_offset */
    653  1.1  christos 	 BFD_RELOC_LARCH_SUB64,			/* bfd_reloc_code_real_type */
    654  1.1  christos 	 NULL),					/* adjust_reloc_bits */
    655  1.1  christos 
    656  1.1  christos   LOONGARCH_HOWTO (R_LARCH_GNU_VTINHERIT,      	/* type (57).  */
    657  1.1  christos 	 0,				   	/* rightshift.  */
    658  1.1  christos 	 0,				   	/* size.  */
    659  1.1  christos 	 0,				  	/* bitsize.  */
    660  1.1  christos 	 false,					/* pc_relative.  */
    661  1.1  christos 	 0,				   	/* bitpos.  */
    662  1.1  christos 	 complain_overflow_signed,	    	/* complain_on_overflow.  */
    663  1.1  christos 	 bfd_elf_generic_reloc,	       		/* special_function.  */
    664  1.1  christos 	 "R_LARCH_GNU_VTINHERIT",  		/* name.  */
    665  1.1  christos 	 false,			       		/* partial_inplace.  */
    666  1.1  christos 	 0,					/* src_mask */
    667  1.1  christos 	 0,					/* dst_mask */
    668  1.1  christos 	 false,					/* pcrel_offset */
    669  1.1  christos 	 BFD_RELOC_NONE,			/* bfd_reloc_code_real_type */
    670  1.1  christos 	 NULL),					/* adjust_reloc_bits */
    671  1.1  christos 
    672  1.1  christos   LOONGARCH_HOWTO (R_LARCH_GNU_VTENTRY,      	/* type (58).  */
    673  1.1  christos 	 0,				   	/* rightshift.  */
    674  1.1  christos 	 0,				   	/* size.  */
    675  1.1  christos 	 0,				  	/* bitsize.  */
    676  1.1  christos 	 false,					/* pc_relative.  */
    677  1.1  christos 	 0,				   	/* bitpos.  */
    678  1.1  christos 	 complain_overflow_signed,	    	/* complain_on_overflow.  */
    679  1.1  christos 	 NULL,					/* special_function.  */
    680  1.1  christos 	 "R_LARCH_GNU_VTENTRY",  		/* name.  */
    681  1.1  christos 	 false,			       		/* partial_inplace.  */
    682  1.1  christos 	 0,					/* src_mask */
    683  1.1  christos 	 0,					/* dst_mask */
    684  1.1  christos 	 false,					/* pcrel_offset */
    685  1.1  christos 	 BFD_RELOC_NONE,			/* bfd_reloc_code_real_type */
    686  1.1  christos 	 NULL),					/* adjust_reloc_bits */
    687  1.1  christos };
    688  1.1  christos 
    689  1.1  christos reloc_howto_type *
    690  1.1  christos loongarch_elf_rtype_to_howto (bfd *abfd, unsigned int r_type)
    691  1.1  christos {
    692  1.1  christos   if(r_type < R_LARCH_count)
    693  1.1  christos     {
    694  1.1  christos       /* For search table fast.  */
    695  1.1  christos       BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count);
    696  1.1  christos 
    697  1.1  christos       if (loongarch_howto_table[r_type].howto.type == r_type)
    698  1.1  christos 	return (reloc_howto_type *)&loongarch_howto_table[r_type];
    699  1.1  christos 
    700  1.1  christos       BFD_ASSERT (loongarch_howto_table[r_type].howto.type == r_type);
    701  1.1  christos 
    702  1.1  christos       for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++)
    703  1.1  christos 	if (loongarch_howto_table[i].howto.type == r_type)
    704  1.1  christos 	  return (reloc_howto_type *)&loongarch_howto_table[i];
    705  1.1  christos     }
    706  1.1  christos 
    707  1.1  christos   (*_bfd_error_handler) (_("%pB: unsupported relocation type %#x"),
    708  1.1  christos 			 abfd, r_type);
    709  1.1  christos   bfd_set_error (bfd_error_bad_value);
    710  1.1  christos   return NULL;
    711  1.1  christos }
    712  1.1  christos 
    713  1.1  christos reloc_howto_type *
    714  1.1  christos loongarch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
    715  1.1  christos {
    716  1.1  christos   BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count);
    717  1.1  christos 
    718  1.1  christos   for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++)
    719  1.1  christos     if (loongarch_howto_table[i].howto.name
    720  1.1  christos 	&& strcasecmp (loongarch_howto_table[i].howto.name, r_name) == 0)
    721  1.1  christos       return (reloc_howto_type *)&loongarch_howto_table[i];
    722  1.1  christos 
    723  1.1  christos   (*_bfd_error_handler) (_("%pB: unsupported relocation type %s"),
    724  1.1  christos 			 abfd, r_name);
    725  1.1  christos   bfd_set_error (bfd_error_bad_value);
    726  1.1  christos 
    727  1.1  christos   return NULL;
    728  1.1  christos }
    729  1.1  christos 
    730  1.1  christos /* Cost so much.  */
    731  1.1  christos reloc_howto_type *
    732  1.1  christos loongarch_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
    733  1.1  christos 			     bfd_reloc_code_real_type code)
    734  1.1  christos {
    735  1.1  christos   BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count);
    736  1.1  christos 
    737  1.1  christos   for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++)
    738  1.1  christos     if (loongarch_howto_table[i].bfd_type == code)
    739  1.1  christos       return (reloc_howto_type *)&loongarch_howto_table[i];
    740  1.1  christos 
    741  1.1  christos   (*_bfd_error_handler) (_("%pB: unsupported bfd relocation type %#x"),
    742  1.1  christos 			 abfd, code);
    743  1.1  christos   bfd_set_error (bfd_error_bad_value);
    744  1.1  christos 
    745  1.1  christos   return NULL;
    746  1.1  christos }
    747  1.1  christos 
    748  1.1  christos #define LARCH_RELOC_BFD_VMA_BIT_MASK(bitsize) \
    749  1.1  christos   (~((((bfd_vma)0x1) << (bitsize)) - 1))
    750  1.1  christos 
    751  1.1  christos /* Adjust val to perform insn
    752  1.1  christos  * BFD_RELOC_LARCH_SOP_POP_32_S_10_5
    753  1.1  christos  * BFD_RELOC_LARCH_SOP_POP_32_S_10_12
    754  1.1  christos  * BFD_RELOC_LARCH_SOP_POP_32_U_10_12
    755  1.1  christos  * BFD_RELOC_LARCH_SOP_POP_32_S_10_16
    756  1.1  christos  * BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2
    757  1.1  christos  * BFD_RELOC_LARCH_SOP_POP_32_S_5_20
    758  1.1  christos  * BFD_RELOC_LARCH_SOP_POP_32_U.
    759  1.1  christos */
    760  1.1  christos 
    761  1.1  christos bool loongarch_gen_adjust_reloc_bits (reloc_howto_type *howto, bfd_vma *fix_val)
    762  1.1  christos {
    763  1.1  christos   bfd_vma val = *fix_val;
    764  1.1  christos   /* Check val low bits if rightshift != 0, before rightshift  */
    765  1.1  christos   if (howto->rightshift
    766  1.1  christos       && (((0x1UL << howto->rightshift) - 1) & val))
    767  1.1  christos     return false;
    768  1.1  christos 
    769  1.1  christos   int bitsize = howto->bitsize + howto->rightshift;
    770  1.1  christos 
    771  1.1  christos   /* Return false if overflow.  */
    772  1.1  christos   if (howto->complain_on_overflow == complain_overflow_signed)
    773  1.1  christos     {
    774  1.1  christos       bfd_vma sig_bit = (val >> (bitsize - 1)) & 0x1;
    775  1.1  christos       /* If val < 0.  */
    776  1.1  christos       if (sig_bit)
    777  1.1  christos 	{
    778  1.1  christos 	  if ((LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val)
    779  1.1  christos 	      != LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1))
    780  1.1  christos 	    return false;
    781  1.1  christos 	}
    782  1.1  christos       else
    783  1.1  christos 	{
    784  1.1  christos 	  if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val)
    785  1.1  christos 	    return false;
    786  1.1  christos 	}
    787  1.1  christos     }
    788  1.1  christos   else if (howto->complain_on_overflow == complain_overflow_unsigned)
    789  1.1  christos     {
    790  1.1  christos       if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize) & val)
    791  1.1  christos 	return false;
    792  1.1  christos     }
    793  1.1  christos   else
    794  1.1  christos     return false;
    795  1.1  christos 
    796  1.1  christos   /* Perform insn bits field.  */
    797  1.1  christos   val = (val & ((0x1U << bitsize) - 1)) >> howto->rightshift;
    798  1.1  christos   val <<= howto->bitpos;
    799  1.1  christos 
    800  1.1  christos   *fix_val = val;
    801  1.1  christos 
    802  1.1  christos   return true;
    803  1.1  christos }
    804  1.1  christos 
    805  1.1  christos /* Reloc type R_LARCH_SOP_POP_32_S_0_5_10_16_S2.  */
    806  1.1  christos bool loongarch_adjust_reloc_bits_l16_xx5_h5 (reloc_howto_type *howto,
    807  1.1  christos 					     bfd_vma *fix_val)
    808  1.1  christos {
    809  1.1  christos   bfd_vma val = *fix_val;
    810  1.1  christos   /* Check val low bits if rightshift != 0, before rightshift  */
    811  1.1  christos   if (howto->rightshift
    812  1.1  christos       && (((0x1UL << howto->rightshift) - 1) & val))
    813  1.1  christos     return false;
    814  1.1  christos 
    815  1.1  christos   /* Return false if overflow.  */
    816  1.1  christos   if (howto->complain_on_overflow != complain_overflow_signed)
    817  1.1  christos     return false;
    818  1.1  christos 
    819  1.1  christos   int bitsize = howto->bitsize + howto->rightshift;
    820  1.1  christos   bfd_vma sig_bit = (val >> (bitsize - 1)) & 0x1;
    821  1.1  christos   /* If val < 0.  */
    822  1.1  christos   if (sig_bit)
    823  1.1  christos     {
    824  1.1  christos       if ((LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val)
    825  1.1  christos 	  != LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1))
    826  1.1  christos 	return false;
    827  1.1  christos     }
    828  1.1  christos   else
    829  1.1  christos     {
    830  1.1  christos       if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val)
    831  1.1  christos 	return false;
    832  1.1  christos     }
    833  1.1  christos 
    834  1.1  christos   /* Perform insn bits field.  */
    835  1.1  christos   val = (val & ((0x1U << bitsize) - 1)) >> howto->rightshift;
    836  1.1  christos 
    837  1.1  christos   /* Perform insn bits field. 20:16>>16, 15:0<<10 */
    838  1.1  christos   val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f);
    839  1.1  christos 
    840  1.1  christos   *fix_val = val;
    841  1.1  christos 
    842  1.1  christos   return true;
    843  1.1  christos }
    844  1.1  christos 
    845  1.1  christos /* Reloc type R_LARCH_SOP_POP_32_S_0_10_10_16_S2.  */
    846  1.1  christos bool loongarch_adjust_reloc_bits_l16_h10 (reloc_howto_type *howto,
    847  1.1  christos 					  bfd_vma *fix_val)
    848  1.1  christos {
    849  1.1  christos   bfd_vma val = *fix_val;
    850  1.1  christos   /* Check val low bits if rightshift != 0, before rightshift  */
    851  1.1  christos   if (howto->rightshift
    852  1.1  christos       && (((0x1UL << howto->rightshift) - 1) & val))
    853  1.1  christos     return false;
    854  1.1  christos 
    855  1.1  christos   /* Return false if overflow.  */
    856  1.1  christos   if (howto->complain_on_overflow != complain_overflow_signed)
    857  1.1  christos     return false;
    858  1.1  christos 
    859  1.1  christos   int bitsize = howto->bitsize + howto->rightshift;
    860  1.1  christos   bfd_vma sig_bit = (val >> (bitsize - 1)) & 0x1;
    861  1.1  christos   /* If val < 0.  */
    862  1.1  christos   if (sig_bit)
    863  1.1  christos     {
    864  1.1  christos       if ((LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val)
    865  1.1  christos 	  != LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1))
    866  1.1  christos 	return false;
    867  1.1  christos     }
    868  1.1  christos   else
    869  1.1  christos     {
    870  1.1  christos       if (LARCH_RELOC_BFD_VMA_BIT_MASK (bitsize - 1) & val)
    871  1.1  christos 	return false;
    872  1.1  christos     }
    873  1.1  christos 
    874  1.1  christos   /* Perform insn bits field.  */
    875  1.1  christos   val = (val & ((0x1U << bitsize) - 1)) >> howto->rightshift;
    876  1.1  christos 
    877  1.1  christos   /* Perform insn bits field. 25:16>>16, 15:0<<10 */
    878  1.1  christos   val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff);
    879  1.1  christos 
    880  1.1  christos   *fix_val = val;
    881  1.1  christos 
    882  1.1  christos   return true;
    883  1.1  christos }
    884  1.1  christos 
    885  1.1  christos bool loongarch_adjust_reloc_bitsfield (reloc_howto_type *howto,
    886  1.1  christos 				       bfd_vma *fix_val)
    887  1.1  christos {
    888  1.1  christos   BFD_ASSERT (((loongarch_reloc_howto_type *)howto)->adjust_reloc_bits);
    889  1.1  christos   return ((loongarch_reloc_howto_type *)
    890  1.1  christos 	  howto)->adjust_reloc_bits(howto, fix_val);
    891  1.1  christos }
    892