mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-15 21:24:00 +00:00
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:
@ -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();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user