sidneym created this revision. sidneym added reviewers: ruiu, shankar.easwaran, kparzysz, bcahoon. sidneym added a project: lld. Herald added subscribers: MaskRay, arichardson, mgorny, emaste. Herald added a reviewer: espindola.
Support B22_PCREL relocation along with a simple test. I'm also working on a llvmSupport patch that will detail the instruction set encoding. Many of Hexagon's instructions have immediates that are peppered throughout the word makeing application of fixups tedious since the same relocation fixup may need to be placed in different bits depending on the instruction. That change will be made in llvmSupport so that both lld and llvm-rtdyld can share encoding information. Repository: rLLD LLVM Linker https://reviews.llvm.org/D47791 Files: ELF/Arch/Hexagon.cpp ELF/CMakeLists.txt ELF/Target.cpp ELF/Target.h test/ELF/Inputs/hexagon.s test/ELF/hexagon.s test/lit.cfg.py
Index: test/lit.cfg.py =================================================================== --- test/lit.cfg.py +++ test/lit.cfg.py @@ -65,6 +65,7 @@ 'AMDGPU': 'amdgpu', 'ARM': 'arm', 'AVR': 'avr', + 'Hexagon': 'hexagon', 'Mips': 'mips', 'PowerPC': 'ppc', 'Sparc': 'sparc', Index: test/ELF/hexagon.s =================================================================== --- /dev/null +++ test/ELF/hexagon.s @@ -0,0 +1,9 @@ +# REQUIRES: hexagon +# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf %s -o %t +# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf %S/Inputs/hexagon.s -o %t2 +# RUN: ld.lld %t2 %t -o %t3 +# RUN: llvm-objdump -d %t3 | FileCheck %s + +# R_HEX_B22_PCREL +call #_start +# CHECK: call 0x11000 Index: test/ELF/Inputs/hexagon.s =================================================================== --- /dev/null +++ test/ELF/Inputs/hexagon.s @@ -0,0 +1,7 @@ + +.global _start +_start: + nop +.global foo +foo: + jumpr lr Index: ELF/Target.h =================================================================== --- ELF/Target.h +++ ELF/Target.h @@ -134,6 +134,7 @@ TargetInfo *getAMDGPUTargetInfo(); TargetInfo *getARMTargetInfo(); TargetInfo *getAVRTargetInfo(); +TargetInfo *getHexagonTargetInfo(); TargetInfo *getPPC64TargetInfo(); TargetInfo *getPPCTargetInfo(); TargetInfo *getSPARCV9TargetInfo(); Index: ELF/Target.cpp =================================================================== --- ELF/Target.cpp +++ ELF/Target.cpp @@ -60,6 +60,8 @@ return getARMTargetInfo(); case EM_AVR: return getAVRTargetInfo(); + case EM_HEXAGON: + return getHexagonTargetInfo(); case EM_MIPS: switch (Config->EKind) { case ELF32LEKind: Index: ELF/CMakeLists.txt =================================================================== --- ELF/CMakeLists.txt +++ ELF/CMakeLists.txt @@ -12,6 +12,7 @@ Arch/AMDGPU.cpp Arch/ARM.cpp Arch/AVR.cpp + Arch/Hexagon.cpp Arch/Mips.cpp Arch/MipsArchTree.cpp Arch/PPC.cpp Index: ELF/Arch/Hexagon.cpp =================================================================== --- /dev/null +++ ELF/Arch/Hexagon.cpp @@ -0,0 +1,87 @@ +//===-- Hexagon.cpp -------------------------------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "InputFiles.h" +#include "Symbols.h" +#include "Target.h" +#include "lld/Common/ErrorHandler.h" +#include "llvm/BinaryFormat/ELF.h" +#include "llvm/Object/ELF.h" +#include "llvm/Support/Endian.h" + +using namespace llvm; +using namespace llvm::object; +using namespace llvm::support::endian; +using namespace llvm::ELF; +using namespace lld; +using namespace lld::elf; + +namespace { +class HexagonReloc final : public TargetInfo { +public: + uint32_t calcEFlags() const override; + uint32_t applyMask(uint32_t Mask, uint32_t Data) const; + RelExpr getRelExpr(RelType Type, const Symbol &S, + const uint8_t *Loc) const override; + void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; +}; +} // namespace + +// Support V60 only at the moment. +uint32_t HexagonReloc::calcEFlags() const { + assert(!ObjectFiles.empty()); + return 0x60; +} + +uint32_t HexagonReloc::applyMask(uint32_t Mask, uint32_t Data) const { + uint32_t Result = 0; + size_t Off = 0; + + for (size_t Bit = 0; Bit != sizeof(uint32_t) * 8; ++Bit) { + const bool ValBit = (Data >> Off) & 1; + const bool MaskBit = (Mask >> Bit) & 1; + if (MaskBit) { + Result |= (ValBit << Bit); + ++Off; + } + } + return Result; +} + +RelExpr HexagonReloc::getRelExpr(RelType Type, const Symbol &S, + const uint8_t *Loc) const { + switch (Type) { + case R_HEX_B22_PCREL: + return R_PC; + default: + return R_ABS; + } +} + +void HexagonReloc::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { + switch (Type) { + case R_HEX_NONE: + break; + case R_HEX_B22_PCREL: { + uint32_t EffectiveValue = (Val >> 2) & 0x3fffff; + EffectiveValue = applyMask(0x01ff3ffe, EffectiveValue); + write32le(Loc, (read32le(Loc) | EffectiveValue)); + break; + } + + default: + error(getErrorLocation(Loc) + "unrecognized reloc " + toString(Type)); + break; + } +} + +TargetInfo *elf::getHexagonTargetInfo() { + static HexagonReloc Target; + return &Target; +}
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits