ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Partitioner.h
Go to the documentation of this file.
1 #ifndef ROSE_DISASSEMBLER_PARTITIONER_H
2 #define ROSE_DISASSEMBLER_PARTITIONER_H
3 
4 #include "callbacks.h"
5 #include "Disassembler.h"
6 
7 #ifndef NAN
8 #define INFINITY (DBL_MAX+DBL_MAX)
9 #define NAN (INFINITY-INFINITY)
10 #endif
11 
116 class Partitioner {
117  /*************************************************************************************************************************
118  * Public Exceptions
119  *************************************************************************************************************************/
120 public:
121  struct Exception {
122  std::string mesg;
123  Exception(const std::string &mesg): mesg(mesg) {}
124  void print(std::ostream &o) const { o <<mesg; }
125  friend std::ostream& operator<<(std::ostream &o, const Exception &e);
126  };
127 
128  /*************************************************************************************************************************
129  * Data Structures Useful to Subclasses
130  *************************************************************************************************************************/
131 protected:
132 
133  struct Function;
134  struct DataBlock;
135  struct BasicBlock;
136 
140  class Instruction {
141  public:
142  Instruction(SgAsmInstruction *node): node(node), bblock(NULL) { assert(node!=NULL); }
146  /* These methods are forwarded to the underlying instruction node for convenience. */
147  Disassembler::AddressSet get_successors(bool *complete) const { return node->get_successors(complete); }
148  rose_addr_t get_address() const { return node->get_address(); }
149  size_t get_size() const { return node->get_size(); }
151  SgUnsignedCharList get_raw_bytes() const { return node->get_raw_bytes(); } // FIXME: should return const ref?
152  };
153 
154  typedef std::map<rose_addr_t, Instruction*> InstructionMap;
155  typedef std::vector<Instruction*> InstructionVector;
156 
175  public:
177  function_return(false), alias_for(0) {}
178  void clear() {
179  age = 0;
180  sucs.clear();
181  sucs_complete = false;
182  is_function_call = false;
184  function_return = false;
185  alias_for = 0;
186  }
187 
188  size_t age;
207  };
208 
215  struct BasicBlock {
218  BasicBlock(): reason(SgAsmBlock::BLK_NONE), function(NULL), code_likelihood(1.0) {}
219 
223 
225  bool valid_cache() const { return cache.age==insns.size(); }
226 
228  void invalidate_cache() { cache.age=0; }
229 
231  void validate_cache() { cache.age=insns.size(); }
232 
235  void clear_data_blocks();
236 
237  Instruction* last_insn() const;
238  rose_addr_t address() const; /* Return the address of the basic block's first (entry) instruction. */
239  unsigned reason;
240  std::vector<Instruction*> insns;
241  std::set<DataBlock*> data_blocks;
243  Function* function;
245  };
246  typedef std::map<rose_addr_t, BasicBlock*> BasicBlocks;
247 
260  struct DataBlock {
264  DataBlock(): reason(SgAsmBlock::BLK_NONE), function(NULL), basic_block(NULL) {}
265 
269 
270  rose_addr_t address() const; /* Return the address of the first node of a data block. */
271  std::vector<SgAsmStaticData*> nodes;
272  unsigned reason;
273  Function *function;
275  };
276  typedef std::map<rose_addr_t, DataBlock*> DataBlocks;
277 
279  class Function {
280  public:
282  : reason(0), pending(true), entry_va(entry_va),
283  may_return_cur(SgAsmFunction::RET_UNKNOWN), may_return_old(SgAsmFunction::RET_UNKNOWN) {}
285  : reason(r), pending(true), entry_va(entry_va),
286  may_return_cur(SgAsmFunction::RET_UNKNOWN), may_return_old(SgAsmFunction::RET_UNKNOWN) {}
287  Function(rose_addr_t entry_va, unsigned r, const std::string& name)
288  : reason(r), name(name), pending(true), entry_va(entry_va),
289  may_return_cur(SgAsmFunction::RET_UNKNOWN), may_return_old(SgAsmFunction::RET_UNKNOWN) {}
290 
292  void clear_basic_blocks();
293 
295  void clear_data_blocks();
296 
298  void move_basic_blocks_from(Function *other);
299 
301  void move_data_blocks_from(Function *other);
302 
310  void set_may_return(SgAsmFunction::MayReturn may_return) { may_return_cur = may_return; }
316  bool possible_may_return() const {
318  }
319 
324 
328  Function *init_properties(const Function &other);
329 
331  void show_properties(FILE*) const;
332 
335  BasicBlock *entry_basic_block() const;
336 
337  public:
338  /* If you add more data members, also update detach_thunk() and/or init_properties() */
339  unsigned reason;
340  std::string name;
343  bool pending;
347  private:
348  /* If you add more data members, also update detach_thunk() and/or init_properties() */
351  };
352  typedef std::map<rose_addr_t, Function*> Functions;
353 
356 
358  struct BlockConfig {
360  size_t ninsns;
366  };
367  typedef std::map<rose_addr_t, BlockConfig*> BlockConfigMap;
368 
369  /*************************************************************************************************************************
370  * Deprecated
371  *************************************************************************************************************************/
372 public:
373 
374  /* FIXME: Backward compatibility stuff prior to 2010-01-01. These are deprecated and should eventually be removed. They
375  * are currently used by src/midend/binaryAnalyses/binary_analysis.C for some of the CFG and call graph functions. */
376 
383  typedef std::map<rose_addr_t, Disassembler::AddressSet> BasicBlockStarts;
384 
389 
394  struct FunctionStart {
395  FunctionStart(unsigned reason, std::string name): reason(reason), name(name) {}
396  unsigned reason;
397  std::string name;
398  };
399 
404  typedef std::map<rose_addr_t, FunctionStart> FunctionStarts;
405 
410  BasicBlockStarts &bb_starts/*out*/) const __attribute__((deprecated));
411 
412 
413  /*************************************************************************************************************************
414  * Constructors, etc.
415  *************************************************************************************************************************/
416 public:
417 
419  : aggregate_mean(NULL), aggregate_variance(NULL), code_criteria(NULL), disassembler(NULL), map(NULL),
420  func_heuristics(SgAsmFunction::FUNC_DEFAULT), debug(NULL), allow_discont_blocks(true)
421  {}
422  virtual ~Partitioner() { clear(); }
423 
424  /*************************************************************************************************************************
425  * Accessors for Properties
426  *************************************************************************************************************************/
427 public:
428 
432  virtual void set_search(unsigned heuristics) {
433  func_heuristics = heuristics;
434  }
435 
438  virtual unsigned get_search() const {
439  return func_heuristics;
440  }
441 
473  }
474 
477  return allow_discont_blocks;
478  }
479 
481  void set_debug(FILE *f) {
482  debug = f;
483  }
484 
486  FILE *get_debug() const {
487  return debug;
488  }
489 
506  void set_map(MemoryMap *mmap, MemoryMap *ro_mmap=NULL);
507  MemoryMap *get_map() const {
508  return map;
509  }
515  void set_progress_reporting(FILE*, unsigned min_interval);
516 
517  /*************************************************************************************************************************
518  * High-level Functions
519  *************************************************************************************************************************/
520 public:
521 
529  user_detectors.push_back(f);
530  }
531 
540  static unsigned parse_switches(const std::string&, unsigned initial_flags);
541 
547 
550 
553  virtual void clear();
554 
557  virtual void load_config(const std::string &filename);
558 
562 
566 
570  return bad_insns;
571  }
572 
578  bad_insns.clear();
579  }
580 
585  virtual Instruction* find_instruction(rose_addr_t, bool create=true);
586 
593  virtual Instruction* discard(Instruction*, bool discard_entire_block=false);
594 
598  virtual BasicBlock *discard(BasicBlock*);
599 
603  virtual Function* add_function(rose_addr_t entry_va, unsigned reasons, std::string name="");
604 
606  virtual Function* find_function(rose_addr_t entry_va);
607 
620  virtual SgAsmBlock* build_ast(SgAsmInterpretation *interp=NULL);
621 
625  virtual void fixup_cfg_edges(SgNode *ast);
626 
639  virtual void fixup_pointers(SgNode *ast, SgAsmInterpretation *interp=NULL);
640 
647 
648  /**************************************************************************************************************************
649  * Range maps relating address ranges to objects
650  **************************************************************************************************************************/
651 public:
653  class FunctionRangeMapValue: public RangeMapValue<Extent, Function*> {
654  public:
657 
658  FunctionRangeMapValue split(const Extent &my_range, const Extent::Value &new_end) {
659  assert(my_range.contains(Extent(new_end)));
660  return *this;
661  }
662 
663  void print(std::ostream &o) const {
664  if (NULL==value) {
665  o <<"(null)";
666  } else {
667  o <<"F" <<StringUtility::addrToString(value->entry_va);
668  }
669  }
670  };
671 
674 
676  class DataRangeMapValue: public RangeMapValue<Extent, DataBlock*> {
677  public:
680 
681  DataRangeMapValue split(const Extent &my_range, const Extent::Value &new_end) {
682  assert(my_range.contains(Extent(new_end)));
683  return *this;
684  }
685 
686  void print(std::ostream &o) const {
687  if (NULL==value) {
688  o <<"(null)";
689  } else {
690  o <<"D" <<StringUtility::addrToString(value->address());
691  }
692  }
693  };
694 
697 
698  /**************************************************************************************************************************
699  * Methods for characterizing whether something is code
700  **************************************************************************************************************************/
701 public:
702 
717  class RegionStats {
718  private:
721  DictionaryEntry(const std::string &name, const std::string &desc, double weight)
722  : name(name), desc(desc), weight(weight) {}
723  std::string name;
724  std::string desc;
725  double weight;
726  };
727 
728  struct AnalysisResult {
730  AnalysisResult(double d): sum(d), nsamples(1) {} // implicit
731  double sum;
732  size_t nsamples;
733  };
734 
735  static std::vector<DictionaryEntry> dictionary;
736  std::vector<AnalysisResult> results;
737 
738  public:
746  };
747 
749  virtual ~RegionStats() {}
750  virtual RegionStats* create() const;
753  static size_t define_analysis(const std::string &name, const std::string &desc, double weight, size_t id=(size_t)(-1));
754  static size_t find_analysis(const std::string &name);
755  static size_t get_nanalyses();
756  static const std::string& get_name(size_t id);
757  static const std::string& get_desc(size_t id);
758  static double get_weight(size_t id);
760  virtual void add_sample(size_t id, double val, size_t nsamples=1);
761  virtual size_t get_nsamples(size_t id) const;
762  virtual double get_sum(size_t id) const;
763  virtual double get_value(size_t id) const;
764  virtual void compute_ratios();
765  virtual void set_value(size_t id, double val);
767  double divnan(size_t num_id, size_t den_id) const;
768  void add_samples(const RegionStats*);
769  void square_diff(const RegionStats*);
771  virtual void print(std::ostream&) const;
772  friend std::ostream& operator<<(std::ostream&, const RegionStats&);
773  protected:
774  static void init_class();
775 
776  };
777 
841  class CodeCriteria {
842  private:
845  DictionaryEntry(const std::string &name, const std::string &desc): name(name), desc(desc) {}
846  std::string name;
847  std::string desc;
848  };
849 
850  struct Criterion {
851  Criterion(): mean(0.0), variance(0.0), weight(0.0) {}
852  double mean;
853  double variance;
854  double weight;
855  };
856 
857  static std::vector<DictionaryEntry> dictionary;
858  std::vector<Criterion> criteria;
859  double threshold;
860 
861  public:
863  CodeCriteria(const RegionStats *mean, const RegionStats *variance, double threshold) {
864  init_class();
865  init(mean, variance, threshold);
866  }
867  virtual ~CodeCriteria() {}
868  virtual CodeCriteria* create() const;
869 
870  static size_t define_criterion(const std::string &name, const std::string &desc, size_t id=(size_t)(-1));
871  static size_t find_criterion(const std::string &name);
872  static size_t get_ncriteria();
873  static const std::string& get_name(size_t id);
874  static const std::string& get_desc(size_t id);
875 
876  virtual double get_mean(size_t id) const;
877  virtual void set_mean(size_t id, double mean);
878  virtual double get_variance(size_t id) const;
879  virtual void set_variance(size_t id, double variance);
880  virtual double get_weight(size_t id) const;
881  virtual void set_weight(size_t id, double weight);
882  void set_value(size_t id, double mean, double variance, double weight) {
883  set_mean(id, mean);
884  set_variance(id, variance);
885  set_weight(id, weight);
886  }
887 
888  double get_threshold() const { return threshold; }
889  void set_threshold(double th) { threshold=th; }
890  virtual double get_vote(const RegionStats*, std::vector<double> *votes=NULL) const;
891  virtual bool satisfied_by(const RegionStats*, double *raw_vote_ptr=NULL, std::ostream *debug=NULL) const;
892 
893  virtual void print(std::ostream&, const RegionStats *stats=NULL, const std::vector<double> *votes=NULL,
894  const double *total_vote=NULL) const;
895  friend std::ostream& operator<<(std::ostream&, const CodeCriteria&);
896 
897  protected:
898  static void init_class();
899  virtual void init(const RegionStats *mean, const RegionStats *variance, double threshold);
900 
901  };
902 
907  return new RegionStats;
908  }
909 
914  return new CodeCriteria;
915  }
916  virtual CodeCriteria *new_code_criteria(const RegionStats *mean, const RegionStats *variance, double threshold) {
917  return new CodeCriteria(mean, variance, threshold);
918  }
925  virtual RegionStats *region_statistics(const ExtentMap&);
926  virtual RegionStats *region_statistics(Function*);
927  virtual RegionStats *region_statistics();
935  virtual RegionStats *aggregate_statistics(bool do_variance=true);
936 
945  virtual RegionStats *get_aggregate_mean() const { return aggregate_mean; }
952  virtual void clear_aggregate_statistics() {
953  delete aggregate_mean; aggregate_mean = NULL;
954  delete aggregate_variance; aggregate_variance = NULL;
955  }
956 
959  virtual size_t count_kinds(const InstructionMap&);
960  virtual size_t count_kinds() { return count_privileged(insns); }
965  virtual size_t count_privileged(const InstructionMap&);
966  virtual size_t count_privileged() { return count_privileged(insns); }
967  virtual double ratio_privileged() { return insns.empty() ? NAN : (double)count_privileged(insns) / insns.size(); }
972  virtual size_t count_floating_point(const InstructionMap&);
973  virtual size_t count_floating_point() { return count_floating_point(insns); }
974  virtual double ratio_floating_point() { return insns.empty() ? NAN : (double)count_floating_point(insns) / insns.size(); }
983  virtual size_t count_registers(const InstructionMap&, double *mean=NULL, double *variance=NULL);
984  virtual size_t count_registers(double *mean=NULL, double *variance=NULL) { return count_registers(insns, mean, variance); }
985  virtual double ratio_registers(double *mean=NULL, double *variance=NULL) {
986  return insns.empty() ? NAN : (double)count_registers(mean, variance) / insns.size();
987  }
995  virtual double count_size_variance(const InstructionMap &insns);
996  virtual double count_size_variance() { return count_size_variance(insns); }
1010  virtual bool is_code(const ExtentMap &region, double *raw_vote_ptr=NULL, std::ostream *debug=NULL);
1011 
1018  virtual CodeCriteria *get_code_criteria() const { return code_criteria; }
1019  virtual void set_code_criteria(CodeCriteria *cc) { code_criteria = cc; }
1022 protected:
1027  /**************************************************************************************************************************
1028  * Functions for scanning through memory
1029  **************************************************************************************************************************/
1030 public:
1031 
1034  public:
1036  struct Args {
1038  Instruction *insn_end, size_t ninsns)
1039  : partitioner(partitioner), insn_prev(insn_prev), insn_begin(insn_begin), insn_end(insn_end),
1040  ninsns(ninsns) {}
1045  size_t ninsns;
1046  };
1047 
1048  virtual ~InsnRangeCallback() {}
1049 
1051  virtual bool operator()(bool enabled, const Args &args) = 0;
1052  };
1054 
1057  public:
1059  struct Args {
1061  : partitioner(partitioner), restrict_map(restrict_map), ranges(ranges), range(range) {}
1066  };
1067 
1068  virtual ~ByteRangeCallback() {}
1069 
1071  virtual bool operator()(bool enabled, const Args &args) = 0;
1072  };
1074 
1086  Instruction *insn_prev, Instruction *insn_end);
1088  Instruction *insn_prev, Instruction *insn_end) {
1089  InsnRangeCallbacks cblist(callback);
1090  scan_contiguous_insns(insns, cblist, insn_prev, insn_end);
1091  }
1110  virtual void scan_unassigned_insns(InsnRangeCallbacks &callbacks);
1112  InsnRangeCallbacks cblist(callback);
1113  scan_unassigned_insns(cblist);
1114  }
1126  virtual void scan_intrafunc_insns(InsnRangeCallbacks &callbacks);
1128  InsnRangeCallbacks cblist(callback);
1129  scan_intrafunc_insns(cblist);
1130  }
1147  virtual void scan_interfunc_insns(InsnRangeCallbacks &callbacks);
1149  InsnRangeCallbacks cblist(callback);
1150  scan_interfunc_insns(cblist);
1151  }
1163  virtual void scan_unassigned_bytes(ByteRangeCallbacks &callbacks, MemoryMap *restrict_map=NULL);
1164  void scan_unassigned_bytes(ByteRangeCallback *callback, MemoryMap *restrict_map=NULL) {
1165  ByteRangeCallbacks cblist(callback);
1166  scan_unassigned_bytes(cblist, restrict_map);
1167  }
1178  virtual void scan_intrafunc_bytes(ByteRangeCallbacks &callbacks, MemoryMap *restrict_map=NULL);
1179  void scan_intrafunc_bytes(ByteRangeCallback *callback, MemoryMap *restrict_map=NULL) {
1180  ByteRangeCallbacks cblist(callback);
1181  scan_intrafunc_bytes(cblist, restrict_map);
1182  }
1193  virtual void scan_interfunc_bytes(ByteRangeCallbacks &callbacks, MemoryMap *restrict_map=NULL);
1194  void scan_interfunc_bytes(ByteRangeCallback *callback, MemoryMap *restrict_map=NULL) {
1195  ByteRangeCallbacks cblist(callback);
1196  scan_interfunc_bytes(cblist, restrict_map);
1197  }
1210  std::vector<SgUnsignedCharList> patterns;
1211  size_t minimum_nrep;
1212  size_t maximum_nrep;
1216  size_t nfound;
1219  : minimum_nrep(2), maximum_nrep(1024*1024), begins_contiguously(false), ends_contiguously(true),
1220  maximum_range_size(100*1024*1024), nfound(0) {}
1221  virtual bool operator()(bool enabled, const Args &args);
1222  };
1223 
1228  struct FindData: public ByteRangeCallback {
1229  unsigned excluded_reasons;
1231  size_t nfound;
1233  FindData(): excluded_reasons(SgAsmFunction::FUNC_PADDING|SgAsmFunction::FUNC_THUNK), padding_ranges(NULL), nfound(0) {}
1235  virtual bool operator()(bool enabled, const Args &args);
1236  };
1237 
1280  std::set<X86InstructionKind> x86_kinds;
1281  std::vector<SgUnsignedCharList> byte_patterns;
1284  size_t minimum_size;
1286  size_t nfound;
1289  : begins_contiguously(true), ends_contiguously(true), minimum_size(0), add_as_data(true), nfound(0) {}
1290  virtual bool operator()(bool enabled, const Args &args);
1291  };
1292 
1318  double threshold;
1319  unsigned excluded_reasons;
1320  size_t nfound;
1327  excluded_reasons(SgAsmFunction::FUNC_PADDING|SgAsmFunction::FUNC_THUNK),
1328  nfound(0), function_extents(NULL), code_criteria(NULL)
1329  {}
1331  delete function_extents;
1332  delete code_criteria;
1333  }
1334  virtual bool operator()(bool enabled, const Args &args);
1335  };
1336 
1347  size_t nfound;
1350  virtual bool operator()(bool enabled, const Args &args);
1351  };
1352 
1365  size_t nfound;
1369  virtual bool operator()(bool enabled, const Args &args);
1370  };
1371 
1377  size_t nfound;
1381  virtual bool operator()(bool enabled, const Args &args);
1382  };
1383 
1393  size_t nfound;
1396  virtual bool operator()(bool enabled, const Args &args);
1397  };
1398 
1399  /**************************************************************************************************************************
1400  * Methods for finding functions by patterns
1401  **************************************************************************************************************************/
1402 protected:
1407  static InstructionMap::const_iterator pattern1(const InstructionMap& insns, InstructionMap::const_iterator first,
1408  Disassembler::AddressSet &exclude);
1409 
1410 #if 0 /* Definitions are also commented out */
1411 
1413  static InstructionMap::const_iterator pattern2(const InstructionMap& insns, InstructionMap::const_iterator first,
1414  Disassembler::AddressSet &exclude);
1415 
1418  static InstructionMap::const_iterator pattern3(const InstructionMap& insns, InstructionMap::const_iterator first,
1419  Disassembler::AddressSet &exclude);
1420 #endif
1421 
1422  /*************************************************************************************************************************
1423  * Low-level Functions
1424  *
1425  * These are public because they might need to be called by the partitioner's instruction or address traversal callbacks,
1426  * and its often convenient to declare those functors outside any Partitioner subclass.
1427  *************************************************************************************************************************/
1428 public:
1429  /* NOTE: Some of these are documented at their implementation because the documentation is more than what conveniently
1430  * fits here. */
1433  virtual void append(BasicBlock*, Instruction*);
1434  virtual void append(BasicBlock*, DataBlock*, unsigned reasons); /* Add a data block to a basic block. */
1435  virtual void append(Function*, BasicBlock*, unsigned reasons, bool keep=false); /* Append a basic block to a function */
1436  virtual void append(Function*, DataBlock*, unsigned reasons, bool force=false); /* Append a data block to a function */
1437  virtual void remove(Function*, BasicBlock*); /* Remove a basic block from a function. */
1438  virtual void remove(Function*, DataBlock*); /* Remove a data block from a function. */
1439  virtual void remove(BasicBlock*, DataBlock*); /* Remove association between basic block and data block. */
1440  virtual BasicBlock* find_bb_containing(rose_addr_t, bool create=true); /* Find basic block containing instruction address */
1441  virtual BasicBlock* find_bb_starting(rose_addr_t, bool create=true); /* Find or create block starting at specified address */
1442  virtual DataBlock* find_db_starting(rose_addr_t, size_t size); /* Find (or create if size>0) a data block */
1443  virtual Disassembler::AddressSet successors(BasicBlock*, bool *complete=NULL); /* Calculates known successors */
1444  virtual rose_addr_t call_target(BasicBlock*); /* Returns address if block could be a function call */
1445  virtual void truncate(BasicBlock*, rose_addr_t); /* Remove instructions from the end of a basic block. */
1446  virtual void discover_first_block(Function*); /* Adds first basic block to empty function to start discovery. */
1447  virtual void discover_blocks(Function*, unsigned reason); /* Start to recursively discover blocks of a function. */
1448  virtual void discover_blocks(Function*, rose_addr_t, unsigned reason); /* Recursively discovers blocks of a function. */
1449  virtual void pre_cfg(SgAsmInterpretation *interp=NULL);
1450  virtual void analyze_cfg(SgAsmBlock::Reason);
1451  virtual void post_cfg(SgAsmInterpretation *interp=NULL);
1452  virtual SgAsmFunction* build_ast(Function*);
1453  virtual SgAsmBlock* build_ast(BasicBlock*);
1454  virtual SgAsmBlock* build_ast(DataBlock*);
1455  virtual bool pops_return_address(rose_addr_t);
1456  virtual void update_analyses(BasicBlock*); /* Makes sure cached analysis results are current. */
1458  virtual bool is_function_call(BasicBlock*, rose_addr_t*); /* True if basic block appears to call a function. */
1459  virtual bool is_thunk(Function*); /* True if function is a thunk. */
1460  virtual Function *effective_function(DataBlock*); /* Function to which a data block is currently bound. */
1461 
1462  virtual void mark_call_insns();
1463  virtual void mark_ipd_configuration();
1464  virtual void mark_entry_targets(SgAsmGenericHeader*);
1465  virtual void mark_export_entries(SgAsmGenericHeader*);
1466  virtual void mark_eh_frames(SgAsmGenericHeader*);
1467  virtual void mark_elf_plt_entries(SgAsmGenericHeader*);
1468  virtual void mark_func_symbols(SgAsmGenericHeader*);
1469  virtual void mark_func_patterns(); /* Seeds functions according to instruction patterns */
1470  virtual void name_plt_entries(SgAsmGenericHeader*); /* Assign names to ELF PLT functions */
1471  virtual void name_import_entries(SgAsmGenericHeader*); /* Assign names to PE import functions */
1472  virtual void find_pe_iat_extents(SgAsmGenericHeader*); /* Find addresses for all PE Import Address Tables */
1473 
1476  virtual size_t function_extent(FunctionRangeMap *extents);
1477 
1486  virtual size_t function_extent(Function*,
1487  FunctionRangeMap *extents=NULL/*in,out*/,
1488  rose_addr_t *lo_addr=NULL/*out*/, rose_addr_t *hi_addr=NULL/*out*/);
1489 
1495  virtual size_t datablock_extent(DataBlock*,
1496  DataRangeMap *extents=NULL/*in,out*/,
1497  rose_addr_t *lo_addr=NULL/*out*/, rose_addr_t *hi_addr=NULL/*out*/);
1498 
1501  virtual size_t datablock_extent(DataRangeMap *extent/*in,out*/);
1502 
1505  virtual size_t padding_extent(DataRangeMap *extent/*in,out*/);
1506 
1511  virtual bool is_contiguous(Function*, bool strict=false);
1512 
1525 
1528 
1532  void progress(FILE*, const char *fmt, ...) const __attribute__((format(printf, 3, 4)));
1533 
1537  virtual size_t detach_thunks();
1538 
1544  virtual bool detach_thunk(Function*);
1545 
1553  bool is_pe_dynlink_thunk(Function*);
1558  void name_pe_dynlink_thunks(SgAsmInterpretation *interp/*=NULL*/);
1559 
1563  virtual void adjust_padding();
1564 
1569  virtual void merge_function_fragments();
1570 
1572  virtual void merge_functions(Function *parent, Function *other);
1573 
1579  Disassembler::AddressSet discover_jump_table(BasicBlock *bb, bool do_create=true, ExtentMap *table_addresses=NULL);
1580 
1581  /*************************************************************************************************************************
1582  * IPD Parser for initializing the Partitioner
1583  *************************************************************************************************************************/
1584 public:
1585 
1750  class IPDParser {
1751  private:
1753  const char *input;
1754  size_t len;
1755  std::string input_name;
1756  size_t at;
1757  Function *cur_func;
1760  public:
1761  IPDParser(Partitioner *p, const char *input, size_t len, const std::string &input_name="")
1762  : partitioner(p), input(input), len(len), input_name(input_name), at(0), cur_func(NULL), cur_block(NULL) {}
1763 
1765  class Exception: public std::runtime_error {
1766  public:
1767  Exception(const std::string &mesg)
1768  : std::runtime_error(mesg), lnum(0) {}
1769  Exception(const std::string &mesg, const std::string &name, unsigned lnum=0)
1770  : std::runtime_error(mesg), name(name), lnum(lnum) {}
1771  ~Exception() throw() {}
1772  std::string format() const;
1773  friend std::ostream& operator<<(std::ostream&, const Exception &e);
1774 
1775  std::string name;
1776  unsigned lnum;
1777  };
1778 
1779  void parse();
1780  static void unparse(std::ostream&, SgNode *ast);
1783  /*************************************************************************************************************************
1784  * Lexical analysis functions.
1785  *************************************************************************************************************************/
1786  private:
1787  void skip_space();
1788 
1789  /* The is_* functions return true if the next token after white space and comments is of the specified type. */
1790  bool is_terminal(const char *to_match);
1791  bool is_symbol(const char *to_match);
1792  bool is_string();
1793  bool is_number();
1794 
1795  /* The match_* functions skip over white space and comments and attempt to match (and consume) the next token. If the next
1796  * token is not as expected then an exception is thrown. */
1797  void match_terminal(const char *to_match);
1798  void match_symbol(const char *to_match);
1799  std::string match_symbol();
1800  std::string match_string();
1801  rose_addr_t match_number();
1802  std::string match_asm(); /* assembly code inside nested curly braces */
1803 
1804 
1805  /*************************************************************************************************************************
1806  * Parsing functions (see rules above). Each returns true if the construct is present and was parsed, false if the
1807  * construct was not present. They throw an exception if the construct was partially present but an error occurred during
1808  * parsing.
1809  *************************************************************************************************************************/
1810  private:
1811  bool parse_File();
1812  bool parse_Declaration();
1813  bool parse_FuncDecl();
1814  bool parse_FuncBody();
1815  bool parse_FuncStmtList();
1816  bool parse_FuncStmt();
1817  bool parse_ReturnSpec();
1818  bool parse_BlockDecl();
1819  bool parse_BlockBody();
1820  bool parse_BlockStmtList();
1821  bool parse_BlockStmt();
1822  bool parse_Alias();
1823  bool parse_Successors();
1824  };
1825 
1826  /*************************************************************************************************************************
1827  * Data Members
1828  *
1829  * These are public so they can be accessed by user-defined traversal callbacks that might be declared outside any
1830  * Partitioner subclass.
1831  *************************************************************************************************************************/
1832 public:
1845  unsigned func_heuristics;
1846  std::vector<FunctionDetector> user_detectors;
1848  FILE *debug;
1852  static time_t progress_interval;
1853  static time_t progress_time;
1854  static FILE *progress_file;
1856 public:
1857  static const rose_addr_t NO_TARGET = (rose_addr_t)-1;
1858 };
1859 
1860 #endif