<html><head><style type="text/css"><!-- DIV {margin:0px;} --></style></head><body><div style="font-family:arial,helvetica,sans-serif;font-size:10pt"><div>Are you planning to add support for ELF also?<br><br>- Jan<br></div><div style="font-family: arial,helvetica,sans-serif; font-size: 10pt;"><br><div style="font-family: Courier New,monaco,monospace,sans-serif; font-size: 10pt;"><font size="2" face="Tahoma"><hr size="1"><b><span style="font-weight: bold;">From:</span></b> Jim Grosbach <grosbach@apple.com><br><b><span style="font-weight: bold;">To:</span></b> llvm-commits@cs.uiuc.edu<br><b><span style="font-weight: bold;">Sent:</span></b> Mon, March 21, 2011 6:15:52 PM<br><b><span style="font-weight: bold;">Subject:</span></b> [llvm-commits] [llvm] r128031 - in /llvm/trunk: include/llvm/ExecutionEngine/RuntimeDyld.h lib/ExecutionEngine/Makefile lib/ExecutionEngine/RuntimeDyld/ lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt
lib/ExecutionEngine/RuntimeDyld/Makefile lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp tools/llvm-rtdyld/Makefile tools/llvm-rtdyld/llvm-rtdyld.cpp<br></font><br>
Author: grosbach<br>Date: Mon Mar 21 17:15:52 2011<br>New Revision: 128031<br><br><span>URL: <a target="_blank" href="http://llvm.org/viewvc/llvm-project?rev=128031&view=rev">http://llvm.org/viewvc/llvm-project?rev=128031&view=rev</a></span><br>Log:<br>Library-ize the dyld components of llvm-rtdyld.<br><br>Move the dynamic linking functionality of the llvm-rtdyld program into an<br>ExecutionEngine support library. Update llvm-rtdyld to just load an object<br>file into memory, use the library to process it, then run the _main()<br>function, if one is found.<br><br><br>Added:<br> llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h<br> llvm/trunk/lib/ExecutionEngine/RuntimeDyld/<br> llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt<br> llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Makefile<br> llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp<br>Modified:<br>
llvm/trunk/lib/ExecutionEngine/Makefile<br> llvm/trunk/tools/llvm-rtdyld/Makefile<br> llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp<br><br>Added: llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h<br><span>URL: <a target="_blank" href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h?rev=128031&view=auto">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h?rev=128031&view=auto</a></span><br>==============================================================================<br>--- llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h (added)<br>+++ llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h Mon Mar 21 17:15:52 2011<br>@@ -0,0 +1,45 @@<br>+//===-- RuntimeDyld.h - Run-time dynamic linker for MC-JIT ------*- C++ -*-===//<br>+//<br>+// The LLVM Compiler
Infrastructure<br>+//<br>+// This file is distributed under the University of Illinois Open Source<br>+// License. See LICENSE.TXT for details.<br>+//<br>+//===----------------------------------------------------------------------===//<br>+//<br>+// Interface for the runtime dynamic linker facilities of the MC-JIT.<br>+//<br>+//===----------------------------------------------------------------------===//<br>+<br>+#ifndef LLVM_RUNTIME_DYLD_H<br>+#define LLVM_RUNTIME_DYLD_H<br>+<br>+#include "llvm/ADT/StringRef.h"<br>+#include "llvm/Support/Memory.h"<br>+<br>+namespace llvm {<br>+<br>+class RuntimeDyldImpl;<br>+class MemoryBuffer;<br>+<br>+class RuntimeDyld {<br>+ RuntimeDyld(const RuntimeDyld &); // DO NOT IMPLEMENT<br>+ void operator=(const RuntimeDyld &); // DO NOT IMPLEMENT<br>+<br>+ // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public<br>+ // interface.<br>+ RuntimeDyldImpl
*Dyld;<br>+public:<br>+ RuntimeDyld();<br>+ ~RuntimeDyld();<br>+<br>+ bool loadObject(MemoryBuffer *InputBuffer);<br>+ void *getSymbolAddress(StringRef Name);<br>+ // FIXME: Should be parameterized to get the memory block associated with<br>+ // a particular loaded object.<br>+ sys::MemoryBlock getMemoryBlock();<br>+};<br>+<br>+} // end namespace llvm<br>+<br>+#endif<br><br>Modified: llvm/trunk/lib/ExecutionEngine/Makefile<br><span>URL: <a target="_blank" href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Makefile?rev=128031&r1=128030&r2=128031&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Makefile?rev=128031&r1=128030&r2=128031&view=diff</a></span><br>==============================================================================<br>--- llvm/trunk/lib/ExecutionEngine/Makefile (original)<br>+++ llvm/trunk/lib/ExecutionEngine/Makefile
Mon Mar 21 17:15:52 2011<br>@@ -8,6 +8,6 @@<br> ##===----------------------------------------------------------------------===##<br> LEVEL = ../..<br> LIBRARYNAME = LLVMExecutionEngine<br>-PARALLEL_DIRS = Interpreter JIT MCJIT<br>+PARALLEL_DIRS = Interpreter JIT MCJIT RuntimeDyld<br> <br> include $(LEVEL)/Makefile.common<br><br>Added: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt<br><span>URL: <a target="_blank" href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt?rev=128031&view=auto">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt?rev=128031&view=auto</a></span><br>==============================================================================<br>--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt (added)<br>+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt Mon Mar 21 17:15:52 2011<br>@@ -0,0 +1,3
@@<br>+add_llvm_library(LLVMRuntimeDyld<br>+ RuntimeDyld.cpp<br>+ )<br><br>Added: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Makefile<br><span>URL: <a target="_blank" href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Makefile?rev=128031&view=auto">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Makefile?rev=128031&view=auto</a></span><br>==============================================================================<br>--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Makefile (added)<br>+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/Makefile Mon Mar 21 17:15:52 2011<br>@@ -0,0 +1,13 @@<br>+##===- lib/ExecutionEngine/MCJIT/Makefile ------------------*- Makefile -*-===##<br>+#<br>+# The LLVM Compiler Infrastructure<br>+#<br>+# This file is distributed under the University of Illinois Open Source<br>+#
License. See LICENSE.TXT for details.<br>+#<br>+##===----------------------------------------------------------------------===##<br>+<br>+LEVEL = ../../..<br>+LIBRARYNAME = LLVMRuntimeDyld<br>+<br>+include $(LEVEL)/Makefile.common<br><br>Added: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp<br><span>URL: <a target="_blank" href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=128031&view=auto">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=128031&view=auto</a></span><br>==============================================================================<br>--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp (added)<br>+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp Mon Mar 21 17:15:52 2011<br>@@ -0,0 +1,329 @@<br>+//===-- RuntimeDyld.h - Run-time dynamic linker for MC-JIT ------*- C++ -*-===//<br>+//<br>+//
The LLVM Compiler Infrastructure<br>+//<br>+// This file is distributed under the University of Illinois Open Source<br>+// License. See LICENSE.TXT for details.<br>+//<br>+//===----------------------------------------------------------------------===//<br>+//<br>+// Implementation of the MC-JIT runtime dynamic linker.<br>+//<br>+//===----------------------------------------------------------------------===//<br>+<br>+#include "llvm/ADT/OwningPtr.h"<br>+#include "llvm/ADT/StringMap.h"<br>+#include "llvm/ADT/StringRef.h"<br>+#include "llvm/ADT/Twine.h"<br>+#include "llvm/ExecutionEngine/RuntimeDyld.h"<br>+#include "llvm/Object/MachOObject.h"<br>+#include "llvm/Support/Memory.h"<br>+#include "llvm/Support/MemoryBuffer.h"<br>+#include "llvm/Support/system_error.h"<br>+using namespace llvm;<br>+using namespace llvm::object;<br>+<br>+namespace llvm {<br>+class RuntimeDyldImpl {<br>+ //
Master symbol table. As modules are loaded and external symbols are<br>+ // resolved, their addresses are stored here.<br>+ StringMap<void*> SymbolTable;<br>+<br>+ // FIXME: Should have multiple data blocks, one for each loaded chunk of<br>+ // compiled code.<br>+ sys::MemoryBlock Data;<br>+<br>+ bool HasError;<br>+ std::string ErrorStr;<br>+<br>+ // Set the error state and record an error string.<br>+ bool Error(const Twine &Msg) {<br>+ ErrorStr = Msg.str();<br>+ HasError = true;<br>+ return true;<br>+ }<br>+<br>+ bool loadSegment32(const MachOObject *Obj,<br>+ const MachOObject::LoadCommandInfo *SegmentLCI,<br>+ const InMemoryStruct<macho::SymtabLoadCommand>
&SymtabLC);<br>+ bool loadSegment64(const MachOObject *Obj,<br>+ const MachOObject::LoadCommandInfo *SegmentLCI,<br>+ const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC);<br>+<br>+public:<br>+ bool loadObject(MemoryBuffer *InputBuffer);<br>+<br>+ void *getSymbolAddress(StringRef Name) {<br>+ // Use lookup() rather than [] because we don't want to add an entry<br>+ // if there isn't one already, which the [] operator does.<br>+ return SymbolTable.lookup(Name);<br>+ }<br>+<br>+ sys::MemoryBlock getMemoryBlock() { return Data; }<br>+<br>+ // Is the linker in an error state?<br>+ bool hasError() { return HasError; }<br>+<br>+ // Mark the error condition as handled and continue.<br>+ void clearError() {
HasError = false; }<br>+<br>+ // Get the error message.<br>+ StringRef getErrorString() { return ErrorStr; }<br>+};<br>+<br>+<br>+<br>+bool RuntimeDyldImpl::<br>+loadSegment32(const MachOObject *Obj,<br>+ const MachOObject::LoadCommandInfo *SegmentLCI,<br>+ const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC) {<br>+ InMemoryStruct<macho::SegmentLoadCommand> Segment32LC;<br>+ Obj->ReadSegmentLoadCommand(*SegmentLCI, Segment32LC);<br>+ if (!Segment32LC)<br>+ return Error("unable to load segment load command");<br>+<br>+ // Map the segment into memory.<br>+ std::string ErrorStr;<br>+ Data = sys::Memory::AllocateRWX(Segment32LC->VMSize, 0, &ErrorStr);<br>+ if (!Data.base())<br>+ return Error("unable to allocate memory block: '" + ErrorStr +
"'");<br>+ memcpy(Data.base(), Obj->getData(Segment32LC->FileOffset,<br>+ Segment32LC->FileSize).data(),<br>+ Segment32LC->FileSize);<br>+ memset((char*)Data.base() + Segment32LC->FileSize, 0,<br>+ Segment32LC->VMSize - Segment32LC->FileSize);<br>+<br>+ // Bind the section indices to address.<br>+ void **SectionBases = new void*[Segment32LC->NumSections];<br>+ for (unsigned i = 0; i != Segment32LC->NumSections; ++i) {<br>+ InMemoryStruct<macho::Section> Sect;<br>+ Obj->ReadSection(*SegmentLCI, i, Sect);<br>+ if (!Sect)<br>+ return Error("unable to load section: '" + Twine(i) + "'");<br>+<br>+ // FIXME: We don't support relocations yet.<br>+
if (Sect->NumRelocationTableEntries != 0)<br>+ return Error("not yet implemented: relocations!");<br>+<br>+ // FIXME: Improve check.<br>+ if (Sect->Flags != 0x80000400)<br>+ return Error("unsupported section type!");<br>+<br>+ SectionBases[i] = (char*) Data.base() + Sect->Address;<br>+ }<br>+<br>+ // Bind all the symbols to address.<br>+ for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) {<br>+ InMemoryStruct<macho::SymbolTableEntry> STE;<br>+ Obj->ReadSymbolTableEntry(SymtabLC->SymbolTableOffset, i, STE);<br>+ if (!STE)<br>+ return Error("unable to read symbol: '" + Twine(i) + "'");<br>+ if (STE->SectionIndex == 0)<br>+ return Error("unexpected undefined symbol!");<br>+<br>+ unsigned Index =
STE->SectionIndex - 1;<br>+ if (Index >= Segment32LC->NumSections)<br>+ return Error("invalid section index for symbol: '" + Twine() + "'");<br>+<br>+ // Get the symbol name.<br>+ StringRef Name = Obj->getStringAtIndex(STE->StringIndex);<br>+<br>+ // Get the section base address.<br>+ void *SectionBase = SectionBases[Index];<br>+<br>+ // Get the symbol address.<br>+ void *Address = (char*) SectionBase + STE->Value;<br>+<br>+ // FIXME: Check the symbol type and flags.<br>+ if (STE->Type != 0xF)<br>+ return Error("unexpected symbol type!");<br>+ if (STE->Flags != 0x0)<br>+ return Error("unexpected symbol type!");<br>+<br>+ SymbolTable[Name] = Address;<br>+ }<br>+<br>+ delete SectionBases;<br>+ return
false;<br>+}<br>+<br>+<br>+bool RuntimeDyldImpl::<br>+loadSegment64(const MachOObject *Obj,<br>+ const MachOObject::LoadCommandInfo *SegmentLCI,<br>+ const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC) {<br>+ InMemoryStruct<macho::Segment64LoadCommand> Segment64LC;<br>+ Obj->ReadSegment64LoadCommand(*SegmentLCI, Segment64LC);<br>+ if (!Segment64LC)<br>+ return Error("unable to load segment load command");<br>+<br>+ // Map the segment into memory.<br>+ std::string ErrorStr;<br>+ Data = sys::Memory::AllocateRWX(Segment64LC->VMSize, 0, &ErrorStr);<br>+ if (!Data.base())<br>+ return Error("unable to allocate memory block: '" + ErrorStr + "'");<br>+ memcpy(Data.base(), Obj->getData(Segment64LC->FileOffset,<br>+
Segment64LC->FileSize).data(),<br>+ Segment64LC->FileSize);<br>+ memset((char*)Data.base() + Segment64LC->FileSize, 0,<br>+ Segment64LC->VMSize - Segment64LC->FileSize);<br>+<br>+ // Bind the section indices to address.<br>+ void **SectionBases = new void*[Segment64LC->NumSections];<br>+ for (unsigned i = 0; i != Segment64LC->NumSections; ++i) {<br>+ InMemoryStruct<macho::Section64> Sect;<br>+ Obj->ReadSection64(*SegmentLCI, i, Sect);<br>+ if (!Sect)<br>+ return Error("unable to load section: '" + Twine(i) + "'");<br>+<br>+ // FIXME: We don't support relocations yet.<br>+ if (Sect->NumRelocationTableEntries != 0)<br>+ return Error("not yet implemented:
relocations!");<br>+<br>+ // FIXME: Improve check.<br>+ if (Sect->Flags != 0x80000400)<br>+ return Error("unsupported section type!");<br>+<br>+ SectionBases[i] = (char*) Data.base() + Sect->Address;<br>+ }<br>+<br>+ // Bind all the symbols to address.<br>+ for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) {<br>+ InMemoryStruct<macho::Symbol64TableEntry> STE;<br>+ Obj->ReadSymbol64TableEntry(SymtabLC->SymbolTableOffset, i, STE);<br>+ if (!STE)<br>+ return Error("unable to read symbol: '" + Twine(i) + "'");<br>+ if (STE->SectionIndex == 0)<br>+ return Error("unexpected undefined symbol!");<br>+<br>+ unsigned Index = STE->SectionIndex - 1;<br>+ if (Index >= Segment64LC->NumSections)<br>+ return
Error("invalid section index for symbol: '" + Twine() + "'");<br>+<br>+ // Get the symbol name.<br>+ StringRef Name = Obj->getStringAtIndex(STE->StringIndex);<br>+<br>+ // Get the section base address.<br>+ void *SectionBase = SectionBases[Index];<br>+<br>+ // Get the symbol address.<br>+ void *Address = (char*) SectionBase + STE->Value;<br>+<br>+ // FIXME: Check the symbol type and flags.<br>+ if (STE->Type != 0xF)<br>+ return Error("unexpected symbol type!");<br>+ if (STE->Flags != 0x0)<br>+ return Error("unexpected symbol type!");<br>+<br>+ SymbolTable[Name] = Address;<br>+ }<br>+<br>+ delete SectionBases;<br>+ return false;<br>+}<br>+<br>+<br>+<br>+bool RuntimeDyldImpl::loadObject(MemoryBuffer *InputBuffer) {<br>+ // If the linker is in an
error state, don't do anything.<br>+ if (hasError())<br>+ return true;<br>+ // Load the Mach-O wrapper object.<br>+ std::string ErrorStr;<br>+ OwningPtr<MachOObject> Obj(<br>+ MachOObject::LoadFromBuffer(InputBuffer, &ErrorStr));<br>+ if (!Obj)<br>+ return Error("unable to load object: '" + ErrorStr + "'");<br>+<br>+ // Validate that the load commands match what we expect.<br>+ const MachOObject::LoadCommandInfo *SegmentLCI = 0, *SymtabLCI = 0,<br>+ *DysymtabLCI = 0;<br>+ for (unsigned i = 0; i != Obj->getHeader().NumLoadCommands; ++i) {<br>+ const MachOObject::LoadCommandInfo &LCI = Obj->getLoadCommandInfo(i);<br>+ switch (LCI.Command.Type) {<br>+ case macho::LCT_Segment:<br>+ case macho::LCT_Segment64:<br>+ if (SegmentLCI)<br>+ return
Error("unexpected input object (multiple segments)");<br>+ SegmentLCI = &LCI;<br>+ break;<br>+ case macho::LCT_Symtab:<br>+ if (SymtabLCI)<br>+ return Error("unexpected input object (multiple symbol tables)");<br>+ SymtabLCI = &LCI;<br>+ break;<br>+ case macho::LCT_Dysymtab:<br>+ if (DysymtabLCI)<br>+ return Error("unexpected input object (multiple symbol tables)");<br>+ DysymtabLCI = &LCI;<br>+ break;<br>+ default:<br>+ return Error("unexpected input object (unexpected load command");<br>+ }<br>+ }<br>+<br>+ if (!SymtabLCI)<br>+ return Error("no symbol table found in object");<br>+ if (!SegmentLCI)<br>+ return
Error("no symbol table found in object");<br>+<br>+ // Read and register the symbol table data.<br>+ InMemoryStruct<macho::SymtabLoadCommand> SymtabLC;<br>+ Obj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC);<br>+ if (!SymtabLC)<br>+ return Error("unable to load symbol table load command");<br>+ Obj->RegisterStringTable(*SymtabLC);<br>+<br>+ // Read the dynamic link-edit information, if present (not present in static<br>+ // objects).<br>+ if (DysymtabLCI) {<br>+ InMemoryStruct<macho::DysymtabLoadCommand> DysymtabLC;<br>+ Obj->ReadDysymtabLoadCommand(*DysymtabLCI, DysymtabLC);<br>+ if (!DysymtabLC)<br>+ return Error("unable to load dynamic link-exit load command");<br>+<br>+ // FIXME: We don't support anything interesting yet.<br>+ if (DysymtabLC->LocalSymbolsIndex != 0)<br>+
return Error("NOT YET IMPLEMENTED: local symbol entries");<br>+ if (DysymtabLC->ExternalSymbolsIndex != 0)<br>+ return Error("NOT YET IMPLEMENTED: non-external symbol entries");<br>+ if (DysymtabLC->UndefinedSymbolsIndex != SymtabLC->NumSymbolTableEntries)<br>+ return Error("NOT YET IMPLEMENTED: undefined symbol entries");<br>+ }<br>+<br>+ // Load the segment load command.<br>+ if (SegmentLCI->Command.Type == macho::LCT_Segment) {<br>+ if (loadSegment32(Obj.get(), SegmentLCI, SymtabLC))<br>+ return true;<br>+ } else {<br>+ if (loadSegment64(Obj.get(), SegmentLCI, SymtabLC))<br>+ return true;<br>+ }<br>+<br>+ return false;<br>+}<br>+<br>+<br>+//===----------------------------------------------------------------------===//<br>+// RuntimeDyld class
implementation<br>+RuntimeDyld::RuntimeDyld() {<br>+ Dyld = new RuntimeDyldImpl;<br>+}<br>+<br>+RuntimeDyld::~RuntimeDyld() {<br>+ delete Dyld;<br>+}<br>+<br>+bool RuntimeDyld::loadObject(MemoryBuffer *InputBuffer) {<br>+ return Dyld->loadObject(InputBuffer);<br>+}<br>+<br>+void *RuntimeDyld::getSymbolAddress(StringRef Name) {<br>+ return Dyld->getSymbolAddress(Name);<br>+}<br>+<br>+sys::MemoryBlock RuntimeDyld::getMemoryBlock() {<br>+ return Dyld->getMemoryBlock();<br>+}<br>+<br>+} // end namespace llvm<br><br>Modified: llvm/trunk/tools/llvm-rtdyld/Makefile<br><span>URL: <a target="_blank"
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rtdyld/Makefile?rev=128031&r1=128030&r2=128031&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rtdyld/Makefile?rev=128031&r1=128030&r2=128031&view=diff</a></span><br>==============================================================================<br>--- llvm/trunk/tools/llvm-rtdyld/Makefile (original)<br>+++ llvm/trunk/tools/llvm-rtdyld/Makefile Mon Mar 21 17:15:52 2011<br>@@ -18,6 +18,6 @@<br> # early so we can set up LINK_COMPONENTS before including Makefile.rules<br> include $(LEVEL)/Makefile.config<br> <br>-LINK_COMPONENTS := $(TARGETS_TO_BUILD) support MC object<br>+LINK_COMPONENTS := $(TARGETS_TO_BUILD) support MC object RuntimeDyld<br> <br> include $(LLVM_SRC_ROOT)/Makefile.rules<br><br>Modified: llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp<br><span>URL: <a target="_blank"
href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp?rev=128031&r1=128030&r2=128031&view=diff">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp?rev=128031&r1=128030&r2=128031&view=diff</a></span><br>==============================================================================<br>--- llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp (original)<br>+++ llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp Mon Mar 21 17:15:52 2011<br>@@ -13,6 +13,7 @@<br> <br> #include "llvm/ADT/StringMap.h"<br> #include "llvm/ADT/OwningPtr.h"<br>+#include "llvm/ExecutionEngine/RuntimeDyld.h"<br> #include "llvm/Object/MachOObject.h"<br> #include "llvm/Support/CommandLine.h"<br> #include "llvm/Support/ManagedStatic.h"<br>@@ -51,157 +52,6 @@<br> }<br> <br> /* *** */<br>-static bool<br>-loadSegment32(const MachOObject *Obj,<br>- sys::MemoryBlock
&Data,<br>- const MachOObject::LoadCommandInfo *SegmentLCI,<br>- const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC,<br>- StringMap<void*> &SymbolTable) {<br>- InMemoryStruct<macho::SegmentLoadCommand> Segment32LC;<br>- Obj->ReadSegmentLoadCommand(*SegmentLCI, Segment32LC);<br>- if (!Segment32LC)<br>- return Error("unable to load segment load command");<br>-<br>- // Map the segment into memory.<br>- std::string ErrorStr;<br>- Data = sys::Memory::AllocateRWX(Segment32LC->VMSize, 0, &ErrorStr);<br>- if (!Data.base())<br>- return Error("unable to allocate memory block: '" + ErrorStr + "'");<br>- memcpy(Data.base(), Obj->getData(Segment32LC->FileOffset,<br>-
Segment32LC->FileSize).data(),<br>- Segment32LC->FileSize);<br>- memset((char*)Data.base() + Segment32LC->FileSize, 0,<br>- Segment32LC->VMSize - Segment32LC->FileSize);<br>-<br>- // Bind the section indices to address.<br>- void **SectionBases = new void*[Segment32LC->NumSections];<br>- for (unsigned i = 0; i != Segment32LC->NumSections; ++i) {<br>- InMemoryStruct<macho::Section> Sect;<br>- Obj->ReadSection(*SegmentLCI, i, Sect);<br>- if (!Sect)<br>- return Error("unable to load section: '" + Twine(i) + "'");<br>-<br>- // FIXME: We don't support relocations yet.<br>- if (Sect->NumRelocationTableEntries != 0)<br>- return Error("not yet implemented:
relocations!");<br>-<br>- // FIXME: Improve check.<br>- if (Sect->Flags != 0x80000400)<br>- return Error("unsupported section type!");<br>-<br>- SectionBases[i] = (char*) Data.base() + Sect->Address;<br>- }<br>-<br>- // Bind all the symbols to address.<br>- for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) {<br>- InMemoryStruct<macho::SymbolTableEntry> STE;<br>- Obj->ReadSymbolTableEntry(SymtabLC->SymbolTableOffset, i, STE);<br>- if (!STE)<br>- return Error("unable to read symbol: '" + Twine(i) + "'");<br>- if (STE->SectionIndex == 0)<br>- return Error("unexpected undefined symbol!");<br>-<br>- unsigned Index = STE->SectionIndex - 1;<br>- if (Index >= Segment32LC->NumSections)<br>- return
Error("invalid section index for symbol: '" + Twine() + "'");<br>-<br>- // Get the symbol name.<br>- StringRef Name = Obj->getStringAtIndex(STE->StringIndex);<br>-<br>- // Get the section base address.<br>- void *SectionBase = SectionBases[Index];<br>-<br>- // Get the symbol address.<br>- void *Address = (char*) SectionBase + STE->Value;<br>-<br>- // FIXME: Check the symbol type and flags.<br>- if (STE->Type != 0xF)<br>- return Error("unexpected symbol type!");<br>- if (STE->Flags != 0x0)<br>- return Error("unexpected symbol type!");<br>-<br>- SymbolTable[Name] = Address;<br>- }<br>-<br>- delete SectionBases;<br>- return false;<br>-}<br>-<br>-static bool<br>-loadSegment64(const MachOObject *Obj,<br>-
sys::MemoryBlock &Data,<br>- const MachOObject::LoadCommandInfo *SegmentLCI,<br>- const InMemoryStruct<macho::SymtabLoadCommand> &SymtabLC,<br>- StringMap<void*> &SymbolTable) {<br>- InMemoryStruct<macho::Segment64LoadCommand> Segment64LC;<br>- Obj->ReadSegment64LoadCommand(*SegmentLCI, Segment64LC);<br>- if (!Segment64LC)<br>- return Error("unable to load segment load command");<br>-<br>- // Map the segment into memory.<br>- std::string ErrorStr;<br>- Data = sys::Memory::AllocateRWX(Segment64LC->VMSize, 0, &ErrorStr);<br>- if (!Data.base())<br>- return Error("unable to allocate memory block: '" + ErrorStr + "'");<br>- memcpy(Data.base(), Obj->getData(Segment64LC->FileOffset,<br>-
Segment64LC->FileSize).data(),<br>- Segment64LC->FileSize);<br>- memset((char*)Data.base() + Segment64LC->FileSize, 0,<br>- Segment64LC->VMSize - Segment64LC->FileSize);<br>-<br>- // Bind the section indices to address.<br>- void **SectionBases = new void*[Segment64LC->NumSections];<br>- for (unsigned i = 0; i != Segment64LC->NumSections; ++i) {<br>- InMemoryStruct<macho::Section64> Sect;<br>- Obj->ReadSection64(*SegmentLCI, i, Sect);<br>- if (!Sect)<br>- return Error("unable to load section: '" + Twine(i) + "'");<br>-<br>- // FIXME: We don't support relocations yet.<br>- if (Sect->NumRelocationTableEntries != 0)<br>- return Error("not
yet implemented: relocations!");<br>-<br>- // FIXME: Improve check.<br>- if (Sect->Flags != 0x80000400)<br>- return Error("unsupported section type!");<br>-<br>- SectionBases[i] = (char*) Data.base() + Sect->Address;<br>- }<br>-<br>- // Bind all the symbols to address.<br>- for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) {<br>- InMemoryStruct<macho::Symbol64TableEntry> STE;<br>- Obj->ReadSymbol64TableEntry(SymtabLC->SymbolTableOffset, i, STE);<br>- if (!STE)<br>- return Error("unable to read symbol: '" + Twine(i) + "'");<br>- if (STE->SectionIndex == 0)<br>- return Error("unexpected undefined symbol!");<br>-<br>- unsigned Index = STE->SectionIndex - 1;<br>- if (Index >= Segment64LC->NumSections)<br>-
return Error("invalid section index for symbol: '" + Twine() + "'");<br>-<br>- // Get the symbol name.<br>- StringRef Name = Obj->getStringAtIndex(STE->StringIndex);<br>-<br>- // Get the section base address.<br>- void *SectionBase = SectionBases[Index];<br>-<br>- // Get the symbol address.<br>- void *Address = (char*) SectionBase + STE->Value;<br>-<br>- // FIXME: Check the symbol type and flags.<br>- if (STE->Type != 0xF)<br>- return Error("unexpected symbol type!");<br>- if (STE->Flags != 0x0)<br>- return Error("unexpected symbol type!");<br>-<br>- SymbolTable[Name] = Address;<br>- }<br>-<br>- delete SectionBases;<br>- return false;<br>-}<br> <br> static int executeInput() {<br> // Load the input memory buffer.<br>@@ -209,94 +59,28
@@<br> if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFile, InputBuffer))<br> return Error("unable to read input: '" + ec.message() + "'");<br> <br>- // Load the Mach-O wrapper object.<br>- std::string ErrorStr;<br>- OwningPtr<MachOObject> Obj(<br>- MachOObject::LoadFromBuffer(InputBuffer.take(), &ErrorStr));<br>- if (!Obj)<br>- return Error("unable to load object: '" + ErrorStr + "'");<br>-<br>- // Validate that the load commands match what we expect.<br>- const MachOObject::LoadCommandInfo *SegmentLCI = 0, *SymtabLCI = 0,<br>- *DysymtabLCI = 0;<br>- for (unsigned i = 0; i != Obj->getHeader().NumLoadCommands; ++i) {<br>- const MachOObject::LoadCommandInfo &LCI = Obj->getLoadCommandInfo(i);<br>- switch (LCI.Command.Type) {<br>- case macho::LCT_Segment:<br>- case
macho::LCT_Segment64:<br>- if (SegmentLCI)<br>- return Error("unexpected input object (multiple segments)");<br>- SegmentLCI = &LCI;<br>- break;<br>- case macho::LCT_Symtab:<br>- if (SymtabLCI)<br>- return Error("unexpected input object (multiple symbol tables)");<br>- SymtabLCI = &LCI;<br>- break;<br>- case macho::LCT_Dysymtab:<br>- if (DysymtabLCI)<br>- return Error("unexpected input object (multiple symbol tables)");<br>- DysymtabLCI = &LCI;<br>- break;<br>- default:<br>- return Error("unexpected input object (unexpected load command");<br>- }<br>- }<br>-<br>- if (!SymtabLCI)<br>- return
Error("no symbol table found in object");<br>- if (!SegmentLCI)<br>- return Error("no symbol table found in object");<br>-<br>- // Read and register the symbol table data.<br>- InMemoryStruct<macho::SymtabLoadCommand> SymtabLC;<br>- Obj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC);<br>- if (!SymtabLC)<br>- return Error("unable to load symbol table load command");<br>- Obj->RegisterStringTable(*SymtabLC);<br>-<br>- // Read the dynamic link-edit information, if present (not present in static<br>- // objects).<br>- if (DysymtabLCI) {<br>- InMemoryStruct<macho::DysymtabLoadCommand> DysymtabLC;<br>- Obj->ReadDysymtabLoadCommand(*DysymtabLCI, DysymtabLC);<br>- if (!DysymtabLC)<br>- return Error("unable to load dynamic link-exit load command");<br>-<br>- // FIXME: We don't support anything
interesting yet.<br>- if (DysymtabLC->LocalSymbolsIndex != 0)<br>- return Error("NOT YET IMPLEMENTED: local symbol entries");<br>- if (DysymtabLC->ExternalSymbolsIndex != 0)<br>- return Error("NOT YET IMPLEMENTED: non-external symbol entries");<br>- if (DysymtabLC->UndefinedSymbolsIndex != SymtabLC->NumSymbolTableEntries)<br>- return Error("NOT YET IMPLEMENTED: undefined symbol entries");<br>- }<br>+ // Instantiate a dynamic linker.<br>+ RuntimeDyld Dyld;<br> <br>- // Load the segment load command.<br>- sys::MemoryBlock Data;<br>- StringMap<void*> SymbolTable;<br>- if (SegmentLCI->Command.Type == macho::LCT_Segment) {<br>- if (loadSegment32(Obj.get(), Data, SegmentLCI, SymtabLC, SymbolTable))<br>- return true;<br>- } else {<br>- if
(loadSegment64(Obj.get(), Data, SegmentLCI, SymtabLC, SymbolTable))<br>- return true;<br>- }<br>+ // Load the object file into it.<br>+ if (Dyld.loadObject(InputBuffer.take()))<br>+ return true;<br> <br> // Get the address of "_main".<br>- StringMap<void*>::iterator it = SymbolTable.find("_main");<br>- if (it == SymbolTable.end())<br>+ void *MainAddress = Dyld.getSymbolAddress("_main");<br>+ if (MainAddress == 0)<br> return Error("no definition for '_main'");<br> <br> // Invalidate the instruction cache.<br>+ sys::MemoryBlock Data = Dyld.getMemoryBlock();<br> sys::Memory::InvalidateInstructionCache(Data.base(), Data.size());<br> <br> // Make sure the memory is executable.<br>+ std::string ErrorStr;<br> if (!sys::Memory::setExecutable(Data, &ErrorStr))<br> return Error("unable to mark function
executable: '" + ErrorStr + "'");<br> <br> // Dispatch to _main().<br>- void *MainAddress = it->second;<br> errs() << "loaded '_main' at: " << MainAddress << "\n";<br> <br> int (*Main)(int, const char**) =<br><br><br>_______________________________________________<br>llvm-commits mailing list<br><a ymailto="mailto:llvm-commits@cs.uiuc.edu" href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br><span><a target="_blank" href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a></span><br></div></div>
</div></body></html>