summaryrefslogtreecommitdiff
path: root/lib/ExecutionEngine
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2014-06-25 00:20:53 +0000
committerLang Hames <lhames@gmail.com>2014-06-25 00:20:53 +0000
commit7ede4b96ded381fd054d9c006a4a66c1f69b5e42 (patch)
treefa706e908f38d34cf0ecdfef8663b1bc9c530973 /lib/ExecutionEngine
parent49b52b35d411a4cc28eb83bdc440a9839bb5bc17 (diff)
downloadllvm-7ede4b96ded381fd054d9c006a4a66c1f69b5e42.tar.gz
llvm-7ede4b96ded381fd054d9c006a4a66c1f69b5e42.tar.bz2
llvm-7ede4b96ded381fd054d9c006a4a66c1f69b5e42.tar.xz
[RuntimeDyld] Adds the necessary hooks to MCJIT to be able to debug generated
MachO files using the GDB JIT debugging interface. Patch by Keno Fischer. Thanks Keno! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211652 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ExecutionEngine')
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp124
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h9
2 files changed, 124 insertions, 9 deletions
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
index 2b425fbdd3..5b96371880 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
@@ -14,6 +14,8 @@
#include "RuntimeDyldMachO.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
+#include "ObjectImageCommon.h"
+#include "JITRegistrar.h"
using namespace llvm;
using namespace llvm::object;
@@ -21,6 +23,123 @@ using namespace llvm::object;
namespace llvm {
+class MachOObjectImage : public ObjectImageCommon {
+private:
+ typedef SmallVector<uint64_t, 1> SectionAddrList;
+ SectionAddrList OldSectionAddrList;
+
+protected:
+ bool is64;
+ bool Registered;
+
+private:
+ void initOldAddress() {
+ MachOObjectFile *objf = static_cast<MachOObjectFile *>(ObjFile.get());
+ // Unfortunately we need to do this, since there's information encoded
+ // in the original addr of the section that we could not otherwise
+ // recover. The reason for this is that symbols do not actually store
+ // their file offset, but only their vmaddr. This means that in order
+ // to locate the symbol correctly in the object file, we need to know
+ // where the original start of the section was (including any padding,
+ // etc).
+ for (section_iterator i = objf->section_begin(), e = objf->section_end();
+ i != e; ++i) {
+ uint64_t Addr;
+ i->getAddress(Addr);
+ OldSectionAddrList[i->getRawDataRefImpl().d.a] = Addr;
+ }
+ }
+
+public:
+ MachOObjectImage(ObjectBuffer *Input, bool is64)
+ : ObjectImageCommon(Input),
+ OldSectionAddrList(ObjFile->section_end()->getRawDataRefImpl().d.a, 0),
+ is64(is64), Registered(false) {
+ initOldAddress();
+ }
+
+ MachOObjectImage(std::unique_ptr<object::ObjectFile> Input, bool is64)
+ : ObjectImageCommon(std::move(Input)),
+ OldSectionAddrList(ObjFile->section_end()->getRawDataRefImpl().d.a, 0),
+ is64(is64), Registered(false) {
+ initOldAddress();
+ }
+
+ virtual ~MachOObjectImage() {}
+
+ // Subclasses can override these methods to update the image with loaded
+ // addresses for sections and common symbols
+ virtual void updateSectionAddress(const SectionRef &Sec, uint64_t Addr) {
+ MachOObjectFile *objf = static_cast<MachOObjectFile *>(ObjFile.get());
+ char *data =
+ const_cast<char *>(objf->getSectionPointer(Sec.getRawDataRefImpl()));
+
+ uint64_t oldAddr = OldSectionAddrList[Sec.getRawDataRefImpl().d.a];
+
+ if (is64) {
+ ((MachO::section_64 *)data)->addr = Addr;
+ } else {
+ ((MachO::section *)data)->addr = Addr;
+ }
+
+ for (symbol_iterator i = objf->symbol_begin(), e = objf->symbol_end();
+ i != e; ++i) {
+ section_iterator symSec(objf->section_end());
+ (*i).getSection(symSec);
+ if (*symSec == Sec) {
+ uint64_t symAddr;
+ (*i).getAddress(symAddr);
+ updateSymbolAddress(*i, symAddr + Addr - oldAddr);
+ }
+ }
+ }
+
+ uint64_t getOldSectionAddr(const SectionRef &Sec) const {
+ return OldSectionAddrList[Sec.getRawDataRefImpl().d.a];
+ }
+
+ virtual void updateSymbolAddress(const SymbolRef &Sym, uint64_t Addr) {
+ char *data = const_cast<char *>(
+ reinterpret_cast<const char *>(Sym.getRawDataRefImpl().p));
+ if (is64)
+ ((MachO::nlist_64 *)data)->n_value = Addr;
+ else
+ ((MachO::nlist *)data)->n_value = Addr;
+ }
+
+ virtual void registerWithDebugger() {
+ JITRegistrar::getGDBRegistrar().registerObject(*Buffer);
+ Registered = true;
+ }
+
+ virtual void deregisterWithDebugger() {
+ JITRegistrar::getGDBRegistrar().deregisterObject(*Buffer);
+ }
+};
+
+ObjectImage *RuntimeDyldMachO::createObjectImage(ObjectBuffer *Buffer) {
+ uint32_t magic = *((uint32_t *)Buffer->getBufferStart());
+ bool is64 = (magic == MachO::MH_MAGIC_64);
+ assert((magic == MachO::MH_MAGIC_64 || magic == MachO::MH_MAGIC) &&
+ "Unrecognized Macho Magic");
+ return new MachOObjectImage(Buffer, is64);
+}
+
+ObjectImage *RuntimeDyldMachO::createObjectImageFromFile(
+ std::unique_ptr<object::ObjectFile> ObjFile) {
+ if (!ObjFile)
+ return nullptr;
+
+ MemoryBuffer *Buffer =
+ MemoryBuffer::getMemBuffer(ObjFile->getData(), "", false);
+
+ uint32_t magic = *((uint32_t *)Buffer->getBufferStart());
+ bool is64 = (magic == MachO::MH_MAGIC_64);
+ assert((magic == MachO::MH_MAGIC_64 || magic == MachO::MH_MAGIC) &&
+ "Unrecognized Macho Magic");
+ return new MachOObjectImage(std::move(ObjFile), is64);
+}
+
static unsigned char *processFDE(unsigned char *P, intptr_t DeltaForText,
intptr_t DeltaForEH) {
DEBUG(dbgs() << "Processing FDE: Delta for text: " << DeltaForText
@@ -533,6 +652,7 @@ relocation_iterator RuntimeDyldMachO::processRelocationRef(
ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols,
StubMap &Stubs) {
const ObjectFile *OF = Obj.getObjectFile();
+ const MachOObjectImage &MachOObj = *static_cast<MachOObjectImage *>(&Obj);
const MachOObjectFile *MachO = static_cast<const MachOObjectFile *>(OF);
MachO::any_relocation_info RE =
MachO->getRelocation(RelI->getRawDataRefImpl());
@@ -609,8 +729,8 @@ relocation_iterator RuntimeDyldMachO::processRelocationRef(
bool IsCode = false;
Sec.isText(IsCode);
Value.SectionID = findOrEmitSection(Obj, Sec, IsCode, ObjSectionToID);
- uint64_t Addr;
- Sec.getAddress(Addr);
+ uint64_t Addr = MachOObj.getOldSectionAddr(Sec);
+ DEBUG(dbgs() << "\nAddr: " << Addr << "\nAddend: " << Addend);
Value.Addend = Addend - Addr;
if (IsPCRel)
Value.Addend += Offset + NumBytes;
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
index 060eb8c29a..35f0720808 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
@@ -105,14 +105,9 @@ public:
void finalizeLoad(ObjectImage &ObjImg,
ObjSectionToIDMap &SectionMap) override;
- static ObjectImage *createObjectImage(ObjectBuffer *InputBuffer) {
- return new ObjectImageCommon(InputBuffer);
- }
-
+ static ObjectImage *createObjectImage(ObjectBuffer *Buffer);
static ObjectImage *
- createObjectImageFromFile(std::unique_ptr<object::ObjectFile> InputObject) {
- return new ObjectImageCommon(std::move(InputObject));
- }
+ createObjectImageFromFile(std::unique_ptr<object::ObjectFile> InputObject);
};
} // end namespace llvm