//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/ExecutionEngine/ObjectBuffer.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/Object/MachO.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Memory.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
using namespace llvm;
using namespace llvm::object;
+using std::error_code;
static cl::list<std::string>
InputFileList(cl::Positional, cl::ZeroOrMore,
cl::desc("Function to call as entry point."),
cl::init("_main"));
+static cl::list<std::string>
+Dylibs("dylib",
+ cl::desc("Add library."),
+ cl::ZeroOrMore);
+
/* *** */
// A trivial memory manager that doesn't do anything fancy, just uses the
SmallVector<sys::MemoryBlock, 16> DataMemory;
uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID, StringRef SectionName);
+ unsigned SectionID,
+ StringRef SectionName) override;
uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
unsigned SectionID, StringRef SectionName,
- bool IsReadOnly);
+ bool IsReadOnly) override;
- virtual void *getPointerToNamedFunction(const std::string &Name,
- bool AbortOnFailure = true) {
- return 0;
+ void *getPointerToNamedFunction(const std::string &Name,
+ bool AbortOnFailure = true) override {
+ return nullptr;
}
- bool finalizeMemory(std::string *ErrMsg) { return false; }
+ bool finalizeMemory(std::string *ErrMsg) override { return false; }
// Invalidate instruction cache for sections with execute permissions.
// Some platforms with separate data cache and instruction cache require
unsigned Alignment,
unsigned SectionID,
StringRef SectionName) {
- sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, 0, 0);
+ sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, nullptr, nullptr);
FunctionMemory.push_back(MB);
return (uint8_t*)MB.base();
}
unsigned SectionID,
StringRef SectionName,
bool IsReadOnly) {
- sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, 0, 0);
+ sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, nullptr, nullptr);
DataMemory.push_back(MB);
return (uint8_t*)MB.base();
}
return 1;
}
+static void loadDylibs() {
+ for (const std::string &Dylib : Dylibs) {
+ if (sys::fs::is_regular_file(Dylib)) {
+ std::string ErrMsg;
+ if (sys::DynamicLibrary::LoadLibraryPermanently(Dylib.c_str(), &ErrMsg))
+ llvm::errs() << "Error loading '" << Dylib << "': "
+ << ErrMsg << "\n";
+ } else
+ llvm::errs() << "Dylib not found: '" << Dylib << "'.\n";
+ }
+}
+
+
/* *** */
static int printLineInfoForInput() {
+ // Load any dylibs requested on the command line.
+ loadDylibs();
+
// If we don't have any input files, read from stdin.
if (!InputFileList.size())
InputFileList.push_back("-");
RuntimeDyld Dyld(&MemMgr);
// Load the input memory buffer.
- OwningPtr<MemoryBuffer> InputBuffer;
- OwningPtr<ObjectImage> LoadedObject;
+ std::unique_ptr<MemoryBuffer> InputBuffer;
+ std::unique_ptr<ObjectImage> LoadedObject;
if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFileList[i],
InputBuffer))
return Error("unable to read input: '" + ec.message() + "'");
// Load the object file
- LoadedObject.reset(Dyld.loadObject(new ObjectBuffer(InputBuffer.take())));
+ LoadedObject.reset(Dyld.loadObject(new ObjectBuffer(InputBuffer.release())));
if (!LoadedObject) {
return Error(Dyld.getErrorString());
}
// Resolve all the relocations we can.
Dyld.resolveRelocations();
- OwningPtr<DIContext> Context(DIContext::getDWARFContext(LoadedObject->getObjectFile()));
+ std::unique_ptr<DIContext> Context(
+ DIContext::getDWARFContext(LoadedObject->getObjectFile()));
// Use symbol info to iterate functions in the object.
for (object::symbol_iterator I = LoadedObject->begin_symbols(),
DILineInfoTable::iterator End = Lines.end();
for (DILineInfoTable::iterator It = Begin; It != End; ++It) {
outs() << " Line info @ " << It->first - Addr << ": "
- << It->second.getFileName()
- << ", line:" << It->second.getLine() << "\n";
+ << It->second.FileName << ", line:" << It->second.Line << "\n";
}
}
}
}
static int executeInput() {
+ // Load any dylibs requested on the command line.
+ loadDylibs();
+
// Instantiate a dynamic linker.
TrivialMemoryManager MemMgr;
RuntimeDyld Dyld(&MemMgr);
InputFileList.push_back("-");
for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) {
// Load the input memory buffer.
- OwningPtr<MemoryBuffer> InputBuffer;
- OwningPtr<ObjectImage> LoadedObject;
+ std::unique_ptr<MemoryBuffer> InputBuffer;
+ std::unique_ptr<ObjectImage> LoadedObject;
if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFileList[i],
InputBuffer))
return Error("unable to read input: '" + ec.message() + "'");
// Load the object file
- LoadedObject.reset(Dyld.loadObject(new ObjectBuffer(InputBuffer.take())));
+ LoadedObject.reset(Dyld.loadObject(new ObjectBuffer(InputBuffer.release())));
if (!LoadedObject) {
return Error(Dyld.getErrorString());
}
// Get the address of the entry point (_main by default).
void *MainAddress = Dyld.getSymbolAddress(EntryPoint);
- if (MainAddress == 0)
+ if (!MainAddress)
return Error("no definition for '" + EntryPoint + "'");
// Invalidate the instruction cache for each loaded function.
const char **Argv = new const char*[2];
// Use the name of the first input object module as argv[0] for the target.
Argv[0] = InputFileList[0].c_str();
- Argv[1] = 0;
+ Argv[1] = nullptr;
return Main(1, Argv);
}