Index: lld/ELF/Arch/CSKY.cpp =================================================================== --- /dev/null +++ lld/ELF/Arch/CSKY.cpp @@ -0,0 +1,68 @@ +//===- CSKY.cpp -----------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "InputFiles.h" +#include "Symbols.h" +#include "Target.h" +#include "llvm/BinaryFormat/ELF.h" +#include "llvm/Support/Endian.h" + +using namespace llvm; +using namespace llvm::support::endian; +using namespace llvm::ELF; +using namespace lld; +using namespace lld::elf; + +namespace { +class CSKY final : public TargetInfo { +public: + CSKY() {} + RelExpr getRelExpr(RelType type, const Symbol &s, + const uint8_t *loc) const override; + void relocate(uint8_t *loc, const Relocation &rel, + uint64_t val) const override; +}; +} // namespace + +RelExpr CSKY::getRelExpr(RelType type, const Symbol &s, + const uint8_t *loc) const { + switch (type) { + case R_CKCORE_ADDR32: + return R_ABS; + case R_CKCORE_PCREL_IMM26_2: + return R_PC; + default: + return R_NONE; + } +} + +void CSKY::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { + switch (rel.type) { + case R_CKCORE_ADDR32: + checkUInt(loc, val, 32, rel); + write32le(loc, val); + break; + + case R_CKCORE_PCREL_IMM26_2: { + checkAlignment(loc, val, 2, rel); + const int32_t Off = ((int64_t)val) >> 1; + checkInt(loc, Off, 26, rel); + write16le(loc, (read16le(loc) & 0xfc00) | ((Off >> 16) & 0x03ff)); + write16le(loc + 2, Off & 0xffff); + break; + } + + default: + llvm_unreachable("unknown relocation"); + } +} + +TargetInfo *elf::getCSKYTargetInfo() { + static CSKY target; + return ⌖ +} Index: lld/ELF/CMakeLists.txt =================================================================== --- lld/ELF/CMakeLists.txt +++ lld/ELF/CMakeLists.txt @@ -24,6 +24,7 @@ Arch/AMDGPU.cpp Arch/ARM.cpp Arch/AVR.cpp + Arch/CSKY.cpp Arch/Hexagon.cpp Arch/Mips.cpp Arch/MipsArchTree.cpp Index: lld/ELF/InputFiles.cpp =================================================================== --- lld/ELF/InputFiles.cpp +++ lld/ELF/InputFiles.cpp @@ -1556,6 +1556,8 @@ return EM_ARM; case Triple::avr: return EM_AVR; + case Triple::csky: + return EM_CSKY; case Triple::hexagon: return EM_HEXAGON; case Triple::mips: Index: lld/ELF/ScriptParser.cpp =================================================================== --- lld/ELF/ScriptParser.cpp +++ lld/ELF/ScriptParser.cpp @@ -424,6 +424,7 @@ .Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64}) .Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64}) .Case("elf64-bigaarch64", {ELF64BEKind, EM_AARCH64}) + .Case("elf32-csky", {ELF32LEKind, EM_CSKY}) .Case("elf32-powerpc", {ELF32BEKind, EM_PPC}) .Case("elf32-powerpcle", {ELF32LEKind, EM_PPC}) .Case("elf64-powerpc", {ELF64BEKind, EM_PPC64}) Index: lld/ELF/Target.h =================================================================== --- lld/ELF/Target.h +++ lld/ELF/Target.h @@ -177,6 +177,7 @@ TargetInfo *getAMDGPUTargetInfo(); TargetInfo *getARMTargetInfo(); TargetInfo *getAVRTargetInfo(); +TargetInfo *getCSKYTargetInfo(); TargetInfo *getHexagonTargetInfo(); TargetInfo *getMSP430TargetInfo(); TargetInfo *getPPC64TargetInfo(); Index: lld/ELF/Target.cpp =================================================================== --- lld/ELF/Target.cpp +++ lld/ELF/Target.cpp @@ -60,6 +60,8 @@ return getARMTargetInfo(); case EM_AVR: return getAVRTargetInfo(); + case EM_CSKY: + return getCSKYTargetInfo(); case EM_HEXAGON: return getHexagonTargetInfo(); case EM_MIPS: Index: lld/test/ELF/csky-reloc.s =================================================================== --- /dev/null +++ lld/test/ELF/csky-reloc.s @@ -0,0 +1,35 @@ +# REQUIRES: csky +# RUN: llvm-mc -filetype=obj -triple=csky %s -o %t.o +# RUN: ld.lld %t.o --defsym=aa=0x12345678 --defsym=bb=0x5555aaaa -Ttext=0x10000 \ +# RUN: --defsym=__foo_b=0x10010 -o %t +# RUN: llvm-objdump -s %t | FileCheck --check-prefix=DATA %s +# RUN: llvm-objdump -d --print-imm-hex %t | FileCheck --check-prefix=TEXT %s + +# TEXT-LABEL: <.TEXT>: +# TEXT-TEXT: 00 e0 02 00 bsr {{.*}} <__foo_a> +# TEXT-LABEL: <__foo_a>: +# TEXT-NEXT: 00 e0 00 00 bsr {{.*}} <__foo_a> +# TEXT-NEXT: ff e3 fe ff bsr {{.*}} <__foo_a> +# TEXT-NEXT: 00 e0 02 00 bsr 0x10010 +# TEXT-NEXT: 00 e0 00 00 bsr 0x10010 +# TEXT-NEXT: ff e3 fe ff bsr 0x10010 + +.section .TEXT,"ax",@progbits +# Relocation is not needed, and the offsets are set by llvm-mc. +bsr __foo_a # bsr .+4 +__foo_a: +bsr __foo_a # bsr .+0 +bsr __foo_a # bsr .-4 + +# Relocation is needed. The offsets should be encoded all the same as above, +# if we define '__foo_b' to the address of the second 'bsr __foo_b'. +bsr __foo_b # R_CKCORE_PCREL_IMM26_2 +bsr __foo_b # R_CKCORE_PCREL_IMM26_2 +bsr __foo_b # R_CKCORE_PCREL_IMM26_2 + +# DATA-LABEL: section .DATA: +# DATA-NEXT: {{.*}} 78563412 bbaa5555 99aa5555 +.section .DATA,"wa",@progbits +.long aa # R_CKCORE_ADDR32 +.long bb + 17 # R_CKCORE_ADDR32 +.long bb - 17 # R_CKCORE_ADDR32