1 #ifndef ROSE_BinaryAnalysis_UnparserBase_H
2 #define ROSE_BinaryAnalysis_UnparserBase_H
4 #include <featureTests.h>
5 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
7 #include <BinaryEdgeArrows.h>
8 #include <BinaryReachability.h>
9 #include <BinaryUnparser.h>
11 #include <Partitioner2/BasicTypes.h>
12 #include <Partitioner2/ControlFlowGraph.h>
13 #include <Partitioner2/FunctionCallGraph.h>
14 #include <Sawyer/Map.h>
15 #include <Sawyer/Message.h>
16 #include <Sawyer/SharedObject.h>
18 #include <Registers.h>
30 void initDiagnostics();
45 POINTABLE_ENTITY_START = 0x00000001,
50 POINTABLE_ENTITY_END = 0x00000002,
53 POINTABLE_ENTITY_INSIDE = 0x00000004,
57 ALWAYS_RENDER = 0x00000008
61 BitFlags<Flags> flags;
87 std::vector<Style> stack_;
89 Color::Colorization colorization_;
97 Color::Colorization colorization()
const {
return colorization_; }
98 void colorization(
const Color::Colorization c) { colorization_ = c; }
104 size_t push(
const Style&);
125 const Style& current()
const;
128 void merge(
const Style &style);
143 StyleGuard(StyleStack &stack,
const Style &style)
145 previous_ = stack_.current();
146 n_ = stack_.push(style);
147 current_ = stack_.current();
150 StyleGuard(StyleStack &stack,
const Style &first,
const Style &second)
152 previous_ = stack_.current();
153 n_ = stack_.push(first);
155 current_ = stack_.current();
163 std::string render()
const;
166 std::string restore()
const;
169 const Style& current()
const {
174 const Style& previous()
const {
192 const Partitioner2::Partitioner &partitioner_;
193 Partitioner2::FunctionCallGraph cg_;
195 Partitioner2::BasicBlockPtr currentBasicBlock_;
197 std::string nextInsnLabel_;
198 AddrString basicBlockLabels_;
199 RegisterNames registerNames_;
200 const Base &frontUnparser_;
201 std::vector<Reachability::ReasonFlags> cfgVertexReachability_;
203 ArrowMargin intraFunctionCfgArrows_;
204 ArrowMargin intraFunctionBlockArrows_;
205 ArrowMargin globalBlockArrows_;
206 bool cfgArrowsPointToInsns_;
207 StyleStack styleStack_;
210 State(
const Partitioner2::Partitioner&,
const Settings&,
const Base &frontUnparser);
211 State(
const Partitioner2::Partitioner&,
const RegisterDictionary*,
const Settings&,
const Base &frontUnparser);
214 const Partitioner2::Partitioner& partitioner()
const;
216 const Partitioner2::FunctionCallGraph& cg()
const;
224 const std::vector<Reachability::ReasonFlags> cfgVertexReachability()
const;
225 void cfgVertexReachability(
const std::vector<Reachability::ReasonFlags>&);
246 const ArrowMargin& intraFunctionCfgArrows()
const {
return intraFunctionCfgArrows_; }
247 ArrowMargin& intraFunctionCfgArrows() {
return intraFunctionCfgArrows_; }
263 const ArrowMargin& intraFunctionBlockArrows()
const {
return intraFunctionBlockArrows_; }
264 ArrowMargin& intraFunctionBlockArrows() {
return intraFunctionBlockArrows_; }
275 const ArrowMargin& globalBlockArrows()
const {
return globalBlockArrows_; }
276 ArrowMargin& globalBlockArrows() {
return globalBlockArrows_; }
280 void thisIsBasicBlockFirstInstruction();
283 void thisIsBasicBlockLastInstruction();
303 bool cfgArrowsPointToInsns()
const {
return cfgArrowsPointToInsns_; }
304 void cfgArrowsPointToInsns(
bool b) { cfgArrowsPointToInsns_ = b; }
310 const StyleStack& styleStack()
const {
return styleStack_; }
311 StyleStack& styleStack() {
return styleStack_; }
335 Partitioner2::BasicBlockPtr currentBasicBlock()
const;
336 void currentBasicBlock(
const Partitioner2::BasicBlockPtr&);
338 const std::string& nextInsnLabel()
const;
339 void nextInsnLabel(
const std::string&);
341 const RegisterNames& registerNames()
const;
342 void registerNames(
const RegisterNames &r);
344 const AddrString& basicBlockLabels()
const;
345 AddrString& basicBlockLabels();
347 const Base& frontUnparser()
const;
409 explicit Base(
const Ptr &nextUnparser);
412 virtual Ptr
copy()
const = 0;
424 virtual const Settings& settings()
const = 0;
425 virtual Settings& settings() = 0;
426 void settings(
const Settings &s) {
438 Ptr nextUnparser()
const {
return nextUnparser_; }
439 void nextUnparser(Ptr next) { nextUnparser_ = next; }
449 void operator()(std::ostream &out,
const Partitioner2::Partitioner &p)
const {
452 void operator()(std::ostream &out,
const Partitioner2::Partitioner &p,
454 unparse(out, p, insn);
456 void operator()(std::ostream &out,
const Partitioner2::Partitioner &p,
457 const Partitioner2::BasicBlockPtr &bb)
const {
460 void operator()(std::ostream &out,
const Partitioner2::Partitioner &p,
461 const Partitioner2::DataBlockPtr &db)
const {
464 void operator()(std::ostream &out,
const Partitioner2::Partitioner &p,
476 return unparse(p, progress);
478 std::string operator()(
const Partitioner2::Partitioner &p,
SgAsmInstruction *insn)
const {
479 return unparse(p, insn);
481 std::string operator()(
const Partitioner2::Partitioner &p,
const Partitioner2::BasicBlockPtr &bb)
const {
482 return unparse(p, bb);
484 std::string operator()(
const Partitioner2::Partitioner &p,
const Partitioner2::DataBlockPtr &db)
const {
485 return unparse(p, db);
488 return unparse(p, f);
503 void unparse(
std::ostream&, const Partitioner2::Partitioner&, const Partitioner2::BasicBlockPtr&) const ;
504 void unparse(
std::ostream&, const Partitioner2::Partitioner&, const Partitioner2::DataBlockPtr&) const ;
505 void unparse(
std::ostream&, const Partitioner2::Partitioner&, const Partitioner2::FunctionPtr&) const ;
507 std::
string unparse(const Partitioner2::Partitioner&, const Progress::Ptr &progress = Progress::Ptr()) const ;
509 std::
string unparse(const Partitioner2::Partitioner&, const Partitioner2::BasicBlockPtr&) const ;
510 std::
string unparse(const Partitioner2::Partitioner&, const Partitioner2::DataBlockPtr&) const ;
511 std::
string unparse(const Partitioner2::Partitioner&, const Partitioner2::FunctionPtr&) const ;
537 virtual
void emitFunction(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
538 virtual
void emitFunctionPrologue(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
539 virtual
void emitFunctionBody(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
540 virtual
void emitFunctionEpilogue(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
542 virtual
void emitFunctionSourceLocation(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
543 virtual
void emitFunctionReasons(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
544 virtual
void emitFunctionCallers(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
545 virtual
void emitFunctionCallees(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
546 virtual
void emitFunctionComment(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
547 virtual
void emitFunctionStackDelta(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
548 virtual
void emitFunctionCallingConvention(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
549 virtual
void emitFunctionNoopAnalysis(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
550 virtual
void emitFunctionMayReturn(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
552 virtual
void emitDataBlockSourceLocation(
std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
553 virtual
void emitDataBlock(
std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
554 virtual
void emitDataBlockPrologue(
std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
555 virtual
void emitDataBlockBody(
std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
556 virtual
void emitDataBlockEpilogue(
std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
558 virtual
void emitBasicBlock(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
559 virtual
void emitBasicBlockPrologue(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
560 virtual
void emitBasicBlockBody(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
561 virtual
void emitBasicBlockEpilogue(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
563 virtual
void emitBasicBlockSourceLocation(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
564 virtual
void emitBasicBlockComment(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
565 virtual
void emitBasicBlockSharing(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
566 virtual
void emitBasicBlockPredecessors(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
567 virtual
void emitBasicBlockSuccessors(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
568 virtual
void emitBasicBlockReachability(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
571 virtual
void emitInstructionPrologue(
std::ostream&, SgAsmInstruction*, State&) const;
572 virtual
void emitInstructionBody(
std::ostream&, SgAsmInstruction*, State&) const;
573 virtual
void emitInstructionEpilogue(
std::ostream&, SgAsmInstruction*, State&) const;
575 virtual
void emitInstructionAddress(
std::ostream&, SgAsmInstruction*, State&) const;
576 virtual
void emitInstructionBytes(
std::ostream&, SgAsmInstruction*, State&) const;
577 virtual
void emitInstructionStackDelta(
std::ostream&, SgAsmInstruction*, State&) const;
578 virtual
void emitInstructionMnemonic(
std::ostream&, SgAsmInstruction*, State&) const;
579 virtual
void emitInstructionOperands(
std::ostream&, SgAsmInstruction*, State&) const;
580 virtual
void emitInstructionComment(
std::ostream&, SgAsmInstruction*, State&) const;
582 virtual
void emitInstructionSemantics(
std::ostream&, SgAsmInstruction*, State&) const;
585 virtual
void emitOperandPrologue(
std::ostream&, SgAsmExpression*, State&) const;
586 virtual
void emitOperandBody(
std::ostream&, SgAsmExpression*, State&) const;
587 virtual
void emitOperandEpilogue(
std::ostream&, SgAsmExpression*, State&) const;
589 virtual
void emitRegister(
std::ostream&, RegisterDescriptor, State&) const;
590 virtual
std::vector<
std::
string> emitUnsignedInteger(
std::ostream&, const
Sawyer::Container::BitVector&, State&) const;
591 virtual
std::vector<
std::
string> emitSignedInteger(
std::ostream&, const
Sawyer::Container::BitVector&, State&) const;
592 virtual
std::vector<
std::
string> emitInteger(
std::ostream&, const
Sawyer::Container::BitVector&, State&,
593 bool isSigned) const;
594 virtual
bool emitAddress(
std::ostream&, rose_addr_t, State&,
bool always=true) const;
595 virtual
bool emitAddress(
std::ostream&, const
Sawyer::Container::BitVector&, State&,
bool always=true) const;
596 virtual
void emitCommentBlock(
std::ostream&, const
std::
string&, State&, const
std::
string &prefix = ";;; ") const;
597 virtual
void emitTypeName(
std::ostream&,
SgAsmType*, State&) const;
599 virtual
void emitLinePrefix(
std::ostream&, State&) const;
609 virtual
void initializeState(State&) const;
616 virtual
void updateIntraFunctionArrows(State&) const;
621 static
std::
string leftJustify(const
std::
string&,
size_t nchars);
628 static
std::
string juxtaposeColumns(const
std::vector<
std::
string> &content, const
std::vector<
size_t> &minWidths,
629 const
std::vector<
std::pair<
std::
string,
std::
string> > &colorEscapes,
630 const
std::
string &columnSeparator = " ");
637 static
bool ascendingSourceAddress(Partitioner2::ControlFlowGraph::ConstEdgeIterator a,
638 Partitioner2::ControlFlowGraph::ConstEdgeIterator b);
645 static
bool ascendingTargetAddress(Partitioner2::ControlFlowGraph::ConstEdgeIterator a,
646 Partitioner2::ControlFlowGraph::ConstEdgeIterator b);
652 static
std::vector<Partitioner2::ControlFlowGraph::ConstEdgeIterator>
653 orderedBlockPredecessors(const Partitioner2::Partitioner&, const Partitioner2::BasicBlock::Ptr&);
659 static
std::vector<Partitioner2::ControlFlowGraph::ConstEdgeIterator>
660 orderedBlockSuccessors(const Partitioner2::Partitioner&, const Partitioner2::BasicBlock::Ptr&);
668 #ifdef ROSE_ENABLE_PYTHON_API
675 explicit PythonBase(
const Base::Ptr &base)
677 ASSERT_not_null(base);
680 std::string unparse(
const Partitioner2::Partitioner &p)
const {
681 return base_->unparse(p);
684 void print(
const Partitioner2::Partitioner &p)
const {
685 base_->unparse(std::cout, p);
Sawyer::SharedPointer< Node > Ptr
Shared-ownership pointer to an expression Node.
void copy(const Word *src, const BitRange &srcRange, Word *dst, const BitRange &dstRange)
Copy some bits.
Base class for machine instructions.
Holds a value or nothing.
void reset()
Reset as if default-constructed.
void print(const StackVariables &, const Partitioner2::Partitioner &, std::ostream &out, const std::string &prefix="")
Print info about multiple local variables.
Main namespace for the ROSE library.
Reason
Predefined bit flags for why something is reachable.
Name space for the entire library.
Sawyer::SharedPointer< Function > FunctionPtr
Shared-ownership pointer for function.
BitFlags< Reason, uint32_t > ReasonFlags
Bit flags for reachability.
Base class for expressions.
Base class for binary types.
Base class for reference counted objects.
const char * Flags(int64_t)
Convert QDocumentCursorHandle::Flags enum constant to a string.
Sawyer::SharedPointer< Progress > Ptr
Progress objects are reference counted.