diff options
Diffstat (limited to 'contrib/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp')
-rw-r--r-- | contrib/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp | 90 |
1 files changed, 67 insertions, 23 deletions
diff --git a/contrib/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp b/contrib/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp index 5b6f301..e87f1e2 100644 --- a/contrib/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp +++ b/contrib/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -13,6 +13,8 @@ #include "llvm/ADT/StringMap.h" #include "llvm/DebugInfo/DIContext.h" +#include "llvm/DebugInfo/DWARF/DWARFContext.h" +#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/ExecutionEngine/RuntimeDyldChecker.h" #include "llvm/MC/MCAsmInfo.h" @@ -21,6 +23,7 @@ #include "llvm/MC/MCInstPrinter.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Object/MachO.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/DynamicLibrary.h" @@ -45,6 +48,7 @@ InputFileList(cl::Positional, cl::ZeroOrMore, enum ActionType { AC_Execute, AC_PrintLineInfo, + AC_PrintDebugLineInfo, AC_Verify }; @@ -55,6 +59,8 @@ Action(cl::desc("Action to perform:"), "Load, link, and execute the inputs."), clEnumValN(AC_PrintLineInfo, "printline", "Load, link, and print line information for each function."), + clEnumValN(AC_PrintDebugLineInfo, "printdebugline", + "Load, link, and print line information for each function using the debug object"), clEnumValN(AC_Verify, "verify", "Load, link and verify the resulting memory image."), clEnumValEnd)); @@ -186,7 +192,9 @@ static void loadDylibs() { /* *** */ -static int printLineInfoForInput() { +static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) { + assert(LoadObjects || !UseDebugObj); + // Load any dylibs requested on the command line. loadDylibs(); @@ -196,7 +204,7 @@ static int printLineInfoForInput() { for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) { // Instantiate a dynamic linker. TrivialMemoryManager MemMgr; - RuntimeDyld Dyld(&MemMgr); + RuntimeDyld Dyld(MemMgr, MemMgr); // Load the input memory buffer. @@ -213,24 +221,32 @@ static int printLineInfoForInput() { ObjectFile &Obj = **MaybeObj; - // Load the object file - std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo = - Dyld.loadObject(Obj); + OwningBinary<ObjectFile> DebugObj; + std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo = nullptr; + ObjectFile *SymbolObj = &Obj; + if (LoadObjects) { + // Load the object file + LoadedObjInfo = + Dyld.loadObject(Obj); - if (Dyld.hasError()) - return Error(Dyld.getErrorString()); + if (Dyld.hasError()) + return Error(Dyld.getErrorString()); - // Resolve all the relocations we can. - Dyld.resolveRelocations(); + // Resolve all the relocations we can. + Dyld.resolveRelocations(); - OwningBinary<ObjectFile> DebugObj = LoadedObjInfo->getObjectForDebug(Obj); + if (UseDebugObj) { + DebugObj = LoadedObjInfo->getObjectForDebug(Obj); + SymbolObj = DebugObj.getBinary(); + } + } std::unique_ptr<DIContext> Context( - DIContext::getDWARFContext(*DebugObj.getBinary())); + new DWARFContextInMemory(*SymbolObj,LoadedObjInfo.get())); // Use symbol info to iterate functions in the object. - for (object::symbol_iterator I = DebugObj.getBinary()->symbol_begin(), - E = DebugObj.getBinary()->symbol_end(); + for (object::symbol_iterator I = SymbolObj->symbol_begin(), + E = SymbolObj->symbol_end(); I != E; ++I) { object::SymbolRef::Type SymType; if (I->getType(SymType)) continue; @@ -242,7 +258,21 @@ static int printLineInfoForInput() { if (I->getAddress(Addr)) continue; if (I->getSize(Size)) continue; - outs() << "Function: " << Name << ", Size = " << Size << "\n"; + // If we're not using the debug object, compute the address of the + // symbol in memory (rather than that in the unrelocated object file) + // and use that to query the DWARFContext. + if (!UseDebugObj && LoadObjects) { + object::section_iterator Sec(SymbolObj->section_end()); + I->getSection(Sec); + StringRef SecName; + Sec->getName(SecName); + uint64_t SectionLoadAddress = + LoadedObjInfo->getSectionLoadAddress(SecName); + if (SectionLoadAddress != 0) + Addr += SectionLoadAddress - Sec->getAddress(); + } + + outs() << "Function: " << Name << ", Size = " << Size << ", Addr = " << Addr << "\n"; DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size); DILineInfoTable::iterator Begin = Lines.begin(); @@ -264,7 +294,12 @@ static int executeInput() { // Instantiate a dynamic linker. TrivialMemoryManager MemMgr; - RuntimeDyld Dyld(&MemMgr); + RuntimeDyld Dyld(MemMgr, MemMgr); + + // FIXME: Preserve buffers until resolveRelocations time to work around a bug + // in RuntimeDyldELF. + // This fixme should be fixed ASAP. This is a very brittle workaround. + std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers; // If we don't have any input files, read from stdin. if (!InputFileList.size()) @@ -282,6 +317,7 @@ static int executeInput() { return Error("unable to create object file: '" + EC.message() + "'"); ObjectFile &Obj = **MaybeObj; + InputBuffers.push_back(std::move(*InputBuffer)); // Load the object file Dyld.loadObject(Obj); @@ -298,7 +334,7 @@ static int executeInput() { // FIXME: Error out if there are unresolved relocations. // Get the address of the entry point (_main by default). - void *MainAddress = Dyld.getSymbolAddress(EntryPoint); + void *MainAddress = Dyld.getSymbolLocalAddress(EntryPoint); if (!MainAddress) return Error("no definition for '" + EntryPoint + "'"); @@ -339,7 +375,7 @@ static int checkAllExpressions(RuntimeDyldChecker &Checker) { return 0; } -std::map<void*, uint64_t> +static std::map<void *, uint64_t> applySpecificSectionMappings(RuntimeDyldChecker &Checker) { std::map<void*, uint64_t> SpecificMappings; @@ -397,9 +433,9 @@ applySpecificSectionMappings(RuntimeDyldChecker &Checker) { // Defaults to zero. Set to something big // (e.g. 1 << 32) to stress-test stubs, GOTs, etc. // -void remapSections(const llvm::Triple &TargetTriple, - const TrivialMemoryManager &MemMgr, - RuntimeDyldChecker &Checker) { +static void remapSections(const llvm::Triple &TargetTriple, + const TrivialMemoryManager &MemMgr, + RuntimeDyldChecker &Checker) { // Set up a work list (section addr/size pairs). typedef std::list<std::pair<void*, uint64_t>> WorklistT; @@ -506,18 +542,23 @@ static int linkAndVerify() { std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo()); std::unique_ptr<MCInstPrinter> InstPrinter( - TheTarget->createMCInstPrinter(0, *MAI, *MII, *MRI, *STI)); + TheTarget->createMCInstPrinter(Triple(TripleName), 0, *MAI, *MII, *MRI)); // Load any dylibs requested on the command line. loadDylibs(); // Instantiate a dynamic linker. TrivialMemoryManager MemMgr; - RuntimeDyld Dyld(&MemMgr); + RuntimeDyld Dyld(MemMgr, MemMgr); Dyld.setProcessAllSections(true); RuntimeDyldChecker Checker(Dyld, Disassembler.get(), InstPrinter.get(), llvm::dbgs()); + // FIXME: Preserve buffers until resolveRelocations time to work around a bug + // in RuntimeDyldELF. + // This fixme should be fixed ASAP. This is a very brittle workaround. + std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers; + // If we don't have any input files, read from stdin. if (!InputFileList.size()) InputFileList.push_back("-"); @@ -536,6 +577,7 @@ static int linkAndVerify() { return Error("unable to create object file: '" + EC.message() + "'"); ObjectFile &Obj = **MaybeObj; + InputBuffers.push_back(std::move(*InputBuffer)); // Load the object file Dyld.loadObject(Obj); @@ -579,8 +621,10 @@ int main(int argc, char **argv) { switch (Action) { case AC_Execute: return executeInput(); + case AC_PrintDebugLineInfo: + return printLineInfoForInput(true,true); case AC_PrintLineInfo: - return printLineInfoForInput(); + return printLineInfoForInput(true,false); case AC_Verify: return linkAndVerify(); } |