xref: /freebsd-src/contrib/llvm-project/llvm/tools/llvm-readobj/StackMapPrinter.h (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===-------- StackMapPrinter.h - Pretty-print stackmaps --------*- C++ -*-===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric 
9*0b57cec5SDimitry Andric #ifndef LLVM_TOOLS_LLVM_READOBJ_STACKMAPPRINTER_H
10*0b57cec5SDimitry Andric #define LLVM_TOOLS_LLVM_READOBJ_STACKMAPPRINTER_H
11*0b57cec5SDimitry Andric 
12*0b57cec5SDimitry Andric #include "llvm/Object/StackMapParser.h"
13*0b57cec5SDimitry Andric #include "llvm/Support/ScopedPrinter.h"
14*0b57cec5SDimitry Andric 
15*0b57cec5SDimitry Andric namespace llvm {
16*0b57cec5SDimitry Andric 
17*0b57cec5SDimitry Andric // Pretty print a stackmap to the given ostream.
18*0b57cec5SDimitry Andric template <typename StackMapParserT>
prettyPrintStackMap(ScopedPrinter & W,const StackMapParserT & SMP)19*0b57cec5SDimitry Andric void prettyPrintStackMap(ScopedPrinter &W, const StackMapParserT &SMP) {
20*0b57cec5SDimitry Andric 
21*0b57cec5SDimitry Andric   W.printNumber("LLVM StackMap Version",  SMP.getVersion());
22*0b57cec5SDimitry Andric   W.printNumber("Num Functions", SMP.getNumFunctions());
23*0b57cec5SDimitry Andric 
24*0b57cec5SDimitry Andric   // Functions:
25*0b57cec5SDimitry Andric   for (const auto &F : SMP.functions())
26*0b57cec5SDimitry Andric     W.startLine() << "  Function address: " << F.getFunctionAddress()
27*0b57cec5SDimitry Andric        << ", stack size: " << F.getStackSize()
28*0b57cec5SDimitry Andric        << ", callsite record count: " << F.getRecordCount() << "\n";
29*0b57cec5SDimitry Andric 
30*0b57cec5SDimitry Andric   // Constants:
31*0b57cec5SDimitry Andric   W.printNumber("Num Constants", SMP.getNumConstants());
32*0b57cec5SDimitry Andric   unsigned ConstantIndex = 0;
33*0b57cec5SDimitry Andric   for (const auto &C : SMP.constants())
34*0b57cec5SDimitry Andric     W.startLine() << "  #" << ++ConstantIndex << ": " << C.getValue() << "\n";
35*0b57cec5SDimitry Andric 
36*0b57cec5SDimitry Andric   // Records:
37*0b57cec5SDimitry Andric   W.printNumber("Num Records", SMP.getNumRecords());
38*0b57cec5SDimitry Andric   for (const auto &R : SMP.records()) {
39*0b57cec5SDimitry Andric     W.startLine() << "  Record ID: " << R.getID()
40*0b57cec5SDimitry Andric                   << ", instruction offset: " << R.getInstructionOffset()
41*0b57cec5SDimitry Andric                   << "\n";
42*0b57cec5SDimitry Andric     W.startLine() << "    " << R.getNumLocations() << " locations:\n";
43*0b57cec5SDimitry Andric 
44*0b57cec5SDimitry Andric     unsigned LocationIndex = 0;
45*0b57cec5SDimitry Andric     for (const auto &Loc : R.locations()) {
46*0b57cec5SDimitry Andric       raw_ostream &OS = W.startLine();
47*0b57cec5SDimitry Andric       OS << "      #" << ++LocationIndex << ": ";
48*0b57cec5SDimitry Andric       switch (Loc.getKind()) {
49*0b57cec5SDimitry Andric       case StackMapParserT::LocationKind::Register:
50*0b57cec5SDimitry Andric         OS << "Register R#" << Loc.getDwarfRegNum();
51*0b57cec5SDimitry Andric         break;
52*0b57cec5SDimitry Andric       case StackMapParserT::LocationKind::Direct:
53*0b57cec5SDimitry Andric         OS << "Direct R#" << Loc.getDwarfRegNum() << " + " << Loc.getOffset();
54*0b57cec5SDimitry Andric         break;
55*0b57cec5SDimitry Andric       case StackMapParserT::LocationKind::Indirect:
56*0b57cec5SDimitry Andric         OS << "Indirect [R#" << Loc.getDwarfRegNum() << " + " << Loc.getOffset()
57*0b57cec5SDimitry Andric            << "]";
58*0b57cec5SDimitry Andric         break;
59*0b57cec5SDimitry Andric       case StackMapParserT::LocationKind::Constant:
60*0b57cec5SDimitry Andric         OS << "Constant " << Loc.getSmallConstant();
61*0b57cec5SDimitry Andric         break;
62*0b57cec5SDimitry Andric       case StackMapParserT::LocationKind::ConstantIndex:
63*0b57cec5SDimitry Andric         OS << "ConstantIndex #" << Loc.getConstantIndex() << " ("
64*0b57cec5SDimitry Andric            << SMP.getConstant(Loc.getConstantIndex()).getValue() << ")";
65*0b57cec5SDimitry Andric         break;
66*0b57cec5SDimitry Andric       }
67*0b57cec5SDimitry Andric       OS << ", size: " << Loc.getSizeInBytes() << "\n";
68*0b57cec5SDimitry Andric     }
69*0b57cec5SDimitry Andric 
70*0b57cec5SDimitry Andric     raw_ostream &OS = W.startLine();
71*0b57cec5SDimitry Andric     OS << "    " << R.getNumLiveOuts() << " live-outs: [ ";
72*0b57cec5SDimitry Andric     for (const auto &LO : R.liveouts())
73*0b57cec5SDimitry Andric       OS << "R#" << LO.getDwarfRegNum() << " ("
74*0b57cec5SDimitry Andric          << LO.getSizeInBytes() << "-bytes) ";
75*0b57cec5SDimitry Andric     OS << "]\n";
76*0b57cec5SDimitry Andric   }
77*0b57cec5SDimitry Andric }
78*0b57cec5SDimitry Andric 
79*0b57cec5SDimitry Andric }
80*0b57cec5SDimitry Andric 
81*0b57cec5SDimitry Andric #endif
82