diff options
author | Jim Grosbach <grosbach@apple.com> | 2011-04-13 15:49:40 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2011-04-13 15:49:40 +0000 |
commit | 4f9f41f2f9772ecd6a57800fcc8de8ec2734f33c (patch) | |
tree | b289e5b4f94ceee90625b6754b54d1bc4378a0a5 /tools/llvm-rtdyld | |
parent | 0d9874b48d747298dcea7e4e6385b511c04a7842 (diff) | |
download | llvm-4f9f41f2f9772ecd6a57800fcc8de8ec2734f33c.tar.gz llvm-4f9f41f2f9772ecd6a57800fcc8de8ec2734f33c.tar.bz2 llvm-4f9f41f2f9772ecd6a57800fcc8de8ec2734f33c.tar.xz |
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
Diffstat (limited to 'tools/llvm-rtdyld')
-rw-r--r-- | tools/llvm-rtdyld/llvm-rtdyld.cpp | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp index ee398e7b4c..ec9d6526ec 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<std::string> -InputFile(cl::Positional, cl::desc("<input file>"), cl::init("-")); +static cl::list<std::string> +InputFileList(cl::Positional, cl::ZeroOrMore, + cl::desc("<input file>")); enum ActionType { AC_Execute @@ -82,22 +83,31 @@ static int Error(const Twine &Msg) { /* *** */ static int executeInput() { - // Load the input memory buffer. - OwningPtr<MemoryBuffer> 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<MemoryBuffer> 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); } |