ROSE 0.11.145.272
Unparser/Base.h
1#ifndef ROSE_BinaryAnalysis_Unparser_Base_H
2#define ROSE_BinaryAnalysis_Unparser_Base_H
3#include <featureTests.h>
4#ifdef ROSE_ENABLE_BINARY_ANALYSIS
5
6#include <Rose/BinaryAnalysis/BasicTypes.h>
7#include <Rose/BinaryAnalysis/Partitioner2/BasicTypes.h>
8#include <Rose/BinaryAnalysis/Partitioner2/ControlFlowGraph.h>
9#include <Rose/BinaryAnalysis/Partitioner2/FunctionCallGraph.h>
10#include <Rose/BinaryAnalysis/Reachability.h>
11#include <Rose/BinaryAnalysis/RegisterNames.h>
12#include <Rose/BinaryAnalysis/Unparser/EdgeArrows.h>
13#include <Rose/BinaryAnalysis/Unparser/Settings.h>
14#include <Rose/BitFlags.h>
15#include <Rose/Progress.h>
16
17#include <Sawyer/Map.h>
18#include <Sawyer/Message.h>
19#include <Sawyer/SharedObject.h>
20
21namespace Rose {
22namespace BinaryAnalysis {
23namespace Unparser {
24
26typedef std::map<uint64_t, std::string> LabelMap;
27
30
31// used internally to initialize mlog
32void initDiagnostics();
33
35// Supporting functions
37
42 ROSE_DEPRECATED("not called by anything");
43
45// Margins containing arrows
47
70public:
71
72 // An arrow endpoint from the assembly listing's perspective is either a line describing the source or target of a CFG edge, or
73 // a line corresponding to the first or last instruction from a CFG basic block vertex.
75 public:
76 enum class End {Source, Target};
77 enum class Type {CfgEdge, CfgVertex};
78 End end; // which end of the arrow is this?
79 Type type; // is this endpoint at a CFG edge output line, or an instruction?
80 size_t cfgId; // an CFG edge ID or a CFG vertex ID, depending on type
81 public:
82 CfgEndpoint() = delete;
83 CfgEndpoint(const End end, const Type type, const size_t cfgId)
84 : end(end), type(type), cfgId(cfgId) {}
85 bool operator<(const CfgEndpoint&) const;
86 };
87
88private:
89 CfgEndpoint::Type srcType_;
90 CfgEndpoint::Type tgtType_;
91 std::map<CfgEndpoint, EdgeArrows::EndpointId> cfgToArrow_;
92 std::vector<EdgeArrows::EndpointId> orderedEndpoints_;
93 EdgeArrows::Graph arrowGraph_;
94 EdgeArrows arrows_;
97 EdgeArrows::OutputPart nextPart_;
99public:
100 ~ArrowMargin();
101 ArrowMargin() = delete;
102 ArrowMargin(const ArrowMargin&) = delete;
103 ArrowMargin& operator=(const ArrowMargin&) = delete;
104 ArrowMargin(CfgEndpoint::Type srcEndpointType, CfgEndpoint::Type dstEndpointType);
105
108
112 void reset();
113
119 CfgEndpoint makeCfgEndpoint(CfgEndpoint::End, const Partitioner2::ControlFlowGraph::Edge&);
120 EdgeArrows::EndpointId getEndpoint(CfgEndpoint::End, const Partitioner2::ControlFlowGraph::Edge&);
127
133
136
140 Sawyer::Optional<EdgeArrows::EndpointId> findEndpoint(CfgEndpoint::End, const Partitioner2::ControlFlowGraph::Edge&) const;
141 Sawyer::Optional<EdgeArrows::EndpointId> findEndpoint(CfgEndpoint::End, const Partitioner2::ControlFlowGraph::Vertex&) const;
145 CfgEndpoint::End whichEnd(EdgeArrows::EndpointId) const;
146
151
158 void atPossibleEndpoint(CfgEndpoint::End, const Partitioner2::ControlFlowGraph::Edge&);
159 void atPossibleEndpoint(CfgEndpoint::End, const Partitioner2::ControlFlowGraph::Vertex&);
166 std::string render();
167
169 void debug(std::ostream&, const Partitioner2::PartitionerConstPtr&) const;
170};
171
173// Output style
175
178 std::vector<Style> stack_;
179 Style current_;
180 Color::Colorization colorization_;
181
182public:
183 StyleStack() {}
184
188 Color::Colorization colorization() const { return colorization_; }
189 void colorization(const Color::Colorization c) { colorization_ = c; }
195 size_t push(const Style&);
196
200 void pop();
201
203 void popTo(size_t);
204
206 void reset();
207
209 size_t size() const;
210
216 const Style& current() const;
217
218private:
219 void merge(const Style &style); // merge style into current_
220 void mergeAll(); // recalculate current_ based on stack_
221};
222
225 StyleStack &stack_;
226 size_t n_;
227 Style current_;
228 Style previous_;
229public:
234 StyleGuard(StyleStack &stack, const Style &style)
235 : stack_(stack) {
236 previous_ = stack_.current();
237 n_ = stack_.push(style);
238 current_ = stack_.current();
239 }
240
241 StyleGuard(StyleStack &stack, const Style &first, const Style &second)
242 : stack_(stack) {
243 previous_ = stack_.current();
244 n_ = stack_.push(first);
245 stack_.push(second);
246 current_ = stack_.current();
247 }
248
249 ~StyleGuard() {
250 stack_.popTo(n_);
251 }
252
254 std::string render() const;
255
257 std::string restore() const;
258
260 const Style& current() const {
261 return current_;
262 }
263
265 const Style& previous() const {
266 return previous_;
267 }
268};
269
271// State of the unparser (the unparser itself is const during unparsing)
273
278class State {
279public:
282private:
285 Partitioner2::FunctionPtr currentFunction_;
286 Partitioner2::BasicBlockPtr previousBasicBlock_, currentBasicBlock_, nextBasicBlock_;
287 SgAsmExpression *currentExpression_;
288 std::string nextInsnLabel_;
289 AddrString basicBlockLabels_;
290 RegisterNames registerNames_;
291 const Base &frontUnparser_;
292 std::vector<Reachability::ReasonFlags> cfgVertexReachability_;
293 Sawyer::Container::Map<Reachability::ReasonFlags::Vector, std::string> reachabilityNames_; // map reachability value to name
294 ArrowMargin intraFunctionCfgArrows_; // arrows for the intra-function control flow graphs
295 ArrowMargin intraFunctionBlockArrows_; // user-defined intra-function arrows to/from blocks
296 ArrowMargin globalBlockArrows_; // user-defined global arrows to/from blocks
297 StyleStack styleStack_; // styles
298 bool isPostInstruction_ = false; // show extra information appearing after an instruction
299
300public:
302 virtual ~State();
303
306
309
316 const std::vector<Reachability::ReasonFlags> cfgVertexReachability() const;
317 void cfgVertexReachability(const std::vector<Reachability::ReasonFlags>&);
325
338 const ArrowMargin& intraFunctionCfgArrows() const { return intraFunctionCfgArrows_; }
339 ArrowMargin& intraFunctionCfgArrows() { return intraFunctionCfgArrows_; }
355 const ArrowMargin& intraFunctionBlockArrows() const { return intraFunctionBlockArrows_; }
356 ArrowMargin& intraFunctionBlockArrows() { return intraFunctionBlockArrows_; }
367 const ArrowMargin& globalBlockArrows() const { return globalBlockArrows_; }
368 ArrowMargin& globalBlockArrows() { return globalBlockArrows_; }
373
376
380 const StyleStack& styleStack() const { return styleStack_; }
381 StyleStack& styleStack() { return styleStack_; }
398 void reachabilityName(Reachability::Reason value, const std::string &name);
402 Partitioner2::FunctionPtr currentFunction() const;
403 void currentFunction(const Partitioner2::FunctionPtr&);
404
425
426 SgAsmExpression* currentExpression() const;
427 void currentExpression(SgAsmExpression*);
428
429 const std::string& nextInsnLabel() const;
430 void nextInsnLabel(const std::string&);
431
432 const RegisterNames& registerNames() const;
433 void registerNames(const RegisterNames &r);
434
435 const AddrString& basicBlockLabels() const;
436 AddrString& basicBlockLabels();
437
438 bool isPostInstruction() const;
439 void isPostInstruction(bool);
440
442 const Base& frontUnparser() const;
443};
444
446// Base unparser
448
496public:
498
499private:
500 Architecture::BaseConstPtr architecture_; // non-null architecture
501 Ptr nextUnparser_;
502
503protected:
504 explicit Base(const Architecture::BaseConstPtr&);
505 explicit Base(const Ptr &nextUnparser);
506
507public:
508 virtual Ptr copy() const = 0;
509 virtual ~Base();
510
520 virtual const Settings& settings() const = 0;
521 virtual Settings& settings() = 0;
522 void settings(const Settings &s) {
523 settings() = s;
524 }
534 Ptr nextUnparser() const { return nextUnparser_; }
535 void nextUnparser(Ptr next) { nextUnparser_ = next; }
542
550 void operator()(std::ostream&, const Partitioner2::PartitionerConstPtr&) const /*final*/;
551 void operator()(std::ostream&, const Partitioner2::PartitionerConstPtr&, SgAsmInstruction*) const /*final*/;
552 void operator()(std::ostream&, const Partitioner2::PartitionerConstPtr&, SgAsmExpression*) const /*final*/;
553 void operator()(std::ostream&, const Partitioner2::PartitionerConstPtr&, const Partitioner2::BasicBlockPtr&) const /*final*/;
554 void operator()(std::ostream&, const Partitioner2::PartitionerConstPtr&, const Partitioner2::DataBlockPtr&) const /*final*/;
555 void operator()(std::ostream&, const Partitioner2::PartitionerConstPtr&, const Partitioner2::FunctionPtr&) const /*final*/;
556 void operator()(std::ostream&, SgAsmInstruction*) const /*final*/;
564 std::string operator()(const Partitioner2::PartitionerConstPtr&, const Progress::Ptr& = Progress::Ptr()) const /*final*/;
565 std::string operator()(const Partitioner2::PartitionerConstPtr&, SgAsmInstruction*) const /*final*/;
566 std::string operator()(const Partitioner2::PartitionerConstPtr&, SgAsmExpression*) const /*final*/;
567 std::string operator()(const Partitioner2::PartitionerConstPtr&, const Partitioner2::BasicBlockPtr&) const /*final*/;
568 std::string operator()(const Partitioner2::PartitionerConstPtr&, const Partitioner2::DataBlockPtr&) const /*final*/;
569 std::string operator()(const Partitioner2::PartitionerConstPtr&, const Partitioner2::FunctionPtr&) const /*final*/;
570 std::string operator()(SgAsmInstruction*) const /*final*/;
573public:
579 void unparse(std::ostream&, const Partitioner2::PartitionerConstPtr&, const Progress::Ptr& = Progress::Ptr()) const /*final*/;
580 void unparse(std::ostream&, const Partitioner2::PartitionerConstPtr&, SgAsmInstruction*) const /*final*/;
581 void unparse(std::ostream&, const Partitioner2::PartitionerConstPtr&, SgAsmExpression*) const /*final*/;
582 void unparse(std::ostream&, const Partitioner2::PartitionerConstPtr&, const Partitioner2::BasicBlockPtr&) const /*final*/;
583 void unparse(std::ostream&, const Partitioner2::PartitionerConstPtr&, const Partitioner2::DataBlockPtr&) const /*final*/;
584 void unparse(std::ostream&, const Partitioner2::PartitionerConstPtr&, const Partitioner2::FunctionPtr&) const /*final*/;
585 void unparse(std::ostream&, SgAsmInstruction*) const /*final*/;
586 void unparse(std::ostream&, SgAsmExpression*) const /*final*/;
587
588 std::string unparse(const Partitioner2::PartitionerConstPtr&, const Progress::Ptr& = Progress::Ptr()) const /*final*/;
589 std::string unparse(const Partitioner2::PartitionerConstPtr&, SgAsmInstruction*) const /*final*/;
590 std::string unparse(const Partitioner2::PartitionerConstPtr&, SgAsmExpression*) const /*final*/;
591 std::string unparse(const Partitioner2::PartitionerConstPtr&, const Partitioner2::BasicBlockPtr&) const /*final*/;
592 std::string unparse(const Partitioner2::PartitionerConstPtr&, const Partitioner2::DataBlockPtr&) const /*final*/;
593 std::string unparse(const Partitioner2::PartitionerConstPtr&, const Partitioner2::FunctionPtr&) const /*final*/;
594 std::string unparse(SgAsmInstruction*) const /*final*/;
595 std::string unparse(SgAsmExpression*) const /*final*/;
598public:
621 virtual void emitFunction(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
622 virtual void emitFunctionPrologue(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
623 virtual void emitFunctionBody(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
624 virtual void emitFunctionEpilogue(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
625
626 virtual void emitFunctionSourceLocation(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
627 virtual void emitFunctionReasons(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
628 virtual void emitFunctionCallers(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
629 virtual void emitFunctionCallees(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
630 virtual void emitFunctionComment(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
631 virtual void emitFunctionStackDelta(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
632 virtual void emitFunctionCallingConvention(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
633 virtual void emitFunctionNoopAnalysis(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
634 virtual void emitFunctionMayReturn(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
635
636 virtual void emitDataBlockSourceLocation(std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
637 virtual void emitDataBlock(std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
638 virtual void emitDataBlockPrologue(std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
639 virtual void emitDataBlockBody(std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
640 virtual void emitDataBlockEpilogue(std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
641
642 virtual void emitBasicBlock(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
643 virtual void emitBasicBlockPrologue(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
644 virtual void emitBasicBlockBody(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
645 virtual void emitBasicBlockEpilogue(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
646 virtual void emitBasicBlockSeparator(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
647
648 virtual void emitBasicBlockSourceLocation(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
649 virtual void emitBasicBlockComment(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
650 virtual void emitBasicBlockSharing(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
651 virtual void emitBasicBlockPredecessors(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
652 virtual void emitBasicBlockSuccessors(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
653 virtual void emitBasicBlockReachability(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
654
655 virtual void emitInstruction(std::ostream&, SgAsmInstruction*, State&) const;
656 virtual void emitInstructionPrologue(std::ostream&, SgAsmInstruction*, State&) const;
657 virtual void emitInstructionBody(std::ostream&, SgAsmInstruction*, State&) const;
658 virtual void emitInstructionEpilogue(std::ostream&, SgAsmInstruction*, State&) const;
659
660 virtual void emitInstructionAddress(std::ostream&, SgAsmInstruction*, State&) const;
661 virtual void emitInstructionBytes(std::ostream&, SgAsmInstruction*, State&) const;
662 virtual void emitInstructionStackDelta(std::ostream&, SgAsmInstruction*, State&) const;
663 virtual void emitInstructionFrameDelta(std::ostream&, SgAsmInstruction*, State&) const;
664 virtual void emitInstructionMnemonic(std::ostream&, SgAsmInstruction*, State&) const;
665 virtual void emitInstructionOperands(std::ostream&, SgAsmInstruction*, State&) const;
666 virtual void emitInstructionComment(std::ostream&, SgAsmInstruction*, State&) const;
667
668 virtual void emitInstructionSemantics(std::ostream&, SgAsmInstruction*, State&) const;
669
670 virtual void emitOperand(std::ostream&, SgAsmExpression*, State&) const;
671 virtual void emitOperandPrologue(std::ostream&, SgAsmExpression*, State&) const;
672 virtual void emitOperandBody(std::ostream&, SgAsmExpression*, State&) const;
673 virtual void emitOperandEpilogue(std::ostream&, SgAsmExpression*, State&) const;
674
675 virtual void emitExpression(std::ostream&, SgAsmExpression*, State&) const;
676#ifdef ROSE_ENABLE_ASM_AARCH32
677 virtual std::vector<std::string> emitAarch32Coprocessor(std::ostream&, SgAsmAarch32Coprocessor*, State&) const;
678#endif
679#ifdef ROSE_ENABLE_ASM_AARCH64
680 virtual std::vector<std::string> emitAarch64AtOperand(std::ostream&, SgAsmAarch64AtOperand*, State&) const;
681 virtual std::vector<std::string> emitAarch64BarrierOperand(std::ostream&, SgAsmAarch64BarrierOperand*, State&) const;
682 virtual std::vector<std::string> emitAarch64CImmediateOperand(std::ostream&, SgAsmAarch64CImmediateOperand*, State&) const;
683 virtual std::vector<std::string> emitAarch64PrefetchOperand(std::ostream&, SgAsmAarch64PrefetchOperand*, State&) const;
684 virtual std::vector<std::string> emitAarch64PState(std::ostream&, SgAsmAarch64PState*, State&) const;
685 virtual std::vector<std::string> emitAarch64SysMoveOperand(std::ostream&, SgAsmAarch64SysMoveOperand*, State&) const;
686#endif
687 virtual std::vector<std::string> emitBinaryAdd(std::ostream&, SgAsmBinaryAdd*, State&) const;
688 virtual std::vector<std::string> emitBinaryAsr(std::ostream&, SgAsmBinaryAsr*, State&) const;
689 virtual std::vector<std::string> emitBinaryConcat(std::ostream&, SgAsmBinaryConcat*, State&) const;
690 virtual std::vector<std::string> emitBinaryDivide(std::ostream&, SgAsmBinaryDivide*, State&) const;
691 virtual std::vector<std::string> emitBinaryLsl(std::ostream&, SgAsmBinaryLsl*, State&) const;
692 virtual std::vector<std::string> emitBinaryLsr(std::ostream&, SgAsmBinaryLsr*, State&) const;
693 virtual std::vector<std::string> emitBinaryMsl(std::ostream&, SgAsmBinaryMsl*, State&) const;
694 virtual std::vector<std::string> emitBinaryMultiply(std::ostream&, SgAsmBinaryMultiply*, State&) const;
695 virtual std::vector<std::string> emitBinaryMod(std::ostream&, SgAsmBinaryMod*, State&) const;
696 virtual std::vector<std::string> emitBinaryPreupdate(std::ostream&, SgAsmBinaryPreupdate*, State&) const;
697 virtual std::vector<std::string> emitBinaryPostupdate(std::ostream&, SgAsmBinaryPostupdate*, State&) const;
698 virtual std::vector<std::string> emitBinaryRor(std::ostream&, SgAsmBinaryRor*, State&) const;
699 virtual std::vector<std::string> emitBinarySubtract(std::ostream&, SgAsmBinarySubtract*, State&) const;
700 virtual std::vector<std::string> emitByteOrder(std::ostream&, SgAsmByteOrder*, State&) const;
701 virtual std::vector<std::string> emitDirectRegisterExpression(std::ostream&, SgAsmDirectRegisterExpression*, State&) const;
702 virtual std::vector<std::string> emitExprListExp(std::ostream&, SgAsmExprListExp*, State&) const;
703 virtual std::vector<std::string> emitFloatValueExpression(std::ostream&, SgAsmFloatValueExpression*, State&) const;
704 virtual std::vector<std::string> emitIndirectRegisterExpression(std::ostream&, SgAsmIndirectRegisterExpression*, State&) const;
705 virtual std::vector<std::string> emitIntegerValueExpression(std::ostream&, SgAsmIntegerValueExpression*, State&) const;
706 virtual std::vector<std::string> emitMemoryReferenceExpression(std::ostream&, SgAsmMemoryReferenceExpression*, State&) const;
707 virtual std::vector<std::string> emitRegisterNames(std::ostream&, SgAsmRegisterNames*, State&) const;
708 virtual std::vector<std::string> emitRiscOperation(std::ostream&, SgAsmRiscOperation*, State&) const;
709 virtual std::vector<std::string> emitStackExpression(std::ostream&, SgAsmStackExpression*, State&) const;
710 virtual std::vector<std::string> emitUnaryMinus(std::ostream&, SgAsmUnaryMinus*, State&) const;
711 virtual std::vector<std::string> emitUnaryPlus(std::ostream&, SgAsmUnaryPlus*, State&) const;
712 virtual std::vector<std::string> emitUnarySignedExtend(std::ostream&, SgAsmUnarySignedExtend*, State&) const;
713 virtual std::vector<std::string> emitUnaryTruncate(std::ostream&, SgAsmUnaryTruncate*, State&) const;
714 virtual std::vector<std::string> emitUnaryUnsignedExtend(std::ostream&, SgAsmUnaryUnsignedExtend*, State&) const;
715
716 virtual void emitRegister(std::ostream&, RegisterDescriptor, State&) const;
717 virtual std::vector<std::string> emitUnsignedInteger(std::ostream&, const Sawyer::Container::BitVector&, State&) const;
718 virtual std::vector<std::string> emitSignedInteger(std::ostream&, const Sawyer::Container::BitVector&, State&) const;
719 virtual std::vector<std::string> emitInteger(std::ostream&, const Sawyer::Container::BitVector&, State&,
720 bool isSigned) const;
721 virtual bool emitAddress(std::ostream&, Address, State&, bool always=true) const;
722 virtual bool emitAddress(std::ostream&, const Sawyer::Container::BitVector&, State&, bool always=true) const;
723 virtual void emitCommentBlock(std::ostream&, const std::string&, State&, const std::string &prefix = ";;; ") const;
724 virtual void emitTypeName(std::ostream&, SgAsmType*, State&) const;
725
726 virtual void emitLinePrefix(std::ostream&, State&) const;
729 //----- Other overrridable things -----
730public:
736 virtual void initializeState(State&) const;
737
743 virtual void updateIntraFunctionArrows(State&) const;
744
745 //----- Utility functions -----
746public:
748 static std::string leftJustify(const std::string&, size_t nchars);
749
755 static std::string juxtaposeColumns(const std::vector<std::string> &content, const std::vector<size_t> &minWidths,
756 const std::vector<std::pair<std::string, std::string> > &colorEscapes,
757 const std::string &columnSeparator = " ");
758
764 static bool ascendingSourceAddress(Partitioner2::ControlFlowGraph::ConstEdgeIterator a,
765 Partitioner2::ControlFlowGraph::ConstEdgeIterator b);
766
772 static bool ascendingTargetAddress(Partitioner2::ControlFlowGraph::ConstEdgeIterator a,
773 Partitioner2::ControlFlowGraph::ConstEdgeIterator b);
774
779 static std::vector<Partitioner2::ControlFlowGraph::ConstEdgeIterator>
781
786 static std::vector<Partitioner2::ControlFlowGraph::ConstEdgeIterator>
788
790 virtual bool
791 suppressFallThroughEdge(const Partitioner2::ControlFlowGraph::Edge&, const Partitioner2::BasicBlockPtr &src,
792 const Partitioner2::BasicBlockPtr &tgt, State&) const;
793
795 bool
797
800};
801
803// Python API wrappers and functions
805
806#ifdef ROSE_ENABLE_PYTHON_API
807class PythonBase {
808 Base::Ptr base_;
809
810public:
811 PythonBase() {}
812
813 explicit PythonBase(const Base::Ptr &base)
814 : base_(base) {
815 ASSERT_not_null(base);
816 }
817
818 std::string unparse(const Partitioner2::PartitionerConstPtr &p) const {
819 return base_->unparse(p);
820 }
821
822 void print(const Partitioner2::PartitionerConstPtr &p) const {
823 base_->unparse(std::cout, p);
824 }
825};
826#endif
827
828} // namespace
829} // namespace
830} // namespace
831
832#endif
833#endif
Reason
Predefined bit flags for why something is reachable.
Describes (part of) a physical CPU register.
Convert a register descriptor to a name.
State associated with printing arrows in the margin.
void computeLayout()
Compute where arrows go in the margins.
void maybeInsertEndpoint(EdgeArrows::EndpointId)
Insert an arrow endpoint into the ordered list of endpoints.
void maybeInsertArrow(EdgeArrows::EndpointId src, EdgeArrows::EndpointId tgt, size_t arrowId)
Insert an arrow into the graph if it isn't already there.
CfgEndpoint::End whichEnd(EdgeArrows::EndpointId) const
Test whether an endpoint is the source or target of an arrow.
void reset()
Reset the margin arrow state.
bool haveEndpointId(EdgeArrows::EndpointId) const
Test whether we have an endpoint ID.
void atPossibleEndpoint(CfgEndpoint::End, const Partitioner2::ControlFlowGraph::Edge &)
While generating output, indicate what line we're at.
void debug(std::ostream &, const Partitioner2::PartitionerConstPtr &) const
Show some debugging information.
void atPossibleEndpoint(CfgEndpoint::End, const Partitioner2::ControlFlowGraph::Vertex &)
While generating output, indicate what line we're at.
EdgeArrows::EndpointId getEndpoint(CfgEndpoint::End, const Partitioner2::ControlFlowGraph::Edge &)
Get an arrow endpoint.
std::string render()
Destructively render the arrows for a line of output.
CfgEndpoint makeCfgEndpoint(CfgEndpoint::End, const Partitioner2::ControlFlowGraph::Edge &)
Get an arrow endpoint.
Sawyer::Optional< EdgeArrows::EndpointId > findEndpoint(CfgEndpoint::End, const Partitioner2::ControlFlowGraph::Vertex &) const
Test whether we have an endpoint ID for a particular line of output given some info about what's on t...
void arrowStyle(EdgeArrows::ArrowStylePreset, EdgeArrows::ArrowSide)
Set arrow style.
Sawyer::Optional< EdgeArrows::EndpointId > findEndpoint(CfgEndpoint::End, const Partitioner2::ControlFlowGraph::Edge &) const
Test whether we have an endpoint ID for a particular line of output given some info about what's on t...
Abstract base class for unparsers.
virtual void emitFunctionStackDelta(std::ostream &, const Partitioner2::FunctionPtr &, State &) const
Mid-level unparser function.
virtual std::vector< std::string > emitExprListExp(std::ostream &, SgAsmExprListExp *, State &) const
Mid-level unparser function.
virtual std::vector< std::string > emitBinaryPreupdate(std::ostream &, SgAsmBinaryPreupdate *, State &) const
Mid-level unparser function.
virtual Settings & settings()=0
Property: Settings associated with this unparser.
virtual std::vector< std::string > emitBinaryDivide(std::ostream &, SgAsmBinaryDivide *, State &) const
Mid-level unparser function.
virtual void emitInstructionPrologue(std::ostream &, SgAsmInstruction *, State &) const
Mid-level unparser function.
virtual void emitBasicBlockSuccessors(std::ostream &, const Partitioner2::BasicBlockPtr &, State &) const
Mid-level unparser function.
void operator()(std::ostream &, const Partitioner2::PartitionerConstPtr &, SgAsmInstruction *) const
Emit the entity to an output stream.
virtual std::vector< std::string > emitFloatValueExpression(std::ostream &, SgAsmFloatValueExpression *, State &) const
Mid-level unparser function.
virtual std::vector< std::string > emitIntegerValueExpression(std::ostream &, SgAsmIntegerValueExpression *, State &) const
Mid-level unparser function.
virtual void emitFunction(std::ostream &, const Partitioner2::FunctionPtr &, State &) const
Mid-level unparser function.
static bool ascendingSourceAddress(Partitioner2::ControlFlowGraph::ConstEdgeIterator a, Partitioner2::ControlFlowGraph::ConstEdgeIterator b)
Return true if edges are in order by source address.
void operator()(std::ostream &, const Partitioner2::PartitionerConstPtr &, const Partitioner2::BasicBlockPtr &) const
Emit the entity to an output stream.
virtual bool emitAddress(std::ostream &, const Sawyer::Container::BitVector &, State &, bool always=true) const
Mid-level unparser function.
virtual std::vector< std::string > emitInteger(std::ostream &, const Sawyer::Container::BitVector &, State &, bool isSigned) const
Mid-level unparser function.
virtual std::vector< std::string > emitBinaryMod(std::ostream &, SgAsmBinaryMod *, State &) const
Mid-level unparser function.
virtual std::vector< std::string > emitBinaryMultiply(std::ostream &, SgAsmBinaryMultiply *, State &) const
Mid-level unparser function.
void operator()(std::ostream &, const Partitioner2::PartitionerConstPtr &, SgAsmExpression *) const
Emit the entity to an output stream.
virtual std::vector< std::string > emitBinarySubtract(std::ostream &, SgAsmBinarySubtract *, State &) const
Mid-level unparser function.
virtual std::vector< std::string > emitUnaryUnsignedExtend(std::ostream &, SgAsmUnaryUnsignedExtend *, State &) const
Mid-level unparser function.
virtual std::vector< std::string > emitUnaryMinus(std::ostream &, SgAsmUnaryMinus *, State &) const
Mid-level unparser function.
virtual void emitDataBlockPrologue(std::ostream &, const Partitioner2::DataBlockPtr &, State &) const
Mid-level unparser function.
virtual void emitInstructionOperands(std::ostream &, SgAsmInstruction *, State &) const
Mid-level unparser function.
virtual std::vector< std::string > emitBinaryMsl(std::ostream &, SgAsmBinaryMsl *, State &) const
Mid-level unparser function.
virtual void emitInstructionFrameDelta(std::ostream &, SgAsmInstruction *, State &) const
Mid-level unparser function.
virtual void emitFunctionReasons(std::ostream &, const Partitioner2::FunctionPtr &, State &) const
Mid-level unparser function.
virtual void emitTypeName(std::ostream &, SgAsmType *, State &) const
Mid-level unparser function.
void operator()(std::ostream &, const Partitioner2::PartitionerConstPtr &, const Partitioner2::DataBlockPtr &) const
Emit the entity to an output stream.
virtual std::vector< std::string > emitUnaryTruncate(std::ostream &, SgAsmUnaryTruncate *, State &) const
Mid-level unparser function.
virtual void emitFunctionCallingConvention(std::ostream &, const Partitioner2::FunctionPtr &, State &) const
Mid-level unparser function.
virtual std::vector< std::string > emitBinaryLsl(std::ostream &, SgAsmBinaryLsl *, State &) const
Mid-level unparser function.
virtual void emitInstructionBody(std::ostream &, SgAsmInstruction *, State &) const
Mid-level unparser function.
virtual void emitBasicBlockSharing(std::ostream &, const Partitioner2::BasicBlockPtr &, State &) const
Mid-level unparser function.
virtual void initializeState(State &) const
Finish initializing the unparser state.
virtual void emitFunctionPrologue(std::ostream &, const Partitioner2::FunctionPtr &, State &) const
Mid-level unparser function.
virtual void emitDataBlock(std::ostream &, const Partitioner2::DataBlockPtr &, State &) const
Mid-level unparser function.
virtual const Settings & settings() const =0
Property: Settings associated with this unparser.
static bool ascendingTargetAddress(Partitioner2::ControlFlowGraph::ConstEdgeIterator a, Partitioner2::ControlFlowGraph::ConstEdgeIterator b)
Return true if edges are in order by target address.
virtual void emitDataBlockEpilogue(std::ostream &, const Partitioner2::DataBlockPtr &, State &) const
Mid-level unparser function.
virtual void emitInstructionEpilogue(std::ostream &, SgAsmInstruction *, State &) const
Mid-level unparser function.
void operator()(std::ostream &, SgAsmInstruction *) const
Emit the entity to an output stream.
virtual void emitCommentBlock(std::ostream &, const std::string &, State &, const std::string &prefix=";;; ") const
Mid-level unparser function.
virtual std::vector< std::string > emitSignedInteger(std::ostream &, const Sawyer::Container::BitVector &, State &) const
Mid-level unparser function.
void settings(const Settings &s)
Property: Settings associated with this unparser.
virtual void emitDataBlockBody(std::ostream &, const Partitioner2::DataBlockPtr &, State &) const
Mid-level unparser function.
virtual void emitBasicBlockComment(std::ostream &, const Partitioner2::BasicBlockPtr &, State &) const
Mid-level unparser function.
static std::vector< Partitioner2::ControlFlowGraph::ConstEdgeIterator > orderedBlockPredecessors(const Partitioner2::PartitionerConstPtr &, const Partitioner2::BasicBlockPtr &)
Ordered incoming CFG edges.
virtual bool emitAddress(std::ostream &, Address, State &, bool always=true) const
Mid-level unparser function.
virtual void emitInstructionBytes(std::ostream &, SgAsmInstruction *, State &) const
Mid-level unparser function.
virtual void emitOperand(std::ostream &, SgAsmExpression *, State &) const
Mid-level unparser function.
virtual void emitLinePrefix(std::ostream &, State &) const
Mid-level unparser function.
virtual void emitInstructionAddress(std::ostream &, SgAsmInstruction *, State &) const
Mid-level unparser function.
Ptr nextUnparser() const
Property: Next parser in chain.
virtual std::vector< std::string > emitIndirectRegisterExpression(std::ostream &, SgAsmIndirectRegisterExpression *, State &) const
Mid-level unparser function.
void nextUnparser(Ptr next)
Property: Next parser in chain.
virtual void emitBasicBlockPrologue(std::ostream &, const Partitioner2::BasicBlockPtr &, State &) const
Mid-level unparser function.
virtual void emitBasicBlockReachability(std::ostream &, const Partitioner2::BasicBlockPtr &, State &) const
Mid-level unparser function.
void computeGutterArrows(const Partitioner2::FunctionPtr &, State &) const
Compute edge arrows shown in the left margin.
virtual std::vector< std::string > emitUnsignedInteger(std::ostream &, const Sawyer::Container::BitVector &, State &) const
Mid-level unparser function.
virtual bool suppressFallThroughEdge(const Partitioner2::ControlFlowGraph::Edge &, const Partitioner2::BasicBlockPtr &src, const Partitioner2::BasicBlockPtr &tgt, State &) const
Predicate to test whether a CFG edge is a suppressable fallthrough edge.
virtual std::vector< std::string > emitMemoryReferenceExpression(std::ostream &, SgAsmMemoryReferenceExpression *, State &) const
Mid-level unparser function.
virtual void emitOperandEpilogue(std::ostream &, SgAsmExpression *, State &) const
Mid-level unparser function.
virtual void emitFunctionMayReturn(std::ostream &, const Partitioner2::FunctionPtr &, State &) const
Mid-level unparser function.
virtual std::vector< std::string > emitBinaryPostupdate(std::ostream &, SgAsmBinaryPostupdate *, State &) const
Mid-level unparser function.
virtual void emitDataBlockSourceLocation(std::ostream &, const Partitioner2::DataBlockPtr &, State &) const
Mid-level unparser function.
virtual void emitBasicBlockEpilogue(std::ostream &, const Partitioner2::BasicBlockPtr &, State &) const
Mid-level unparser function.
void operator()(std::ostream &, const Partitioner2::PartitionerConstPtr &) const
Emit the entity to an output stream.
virtual void emitInstructionComment(std::ostream &, SgAsmInstruction *, State &) const
Mid-level unparser function.
virtual std::vector< std::string > emitBinaryAsr(std::ostream &, SgAsmBinaryAsr *, State &) const
Mid-level unparser function.
virtual std::vector< std::string > emitRiscOperation(std::ostream &, SgAsmRiscOperation *, State &) const
Mid-level unparser function.
virtual std::vector< std::string > emitBinaryAdd(std::ostream &, SgAsmBinaryAdd *, State &) const
Mid-level unparser function.
std::string operator()(const Partitioner2::PartitionerConstPtr &, const Progress::Ptr &=Progress::Ptr()) const
Emit the entity to a string.
virtual void emitExpression(std::ostream &, SgAsmExpression *, State &) const
Mid-level unparser function.
virtual std::vector< std::string > emitUnarySignedExtend(std::ostream &, SgAsmUnarySignedExtend *, State &) const
Mid-level unparser function.
static std::vector< Partitioner2::ControlFlowGraph::ConstEdgeIterator > orderedBlockSuccessors(const Partitioner2::PartitionerConstPtr &, const Partitioner2::BasicBlockPtr &)
Ordered outgoing CFG edges.
void operator()(std::ostream &, const Partitioner2::PartitionerConstPtr &, const Partitioner2::FunctionPtr &) const
Emit the entity to an output stream.
virtual void emitInstructionStackDelta(std::ostream &, SgAsmInstruction *, State &) const
Mid-level unparser function.
virtual void emitBasicBlock(std::ostream &, const Partitioner2::BasicBlockPtr &, State &) const
Mid-level unparser function.
virtual void emitBasicBlockPredecessors(std::ostream &, const Partitioner2::BasicBlockPtr &, State &) const
Mid-level unparser function.
virtual void emitRegister(std::ostream &, RegisterDescriptor, State &) const
Mid-level unparser function.
virtual void emitBasicBlockSourceLocation(std::ostream &, const Partitioner2::BasicBlockPtr &, State &) const
Mid-level unparser function.
virtual void emitFunctionCallers(std::ostream &, const Partitioner2::FunctionPtr &, State &) const
Mid-level unparser function.
static std::string juxtaposeColumns(const std::vector< std::string > &content, const std::vector< size_t > &minWidths, const std::vector< std::pair< std::string, std::string > > &colorEscapes, const std::string &columnSeparator=" ")
Render a table row.
virtual void emitBasicBlockSeparator(std::ostream &, const Partitioner2::BasicBlockPtr &, State &) const
Mid-level unparser function.
virtual void emitBasicBlockBody(std::ostream &, const Partitioner2::BasicBlockPtr &, State &) const
Mid-level unparser function.
virtual std::vector< std::string > emitBinaryConcat(std::ostream &, SgAsmBinaryConcat *, State &) const
Mid-level unparser function.
void unparse(std::ostream &, const Partitioner2::PartitionerConstPtr &, const Progress::Ptr &=Progress::Ptr()) const
High-level unparsing function.
virtual std::vector< std::string > emitBinaryLsr(std::ostream &, SgAsmBinaryLsr *, State &) const
Mid-level unparser function.
virtual void emitFunctionEpilogue(std::ostream &, const Partitioner2::FunctionPtr &, State &) const
Mid-level unparser function.
virtual void emitInstruction(std::ostream &, SgAsmInstruction *, State &) const
Mid-level unparser function.
virtual std::vector< std::string > emitDirectRegisterExpression(std::ostream &, SgAsmDirectRegisterExpression *, State &) const
Mid-level unparser function.
virtual void emitFunctionBody(std::ostream &, const Partitioner2::FunctionPtr &, State &) const
Mid-level unparser function.
virtual std::vector< std::string > emitBinaryRor(std::ostream &, SgAsmBinaryRor *, State &) const
Mid-level unparser function.
Architecture::BaseConstPtr architecture() const
Property: Architecture.
virtual void emitInstructionMnemonic(std::ostream &, SgAsmInstruction *, State &) const
Mid-level unparser function.
virtual void emitFunctionComment(std::ostream &, const Partitioner2::FunctionPtr &, State &) const
Mid-level unparser function.
virtual void emitFunctionCallees(std::ostream &, const Partitioner2::FunctionPtr &, State &) const
Mid-level unparser function.
virtual void emitFunctionSourceLocation(std::ostream &, const Partitioner2::FunctionPtr &, State &) const
Mid-level unparser function.
virtual std::vector< std::string > emitStackExpression(std::ostream &, SgAsmStackExpression *, State &) const
Mid-level unparser function.
virtual void emitInstructionSemantics(std::ostream &, SgAsmInstruction *, State &) const
Mid-level unparser function.
virtual std::vector< std::string > emitRegisterNames(std::ostream &, SgAsmRegisterNames *, State &) const
Mid-level unparser function.
static std::string leftJustify(const std::string &, size_t nchars)
Render a string left justified.
virtual void emitOperandPrologue(std::ostream &, SgAsmExpression *, State &) const
Mid-level unparser function.
virtual std::vector< std::string > emitUnaryPlus(std::ostream &, SgAsmUnaryPlus *, State &) const
Mid-level unparser function.
virtual void updateIntraFunctionArrows(State &) const
Calculate intra-function arrows.
virtual void emitOperandBody(std::ostream &, SgAsmExpression *, State &) const
Mid-level unparser function.
virtual void emitFunctionNoopAnalysis(std::ostream &, const Partitioner2::FunctionPtr &, State &) const
Mid-level unparser function.
bool hasSuppressedFallThroughEdge(const Partitioner2::BasicBlockPtr &src, const Partitioner2::BasicBlockPtr &dst, State &) const
Test whether there are any fall-through edges between the two specified basic blocks.
virtual std::vector< std::string > emitByteOrder(std::ostream &, SgAsmByteOrder *, State &) const
Mid-level unparser function.
Renders textual margin arrows.
Definition EdgeArrows.h:38
ArrowSide
Specifies on which side of the output the arrows appear.
Definition EdgeArrows.h:100
size_t EndpointId
Endpoint identification number.
Definition EdgeArrows.h:59
Partitioner2::BasicBlockPtr previousBasicBlock() const
Points to a relevant basic block.
const std::vector< Reachability::ReasonFlags > cfgVertexReachability() const
Property: Reachability analysis results.
ArrowMargin & intraFunctionBlockArrows()
User-defined intra-function margin arrows.
ArrowMargin & globalBlockArrows()
User-defined arrows to basic blocks across entire output.
ArrowMargin & intraFunctionCfgArrows()
Control flow graph arrows within a function.
void previousBasicBlock(const Partitioner2::BasicBlockPtr &)
Points to a relevant basic block.
Partitioner2::BasicBlockPtr nextBasicBlock() const
Points to a relevant basic block.
std::string reachabilityName(Reachability::ReasonFlags value) const
Assign a reachability name to a reachability value.
Partitioner2::BasicBlockPtr currentBasicBlock() const
Points to a relevant basic block.
void currentBasicBlock(const Partitioner2::BasicBlockPtr &)
Points to a relevant basic block.
const Base & frontUnparser() const
First unparser in the chained list of unparsers.
Sawyer::Container::Map< Address, std::string > AddrString
Map from address to string.
void nextBasicBlock(const Partitioner2::BasicBlockPtr &)
Points to a relevant basic block.
const ArrowMargin & intraFunctionCfgArrows() const
Control flow graph arrows within a function.
void thisIsBasicBlockFirstInstruction()
Call this when you're about to output the first instruction of a basic block.
const StyleStack & styleStack() const
Property: Stack of styles.
Partitioner2::PartitionerConstPtr partitioner() const
Property: Partitioner, which may be null.
StyleStack & styleStack()
Property: Stack of styles.
Reachability::ReasonFlags isCfgVertexReachable(size_t vertexId) const
Returns reachability based on the cfgVertexReachability property.
void rotateBasicBlocks(const Partitioner2::BasicBlockPtr &current, const Partitioner2::BasicBlockPtr &next)
Rotate the basic block pointers.
void reachabilityName(Reachability::Reason value, const std::string &name)
Assign a reachability name to a reachability value.
const ArrowMargin & intraFunctionBlockArrows() const
User-defined intra-function margin arrows.
const Partitioner2::FunctionCallGraph & cg() const
Property: Call grap, which may be empty.
const ArrowMargin & globalBlockArrows() const
User-defined arrows to basic blocks across entire output.
void cfgVertexReachability(const std::vector< Reachability::ReasonFlags > &)
Property: Reachability analysis results.
void thisIsBasicBlockLastInstruction()
Call this when you're about to output the last instruction of a basic block.
Pushes a style and arranges for it to be popped later.
std::string render() const
Render style entry.
StyleGuard(StyleStack &stack, const Style &style)
Push style onto stack.
const Style & previous() const
Style before pushing.
std::string restore() const
Render style exit.
const Style & current() const
Current merged style.
size_t push(const Style &)
Push style onto stack.
const Style & current() const
Merged style.
size_t size() const
Number of styles on the stack.
void colorization(const Color::Colorization c)
Property: Colorization settings.
Color::Colorization colorization() const
Property: Colorization settings.
void popTo(size_t)
Pop until stack is a certain size.
void pop()
Pop top style from stack.
A general, thread-safe way to report progress made on some task.
Definition Progress.h:167
Container associating values with keys.
Definition Sawyer/Map.h:72
Collection of streams.
Definition Message.h:1606
Holds a value or nothing.
Definition Optional.h:56
Base class for reference counted objects.
Operand referencing a Co-processor.
Expression that adds two operands.
Expression that performs an arithmetic, sign-bit preserving right shift.
Expression that concatenates two values to form a wider value.
Expression that divides the first operand by the second.
Expression that performs a logical left shift operation.
Expression that performs a logical, sign-bit non-preserving right shift.
Expression that returns the remainder when dividing the first operand by the second.
Expression that performs a logical left shift operation filling low-order bits with one.
Expression that multiplies two operands.
Expression that represents an update to a storage location.
Expression that represents an update to a storage location.
Expression that performs a right rotate.
Expression that subtracts the second operand from the first.
Byte order specification.
Expression representing a machine register.
List of expression nodes.
Base class for expressions.
Registers accessed indirectly.
Base class for machine instructions.
Base class for integer values.
Reference to memory locations.
An ordered list of registers.
Static representation of instruction semantics.
Base class for references to a machine register.
Base class for binary types.
Expression represting negation.
Expression representing a (no-op) unary plus operation.
Expression representing sign extending.
Expression representing truncation.
Expression representing unsigned extending.
std::shared_ptr< const Base > BaseConstPtr
Reference counted pointer for Architecture::Base.
std::map< uint64_t, std::string > LabelMap
Map from address to label.
Sawyer::Message::Facility mlog
Diagnostic output for unparsing.
std::string invalidRegister(SgAsmInstruction *, RegisterDescriptor, const RegisterDictionaryPtr &)
Constructs a string to describe the invalid register.
std::uint64_t Address
Address.
Definition Address.h:11
The ROSE library.
Settings that control unparsing.
Control colored command output.
Definition Color.h:37