From 4f9f41f2f9772ecd6a57800fcc8de8ec2734f33c Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 13 Apr 2011 15:49:40 +0000 Subject: Load multiple object files and link them via RuntimeDyld in llvm-rtdyld. Relocations between the object modules are properly resolved, as in the following trivial example: $ cat t.c int foo(); int main() { return foo(); } $ cat foo.c int foo() { return 65; } $ clang -c t.c -fno-asynchronous-unwind-tables $ clang -c foo.c -fno-asynchronous-unwind-tables $ llvm-rtdyld t.o foo.o ; echo $? loaded '_main' at: 0x10015c000 65 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129448 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-rtdyld/llvm-rtdyld.cpp | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'tools/llvm-rtdyld') diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp index ee398e7..ec9d652 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); } -- cgit v1.1