diff --git a/src/device/r4300/new_dynarec/arm/assem_arm.c b/src/device/r4300/new_dynarec/arm/assem_arm.c index 32a852a32..8acef6726 100644 --- a/src/device/r4300/new_dynarec/arm/assem_arm.c +++ b/src/device/r4300/new_dynarec/arm/assem_arm.c @@ -249,6 +249,7 @@ static void set_jump_target(int addr,u_int target) { u_char *ptr=(u_char *)addr; u_int *ptr2=(u_int *)ptr; + if(ptr==NULL) return; if(ptr[3]==0xe2) { assert((target-(u_int)ptr2-8)<1024); assert((addr&3)==0); @@ -2039,6 +2040,7 @@ static void emit_writebyte_indexed_tlb(int rt, int addr, int rs, int map) } static void emit_writeword(int rt, int addr) { + if(rt<0) return; u_int offset = addr-(u_int)&g_dev.r4300.new_dynarec_hot_state; assert(offset<4096); assem_debug("str %s,fp+%d",regname[rt],offset); @@ -2622,6 +2624,7 @@ static void emit_extjump2(int addr, int target, int linker) static void do_invstub(int n) { + if(stubs[n][4]==-1) return; literal_pool(20); u_int reglist=stubs[n][3]; set_jump_target(stubs[n][1],(int)out); diff --git a/src/device/r4300/new_dynarec/arm64/assem_arm64.c b/src/device/r4300/new_dynarec/arm64/assem_arm64.c index fb2a3a7d8..d56b9ed5c 100644 --- a/src/device/r4300/new_dynarec/arm64/assem_arm64.c +++ b/src/device/r4300/new_dynarec/arm64/assem_arm64.c @@ -300,6 +300,7 @@ static void set_jump_target(intptr_t addr,uintptr_t target) { u_int *ptr=(u_int *)addr; intptr_t offset=target-(intptr_t)addr; + if(ptr==NULL) return; if((*ptr&0xFC000000)==0x14000000) { assert(offset>=-134217728LL&&offset<134217728LL); @@ -2392,6 +2393,7 @@ static void emit_writebyte_indexed_tlb(int rt, int addr, int rs, int map) static void emit_writeword(int rt, intptr_t addr) { + if(rt<0) return; intptr_t offset = addr-(intptr_t)&g_dev.r4300.new_dynarec_hot_state; assert(offset<16380LL); assert(offset%4 == 0); /* 4 bytes aligned */ @@ -3097,6 +3099,7 @@ static void emit_extjump2(intptr_t addr, int target, intptr_t linker) static void do_invstub(int n) { + if(stubs[n][4]==-1) return; literal_pool(20); u_int reglist=stubs[n][3]; set_jump_target(stubs[n][1],(intptr_t)out); diff --git a/src/device/r4300/new_dynarec/new_dynarec.c b/src/device/r4300/new_dynarec/new_dynarec.c index dca53aa68..c39f393ed 100644 --- a/src/device/r4300/new_dynarec/new_dynarec.c +++ b/src/device/r4300/new_dynarec/new_dynarec.c @@ -2813,7 +2813,7 @@ void invalidate_block(u_int block) { u_int page; page=block^0x80000; - if(page>262143&&g_dev.r4300.cp0.tlb.LUT_r[block]) page=(g_dev.r4300.cp0.tlb.LUT_r[block]^0x80000000)>>12; + if(block<0x100000&&page>262143&&g_dev.r4300.cp0.tlb.LUT_r[block]) page=(g_dev.r4300.cp0.tlb.LUT_r[block]^0x80000000)>>12; if(page>2048) page=2048+(page&2047); inv_debug("INVALIDATE: %x (%d)\n",block<<12,page); u_int first,last; @@ -2869,9 +2869,11 @@ void invalidate_block(u_int block) #endif // Don't trap writes - g_dev.r4300.cached_interp.invalid_code[block]=1; + if(block<0x100000) { + g_dev.r4300.cached_interp.invalid_code[block]=1; + } // If there is a valid TLB entry for this page, remove write protect - if(g_dev.r4300.cp0.tlb.LUT_w[block]) { + if(block<0x100000&&g_dev.r4300.cp0.tlb.LUT_w[block]) { assert(g_dev.r4300.cp0.tlb.LUT_r[block]==g_dev.r4300.cp0.tlb.LUT_w[block]); g_dev.r4300.new_dynarec_hot_state.memory_map[block]=((uintptr_t)g_dev.rdram.dram+(uintptr_t)((g_dev.r4300.cp0.tlb.LUT_w[block]&0xFFFFF000)-0x80000000)-(block<<12))>>2; u_int real_block=g_dev.r4300.cp0.tlb.LUT_w[block]>>12; @@ -4270,6 +4272,7 @@ static void loop_preload(signed char pre[],signed char entry[]) // Generate address for load/store instruction static void address_generation(int i,struct regstat *i_regs,signed char entry[]) { + if(i>=4069) return; if(itype[i]==LOAD||itype[i]==LOADLR||itype[i]==STORE||itype[i]==STORELR||itype[i]==C1LS) { int ra=0; int agr=AGEN1+(i&1); @@ -4376,6 +4379,7 @@ static void address_generation(int i,struct regstat *i_regs,signed char entry[]) } } // Preload constants for next instruction + if(i+1>=4096) return; if(itype[i+1]==LOAD||itype[i+1]==LOADLR||itype[i+1]==STORE||itype[i+1]==STORELR||itype[i+1]==C1LS) { int agr,ra; #if (NEW_DYNAREC!=NEW_DYNAREC_X86) && (NEW_DYNAREC!=NEW_DYNAREC_X64) diff --git a/src/device/r4300/new_dynarec/x64/assem_x64.c b/src/device/r4300/new_dynarec/x64/assem_x64.c index 28f3819d0..341165206 100644 --- a/src/device/r4300/new_dynarec/x64/assem_x64.c +++ b/src/device/r4300/new_dynarec/x64/assem_x64.c @@ -70,6 +70,7 @@ static const uintptr_t invalidate_block_reg[8] = { static void set_jump_target(uintptr_t addr,uintptr_t target) { u_char *ptr=(u_char *)addr; + if(ptr==NULL) return; if(*ptr==0x0f) { assert(ptr[1]>=0x80&&ptr[1]<=0x8f); // conditional jmp @@ -2308,6 +2309,7 @@ static void emit_xchg64(int rs, int rt) } static void emit_writeword(int rt, intptr_t addr) { + if(rt<0) return; assert((intptr_t)addr-(intptr_t)out>=-2147483648LL&&(intptr_t)addr-(intptr_t)out<2147483647LL); assem_debug("movl %%%s,%llx",regname[rt],addr); output_byte(0x89); @@ -3026,6 +3028,7 @@ static void emit_extjump2(intptr_t addr, int target, intptr_t linker) static void do_invstub(int n) { + if(stubs[n][4]==-1) return; u_int reglist=stubs[n][3]; set_jump_target(stubs[n][1],(intptr_t)out); save_regs(reglist); diff --git a/src/device/rcp/ai/ai_controller.c b/src/device/rcp/ai/ai_controller.c index bc46a5f75..9e90cdbeb 100644 --- a/src/device/rcp/ai/ai_controller.c +++ b/src/device/rcp/ai/ai_controller.c @@ -180,7 +180,7 @@ void read_ai_regs(void* opaque, uint32_t address, uint32_t* value) ai->last_read = *value; } } - else + else if (reg < AI_REGS_COUNT) { *value = ai->regs[reg]; } @@ -212,11 +212,15 @@ void write_ai_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask if ((ai->regs[reg]) != (value & mask)) ai->samples_format_changed = 1; - masked_write(&ai->regs[reg], value, mask); + if (reg < AI_REGS_COUNT) { + masked_write(&ai->regs[reg], value, mask); + } return; } - masked_write(&ai->regs[reg], value, mask); + if (reg < AI_REGS_COUNT) { + masked_write(&ai->regs[reg], value, mask); + } } void ai_end_of_dma_event(void* opaque) diff --git a/src/device/rcp/mi/mi_controller.c b/src/device/rcp/mi/mi_controller.c index 05ecdd776..ed390eb99 100644 --- a/src/device/rcp/mi/mi_controller.c +++ b/src/device/rcp/mi/mi_controller.c @@ -83,7 +83,9 @@ void read_mi_regs(void* opaque, uint32_t address, uint32_t* value) struct mi_controller* mi = (struct mi_controller*)opaque; uint32_t reg = mi_reg(address); - *value = mi->regs[reg]; + if (reg < MI_REGS_COUNT) { + *value = mi->regs[reg]; + } } void write_mi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) diff --git a/src/device/rcp/pi/pi_controller.c b/src/device/rcp/pi/pi_controller.c index 0fc36bf3d..6f8b0269c 100644 --- a/src/device/rcp/pi/pi_controller.c +++ b/src/device/rcp/pi/pi_controller.c @@ -209,7 +209,9 @@ void write_pi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask return; } - masked_write(&pi->regs[reg], value, mask); + if (reg < PI_REGS_COUNT) { + masked_write(&pi->regs[reg], value, mask); + } } void pi_end_of_dma_event(void* opaque) diff --git a/src/device/rcp/rdp/rdp_core.c b/src/device/rcp/rdp/rdp_core.c index f091801bd..428652ed2 100644 --- a/src/device/rcp/rdp/rdp_core.c +++ b/src/device/rcp/rdp/rdp_core.c @@ -86,7 +86,9 @@ void read_dpc_regs(void* opaque, uint32_t address, uint32_t* value) struct rdp_core* dp = (struct rdp_core*)opaque; uint32_t reg = dpc_reg(address); - *value = dp->dpc_regs[reg]; + if (reg < DPC_REGS_COUNT) { + *value = dp->dpc_regs[reg]; + } } void write_dpc_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) @@ -106,7 +108,9 @@ void write_dpc_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mas return; } - masked_write(&dp->dpc_regs[reg], value, mask); + if (reg < DPC_REGS_COUNT) { + masked_write(&dp->dpc_regs[reg], value, mask); + } switch(reg) { @@ -128,7 +132,9 @@ void read_dps_regs(void* opaque, uint32_t address, uint32_t* value) struct rdp_core* dp = (struct rdp_core*)opaque; uint32_t reg = dps_reg(address); - *value = dp->dps_regs[reg]; + if (reg < DPS_REGS_COUNT) { + *value = dp->dps_regs[reg]; + } } void write_dps_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) @@ -136,7 +142,9 @@ void write_dps_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mas struct rdp_core* dp = (struct rdp_core*)opaque; uint32_t reg = dps_reg(address); - masked_write(&dp->dps_regs[reg], value, mask); + if (reg < DPS_REGS_COUNT) { + masked_write(&dp->dps_regs[reg], value, mask); + } } void rdp_interrupt_event(void* opaque) diff --git a/src/device/rcp/ri/ri_controller.c b/src/device/rcp/ri/ri_controller.c index d74dd66c5..39ff36a84 100644 --- a/src/device/rcp/ri/ri_controller.c +++ b/src/device/rcp/ri/ri_controller.c @@ -41,7 +41,9 @@ void read_ri_regs(void* opaque, uint32_t address, uint32_t* value) struct ri_controller* ri = (struct ri_controller*)opaque; uint32_t reg = ri_reg(address); - *value = ri->regs[reg]; + if (reg < RI_REGS_COUNT) { + *value = ri->regs[reg]; + } } void write_ri_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) @@ -49,6 +51,8 @@ void write_ri_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask struct ri_controller* ri = (struct ri_controller*)opaque; uint32_t reg = ri_reg(address); - masked_write(&ri->regs[reg], value, mask); + if (reg < RI_REGS_COUNT) { + masked_write(&ri->regs[reg], value, mask); + } } diff --git a/src/device/rcp/rsp/rsp_core.c b/src/device/rcp/rsp/rsp_core.c index 270fd6520..d6b4584d0 100644 --- a/src/device/rcp/rsp/rsp_core.c +++ b/src/device/rcp/rsp/rsp_core.c @@ -259,7 +259,9 @@ void read_rsp_regs(void* opaque, uint32_t address, uint32_t* value) struct rsp_core* sp = (struct rsp_core*)opaque; uint32_t reg = rsp_reg(address); - *value = sp->regs[reg]; + if (reg < SP_REGS_COUNT) { + *value = sp->regs[reg]; + } if (reg == SP_SEMAPHORE_REG) { @@ -281,7 +283,9 @@ void write_rsp_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mas return; } - masked_write(&sp->regs[reg], value, mask); + if (reg < SP_REGS_COUNT) { + masked_write(&sp->regs[reg], value, mask); + } switch(reg) { @@ -303,7 +307,9 @@ void read_rsp_regs2(void* opaque, uint32_t address, uint32_t* value) struct rsp_core* sp = (struct rsp_core*)opaque; uint32_t reg = rsp_reg2(address); - *value = sp->regs2[reg]; + if (reg < SP_REGS2_COUNT) { + *value = sp->regs2[reg]; + } if (reg == SP_PC_REG) *value &= 0xffc; @@ -318,7 +324,9 @@ void write_rsp_regs2(void* opaque, uint32_t address, uint32_t value, uint32_t ma if (reg == SP_PC_REG) mask &= 0xffc; - masked_write(&sp->regs2[reg], value, mask); + if (reg < SP_REGS2_COUNT) { + masked_write(&sp->regs2[reg], value, mask); + } } void do_SP_Task(struct rsp_core* sp) diff --git a/src/device/rcp/si/si_controller.c b/src/device/rcp/si/si_controller.c index c35de3745..5ef416627 100644 --- a/src/device/rcp/si/si_controller.c +++ b/src/device/rcp/si/si_controller.c @@ -123,7 +123,9 @@ void read_si_regs(void* opaque, uint32_t address, uint32_t* value) struct si_controller* si = (struct si_controller*)opaque; uint32_t reg = si_reg(address); - *value = si->regs[reg]; + if (reg < SI_REGS_COUNT) { + *value = si->regs[reg]; + } } void write_si_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) diff --git a/src/device/rcp/vi/vi_controller.c b/src/device/rcp/vi/vi_controller.c index 4cd3abb6a..e7eb8d4f2 100644 --- a/src/device/rcp/vi/vi_controller.c +++ b/src/device/rcp/vi/vi_controller.c @@ -105,7 +105,9 @@ void read_vi_regs(void* opaque, uint32_t address, uint32_t* value) vi->regs[VI_CURRENT_REG] = (vi->regs[VI_CURRENT_REG] & (~1)) | vi->field; } - *value = vi->regs[reg]; + if (reg < VI_REGS_COUNT) { + *value = vi->regs[reg]; + } } void write_vi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) @@ -151,7 +153,9 @@ void write_vi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask return; } - masked_write(&vi->regs[reg], value, mask); + if (reg < VI_REGS_COUNT) { + masked_write(&vi->regs[reg], value, mask); + } } void vi_vertical_interrupt_event(void* opaque) diff --git a/src/device/rdram/rdram.c b/src/device/rdram/rdram.c index 28065eaf0..7fbb20243 100644 --- a/src/device/rdram/rdram.c +++ b/src/device/rdram/rdram.c @@ -173,7 +173,9 @@ void read_rdram_regs(void* opaque, uint32_t address, uint32_t* value) return; } - *value = rdram->regs[module][reg]; + if (reg < RDRAM_REGS_COUNT) { + *value = rdram->regs[module][reg]; + } /* some bits are inverted when read */ if (reg == RDRAM_MODE_REG) { @@ -211,6 +213,8 @@ void write_rdram_regs(void* opaque, uint32_t address, uint32_t value, uint32_t m } } + /* don't go out-of-bounds */ + if (reg >= RDRAM_REGS_COUNT) return; if (address & RDRAM_BCAST_ADDRESS_MASK) { for (module = 0; module < modules; ++module) {