00001 #ifndef ROSE_DISASSEMBLER_H
00002 #define ROSE_DISASSEMBLER_H
00003
00004 #include "threadSupport.h"
00005 #include "Registers.h"
00006
00113 class Disassembler {
00114 public:
00116 class Exception {
00117 public:
00119 Exception(const std::string &reason)
00120 : mesg(reason), ip(0), bit(0), insn(NULL)
00121 {}
00123 Exception(const std::string &reason, rose_addr_t ip)
00124 : mesg(reason), ip(ip), bit(0), insn(NULL)
00125 {}
00127 Exception(const std::string &reason, rose_addr_t ip, const SgUnsignedCharList &raw_data, size_t bit)
00128 : mesg(reason), ip(ip), bytes(raw_data), bit(bit), insn(NULL)
00129 {}
00131 Exception(const std::string &reason, SgAsmInstruction *insn)
00132 : mesg(reason), ip(insn->get_address()), bit(0), insn(insn)
00133 {}
00134 void print(std::ostream&) const;
00135 friend std::ostream& operator<<(std::ostream &o, const Exception &e);
00136
00137 std::string mesg;
00138 rose_addr_t ip;
00139 SgUnsignedCharList bytes;
00142 size_t bit;
00144 SgAsmInstruction *insn;
00145 };
00146
00151 enum SearchHeuristic
00152 {
00153 SEARCH_FOLLOWING = 0x0001,
00155 SEARCH_IMMEDIATE = 0x0002,
00159 SEARCH_WORDS = 0x0004,
00163 SEARCH_ALLBYTES = 0x0008,
00165 SEARCH_UNUSED = 0x0010,
00172 SEARCH_NONEXE = 0x0020,
00181 SEARCH_DEADEND = 0x0040,
00187 SEARCH_UNKNOWN = 0x0080,
00190 SEARCH_FUNCSYMS = 0x0100,
00194 SEARCH_DEFAULT = 0x0101
00195 };
00196
00205 static unsigned parse_switches(const std::string &s, unsigned initial=SEARCH_DEFAULT);
00206
00209 typedef std::set<rose_addr_t> AddressSet;
00210
00212 typedef std::map<rose_addr_t, SgAsmInstruction*> InstructionMap;
00213
00216 typedef std::map<rose_addr_t, Exception> BadMap;
00217
00218 Disassembler()
00219 : p_registers(NULL), p_partitioner(NULL), p_search(SEARCH_DEFAULT), p_debug(NULL),
00220 p_wordsize(4), p_sex(SgAsmExecutableFileFormat::ORDER_LSB), p_alignment(4), p_ndisassembled(0),
00221 p_protection(MemoryMap::MM_PROT_EXEC)
00222 {ctor();}
00223
00224 Disassembler(const Disassembler& other)
00225 : p_registers(other.p_registers), p_partitioner(other.p_partitioner), p_search(other.p_search),
00226 p_debug(other.p_debug), p_wordsize(other.p_wordsize), p_sex(other.p_sex), p_alignment(other.p_alignment),
00227 p_ndisassembled(other.p_ndisassembled), p_protection(other.p_protection)
00228 {}
00229
00230 virtual ~Disassembler() {}
00231
00232
00233
00234
00235
00236
00237
00238 public:
00244 static void register_subclass(Disassembler*);
00245
00251 virtual bool can_disassemble(SgAsmGenericHeader*) const = 0;
00252
00259 static Disassembler *lookup(SgAsmGenericHeader*);
00260
00269 static Disassembler *lookup(SgAsmInterpretation*);
00270
00274 virtual Disassembler *clone() const = 0;
00275
00276
00277
00278
00279 public:
00298 void disassemble(SgAsmInterpretation*, AddressSet *successors=NULL, BadMap *bad=NULL);
00299
00306 static void disassembleInterpretation(SgAsmInterpretation*);
00307
00308
00309
00310
00311
00312
00313
00314
00315 public:
00322 void set_registers(const RegisterDictionary *rdict) {
00323 p_registers = rdict;
00324 }
00325
00329 const RegisterDictionary *get_registers() const {
00330 return p_registers;
00331 }
00332
00337 void set_partitioner(class Partitioner *p) {
00338 p_partitioner = p;
00339 }
00340
00344 class Partitioner *get_partitioner() const {
00345 return p_partitioner;
00346 }
00347
00353 void set_search(unsigned bits) {
00354 p_search = bits;
00355 }
00356
00361 unsigned get_search() const {
00362 return p_search;
00363 }
00364
00370 void set_wordsize(size_t);
00371
00375 size_t get_wordsize() const {
00376 return p_wordsize;
00377 }
00378
00385 void set_alignment(size_t);
00386
00390 size_t get_alignment() const {
00391 return p_alignment;
00392 }
00393
00398 void set_sex(SgAsmExecutableFileFormat::ByteOrder sex) {
00399 p_sex = sex;
00400 }
00401
00405 SgAsmExecutableFileFormat::ByteOrder get_sex() const {
00406 return p_sex;
00407 }
00408
00413 void set_debug(FILE *f) {
00414 p_debug = f;
00415 }
00416
00420 FILE *get_debug() const {
00421 return p_debug;
00422 }
00423
00428 size_t get_ndisassembled() const {
00429 return p_ndisassembled;
00430 }
00431
00437 void set_protection(unsigned bitvec) {
00438 p_protection = bitvec;
00439 }
00440
00445 unsigned get_protection() const {
00446 return p_protection;
00447 }
00448
00455 void set_progress_reporting(FILE*, unsigned min_interval);
00456
00457
00458
00459
00460
00461
00462 public:
00473 virtual SgAsmInstruction *disassembleOne(const MemoryMap *map, rose_addr_t start_va, AddressSet *successors=NULL) = 0;
00474
00481 SgAsmInstruction *disassembleOne(const unsigned char *buf, rose_addr_t buf_va, size_t buf_size, rose_addr_t start_va,
00482 AddressSet *successors=NULL);
00483
00484
00485
00486
00509 InstructionMap disassembleBlock(const MemoryMap *map, rose_addr_t start_va, AddressSet *successors=NULL,
00510 InstructionMap *cache=NULL);
00511
00517 InstructionMap disassembleBlock(const unsigned char *buf, rose_addr_t buf_va, size_t buf_size, rose_addr_t start_va,
00518 AddressSet *successors=NULL, InstructionMap *cache=NULL);
00519
00520
00521
00522
00533 InstructionMap disassembleBuffer(const MemoryMap *map, size_t start_va, AddressSet *successors=NULL, BadMap *bad=NULL);
00534
00540 InstructionMap disassembleBuffer(const unsigned char *buf, rose_addr_t buf_va, size_t buf_size, rose_addr_t start_va,
00541 AddressSet *successors=NULL, BadMap *bad=NULL);
00542
00548 InstructionMap disassembleBuffer(const MemoryMap *map, AddressSet workset, AddressSet *successors=NULL, BadMap *bad=NULL);
00549
00550
00551
00552
00557 InstructionMap disassembleSection(SgAsmGenericSection *section, rose_addr_t section_va, rose_addr_t start_offset,
00558 AddressSet *successors=NULL, BadMap *bad=NULL);
00559
00567 InstructionMap disassembleInterp(SgAsmInterpretation *interp, AddressSet *successors=NULL, BadMap *bad=NULL);
00568
00569
00570
00571
00572
00573
00574
00575 public:
00581 void search_following(AddressSet *worklist, const InstructionMap &bb, rose_addr_t bb_va,
00582 const MemoryMap *map, const BadMap *bad);
00583
00590 void search_immediate(AddressSet *worklist, const InstructionMap &bb, const MemoryMap *map, const BadMap *bad);
00591
00597 void search_words(AddressSet *worklist, const MemoryMap *map, const BadMap *bad);
00598
00608 void search_next_address(AddressSet *worklist, rose_addr_t start_va, const MemoryMap *map, const InstructionMap &insns,
00609 const BadMap *bad, bool avoid_overlaps);
00610
00611
00618 void search_function_symbols(AddressSet *worklist, const MemoryMap*, SgAsmGenericHeader*);
00619
00620
00621
00622
00623
00624 public:
00629 void update_progress(SgAsmInstruction*);
00630
00636 void progress(FILE*, const char *fmt, ...) const __attribute__((format(printf, 3, 4)));
00637
00641 virtual SgAsmInstruction *make_unknown_instruction(const Exception&) = 0;
00642
00646 void mark_referenced_instructions(SgAsmInterpretation*, const MemoryMap*, const InstructionMap&);
00647
00653 AddressSet get_block_successors(const InstructionMap&, bool *complete);
00654
00655 private:
00657 static void initclass();
00658
00660 void ctor();
00661
00667 static SgAsmInstruction *find_instruction_containing(const InstructionMap &insns, rose_addr_t va);
00668
00669
00670
00671
00672
00673
00674
00675 protected:
00676 const RegisterDictionary *p_registers;
00677 class Partitioner *p_partitioner;
00678 unsigned p_search;
00679 FILE *p_debug;
00680 size_t p_wordsize;
00681 SgAsmExecutableFileFormat::ByteOrder p_sex;
00682 size_t p_alignment;
00683 static std::vector<Disassembler*> disassemblers;
00684 size_t p_ndisassembled;
00685 unsigned p_protection;
00687 static time_t progress_interval;
00688 static time_t progress_time;
00689 static FILE *progress_file;
00691 static RTS_mutex_t class_mutex;
00692 };
00693
00694 #endif