diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h @@ -36,9 +36,22 @@ protected: RuntimeDyldCOFF(RuntimeDyld::MemoryManager &MemMgr, - JITSymbolResolver &Resolver) - : RuntimeDyldImpl(MemMgr, Resolver) {} + JITSymbolResolver &Resolver, unsigned PointerSize, + uint32_t PointerReloc) + : RuntimeDyldImpl(MemMgr, Resolver), PointerSize(PointerSize), + PointerReloc(PointerReloc) { + assert((PointerSize == 4 || PointerSize == 8) && "Unexpected pointer size"); + } + uint64_t getSymbolOffset(const SymbolRef &Sym); + uint64_t getDLLImportOffset(unsigned SectionID, StubMap &Stubs, + StringRef Name, bool SetSectionIDMinus1 = false); + + static constexpr StringRef getImportSymbolPrefix() { return "__imp_"; } + +private: + unsigned PointerSize; + uint32_t PointerReloc; }; } // end namespace llvm diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Triple.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/Support/FormatVariadic.h" using namespace llvm; using namespace llvm::object; @@ -78,6 +79,41 @@ return Sym.getValue(); } +uint64_t RuntimeDyldCOFF::getDLLImportOffset(unsigned SectionID, StubMap &Stubs, + StringRef Name, + bool SetSectionIDMinus1) { + LLVM_DEBUG(dbgs() << "Getting DLLImport entry for " << Name << "... "); + assert(Name.startswith(getImportSymbolPrefix()) && "Not a DLLImport symbol?"); + RelocationValueRef Reloc; + Reloc.SymbolName = Name.data(); + auto I = Stubs.find(Reloc); + if (I != Stubs.end()) { + LLVM_DEBUG(dbgs() << format("{0:x8}", I->second) << "\n"); + return I->second; + } + + assert(SectionID < Sections.size() && "SectionID out of range"); + auto &Sec = Sections[SectionID]; + auto EntryOffset = alignTo(Sec.getStubOffset(), PointerSize); + Sec.advanceStubOffset(EntryOffset + PointerSize - Sec.getStubOffset()); + Stubs[Reloc] = EntryOffset; + + RelocationEntry RE(SectionID, EntryOffset, PointerReloc, 0, false, + Log2_64(PointerSize)); + // Hack to tell I386/Thumb resolveRelocation that this isn't section relative. + if (SetSectionIDMinus1) + RE.Sections.SectionA = -1; + addRelocationForSymbol(RE, Name.drop_front(getImportSymbolPrefix().size())); + + LLVM_DEBUG({ + dbgs() << "Creating entry at " + << formatv("{0:x16} + {1:x8} ( {2:x16} )", Sec.getLoadAddress(), + EntryOffset, Sec.getLoadAddress() + EntryOffset) + << "\n"; + }); + return EntryOffset; +} + bool RuntimeDyldCOFF::isCompatibleFile(const object::ObjectFile &Obj) const { return Obj.isCOFF(); } diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -191,13 +191,11 @@ class RelocationValueRef { public: - unsigned SectionID; - uint64_t Offset; - int64_t Addend; - const char *SymbolName; + unsigned SectionID = 0; + uint64_t Offset = 0; + int64_t Addend = 0; + const char *SymbolName = nullptr; bool IsStubThumb = false; - RelocationValueRef() : SectionID(0), Offset(0), Addend(0), - SymbolName(nullptr) {} inline bool operator==(const RelocationValueRef &Other) const { return SectionID == Other.SectionID && Offset == Other.Offset && diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFAArch64.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFAArch64.h --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFAArch64.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFAArch64.h @@ -89,7 +89,8 @@ public: RuntimeDyldCOFFAArch64(RuntimeDyld::MemoryManager &MM, JITSymbolResolver &Resolver) - : RuntimeDyldCOFF(MM, Resolver), ImageBase(0) {} + : RuntimeDyldCOFF(MM, Resolver, 8, COFF::IMAGE_REL_ARM64_ADDR64), + ImageBase(0) {} unsigned getStubAlignment() override { return 8; } @@ -161,7 +162,7 @@ uint64_t Offset = RelI->getOffset(); // If there is no section, this must be an external reference. - const bool IsExtern = Section == Obj.section_end(); + bool IsExtern = Section == Obj.section_end(); // Determine the Addend used to adjust the relocation value. uint64_t Addend = 0; @@ -169,6 +170,24 @@ uintptr_t ObjTarget = AddendSection.getObjAddress() + Offset; uint8_t *Displacement = (uint8_t *)ObjTarget; + unsigned TargetSectionID = -1; + uint64_t TargetOffset = -1; + + if (TargetName.startswith(getImportSymbolPrefix())) { + TargetSectionID = SectionID; + TargetOffset = getDLLImportOffset(SectionID, Stubs, TargetName); + TargetName = StringRef(); + IsExtern = false; + } else if (!IsExtern) { + if (auto TargetSectionIDOrErr = findOrEmitSection( + Obj, *Section, Section->isText(), ObjSectionToID)) + TargetSectionID = *TargetSectionIDOrErr; + else + return TargetSectionIDOrErr.takeError(); + + TargetOffset = getSymbolOffset(*Symbol); + } + switch (RelType) { case COFF::IMAGE_REL_ARM64_ADDR32: case COFF::IMAGE_REL_ARM64_ADDR32NB: @@ -224,18 +243,10 @@ << TargetName << " Addend " << Addend << "\n"); #endif - unsigned TargetSectionID = -1; if (IsExtern) { RelocationEntry RE(SectionID, Offset, RelType, Addend); addRelocationForSymbol(RE, TargetName); } else { - if (auto TargetSectionIDOrErr = findOrEmitSection( - Obj, *Section, Section->isText(), ObjSectionToID)) { - TargetSectionID = *TargetSectionIDOrErr; - } else - return TargetSectionIDOrErr.takeError(); - - uint64_t TargetOffset = getSymbolOffset(*Symbol); RelocationEntry RE(SectionID, Offset, RelType, TargetOffset + Addend); addRelocationForSection(RE, TargetSectionID); } diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h @@ -25,7 +25,7 @@ public: RuntimeDyldCOFFI386(RuntimeDyld::MemoryManager &MM, JITSymbolResolver &Resolver) - : RuntimeDyldCOFF(MM, Resolver) {} + : RuntimeDyldCOFF(MM, Resolver, 4, COFF::IMAGE_REL_I386_DIR32) {} unsigned getMaxStubSize() const override { return 8; // 2-byte jmp instruction + 32-bit relative address + 2 byte pad @@ -53,10 +53,28 @@ if (!SectionOrErr) return SectionOrErr.takeError(); auto Section = *SectionOrErr; + bool IsExtern = Section == Obj.section_end(); uint64_t RelType = RelI->getType(); uint64_t Offset = RelI->getOffset(); + unsigned TargetSectionID = -1; + uint64_t TargetOffset = -1; + if (TargetName.startswith(getImportSymbolPrefix())) { + TargetSectionID = SectionID; + TargetOffset = getDLLImportOffset(SectionID, Stubs, TargetName, true); + TargetName = StringRef(); + IsExtern = false; + } else if (!IsExtern) { + if (auto TargetSectionIDOrErr = findOrEmitSection( + Obj, *Section, Section->isText(), ObjSectionToID)) + TargetSectionID = *TargetSectionIDOrErr; + else + return TargetSectionIDOrErr.takeError(); + if (RelType != COFF::IMAGE_REL_I386_SECTION) + TargetOffset = getSymbolOffset(*Symbol); + } + // Determine the Addend used to adjust the relocation value. uint64_t Addend = 0; SectionEntry &AddendSection = Sections[SectionID]; @@ -83,16 +101,10 @@ << " RelType: " << RelTypeName << " TargetName: " << TargetName << " Addend " << Addend << "\n"); - unsigned TargetSectionID = -1; - if (Section == Obj.section_end()) { + if (IsExtern) { RelocationEntry RE(SectionID, Offset, RelType, 0, -1, 0, 0, 0, false, 0); addRelocationForSymbol(RE, TargetName); } else { - if (auto TargetSectionIDOrErr = - findOrEmitSection(Obj, *Section, Section->isText(), ObjSectionToID)) - TargetSectionID = *TargetSectionIDOrErr; - else - return TargetSectionIDOrErr.takeError(); switch (RelType) { case COFF::IMAGE_REL_I386_ABSOLUTE: @@ -103,7 +115,7 @@ case COFF::IMAGE_REL_I386_REL32: { RelocationEntry RE = RelocationEntry(SectionID, Offset, RelType, Addend, TargetSectionID, - getSymbolOffset(*Symbol), 0, 0, false, 0); + TargetOffset, 0, 0, false, 0); addRelocationForSection(RE, TargetSectionID); break; } @@ -114,15 +126,14 @@ break; } case COFF::IMAGE_REL_I386_SECREL: { - RelocationEntry RE = RelocationEntry(SectionID, Offset, RelType, - getSymbolOffset(*Symbol) + Addend); + RelocationEntry RE = + RelocationEntry(SectionID, Offset, RelType, TargetOffset + Addend); addRelocationForSection(RE, TargetSectionID); break; } default: llvm_unreachable("unsupported relocation type"); } - } return ++RelI; diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h @@ -48,7 +48,7 @@ public: RuntimeDyldCOFFThumb(RuntimeDyld::MemoryManager &MM, JITSymbolResolver &Resolver) - : RuntimeDyldCOFF(MM, Resolver) {} + : RuntimeDyldCOFF(MM, Resolver, 4, COFF::IMAGE_REL_ARM_ADDR32) {} unsigned getMaxStubSize() const override { return 16; // 8-byte load instructions, 4-byte jump, 4-byte padding @@ -103,16 +103,29 @@ << " RelType: " << RelTypeName << " TargetName: " << TargetName << " Addend " << Addend << "\n"); + bool IsExtern = Section == Obj.section_end(); unsigned TargetSectionID = -1; - if (Section == Obj.section_end()) { - RelocationEntry RE(SectionID, Offset, RelType, 0, -1, 0, 0, 0, false, 0); - addRelocationForSymbol(RE, TargetName); - } else { + uint64_t TargetOffset = -1; + + if (TargetName.startswith(getImportSymbolPrefix())) { + TargetSectionID = SectionID; + TargetOffset = getDLLImportOffset(SectionID, Stubs, TargetName, true); + TargetName = StringRef(); + IsExtern = false; + } else if (!IsExtern) { if (auto TargetSectionIDOrErr = findOrEmitSection(Obj, *Section, Section->isText(), ObjSectionToID)) TargetSectionID = *TargetSectionIDOrErr; else return TargetSectionIDOrErr.takeError(); + if (RelType != COFF::IMAGE_REL_ARM_SECTION) + TargetOffset = getSymbolOffset(*Symbol); + } + + if (IsExtern) { + RelocationEntry RE(SectionID, Offset, RelType, 0, -1, 0, 0, 0, false, 0); + addRelocationForSymbol(RE, TargetName); + } else { // We need to find out if the relocation is relative to a thumb function // so that we include the ISA selection bit when resolve the relocation @@ -124,16 +137,16 @@ // This relocation is ignored. break; case COFF::IMAGE_REL_ARM_ADDR32: { - RelocationEntry RE = RelocationEntry( - SectionID, Offset, RelType, Addend, TargetSectionID, - getSymbolOffset(*Symbol), 0, 0, false, 0, IsTargetThumbFunc); + RelocationEntry RE = + RelocationEntry(SectionID, Offset, RelType, Addend, TargetSectionID, + TargetOffset, 0, 0, false, 0, IsTargetThumbFunc); addRelocationForSection(RE, TargetSectionID); break; } case COFF::IMAGE_REL_ARM_ADDR32NB: { RelocationEntry RE = RelocationEntry(SectionID, Offset, RelType, Addend, TargetSectionID, - getSymbolOffset(*Symbol), 0, 0, false, 0); + TargetOffset, 0, 0, false, 0); addRelocationForSection(RE, TargetSectionID); break; } @@ -144,24 +157,23 @@ break; } case COFF::IMAGE_REL_ARM_SECREL: { - RelocationEntry RE = RelocationEntry(SectionID, Offset, RelType, - getSymbolOffset(*Symbol) + Addend); + RelocationEntry RE = + RelocationEntry(SectionID, Offset, RelType, TargetOffset + Addend); addRelocationForSection(RE, TargetSectionID); break; } case COFF::IMAGE_REL_ARM_MOV32T: { - RelocationEntry RE = RelocationEntry( - SectionID, Offset, RelType, Addend, TargetSectionID, - getSymbolOffset(*Symbol), 0, 0, false, 0, IsTargetThumbFunc); + RelocationEntry RE = + RelocationEntry(SectionID, Offset, RelType, Addend, TargetSectionID, + TargetOffset, 0, 0, false, 0, IsTargetThumbFunc); addRelocationForSection(RE, TargetSectionID); break; } case COFF::IMAGE_REL_ARM_BRANCH20T: case COFF::IMAGE_REL_ARM_BRANCH24T: case COFF::IMAGE_REL_ARM_BLX23T: { - RelocationEntry RE = - RelocationEntry(SectionID, Offset, RelType, - getSymbolOffset(*Symbol) + Addend, true, 0); + RelocationEntry RE = RelocationEntry(SectionID, Offset, RelType, + TargetOffset + Addend, true, 0); addRelocationForSection(RE, TargetSectionID); break; } @@ -256,7 +268,6 @@ EncodeImmediate(&Target[0], (static_cast(Result) >> 00) | ISASelectionBit); EncodeImmediate(&Target[4], static_cast(Result) >> 16); - break; } case COFF::IMAGE_REL_ARM_BRANCH20T: { diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h @@ -56,7 +56,8 @@ public: RuntimeDyldCOFFX86_64(RuntimeDyld::MemoryManager &MM, JITSymbolResolver &Resolver) - : RuntimeDyldCOFF(MM, Resolver), ImageBase(0) {} + : RuntimeDyldCOFF(MM, Resolver, 8, COFF::IMAGE_REL_AMD64_ADDR64), + ImageBase(0) {} unsigned getStubAlignment() override { return 1; } @@ -202,7 +203,7 @@ return SectionOrError.takeError(); object::section_iterator SecI = *SectionOrError; // If there is no section, this must be an external reference. - const bool IsExtern = SecI == Obj.section_end(); + bool IsExtern = SecI == Obj.section_end(); // Determine the Addend used to adjust the relocation value. uint64_t RelType = RelI->getType(); @@ -214,7 +215,25 @@ Expected TargetNameOrErr = Symbol->getName(); if (!TargetNameOrErr) return TargetNameOrErr.takeError(); + StringRef TargetName = *TargetNameOrErr; + unsigned TargetSectionID = 0; + uint64_t TargetOffset = 0; + + if (TargetName.startswith(getImportSymbolPrefix())) { + assert(IsExtern && "DLLImport not marked extern?"); + TargetSectionID = SectionID; + TargetOffset = getDLLImportOffset(SectionID, Stubs, TargetName); + TargetName = StringRef(); + IsExtern = false; + } else if (!IsExtern) { + if (auto TargetSectionIDOrErr = + findOrEmitSection(Obj, *SecI, SecI->isText(), ObjSectionToID)) + TargetSectionID = *TargetSectionIDOrErr; + else + return TargetSectionIDOrErr.takeError(); + TargetOffset = getSymbolOffset(*Symbol); + } switch (RelType) { @@ -253,14 +272,6 @@ RelocationEntry RE(SectionID, Offset, RelType, Addend); addRelocationForSymbol(RE, TargetName); } else { - bool IsCode = SecI->isText(); - unsigned TargetSectionID; - if (auto TargetSectionIDOrErr = - findOrEmitSection(Obj, *SecI, IsCode, ObjSectionToID)) - TargetSectionID = *TargetSectionIDOrErr; - else - return TargetSectionIDOrErr.takeError(); - uint64_t TargetOffset = getSymbolOffset(*Symbol); RelocationEntry RE(SectionID, Offset, RelType, TargetOffset + Addend); addRelocationForSection(RE, TargetSectionID); } diff --git a/llvm/test/ExecutionEngine/RuntimeDyld/ARM/COFF_Thumb.s b/llvm/test/ExecutionEngine/RuntimeDyld/ARM/COFF_Thumb.s --- a/llvm/test/ExecutionEngine/RuntimeDyld/ARM/COFF_Thumb.s +++ b/llvm/test/ExecutionEngine/RuntimeDyld/ARM/COFF_Thumb.s @@ -1,5 +1,8 @@ -// RUN: llvm-mc -triple thumbv7-windows-itanium -filetype obj -o %t.obj %s -// RUN: llvm-rtdyld -triple thumbv7-windows -dummy-extern OutputDebugStringW=0x01310061 -dummy-extern OutputDebugStringA=0x78563413 -dummy-extern ExitProcess=0x54769891 -dummy-extern unnamed_addr=0x00001024 -verify -check %s %t.obj +# RUN: rm -rf %t && mkdir -p %t +# RUN: llvm-mc -triple thumbv7-windows-itanium -filetype obj -o %t/COFF_Thumb.o %s +# RUN: llvm-rtdyld -triple thumbv7-windows \ +# RUN: -dummy-extern ExitProcess=0x54769891 \ +# RUN: -dummy-extern unnamed_addr=0x00001024 -verify -check %s %t/COFF_Thumb.o .text .syntax unified @@ -33,23 +36,26 @@ function: push.w {r11, lr} mov r11, sp -rel2: @ IMAGE_REL_ARM_MOV32T - movw r0, :lower16:__imp_OutputDebugStringA -# rtdyld-check: decode_operand(rel2, 1) = (__imp_OutputDebugStringA&0x0000ffff) - movt r0, :upper16:__imp_OutputDebugStringA -# TODO rtdyld-check: decode_operand(rel2, 1) = (__imp_OutputDebugStringA&0xffff0000>>16) - ldr r1, [r0] rel3: @ IMAGE_REL_ARM_MOV32T movw r0, :lower16:string # rtdyld-check: decode_operand(rel3, 1) = (string&0x0000ffff) movt r0, :upper16:string # TODO rtdyld-check: decode_operand(rel3, 1) = (string&0xffff0000>>16) blx r1 -rel4: @ IMAGE_REL_ARM_MOV32T +load_from_dllimport_lo: @ IMAGE_REL_ARM_MOV32T movw r0, :lower16:__imp_ExitProcess -# rtdyld-check: decode_operand(rel4, 1) = (__imp_ExitProcess&0x0000ffff) +# (1) Check stub content. +# rtdyld-check: *{4}(stub_addr(COFF_Thumb.o/.text, __imp_ExitProcess)) = \ +# rtdyld-check: ExitProcess +# +# (2) Check lo bits of stub address. +# rtdyld-check: decode_operand(load_from_dllimport_lo, 1) = \ +# rtdyld-check: stub_addr(COFF_Thumb.o/.text, __imp_ExitProcess)[15:0] +load_from_dllimport_hi: movt r0, :upper16:__imp_ExitProcess -# TODO rtdyld-check: decode_operand(rel4, 1) = (__imp_ExitProcess&0xffff0000>>16) +# (3) Check hi bits of stub address. +# rtdyld-check: decode_operand(load_from_dllimport_hi, 2) = \ +# rtdyld-check: stub_addr(COFF_Thumb.o/.text, __imp_ExitProcess)[31:16] ldr r1, [r0] movs r0, #0 pop.w {r11, lr} @@ -78,49 +84,26 @@ .data - .p2align 2 -__imp_OutputDebugStringA: -@ rel6: - .long OutputDebugStringA @ IMAGE_REL_ARM_ADDR32 -# rtdyld-check: *{4}__imp_OutputDebugStringA = 0x78563413 - - .p2align 2 -__imp_ExitProcess: -@ rel7: - .long ExitProcess @ IMAGE_REL_ARM_ADDR32 -# rtdyld-check: *{4}__imp_ExitProcess = 0x54769891 - .global relocations relocations: @ rel8: .long function(imgrel) @ IMAGE_REL_ARM_ADDR32NB -# rtdyld-check: *{4}relocations = function - section_addr(COFF_Thumb.s.tmp.obj, .text) +# rtdyld-check: *{4}relocations = function - section_addr(COFF_Thumb.o, .text) rel9: - .secidx __imp_OutputDebugStringA @ IMAGE_REL_ARM_SECTION -# rtdyld-check: *{2}rel9 = 1 + .secidx __imp_ExitProcess @ IMAGE_REL_ARM_SECTION +# rtdyld-check: *{2}rel9 = 2 rel10: .long relocations(secrel32) @ IMAGE_REL_ARM_SECREL -# rtdyld-check: *{4}rel10 = relocations - section_addr(COFF_Thumb.s.tmp.obj, .data) +# rtdyld-check: *{4}rel10 = relocations - section_addr(COFF_Thumb.o, .data) rel11: .secrel32 relocations @ IMAGE_REL_ARM_SECREL -# rtdyld-check: *{4}rel11 = relocations - section_addr(COFF_Thumb.s.tmp.obj, .data) -rel12: @ IMAGE_REL_ARM_MOV32T - movw r0, :lower16:__imp_OutputDebugStringW -# rtdyld-check: decode_operand(rel12, 1) = (__imp_OutputDebugStringW&0x0000ffff) - movt r0, :upper16:__imp_OutputDebugStringW -# TODO rtdyld-check: decode_operand(rel12, 1) = (__imp_OutputDebugStringW&0xffff0000>>16) +# rtdyld-check: *{4}rel11 = relocations - section_addr(COFF_Thumb.o, .data) bx r0 trap .data .p2align 2 -__imp_OutputDebugStringW: -@ rel13: - .long OutputDebugStringW @ IMAGE_REL_ARM_ADDR32 -# rtdyld-check: *{4}__imp_OutputDebugStringW = 0x01310061 - - .p2align 2 branch_to_thumb_func: @ rel14: @ IMAGE_REL_ARM_MOV32T diff --git a/llvm/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s b/llvm/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s --- a/llvm/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s +++ b/llvm/test/ExecutionEngine/RuntimeDyld/X86/COFF_i386.s @@ -1,5 +1,8 @@ -// RUN: llvm-mc -triple i686-windows -filetype obj -o %t.obj %s -// RUN: llvm-rtdyld -triple i686-windows -dummy-extern _printf=0x7ffffffd -dummy-extern _OutputDebugStringA@4=0x7ffffffe -dummy-extern _ExitProcess@4=0x7fffffff -verify -check=%s %t.obj +// RUN: rm -rf %t && mkdir -p %t +// RUN: llvm-mc -triple i686-windows -filetype obj -o %t/COFF_i386.o %s +// RUN: llvm-rtdyld -triple i686-windows -dummy-extern _printf=0x7ffffffd \ +// RUN: -dummy-extern _ExitProcess=0x7fffffff \ +// RUN: -verify -check=%s %t/COFF_i386.o .text @@ -24,41 +27,25 @@ _function: rel2: pushl string +# rtdyld-check: decode_operand(rel3, 3) = \ +# rtdyld-check: stub_addr(COFF_i386.o/.text, __imp__ExitProcess) +# rtdyld-check: *{4}(stub_addr(COFF_i386.o/.text, __imp__ExitProcess)) = \ +# rtdyld-check: _ExitProcess rel3: - calll *__imp__OutputDebugStringA // IMAGE_REL_I386_DIR32 -# rtdyld-check: decode_operand(rel3, 3) = __imp__OutputDebugStringA - addl $4, %esp - pushl $0 -rel4: - calll *__imp__ExitProcess // IMAGE_REL_I386_DIR32 -# rtdyld-check: decode_operand(rel4, 3) = __imp__ExitProcess - addl $4, %esp - retl + calll *__imp__ExitProcess // IMAGE_REL_I386_DIR32 .data - .global __imp__OutputDebugStringA - .align 4 -__imp__OutputDebugStringA: - .long "_OutputDebugStringA@4" // IMAGE_REL_I386_DIR32 -# rtdyld-check: *{4}__imp__OutputDebugStringA = 0x7ffffffe - - .global __imp__ExitProcess - .align 4 -__imp__ExitProcess: - .long "_ExitProcess@4" // IMAGE_REL_I386_DIR32 -# rtdyld-check: *{4}__imp__ExitProcess = 0x7fffffff - .global relocations relocations: rel5: .long _function@imgrel // IMAGE_REL_I386_DIR32NB -# rtdyld-check: *{4}rel5 = _function - section_addr(COFF_i386.s.tmp.obj, .text) +# rtdyld-check: *{4}rel5 = _function - section_addr(COFF_i386.o, .text) rel6: # rtdyld-check: *{2}rel6 = 1 - .secidx __imp__OutputDebugStringA // IMAGE_REL_I386_SECTION + .secidx rel5 // IMAGE_REL_I386_SECTION rel7: -# rtdyld-check: *{4}rel7 = string - section_addr(COFF_i386.s.tmp.obj, .data) +# rtdyld-check: *{4}rel7 = string - section_addr(COFF_i386.o, .data) .secrel32 string // IMAGE_REL_I386_SECREL # Test that addends work. @@ -69,10 +56,10 @@ # rtdyld-check: *{4}rel9 = string+1 .long string+1 // IMAGE_REL_I386_DIR32 rel10: -# rtdyld-check: *{4}rel10 = string - section_addr(COFF_i386.s.tmp.obj, .text) + 1 +# rtdyld-check: *{4}rel10 = string - section_addr(COFF_i386.o, .text) + 1 .long string@imgrel+1 // IMAGE_REL_I386_DIR32NB rel11: -# rtdyld-check: *{4}rel11 = string - section_addr(COFF_i386.s.tmp.obj, .data) + 1 +# rtdyld-check: *{4}rel11 = string - section_addr(COFF_i386.o, .data) + 1 .long string@SECREL32+1 // IMAGE_REL_I386_SECREL # We explicitly add padding to put string outside of the 16bit address space diff --git a/llvm/test/ExecutionEngine/RuntimeDyld/X86/COFF_x86_64.s b/llvm/test/ExecutionEngine/RuntimeDyld/X86/COFF_x86_64.s --- a/llvm/test/ExecutionEngine/RuntimeDyld/X86/COFF_x86_64.s +++ b/llvm/test/ExecutionEngine/RuntimeDyld/X86/COFF_x86_64.s @@ -1,7 +1,10 @@ # RUN: rm -rf %t && mkdir -p %t # RUN: llvm-mc -triple=x86_64-pc-win32 -filetype=obj -o %t/COFF_x86_64.o %s -# RUN: llvm-rtdyld -triple=x86_64-pc-win32 -verify -check=%s %t/COFF_x86_64.o - .text +# RUN: llvm-rtdyld -triple=x86_64-pc-win32 -dummy-extern external_func=0x1 \ +# RUN: -dummy-extern external_data=0x2 -verify -check=%s %t/COFF_x86_64.o + + + .text .def F; .scl 2; .type 32; @@ -29,6 +32,36 @@ .Ltmp2: .seh_endproc + .globl call_to_dllimport + .p2align 4, 0x90 +# Check calls to dllimports. +# +# (1) Check that callq argument points to synthesized stub addr. +# rtdyld-check: decode_operand(call_to_dllimport, 3) = \ +# rtdyld-check: stub_addr(COFF_x86_64.o/.text, __imp_external_func) - \ +# rtdyld-check: next_pc(call_to_dllimport) +# +# (2) Check that synthesized stub entry points to call target. +# rtdyld-check: *{8}(stub_addr(COFF_x86_64.o/.text, __imp_external_func)) = \ +# rtdyld-check: external_func +call_to_dllimport: + callq *__imp_external_func(%rip) + + .globl load_from_dllimport + .p2align 4, 0x90 +# Check loads from dllimports. +# +# (1) Check that the movq argument points to synthesized stub addr. +# rtdyld-check: decode_operand(load_from_dllimport, 4) = \ +# rtdyld-check: stub_addr(COFF_x86_64.o/.text, __imp_external_data) - \ +# rtdyld-check: next_pc(load_from_dllimport) +# +# (2) Check that synthesized stub entry points to datao target. +# rtdyld-check: *{8}(stub_addr(COFF_x86_64.o/.text, __imp_external_data)) = \ +# rtdyld-check: external_data +load_from_dllimport: + movq __imp_external_data(%rip), %rax + .data .globl x # @x # rtdyld-check: *{8}x = F