1 #ifndef ROSE_BinaryAnalysis_Unparser_Base_H
2 #define ROSE_BinaryAnalysis_Unparser_Base_H
4 #include <featureTests.h>
5 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
7 #include <Rose/BinaryAnalysis/Unparser/EdgeArrows.h>
8 #include <Rose/BinaryAnalysis/Reachability.h>
9 #include <Rose/BinaryAnalysis/Unparser/Settings.h>
10 #include <Rose/BitFlags.h>
11 #include <Rose/BinaryAnalysis/Partitioner2/BasicTypes.h>
12 #include <Rose/BinaryAnalysis/Partitioner2/ControlFlowGraph.h>
13 #include <Rose/BinaryAnalysis/Partitioner2/FunctionCallGraph.h>
14 #include <Sawyer/Map.h>
15 #include <Sawyer/Message.h>
16 #include <Sawyer/SharedObject.h>
17 #include <Rose/Progress.h>
18 #include <Rose/BinaryAnalysis/Registers.h>
21 namespace BinaryAnalysis {
27 typedef std::map<uint64_t, std::string> LabelMap;
42 std::string invalidRegister(
SgAsmInstruction*, RegisterDescriptor,
const RegisterDictionary*);
57 POINTABLE_ENTITY_START = 0x00000001,
62 POINTABLE_ENTITY_END = 0x00000002,
65 POINTABLE_ENTITY_INSIDE = 0x00000004,
69 ALWAYS_RENDER = 0x00000008
73 BitFlags<Flags> flags;
99 std::vector<Style> stack_;
101 Color::Colorization colorization_;
109 Color::Colorization colorization()
const {
return colorization_; }
110 void colorization(
const Color::Colorization c) { colorization_ = c; }
116 size_t push(
const Style&);
137 const Style& current()
const;
140 void merge(
const Style &style);
155 StyleGuard(StyleStack &stack,
const Style &style)
157 previous_ = stack_.current();
158 n_ = stack_.push(style);
159 current_ = stack_.current();
162 StyleGuard(StyleStack &stack,
const Style &first,
const Style &second)
164 previous_ = stack_.current();
165 n_ = stack_.push(first);
167 current_ = stack_.current();
175 std::string render()
const;
178 std::string restore()
const;
181 const Style& current()
const {
186 const Style& previous()
const {
204 const Partitioner2::Partitioner &partitioner_;
205 Partitioner2::FunctionCallGraph cg_;
207 Partitioner2::BasicBlockPtr currentBasicBlock_;
209 std::string nextInsnLabel_;
210 AddrString basicBlockLabels_;
211 RegisterNames registerNames_;
212 const Base &frontUnparser_;
213 std::vector<Reachability::ReasonFlags> cfgVertexReachability_;
215 ArrowMargin intraFunctionCfgArrows_;
216 ArrowMargin intraFunctionBlockArrows_;
217 ArrowMargin globalBlockArrows_;
218 bool cfgArrowsPointToInsns_;
219 StyleStack styleStack_;
222 State(
const Partitioner2::Partitioner&,
const Settings&,
const Base &frontUnparser);
223 State(
const Partitioner2::Partitioner&,
const RegisterDictionary*,
const Settings&,
const Base &frontUnparser);
226 const Partitioner2::Partitioner& partitioner()
const;
228 const Partitioner2::FunctionCallGraph& cg()
const;
236 const std::vector<Reachability::ReasonFlags> cfgVertexReachability()
const;
237 void cfgVertexReachability(
const std::vector<Reachability::ReasonFlags>&);
258 const ArrowMargin& intraFunctionCfgArrows()
const {
return intraFunctionCfgArrows_; }
259 ArrowMargin& intraFunctionCfgArrows() {
return intraFunctionCfgArrows_; }
275 const ArrowMargin& intraFunctionBlockArrows()
const {
return intraFunctionBlockArrows_; }
276 ArrowMargin& intraFunctionBlockArrows() {
return intraFunctionBlockArrows_; }
287 const ArrowMargin& globalBlockArrows()
const {
return globalBlockArrows_; }
288 ArrowMargin& globalBlockArrows() {
return globalBlockArrows_; }
292 void thisIsBasicBlockFirstInstruction();
295 void thisIsBasicBlockLastInstruction();
315 bool cfgArrowsPointToInsns()
const {
return cfgArrowsPointToInsns_; }
316 void cfgArrowsPointToInsns(
bool b) { cfgArrowsPointToInsns_ = b; }
322 const StyleStack& styleStack()
const {
return styleStack_; }
323 StyleStack& styleStack() {
return styleStack_; }
347 Partitioner2::BasicBlockPtr currentBasicBlock()
const;
348 void currentBasicBlock(
const Partitioner2::BasicBlockPtr&);
350 const std::string& nextInsnLabel()
const;
351 void nextInsnLabel(
const std::string&);
353 const RegisterNames& registerNames()
const;
354 void registerNames(
const RegisterNames &r);
356 const AddrString& basicBlockLabels()
const;
357 AddrString& basicBlockLabels();
359 const Base& frontUnparser()
const;
421 explicit Base(
const Ptr &nextUnparser);
424 virtual Ptr
copy()
const = 0;
436 virtual const Settings& settings()
const = 0;
437 virtual Settings& settings() = 0;
438 void settings(
const Settings &s) {
450 Ptr nextUnparser()
const {
return nextUnparser_; }
451 void nextUnparser(Ptr next) { nextUnparser_ = next; }
461 void operator()(std::ostream &out,
const Partitioner2::Partitioner &p)
const {
464 void operator()(std::ostream &out,
const Partitioner2::Partitioner &p,
466 unparse(out, p, insn);
468 void operator()(std::ostream &out,
const Partitioner2::Partitioner &p,
469 const Partitioner2::BasicBlockPtr &bb)
const {
472 void operator()(std::ostream &out,
const Partitioner2::Partitioner &p,
473 const Partitioner2::DataBlockPtr &db)
const {
476 void operator()(std::ostream &out,
const Partitioner2::Partitioner &p,
488 return unparse(p, progress);
490 std::string operator()(
const Partitioner2::Partitioner &p,
SgAsmInstruction *insn)
const {
491 return unparse(p, insn);
493 std::string operator()(
const Partitioner2::Partitioner &p,
const Partitioner2::BasicBlockPtr &bb)
const {
494 return unparse(p, bb);
496 std::string operator()(
const Partitioner2::Partitioner &p,
const Partitioner2::DataBlockPtr &db)
const {
497 return unparse(p, db);
500 return unparse(p, f);
515 void unparse(
std::ostream&, const Partitioner2::Partitioner&, const Partitioner2::BasicBlockPtr&) const ;
516 void unparse(
std::ostream&, const Partitioner2::Partitioner&, const Partitioner2::DataBlockPtr&) const ;
517 void unparse(
std::ostream&, const Partitioner2::Partitioner&, const Partitioner2::FunctionPtr&) const ;
519 std::
string unparse(const Partitioner2::Partitioner&, const Progress::Ptr &progress = Progress::Ptr()) const ;
521 std::
string unparse(const Partitioner2::Partitioner&, const Partitioner2::BasicBlockPtr&) const ;
522 std::
string unparse(const Partitioner2::Partitioner&, const Partitioner2::DataBlockPtr&) const ;
523 std::
string unparse(const Partitioner2::Partitioner&, const Partitioner2::FunctionPtr&) const ;
549 virtual
void emitFunction(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
550 virtual
void emitFunctionPrologue(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
551 virtual
void emitFunctionBody(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
552 virtual
void emitFunctionEpilogue(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
554 virtual
void emitFunctionSourceLocation(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
555 virtual
void emitFunctionReasons(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
556 virtual
void emitFunctionCallers(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
557 virtual
void emitFunctionCallees(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
558 virtual
void emitFunctionComment(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
559 virtual
void emitFunctionStackDelta(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
560 virtual
void emitFunctionCallingConvention(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
561 virtual
void emitFunctionNoopAnalysis(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
562 virtual
void emitFunctionMayReturn(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
564 virtual
void emitDataBlockSourceLocation(
std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
565 virtual
void emitDataBlock(
std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
566 virtual
void emitDataBlockPrologue(
std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
567 virtual
void emitDataBlockBody(
std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
568 virtual
void emitDataBlockEpilogue(
std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
570 virtual
void emitBasicBlock(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
571 virtual
void emitBasicBlockPrologue(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
572 virtual
void emitBasicBlockBody(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
573 virtual
void emitBasicBlockEpilogue(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
575 virtual
void emitBasicBlockSourceLocation(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
576 virtual
void emitBasicBlockComment(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
577 virtual
void emitBasicBlockSharing(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
578 virtual
void emitBasicBlockPredecessors(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
579 virtual
void emitBasicBlockSuccessors(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
580 virtual
void emitBasicBlockReachability(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
583 virtual
void emitInstructionPrologue(
std::ostream&, SgAsmInstruction*, State&) const;
584 virtual
void emitInstructionBody(
std::ostream&, SgAsmInstruction*, State&) const;
585 virtual
void emitInstructionEpilogue(
std::ostream&, SgAsmInstruction*, State&) const;
587 virtual
void emitInstructionAddress(
std::ostream&, SgAsmInstruction*, State&) const;
588 virtual
void emitInstructionBytes(
std::ostream&, SgAsmInstruction*, State&) const;
589 virtual
void emitInstructionStackDelta(
std::ostream&, SgAsmInstruction*, State&) const;
590 virtual
void emitInstructionMnemonic(
std::ostream&, SgAsmInstruction*, State&) const;
591 virtual
void emitInstructionOperands(
std::ostream&, SgAsmInstruction*, State&) const;
592 virtual
void emitInstructionComment(
std::ostream&, SgAsmInstruction*, State&) const;
594 virtual
void emitInstructionSemantics(
std::ostream&, SgAsmInstruction*, State&) const;
597 virtual
void emitOperandPrologue(
std::ostream&, SgAsmExpression*, State&) const;
598 virtual
void emitOperandBody(
std::ostream&, SgAsmExpression*, State&) const;
599 virtual
void emitOperandEpilogue(
std::ostream&, SgAsmExpression*, State&) const;
601 virtual
void emitRegister(
std::ostream&, RegisterDescriptor, State&) const;
602 virtual
std::vector<
std::
string> emitUnsignedInteger(
std::ostream&, const
Sawyer::Container::BitVector&, State&) const;
603 virtual
std::vector<
std::
string> emitSignedInteger(
std::ostream&, const
Sawyer::Container::BitVector&, State&) const;
604 virtual
std::vector<
std::
string> emitInteger(
std::ostream&, const
Sawyer::Container::BitVector&, State&,
605 bool isSigned) const;
606 virtual
bool emitAddress(
std::ostream&, rose_addr_t, State&,
bool always=true) const;
607 virtual
bool emitAddress(
std::ostream&, const
Sawyer::Container::BitVector&, State&,
bool always=true) const;
608 virtual
void emitCommentBlock(
std::ostream&, const
std::
string&, State&, const
std::
string &prefix = ";;; ") const;
609 virtual
void emitTypeName(
std::ostream&,
SgAsmType*, State&) const;
611 virtual
void emitLinePrefix(
std::ostream&, State&) const;
621 virtual
void initializeState(State&) const;
628 virtual
void updateIntraFunctionArrows(State&) const;
633 static
std::
string leftJustify(const
std::
string&,
size_t nchars);
640 static
std::
string juxtaposeColumns(const
std::vector<
std::
string> &content, const
std::vector<
size_t> &minWidths,
641 const
std::vector<
std::pair<
std::
string,
std::
string> > &colorEscapes,
642 const
std::
string &columnSeparator = " ");
649 static
bool ascendingSourceAddress(Partitioner2::ControlFlowGraph::ConstEdgeIterator a,
650 Partitioner2::ControlFlowGraph::ConstEdgeIterator b);
657 static
bool ascendingTargetAddress(Partitioner2::ControlFlowGraph::ConstEdgeIterator a,
658 Partitioner2::ControlFlowGraph::ConstEdgeIterator b);
664 static
std::vector<Partitioner2::ControlFlowGraph::ConstEdgeIterator>
665 orderedBlockPredecessors(const Partitioner2::Partitioner&, const Partitioner2::BasicBlock::Ptr&);
671 static
std::vector<Partitioner2::ControlFlowGraph::ConstEdgeIterator>
672 orderedBlockSuccessors(const Partitioner2::Partitioner&, const Partitioner2::BasicBlock::Ptr&);
680 #ifdef ROSE_ENABLE_PYTHON_API
687 explicit PythonBase(
const Base::Ptr &base)
689 ASSERT_not_null(base);
692 std::string unparse(
const Partitioner2::Partitioner &p)
const {
693 return base_->unparse(p);
696 void print(
const Partitioner2::Partitioner &p)
const {
697 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.
ROSE_DLL_API Sawyer::Message::Facility mlog
Diagnostic facility for the ROSE library as a whole.
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.
ROSE_DLL_API void merge(SgProject *project)
Performs sharing of AST nodes followed by linking accross translation units.
const char * Flags(int64_t)
Convert QDocumentCursorHandle::Flags enum constant to a string.
BitFlags< Reason, uint32_t > ReasonFlags
Bit flags for reachability.
Base class for expressions.
0x57: "Pop the top operand stack value"
Base class for binary types.
Base class for reference counted objects.
void initDiagnostics()
Initialize diagnostics.
Sawyer::SharedPointer< Progress > Ptr
Progress objects are reference counted.