diff options
Diffstat (limited to 'llvm/tools/llvm-readobj')
-rw-r--r-- | llvm/tools/llvm-readobj/COFFDumper.cpp | 32 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 25 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/MachODumper.cpp | 31 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/ObjDumper.h | 2 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/StackMapPrinter.h | 80 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/llvm-readobj.cpp | 9 |
6 files changed, 178 insertions, 1 deletions
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp index 4a1d5da30e6..0041c7ef6a9 100644 --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -16,6 +16,7 @@ #include "ARMWinEHPrinter.h" #include "Error.h" #include "ObjDumper.h" +#include "StackMapPrinter.h" #include "StreamWriter.h" #include "Win64EHDumper.h" #include "llvm/ADT/DenseMap.h" @@ -60,7 +61,7 @@ public: void printCOFFExports() override; void printCOFFDirectives() override; void printCOFFBaseReloc() override; - + void printStackMap() const override; private: void printSymbol(const SymbolRef &Sym); void printRelocation(const SectionRef &Section, const RelocationRef &Reloc); @@ -1140,3 +1141,32 @@ void COFFDumper::printCOFFBaseReloc() { W.printHex("Address", RVA); } } + +void COFFDumper::printStackMap() const { + object::SectionRef StackMapSection; + for (auto Sec : Obj->sections()) { + StringRef Name; + Sec.getName(Name); + if (Name == ".llvm_stackmaps") { + StackMapSection = Sec; + break; + } + } + + if (StackMapSection == object::SectionRef()) + return; + + StringRef StackMapContents; + StackMapSection.getContents(StackMapContents); + ArrayRef<uint8_t> StackMapContentsArray( + reinterpret_cast<const uint8_t*>(StackMapContents.data()), + StackMapContents.size()); + + if (Obj->isLittleEndian()) + prettyPrintStackMap( + llvm::outs(), + StackMapV1Parser<support::little>(StackMapContentsArray)); + else + prettyPrintStackMap(llvm::outs(), + StackMapV1Parser<support::big>(StackMapContentsArray)); +} diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 630f0ee5fb8..4efd8cb07ea 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -17,6 +17,7 @@ #include "ARMEHABIPrinter.h" #include "Error.h" #include "ObjDumper.h" +#include "StackMapPrinter.h" #include "StreamWriter.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallString.h" @@ -61,6 +62,8 @@ public: void printMipsABIFlags() override; void printMipsReginfo() override; + void printStackMap() const override; + private: typedef ELFFile<ELFT> ELFO; typedef typename ELFO::Elf_Shdr Elf_Shdr; @@ -1494,3 +1497,25 @@ template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() { W.printHex("Co-Proc Mask2", Reginfo->ri_cprmask[2]); W.printHex("Co-Proc Mask3", Reginfo->ri_cprmask[3]); } + +template <class ELFT> void ELFDumper<ELFT>::printStackMap() const { + const typename ELFFile<ELFT>::Elf_Shdr *StackMapSection = nullptr; + for (const auto &Sec : Obj->sections()) { + ErrorOr<StringRef> Name = Obj->getSectionName(&Sec); + if (*Name == ".llvm_stackmaps") { + StackMapSection = &Sec; + break; + } + } + + if (!StackMapSection) + return; + + StringRef StackMapContents; + ErrorOr<ArrayRef<uint8_t>> StackMapContentsArray = + Obj->getSectionContents(StackMapSection); + + prettyPrintStackMap( + llvm::outs(), + StackMapV1Parser<ELFT::TargetEndianness>(*StackMapContentsArray)); +} diff --git a/llvm/tools/llvm-readobj/MachODumper.cpp b/llvm/tools/llvm-readobj/MachODumper.cpp index aeb563a25ff..6666870825f 100644 --- a/llvm/tools/llvm-readobj/MachODumper.cpp +++ b/llvm/tools/llvm-readobj/MachODumper.cpp @@ -14,6 +14,7 @@ #include "llvm-readobj.h" #include "Error.h" #include "ObjDumper.h" +#include "StackMapPrinter.h" #include "StreamWriter.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" @@ -37,6 +38,7 @@ public: void printSymbols() override; void printDynamicSymbols() override; void printUnwindInfo() override; + void printStackMap() const override; private: template<class MachHeader> @@ -573,3 +575,32 @@ void MachODumper::printSymbol(const SymbolRef &Symbol) { void MachODumper::printUnwindInfo() { W.startLine() << "UnwindInfo not implemented.\n"; } + +void MachODumper::printStackMap() const { + object::SectionRef StackMapSection; + for (auto Sec : Obj->sections()) { + StringRef Name; + Sec.getName(Name); + if (Name == "__llvm_stackmaps") { + StackMapSection = Sec; + break; + } + } + + if (StackMapSection == object::SectionRef()) + return; + + StringRef StackMapContents; + StackMapSection.getContents(StackMapContents); + ArrayRef<uint8_t> StackMapContentsArray( + reinterpret_cast<const uint8_t*>(StackMapContents.data()), + StackMapContents.size()); + + if (Obj->isLittleEndian()) + prettyPrintStackMap( + llvm::outs(), + StackMapV1Parser<support::little>(StackMapContentsArray)); + else + prettyPrintStackMap(llvm::outs(), + StackMapV1Parser<support::big>(StackMapContentsArray)); +} diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h index cfca850150f..27e15b256cc 100644 --- a/llvm/tools/llvm-readobj/ObjDumper.h +++ b/llvm/tools/llvm-readobj/ObjDumper.h @@ -52,6 +52,8 @@ public: virtual void printCOFFDirectives() { } virtual void printCOFFBaseReloc() { } + virtual void printStackMap() const = 0; + protected: StreamWriter& W; }; diff --git a/llvm/tools/llvm-readobj/StackMapPrinter.h b/llvm/tools/llvm-readobj/StackMapPrinter.h new file mode 100644 index 00000000000..92645bcf917 --- /dev/null +++ b/llvm/tools/llvm-readobj/StackMapPrinter.h @@ -0,0 +1,80 @@ +//===-------- StackMapPrinter.h - Pretty-print stackmaps --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVM_READOBJ_STACKMAPPRINTER_H +#define LLVM_TOOLS_LLVM_READOBJ_STACKMAPPRINTER_H + +#include "llvm/Object/StackMapParser.h" + +namespace llvm { + +// Pretty print a stackmap to the given ostream. +template <typename OStreamT, typename StackMapParserT> +void prettyPrintStackMap(OStreamT &OS, const StackMapParserT &SMP) { + + OS << "LLVM StackMap Version: " << SMP.getVersion() + << "\nNum Functions: " << SMP.getNumFunctions(); + + // Functions: + for (const auto &F : SMP.functions()) + OS << "\n Function address: " << F.getFunctionAddress() + << ", stack size: " << F.getStackSize(); + + // Constants: + OS << "\nNum Constants: " << SMP.getNumConstants(); + unsigned ConstantIndex = 0; + for (const auto &C : SMP.constants()) + OS << "\n #" << ++ConstantIndex << ": " << C.getValue(); + + // Records: + OS << "\nNum Records: " << SMP.getNumRecords(); + for (const auto &R : SMP.records()) { + OS << "\n Record ID: " << R.getID() + << ", instruction offset: " << R.getInstructionOffset() + << "\n " << R.getNumLocations() << " locations:"; + + unsigned LocationIndex = 0; + for (const auto &Loc : R.locations()) { + OS << "\n #" << ++LocationIndex << ": "; + switch (Loc.getKind()) { + case StackMapParserT::LocationKind::Register: + OS << "Register R#" << Loc.getDwarfRegNum(); + break; + case StackMapParserT::LocationKind::Direct: + OS << "Direct R#" << Loc.getDwarfRegNum() << " + " + << Loc.getOffset(); + break; + case StackMapParserT::LocationKind::Indirect: + OS << "Indirect [R#" << Loc.getDwarfRegNum() << " + " + << Loc.getOffset() << "]"; + break; + case StackMapParserT::LocationKind::Constant: + OS << "Constant " << Loc.getSmallConstant(); + break; + case StackMapParserT::LocationKind::ConstantIndex: + OS << "ConstantIndex #" << Loc.getConstantIndex() << " (" + << SMP.getConstant(Loc.getConstantIndex()).getValue() << ")"; + break; + } + } + + OS << "\n " << R.getNumLiveOuts() << " live-outs: [ "; + for (const auto &LO : R.liveouts()) + OS << "R#" << LO.getDwarfRegNum() << " (" + << LO.getSizeInBytes() << "-bytes) "; + OS << "]\n"; + } + + OS << "\n"; + +} + +} + +#endif diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp index 3a6483a1386..222c1a13600 100644 --- a/llvm/tools/llvm-readobj/llvm-readobj.cpp +++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp @@ -176,6 +176,12 @@ namespace opts { cl::opt<bool> COFFBaseRelocs("coff-basereloc", cl::desc("Display the PE/COFF .reloc section")); + + // -stackmap + cl::opt<bool> + PrintStackMap("stackmap", + cl::desc("Display contents of stackmap section")); + } // namespace opts static int ReturnValue = EXIT_SUCCESS; @@ -316,6 +322,9 @@ static void dumpObject(const ObjectFile *Obj) { Dumper->printCOFFDirectives(); if (opts::COFFBaseRelocs) Dumper->printCOFFBaseReloc(); + + if (opts::PrintStackMap) + Dumper->printStackMap(); } /// @brief Dumps each object file in \a Arc; |