ROSE  0.10.5.0
AsmFunctionIndex.h
1 #ifndef ROSE_AsmFunctionIndex_H
2 #define ROSE_AsmFunctionIndex_H
3 #include <rosePublicConfig.h>
4 #ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT
5 
6 #include <algorithm>
7 #include <ostream>
8 #include <vector>
9 
10 #include "callbacks.h"
11 #include "Diagnostics.h"
12 
13 namespace Rose {
14 namespace BinaryAnalysis {
15 
80  /**************************************************************************************************************************
81  * The main public members
82  **************************************************************************************************************************/
83 public:
84 
87  init();
88  }
89 
92  init();
93  add_functions(ast);
94  }
95 
96  virtual ~AsmFunctionIndex() {}
97 
99  virtual void add_function(SgAsmFunction*);
100 
104  virtual void add_functions(SgNode *ast);
105 
107  virtual void clear() {
108  functions.clear();
109  }
110 
112  virtual bool empty() const {
113  return functions.empty();
114  }
115 
117  virtual size_t size() const {
118  return functions.size();
119  }
120 
121  /**************************************************************************************************************************
122  * Functors for sorting
123  * These are expected to be commonly used, so we define them here for convenience. The generic sorting method is defined
124  * below.
125  **************************************************************************************************************************/
126 public:
127 
130  bool operator()(SgAsmFunction *a, SgAsmFunction *b) {
131  return a->get_entry_va() < b->get_entry_va();
132  }
133  bool unique(SgAsmFunction *a, SgAsmFunction *b) {
134  return a->get_entry_va() != b->get_entry_va();
135  }
136  };
137 
140  bool operator()(SgAsmFunction *a, SgAsmFunction *b) {
141  return val(a)<val(b);
142  }
143  bool unique(SgAsmFunction *a, SgAsmFunction *b) {
144  return val(a)!=val(b);
145  }
146  rose_addr_t val(SgAsmFunction *x) {
147  rose_addr_t lo;
148  x->get_extent(NULL, &lo);
149  return lo;
150  }
151  };
152 
155  bool operator()(SgAsmFunction *a, SgAsmFunction *b) {
156  return val(a) < val(b);
157  }
158  bool unique(SgAsmFunction *a, SgAsmFunction *b) {
159  return val(a) != val(b);
160  }
161  size_t val(SgAsmFunction *x) {
162  return SageInterface::querySubTree<SgAsmInstruction>(x).size();
163  }
164  };
165 
169  bool operator()(SgAsmFunction *a, SgAsmFunction *b) {
170  return val(a) < val(b);
171  }
172  bool unique(SgAsmFunction *a, SgAsmFunction *b) {
173  return val(a) != val(b);
174  }
175  size_t val(SgAsmFunction *x) {
176  AddressIntervalSet extent;
177  x->get_extent(&extent);
178  return extent.size();
179  }
180  };
181 
183  struct SortByName {
184  bool operator()(SgAsmFunction *a, SgAsmFunction *b) {
185  return a->get_name().compare(b->get_name()) < 0;
186  }
187  bool unique(SgAsmFunction *a, SgAsmFunction *b) {
188  return 0 != a->get_name().compare(b->get_name());
189  }
190  };
191 
192 
193 
194  /**************************************************************************************************************************
195  * Sorting methods
196  **************************************************************************************************************************/
197 public:
198 
204  template<class Comparator> AsmFunctionIndex& sort(Comparator comp, bool unique=false) {
205  std::stable_sort(functions.begin(), functions.end(), comp);
206  if (unique) {
207  Functions newlist;
208  for (Functions::iterator fi=functions.begin(); fi!=functions.end(); fi++) {
209  if (newlist.empty() || comp.unique(newlist.back(), *fi))
210  newlist.push_back(*fi);
211  }
212  if (newlist.size()!=functions.size())
213  functions = newlist;
214  }
215  return *this;
216  }
217 
221  AsmFunctionIndex& sort_by_entry_addr(bool unique=false) { return sort(SortByEntryAddr(), unique); }
222  AsmFunctionIndex& sort_by_begin_addr(bool unique=false) { return sort(SortByBeginAddr(), unique); }
223  AsmFunctionIndex& sort_by_ninsns(bool unique=false) { return sort(SortByInsnsSize(), unique); }
224  AsmFunctionIndex& sort_by_nbytes(bool unique=false) { return sort(SortByBytesSize(), unique); }
225  AsmFunctionIndex& sort_by_name(bool unique=false) { return sort(SortByName(), unique); }
230  std::reverse(functions.begin(), functions.end());
231  return *this;
232  }
233 
234  /**************************************************************************************************************************
235  * Footnotes
236  **************************************************************************************************************************/
237 public:
238  class Footnotes {
239  public:
240  Footnotes() {
241  set_footnote_title("== Footnotes ==");
242  }
243 
251  size_t add_footnote(const std::string &text);
252 
257  void change_footnote(size_t idx, const std::string &text);
258 
261  const std::string& get_footnote(size_t idx) const;
262 
265  size_t size() const { return footnotes.size(); }
266 
269  void set_footnote_title(const std::string &title);
270 
272  const std::string& get_footnote_title() const;
273 
276  void set_footnote_prefix(const std::string &prefix) { footnote_prefix = prefix; }
277 
279  const std::string& get_footnote_prefix() const { return footnote_prefix; }
280 
282  std::string get_footnote_name(size_t idx) const;
283 
285  void print(std::ostream&) const;
286 
288  friend std::ostream& operator<<(std::ostream &o, const Footnotes *footnotes) {
289  footnotes->print(o);
290  return o;
291  }
292 
293  protected:
294  std::vector<std::string> footnotes;
295  std::string footnote_prefix;
296  };
297 
298  /**************************************************************************************************************************
299  * Output methods
300  **************************************************************************************************************************/
301 public:
303  virtual void print(std::ostream&) const;
304  friend std::ostream& operator<<(std::ostream&, const AsmFunctionIndex&);
305 
306 
307 
308  /**************************************************************************************************************************
309  * Output callback base classes
310  **************************************************************************************************************************/
311 public:
312 
329  public:
331  struct GeneralArgs {
333  : index(index), output(output), footnotes(footnotes) {}
335  std::ostream &output;
337  };
338 
340  struct BeforeAfterArgs: public GeneralArgs {
341  BeforeAfterArgs(const AsmFunctionIndex *index, std::ostream &output, Footnotes *footnotes, int when)
342  : GeneralArgs(index, output, footnotes), when(when) {}
343  int when;
344  };
345 
348  struct HeadingArgs: public GeneralArgs {
349  HeadingArgs(const AsmFunctionIndex *index, std::ostream &output, Footnotes *footnotes, char sep='\0')
350  : GeneralArgs(index, output, footnotes), sep(sep) {}
351  char sep;
352  };
353 
355  struct DataArgs: public GeneralArgs {
356  DataArgs(const AsmFunctionIndex *index, std::ostream &output, Footnotes *footnotes, SgAsmFunction *func, size_t rowid)
357  : GeneralArgs(index, output, footnotes), func(func), rowid(rowid) {}
358  SgAsmFunction *func;
359  size_t rowid;
360  };
361 
365  OutputCallback(const std::string &name, size_t width, const std::string description="")
366  : name(name), desc(description), width(width), header_prefix(" "), separator_prefix(" "), data_prefix(" ") {
367  ASSERT_require(width>0 || name.empty());
368  }
369 
370  virtual ~OutputCallback() {}
371 
373  void set_prefix(const std::string &header, const std::string &separator=" ", const std::string &data=" ");
374 
377  virtual bool operator()(bool enabled, const BeforeAfterArgs&);
378 
381  virtual bool operator()(bool enabled, const HeadingArgs&);
382 
385  virtual bool operator()(bool enabled, const DataArgs&);
386 
387  protected:
388  std::string center(const std::string&, size_t width);
390  std::string name;
391  std::string desc;
392  size_t width;
393  std::string header_prefix;
394  std::string separator_prefix;
395  std::string data_prefix;
396  };
397 
398 
399 
400  /**************************************************************************************************************************
401  * Predefined output callbacks
402  **************************************************************************************************************************/
403 public:
404 
407  public:
408  RowIdCallback(): OutputCallback("Num", 4) {}
409  virtual bool operator()(bool enabled, const DataArgs&);
410  } rowIdCallback;
411 
414  public:
415  EntryAddrCallback(): OutputCallback("Entry-Addr", 10) {}
416  virtual bool operator()(bool enabled, const DataArgs&);
417  } entryAddrCallback;
418 
421  public:
422  BeginAddrCallback(): OutputCallback("Begin-Addr", 10) {}
423  virtual bool operator()(bool enabled, const DataArgs&);
424  } beginAddrCallback;
425 
428  public:
429  EndAddrCallback(): OutputCallback("End-Addr", 10) {}
430  virtual bool operator()(bool enabled, const DataArgs&);
431  } endAddrCallback;
432 
435  public:
436  SizeInsnsCallback(): OutputCallback("Insns", 5) {}
437  virtual bool operator()(bool enabled, const DataArgs&);
438  } sizeInsnsCallback;
439 
442  public:
443  SizeBytesCallback(): OutputCallback("Bytes", 6) {
444  set_prefix("/", "-", "/");
445  }
446  virtual bool operator()(bool enabled, const DataArgs&);
447  } sizeBytesCallback;
448 
451  public:
452  ReasonCallback(): OutputCallback("Reason", 1) {} // width will be overridden in the callback
453  virtual bool operator()(bool enabled, const HeadingArgs&);
454  virtual bool operator()(bool enabled, const DataArgs&);
455  } reasonCallback;
456 
459  public:
460  CallingConventionCallback(): OutputCallback("CallConv", 8) {}
461  virtual bool operator()(bool enabled, const DataArgs&);
462  } callingConventionCallback;
463 
466  public:
467  MayReturnCallback(): OutputCallback("Returns", 9) {}
468  virtual bool operator()(bool enabled, const DataArgs&);
469  } mayReturnCallback;
470 
473  public:
474  StackDeltaCallback(): OutputCallback("Stack", 9) {}
475  virtual bool operator()(bool enabled, const HeadingArgs&);
476  virtual bool operator()(bool enabled, const DataArgs&);
477  } stackDeltaCallback;
478 
480  class NameCallback: public OutputCallback {
481  public:
482  NameCallback(): OutputCallback("Name", 32) {}
483  virtual bool operator()(bool enabled, const DataArgs&);
484  } nameCallback;
485 
488  public:
489  FootnotesCallback(): OutputCallback("", 0) {} // not a table column
490  virtual bool operator()(bool enabled, const BeforeAfterArgs&);
491  } footnotesCallback;
492 
493 
494 
495  /**************************************************************************************************************************
496  * Miscellaneous
497  **************************************************************************************************************************/
498 protected:
499  typedef std::vector<SgAsmFunction*> Functions;
500  Functions functions;
503  virtual void init();
504 
507 };
508 
509 } // namespace
510 } // namespace
511 
512 #endif
513 #endif
std::string data_prefix
Character(s) to print before data cells.
void set_footnote_prefix(const std::string &prefix)
Set the footnote prefix string.
List of callback functors.
Definition: callbacks.h:82
void print(std::ostream &) const
Print non-empty footnotes.
virtual bool operator()(bool enabled, const DataArgs &)
Callback to print data for a table cell.
Functor for sorting by function entry virtual address.
void set_footnote_title(const std::string &title)
Change the footnote title string.
Print number of instructions in function.
Callbacks::List< OutputCallback > output_callbacks
List of callbacks to be invoked when printing columns.
std::string name
Column name used when printing table headers.
virtual bool operator()(bool enabled, const DataArgs &)
Callback to print data for a table cell.
std::string get_footnote_name(size_t idx) const
Generates a footnote name from a footnote index.
AsmFunctionIndex & sort_by_name(bool unique=false)
Specific sorting method.
std::string separator_prefix
Character(s) to print before line separators.
std::vector< std::string > footnotes
List of footnotes.
void change_footnote(size_t idx, const std::string &text)
Change the text associated with a footnote.
virtual bool operator()(bool enabled, const DataArgs &)
Callback to print data for a table cell.
Represents a synthesized function.
size_t size() const
Returns the number of footnotes.
Functor for sorting by number of instructions in function.
Main namespace for the ROSE library.
const std::string & get_footnote(size_t idx) const
Get the string for a footnote.
char sep
If non-NUL, then print a line of these characters.
virtual bool operator()(bool enabled, const HeadingArgs &)
Callback to print a column heading.
AsmFunctionIndex()
Constructs an empty index.
AsmFunctionIndex & reverse()
Reverse the order of the functions.
AsmFunctionIndex & sort_by_begin_addr(bool unique=false)
Specific sorting method.
virtual bool empty() const
Determines if an index is empty.
virtual void init()
Initializes the callback lists.
std::string header_prefix
Character(s) to print before headings.
virtual bool operator()(bool enabled, const DataArgs &)
Callback to print data for a table cell.
Functions functions
Functions in index order.
AsmFunctionIndex & sort_by_entry_addr(bool unique=false)
Specific sorting method.
std::ostream & output
Stream to which index is being printed.
Functor for sorting by function beginning address.
const std::string & get_name() const
Property: Name.
const AsmFunctionIndex * index
Index object being printed.
size_t get_extent(AddressIntervalSet *emap=NULL, rose_addr_t *lo_addr=NULL, rose_addr_t *hi_addr=NULL, NodeSelector *selector=NULL)
Returns information about the function addresses.
This class represents the base class for all IR nodes within Sage III.
Definition: Cxx_Grammar.h:9176
int when
Zero implies before table, one implies after table.
virtual void clear()
Clears the index.
virtual void add_function(SgAsmFunction *)
Adds a function to the end of this index.
const std::string & get_footnote_prefix() const
Get the footnote prefix string.
AsmFunctionIndex & sort_by_ninsns(bool unique=false)
Specific sorting method.
const std::string & get_footnote_title() const
Get the footnote title.
OutputCallback(const std::string &name, size_t width, const std::string description="")
Constructor.
virtual bool operator()(bool enabled, const DataArgs &)
Callback to print data for a table cell.
size_t width
Minimum width of column header or data.
virtual void add_functions(SgNode *ast)
Adds functions to this index.
virtual bool operator()(bool enabled, const HeadingArgs &)
Callback to print a column heading.
virtual size_t size() const
Returns the number of functions in the index.
rose_addr_t get_entry_va() const
Property: Primary entry address.
AsmFunctionIndex & sort(Comparator comp, bool unique=false)
Sort the functions in the index.
std::string center(const std::string &, size_t width)
Center s in a string of length width.
AsmFunctionIndex & sort_by_nbytes(bool unique=false)
Specific sorting method.
std::string footnote_prefix
String to emit before every footnote line.
virtual bool operator()(bool enabled, const DataArgs &)
Callback to print data for a table cell.
virtual bool operator()(bool enabled, const DataArgs &)
Callback to print data for a table cell.
virtual bool operator()(bool enabled, const DataArgs &)
Callback to print data for a table cell.
AsmFunctionIndex(SgNode *ast)
Constructs an index from an AST.
virtual bool operator()(bool enabled, const DataArgs &)
Callback to print data for a table cell.
Functions indexed by entry address.
Interval::Value size() const
Number of scalar elements represented.
Definition: IntervalSet.h:308
std::string desc
Optional description to appear in footnote.
friend std::ostream & operator<<(std::ostream &o, const Footnotes *footnotes)
Print non-empty footnotes.
Footnotes * footnotes
Footnotes (newly created for each index output).
virtual void print(std::ostream &) const
Prints a function index to an output stream.
size_t add_footnote(const std::string &text)
Adds a footnote to the table.
virtual bool operator()(bool enabled, const BeforeAfterArgs &)
Callback for before and after the table.
virtual bool operator()(bool enabled, const BeforeAfterArgs &)
Callback for before and after the table.
void set_prefix(const std::string &header, const std::string &separator=" ", const std::string &data=" ")
Set prefix characters.
Functor for sorting by number of bytes in function.