ROSE  0.11.83.2
AsmFunctionIndex.h
1 #ifndef ROSE_BinaryAnalysis_AsmFunctionIndex_H
2 #define ROSE_BinaryAnalysis_AsmFunctionIndex_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
5 
6 #include <algorithm>
7 #include <ostream>
8 #include <vector>
9 
10 #include "callbacks.h"
11 #include <Rose/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.
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.