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

Reply via email to