00001 #ifndef ROSE_AsmFunctionIndex_H
00002 #define ROSE_AsmFunctionIndex_H
00003
00004 #include <algorithm>
00005 #include <ostream>
00006 #include <vector>
00007
00008 #include "callbacks.h"
00009
00058 class AsmFunctionIndex {
00059
00060
00061
00062 public:
00063
00065 AsmFunctionIndex() {
00066 init();
00067 }
00068
00070 AsmFunctionIndex(SgNode *ast) {
00071 init();
00072 add_functions(ast);
00073 }
00074
00075 virtual ~AsmFunctionIndex() {}
00076
00078 virtual void add_function(SgAsmFunction*);
00079
00083 virtual void add_functions(SgNode *ast);
00084
00086 virtual void clear() {
00087 functions.clear();
00088 }
00089
00091 virtual bool empty() const {
00092 return functions.empty();
00093 }
00094
00096 virtual size_t size() const {
00097 return functions.size();
00098 }
00099
00100
00101
00102
00103
00104
00105 public:
00106
00108 struct SortByEntryAddr {
00109 bool operator()(SgAsmFunction *a, SgAsmFunction *b) {
00110 return a->get_entry_va() < b->get_entry_va();
00111 }
00112 bool unique(SgAsmFunction *a, SgAsmFunction *b) {
00113 return a->get_entry_va() != b->get_entry_va();
00114 }
00115 };
00116
00118 struct SortByBeginAddr {
00119 bool operator()(SgAsmFunction *a, SgAsmFunction *b) {
00120 return val(a)<val(b);
00121 }
00122 bool unique(SgAsmFunction *a, SgAsmFunction *b) {
00123 return val(a)!=val(b);
00124 }
00125 rose_addr_t val(SgAsmFunction *x) {
00126 rose_addr_t lo;
00127 x->get_extent(NULL, &lo);
00128 return lo;
00129 }
00130 };
00131
00133 struct SortByInsnsSize {
00134 bool operator()(SgAsmFunction *a, SgAsmFunction *b) {
00135 return val(a) < val(b);
00136 }
00137 bool unique(SgAsmFunction *a, SgAsmFunction *b) {
00138 return val(a) != val(b);
00139 }
00140 size_t val(SgAsmFunction *x) {
00141 return SageInterface::querySubTree<SgAsmInstruction>(x).size();
00142 }
00143 };
00144
00147 struct SortByBytesSize {
00148 bool operator()(SgAsmFunction *a, SgAsmFunction *b) {
00149 return val(a) < val(b);
00150 }
00151 bool unique(SgAsmFunction *a, SgAsmFunction *b) {
00152 return val(a) != val(b);
00153 }
00154 size_t val(SgAsmFunction *x) {
00155 ExtentMap extent;
00156 x->get_extent(&extent);
00157 return extent.size();
00158 }
00159 };
00160
00162 struct SortByName {
00163 bool operator()(SgAsmFunction *a, SgAsmFunction *b) {
00164 return a->get_name().compare(b->get_name()) < 0;
00165 }
00166 bool unique(SgAsmFunction *a, SgAsmFunction *b) {
00167 return 0 != a->get_name().compare(b->get_name());
00168 }
00169 };
00170
00171
00172
00173
00174
00175
00176 public:
00177
00183 template<class Comparator> AsmFunctionIndex& sort(Comparator comp, bool unique=false) {
00184 std::stable_sort(functions.begin(), functions.end(), comp);
00185 if (unique) {
00186 Functions newlist;
00187 for (Functions::iterator fi=functions.begin(); fi!=functions.end(); fi++) {
00188 if (newlist.empty() || comp.unique(newlist.back(), *fi))
00189 newlist.push_back(*fi);
00190 }
00191 if (newlist.size()!=functions.size())
00192 functions = newlist;
00193 }
00194 return *this;
00195 }
00196
00200 AsmFunctionIndex& sort_by_entry_addr(bool unique=false) { return sort(SortByEntryAddr(), unique); }
00201 AsmFunctionIndex& sort_by_begin_addr(bool unique=false) { return sort(SortByBeginAddr(), unique); }
00202 AsmFunctionIndex& sort_by_ninsns(bool unique=false) { return sort(SortByInsnsSize(), unique); }
00203 AsmFunctionIndex& sort_by_nbytes(bool unique=false) { return sort(SortByBytesSize(), unique); }
00204 AsmFunctionIndex& sort_by_name(bool unique=false) { return sort(SortByName(), unique); }
00208 AsmFunctionIndex& reverse() {
00209 std::reverse(functions.begin(), functions.end());
00210 return *this;
00211 }
00212
00213
00214
00215
00216 public:
00217 class Footnotes {
00218 public:
00219 Footnotes() {
00220 set_footnote_title("== Footnotes ==");
00221 }
00222
00230 size_t add_footnote(const std::string &text);
00231
00236 void change_footnote(size_t idx, const std::string &text);
00237
00240 const std::string& get_footnote(size_t idx) const;
00241
00244 size_t size() const { return footnotes.size(); }
00245
00248 void set_footnote_title(const std::string &title);
00249
00251 const std::string& get_footnote_title() const;
00252
00255 void set_footnote_prefix(const std::string &prefix) { footnote_prefix = prefix; }
00256
00258 const std::string& get_footnote_prefix() const { return footnote_prefix; }
00259
00261 std::string get_footnote_name(size_t idx) const;
00262
00264 void print(std::ostream&) const;
00265
00267 friend std::ostream& operator<<(std::ostream &o, const Footnotes *footnotes) {
00268 footnotes->print(o);
00269 return o;
00270 }
00271
00272 protected:
00273 std::vector<std::string> footnotes;
00274 std::string footnote_prefix;
00275 };
00276
00277
00278
00279
00280 public:
00282 virtual void print(std::ostream&) const;
00283 friend std::ostream& operator<<(std::ostream&, const AsmFunctionIndex&);
00284
00285
00286
00287
00288
00289
00290 public:
00291
00307 class OutputCallback {
00308 public:
00310 struct GeneralArgs {
00311 GeneralArgs(const AsmFunctionIndex *index, std::ostream &output, Footnotes *footnotes)
00312 : index(index), output(output), footnotes(footnotes) {}
00313 const AsmFunctionIndex *index;
00314 std::ostream &output;
00315 Footnotes *footnotes;
00316 };
00317
00319 struct BeforeAfterArgs: public GeneralArgs {
00320 BeforeAfterArgs(const AsmFunctionIndex *index, std::ostream &output, Footnotes *footnotes, int when)
00321 : GeneralArgs(index, output, footnotes), when(when) {}
00322 int when;
00323 };
00324
00327 struct HeadingArgs: public GeneralArgs {
00328 HeadingArgs(const AsmFunctionIndex *index, std::ostream &output, Footnotes *footnotes, char sep='\0')
00329 : GeneralArgs(index, output, footnotes), sep(sep) {}
00330 char sep;
00331 };
00332
00334 struct DataArgs: public GeneralArgs {
00335 DataArgs(const AsmFunctionIndex *index, std::ostream &output, Footnotes *footnotes, SgAsmFunction *func, size_t rowid)
00336 : GeneralArgs(index, output, footnotes), func(func), rowid(rowid) {}
00337 SgAsmFunction *func;
00338 size_t rowid;
00339 };
00340
00344 OutputCallback(const std::string &name, size_t width, const std::string description="")
00345 : name(name), desc(description), width(width), header_prefix(" "), separator_prefix(" "), data_prefix(" ") {
00346 assert(width>0 || name.empty());
00347 }
00348
00349 virtual ~OutputCallback() {}
00350
00352 void set_prefix(const std::string &header, const std::string &separator=" ", const std::string &data=" ");
00353
00356 virtual bool operator()(bool enabled, const BeforeAfterArgs&);
00357
00360 virtual bool operator()(bool enabled, const HeadingArgs&);
00361
00364 virtual bool operator()(bool enabled, const DataArgs&);
00365
00366 protected:
00367 std::string center(const std::string&, size_t width);
00369 std::string name;
00370 std::string desc;
00371 size_t width;
00372 std::string header_prefix;
00373 std::string separator_prefix;
00374 std::string data_prefix;
00375 };
00376
00377
00378
00379
00380
00381
00382 public:
00383
00385 class RowIdCallback: public OutputCallback {
00386 public:
00387 RowIdCallback(): OutputCallback("Num", 4) {}
00388 virtual bool operator()(bool enabled, const DataArgs&);
00389 } rowIdCallback;
00390
00392 class EntryAddrCallback: public OutputCallback {
00393 public:
00394 EntryAddrCallback(): OutputCallback("Entry-Addr", 10) {}
00395 virtual bool operator()(bool enabled, const DataArgs&);
00396 } entryAddrCallback;
00397
00399 class BeginAddrCallback: public OutputCallback {
00400 public:
00401 BeginAddrCallback(): OutputCallback("Begin-Addr", 10) {}
00402 virtual bool operator()(bool enabled, const DataArgs&);
00403 } beginAddrCallback;
00404
00406 class EndAddrCallback: public OutputCallback {
00407 public:
00408 EndAddrCallback(): OutputCallback("End-Addr", 10) {}
00409 virtual bool operator()(bool enabled, const DataArgs&);
00410 } endAddrCallback;
00411
00413 class SizeInsnsCallback: public OutputCallback {
00414 public:
00415 SizeInsnsCallback(): OutputCallback("Insns", 5) {}
00416 virtual bool operator()(bool enabled, const DataArgs&);
00417 } sizeInsnsCallback;
00418
00420 class SizeBytesCallback: public OutputCallback {
00421 public:
00422 SizeBytesCallback(): OutputCallback("Bytes", 6) {
00423 set_prefix("/", "-", "/");
00424 }
00425 virtual bool operator()(bool enabled, const DataArgs&);
00426 } sizeBytesCallback;
00427
00429 class ReasonCallback: public OutputCallback {
00430 public:
00431 ReasonCallback(): OutputCallback("Reason", 1) {}
00432 virtual bool operator()(bool enabled, const HeadingArgs&);
00433 virtual bool operator()(bool enabled, const DataArgs&);
00434 } reasonCallback;
00435
00437 class CallingConventionCallback: public OutputCallback {
00438 public:
00439 CallingConventionCallback(): OutputCallback("Kind", 8) {}
00440 virtual bool operator()(bool enabled, const DataArgs&);
00441 } callingConventionCallback;
00442
00444 class NameCallback: public OutputCallback {
00445 public:
00446 NameCallback(): OutputCallback("Name", 32) {}
00447 virtual bool operator()(bool enabled, const DataArgs&);
00448 } nameCallback;
00449
00451 class FootnotesCallback: public OutputCallback {
00452 public:
00453 FootnotesCallback(): OutputCallback("", 0) {}
00454 virtual bool operator()(bool enabled, const BeforeAfterArgs&);
00455 } footnotesCallback;
00456
00457
00458
00459
00460
00461
00462 protected:
00463 typedef std::vector<SgAsmFunction*> Functions;
00464 Functions functions;
00467 virtual void init();
00468
00470 ROSE_Callbacks::List<OutputCallback> output_callbacks;
00471 };
00472
00473
00474 #endif