summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-readobj
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-readobj')
-rw-r--r--llvm/tools/llvm-readobj/COFFDumper.cpp32
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp25
-rw-r--r--llvm/tools/llvm-readobj/MachODumper.cpp31
-rw-r--r--llvm/tools/llvm-readobj/ObjDumper.h2
-rw-r--r--llvm/tools/llvm-readobj/StackMapPrinter.h80
-rw-r--r--llvm/tools/llvm-readobj/llvm-readobj.cpp9
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;
OpenPOWER on IntegriCloud