summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp')
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp43
1 files changed, 42 insertions, 1 deletions
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
index 54f1a1c0cc2..0560a1b6127 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
@@ -13,10 +13,12 @@
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "RuntimeDyldCheckerImpl.h"
+#include "RuntimeDyldCOFF.h"
#include "RuntimeDyldELF.h"
#include "RuntimeDyldImpl.h"
#include "RuntimeDyldMachO.h"
#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/COFF.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MutexGuard.h"
@@ -264,6 +266,20 @@ static bool isRequiredForExecution(const SectionRef &Section) {
const ObjectFile *Obj = Section.getObject();
if (auto *ELFObj = dyn_cast<object::ELFObjectFileBase>(Obj))
return ELFObj->getSectionFlags(Section) & ELF::SHF_ALLOC;
+ if (auto *COFFObj = dyn_cast<object::COFFObjectFile>(Obj)) {
+ const coff_section *CoffSection = COFFObj->getCOFFSection(Section);
+ // Avoid loading zero-sized COFF sections.
+ // In PE files, VirtualSize gives the section size, and SizeOfRawData
+ // may be zero for sections with content. In Obj files, SizeOfRawData
+ // gives the section size, and VirtualSize is always zero. Hence
+ // the need to check for both cases below.
+ bool HasContent = (CoffSection->VirtualSize > 0)
+ || (CoffSection->SizeOfRawData > 0);
+ bool IsDiscardable = CoffSection->Characteristics &
+ (COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_LNK_INFO);
+ return HasContent && !IsDiscardable;
+ }
+
assert(isa<MachOObjectFile>(Obj));
return true;
}
@@ -273,6 +289,15 @@ static bool isReadOnlyData(const SectionRef &Section) {
if (auto *ELFObj = dyn_cast<object::ELFObjectFileBase>(Obj))
return !(ELFObj->getSectionFlags(Section) &
(ELF::SHF_WRITE | ELF::SHF_EXECINSTR));
+ if (auto *COFFObj = dyn_cast<object::COFFObjectFile>(Obj))
+ return ((COFFObj->getCOFFSection(Section)->Characteristics &
+ (COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
+ | COFF::IMAGE_SCN_MEM_READ
+ | COFF::IMAGE_SCN_MEM_WRITE))
+ ==
+ (COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
+ | COFF::IMAGE_SCN_MEM_READ));
+
assert(isa<MachOObjectFile>(Obj));
return false;
}
@@ -281,6 +306,9 @@ static bool isZeroInit(const SectionRef &Section) {
const ObjectFile *Obj = Section.getObject();
if (auto *ELFObj = dyn_cast<object::ELFObjectFileBase>(Obj))
return ELFObj->getSectionType(Section) == ELF::SHT_NOBITS;
+ if (auto *COFFObj = dyn_cast<object::COFFObjectFile>(Obj))
+ return COFFObj->getCOFFSection(Section)->Characteristics &
+ COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
auto *MachO = cast<MachOObjectFile>(Obj);
unsigned SectionType = MachO->getSectionType(Section);
@@ -512,7 +540,6 @@ unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
const SectionRef &Section, bool IsCode) {
StringRef data;
- Check(Section.getContents(data));
uint64_t Alignment64 = Section.getAlignment();
unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL;
@@ -542,6 +569,7 @@ unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
// Some sections, such as debug info, don't need to be loaded for execution.
// Leave those where they are.
if (IsRequired) {
+ Check(Section.getContents(data));
Allocate = DataSize + PaddingSize + StubBufSize;
Addr = IsCode ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID,
Name)
@@ -816,6 +844,15 @@ RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
RuntimeDyld::~RuntimeDyld() {}
+static std::unique_ptr<RuntimeDyldCOFF>
+createRuntimeDyldCOFF(Triple::ArchType Arch, RTDyldMemoryManager *MM,
+ bool ProcessAllSections, RuntimeDyldCheckerImpl *Checker) {
+ std::unique_ptr<RuntimeDyldCOFF> Dyld(RuntimeDyldCOFF::create(Arch, MM));
+ Dyld->setProcessAllSections(ProcessAllSections);
+ Dyld->setRuntimeDyldChecker(Checker);
+ return Dyld;
+}
+
static std::unique_ptr<RuntimeDyldELF>
createRuntimeDyldELF(RTDyldMemoryManager *MM, bool ProcessAllSections,
RuntimeDyldCheckerImpl *Checker) {
@@ -843,6 +880,10 @@ RuntimeDyld::loadObject(const ObjectFile &Obj) {
Dyld = createRuntimeDyldMachO(
static_cast<Triple::ArchType>(Obj.getArch()), MM,
ProcessAllSections, Checker);
+ else if (Obj.isCOFF())
+ Dyld = createRuntimeDyldCOFF(
+ static_cast<Triple::ArchType>(Obj.getArch()), MM,
+ ProcessAllSections, Checker);
else
report_fatal_error("Incompatible object format!");
}
OpenPOWER on IntegriCloud