Index: llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h =================================================================== --- llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h +++ llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h @@ -108,6 +108,18 @@ /// symbol was not been defined. Delta64FromGOT, + /// A 16-bit constant data. + /// + /// Sets a 16-bit constant inside addend + /// + /// Fixup expression: + /// Fixup <- Adeend : uint16 + /// + /// Errors: + /// - If addend does not fit into uint16, an out-of-range error will be + /// returned. + Const16, + /// A 32-bit PC-relative branch. /// /// Represents a PC-relative call or branch to a target. This can be used to @@ -467,6 +479,14 @@ *(little64_t *)FixupPtr = Value; break; } + case Const16: { + int64_t Value = E.getAddend(); + if (LLVM_LIKELY(isUInt<16>(Value))) + *(ulittle16_t *)FixupPtr = Value; + else + return makeTargetOutOfRangeError(G, B, E); + break; + } default: return make_error( Index: llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp =================================================================== --- llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp +++ llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp @@ -30,6 +30,8 @@ PCRel32 = x86_64::FirstPlatformRelocation, Pointer32NB, Pointer64, + SectionIdx16, + SecRel32, }; class COFFJITLinker_x86_64 : public JITLinker { @@ -120,6 +122,20 @@ Addend = *reinterpret_cast(FixupPtr); break; } + case COFF::RelocationTypeAMD64::IMAGE_REL_AMD64_SECTION: { + Kind = EdgeKind_coff_x86_64::SectionIdx16; + Addend = *reinterpret_cast(FixupPtr); + if (COFFSymbol.isAbsolute()) + Addend += getObject().getNumberOfSections() + 1; + else + Addend += COFFSymbol.getSectionNumber(); + break; + } + case COFF::RelocationTypeAMD64::IMAGE_REL_AMD64_SECREL: { + Kind = EdgeKind_coff_x86_64::SecRel32; + Addend = *reinterpret_cast(FixupPtr); + break; + } default: { return make_error("Unsupported x86_64 relocation:" + formatv("{0:d}", Rel.getType())); @@ -168,6 +184,17 @@ E.setKind(x86_64::Pointer64); break; } + case EdgeKind_coff_x86_64::SectionIdx16: { + E.setKind(x86_64::Const16); + 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; } @@ -178,6 +205,15 @@ 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 getImageBaseAddress(LinkGraph &G, JITLinkContext &Ctx) { if (this->ImageBase) @@ -207,6 +243,8 @@ this->ImageBase = ImageBase; return ImageBase; } + + DenseMap
SectionStartCache; JITTargetAddress ImageBase = 0; }; @@ -233,6 +271,10 @@ return "Pointer32NB"; case Pointer64: return "Pointer64"; + case SectionIdx16: + return "SectionIdx16"; + case SecRel32: + return "SecRel32"; default: return x86_64::getEdgeKindName(R); } Index: llvm/lib/ExecutionEngine/JITLink/x86_64.cpp =================================================================== --- llvm/lib/ExecutionEngine/JITLink/x86_64.cpp +++ llvm/lib/ExecutionEngine/JITLink/x86_64.cpp @@ -36,6 +36,8 @@ return "NegDelta32"; case Delta64FromGOT: return "Delta64FromGOT"; + case Const16: + return "Const16"; case PCRel32: return "PCRel32"; case BranchPCRel32: Index: llvm/test/ExecutionEngine/JITLink/X86/COFF_section_relocs.test =================================================================== --- /dev/null +++ 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