comparison z80_to_x86.c @ 264:8fd6652e56f8

Fix a crash bug in instruction retranslation
author Mike Pavone <pavone@retrodev.com>
date Wed, 01 May 2013 20:09:53 -0700
parents d97c9eca49f4
children 376df762ddf5
comparison
equal deleted inserted replaced
263:2989ed7b8608 264:8fd6652e56f8
1221 return NULL; 1221 return NULL;
1222 } 1222 }
1223 if (!map->base || !map->offsets || map->offsets[address] == INVALID_OFFSET) { 1223 if (!map->base || !map->offsets || map->offsets[address] == INVALID_OFFSET) {
1224 return NULL; 1224 return NULL;
1225 } 1225 }
1226 //printf("z80_get_native_address: %X %p\n", address, map->base + map->offsets[address]);
1226 return map->base + map->offsets[address]; 1227 return map->base + map->offsets[address];
1227 } 1228 }
1228 1229
1229 uint8_t z80_get_native_inst_size(x86_z80_options * opts, uint32_t address) 1230 uint8_t z80_get_native_inst_size(x86_z80_options * opts, uint32_t address)
1230 { 1231 {
1299 z80_context * z80_handle_code_write(uint32_t address, z80_context * context) 1300 z80_context * z80_handle_code_write(uint32_t address, z80_context * context)
1300 { 1301 {
1301 uint32_t inst_start = z80_get_instruction_start(context->static_code_map, address); 1302 uint32_t inst_start = z80_get_instruction_start(context->static_code_map, address);
1302 if (inst_start != INVALID_INSTRUCTION_START) { 1303 if (inst_start != INVALID_INSTRUCTION_START) {
1303 uint8_t * dst = z80_get_native_address(context, inst_start); 1304 uint8_t * dst = z80_get_native_address(context, inst_start);
1305 //printf("patching code at %p for Z80 instruction at %X due to write to %X\n", dst, inst_start, address);
1304 dst = mov_ir(dst, inst_start, SCRATCH1, SZ_D); 1306 dst = mov_ir(dst, inst_start, SCRATCH1, SZ_D);
1305 dst = jmp(dst, (uint8_t *)z80_retrans_stub); 1307 dst = jmp(dst, (uint8_t *)z80_retrans_stub);
1306 } 1308 }
1307 return context; 1309 return context;
1310 }
1311
1312 uint8_t * z80_get_native_address_trans(z80_context * context, uint32_t address)
1313 {
1314 uint8_t * addr = z80_get_native_address(context, address);
1315 if (!addr) {
1316 translate_z80_stream(context, address);
1317 addr = z80_get_native_address(context, address);
1318 if (!addr) {
1319 printf("Failed to translate %X to native code\n", address);
1320 }
1321 }
1322 return addr;
1308 } 1323 }
1309 1324
1310 void * z80_retranslate_inst(uint32_t address, z80_context * context) 1325 void * z80_retranslate_inst(uint32_t address, z80_context * context)
1311 { 1326 {
1312 x86_z80_options * opts = context->options; 1327 x86_z80_options * opts = context->options;
1326 opts->code_end = dst_end = dst + size; 1341 opts->code_end = dst_end = dst + size;
1327 opts->cur_code = dst; 1342 opts->cur_code = dst;
1328 } 1343 }
1329 uint8_t * native_end = translate_z80inst(&instbuf, dst, context, address); 1344 uint8_t * native_end = translate_z80inst(&instbuf, dst, context, address);
1330 if ((native_end - dst) <= orig_size) { 1345 if ((native_end - dst) <= orig_size) {
1331 native_end = translate_z80inst(&instbuf, orig_start, context, address); 1346 uint8_t * native_next = z80_get_native_address(context, address + after-inst);
1332 while (native_end < orig_start + orig_size) { 1347 if (native_next && ((native_next == orig_start + orig_size) || (orig_size - (native_end - dst)) > 5)) {
1333 *(native_end++) = 0x90; //NOP 1348 native_end = translate_z80inst(&instbuf, orig_start, context, address);
1334 } 1349 if (native_next == orig_start + orig_size) {
1335 return orig_start; 1350 while (native_end < orig_start + orig_size) {
1336 } else { 1351 *(native_end++) = 0x90; //NOP
1337 z80_map_native_address(context, address, dst, after-inst, ZMAX_NATIVE_SIZE); 1352 }
1338 opts->code_end = dst+ZMAX_NATIVE_SIZE; 1353 } else {
1339 if(!(instbuf.op == Z80_RET || instbuf.op == Z80_RETI || instbuf.op == Z80_RETN || instbuf.op == Z80_JP || (instbuf.op == Z80_NOP && instbuf.immed == 42))) { 1354 jmp(native_end, native_next);
1340 jmp(native_end, z80_get_native_address(context, address + after-inst)); 1355 }
1341 } 1356 return orig_start;
1342 return dst; 1357 }
1343 } 1358 }
1359 z80_map_native_address(context, address, dst, after-inst, ZMAX_NATIVE_SIZE);
1360 opts->code_end = dst+ZMAX_NATIVE_SIZE;
1361 if(!(instbuf.op == Z80_RET || instbuf.op == Z80_RETI || instbuf.op == Z80_RETN || instbuf.op == Z80_JP || (instbuf.op == Z80_NOP && instbuf.immed == 42))) {
1362 jmp(native_end, z80_get_native_address_trans(context, address + after-inst));
1363 }
1364 return dst;
1344 } else { 1365 } else {
1345 dst = translate_z80inst(&instbuf, orig_start, context, address); 1366 dst = translate_z80inst(&instbuf, orig_start, context, address);
1346 if(!(instbuf.op == Z80_RET || instbuf.op == Z80_RETI || instbuf.op == Z80_RETN || instbuf.op == Z80_JP || (instbuf.op == Z80_NOP && instbuf.immed == 42))) { 1367 if(!(instbuf.op == Z80_RET || instbuf.op == Z80_RETI || instbuf.op == Z80_RETN || instbuf.op == Z80_JP || (instbuf.op == Z80_NOP && instbuf.immed == 42))) {
1347 dst = jmp(dst, z80_get_native_address(context, address + after-inst)); 1368 dst = jmp(dst, z80_get_native_address_trans(context, address + after-inst));
1348 } 1369 }
1349 return orig_start; 1370 return orig_start;
1350 } 1371 }
1351 }
1352
1353 uint8_t * z80_get_native_address_trans(z80_context * context, uint32_t address)
1354 {
1355 uint8_t * addr = z80_get_native_address(context, address);
1356 if (!addr) {
1357 translate_z80_stream(context, address);
1358 addr = z80_get_native_address(context, address);
1359 if (!addr) {
1360 printf("Failed to translate %X to native code\n", address);
1361 }
1362 }
1363 return addr;
1364 } 1372 }
1365 1373
1366 void translate_z80_stream(z80_context * context, uint32_t address) 1374 void translate_z80_stream(z80_context * context, uint32_t address)
1367 { 1375 {
1368 char disbuf[80]; 1376 char disbuf[80];
1377 encoded = context->mem_pointers[1] + (address & 0x7FFF); 1385 encoded = context->mem_pointers[1] + (address & 0x7FFF);
1378 } 1386 }
1379 while (encoded != NULL) 1387 while (encoded != NULL)
1380 { 1388 {
1381 z80inst inst; 1389 z80inst inst;
1382 printf("translating Z80 code at address %X\n", address); 1390 //printf("translating Z80 code at address %X\n", address);
1383 do { 1391 do {
1384 if (opts->code_end-opts->cur_code < ZMAX_NATIVE_SIZE) { 1392 if (opts->code_end-opts->cur_code < ZMAX_NATIVE_SIZE) {
1385 if (opts->code_end-opts->cur_code < 5) { 1393 if (opts->code_end-opts->cur_code < 5) {
1386 puts("out of code memory, not enough space for jmp to next chunk"); 1394 puts("out of code memory, not enough space for jmp to next chunk");
1387 exit(1); 1395 exit(1);