From 4c239f92d6405b2b0ec7af7aef8a4495450d0964 Mon Sep 17 00:00:00 2001 From: Zhang Na Date: Tue, 4 Apr 2023 19:12:29 +0800 Subject: [PATCH] Add LoongArch support --- api/python/examples/elf_reader.py | 3 + api/python/lief/ELF.pyi | 20 ++++ api/python/lief/__init__.pyi | 1 + api/python/src/Abstract/pyEnums.cpp | 3 +- api/python/src/ELF/objects/pyHeader.cpp | 11 ++ api/python/src/ELF/pyEnums.cpp | 100 +++++++++++++++++- include/LIEF/Abstract/enums.hpp | 1 + include/LIEF/ELF/EnumToString.hpp | 2 + include/LIEF/ELF/Header.hpp | 7 ++ include/LIEF/ELF/Relocation.hpp | 1 + include/LIEF/ELF/RelocationSizes.hpp | 1 + include/LIEF/ELF/Relocations/LoongArch.def | 102 ++++++++++++++++++ include/LIEF/ELF/enums.hpp | 19 +++- include/LIEF/ELF/enums.inc | 18 +++- include/LIEF/ELF/undef.h | 98 ++++++++++++++++++ src/Abstract/EnumToString.cpp | 3 +- src/ELF/EnumToString.cpp | 115 ++++++++++++++++++++- src/ELF/Header.cpp | 31 ++++++ src/ELF/Parser.cpp | 1 + src/ELF/Relocation.cpp | 17 +++ src/ELF/RelocationSizes.cpp | 96 +++++++++++++++++ src/ELF/Structures.hpp | 9 ++ 22 files changed, 650 insertions(+), 9 deletions(-) create mode 100644 include/LIEF/ELF/Relocations/LoongArch.def diff --git a/api/python/examples/elf_reader.py b/api/python/examples/elf_reader.py index 313dc3ddb2..bee393d368 100644 --- a/api/python/examples/elf_reader.py +++ b/api/python/examples/elf_reader.py @@ -71,6 +71,9 @@ def print_header(binary): if header.machine_type == lief.ELF.ARCH.HEXAGON: eflags_str = " - ".join([str(s).split(".")[-1] for s in header.hexagon_flags_list]) + + if header.machine_type == lief.ELF.ARCH.LOONGARCH: + eflags_str = " - ".join([str(s).split(".")[-1] for s in header.loongarch_flags_list]) print(identity) print(format_ide.format("Magic:", identity[0], identity[1], identity[2], identity[3])) print(format_str.format("Class:", str(header.identity_class).split(".")[-1])) diff --git a/api/python/lief/ELF.pyi b/api/python/lief/ELF.pyi index 5ff0b96180..a6d13d29ea 100644 --- a/api/python/lief/ELF.pyi +++ b/api/python/lief/ELF.pyi @@ -89,6 +89,7 @@ class ARCH: KVARC: ClassVar[ARCH] = ... L10M: ClassVar[ARCH] = ... LATTICEMICO32: ClassVar[ARCH] = ... + LOONGARCH: ClassVar[ARCH] = ... M16C: ClassVar[ARCH] = ... M32: ClassVar[ARCH] = ... M32C: ClassVar[ARCH] = ... @@ -1113,6 +1114,21 @@ class HEXAGON_EFLAGS: @property def value(self) -> int: ... +class LOONGARCH_EFLAGS: + __members__: ClassVar[dict] = ... # read-only + BASE_ABI_ILP32S: ClassVar[LOONGARCH_EFLAGS] = ... + BASE_ABI_ILP32F: ClassVar[LOONGARCH_EFLAGS] = ... + BASE_ABI_ILP32D: ClassVar[LOONGARCH_EFLAGS] = ... + BASE_ABI_LP64S: ClassVar[LOONGARCH_EFLAGS] = ... + BASE_ABI_LP64F: ClassVar[LOONGARCH_EFLAGS] = ... + BASE_ABI_LP64D: ClassVar[LOONGARCH_EFLAGS] = ... + __entries: ClassVar[dict] = ... + def __init__(self, value: int) -> None: ... + @property + def name(self) -> str: ... + @property + def value(self) -> int: ... + class Header(lief.Object): entrypoint: int file_type: lief.ELF.E_TYPE @@ -1142,6 +1158,8 @@ class Header(lief.Object): def __contains__(self, arg0: lief.ELF.PPC64_EFLAGS) -> bool: ... @overload def __contains__(self, arg0: lief.ELF.HEXAGON_EFLAGS) -> bool: ... + @overload + def __contains__(self, arg0: lief.ELF.LOONGARCH_EFLAGS) -> bool: ... @property def arm_flags_list(self) -> Set[lief.ELF.ARM_EFLAGS]: ... @property @@ -1150,6 +1168,8 @@ class Header(lief.Object): def mips_flags_list(self) -> Set[lief.ELF.MIPS_EFLAGS]: ... @property def ppc64_flags_list(self) -> Set[lief.ELF.PPC64_EFLAGS]: ... + @property + def loongarch_flags_list(self) -> Set[lief.ELF.LOONGARCH_EFLAGS]: ... class IDENTITY: __members__: ClassVar[dict] = ... # read-only diff --git a/api/python/lief/__init__.pyi b/api/python/lief/__init__.pyi index 865b596b34..3b9c5ea436 100644 --- a/api/python/lief/__init__.pyi +++ b/api/python/lief/__init__.pyi @@ -9,6 +9,7 @@ class ARCHITECTURES: ARM: ClassVar[ARCHITECTURES] = ... ARM64: ClassVar[ARCHITECTURES] = ... INTEL: ClassVar[ARCHITECTURES] = ... + LOONGARCH: ClassVar[ARCHITECTURES] = ... MIPS: ClassVar[ARCHITECTURES] = ... NONE: ClassVar[ARCHITECTURES] = ... PPC: ClassVar[ARCHITECTURES] = ... diff --git a/api/python/src/Abstract/pyEnums.cpp b/api/python/src/Abstract/pyEnums.cpp index 3634a3f31e..980042390c 100644 --- a/api/python/src/Abstract/pyEnums.cpp +++ b/api/python/src/Abstract/pyEnums.cpp @@ -44,7 +44,8 @@ void init_enums(py::module& m) { .value(PY_ENUM(ARCHITECTURES::ARCH_SYSZ)) .value(PY_ENUM(ARCHITECTURES::ARCH_XCORE)) .value(PY_ENUM(ARCHITECTURES::ARCH_INTEL)) - .value(PY_ENUM(ARCHITECTURES::ARCH_RISCV)); + .value(PY_ENUM(ARCHITECTURES::ARCH_RISCV)) + .value(PY_ENUM(ARCHITECTURES::ARCH_LOONGARCH)); py::enum_(m, "MODES") .value(PY_ENUM(MODES::MODE_NONE)) diff --git a/api/python/src/ELF/objects/pyHeader.cpp b/api/python/src/ELF/objects/pyHeader.cpp index bb17ca8e06..d7b54f16cc 100644 --- a/api/python/src/ELF/objects/pyHeader.cpp +++ b/api/python/src/ELF/objects/pyHeader.cpp @@ -158,6 +158,12 @@ void create
(py::module& m) { ":attr:`~lief.ELF.Header.processor_flag`", py::return_value_policy::reference_internal) + .def_property_readonly("loongarch_flags_list", + &Header::loongarch_flags_list, + "Return a list of " RST_CLASS_REF(lief.ELF.LOONGARCH_EFLAGS) " present in " + ":attr:`~lief.ELF.Header.processor_flag`", + py::return_value_policy::reference_internal) + .def_property("header_size", static_cast>(&Header::header_size), static_cast>(&Header::header_size), @@ -230,6 +236,11 @@ void create
(py::module& m) { "Check if the given " RST_CLASS_REF(lief.ELF.HEXAGON_EFLAGS) " is present in " ":attr:`~lief.ELF.Header.processor_flag`") + .def("__contains__", + static_cast(&Header::has), + "Check if the given " RST_CLASS_REF(lief.ELF.LOONGARCH_EFLAGS) " is present in " + ":attr:`~lief.ELF.Header.processor_flag`") + .def("__str__", [] (const Header& header) { diff --git a/api/python/src/ELF/pyEnums.cpp b/api/python/src/ELF/pyEnums.cpp index f4c9712723..8a630a9794 100644 --- a/api/python/src/ELF/pyEnums.cpp +++ b/api/python/src/ELF/pyEnums.cpp @@ -255,7 +255,8 @@ void init_enums(py::module& m) { .value(PY_ENUM(ARCH::EM_CSR_KALIMBA)) .value(PY_ENUM(ARCH::EM_AMDGPU)) .value(PY_ENUM(ARCH::EM_RISCV)) - .value(PY_ENUM(ARCH::EM_BPF)); + .value(PY_ENUM(ARCH::EM_BPF)) + .value(PY_ENUM(ARCH::EM_LOONGARCH)); //! Enum for the *sh_type* of ElfXX_Shdr; @@ -1079,6 +1080,96 @@ void init_enums(py::module& m) { .value(PY_ENUM(RELOC_MIPS::R_MICROMIPS_PC18_S3)) .value(PY_ENUM(RELOC_MIPS::R_MICROMIPS_PC19_S2)); + LIEF::enum_(m, "RELOCATION_LOONGARCH") + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_NONE)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_32)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_64)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_RELATIVE)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_COPY)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_JUMP_SLOT)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_DTPMOD32)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_DTPMOD64)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_DTPREL32)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_DTPREL64)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_TPREL32)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_TPREL64)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_IRELATIVE)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_MARK_LA)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_MARK_PCREL)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_PUSH_PCREL)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_PUSH_ABSOLUTE)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_PUSH_DUP)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_PUSH_GPREL)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_PUSH_TLS_TPREL)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_PUSH_TLS_GOT)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_PUSH_TLS_GD)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_PUSH_PLT_PCREL)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_ASSERT)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_NOT)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_SUB)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_SL)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_SR)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_ADD)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_AND)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_IF_ELSE)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_10_5)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_POP_32_U_10_12)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_10_12)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_10_16)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_10_16_S2)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_5_20)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_0_5_10_16_S2)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_0_10_10_16_S2)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SOP_POP_32_U)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_ADD8)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_ADD16)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_ADD24)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_ADD32)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_ADD64)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SUB8)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SUB16)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SUB24)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SUB32)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_SUB64)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GNU_VTINHERIT)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GNU_VTENTRY)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_B16)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_B21)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_B26)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_ABS_HI20)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_ABS_LO12)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_ABS64_LO20)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_ABS64_HI12)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_PCALA_HI20)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_PCALA_LO12)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_PCALA64_LO20)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_PCALA64_HI12)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GOT_PC_HI20)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GOT_PC_LO12)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GOT64_PC_LO20)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GOT64_PC_HI12)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GOT_HI20)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GOT_LO12)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GOT64_LO20)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_GOT64_HI12)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_LE_HI20)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_LE_LO12)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_LE64_LO20)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_LE64_HI12)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_IE_PC_HI20)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_IE_PC_LO12)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_IE64_PC_LO20)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_IE64_PC_HI12)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_IE_HI20)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_IE_LO12)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_IE64_LO20)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_IE64_HI12)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_LD_PC_HI20)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_LD_HI20)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_GD_PC_HI20)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_TLS_GD_HI20)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_32_PCREL)) + .value(PY_ENUM(RELOC_LOONGARCH::R_LARCH_RELAX)); LIEF::enum_(m, "DYNSYM_COUNT_METHODS") .value(PY_ENUM(DYNSYM_COUNT_METHODS::COUNT_AUTO)) @@ -1208,6 +1299,13 @@ void init_enums(py::module& m) { .value(PY_ENUM(HEXAGON_EFLAGS::EF_HEXAGON_ISA_V4)) .value(PY_ENUM(HEXAGON_EFLAGS::EF_HEXAGON_ISA_V5)); + LIEF::enum_(m, "LOONGARCH_EFLAGS", py::arithmetic()) + .value(PY_ENUM(LOONGARCH_EFLAGS::EF_LARCH_BASE_ABI_ILP32S)) + .value(PY_ENUM(LOONGARCH_EFLAGS::EF_LARCH_BASE_ABI_ILP32F)) + .value(PY_ENUM(LOONGARCH_EFLAGS::EF_LARCH_BASE_ABI_ILP32D)) + .value(PY_ENUM(LOONGARCH_EFLAGS::EF_LARCH_BASE_ABI_LP64S)) + .value(PY_ENUM(LOONGARCH_EFLAGS::EF_LARCH_BASE_ABI_LP64F)) + .value(PY_ENUM(LOONGARCH_EFLAGS::EF_LARCH_BASE_ABI_LP64D)); LIEF::enum_(m, "IDENTITY") .value(PY_ENUM(IDENTITY::EI_MAG0)) diff --git a/include/LIEF/Abstract/enums.hpp b/include/LIEF/Abstract/enums.hpp index eccadb4a4d..98c50456bc 100644 --- a/include/LIEF/Abstract/enums.hpp +++ b/include/LIEF/Abstract/enums.hpp @@ -48,6 +48,7 @@ enum ARCHITECTURES { ARCH_XCORE = 8, ARCH_INTEL = 9, ARCH_RISCV = 10, + ARCH_LOONGARCH = 11, }; enum MODES { diff --git a/include/LIEF/ELF/EnumToString.hpp b/include/LIEF/ELF/EnumToString.hpp index 52a79f844f..b9df818624 100644 --- a/include/LIEF/ELF/EnumToString.hpp +++ b/include/LIEF/ELF/EnumToString.hpp @@ -56,6 +56,8 @@ LIEF_API const char* to_string(PPC64_EFLAGS e); LIEF_API const char* to_string(ARM_EFLAGS e); LIEF_API const char* to_string(MIPS_EFLAGS e); LIEF_API const char* to_string(HEXAGON_EFLAGS e); +LIEF_API const char* to_string(LOONGARCH_EFLAGS e); +LIEF_API const char* to_string(RELOC_LOONGARCH e); diff --git a/include/LIEF/ELF/Header.hpp b/include/LIEF/ELF/Header.hpp index 11dde7cb11..4be2b33911 100644 --- a/include/LIEF/ELF/Header.hpp +++ b/include/LIEF/ELF/Header.hpp @@ -50,6 +50,7 @@ class LIEF_API Header : public Object { using mips_flags_list_t = flags_list_t; using hexagon_flags_list_t = flags_list_t; using ppc64_flags_list_t = flags_list_t; + using loongarch_flags_list_t = flags_list_t; public: Header(); @@ -117,6 +118,12 @@ class LIEF_API Header : public Object { //! Return a list of HEXAGON_EFLAGS present in processor_flag() hexagon_flags_list_t hexagon_flags_list() const; + //! Check if the given flag is present in processor_flag() + bool has(LOONGARCH_EFLAGS f) const; + + //! Return a list of LOONGARCH_EFLAGS present in processor_flag() + loongarch_flags_list_t loongarch_flags_list() const; + //! Size of the current header //! //! This size should be 64 for an ``ELF64`` binary and 52 for an ``ELF32``. diff --git a/include/LIEF/ELF/Relocation.hpp b/include/LIEF/ELF/Relocation.hpp index e3baa6b5cb..54852bf23b 100644 --- a/include/LIEF/ELF/Relocation.hpp +++ b/include/LIEF/ELF/Relocation.hpp @@ -89,6 +89,7 @@ class LIEF_API Relocation : public LIEF::Relocation { //! * RELOC_HEXAGON //! * RELOC_SYSTEMZ //! * RELOC_SPARC + //! * RELOC_LOONGARCH uint32_t type() const; //! Check if the relocation uses the explicit addend() field (this is usually the case for 64 bits binaries) diff --git a/include/LIEF/ELF/RelocationSizes.hpp b/include/LIEF/ELF/RelocationSizes.hpp index 5197972d26..e2094b51e4 100644 --- a/include/LIEF/ELF/RelocationSizes.hpp +++ b/include/LIEF/ELF/RelocationSizes.hpp @@ -30,6 +30,7 @@ int32_t get_reloc_size(RELOC_AARCH64 R); int32_t get_reloc_size(RELOC_POWERPC32 R); int32_t get_reloc_size(RELOC_POWERPC64 R); int32_t get_reloc_size(RELOC_MIPS R); +int32_t get_reloc_size(RELOC_LOONGARCH R); } } diff --git a/include/LIEF/ELF/Relocations/LoongArch.def b/include/LIEF/ELF/Relocations/LoongArch.def new file mode 100644 index 0000000000..6699e73202 --- /dev/null +++ b/include/LIEF/ELF/Relocations/LoongArch.def @@ -0,0 +1,102 @@ + +#ifndef ELF_RELOC +#error "ELF_RELOC must be defined" +#endif + +ELF_RELOC(R_LARCH_NONE, 0) +ELF_RELOC(R_LARCH_32, 1) +ELF_RELOC(R_LARCH_64, 2) +ELF_RELOC(R_LARCH_RELATIVE, 3) +ELF_RELOC(R_LARCH_COPY, 4) +ELF_RELOC(R_LARCH_JUMP_SLOT, 5) +ELF_RELOC(R_LARCH_TLS_DTPMOD32, 6) +ELF_RELOC(R_LARCH_TLS_DTPMOD64, 7) +ELF_RELOC(R_LARCH_TLS_DTPREL32, 8) +ELF_RELOC(R_LARCH_TLS_DTPREL64, 9) +ELF_RELOC(R_LARCH_TLS_TPREL32, 10) +ELF_RELOC(R_LARCH_TLS_TPREL64, 11) +ELF_RELOC(R_LARCH_IRELATIVE, 12) + +ELF_RELOC(R_LARCH_MARK_LA, 20) +ELF_RELOC(R_LARCH_MARK_PCREL, 21) + +ELF_RELOC(R_LARCH_SOP_PUSH_PCREL, 22) + +ELF_RELOC(R_LARCH_SOP_PUSH_ABSOLUTE, 23) + +ELF_RELOC(R_LARCH_SOP_PUSH_DUP, 24) +ELF_RELOC(R_LARCH_SOP_PUSH_GPREL, 25) +ELF_RELOC(R_LARCH_SOP_PUSH_TLS_TPREL, 26) +ELF_RELOC(R_LARCH_SOP_PUSH_TLS_GOT, 27) +ELF_RELOC(R_LARCH_SOP_PUSH_TLS_GD, 28) +ELF_RELOC(R_LARCH_SOP_PUSH_PLT_PCREL, 29) + +ELF_RELOC(R_LARCH_SOP_ASSERT, 30) +ELF_RELOC(R_LARCH_SOP_NOT, 31) +ELF_RELOC(R_LARCH_SOP_SUB, 32) +ELF_RELOC(R_LARCH_SOP_SL, 33) +ELF_RELOC(R_LARCH_SOP_SR, 34) +ELF_RELOC(R_LARCH_SOP_ADD, 35) +ELF_RELOC(R_LARCH_SOP_AND, 36) +ELF_RELOC(R_LARCH_SOP_IF_ELSE, 37) +ELF_RELOC(R_LARCH_SOP_POP_32_S_10_5, 38) +ELF_RELOC(R_LARCH_SOP_POP_32_U_10_12, 39) +ELF_RELOC(R_LARCH_SOP_POP_32_S_10_12, 40) +ELF_RELOC(R_LARCH_SOP_POP_32_S_10_16, 41) +ELF_RELOC(R_LARCH_SOP_POP_32_S_10_16_S2, 42) +ELF_RELOC(R_LARCH_SOP_POP_32_S_5_20, 43) +ELF_RELOC(R_LARCH_SOP_POP_32_S_0_5_10_16_S2, 44) +ELF_RELOC(R_LARCH_SOP_POP_32_S_0_10_10_16_S2, 45) +ELF_RELOC(R_LARCH_SOP_POP_32_U, 46) + +ELF_RELOC(R_LARCH_ADD8, 47) +ELF_RELOC(R_LARCH_ADD16, 48) +ELF_RELOC(R_LARCH_ADD24, 49) +ELF_RELOC(R_LARCH_ADD32, 50) +ELF_RELOC(R_LARCH_ADD64, 51) +ELF_RELOC(R_LARCH_SUB8, 52) +ELF_RELOC(R_LARCH_SUB16, 53) +ELF_RELOC(R_LARCH_SUB24, 54) +ELF_RELOC(R_LARCH_SUB32, 55) +ELF_RELOC(R_LARCH_SUB64, 56) + +ELF_RELOC(R_LARCH_GNU_VTINHERIT, 57) +ELF_RELOC(R_LARCH_GNU_VTENTRY, 58) + +ELF_RELOC(R_LARCH_B16, 64) +ELF_RELOC(R_LARCH_B21, 65) +ELF_RELOC(R_LARCH_B26, 66) +ELF_RELOC(R_LARCH_ABS_HI20, 67) +ELF_RELOC(R_LARCH_ABS_LO12, 68) +ELF_RELOC(R_LARCH_ABS64_LO20, 69) +ELF_RELOC(R_LARCH_ABS64_HI12, 70) +ELF_RELOC(R_LARCH_PCALA_HI20, 71) +ELF_RELOC(R_LARCH_PCALA_LO12, 72) +ELF_RELOC(R_LARCH_PCALA64_LO20, 73) +ELF_RELOC(R_LARCH_PCALA64_HI12, 74) +ELF_RELOC(R_LARCH_GOT_PC_HI20, 75) +ELF_RELOC(R_LARCH_GOT_PC_LO12, 76) +ELF_RELOC(R_LARCH_GOT64_PC_LO20, 77) +ELF_RELOC(R_LARCH_GOT64_PC_HI12, 78) +ELF_RELOC(R_LARCH_GOT_HI20, 79) +ELF_RELOC(R_LARCH_GOT_LO12, 80) +ELF_RELOC(R_LARCH_GOT64_LO20, 81) +ELF_RELOC(R_LARCH_GOT64_HI12, 82) +ELF_RELOC(R_LARCH_TLS_LE_HI20, 83) +ELF_RELOC(R_LARCH_TLS_LE_LO12, 84) +ELF_RELOC(R_LARCH_TLS_LE64_LO20, 85) +ELF_RELOC(R_LARCH_TLS_LE64_HI12, 86) +ELF_RELOC(R_LARCH_TLS_IE_PC_HI20, 87) +ELF_RELOC(R_LARCH_TLS_IE_PC_LO12, 88) +ELF_RELOC(R_LARCH_TLS_IE64_PC_LO20, 89) +ELF_RELOC(R_LARCH_TLS_IE64_PC_HI12, 90) +ELF_RELOC(R_LARCH_TLS_IE_HI20, 91) +ELF_RELOC(R_LARCH_TLS_IE_LO12, 92) +ELF_RELOC(R_LARCH_TLS_IE64_LO20, 93) +ELF_RELOC(R_LARCH_TLS_IE64_HI12, 94) +ELF_RELOC(R_LARCH_TLS_LD_PC_HI20, 95) +ELF_RELOC(R_LARCH_TLS_LD_HI20, 96) +ELF_RELOC(R_LARCH_TLS_GD_PC_HI20, 97) +ELF_RELOC(R_LARCH_TLS_GD_HI20, 98) +ELF_RELOC(R_LARCH_32_PCREL, 99) +ELF_RELOC(R_LARCH_RELAX, 100) diff --git a/include/LIEF/ELF/enums.hpp b/include/LIEF/ELF/enums.hpp index 5e804a7eb8..066622e9f2 100644 --- a/include/LIEF/ELF/enums.hpp +++ b/include/LIEF/ELF/enums.hpp @@ -247,7 +247,8 @@ enum class ARCH: size_t { EM_CSR_KALIMBA = 219, /**< CSR Kalimba architecture family */ EM_AMDGPU = 224, /**< AMD GPU architecture */ EM_RISCV = 243, /**< RISC-V */ - EM_BPF = 247 /**< eBPF Filter */ + EM_BPF = 247, /**< eBPF Filter */ + EM_LOONGARCH = 258 /**< Loongson LoongArch */ }; @@ -346,6 +347,11 @@ enum class RELOC_SPARC: size_t { #include "LIEF/ELF/Relocations/Sparc.def" }; +/* ELF Relocation type for LoongArch. */ +enum class RELOC_LOONGARCH: size_t { + #include "LIEF/ELF/Relocations/LoongArch.def" +}; + #undef ELF_RELOC /* Specific e_flags for PPC64 */ @@ -449,7 +455,15 @@ enum class HEXAGON_EFLAGS: size_t { EF_HEXAGON_ISA_V5 = 0x00000040 /* Hexagon V5 ISA */ }; - +/* LoongArch Specific e_flags */ +enum class LOONGARCH_EFLAGS: size_t { + EF_LARCH_BASE_ABI_ILP32S = 0x5, + EF_LARCH_BASE_ABI_ILP32F = 0x6, + EF_LARCH_BASE_ABI_ILP32D = 0x7, + EF_LARCH_BASE_ABI_LP64S = 0x1, + EF_LARCH_BASE_ABI_LP64F = 0x2, + EF_LARCH_BASE_ABI_LP64D = 0x3 +}; /** Special section indices. */ @@ -998,6 +1012,7 @@ ENABLE_BITMASK_OPERATORS(LIEF::ELF::ELF_SEGMENT_FLAGS) ENABLE_BITMASK_OPERATORS(LIEF::ELF::ARM_EFLAGS) ENABLE_BITMASK_OPERATORS(LIEF::ELF::MIPS_EFLAGS) ENABLE_BITMASK_OPERATORS(LIEF::ELF::HEXAGON_EFLAGS) +ENABLE_BITMASK_OPERATORS(LIEF::ELF::LOONGARCH_EFLAGS) ENABLE_BITMASK_OPERATORS(LIEF::ELF::ELF_SECTION_FLAGS) ENABLE_BITMASK_OPERATORS(LIEF::ELF::DYNAMIC_FLAGS) ENABLE_BITMASK_OPERATORS(LIEF::ELF::DYNAMIC_FLAGS_1) diff --git a/include/LIEF/ELF/enums.inc b/include/LIEF/ELF/enums.inc index e78ad199f7..11204d2e3b 100644 --- a/include/LIEF/ELF/enums.inc +++ b/include/LIEF/ELF/enums.inc @@ -222,7 +222,8 @@ enum _LIEF_EN(ARCH) { _LIEF_EI(EM_CSR_KALIMBA) = 219, /**< CSR Kalimba architecture family */ _LIEF_EI(EM_AMDGPU) = 224, /**< AMD GPU architecture */ _LIEF_EI(EM_RISCV) = 243, /**< RISC-V */ - _LIEF_EI(EM_BPF) = 247 /**< eBPF Filter */ + _LIEF_EI(EM_BPF) = 247, /**< eBPF Filter */ + _LIEF_EI(EM_LOONGARCH) = 258 /**< Loongson LoongArch */ }; @@ -321,6 +322,11 @@ enum _LIEF_EN(RELOC_SPARC) { #include "LIEF/ELF/Relocations/Sparc.def" }; +/* ELF Relocation type for LoongArch. */ +enum _LIEF_EN(RELOC_LOONGARCH) { + #include "LIEF/ELF/Relocations/LoongArch.def" +}; + #undef ELF_RELOC /* Specific e_flags for PPC64 */ @@ -425,7 +431,15 @@ enum _LIEF_EN(HEXAGON_EFLAGS) { }; - +/* LoongArch Specific e_flags */ +enum _LIEF_EN(LOONGARCH_EFLAGS) { + _LIEF_EI(EF_LARCH_BASE_ABI_ILP32S) = 0x5, + _LIEF_EI(EF_LARCH_BASE_ABI_ILP32F) = 0x6, + _LIEF_EI(EF_LARCH_BASE_ABI_ILP32D) = 0x7, + _LIEF_EI(EF_LARCH_BASE_ABI_LP64S) = 0x1, + _LIEF_EI(EF_LARCH_BASE_ABI_LP64F) = 0x2, + _LIEF_EI(EF_LARCH_BASE_ABI_LP64D) = 0x3 +}; /** Special section indices. */ enum _LIEF_EN(SYMBOL_SECTION_INDEX) { diff --git a/include/LIEF/ELF/undef.h b/include/LIEF/ELF/undef.h index fb2321003d..3d3e528c2d 100644 --- a/include/LIEF/ELF/undef.h +++ b/include/LIEF/ELF/undef.h @@ -232,6 +232,7 @@ #undef EM_AMDGPU #undef EM_RISCV #undef EM_BPF +#undef EM_LOONGARCH #undef ELFCLASSNONE @@ -348,6 +349,14 @@ #undef EF_HEXAGON_ISA_V5 +#undef EF_LARCH_BASE_ABI_ILP32S +#undef EF_LARCH_BASE_ABI_ILP32F +#undef EF_LARCH_BASE_ABI_ILP32D +#undef EF_LARCH_BASE_ABI_LP64S +#undef EF_LARCH_BASE_ABI_LP64F +#undef EF_LARCH_BASE_ABI_LP64D + + #undef SHN_UNDEF #undef SHN_LORESERVE #undef SHN_LOPROC @@ -1576,6 +1585,95 @@ #undef R_X86_64_GOTPCRELX #undef R_X86_64_REX_GOTPCRELX +#undef R_LARCH_NONE +#undef R_LARCH_32 +#undef R_LARCH_64 +#undef R_LARCH_RELATIVE +#undef R_LARCH_COPY +#undef R_LARCH_JUMP_SLOT +#undef R_LARCH_TLS_DTPMOD32 +#undef R_LARCH_TLS_DTPMOD64 +#undef R_LARCH_TLS_DTPREL32 +#undef R_LARCH_TLS_DTPREL64 +#undef R_LARCH_TLS_TPREL32 +#undef R_LARCH_TLS_TPREL64 +#undef R_LARCH_IRELATIVE +#undef R_LARCH_MARK_LA +#undef R_LARCH_MARK_PCREL +#undef R_LARCH_SOP_PUSH_PCREL +#undef R_LARCH_SOP_PUSH_ABSOLUTE +#undef R_LARCH_SOP_PUSH_DUP +#undef R_LARCH_SOP_PUSH_GPREL +#undef R_LARCH_SOP_PUSH_TLS_TPREL +#undef R_LARCH_SOP_PUSH_TLS_GOT +#undef R_LARCH_SOP_PUSH_TLS_GD +#undef R_LARCH_SOP_PUSH_PLT_PCREL +#undef R_LARCH_SOP_ASSERT +#undef R_LARCH_SOP_NOT +#undef R_LARCH_SOP_SUB +#undef R_LARCH_SOP_SL +#undef R_LARCH_SOP_SR +#undef R_LARCH_SOP_ADD +#undef R_LARCH_SOP_AND +#undef R_LARCH_SOP_IF_ELSE +#undef R_LARCH_SOP_POP_32_S_10_5 +#undef R_LARCH_SOP_POP_32_U_10_12 +#undef R_LARCH_SOP_POP_32_S_10_12 +#undef R_LARCH_SOP_POP_32_S_10_16 +#undef R_LARCH_SOP_POP_32_S_10_16_S2 +#undef R_LARCH_SOP_POP_32_S_5_20 +#undef R_LARCH_SOP_POP_32_S_0_5_10_16_S2 +#undef R_LARCH_SOP_POP_32_S_0_10_10_16_S2 +#undef R_LARCH_SOP_POP_32_U +#undef R_LARCH_ADD8 +#undef R_LARCH_ADD16 +#undef R_LARCH_ADD24 +#undef R_LARCH_ADD32 +#undef R_LARCH_ADD64 +#undef R_LARCH_SUB8 +#undef R_LARCH_SUB16 +#undef R_LARCH_SUB24 +#undef R_LARCH_SUB32 +#undef R_LARCH_SUB64 +#undef R_LARCH_GNU_VTINHERIT +#undef R_LARCH_GNU_VTENTRY +#undef R_LARCH_B16 +#undef R_LARCH_B21 +#undef R_LARCH_B26 +#undef R_LARCH_ABS_HI20 +#undef R_LARCH_ABS_LO12 +#undef R_LARCH_ABS64_LO20 +#undef R_LARCH_ABS64_HI12 +#undef R_LARCH_PCALA_HI20 +#undef R_LARCH_PCALA_LO12 +#undef R_LARCH_PCALA64_LO20 +#undef R_LARCH_PCALA64_HI12 +#undef R_LARCH_GOT_PC_HI20 +#undef R_LARCH_GOT_PC_LO12 +#undef R_LARCH_GOT64_PC_LO20 +#undef R_LARCH_GOT64_PC_HI12 +#undef R_LARCH_GOT_HI20 +#undef R_LARCH_GOT_LO12 +#undef R_LARCH_GOT64_LO20 +#undef R_LARCH_GOT64_HI12 +#undef R_LARCH_TLS_LE_HI20 +#undef R_LARCH_TLS_LE_LO12 +#undef R_LARCH_TLS_LE64_LO20 +#undef R_LARCH_TLS_LE64_HI12 +#undef R_LARCH_TLS_IE_PC_HI20 +#undef R_LARCH_TLS_IE_PC_LO12 +#undef R_LARCH_TLS_IE64_PC_LO20 +#undef R_LARCH_TLS_IE64_PC_HI12 +#undef R_LARCH_TLS_IE_HI20 +#undef R_LARCH_TLS_IE_LO12 +#undef R_LARCH_TLS_IE64_LO20 +#undef R_LARCH_TLS_IE64_HI12 +#undef R_LARCH_TLS_LD_PC_HI20 +#undef R_LARCH_TLS_LD_HI20 +#undef R_LARCH_TLS_GD_PC_HI20 +#undef R_LARCH_TLS_GD_HI20 +#undef R_LARCH_32_PCREL +#undef R_LARCH_RELAX #undef AT_NULL #undef AT_IGNORE diff --git a/src/Abstract/EnumToString.cpp b/src/Abstract/EnumToString.cpp index 3fd004a274..947e546fda 100644 --- a/src/Abstract/EnumToString.cpp +++ b/src/Abstract/EnumToString.cpp @@ -41,7 +41,7 @@ const char* to_string(OBJECT_TYPES e) { } const char* to_string(ARCHITECTURES e) { - CONST_MAP(ARCHITECTURES, const char*, 11) enumStrings { + CONST_MAP(ARCHITECTURES, const char*, 12) enumStrings { { ARCHITECTURES::ARCH_NONE, "NONE" }, { ARCHITECTURES::ARCH_ARM, "ARM" }, { ARCHITECTURES::ARCH_ARM64, "ARM64" }, @@ -53,6 +53,7 @@ const char* to_string(ARCHITECTURES e) { { ARCHITECTURES::ARCH_XCORE, "XCORE" }, { ARCHITECTURES::ARCH_INTEL, "INTEL" }, { ARCHITECTURES::ARCH_RISCV, "RISCV" }, + { ARCHITECTURES::ARCH_LOONGARCH, "LOONGARCH" }, }; const auto it = enumStrings.find(e); return it == enumStrings.end() ? "UNDEFINED" : it->second; diff --git a/src/ELF/EnumToString.cpp b/src/ELF/EnumToString.cpp index a883bceb81..e17b470086 100644 --- a/src/ELF/EnumToString.cpp +++ b/src/ELF/EnumToString.cpp @@ -58,7 +58,7 @@ const char* to_string(VERSION e) { const char* to_string(ARCH e) { - CONST_MAP(ARCH, const char*, 177) enumStrings { + CONST_MAP(ARCH, const char*, 178) enumStrings { { ARCH::EM_NONE, "NONE" }, { ARCH::EM_M32, "M32"}, { ARCH::EM_SPARC, "SPARC"}, @@ -235,7 +235,8 @@ const char* to_string(ARCH e) { { ARCH::EM_CSR_KALIMBA, "CSR_KALIMBA"}, { ARCH::EM_AMDGPU, "AMDGPU"}, { ARCH::EM_RISCV, "RISCV"}, - { ARCH::EM_BPF, "BPF"} + { ARCH::EM_BPF, "BPF"}, + { ARCH::EM_LOONGARCH, "LOONGARCH"} }; const auto it = enumStrings.find(e); return it == enumStrings.end() ? "UNDEFINED" : it->second; @@ -1126,6 +1127,102 @@ const char* to_string(RELOC_MIPS e) { return it == enumStrings.end() ? "UNDEFINED" : it->second; } +const char* to_string(RELOC_LOONGARCH e) { + CONST_MAP(RELOC_LOONGARCH, const char*, 89) enumStrings { + { RELOC_LOONGARCH::R_LARCH_NONE, "LARCH_NONE" }, + { RELOC_LOONGARCH::R_LARCH_32, "LARCH_32" }, + { RELOC_LOONGARCH::R_LARCH_64, "LARCH_64" }, + { RELOC_LOONGARCH::R_LARCH_RELATIVE, "LARCH_RELATIVE" }, + { RELOC_LOONGARCH::R_LARCH_COPY, "LARCH_COPY" }, + { RELOC_LOONGARCH::R_LARCH_JUMP_SLOT, "LARCH_JUMP_SLOT" }, + { RELOC_LOONGARCH::R_LARCH_TLS_DTPMOD32, "LARCH_TLS_DTPMOD32" }, + { RELOC_LOONGARCH::R_LARCH_TLS_DTPMOD64, "LARCH_TLS_DTPMOD64" }, + { RELOC_LOONGARCH::R_LARCH_TLS_DTPREL32, "LARCH_TLS_DTPREL32" }, + { RELOC_LOONGARCH::R_LARCH_TLS_DTPREL64, "LARCH_TLS_DTPREL64" }, + { RELOC_LOONGARCH::R_LARCH_TLS_TPREL32, "LARCH_TLS_TPREL32" }, + { RELOC_LOONGARCH::R_LARCH_TLS_TPREL64, "LARCH_TLS_TPREL64" }, + { RELOC_LOONGARCH::R_LARCH_IRELATIVE, "LARCH_IRELATIVE" }, + { RELOC_LOONGARCH::R_LARCH_MARK_LA, "LARCH_MARK_LA" }, + { RELOC_LOONGARCH::R_LARCH_MARK_PCREL, "LARCH_MARK_PCREL" }, + { RELOC_LOONGARCH::R_LARCH_SOP_PUSH_PCREL, "LARCH_SOP_PUSH_PCREL" }, + { RELOC_LOONGARCH::R_LARCH_SOP_PUSH_ABSOLUTE, "LARCH_SOP_PUSH_ABSOLUTE" }, + { RELOC_LOONGARCH::R_LARCH_SOP_PUSH_DUP, "LARCH_SOP_PUSH_DUP" }, + { RELOC_LOONGARCH::R_LARCH_SOP_PUSH_GPREL, "LARCH_SOP_PUSH_GPREL" }, + { RELOC_LOONGARCH::R_LARCH_SOP_PUSH_TLS_TPREL, "LARCH_SOP_PUSH_TLS_TPREL" }, + { RELOC_LOONGARCH::R_LARCH_SOP_PUSH_TLS_GOT, "LARCH_SOP_PUSH_TLS_GOT" }, + { RELOC_LOONGARCH::R_LARCH_SOP_PUSH_TLS_GD, "LARCH_SOP_PUSH_TLS_GD" }, + { RELOC_LOONGARCH::R_LARCH_SOP_PUSH_PLT_PCREL, "LARCH_SOP_PUSH_PLT_PCREL" }, + { RELOC_LOONGARCH::R_LARCH_SOP_ASSERT, "LARCH_SOP_ASSERT" }, + { RELOC_LOONGARCH::R_LARCH_SOP_NOT, "LARCH_SOP_NOT" }, + { RELOC_LOONGARCH::R_LARCH_SOP_SUB, "LARCH_SOP_SUB" }, + { RELOC_LOONGARCH::R_LARCH_SOP_SL, "LARCH_SOP_SL" }, + { RELOC_LOONGARCH::R_LARCH_SOP_SR, "LARCH_SOP_SR" }, + { RELOC_LOONGARCH::R_LARCH_SOP_ADD, "LARCH_SOP_ADD" }, + { RELOC_LOONGARCH::R_LARCH_SOP_AND, "LARCH_SOP_AND" }, + { RELOC_LOONGARCH::R_LARCH_SOP_IF_ELSE, "LARCH_SOP_IF_ELSE" }, + { RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_10_5, "LARCH_SOP_POP_32_S_10_5" }, + { RELOC_LOONGARCH::R_LARCH_SOP_POP_32_U_10_12, "LARCH_SOP_POP_32_U_10_12" }, + { RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_10_12, "LARCH_SOP_POP_32_S_10_12" }, + { RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_10_16, "LARCH_SOP_POP_32_S_10_16" }, + { RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_10_16_S2, "LARCH_SOP_POP_32_S_10_16_S2" }, + { RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_5_20, "LARCH_SOP_POP_32_S_5_20" }, + { RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_0_5_10_16_S2, "LARCH_SOP_POP_32_S_0_5_10_16_S2" }, + { RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_0_10_10_16_S2, "LARCH_SOP_POP_32_S_0_10_10_16_S2" }, + { RELOC_LOONGARCH::R_LARCH_SOP_POP_32_U, "LARCH_SOP_POP_32_U" }, + { RELOC_LOONGARCH::R_LARCH_ADD8, "LARCH_ADD8" }, + { RELOC_LOONGARCH::R_LARCH_ADD16, "LARCH_ADD16" }, + { RELOC_LOONGARCH::R_LARCH_ADD24, "LARCH_ADD24" }, + { RELOC_LOONGARCH::R_LARCH_ADD32, "LARCH_ADD32" }, + { RELOC_LOONGARCH::R_LARCH_ADD64, "LARCH_ADD64" }, + { RELOC_LOONGARCH::R_LARCH_SUB8, "LARCH_SUB8" }, + { RELOC_LOONGARCH::R_LARCH_SUB16, "LARCH_SUB16" }, + { RELOC_LOONGARCH::R_LARCH_SUB24, "LARCH_SUB24" }, + { RELOC_LOONGARCH::R_LARCH_SUB32, "LARCH_SUB32" }, + { RELOC_LOONGARCH::R_LARCH_SUB64, "LARCH_SUB64" }, + { RELOC_LOONGARCH::R_LARCH_GNU_VTINHERIT, "LARCH_GNU_VTINHERIT" }, + { RELOC_LOONGARCH::R_LARCH_GNU_VTENTRY, "LARCH_GNU_VTENTRY" }, + { RELOC_LOONGARCH::R_LARCH_B16, "LARCH_B16" }, + { RELOC_LOONGARCH::R_LARCH_B21, "LARCH_B21" }, + { RELOC_LOONGARCH::R_LARCH_B26, "LARCH_B26" }, + { RELOC_LOONGARCH::R_LARCH_ABS_HI20, "LARCH_ABS_HI20" }, + { RELOC_LOONGARCH::R_LARCH_ABS_LO12, "LARCH_ABS_LO12" }, + { RELOC_LOONGARCH::R_LARCH_ABS64_LO20, "LARCH_ABS64_LO20" }, + { RELOC_LOONGARCH::R_LARCH_ABS64_HI12, "LARCH_ABS64_HI12" }, + { RELOC_LOONGARCH::R_LARCH_PCALA_HI20, "LARCH_PCALA_HI20" }, + { RELOC_LOONGARCH::R_LARCH_PCALA_LO12, "LARCH_PCALA_LO12" }, + { RELOC_LOONGARCH::R_LARCH_PCALA64_LO20, "LARCH_PCALA64_LO20" }, + { RELOC_LOONGARCH::R_LARCH_PCALA64_HI12, "LARCH_PCALA64_HI12" }, + { RELOC_LOONGARCH::R_LARCH_GOT_PC_HI20, "LARCH_GOT_PC_HI20" }, + { RELOC_LOONGARCH::R_LARCH_GOT_PC_LO12, "LARCH_GOT_PC_LO12" }, + { RELOC_LOONGARCH::R_LARCH_GOT64_PC_LO20, "LARCH_GOT64_PC_LO20" }, + { RELOC_LOONGARCH::R_LARCH_GOT64_PC_HI12, "LARCH_GOT64_PC_HI12" }, + { RELOC_LOONGARCH::R_LARCH_GOT_HI20, "LARCH_GOT_HI20" }, + { RELOC_LOONGARCH::R_LARCH_GOT_LO12, "LARCH_GOT_LO12" }, + { RELOC_LOONGARCH::R_LARCH_GOT64_LO20, "LARCH_GOT64_LO20" }, + { RELOC_LOONGARCH::R_LARCH_GOT64_HI12, "LARCH_GOT64_HI12" }, + { RELOC_LOONGARCH::R_LARCH_TLS_LE_HI20, "LARCH_TLS_LE_HI20" }, + { RELOC_LOONGARCH::R_LARCH_TLS_LE_LO12, "LARCH_TLS_LE_LO12" }, + { RELOC_LOONGARCH::R_LARCH_TLS_LE64_LO20, "LARCH_TLS_LE64_LO20" }, + { RELOC_LOONGARCH::R_LARCH_TLS_LE64_HI12, "LARCH_TLS_LE64_HI12" }, + { RELOC_LOONGARCH::R_LARCH_TLS_IE_PC_HI20, "LARCH_TLS_IE_PC_HI20" }, + { RELOC_LOONGARCH::R_LARCH_TLS_IE_PC_LO12, "LARCH_TLS_IE_PC_LO12" }, + { RELOC_LOONGARCH::R_LARCH_TLS_IE64_PC_LO20, "LARCH_TLS_IE64_PC_LO20" }, + { RELOC_LOONGARCH::R_LARCH_TLS_IE64_PC_HI12, "LARCH_TLS_IE64_PC_HI12" }, + { RELOC_LOONGARCH::R_LARCH_TLS_IE_HI20, "LARCH_TLS_IE_HI20" }, + { RELOC_LOONGARCH::R_LARCH_TLS_IE_LO12, "LARCH_TLS_IE_LO12" }, + { RELOC_LOONGARCH::R_LARCH_TLS_IE64_LO20, "LARCH_TLS_IE64_LO20" }, + { RELOC_LOONGARCH::R_LARCH_TLS_IE64_HI12, "LARCH_TLS_IE64_HI12" }, + { RELOC_LOONGARCH::R_LARCH_TLS_LD_PC_HI20, "LARCH_TLS_LD_PC_HI20" }, + { RELOC_LOONGARCH::R_LARCH_TLS_LD_HI20, "LARCH_TLS_LD_HI20" }, + { RELOC_LOONGARCH::R_LARCH_TLS_GD_PC_HI20, "LARCH_TLS_GD_PC_HI20" }, + { RELOC_LOONGARCH::R_LARCH_TLS_GD_HI20, "LARCH_TLS_GD_HI20" }, + { RELOC_LOONGARCH::R_LARCH_32_PCREL, "LARCH_32_PCREL" }, + { RELOC_LOONGARCH::R_LARCH_RELAX, "LARCH_RELAX" }, + }; + const auto it = enumStrings.find(e); + return it == enumStrings.end() ? "UNDEFINED" : it->second; +} + const char* to_string(ELF_CLASS e) { CONST_MAP(ELF_CLASS, const char*, 3) enumStrings { { ELF_CLASS::ELFCLASSNONE, "NONE"}, @@ -1368,6 +1465,20 @@ const char* to_string(HEXAGON_EFLAGS e) { return it == enumStrings.end() ? "UNDEFINED" : it->second; } +const char* to_string(LOONGARCH_EFLAGS e) { + CONST_MAP(LOONGARCH_EFLAGS, const char*, 6) enumStrings { + { LOONGARCH_EFLAGS::EF_LARCH_BASE_ABI_ILP32S, "BASE_ABI_ILP32S" }, + { LOONGARCH_EFLAGS::EF_LARCH_BASE_ABI_ILP32F, "BASE_ABI_ILP32F" }, + { LOONGARCH_EFLAGS::EF_LARCH_BASE_ABI_ILP32D, "BASE_ABI_ILP32D" }, + { LOONGARCH_EFLAGS::EF_LARCH_BASE_ABI_LP64S, "BASE_ABI_LP64S" }, + { LOONGARCH_EFLAGS::EF_LARCH_BASE_ABI_LP64F, "BASE_ABI_LP64F" }, + { LOONGARCH_EFLAGS::EF_LARCH_BASE_ABI_LP64D, "BASE_ABI_LP64D" }, + }; + + const auto it = enumStrings.find(e); + return it == enumStrings.end() ? "UNDEFINED" : it->second; +} + const char* to_string(IDENTITY e) { CONST_MAP(IDENTITY, const char*, 11) enumStrings { { IDENTITY::EI_MAG0, "MAG0" }, diff --git a/src/ELF/Header.cpp b/src/ELF/Header.cpp index 3f7cbc1ae7..580f610e5c 100644 --- a/src/ELF/Header.cpp +++ b/src/ELF/Header.cpp @@ -133,6 +133,7 @@ Header::abstract_architecture_t Header::abstract_architecture() const { {ARCH::EM_PPC, {ARCH_PPC, {MODE_32}}}, {ARCH::EM_PPC64, {ARCH_PPC, {MODE_64}}}, {ARCH::EM_RISCV, {ARCH_RISCV, {MODE_64}}}, + {ARCH::EM_LOONGARCH, {ARCH_LOONGARCH, {MODE_64}}}, }; const auto it = arch_elf_to_lief.find(machine_type()); @@ -363,6 +364,26 @@ Header::hexagon_flags_list_t Header::hexagon_flags_list() const { } +bool Header::has(LOONGARCH_EFLAGS f) const { + if (machine_type() != ARCH::EM_LOONGARCH) { + return false; + } + + return (processor_flag() & static_cast(f)) > 0; +} + +Header::loongarch_flags_list_t Header::loongarch_flags_list() const { + loongarch_flags_list_t flags; + + std::copy_if( + std::begin(details::loongarch_eflags_array), + std::end(details::loongarch_eflags_array), + std::inserter(flags, std::begin(flags)), + [this] (LOONGARCH_EFLAGS f) { return has(f); }); + + return flags; + +} uint32_t Header::header_size() const { return header_size_; @@ -598,6 +619,16 @@ std::ostream& operator<<(std::ostream& os, const Header& hdr) }); } + if (hdr.machine_type() == ARCH::EM_LOONGARCH) { + const Header::loongarch_flags_list_t& flags = hdr.loongarch_flags_list(); + processor_flags_str = std::accumulate( + std::begin(flags), + std::end(flags), std::string{}, + [] (const std::string& a, LOONGARCH_EFLAGS b) { + return a.empty() ? to_string(b) : a + " " + to_string(b); + }); + } + os << std::hex << std::left; os << std::setw(33) << std::setfill(' ') << "Magic:" << ident_magic << std::endl; os << std::setw(33) << std::setfill(' ') << "Class:" << to_string(hdr.identity_class()) << std::endl; diff --git a/src/ELF/Parser.cpp b/src/ELF/Parser.cpp index a698379935..2b53bced87 100644 --- a/src/ELF/Parser.cpp +++ b/src/ELF/Parser.cpp @@ -99,6 +99,7 @@ ELF_DATA determine_elf_endianess(ARCH machine) { case ARCH::EM_386: // x86 case ARCH::EM_X86_64: case ARCH::EM_IA_64: + case ARCH::EM_LOONGARCH: { return ELF_DATA::ELFDATA2LSB; } diff --git a/src/ELF/Relocation.cpp b/src/ELF/Relocation.cpp index 9690dc3f7b..05ca5162a9 100644 --- a/src/ELF/Relocation.cpp +++ b/src/ELF/Relocation.cpp @@ -242,6 +242,17 @@ size_t Relocation::size() const { return size; } + case ARCH::EM_LOONGARCH: + { + const auto rtype = static_cast(type()); + const int32_t size = get_reloc_size(rtype); + if (size < 0) { + LIEF_ERR("{} - {}", to_string(architecture()), to_string(rtype)); + return SIZE_MAX; + } + return size; + } + default: { LIEF_ERR("Architecture {} not implemented", to_string(architecture())); @@ -355,6 +366,12 @@ std::ostream& operator<<(std::ostream& os, const Relocation& entry) { break; } + case ARCH::EM_LOONGARCH: + { + relocation_type = to_string(static_cast(entry.type())); + break; + } + default: { relocation_type = std::to_string(entry.type()); diff --git a/src/ELF/RelocationSizes.cpp b/src/ELF/RelocationSizes.cpp index 9296285436..d017fcc18d 100644 --- a/src/ELF/RelocationSizes.cpp +++ b/src/ELF/RelocationSizes.cpp @@ -670,6 +670,102 @@ int32_t get_reloc_size(RELOC_MIPS R) { return it == SIZES.end() ? -1 : it->second; } +int32_t get_reloc_size(RELOC_LOONGARCH R) { + CONST_MAP(RELOC_LOONGARCH, uint32_t, 89) SIZES { + {RELOC_LOONGARCH::R_LARCH_NONE, 0}, + {RELOC_LOONGARCH::R_LARCH_32, 32}, + {RELOC_LOONGARCH::R_LARCH_64, 64}, + {RELOC_LOONGARCH::R_LARCH_RELATIVE, 32}, + {RELOC_LOONGARCH::R_LARCH_COPY, 0}, + {RELOC_LOONGARCH::R_LARCH_JUMP_SLOT, 64}, + {RELOC_LOONGARCH::R_LARCH_TLS_DTPMOD32, 32}, + {RELOC_LOONGARCH::R_LARCH_TLS_DTPMOD64, 64}, + {RELOC_LOONGARCH::R_LARCH_TLS_DTPREL32, 32}, + {RELOC_LOONGARCH::R_LARCH_TLS_DTPREL64, 64}, + {RELOC_LOONGARCH::R_LARCH_TLS_TPREL32, 32}, + {RELOC_LOONGARCH::R_LARCH_TLS_TPREL64, 64}, + {RELOC_LOONGARCH::R_LARCH_IRELATIVE, 32}, + {RELOC_LOONGARCH::R_LARCH_MARK_LA, 0}, + {RELOC_LOONGARCH::R_LARCH_MARK_PCREL, 0}, + {RELOC_LOONGARCH::R_LARCH_SOP_PUSH_PCREL, 32}, + {RELOC_LOONGARCH::R_LARCH_SOP_PUSH_ABSOLUTE, 32}, + {RELOC_LOONGARCH::R_LARCH_SOP_PUSH_DUP, 32}, + {RELOC_LOONGARCH::R_LARCH_SOP_PUSH_GPREL, 32}, + {RELOC_LOONGARCH::R_LARCH_SOP_PUSH_TLS_TPREL, 32}, + {RELOC_LOONGARCH::R_LARCH_SOP_PUSH_TLS_GOT, 32}, + {RELOC_LOONGARCH::R_LARCH_SOP_PUSH_TLS_GD, 32}, + {RELOC_LOONGARCH::R_LARCH_SOP_PUSH_PLT_PCREL, 32}, + {RELOC_LOONGARCH::R_LARCH_SOP_ASSERT, 32}, + {RELOC_LOONGARCH::R_LARCH_SOP_NOT, 32}, + {RELOC_LOONGARCH::R_LARCH_SOP_SUB, 32}, + {RELOC_LOONGARCH::R_LARCH_SOP_SL, 32}, + {RELOC_LOONGARCH::R_LARCH_SOP_SR, 32}, + {RELOC_LOONGARCH::R_LARCH_SOP_ADD, 32}, + {RELOC_LOONGARCH::R_LARCH_SOP_AND, 32}, + {RELOC_LOONGARCH::R_LARCH_SOP_IF_ELSE, 32}, + {RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_10_5, 5}, + {RELOC_LOONGARCH::R_LARCH_SOP_POP_32_U_10_12, 12}, + {RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_10_12, 12}, + {RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_10_16, 16}, + {RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_10_16_S2, 16}, + {RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_5_20, 20}, + {RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_0_5_10_16_S2, 21}, + {RELOC_LOONGARCH::R_LARCH_SOP_POP_32_S_0_10_10_16_S2, 26}, + {RELOC_LOONGARCH::R_LARCH_SOP_POP_32_U, 32}, + {RELOC_LOONGARCH::R_LARCH_ADD8, 8}, + {RELOC_LOONGARCH::R_LARCH_ADD16, 16}, + {RELOC_LOONGARCH::R_LARCH_ADD24, 24}, + {RELOC_LOONGARCH::R_LARCH_ADD32, 32}, + {RELOC_LOONGARCH::R_LARCH_ADD64, 64}, + {RELOC_LOONGARCH::R_LARCH_SUB8, 8}, + {RELOC_LOONGARCH::R_LARCH_SUB16, 16}, + {RELOC_LOONGARCH::R_LARCH_SUB24, 24}, + {RELOC_LOONGARCH::R_LARCH_SUB32, 32}, + {RELOC_LOONGARCH::R_LARCH_SUB64, 64}, + {RELOC_LOONGARCH::R_LARCH_GNU_VTINHERIT, 0}, + {RELOC_LOONGARCH::R_LARCH_GNU_VTENTRY, 0}, + {RELOC_LOONGARCH::R_LARCH_B16, 16}, + {RELOC_LOONGARCH::R_LARCH_B21, 21}, + {RELOC_LOONGARCH::R_LARCH_B26, 26}, + {RELOC_LOONGARCH::R_LARCH_ABS_HI20, 20}, + {RELOC_LOONGARCH::R_LARCH_ABS_LO12, 12}, + {RELOC_LOONGARCH::R_LARCH_ABS64_LO20, 20}, + {RELOC_LOONGARCH::R_LARCH_ABS64_HI12, 12}, + {RELOC_LOONGARCH::R_LARCH_PCALA_HI20, 20}, + {RELOC_LOONGARCH::R_LARCH_PCALA_LO12, 12}, + {RELOC_LOONGARCH::R_LARCH_PCALA64_LO20, 20}, + {RELOC_LOONGARCH::R_LARCH_PCALA64_HI12, 12}, + {RELOC_LOONGARCH::R_LARCH_GOT_PC_HI20, 20}, + {RELOC_LOONGARCH::R_LARCH_GOT_PC_LO12, 12}, + {RELOC_LOONGARCH::R_LARCH_GOT64_PC_LO20, 20}, + {RELOC_LOONGARCH::R_LARCH_GOT64_PC_HI12, 12}, + {RELOC_LOONGARCH::R_LARCH_GOT_HI20, 20}, + {RELOC_LOONGARCH::R_LARCH_GOT_LO12, 12}, + {RELOC_LOONGARCH::R_LARCH_GOT64_LO20, 20}, + {RELOC_LOONGARCH::R_LARCH_GOT64_HI12, 12}, + {RELOC_LOONGARCH::R_LARCH_TLS_LE_HI20, 20}, + {RELOC_LOONGARCH::R_LARCH_TLS_LE_LO12, 12}, + {RELOC_LOONGARCH::R_LARCH_TLS_LE64_LO20, 20}, + {RELOC_LOONGARCH::R_LARCH_TLS_LE64_HI12, 12}, + {RELOC_LOONGARCH::R_LARCH_TLS_IE_PC_HI20, 20}, + {RELOC_LOONGARCH::R_LARCH_TLS_IE_PC_LO12, 12}, + {RELOC_LOONGARCH::R_LARCH_TLS_IE64_PC_LO20, 20}, + {RELOC_LOONGARCH::R_LARCH_TLS_IE64_PC_HI12, 12}, + {RELOC_LOONGARCH::R_LARCH_TLS_IE_HI20, 20}, + {RELOC_LOONGARCH::R_LARCH_TLS_IE_LO12, 12}, + {RELOC_LOONGARCH::R_LARCH_TLS_IE64_LO20, 20}, + {RELOC_LOONGARCH::R_LARCH_TLS_IE64_HI12, 12}, + {RELOC_LOONGARCH::R_LARCH_TLS_LD_PC_HI20, 20}, + {RELOC_LOONGARCH::R_LARCH_TLS_LD_HI20, 20}, + {RELOC_LOONGARCH::R_LARCH_TLS_GD_PC_HI20, 20}, + {RELOC_LOONGARCH::R_LARCH_TLS_GD_HI20, 20}, + {RELOC_LOONGARCH::R_LARCH_32_PCREL, 32}, + {RELOC_LOONGARCH::R_LARCH_RELAX, 0}, +}; + const auto it = SIZES.find(R); + return it == SIZES.end() ? -1 : it->second; +} + } } diff --git a/src/ELF/Structures.hpp b/src/ELF/Structures.hpp index 8e879855e3..232f7ab8c2 100644 --- a/src/ELF/Structures.hpp +++ b/src/ELF/Structures.hpp @@ -114,6 +114,15 @@ static const HEXAGON_EFLAGS hexagon_eflags_array[] = { HEXAGON_EFLAGS::EF_HEXAGON_ISA_V5, }; +static const LOONGARCH_EFLAGS loongarch_eflags_array[] = { + LOONGARCH_EFLAGS::EF_LARCH_BASE_ABI_ILP32S, + LOONGARCH_EFLAGS::EF_LARCH_BASE_ABI_ILP32F, + LOONGARCH_EFLAGS::EF_LARCH_BASE_ABI_ILP32D, + LOONGARCH_EFLAGS::EF_LARCH_BASE_ABI_LP64S, + LOONGARCH_EFLAGS::EF_LARCH_BASE_ABI_LP64F, + LOONGARCH_EFLAGS::EF_LARCH_BASE_ABI_LP64D, +}; + static const DYNAMIC_FLAGS dynamic_flags_array[] = { DYNAMIC_FLAGS::DF_ORIGIN, DYNAMIC_FLAGS::DF_SYMBOLIC,