<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>