1 /* 2 * HT Editor 3 * analy.h 4 * 5 * Copyright (C) 1999-2002 Sebastian Biallas (sb@biallas.net) 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 */ 20 21 #ifndef analy_h 22 #define analy_h 23 24 #include "asm.h" 25 #include "data.h" 26 #include "code_analy.h" 27 #include "data_analy.h" 28 #include "stddata.h" 29 30 extern int num_ops_parsed; 31 32 class Analyser; 33 34 #define ADDRESS_STRING_FORMAT_COMPACT 0 35 #define ADDRESS_STRING_FORMAT_LEADING_WHITESPACE 1 36 #define ADDRESS_STRING_FORMAT_LEADING_ZEROS 2 37 #define ADDRESS_STRING_FORMAT_RESERVED 3 38 39 #define ADDRESS_STRING_FORMAT_HEX_CAPS 4 40 #define ADDRESS_STRING_FORMAT_ADD_0X 8 41 #define ADDRESS_STRING_FORMAT_ADD_H 16 42 43 class Address: public Object { 44 public: Address()45 Address() {}; Address(BuildCtorArg & a)46 Address(BuildCtorArg&a): Object(a) {}; 47 virtual bool add(int offset) = 0; 48 virtual int byteSize() = 0; 49 virtual Address * clone() const = 0; 50 virtual int compareDelinear(Address *to); 51 virtual bool difference(int &result, Address *to) = 0; 52 virtual void getFromArray(const byte *array) = 0; 53 virtual void getFromCPUAddress(CPU_ADDR *ca) = 0; 54 virtual bool getFromUInt64(uint64 u) = 0; 55 virtual bool isValid(); 56 virtual int parseString(const char *s, int length, Analyser *a) = 0; 57 virtual void putIntoArray(byte *array) const = 0; 58 virtual void putIntoCPUAddress(CPU_ADDR *ca) const = 0; 59 virtual bool putIntoUInt64(uint64 &u) const = 0; 60 virtual int stringify(char *s, int max_length, int format) const = 0; 61 virtual int stringSize() const = 0; 62 virtual int toString(char *buf, int buflen) const; 63 }; 64 65 class InvalidAddress: public Address { 66 public: InvalidAddress()67 InvalidAddress() {}; InvalidAddress(BuildCtorArg & a)68 InvalidAddress(BuildCtorArg&a): Address(a) {}; 69 virtual bool add(int offset); 70 virtual int byteSize(); 71 virtual int compareTo(const Object *obj) const; 72 virtual bool difference(int &result, Address *to); 73 virtual InvalidAddress *clone() const; 74 virtual void getFromArray(const byte *array); 75 virtual void getFromCPUAddress(CPU_ADDR *ca); 76 virtual bool getFromUInt64(uint64 u); 77 virtual bool isValid(); 78 virtual ObjectID getObjectID() const; 79 virtual int parseString(const char *s, int length, Analyser *a); 80 virtual void putIntoArray(byte *array) const; 81 virtual void putIntoCPUAddress(CPU_ADDR *ca) const; 82 virtual bool putIntoUInt64(uint64 &u) const; 83 virtual int stringify(char *s, int max_length, int format) const; 84 virtual int stringSize() const; 85 }; 86 87 /* 88 * This address type will be used by most analysers, so we define it here. 89 */ 90 class AddressFlat32: public Address { 91 public: 92 uint32 addr; AddressFlat32(BuildCtorArg & a)93 AddressFlat32(BuildCtorArg&a): Address(a) {}; addr(a)94 AddressFlat32(uint32 a=0): addr(a) {}; 95 virtual bool add(int offset); 96 virtual int byteSize(); 97 virtual AddressFlat32 * clone() const; 98 virtual int compareTo(const Object *obj) const; 99 virtual int compareDelinear(Address *to); 100 virtual void getFromArray(const byte *array); 101 virtual void getFromCPUAddress(CPU_ADDR *ca); 102 virtual bool getFromUInt64(uint64 u); 103 virtual bool difference(int &result, Address *to); 104 virtual void load(ObjectStream &s); 105 virtual ObjectID getObjectID() const; 106 virtual int parseString(const char *s, int length, Analyser *a); 107 virtual void putIntoArray(byte *array) const; 108 virtual void putIntoCPUAddress(CPU_ADDR *ca) const; 109 virtual bool putIntoUInt64(uint64 &u) const; 110 virtual void store(ObjectStream &s) const; 111 virtual int stringify(char *s, int max_length, int format) const; 112 virtual int stringSize() const; 113 }; 114 115 class AddressFlat64: public Address { 116 public: 117 uint64 addr; AddressFlat64(BuildCtorArg & a)118 AddressFlat64(BuildCtorArg&a): Address(a) {}; addr(a)119 AddressFlat64(uint64 a=0): addr(a) {}; 120 virtual bool add(int offset); 121 virtual int byteSize(); 122 virtual int compareTo(const Object *obj) const; 123 virtual int compareDelinear(Address *to); 124 virtual void getFromArray(const byte *array); 125 virtual void getFromCPUAddress(CPU_ADDR *ca); 126 virtual bool getFromUInt64(uint64 u); 127 virtual bool difference(int &result, Address *to); 128 virtual AddressFlat64 * clone() const; 129 virtual void load(ObjectStream &s); 130 virtual ObjectID getObjectID() const; 131 virtual int parseString(const char *s, int length, Analyser *a); 132 virtual void putIntoArray(byte *array) const; 133 virtual void putIntoCPUAddress(CPU_ADDR *ca) const; 134 virtual bool putIntoUInt64(uint64 &u) const; 135 virtual void store(ObjectStream &s) const; 136 virtual int stringify(char *s, int max_length, int format) const; 137 virtual int stringSize() const; 138 }; 139 140 #define ANALY_SEGMENT_CAP_WRITE 1 141 #define ANALY_SEGMENT_CAP_INITIALIZED 2 142 // other caps can be defined locally 143 144 class Segment: public Object { 145 Address *start, *end; 146 char *name; 147 int caps; 148 149 Segment(const char *n, Address *s, Address *e, int c, int address_size); 150 virtual bool containsAddress(Address *addr) = 0; 151 virtual String & getName(String &res); 152 virtual int getAddressSize(); 153 virtual int getCapability(int cap); 154 }; 155 156 /* 157 * these are the different possibilities of a branch 158 * to support further processors other types can be added 159 */ 160 enum branch_enum_t { 161 br_nobranch, // straight exec. flow 162 br_jump, 163 br_return, 164 br_call, 165 br_jXX 166 }; 167 168 /* 169 * internal opcodes are interchanged in this format 170 */ 171 #define OPCODE dis_insn 172 173 /* 174 * 175 */ 176 class AnalyDisassembler: public Object { 177 public: 178 Analyser *analy; 179 Disassembler *disasm; 180 AnalyDisassembler(); AnalyDisassembler(BuildCtorArg & a)181 AnalyDisassembler(BuildCtorArg &a): Object(a) {}; 182 183 void init(Analyser *A); 184 185 virtual Address * branchAddr(OPCODE *opcode, branch_enum_t branchtype, bool examine) = 0; 186 virtual void examineOpcode(OPCODE *opcode) = 0; 187 virtual void initDisasm(); 188 virtual branch_enum_t isBranch(OPCODE *opcode) = 0; 189 }; 190 191 /***************************************************************************/ 192 193 enum xref_enum_t { 194 xrefread, 195 xrefwrite, 196 xrefoffset, 197 xrefjump, 198 xrefcall, 199 xrefijump, 200 xreficall 201 }; 202 203 class AddrXRef: public Object { 204 public: 205 Address *addr; 206 xref_enum_t type; 207 AddrXRef(Address *a, xref_enum_t aType = xrefread); AddrXRef(BuildCtorArg & a)208 AddrXRef(BuildCtorArg&a): Object(a) {}; 209 virtual ~AddrXRef(); 210 virtual void load(ObjectStream &s); 211 virtual ObjectID getObjectID() const; 212 virtual void store(ObjectStream &s) const; 213 virtual int compareTo(const Object *) const; 214 }; 215 216 class CommentList: public Array { 217 public: 218 CommentList(); 219 void appendPreComment(const char *s); 220 void appendPreComment(int special); 221 void appendPostComment(const char *s); 222 void appendPostComment(int special); 223 const char * getName(uint i); 224 }; 225 226 struct Symbol; 227 228 struct Location { 229 // the address 230 Address *addr; 231 // this is a tree structure (key is addr) 232 Location *left, *right; 233 // attached label 234 Symbol *label; 235 // attached xrefs 236 Container *xrefs; 237 // attached comments 238 CommentList *comments; 239 // for data types 240 taddr_type type; 241 // the function the address belongs to (if applicable) 242 Location *thisfunc; 243 // some flags 244 int flags; 245 }; 246 247 /* 248 * taddr.flags: 249 */ 250 #define AF_DELETED 1 251 #define AF_FUNCTION_SET 2 252 #define AF_FUNCTION_END 4 253 254 enum tsectype { 255 scvalid, 256 scread, 257 scwrite, 258 screadwrite, 259 sccode, 260 scinitialized 261 }; 262 263 enum taccesstype { 264 acread, 265 acwrite, 266 acoffset 267 }; 268 269 struct taccess { 270 bool indexed; 271 int size; 272 taccesstype type; 273 }; 274 275 enum labeltype { 276 label_unknown = 0, 277 label_func, 278 label_loc, 279 label_data 280 }; 281 282 struct Symbol { 283 labeltype type; 284 Location * location; 285 char * name; 286 Symbol *left, *right; 287 }; 288 289 class AddressQueueItem: public Object { 290 public: 291 Address *addr; 292 Address *func; AddressQueueItem(BuildCtorArg & a)293 AddressQueueItem(BuildCtorArg&a): Object(a) {}; 294 AddressQueueItem(Address *Addr, Address *Func); 295 ~AddressQueueItem(); 296 virtual void load(ObjectStream &s); 297 virtual ObjectID getObjectID() const; 298 virtual void store(ObjectStream &s) const; 299 }; 300 301 class CodeAnalyser; 302 class DataAnalyser; 303 304 class Analyser: public Object { 305 public: 306 Address * addr; 307 Address * invalid_addr; 308 Queue * addr_queue; 309 int ops_parsed; // for continuing 310 bool active; 311 Address *next_explored, *first_explored, *last_explored; 312 bool next_address_is_invalid; 313 Area * explored; 314 Area * initialized; 315 Location * locations; 316 CodeAnalyser * code; 317 DataAnalyser * data; 318 AnalyDisassembler * analy_disasm; 319 Disassembler * disasm; 320 Symbol * symbols; 321 int location_threshold, symbol_threshold; 322 int cur_addr_ops, cur_label_ops; // for threshold 323 int max_opcode_length; 324 Location *cur_func; 325 mutable bool dirty; 326 327 int symbol_count; 328 int location_count; 329 Analyser()330 Analyser() {}; Analyser(BuildCtorArg & a)331 Analyser(BuildCtorArg&a): Object(a) {}; 332 333 void init(); 334 virtual void load(ObjectStream &s); 335 virtual void done(); 336 337 bool addAddressSymbol(Address *Addr, const char *Prefix, labeltype type, Location *infunc=NULL); 338 void addComment(Address *Addr, int line, const char *c); 339 bool addSymbol(Address *Addr, const char *label, labeltype type, Location *infunc=NULL); 340 virtual FileOfs addressToFileofs(Address *Addr) = 0; 341 bool addXRef(Address *from, Address *to, xref_enum_t action); 342 void assignComment(Address *Addr, int line, const char *c); 343 bool assignSymbol(Address *Addr, const char *label, labeltype type, Location *infunc=NULL); 344 void assignXRef(Address *from, Address *to, xref_enum_t action); 345 virtual void beginAnalysis(); 346 virtual uint bufPtr(Address *Addr, byte *buf, int size) = 0; 347 bool continueAnalysis(); 348 void continueAnalysisAt(Address *Addr); 349 virtual Address* createAddress() = 0; 350 void dataAccess(Address *Addr, taccess access); 351 void deleteLocation(Address *Addr); 352 void deleteSymbol(Address *Addr); 353 bool deleteXRef(Address *from, Address *to); 354 void disableSymbol(Symbol *label); 355 void doBranch(branch_enum_t branch, OPCODE *opcode, int len); 356 void engageCodeanalyser(); 357 Location * enumLocations(Address *Addr); 358 Location * enumLocationsReverse(Address *Addr); 359 Symbol * enumSymbolsByName(const char *at); 360 Symbol * enumSymbolsByNameReverse(const char *at); 361 Symbol * enumSymbols(Symbol *sym); 362 Symbol * enumSymbolsReverse(Symbol *sym); 363 virtual taddr_typetype examineData(Address *Addr); 364 void finish(); 365 void freeLocation(Location *loc); 366 void freeLocations(Location *locs); 367 void freeComments(Location *loc); 368 void freeSymbol(Symbol *sym); 369 void freeSymbols(Symbol *syms); 370 Location * getLocationByAddress(Address *Addr); 371 Location * getLocationContextByAddress(Address *Addr); 372 int getLocationCount() const; 373 Location * getFunctionByAddress(Address *Addr); 374 Location * getPreviousSymbolByAddress(Address *Addr); 375 virtual const char * getSegmentNameByAddress(Address *Addr); 376 Symbol * getSymbolByAddress(Address *Addr); 377 Symbol * getSymbolByName(const char *label); 378 const char * getSymbolNameByLocation(Location *loc); 379 int getSymbolCount() const; 380 bool gotoAddress(Address *Addr, Address *func); 381 virtual void initCodeAnalyser(); 382 virtual void initDataAnalyser(); 383 virtual void initUnasm() = 0; 384 virtual bool isAddressFixedUp(Address *Addr, int offset); 385 virtual void log(const char *s); // stub 386 virtual CPU_ADDR mapAddr(Address *Addr); // stub 387 Location * newLocation(Address *Addr); 388 Location * newLocation(Location *&locs, Address *Addr); 389 Symbol * newSymbol(const char *label, Location *loc, labeltype type, Location *infunc); 390 Symbol * newSymbol(Symbol *&syms, const char *label, Location *loc, labeltype type); 391 virtual Address * nextValid(Address *Addr) = 0; 392 void optimizeLocationTree(); 393 void optimizeSymbolTree(); 394 bool popAddress(Address **Addr, Address **func); 395 void pushAddress(Address *Addr, Address *func); 396 virtual int queryConfig(int mode); // stub 397 void setActive(bool mode); 398 void setLocationFunction(Location *a, Location *func); 399 void setLocationTreeOptimizeThreshold(int threshold); 400 void setDisasm(Disassembler *d); 401 void setSymbolTreeOptimizeThreshold(int threshold); 402 virtual void store(ObjectStream &s) const; 403 virtual bool validAddress(Address *addr, tsectype action) = 0; 404 bool validCodeAddress(Address *addr); 405 bool validReadAddress(Address *addr); 406 bool validWriteAddress(Address *addr); 407 408 // interface only (there's no internal use) 409 int mode; 410 411 virtual Assembler * createAssembler(); 412 virtual Address * fileofsToAddress(FileOfs fileofs); 413 CommentList * getComments(Address *Addr); 414 const char * getDisasmStr(Address *Addr, int &length); 415 const char * getDisasmStrFormatted(Address *Addr); 416 int getDisplayMode(); 417 virtual String & getName(String &res); 418 virtual const char * getType(); 419 Container * getXRefs(Address *Addr); 420 bool isDirty(); 421 void makeDirty(); 422 void setDisplayMode(int enable, int disable); 423 void toggleDisplayMode(int toggle); 424 }; 425 426 /* display modes */ 427 #define ANALY_SHOW_ADDRESS 1 428 #define ANALY_SHOW_COMMENTS 2 429 #define ANALY_SHOW_LABELS 4 430 #define ANALY_SHOW_XREFS 8 431 #define ANALY_SHOW_BYTES 16 432 #define ANALY_EDIT_BYTES 32 433 #define ANALY_TRANSLATE_SYMBOLS 64 434 #define ANALY_COLLAPSE_XREFS 128 435 436 /* queryConfig() constants */ 437 #define Q_DO_ANALYSIS 1 438 #define Q_ENGAGE_CODE_ANALYSER 2 439 #define Q_ENGAGE_DATA_ANALYSER 3 440 441 /* interesting constants */ 442 #define INVALID_FILE_OFS ((FileOfs)-1) 443 444 /* analyser system constants */ 445 #define MAX_OPS_PER_CONTINUE 10 446 447 extern int global_analyser_address_string_format; 448 449 #endif 450