forked from OSchip/llvm-project
[RuntimeDyld][COFF] Build stubs for COFF dllimport symbols.
Summary: Enables JIT-linking by RuntimeDyld of COFF objects that contain references to dllimport symbols. This is done by recognizing symbols that start with the reserved "__imp_" prefix and building a pointer entry to the target symbol in the stubs area of the section. References to the "__imp_" symbol are updated to point to this pointer. Work in progress: The generic code is in place, but only RuntimeDyldCOFFX86_64 and RuntimeDyldCOFFI386 have been updated to look for and update references to dllimport symbols. Reviewers: compnerd Subscribers: hiraditya, ributzka, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D75884
This commit is contained in:
parent
aed5712522
commit
337e131ca7
|
@ -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 @@ uint64_t RuntimeDyldCOFF::getSymbolOffset(const SymbolRef &Sym) {
|
|||
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();
|
||||
}
|
||||
|
|
|
@ -36,9 +36,22 @@ public:
|
|||
|
||||
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
|
||||
|
|
|
@ -191,13 +191,11 @@ public:
|
|||
|
||||
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 &&
|
||||
|
|
|
@ -89,7 +89,8 @@ private:
|
|||
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 @@ public:
|
|||
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 @@ public:
|
|||
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 @@ public:
|
|||
<< 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);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ class RuntimeDyldCOFFI386 : public RuntimeDyldCOFF {
|
|||
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 @@ public:
|
|||
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 @@ public:
|
|||
<< " 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 @@ public:
|
|||
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 @@ public:
|
|||
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;
|
||||
|
|
|
@ -48,7 +48,7 @@ class RuntimeDyldCOFFThumb : public RuntimeDyldCOFF {
|
|||
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 @@ public:
|
|||
<< " 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 @@ public:
|
|||
// 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 @@ public:
|
|||
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 @@ public:
|
|||
EncodeImmediate(&Target[0],
|
||||
(static_cast<uint32_t>(Result) >> 00) | ISASelectionBit);
|
||||
EncodeImmediate(&Target[4], static_cast<uint32_t>(Result) >> 16);
|
||||
|
||||
break;
|
||||
}
|
||||
case COFF::IMAGE_REL_ARM_BRANCH20T: {
|
||||
|
|
|
@ -56,7 +56,8 @@ private:
|
|||
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 @@ public:
|
|||
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 @@ public:
|
|||
Expected<StringRef> 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 @@ public:
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -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 @@ branch24t:
|
|||
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,48 +84,25 @@ string:
|
|||
|
||||
.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:
|
||||
|
|
|
@ -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 @@ rel12:
|
|||
_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 @@ rel9:
|
|||
# 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
|
||||
|
|
|
@ -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 @@ inst1:
|
|||
.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
|
||||
|
|
Loading…
Reference in New Issue