diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp index ee398e7b4cf..ec9d6526ece 100644 --- a/tools/llvm-rtdyld/llvm-rtdyld.cpp +++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -24,8 +24,9 @@ using namespace llvm; using namespace llvm::object; -static cl::opt -InputFile(cl::Positional, cl::desc(""), cl::init("-")); +static cl::list +InputFileList(cl::Positional, cl::ZeroOrMore, + cl::desc("")); enum ActionType { AC_Execute @@ -82,22 +83,31 @@ static int Error(const Twine &Msg) { /* *** */ static int executeInput() { - // Load the input memory buffer. - OwningPtr InputBuffer; - if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFile, InputBuffer)) - return Error("unable to read input: '" + ec.message() + "'"); - // Instantiate a dynamic linker. TrivialMemoryManager *MemMgr = new TrivialMemoryManager; RuntimeDyld Dyld(MemMgr); - // Load the object file into it. - if (Dyld.loadObject(InputBuffer.take())) { - return Error(Dyld.getErrorString()); + // If we don't have any input files, read from stdin. + if (!InputFileList.size()) + InputFileList.push_back("-"); + for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) { + // Load the input memory buffer. + OwningPtr InputBuffer; + if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFileList[i], + InputBuffer)) + return Error("unable to read input: '" + ec.message() + "'"); + + // Load the object file into it. + if (Dyld.loadObject(InputBuffer.take())) { + return Error(Dyld.getErrorString()); + } } + // Resolve all the relocations we can. Dyld.resolveRelocations(); + // FIXME: Error out if there are unresolved relocations. + // Get the address of the entry point (_main by default). void *MainAddress = Dyld.getSymbolAddress(EntryPoint); if (MainAddress == 0) @@ -113,14 +123,14 @@ static int executeInput() { return Error("unable to mark function executable: '" + ErrorStr + "'"); } - // Dispatch to _main(). - errs() << "loaded '_main' at: " << (void*)MainAddress << "\n"; + errs() << "loaded '" << EntryPoint << "' at: " << (void*)MainAddress << "\n"; int (*Main)(int, const char**) = (int(*)(int,const char**)) uintptr_t(MainAddress); const char **Argv = new const char*[2]; - Argv[0] = InputFile.c_str(); + // Use the name of the first input object module as argv[0] for the target. + Argv[0] = InputFileList[0].c_str(); Argv[1] = 0; return Main(1, Argv); }