summaryrefslogtreecommitdiff
path: root/tools/llvm-rtdyld
diff options
context:
space:
mode:
authorAndrew Kaylor <andrew.kaylor@intel.com>2013-01-25 22:50:58 +0000
committerAndrew Kaylor <andrew.kaylor@intel.com>2013-01-25 22:50:58 +0000
commitee7c0d2f931590ccdc53a14b1839e11bb29fc96e (patch)
tree691f74c6f15436cdeacf8fa67089c34071a00460 /tools/llvm-rtdyld
parentc73b7f702258b844dc2702fd9d79d8a8706460a7 (diff)
downloadllvm-ee7c0d2f931590ccdc53a14b1839e11bb29fc96e.tar.gz
llvm-ee7c0d2f931590ccdc53a14b1839e11bb29fc96e.tar.bz2
llvm-ee7c0d2f931590ccdc53a14b1839e11bb29fc96e.tar.xz
Add support for applying in-memory relocations to the .debug_line section and, in the case of ELF files, using symbol addresses when available for relocations to the .debug_info section. Also extending the llvm-rtdyld tool to add the ability to dump line number information for testing purposes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173517 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-rtdyld')
-rw-r--r--tools/llvm-rtdyld/CMakeLists.txt2
-rw-r--r--tools/llvm-rtdyld/Makefile2
-rw-r--r--tools/llvm-rtdyld/llvm-rtdyld.cpp62
3 files changed, 63 insertions, 3 deletions
diff --git a/tools/llvm-rtdyld/CMakeLists.txt b/tools/llvm-rtdyld/CMakeLists.txt
index 17e2c3e2d5..8d161d366d 100644
--- a/tools/llvm-rtdyld/CMakeLists.txt
+++ b/tools/llvm-rtdyld/CMakeLists.txt
@@ -1,4 +1,4 @@
-set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support MC object RuntimeDyld JIT)
+set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support MC object RuntimeDyld JIT debuginfo)
add_llvm_tool(llvm-rtdyld
llvm-rtdyld.cpp
diff --git a/tools/llvm-rtdyld/Makefile b/tools/llvm-rtdyld/Makefile
index 30fbee0979..fabdd683a9 100644
--- a/tools/llvm-rtdyld/Makefile
+++ b/tools/llvm-rtdyld/Makefile
@@ -9,7 +9,7 @@
LEVEL := ../..
TOOLNAME := llvm-rtdyld
-LINK_COMPONENTS := all-targets support MC object RuntimeDyld JIT
+LINK_COMPONENTS := all-targets support MC object RuntimeDyld JIT debuginfo
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS := 1
diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp
index ec63c9b56c..8b71a4f364 100644
--- a/tools/llvm-rtdyld/llvm-rtdyld.cpp
+++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp
@@ -13,6 +13,7 @@
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/DebugInfo/DIContext.h"
#include "llvm/ExecutionEngine/ObjectBuffer.h"
#include "llvm/ExecutionEngine/ObjectImage.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
@@ -31,7 +32,8 @@ InputFileList(cl::Positional, cl::ZeroOrMore,
cl::desc("<input file>"));
enum ActionType {
- AC_Execute
+ AC_Execute,
+ AC_PrintLineInfo
};
static cl::opt<ActionType>
@@ -39,6 +41,8 @@ Action(cl::desc("Action to perform:"),
cl::init(AC_Execute),
cl::values(clEnumValN(AC_Execute, "execute",
"Load, link, and execute the inputs."),
+ clEnumValN(AC_PrintLineInfo, "printline",
+ "Load, link, and print line information for each function."),
clEnumValEnd));
static cl::opt<std::string>
@@ -114,6 +118,60 @@ static int Error(const Twine &Msg) {
/* *** */
+static int printLineInfoForInput() {
+ // 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) {
+ // Instantiate a dynamic linker.
+ TrivialMemoryManager *MemMgr = new TrivialMemoryManager;
+ RuntimeDyld Dyld(MemMgr);
+
+ // Load the input memory buffer.
+ OwningPtr<MemoryBuffer> InputBuffer;
+ OwningPtr<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())));
+ if (!LoadedObject) {
+ return Error(Dyld.getErrorString());
+ }
+
+ // Resolve all the relocations we can.
+ Dyld.resolveRelocations();
+
+ OwningPtr<DIContext> Context(DIContext::getDWARFContext(LoadedObject->getObjectFile()));
+
+ // Use symbol info to iterate functions in the object.
+ error_code ec;
+ for (object::symbol_iterator I = LoadedObject->begin_symbols(),
+ E = LoadedObject->end_symbols();
+ I != E && !ec;
+ I.increment(ec)) {
+ object::SymbolRef::Type SymType;
+ if (I->getType(SymType)) continue;
+ if (SymType == object::SymbolRef::ST_Function) {
+ StringRef Name;
+ uint64_t Addr;
+ uint64_t Size;
+ if (I->getName(Name)) continue;
+ if (I->getAddress(Addr)) continue;
+ if (I->getSize(Size)) continue;
+
+ outs() << "Function: " << Name << ", Size = " << Size << "\n";
+
+ DILineInfo Result = Context->getLineInfoForAddress(Addr);
+ outs() << " Line info:" << Result.getFileName() << ", line:" << Result.getLine() << "\n";
+ }
+ }
+ }
+
+ return 0;
+}
+
static int executeInput() {
// Instantiate a dynamic linker.
TrivialMemoryManager *MemMgr = new TrivialMemoryManager;
@@ -180,5 +238,7 @@ int main(int argc, char **argv) {
switch (Action) {
case AC_Execute:
return executeInput();
+ case AC_PrintLineInfo:
+ return printLineInfoForInput();
}
}