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
This commit is contained in:
Andrew Kaylor
2013-01-25 22:50:58 +00:00
parent c73b7f7022
commit ee7c0d2f93
13 changed files with 137 additions and 11 deletions

View File

@ -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();
}
}