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/BasicTypes.h>
8 #include <Rose/BinaryAnalysis/Partitioner2/BasicTypes.h>
9 #include <Rose/BinaryAnalysis/Partitioner2/ControlFlowGraph.h>
10 #include <Rose/BinaryAnalysis/Partitioner2/FunctionCallGraph.h>
11 #include <Rose/BinaryAnalysis/Reachability.h>
12 #include <Rose/BinaryAnalysis/RegisterNames.h>
13 #include <Rose/BinaryAnalysis/Unparser/EdgeArrows.h>
14 #include <Rose/BinaryAnalysis/Unparser/Settings.h>
15 #include <Rose/BitFlags.h>
16 #include <Rose/Progress.h>
18 #include <Sawyer/Map.h>
19 #include <Sawyer/Message.h>
20 #include <Sawyer/SharedObject.h>
23 namespace BinaryAnalysis {
29 typedef std::map<uint64_t, std::string> LabelMap;
59 POINTABLE_ENTITY_START = 0x00000001,
64 POINTABLE_ENTITY_END = 0x00000002,
67 POINTABLE_ENTITY_INSIDE = 0x00000004,
71 ALWAYS_RENDER = 0x00000008
75 BitFlags<Flags> flags;
101 std::vector<Style> stack_;
103 Color::Colorization colorization_;
111 Color::Colorization colorization()
const {
return colorization_; }
112 void colorization(
const Color::Colorization c) { colorization_ = c; }
118 size_t push(
const Style&);
139 const Style& current()
const;
142 void merge(
const Style &style);
157 StyleGuard(StyleStack &stack,
const Style &style)
159 previous_ = stack_.current();
160 n_ = stack_.push(style);
161 current_ = stack_.current();
164 StyleGuard(StyleStack &stack,
const Style &first,
const Style &second)
166 previous_ = stack_.current();
167 n_ = stack_.push(first);
169 current_ = stack_.current();
177 std::string render()
const;
180 std::string restore()
const;
183 const Style& current()
const {
188 const Style& previous()
const {
206 const Partitioner2::Partitioner &partitioner_;
207 Partitioner2::FunctionCallGraph cg_;
209 Partitioner2::BasicBlockPtr currentBasicBlock_;
211 std::string nextInsnLabel_;
212 AddrString basicBlockLabels_;
213 RegisterNames registerNames_;
214 const Base &frontUnparser_;
215 std::vector<Reachability::ReasonFlags> cfgVertexReachability_;
217 ArrowMargin intraFunctionCfgArrows_;
218 ArrowMargin intraFunctionBlockArrows_;
219 ArrowMargin globalBlockArrows_;
220 bool cfgArrowsPointToInsns_;
221 StyleStack styleStack_;
224 State(
const Partitioner2::Partitioner&,
const Settings&,
const Base &frontUnparser);
228 const Partitioner2::Partitioner& partitioner()
const;
230 const Partitioner2::FunctionCallGraph& cg()
const;
238 const std::vector<Reachability::ReasonFlags> cfgVertexReachability()
const;
239 void cfgVertexReachability(
const std::vector<Reachability::ReasonFlags>&);
260 const ArrowMargin& intraFunctionCfgArrows()
const {
return intraFunctionCfgArrows_; }
261 ArrowMargin& intraFunctionCfgArrows() {
return intraFunctionCfgArrows_; }
277 const ArrowMargin& intraFunctionBlockArrows()
const {
return intraFunctionBlockArrows_; }
278 ArrowMargin& intraFunctionBlockArrows() {
return intraFunctionBlockArrows_; }
289 const ArrowMargin& globalBlockArrows()
const {
return globalBlockArrows_; }
290 ArrowMargin& globalBlockArrows() {
return globalBlockArrows_; }
294 void thisIsBasicBlockFirstInstruction();
297 void thisIsBasicBlockLastInstruction();
317 bool cfgArrowsPointToInsns()
const {
return cfgArrowsPointToInsns_; }
318 void cfgArrowsPointToInsns(
bool b) { cfgArrowsPointToInsns_ = b; }
324 const StyleStack& styleStack()
const {
return styleStack_; }
325 StyleStack& styleStack() {
return styleStack_; }
349 Partitioner2::BasicBlockPtr currentBasicBlock()
const;
350 void currentBasicBlock(
const Partitioner2::BasicBlockPtr&);
352 const std::string& nextInsnLabel()
const;
353 void nextInsnLabel(
const std::string&);
355 const RegisterNames& registerNames()
const;
356 void registerNames(
const RegisterNames &r);
358 const AddrString& basicBlockLabels()
const;
359 AddrString& basicBlockLabels();
361 const Base& frontUnparser()
const;
423 explicit Base(
const Ptr &nextUnparser);
426 virtual Ptr
copy()
const = 0;
438 virtual const Settings& settings()
const = 0;
439 virtual Settings& settings() = 0;
440 void settings(
const Settings &s) {
452 Ptr nextUnparser()
const {
return nextUnparser_; }
453 void nextUnparser(Ptr next) { nextUnparser_ = next; }
463 void operator()(std::ostream &out,
const Partitioner2::Partitioner &p)
const {
466 void operator()(std::ostream &out,
const Partitioner2::Partitioner &p,
468 unparse(out, p, insn);
470 void operator()(std::ostream &out,
const Partitioner2::Partitioner &p,
471 const Partitioner2::BasicBlockPtr &bb)
const {
474 void operator()(std::ostream &out,
const Partitioner2::Partitioner &p,
475 const Partitioner2::DataBlockPtr &db)
const {
478 void operator()(std::ostream &out,
const Partitioner2::Partitioner &p,
490 return unparse(p, progress);
492 std::string operator()(
const Partitioner2::Partitioner &p,
SgAsmInstruction *insn)
const {
493 return unparse(p, insn);
495 std::string operator()(
const Partitioner2::Partitioner &p,
const Partitioner2::BasicBlockPtr &bb)
const {
496 return unparse(p, bb);
498 std::string operator()(
const Partitioner2::Partitioner &p,
const Partitioner2::DataBlockPtr &db)
const {
499 return unparse(p, db);
502 return unparse(p, f);
517 void unparse(
std::ostream&, const Partitioner2::Partitioner&, const Partitioner2::BasicBlockPtr&) const ;
518 void unparse(
std::ostream&, const Partitioner2::Partitioner&, const Partitioner2::DataBlockPtr&) const ;
519 void unparse(
std::ostream&, const Partitioner2::Partitioner&, const Partitioner2::FunctionPtr&) const ;
521 std::
string unparse(const Partitioner2::Partitioner&, const Progress::Ptr &progress = Progress::Ptr()) const ;
523 std::
string unparse(const Partitioner2::Partitioner&, const Partitioner2::BasicBlockPtr&) const ;
524 std::
string unparse(const Partitioner2::Partitioner&, const Partitioner2::DataBlockPtr&) const ;
525 std::
string unparse(const Partitioner2::Partitioner&, const Partitioner2::FunctionPtr&) const ;
551 virtual
void emitFunction(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
552 virtual
void emitFunctionPrologue(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
553 virtual
void emitFunctionBody(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
554 virtual
void emitFunctionEpilogue(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
556 virtual
void emitFunctionSourceLocation(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
557 virtual
void emitFunctionReasons(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
558 virtual
void emitFunctionCallers(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
559 virtual
void emitFunctionCallees(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
560 virtual
void emitFunctionComment(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
561 virtual
void emitFunctionStackDelta(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
562 virtual
void emitFunctionCallingConvention(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
563 virtual
void emitFunctionNoopAnalysis(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
564 virtual
void emitFunctionMayReturn(
std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
566 virtual
void emitDataBlockSourceLocation(
std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
567 virtual
void emitDataBlock(
std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
568 virtual
void emitDataBlockPrologue(
std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
569 virtual
void emitDataBlockBody(
std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
570 virtual
void emitDataBlockEpilogue(
std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
572 virtual
void emitBasicBlock(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
573 virtual
void emitBasicBlockPrologue(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
574 virtual
void emitBasicBlockBody(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
575 virtual
void emitBasicBlockEpilogue(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
577 virtual
void emitBasicBlockSourceLocation(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
578 virtual
void emitBasicBlockComment(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
579 virtual
void emitBasicBlockSharing(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
580 virtual
void emitBasicBlockPredecessors(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
581 virtual
void emitBasicBlockSuccessors(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
582 virtual
void emitBasicBlockReachability(
std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
585 virtual
void emitInstructionPrologue(
std::ostream&, SgAsmInstruction*, State&) const;
586 virtual
void emitInstructionBody(
std::ostream&, SgAsmInstruction*, State&) const;
587 virtual
void emitInstructionEpilogue(
std::ostream&, SgAsmInstruction*, State&) const;
589 virtual
void emitInstructionAddress(
std::ostream&, SgAsmInstruction*, State&) const;
590 virtual
void emitInstructionBytes(
std::ostream&, SgAsmInstruction*, State&) const;
591 virtual
void emitInstructionStackDelta(
std::ostream&, SgAsmInstruction*, State&) const;
592 virtual
void emitInstructionMnemonic(
std::ostream&, SgAsmInstruction*, State&) const;
593 virtual
void emitInstructionOperands(
std::ostream&, SgAsmInstruction*, State&) const;
594 virtual
void emitInstructionComment(
std::ostream&, SgAsmInstruction*, State&) const;
596 virtual
void emitInstructionSemantics(
std::ostream&, SgAsmInstruction*, State&) const;
599 virtual
void emitOperandPrologue(
std::ostream&, SgAsmExpression*, State&) const;
600 virtual
void emitOperandBody(
std::ostream&, SgAsmExpression*, State&) const;
601 virtual
void emitOperandEpilogue(
std::ostream&, SgAsmExpression*, State&) const;
603 virtual
void emitRegister(
std::ostream&, RegisterDescriptor, State&) const;
604 virtual
std::vector<
std::
string> emitUnsignedInteger(
std::ostream&, const
Sawyer::Container::BitVector&, State&) const;
605 virtual
std::vector<
std::
string> emitSignedInteger(
std::ostream&, const
Sawyer::Container::BitVector&, State&) const;
606 virtual
std::vector<
std::
string> emitInteger(
std::ostream&, const
Sawyer::Container::BitVector&, State&,
607 bool isSigned) const;
608 virtual
bool emitAddress(
std::ostream&, rose_addr_t, State&,
bool always=true) const;
609 virtual
bool emitAddress(
std::ostream&, const
Sawyer::Container::BitVector&, State&,
bool always=true) const;
610 virtual
void emitCommentBlock(
std::ostream&, const
std::
string&, State&, const
std::
string &prefix = ";;; ") const;
611 virtual
void emitTypeName(
std::ostream&,
SgAsmType*, State&) const;
613 virtual
void emitLinePrefix(
std::ostream&, State&) const;
623 virtual
void initializeState(State&) const;
630 virtual
void updateIntraFunctionArrows(State&) const;
635 static
std::
string leftJustify(const
std::
string&,
size_t nchars);
642 static
std::
string juxtaposeColumns(const
std::vector<
std::
string> &content, const
std::vector<
size_t> &minWidths,
643 const
std::vector<
std::pair<
std::
string,
std::
string> > &colorEscapes,
644 const
std::
string &columnSeparator = " ");
651 static
bool ascendingSourceAddress(Partitioner2::ControlFlowGraph::ConstEdgeIterator a,
652 Partitioner2::ControlFlowGraph::ConstEdgeIterator b);
659 static
bool ascendingTargetAddress(Partitioner2::ControlFlowGraph::ConstEdgeIterator a,
660 Partitioner2::ControlFlowGraph::ConstEdgeIterator b);
666 static
std::vector<Partitioner2::ControlFlowGraph::ConstEdgeIterator>
667 orderedBlockPredecessors(const Partitioner2::Partitioner&, const Partitioner2::BasicBlock::Ptr&);
673 static
std::vector<Partitioner2::ControlFlowGraph::ConstEdgeIterator>
674 orderedBlockSuccessors(const Partitioner2::Partitioner&, const Partitioner2::BasicBlock::Ptr&);
682 #ifdef ROSE_ENABLE_PYTHON_API
689 explicit PythonBase(
const Base::Ptr &base)
691 ASSERT_not_null(base);
694 std::string unparse(
const Partitioner2::Partitioner &p)
const {
695 return base_->unparse(p);
698 void print(
const Partitioner2::Partitioner &p)
const {
699 base_->unparse(std::cout, p);
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.
Sawyer::SharedPointer< RegisterDictionary > RegisterDictionaryPtr
Reference counting pointer.
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.
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< Node > Ptr
Reference counting pointer.
Sawyer::SharedPointer< Progress > Ptr
Progress objects are reference counted.
const char * Flags(int64_t)
Convert Rose::BinaryAnalysis::Unparser::ArrowMargin::Flags enum constant to a string.