static void libbf_save_state(DynAllocDesc* desc, void* ptr) { cast_ptr_to_context(ptr, context); long pagesize = libbf_getpagesize(); long regIP = (long)GET_IP(context); int relative_ip = regIP - (long)desc->current_executable_code; void* data_ptr = (void*)GET_DATA_PTR_REG(context); void* base_data_ptr = desc->executableCodeData.base_data_ptr; int relative_data_ptr = (long)data_ptr - (long)base_data_ptr; /* Restore regular protection for user data pages */ int ret = libbf_mprotect(desc->current_mem, (COUNT_LOW_ACT_HIGH_PAGES(desc)) * pagesize, PROT_READ | PROT_WRITE); if (ret != 0) fatal("mprotect failed\n"); assert (regIP >= (long)desc->current_executable_code && regIP < (long)desc->current_executable_code + desc->size_of_executable_code); #if defined(__i386__) { int eax = GET_AX(context); int ebx = GET_BX(context); int ecx = GET_CX(context); int edx = GET_DX(context); int flags = GET_FL(context); int i; unsigned char* c = (unsigned char*) desc->current_executable_code; FILE* f; if (desc->options->suspend_file && (f = fopen(desc->options->suspend_file, "wb")) != NULL) { fwrite(desc->current_executable_code, desc->size_of_executable_code, 1, f); fwrite(&relative_ip, sizeof(int), 1, f); fwrite(&eax, sizeof(int), 1, f); fwrite(&ebx, sizeof(int), 1, f); fwrite(&ecx, sizeof(int), 1, f); fwrite(&edx, sizeof(int), 1, f); fwrite(&flags, sizeof(int), 1, f); fwrite(&relative_data_ptr, sizeof(int), 1, f); fwrite(&desc->count_active_pages, sizeof(int), 1, f); fwrite(base_data_ptr, desc->count_active_pages * pagesize, 1, f); fclose(f); } else { warning("Can't write in suspend file\n"); } /* seek : 83 c4 0c add $12,%esp */ for(i=desc->size_of_executable_code-3-1;i>=0;i--) { if (c[i] == 0x83 && c[i+1] == 0xc4 && c[i+2] == 4*3) { GET_IP(context) = (int)(c + i); return; } } SHOULDNT_HAPPEN(); } #else { long rax = GET_AX(context); long rdi = GET_DI(context); long rsi = GET_SI(context); long rcx = GET_CX(context); long rdx = GET_DX(context); long flags = GET_FL(context); int i; unsigned char* c = (unsigned char*) desc->current_executable_code; FILE* f; if (desc->options->suspend_file && (f = fopen(desc->options->suspend_file, "wb")) != NULL) { fwrite(desc->current_executable_code, desc->size_of_executable_code, 1, f); fwrite(&relative_ip, sizeof(int), 1, f); fwrite(&rax, sizeof(rax), 1, f); fwrite(&rdi, sizeof(rdi), 1, f); fwrite(&rsi, sizeof(rsi), 1, f); fwrite(&rcx, sizeof(rcx), 1, f); fwrite(&rdx, sizeof(rdx), 1, f); fwrite(&flags, sizeof(flags), 1, f); fwrite(&relative_data_ptr, sizeof(int), 1, f); fwrite(&desc->count_active_pages, sizeof(int), 1, f); fwrite(base_data_ptr, desc->count_active_pages * pagesize, 1, f); fclose(f); } else { warning("Can't write in suspend file\n"); } /* seek : 48 83 c4 18 add $24,%rsp */ for(i=desc->size_of_executable_code-4-1;i>=0;i--) { if (c[i] == 0x48 && c[i+1] == 0x83 && c[i+2] == 0xc4 && c[i+3] == 8*3) { GET_IP(context) = (long)(c + i); return; } } SHOULDNT_HAPPEN(); } #endif }
void er59256_set_iobits(device_t *device, UINT8 newbits) { er59256_t *er59256 = get_token(device); //UINT32 bit; // Make sure we only apply valid bits newbits&=ALL_MASK; if(LOGLEVEL>1) { logerror("er59256:newbits=%02X : ",newbits); LOG_BITS(newbits); logerror(" io_bits=%02X : ",er59256->io_bits); LOG_BITS(er59256->io_bits); logerror(" old_io_bits=%02X : ",er59256->old_io_bits); LOG_BITS(er59256->old_io_bits); logerror(" bitcount=%d, in_shifter=%04X, out_shifter=%05X, flags=%02X\n",er59256->bitcount,er59256->in_shifter,er59256->out_shifter,er59256->flags); } // Only do anything if the inputs have changed if((newbits&IN_MASK)!=(er59256->io_bits&IN_MASK)) { // save the current state, then set the new one, remembering to preserve data out er59256->old_io_bits=er59256->io_bits; er59256->io_bits=(newbits & ~DO_MASK) | (er59256->old_io_bits&DO_MASK); if(CS_RISE(er59256)) { er59256->flags&=~FLAG_START_BIT; er59256->command=CMD_INVALID; } if(LOGLEVEL>1) { if(CK_RISE(er59256)) logerror("er59256:CK rise\n"); if(CS_RISE(er59256)) logerror("er59256:CS rise\n"); if(CK_FALL(er59256)) logerror("er59256:CK fall\n"); if(CS_FALL(er59256)) logerror("er59256:CS fall\n"); } if(CK_RISE(er59256) && CS_VALID(er59256)) { if((STARTED(er59256)==0) && (GET_DI(er59256)==1)) { er59256->bitcount=0; er59256->flags|=FLAG_START_BIT; } else { SHIFT_IN(er59256); er59256->bitcount++; if(er59256->bitcount==CMD_BITLEN) decode_command(er59256); if((er59256->bitcount==WRITE_BITLEN) && ((er59256->command & CMD_MASK)==CMD_WRITE)) { er59256->eerom[er59256->command & ADDR_MASK]=er59256->in_shifter; LOG(1,"er59256:write[%02X]=%04X\n",(er59256->command & ADDR_MASK),er59256->in_shifter); er59256->command=CMD_INVALID; } LOG(1,"out_shifter=%05X, io_bits=%02X\n",er59256->out_shifter,er59256->io_bits); SHIFT_OUT(er59256); } LOG(2,"io_bits:out=%02X\n",er59256->io_bits); } } }