diff options
author | liuzhensong <liuzhensong@loongson.cn> | 2021-10-22 16:42:03 +0800 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2021-10-24 21:36:31 +1030 |
commit | e214f8db56f65531b0a5ec296c42339dcaa5af31 (patch) | |
tree | 98bd755197a63aaf79bda89bb3ea792e5a49aaab /bfd/elfxx-loongarch.c | |
parent | e515d93264b8c74993d8c9f3ac76bd6deaa666f8 (diff) | |
download | binutils-e214f8db56f65531b0a5ec296c42339dcaa5af31.zip binutils-e214f8db56f65531b0a5ec296c42339dcaa5af31.tar.gz binutils-e214f8db56f65531b0a5ec296c42339dcaa5af31.tar.bz2 |
LoongArch bfd support
2021-10-22 Chenghua Xu <xuchenghua@loongson.cn>
Zhensong Liu <liuzhensong@loongson.cn>
Weinan Liu <liuweinan@loongson.cn>
bfd/
* Makefile.am: Add LoongArch.
* archures.c: Likewise.
* config.bfd: Likewise.
* configure.ac: Likewise.
* cpu-loongarch.c: New.
* elf-bfd.h: Add LoongArch.
* elf.c: Add LoongArch elfcore_grok_xxx.
* elfnn-loongarch.c: New.
* elfxx-loongarch.c: New.
* elfxx-loongarch.h: New.
* reloc.c: Add LoongArch BFD RELOC ENUM.
* targets.c: Add LoongArch target.
* Makefile.in: Regenerate.
* bfd-in2.h: Regenerate.
* configure: Regenerate.
* libbfd.h: Regenerate.
* po/BLD-POTFILES.in: Regenerate.
* po/SRC-POTFILES.in: Regenerate.
include/
* elf/common.h: Add NT_LARCH_{CPUCFG,CSR,LSX,LASX}.
* elf/loongarch.h: New.
Diffstat (limited to 'bfd/elfxx-loongarch.c')
-rw-r--r-- | bfd/elfxx-loongarch.c | 661 |
1 files changed, 661 insertions, 0 deletions
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c new file mode 100644 index 0000000..a0de51f --- /dev/null +++ b/bfd/elfxx-loongarch.c @@ -0,0 +1,661 @@ +/* LoongArch-specific support for ELF. + Copyright (C) 2021 Free Software Foundation, Inc. + Contributed by Loongson Ltd. + + Based on RISC-V target. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING3. If not, + see <http://www.gnu.org/licenses/>. */ + +#include "sysdep.h" +#include "bfd.h" +#include "libbfd.h" +#include "elf-bfd.h" +#include "elf/loongarch.h" +#include "elfxx-loongarch.h" + +#define ALL_ONES (~ (bfd_vma) 0) + +/* This does not include any relocation information, but should be + good enough for GDB or objdump to read the file. */ + +static reloc_howto_type howto_table[] = +{ +#define LOONGARCH_HOWTO(r_name) \ + HOWTO (R_LARCH_##r_name, 0, 2, 32, false, 0, complain_overflow_signed, \ + bfd_elf_generic_reloc, "R_LARCH_" #r_name, false, 0, 0xffffffff, false) + + /* No relocation. */ + HOWTO (R_LARCH_NONE, /* type (0). */ + 0, /* rightshift */ + 3, /* size */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_LARCH_NONE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* 32 bit relocation. */ + HOWTO (R_LARCH_32, /* type (1). */ + 0, /* rightshift */ + 2, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_LARCH_32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 64 bit relocation. */ + HOWTO (R_LARCH_64, /* type (2). */ + 0, /* rightshift */ + 4, /* size */ + 64, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_LARCH_64", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + ALL_ONES, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_LARCH_RELATIVE, /* type (3). */ + 0, /* rightshift */ + 2, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_LARCH_RELATIVE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_LARCH_COPY, /* type (4). */ + 0, /* rightshift */ + 0, /* this one is variable size */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_LARCH_COPY", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_LARCH_JUMP_SLOT, /* type (5). */ + 0, /* rightshift */ + 4, /* size */ + 64, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_LARCH_JUMP_SLOT", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Dynamic TLS relocations. */ + HOWTO (R_LARCH_TLS_DTPMOD32, /* type (6). */ + 0, /* rightshift */ + 2, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_LARCH_TLS_DTPMOD32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_LARCH_TLS_DTPMOD64, /* type (7). */ + 0, /* rightshift */ + 4, /* size */ + 64, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_LARCH_TLS_DTPMOD64", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + ALL_ONES, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_LARCH_TLS_DTPREL32, /* type (8). */ + 0, /* rightshift */ + 2, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_LARCH_TLS_DTPREL32", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_LARCH_TLS_DTPREL64, /* type (9). */ + 0, /* rightshift */ + 4, /* size */ + 64, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_LARCH_TLS_DTPREL64", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + ALL_ONES, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_LARCH_TLS_TPREL32, /* type (10). */ + 0, /* rightshift */ + 2, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_LARCH_TLS_TPREL32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_LARCH_TLS_TPREL64, /* type (11). */ + 0, /* rightshift */ + 4, /* size */ + 64, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_LARCH_TLS_TPREL64", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + ALL_ONES, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO (R_LARCH_IRELATIVE, /* type (12). */ + 0, /* rightshift */ + 2, /* size */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_LARCH_IRELATIVE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + EMPTY_HOWTO(13), + EMPTY_HOWTO(14), + EMPTY_HOWTO(15), + EMPTY_HOWTO(16), + EMPTY_HOWTO(17), + EMPTY_HOWTO(18), + EMPTY_HOWTO(19), + + HOWTO (R_LARCH_MARK_LA, /* type (20). */ + 0, /* rightshift. */ + 3, /* size. */ + 0, /* bitsize. */ + false, /* pc_relative. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_MARK_LA", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask. */ + 0, /* dst_mask. */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_MARK_PCREL, /* type (21). */ + 0, /* rightshift. */ + 3, /* size. */ + 0, /* bitsize. */ + false, /* pc_relative. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_MARK_PCREL", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask. */ + 0, /* dst_mask. */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_SOP_PUSH_PCREL, /* type (22). */ + 2, /* rightshift. */ + 2, /* size. */ + 32, /* bitsize. */ + true /* FIXME: somewhat use this. */, /* pc_relative. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_SOP_PUSH_PCREL", /* name. */ + false, /* partial_inplace. */ + 0x03ffffff, /* src_mask. */ + 0x03ffffff, /* dst_mask. */ + false), /* pcrel_offset. */ + + /* type 23-37. */ + LOONGARCH_HOWTO (SOP_PUSH_ABSOLUTE), + LOONGARCH_HOWTO (SOP_PUSH_DUP), + LOONGARCH_HOWTO (SOP_PUSH_GPREL), + LOONGARCH_HOWTO (SOP_PUSH_TLS_TPREL), + LOONGARCH_HOWTO (SOP_PUSH_TLS_GOT), + LOONGARCH_HOWTO (SOP_PUSH_TLS_GD), + LOONGARCH_HOWTO (SOP_PUSH_PLT_PCREL), + LOONGARCH_HOWTO (SOP_ASSERT), + LOONGARCH_HOWTO (SOP_NOT), + LOONGARCH_HOWTO (SOP_SUB), + LOONGARCH_HOWTO (SOP_SL), + LOONGARCH_HOWTO (SOP_SR), + LOONGARCH_HOWTO (SOP_ADD), + LOONGARCH_HOWTO (SOP_AND), + LOONGARCH_HOWTO (SOP_IF_ELSE), + + HOWTO (R_LARCH_SOP_POP_32_S_10_5, /* type (38). */ + 0, /* rightshift. */ + 2, /* size. */ + 5, /* bitsize. */ + false, /* pc_relative. */ + 10, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_SOP_POP_32_S_10_5", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask */ + 0x7c00, /* dst_mask */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_SOP_POP_32_U_10_12, /* type (39). */ + 0, /* rightshift. */ + 2, /* size. */ + 12, /* bitsize. */ + false, /* pc_relative. */ + 10, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_SOP_POP_32_U_10_12", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask */ + 0x3ffc00, /* dst_mask */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_SOP_POP_32_S_10_12, /* type (40). */ + 0, /* rightshift. */ + 2, /* size. */ + 12, /* bitsize. */ + false, /* pc_relative. */ + 10, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_SOP_POP_32_S_10_12", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask */ + 0x3ffc00, /* dst_mask */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_SOP_POP_32_S_10_16, /* type (41). */ + 0, /* rightshift. */ + 2, /* size. */ + 16, /* bitsize. */ + false, /* pc_relative. */ + 10, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_SOP_POP_32_S_10_16", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask */ + 0x3fffc00, /* dst_mask */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_SOP_POP_32_S_10_16_S2, /* type (42). */ + 2, /* rightshift. */ + 2, /* size. */ + 16, /* bitsize. */ + false, /* pc_relative. */ + 10, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_SOP_POP_32_S_10_16_S2", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask */ + 0x3fffc00, /* dst_mask */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_SOP_POP_32_S_5_20, /* type (43). */ + 0, /* rightshift. */ + 2, /* size. */ + 20, /* bitsize. */ + false, /* pc_relative. */ + 5, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_SOP_POP_32_S_5_20", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask */ + 0x1fffe0, /* dst_mask */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_SOP_POP_32_S_0_5_10_16_S2, /* type (44). */ + 2, /* rightshift. */ + 2, /* size. */ + 21, /* bitsize. */ + false, /* pc_relative. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_SOP_POP_32_S_0_5_10_16_S2", /* name. */ + false, /* partial_inplace. */ + 0xfc0003e0, /* src_mask */ + 0xfc0003e0, /* dst_mask */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_SOP_POP_32_S_0_10_10_16_S2, /* type (45). */ + 2, /* rightshift. */ + 2, /* size. */ + 26, /* bitsize. */ + false, /* pc_relative. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_SOP_POP_32_S_0_10_10_16_S2", /* name. */ + false, /* partial_inplace. */ + 0xfc000000, /* src_mask */ + 0xfc000000, /* dst_mask */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_SOP_POP_32_U, /* type (46). */ + 0, /* rightshift. */ + 2, /* size. */ + 32, /* bitsize. */ + false, /* pc_relative. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_SOP_POP_32_S_U", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_ADD8, /* type (47). */ + 0, /* rightshift. */ + 2, /* size. */ + 8, /* bitsize. */ + false, /* pc_relative. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_ADD8", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_ADD16, /* type (48). */ + 0, /* rightshift. */ + 2, /* size. */ + 16, /* bitsize. */ + false, /* pc_relative. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_ADD16", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_ADD24, /* type (49). */ + 0, /* rightshift. */ + 2, /* size. */ + 24, /* bitsize. */ + false, /* pc_relative. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_ADD24", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_ADD32, /* type (50). */ + 0, /* rightshift. */ + 2, /* size. */ + 32, /* bitsize. */ + false, /* pc_relative. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_ADD32", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_ADD64, /* type (51). */ + 0, /* rightshift. */ + 4, /* size. */ + 64, /* bitsize. */ + false, /* pc_relative. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_ADD64", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask */ + ALL_ONES, /* dst_mask */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_SUB8, /* type (52). */ + 0, /* rightshift. */ + 2, /* size. */ + 8, /* bitsize. */ + false, /* pc_relative. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_SUB8", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_SUB16, /* type (53). */ + 0, /* rightshift. */ + 2, /* size. */ + 16, /* bitsize. */ + false, /* pc_relative. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_SUB16", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_SUB24, /* type (54). */ + 0, /* rightshift. */ + 2, /* size. */ + 24, /* bitsize. */ + false, /* pc_relative. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_SUB24", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_SUB32, /* type (55). */ + 0, /* rightshift. */ + 2, /* size. */ + 32, /* bitsize. */ + false, /* pc_relative. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_SUB32", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset. */ + + HOWTO (R_LARCH_SUB64, /* type (56). */ + 0, /* rightshift. */ + 4, /* size. */ + 64, /* bitsize. */ + false, /* pc_relative. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_SUB64", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask */ + ALL_ONES, /* dst_mask */ + false), /* pcrel_offset. */ + +}; + +struct elf_reloc_map +{ + bfd_reloc_code_real_type bfd_val; + enum elf_loongarch_reloc_type elf_val; +}; + +static const struct elf_reloc_map larch_reloc_map[] = +{ + { BFD_RELOC_NONE, R_LARCH_NONE }, + { BFD_RELOC_32, R_LARCH_32 }, + { BFD_RELOC_64, R_LARCH_64 }, + +#define LOONGARCH_reloc_map(r_name) \ + { \ + BFD_RELOC_LARCH_##r_name, R_LARCH_##r_name \ + } + LOONGARCH_reloc_map (TLS_DTPMOD32), + LOONGARCH_reloc_map (TLS_DTPMOD64), + LOONGARCH_reloc_map (TLS_DTPREL32), + LOONGARCH_reloc_map (TLS_DTPREL64), + LOONGARCH_reloc_map (TLS_TPREL32), + LOONGARCH_reloc_map (TLS_TPREL64), + + LOONGARCH_reloc_map (MARK_LA), + LOONGARCH_reloc_map (MARK_PCREL), + LOONGARCH_reloc_map (SOP_PUSH_PCREL), + LOONGARCH_reloc_map (SOP_PUSH_ABSOLUTE), + LOONGARCH_reloc_map (SOP_PUSH_DUP), + LOONGARCH_reloc_map (SOP_PUSH_GPREL), + LOONGARCH_reloc_map (SOP_PUSH_TLS_TPREL), + LOONGARCH_reloc_map (SOP_PUSH_TLS_GOT), + LOONGARCH_reloc_map (SOP_PUSH_TLS_GD), + LOONGARCH_reloc_map (SOP_PUSH_PLT_PCREL), + LOONGARCH_reloc_map (SOP_ASSERT), + LOONGARCH_reloc_map (SOP_NOT), + LOONGARCH_reloc_map (SOP_SUB), + LOONGARCH_reloc_map (SOP_SL), + LOONGARCH_reloc_map (SOP_SR), + LOONGARCH_reloc_map (SOP_ADD), + LOONGARCH_reloc_map (SOP_AND), + LOONGARCH_reloc_map (SOP_IF_ELSE), + LOONGARCH_reloc_map (SOP_POP_32_S_10_5), + LOONGARCH_reloc_map (SOP_POP_32_U_10_12), + LOONGARCH_reloc_map (SOP_POP_32_S_10_12), + LOONGARCH_reloc_map (SOP_POP_32_S_10_16), + LOONGARCH_reloc_map (SOP_POP_32_S_10_16_S2), + LOONGARCH_reloc_map (SOP_POP_32_S_5_20), + LOONGARCH_reloc_map (SOP_POP_32_S_0_5_10_16_S2), + LOONGARCH_reloc_map (SOP_POP_32_S_0_10_10_16_S2), + LOONGARCH_reloc_map (SOP_POP_32_U), + LOONGARCH_reloc_map (ADD8), + LOONGARCH_reloc_map (ADD16), + LOONGARCH_reloc_map (ADD24), + LOONGARCH_reloc_map (ADD32), + LOONGARCH_reloc_map (ADD64), + LOONGARCH_reloc_map (SUB8), + LOONGARCH_reloc_map (SUB16), + LOONGARCH_reloc_map (SUB24), + LOONGARCH_reloc_map (SUB32), + LOONGARCH_reloc_map (SUB64), +}; + +reloc_howto_type * +loongarch_elf_rtype_to_howto (bfd *abfd, unsigned int r_type) +{ + size_t i; + for (i = 0; i < ARRAY_SIZE (howto_table); i++) + if (howto_table[i].type == r_type) + return &howto_table[i]; + + (*_bfd_error_handler) (_("%pB: unsupported relocation type %#x"), + abfd, r_type); + bfd_set_error (bfd_error_bad_value); + return NULL; +} + +reloc_howto_type * +loongarch_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) +{ + unsigned int i; + for (i = 0; i < ARRAY_SIZE (larch_reloc_map); i++) + if (larch_reloc_map[i].bfd_val == code) + return loongarch_elf_rtype_to_howto (abfd, + (int) larch_reloc_map[i].elf_val); + + return NULL; +} + +reloc_howto_type * +loongarch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE (howto_table); i++) + if (howto_table[i].name && strcasecmp (howto_table[i].name, r_name) == 0) + return &howto_table[i]; + + return NULL; +} |