[llvm] 5cf0082 - [JITLink][COFF][x86_64] Implement SECTION/SECREL relocation.

Sunho Kim via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 10 23:13:44 PDT 2022


Author: Sunho Kim
Date: 2022-08-11T15:12:24+09:00
New Revision: 5cf0082ae3f4b281963e999fcac4b875447f2cda

URL: https://github.com/llvm/llvm-project/commit/5cf0082ae3f4b281963e999fcac4b875447f2cda
DIFF: https://github.com/llvm/llvm-project/commit/5cf0082ae3f4b281963e999fcac4b875447f2cda.diff

LOG: [JITLink][COFF][x86_64] Implement SECTION/SECREL relocation.

Implements SECTION/SECREL relocation. These are used by debug info (pdb) data.

Reviewed By: lhames

Differential Revision: https://reviews.llvm.org/D130275

Added: 
    llvm/test/ExecutionEngine/JITLink/X86/COFF_section_relocs.test

Modified: 
    llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
    llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h
    llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp
    llvm/lib/ExecutionEngine/JITLink/x86_64.cpp
    llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
index dae4ccddfaf5f..e53e3ffa2579a 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
@@ -1102,11 +1102,11 @@ class LinkGraph {
   Symbol &addAbsoluteSymbol(StringRef Name, orc::ExecutorAddr Address,
                             orc::ExecutorAddrDiff Size, Linkage L, Scope S,
                             bool IsLive) {
-    assert(llvm::count_if(AbsoluteSymbols,
-                          [&](const Symbol *Sym) {
-                            return Sym->getName() == Name;
-                          }) == 0 &&
-           "Duplicate absolute symbol");
+    assert(S == Scope::Local || llvm::count_if(AbsoluteSymbols,
+                                               [&](const Symbol *Sym) {
+                                                 return Sym->getName() == Name;
+                                               }) == 0 &&
+                                    "Duplicate absolute symbol");
     auto &Sym = Symbol::constructAbsolute(Allocator.Allocate<Symbol>(),
                                           createAddressable(Address), Name,
                                           Size, L, S, IsLive);

diff  --git a/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h b/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h
index d68dccac3fa98..2de949f21656d 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h
@@ -53,6 +53,17 @@ enum EdgeKind_x86_64 : Edge::Kind {
   ///   the address space, otherwise an out-of-range error will be returned.
   Pointer32Signed,
 
+  /// A plain 16-bit pointer value relocation.
+  ///
+  /// Fixup expression:
+  ///   Fixup <- Target + Addend : uint16
+  ///
+  /// Errors:
+  ///   - The target must reside in the low 16-bits of the address space,
+  ///     otherwise an out-of-range error will be returned.
+  ///
+  Pointer16,
+
   /// A 64-bit delta.
   ///
   /// Delta from the fixup to the target.
@@ -415,6 +426,15 @@ inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E,
     break;
   }
 
+  case Pointer16: {
+    uint64_t Value = E.getTarget().getAddress().getValue() + E.getAddend();
+    if (LLVM_LIKELY(isUInt<16>(Value)))
+      *(ulittle16_t *)FixupPtr = Value;
+    else
+      return makeTargetOutOfRangeError(G, B, E);
+    break;
+  }
+
   case PCRel32:
   case BranchPCRel32:
   case BranchPCRel32ToPtrJumpStub:

diff  --git a/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp
index 1cb756d8024f2..4756cb8a7cbdc 100644
--- a/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp
@@ -30,6 +30,8 @@ enum EdgeKind_coff_x86_64 : Edge::Kind {
   PCRel32 = x86_64::FirstPlatformRelocation,
   Pointer32NB,
   Pointer64,
+  SectionIdx16,
+  SecRel32,
 };
 
 class COFFJITLinker_x86_64 : public JITLinker<COFFJITLinker_x86_64> {
@@ -144,6 +146,25 @@ class COFFLinkGraphBuilder_x86_64 : public COFFLinkGraphBuilder {
       Addend = *reinterpret_cast<const support::little64_t *>(FixupPtr);
       break;
     }
+    case COFF::RelocationTypeAMD64::IMAGE_REL_AMD64_SECTION: {
+      Kind = EdgeKind_coff_x86_64::SectionIdx16;
+      Addend = *reinterpret_cast<const support::little16_t *>(FixupPtr);
+      uint64_t SectionIdx = 0;
+      if (COFFSymbol.isAbsolute())
+        SectionIdx = getObject().getNumberOfSections() + 1;
+      else
+        SectionIdx = COFFSymbol.getSectionNumber();
+      auto *AbsSym = &getGraph().addAbsoluteSymbol(
+          "secidx", orc::ExecutorAddr(SectionIdx), 2, Linkage::Strong,
+          Scope::Local, false);
+      GraphSymbol = AbsSym;
+      break;
+    }
+    case COFF::RelocationTypeAMD64::IMAGE_REL_AMD64_SECREL: {
+      Kind = EdgeKind_coff_x86_64::SecRel32;
+      Addend = *reinterpret_cast<const support::little32_t *>(FixupPtr);
+      break;
+    }
     default: {
       return make_error<JITLinkError>("Unsupported x86_64 relocation:" +
                                       formatv("{0:d}", Rel.getType()));
@@ -192,6 +213,17 @@ class COFFLinkGraphLowering_x86_64 {
           E.setKind(x86_64::Pointer64);
           break;
         }
+        case EdgeKind_coff_x86_64::SectionIdx16: {
+          E.setKind(x86_64::Pointer16);
+          break;
+        }
+        case EdgeKind_coff_x86_64::SecRel32: {
+          E.setAddend(E.getAddend() -
+                      getSectionStart(E.getTarget().getBlock().getSection())
+                          .getValue());
+          E.setKind(x86_64::Pointer32);
+          break;
+        }
         default:
           break;
         }
@@ -202,6 +234,15 @@ class COFFLinkGraphLowering_x86_64 {
 
 private:
   static StringRef getImageBaseSymbolName() { return "__ImageBase"; }
+
+  orc::ExecutorAddr getSectionStart(Section &Sec) {
+    if (!SectionStartCache.count(&Sec)) {
+      SectionRange Range(Sec);
+      SectionStartCache[&Sec] = Range.getStart();
+    }
+    return SectionStartCache[&Sec];
+  }
+
   Expected<JITTargetAddress> getImageBaseAddress(LinkGraph &G,
                                                  JITLinkContext &Ctx) {
     if (this->ImageBase)
@@ -231,6 +272,8 @@ class COFFLinkGraphLowering_x86_64 {
     this->ImageBase = ImageBase;
     return ImageBase;
   }
+
+  DenseMap<Section *, orc::ExecutorAddr> SectionStartCache;
   JITTargetAddress ImageBase = 0;
 };
 
@@ -257,6 +300,10 @@ const char *getCOFFX86RelocationKindName(Edge::Kind R) {
     return "Pointer32NB";
   case Pointer64:
     return "Pointer64";
+  case SectionIdx16:
+    return "SectionIdx16";
+  case SecRel32:
+    return "SecRel32";
   default:
     return x86_64::getEdgeKindName(R);
   }

diff  --git a/llvm/lib/ExecutionEngine/JITLink/x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/x86_64.cpp
index 393250a5578b7..097e19e02530e 100644
--- a/llvm/lib/ExecutionEngine/JITLink/x86_64.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/x86_64.cpp
@@ -26,6 +26,8 @@ const char *getEdgeKindName(Edge::Kind K) {
     return "Pointer32";
   case Pointer32Signed:
     return "Pointer32Signed";
+  case Pointer16:
+    return "Pointer16";
   case Delta64:
     return "Delta64";
   case Delta32:

diff  --git a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
index 5ddb35cbafd5b..070118c1f8915 100644
--- a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp
@@ -537,7 +537,8 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
     for (auto *B : G.blocks()) {
       auto &BI = BlockInfos[B];
       for (auto &E : B->edges()) {
-        if (E.getTarget().getScope() == Scope::Local) {
+        if (E.getTarget().getScope() == Scope::Local &&
+            !E.getTarget().isAbsolute()) {
           auto &TgtB = E.getTarget().getBlock();
           if (&TgtB != B) {
             BI.Dependencies.insert(&TgtB);

diff  --git a/llvm/test/ExecutionEngine/JITLink/X86/COFF_section_relocs.test b/llvm/test/ExecutionEngine/JITLink/X86/COFF_section_relocs.test
new file mode 100644
index 0000000000000..739dbf7b15384
--- /dev/null
+++ b/llvm/test/ExecutionEngine/JITLink/X86/COFF_section_relocs.test
@@ -0,0 +1,89 @@
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-jitlink -noexec -abs __ImageBase=0xfff00000 \
+# RUN: -slab-allocate 100Kb -slab-address 0xfff00000 -slab-page-size 4096 \
+# RUN: -check %s %t 
+# 
+# Check IMAGE_REL_AMD64_SECTION and IMAGE_REL_AMD64_SECREL relocations
+# are working correctly.
+#
+# jitlink-check: *{2}(sect) = 2
+# jitlink-check: *{4}(sect+2) = 4
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       16
+    SectionData:     '0000000000000000'
+  - Name:            .func
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       16
+    SectionData:     '0000000000000000'
+  - Name:            .sect
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     '0000000000000000'
+    Relocations:
+      - VirtualAddress:  0
+        SymbolTableIndex: 7
+        Type:            IMAGE_REL_AMD64_SECTION
+      - VirtualAddress:  2
+        SymbolTableIndex: 7
+        Type:            IMAGE_REL_AMD64_SECREL
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          8
+      NumberOfRelocations: 0
+      CheckSum:            0
+      NumberOfLinenumbers: 0
+      Number:          1
+  - Name:            .func
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          8
+      NumberOfRelocations: 0
+      CheckSum:            0
+      NumberOfLinenumbers: 0
+      Number:          2
+  - Name:            .pdata
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          8
+      NumberOfRelocations: 1
+      CheckSum:            0
+      NumberOfLinenumbers: 0
+      Number:          3
+  - Name:            main
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            func
+    Value:           4
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            sect
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL


        


More information about the llvm-commits mailing list