ROSE  0.9.10.135
BinaryUnparserBase.h
1 #ifndef ROSE_BinaryAnalysis_UnparserBase_H
2 #define ROSE_BinaryAnalysis_UnparserBase_H
3 
4 #include <BinaryEdgeArrows.h>
5 #include <BinaryUnparser.h>
6 #include <BitFlags.h>
7 #include <Partitioner2/BasicTypes.h>
8 #include <Partitioner2/ControlFlowGraph.h>
9 #include <Partitioner2/FunctionCallGraph.h>
10 #include <Sawyer/Map.h>
11 #include <Sawyer/Message.h>
12 #include <Sawyer/SharedObject.h>
13 #include <Progress.h>
14 #include <Registers.h>
15 
16 namespace Rose {
17 namespace BinaryAnalysis {
18 
20 namespace Unparser {
21 
23 extern Sawyer::Message::Facility mlog;
24 
25 // used internally to initialize mlog
26 void initDiagnostics();
27 
29 // Margins containing arrows
31 
33 class ArrowMargin {
34 public:
36  enum Flags {
41  POINTABLE_ENTITY_START = 0x00000001,
42 
46  POINTABLE_ENTITY_END = 0x00000002,
47 
49  POINTABLE_ENTITY_INSIDE = 0x00000004,
50 
53  ALWAYS_RENDER = 0x00000008
54  };
55 
56  EdgeArrows arrows;
57  BitFlags<Flags> flags;
63  void reset() {
64  arrows.reset();
65  flags = 0;
66  latestEntity = Sawyer::Nothing();
67  }
68 
74  std::string render(Sawyer::Optional<EdgeArrows::VertexId> currentEntity);
75 };
76 
78 // State of the unparser (the unparser itself is const during unparsing)
80 
85 class State {
86 public:
89 private:
90  const Partitioner2::Partitioner &partitioner_;
91  Partitioner2::FunctionCallGraph cg_;
92  Partitioner2::FunctionPtr currentFunction_;
93  Partitioner2::BasicBlockPtr currentBasicBlock_;
94  Sawyer::Optional<EdgeArrows::VertexId> currentPredSuccId_;
95  std::string nextInsnLabel_;
96  AddrString basicBlockLabels_;
97  RegisterNames registerNames_;
98  const Base &frontUnparser_;
99  std::vector<unsigned> cfgVertexReachability_;
100  Sawyer::Container::Map<unsigned, std::string> reachabilityNames_; // map reachability value to name
101  ArrowMargin intraFunctionCfgArrows_; // arrows for the intra-function control flow graphs
102  ArrowMargin intraFunctionBlockArrows_; // user-defined intra-function arrows to/from blocks
103  ArrowMargin globalBlockArrows_; // user-defined global arrows to/from blocks
104  bool cfgArrowsPointToInsns_; // arrows point to insns? else predecessor/successor lines
105 
106 public:
107  State(const Partitioner2::Partitioner&, const Settings&, const Base &frontUnparser);
108  virtual ~State();
109 
110  const Partitioner2::Partitioner& partitioner() const;
111 
112  const Partitioner2::FunctionCallGraph& cg() const;
113 
114  const std::vector<unsigned> cfgVertexReachability() const;
115  void cfgVertexReachability(const std::vector<unsigned>&);
116  unsigned isCfgVertexReachable(size_t vertexId) const;
117 
130  const ArrowMargin& intraFunctionCfgArrows() const { return intraFunctionCfgArrows_; }
131  ArrowMargin& intraFunctionCfgArrows() { return intraFunctionCfgArrows_; }
147  const ArrowMargin& intraFunctionBlockArrows() const { return intraFunctionBlockArrows_; }
148  ArrowMargin& intraFunctionBlockArrows() { return intraFunctionBlockArrows_; }
159  const ArrowMargin& globalBlockArrows() const { return globalBlockArrows_; }
160  ArrowMargin& globalBlockArrows() { return globalBlockArrows_; }
164  void thisIsBasicBlockFirstInstruction();
165 
167  void thisIsBasicBlockLastInstruction();
168 
176  Sawyer::Optional<EdgeArrows::VertexId> currentPredSuccId() const { return currentPredSuccId_; }
177  void currentPredSuccId(Sawyer::Optional<EdgeArrows::VertexId> id) { currentPredSuccId_ = id; }
187  bool cfgArrowsPointToInsns() const { return cfgArrowsPointToInsns_; }
188  void cfgArrowsPointToInsns(bool b) { cfgArrowsPointToInsns_ = b; }
205  void reachabilityName(unsigned value, const std::string &name);
206  std::string reachabilityName(unsigned value) const;
209  Partitioner2::FunctionPtr currentFunction() const;
210  void currentFunction(const Partitioner2::FunctionPtr&);
211 
212  Partitioner2::BasicBlockPtr currentBasicBlock() const;
213  void currentBasicBlock(const Partitioner2::BasicBlockPtr&);
214 
215  const std::string& nextInsnLabel() const;
216  void nextInsnLabel(const std::string&);
217 
218  const RegisterNames& registerNames() const;
219  void registerNames(const RegisterNames &r);
220 
221  const AddrString& basicBlockLabels() const;
222  AddrString& basicBlockLabels();
223 
224  const Base& frontUnparser() const;
225 };
226 
228 // Base unparser
230 
277 class Base: public Sawyer::SharedObject {
278 public:
280 
281 private:
282  Ptr nextUnparser_;
283 
284 protected:
285  Base();
286  explicit Base(const Ptr &nextUnparser);
287 
288 public:
289  virtual Ptr copy() const = 0;
290  virtual ~Base();
291 
299  virtual const Settings& settings() const = 0;
300  virtual Settings& settings() = 0;
310  Ptr nextUnparser() const { return nextUnparser_; }
311  void nextUnparser(Ptr next) { nextUnparser_ = next; }
321  void operator()(std::ostream &out, const Partitioner2::Partitioner &p) const /*final*/ {
322  unparse(out, p);
323  }
324  void operator()(std::ostream &out, const Partitioner2::Partitioner &p,
325  SgAsmInstruction *insn) const /*final*/ {
326  unparse(out, p, insn);
327  }
328  void operator()(std::ostream &out, const Partitioner2::Partitioner &p,
329  const Partitioner2::BasicBlockPtr &bb) const /*final*/{
330  unparse(out, p, bb);
331  }
332  void operator()(std::ostream &out, const Partitioner2::Partitioner &p,
333  const Partitioner2::DataBlockPtr &db) const /*final*/ {
334  unparse(out, p, db);
335  }
336  void operator()(std::ostream &out, const Partitioner2::Partitioner &p,
337  const Partitioner2::FunctionPtr &f) const /*final*/ {
338  unparse(out, p, f);
339  }
347  std::string operator()(const Partitioner2::Partitioner &p, const Progress::Ptr &progress = Progress::Ptr()) const /*final*/ {
348  return unparse(p, progress);
349  }
350  std::string operator()(const Partitioner2::Partitioner &p, SgAsmInstruction *insn) const /*final*/ {
351  return unparse(p, insn);
352  }
353  std::string operator()(const Partitioner2::Partitioner &p, const Partitioner2::BasicBlockPtr &bb) const /*final*/ {
354  return unparse(p, bb);
355  }
356  std::string operator()(const Partitioner2::Partitioner &p, const Partitioner2::DataBlockPtr &db) const /*final*/ {
357  return unparse(p, db);
358  }
359  std::string operator()(const Partitioner2::Partitioner &p, const Partitioner2::FunctionPtr &f) const /*final*/ {
360  return unparse(p, f);
361  }
367 public:
373  void unparse(std::ostream&, const Partitioner2::Partitioner&, const Progress::Ptr &progress = Progress::Ptr()) const /*final*/;
374  void unparse(std::ostream&, const Partitioner2::Partitioner&, SgAsmInstruction*) const /*final*/;
375  void unparse(std::ostream&, const Partitioner2::Partitioner&, const Partitioner2::BasicBlockPtr&) const /*final*/;
376  void unparse(std::ostream&, const Partitioner2::Partitioner&, const Partitioner2::DataBlockPtr&) const /*final*/;
377  void unparse(std::ostream&, const Partitioner2::Partitioner&, const Partitioner2::FunctionPtr&) const /*final*/;
378 
379  std::string unparse(const Partitioner2::Partitioner&, const Progress::Ptr &progress = Progress::Ptr()) const /*final*/;
380  std::string unparse(const Partitioner2::Partitioner&, SgAsmInstruction*) const /*final*/;
381  std::string unparse(const Partitioner2::Partitioner&, const Partitioner2::BasicBlockPtr&) const /*final*/;
382  std::string unparse(const Partitioner2::Partitioner&, const Partitioner2::DataBlockPtr&) const /*final*/;
383  std::string unparse(const Partitioner2::Partitioner&, const Partitioner2::FunctionPtr&) const /*final*/;
386 public:
409  virtual void emitFunction(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
410  virtual void emitFunctionPrologue(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
411  virtual void emitFunctionBody(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
412  virtual void emitFunctionEpilogue(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
413 
414  virtual void emitFunctionReasons(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
415  virtual void emitFunctionCallers(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
416  virtual void emitFunctionCallees(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
417  virtual void emitFunctionComment(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
418  virtual void emitFunctionStackDelta(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
419  virtual void emitFunctionCallingConvention(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
420  virtual void emitFunctionNoopAnalysis(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
421  virtual void emitFunctionMayReturn(std::ostream&, const Partitioner2::FunctionPtr&, State&) const;
422 
423  virtual void emitDataBlock(std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
424  virtual void emitDataBlockPrologue(std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
425  virtual void emitDataBlockBody(std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
426  virtual void emitDataBlockEpilogue(std::ostream&, const Partitioner2::DataBlockPtr&, State&) const;
427 
428  virtual void emitBasicBlock(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
429  virtual void emitBasicBlockPrologue(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
430  virtual void emitBasicBlockBody(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
431  virtual void emitBasicBlockEpilogue(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
432 
433  virtual void emitBasicBlockComment(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
434  virtual void emitBasicBlockSharing(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
435  virtual void emitBasicBlockPredecessors(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
436  virtual void emitBasicBlockSuccessors(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
437  virtual void emitBasicBlockReachability(std::ostream&, const Partitioner2::BasicBlockPtr&, State&) const;
438 
439  virtual void emitInstruction(std::ostream&, SgAsmInstruction*, State&) const;
440  virtual void emitInstructionPrologue(std::ostream&, SgAsmInstruction*, State&) const;
441  virtual void emitInstructionBody(std::ostream&, SgAsmInstruction*, State&) const;
442  virtual void emitInstructionEpilogue(std::ostream&, SgAsmInstruction*, State&) const;
443 
444  virtual void emitInstructionAddress(std::ostream&, SgAsmInstruction*, State&) const;
445  virtual void emitInstructionBytes(std::ostream&, SgAsmInstruction*, State&) const;
446  virtual void emitInstructionStackDelta(std::ostream&, SgAsmInstruction*, State&) const;
447  virtual void emitInstructionMnemonic(std::ostream&, SgAsmInstruction*, State&) const;
448  virtual void emitInstructionOperands(std::ostream&, SgAsmInstruction*, State&) const;
449  virtual void emitInstructionComment(std::ostream&, SgAsmInstruction*, State&) const;
450 
451  virtual void emitInstructionSemantics(std::ostream&, SgAsmInstruction*, State&) const;
452 
453  virtual void emitOperand(std::ostream&, SgAsmExpression*, State&) const;
454  virtual void emitOperandPrologue(std::ostream&, SgAsmExpression*, State&) const;
455  virtual void emitOperandBody(std::ostream&, SgAsmExpression*, State&) const;
456  virtual void emitOperandEpilogue(std::ostream&, SgAsmExpression*, State&) const;
457 
458  virtual void emitRegister(std::ostream&, RegisterDescriptor, State&) const;
459  virtual std::vector<std::string> emitUnsignedInteger(std::ostream&, const Sawyer::Container::BitVector&, State&) const;
460  virtual std::vector<std::string> emitSignedInteger(std::ostream&, const Sawyer::Container::BitVector&, State&) const;
461  virtual std::vector<std::string> emitInteger(std::ostream&, const Sawyer::Container::BitVector&, State&,
462  bool isSigned) const;
463  virtual bool emitAddress(std::ostream&, rose_addr_t, State&, bool always=true) const;
464  virtual bool emitAddress(std::ostream&, const Sawyer::Container::BitVector&, State&, bool always=true) const;
465  virtual void emitCommentBlock(std::ostream&, const std::string&, State&, const std::string &prefix = ";;; ") const;
466  virtual void emitTypeName(std::ostream&, SgAsmType*, State&) const;
467 
468  virtual void emitLinePrefix(std::ostream&, State&) const;
471  //----- Other overrridable things -----
472 public:
478  virtual void initializeState(State&) const;
479 
485  virtual void updateIntraFunctionArrows(State&) const;
486 
487  //----- Utility functions -----
488 public:
490  static std::string leftJustify(const std::string&, size_t nchars);
491 
496  static std::string juxtaposeColumns(const std::vector<std::string> &content, const std::vector<size_t> &minWidths,
497  const std::string &columnSeparator = " ");
498 
504  static bool ascendingSourceAddress(Partitioner2::ControlFlowGraph::ConstEdgeIterator a,
505  Partitioner2::ControlFlowGraph::ConstEdgeIterator b);
506 
512  static bool ascendingTargetAddress(Partitioner2::ControlFlowGraph::ConstEdgeIterator a,
513  Partitioner2::ControlFlowGraph::ConstEdgeIterator b);
514 
519  static std::vector<Partitioner2::ControlFlowGraph::ConstEdgeIterator>
520  orderedBlockPredecessors(const Partitioner2::Partitioner&, const Partitioner2::BasicBlock::Ptr&);
521 
526  static std::vector<Partitioner2::ControlFlowGraph::ConstEdgeIterator>
527  orderedBlockSuccessors(const Partitioner2::Partitioner&, const Partitioner2::BasicBlock::Ptr&);
528 };
529 
530 
532 // Python API wrappers and functions
534 
535 #ifdef ROSE_ENABLE_PYTHON_API
536 class PythonBase {
537  Base::Ptr base_;
538 
539 public:
540  PythonBase() {}
541 
542  explicit PythonBase(const Base::Ptr &base)
543  : base_(base) {
544  ASSERT_not_null(base);
545  }
546 
547  std::string unparse(const Partitioner2::Partitioner &p) const {
548  return base_->unparse(p);
549  }
550 
551  void print(const Partitioner2::Partitioner &p) const {
552  base_->unparse(std::cout, p);
553  }
554 };
555 #endif
556 
557 } // namespace
558 } // namespace
559 } // namespace
560 
561 #endif
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.
Collection of streams.
Definition: Message.h:1579
const char * Flags(long)
Convert Rose::BinaryAnalysis::Unparser::ArrowMargin::Flags enum constant to a string.
Definition: stringify.C:9
STL namespace.
Holds a value or nothing.
Definition: Optional.h:49
Main namespace for the ROSE library.
Describes (part of) a physical CPU register.
Name space for the entire library.
Definition: Access.h:13
Sawyer::SharedPointer< Function > FunctionPtr
Shared-ownership pointer for function.
Definition: BasicTypes.h:434
Base class for expressions.
Prints a register name even when no dictionary is available or when the dictionary doesn't contain an...
Definition: Registers.h:354
Base class for binary types.
Base class for reference counted objects.
Definition: SharedObject.h:22
Represents no value.
Definition: Optional.h:32
Sawyer::SharedPointer< Progress > Ptr
Progress objects are reference counted.
Definition: Progress.h:167