From 9a138393ff9e1df0332154e23f7e20ec3dcb14fc Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Sun, 21 Apr 2019 20:34:19 +0000 Subject: [PATCH] [JITLink] Add an option to dump relocated section content. The -dump-relocated-section-content option will dump the contents of each section after relocations are applied, and before any checks are run or code executed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358863 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-jitlink/llvm-jitlink.cpp | 85 ++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 3 deletions(-) diff --git a/tools/llvm-jitlink/llvm-jitlink.cpp b/tools/llvm-jitlink/llvm-jitlink.cpp index 9ea26128991..a08c707df13 100644 --- a/tools/llvm-jitlink/llvm-jitlink.cpp +++ b/tools/llvm-jitlink/llvm-jitlink.cpp @@ -87,9 +87,14 @@ static cl::opt ShowAtomGraph( cl::init(false)); static cl::opt ShowSizes( - "show-sizes", - cl::desc("Show sizes: pre- and post-dead stripping, and allocations"), - cl::init(false)); + "show-sizes", + cl::desc("Show sizes pre- and post-dead stripping, and allocations"), + cl::init(false)); + +static cl::opt ShowRelocatedSectionContents( + "show-relocated-section-contents", + cl::desc("show section contents after fixups have been applied"), + cl::init(false)); ExitOnError ExitOnErr; @@ -139,6 +144,74 @@ static uint64_t computeTotalAtomSizes(AtomGraph &G) { return TotalSize; } +static void dumpSectionContents(raw_ostream &OS, AtomGraph &G) { + constexpr JITTargetAddress DumpWidth = 16; + static_assert(isPowerOf2_64(DumpWidth), "DumpWidth must be a power of two"); + + // Put sections in address order. + std::vector
Sections; + for (auto &S : G.sections()) + Sections.push_back(&S); + + std::sort(Sections.begin(), Sections.end(), + [](const Section *LHS, const Section *RHS) { + if (LHS->atoms_empty() && RHS->atoms_empty()) + return false; + if (LHS->atoms_empty()) + return false; + if (RHS->atoms_empty()) + return true; + return (*LHS->atoms().begin())->getAddress() < + (*RHS->atoms().begin())->getAddress(); + }); + + for (auto *S : Sections) { + OS << S->getName() << " content:"; + if (S->atoms_empty()) { + OS << "\n section empty\n"; + continue; + } + + // Sort atoms into order, then render. + std::vector Atoms(S->atoms().begin(), S->atoms().end()); + std::sort(Atoms.begin(), Atoms.end(), + [](const DefinedAtom *LHS, const DefinedAtom *RHS) { + return LHS->getAddress() < RHS->getAddress(); + }); + + JITTargetAddress NextAddr = Atoms.front()->getAddress() & ~(DumpWidth - 1); + for (auto *DA : Atoms) { + bool IsZeroFill = DA->isZeroFill(); + JITTargetAddress AtomStart = DA->getAddress(); + JITTargetAddress AtomSize = + IsZeroFill ? DA->getZeroFillSize() : DA->getContent().size(); + JITTargetAddress AtomEnd = AtomStart + AtomSize; + const uint8_t *AtomData = + IsZeroFill ? nullptr : DA->getContent().bytes_begin(); + + // Pad any space before the atom starts. + while (NextAddr != AtomStart) { + if (NextAddr % DumpWidth == 0) + OS << formatv("\n{0:x16}:", NextAddr); + OS << " "; + ++NextAddr; + } + + // Render the atom content. + while (NextAddr != AtomEnd) { + if (NextAddr % DumpWidth == 0) + OS << formatv("\n{0:x16}:", NextAddr); + if (IsZeroFill) + OS << " 00"; + else + OS << formatv(" {0:x-2}", AtomData[NextAddr - AtomStart]); + ++NextAddr; + } + } + OS << "\n"; + } +} + Session::Session(Triple TT) : ObjLayer(ES, MemMgr, ObjectLinkingLayer::NotifyLoadedFunction(), ObjectLinkingLayer::NotifyEmittedFunction(), @@ -181,6 +254,12 @@ void Session::modifyPassConfig(const Triple &FTT, }); } + if (ShowRelocatedSectionContents) + PassConfig.PostFixupPasses.push_back([](AtomGraph &G) -> Error { + outs() << "Relocated section contents for " << G.getName() << ":\n"; + dumpSectionContents(outs(), G); + return Error::success(); + }); } Expected Session::findFileInfo(StringRef FileName) { -- 2.50.1