1 2 /*---------------------------------------------------------------*/ 3 /*--- begin dispatch.c ---*/ 4 /*---------------------------------------------------------------*/ 5 6 #include "basictypes.h" 7 8 9 /* --------------------------------------------------------- */ 10 /* TRANSLATION TABLE/CACHE */ 11 /* --------------------------------------------------------- */ 12 13 static 14 char* find_translation ( char* orig ) 15 { 16 int i; 17 for (i = 0; i < n_transtab_used; i++) 18 if (transtab[i].orig == orig) 19 return transtab[i].trans; 20 return NULL; 21 } 22 23 24 #define N_TT_ENTRIES 1000 25 26 typedef 27 struct { 28 char* orig; 29 int orig_size; 30 char* trans; 31 int trans_size; 32 } 33 TTEntry; 34 35 int n_transtab_used = 0; 36 TTEntry transtab[N_TT_ENTRIES]; 37 38 39 /* Call here to add a translation to the trans cache. 40 Supplied translation is in mallocville. add_translation should 41 copy it out as the caller will free it on return. */ 42 43 /* EXPORTED */ 44 void add_translation ( char* orig, int orig_size, char* trans, int trans_size ) 45 { 46 int i; 47 assert(n_transtab_used < N_TT_ENTRIES); 48 transtab[n_transtab_used].orig = orig; 49 transtab[n_transtab_used].orig_size = orig_size; 50 transtab[n_transtab_used].trans_size = trans_size; 51 52 transtab[n_transtab_used].trans = malloc(trans_size); 53 assert(transtab[n_transtab_used].trans != NULL); 54 for (i = 0; i < trans_size; i++) 55 transtab[n_transtab_used].trans[i] = trans[i]; 56 57 #ifdef arm_TARGET_ARCH 58 arm_notify_new_code(transtab[n_transtab_used].trans, trans_size); 59 #endif 60 61 n_transtab_used++; 62 } 63 64 /* Run the simulated machine for a while. Returns when a new BB needs 65 to be translated, and returns its address. Returns NULL when we 66 want to stop. */ 67 68 /* EXPORTED */ 69 char* run_machine ( void ) 70 { 71 char* nextpc_orig; 72 char* nextpc_trans; 73 while (1) { 74 nextpc_orig = (char*)(regs_arm[REG_PC]); 75 if (nextpc_orig == stop_at) 76 return NULL; 77 nextpc_trans = find_translation(nextpc_orig); 78 if (nextpc_trans == NULL) 79 return nextpc_orig; 80 run_translation(nextpc_trans, (char*) ®s_arm[0] ); 81 } 82 } 83 84 85 /* HOW TO USE: 86 87 for a main fn :: void main ( void ) 88 89 * load .o's, link, etc 90 91 * call initialise_machine with & main 92 93 * call run_machine repeatedly. If it returns NULL, stop. Else 94 make a translation of the returned address, pass it to 95 add_translation, and resume running by calling run_machine. 96 97 */ 98