diff --git a/include/arch/arch_mips32.hpp b/include/arch/arch_mips32.hpp index 0d1bf435208f29204bc7bb2480f9966bf81feff8..5746425db030d5da2f94867055483a84aa620de9 100644 --- a/include/arch/arch_mips32.hpp +++ b/include/arch/arch_mips32.hpp @@ -10,8 +10,8 @@ class ZiprArchitectureHelperMIPS32_t : public ZiprArchitectureHelperBase_t virtual IRDB_SDK::Instruction_t* createNewJumpInstruction(IRDB_SDK::FileIR_t *p_firp, IRDB_SDK::Instruction_t* p_existing) override { - // bytes = 0b00000000 0b00000000 0b00000000 0b00010000 - // jump always with 26bit offset + // create a beq $0, $0, imm16 instruction + // to be PC-relative. const auto bits =string("\x10\x00\x00\x000",4); auto ret=IRDB_SDK::addNewDataBits(p_firp, p_existing, bits); const auto d=IRDB_SDK::DecodedInstruction_t::factory(ret); diff --git a/src/patcher_mips32.cpp b/src/patcher_mips32.cpp index ec147ecd4eb9537d2dc08830bf86433560e70c17..392a57175fb07b4f4c610a5116cbecc8b2b53e7e 100644 --- a/src/patcher_mips32.cpp +++ b/src/patcher_mips32.cpp @@ -64,43 +64,28 @@ void ZiprPatcherMIPS32_t::ApplyNopToPatch(RangeAddress_t addr) void ZiprPatcherMIPS32_t::ApplyPatch(RangeAddress_t from_addr, RangeAddress_t to_addr) { +#if 0 const auto first_byte = (uint8_t)memory_space[from_addr+0]; - const auto new_offset = (int32_t)((to_addr) - (from_addr+8)) >> 2; - - // A Branch in binary is: op= 000010 imm26=0000 00000000 00000000 00000000 - // it includes a 26-bit immediate, which is +/- 128mb, which should be a good enough "jump anywhere" - // for now. - const auto mask6 = (0b111111); - const auto is_uncond_branch = ((first_byte >> 2) & mask6) == (0b000010); // jump branch - - if(is_uncond_branch) - { - cout<<"Applying uncond branch patch from "<<hex<<from_addr<<" to "<<to_addr<<endl; - const auto non_imm_bits = 32U-26U; // 32 bits - imm26 - // assert there's no overflow. - assert((int64_t)(new_offset << non_imm_bits) == ((int64_t)new_offset) << non_imm_bits); - // or in opcode for first byte. set remaining bytes. - const auto mask26 = ((1<<26)-1); - const auto trimmed_offset = new_offset & mask26; - memory_space[from_addr+3] = (trimmed_offset>> 0)&0xff; - memory_space[from_addr+2] = (trimmed_offset>> 8)&0xff; - memory_space[from_addr+1] = (trimmed_offset>>16)&0xff; - memory_space[from_addr+0] |= (trimmed_offset>>24)&0x02; - } - else - { - cout<<"Applying cond branch patch from "<<hex<<from_addr<<" to "<<to_addr<<endl; - const auto non_imm_bits = 32U-24U; // 32 bits - imm24 - // assert there's no overflow. - assert((int64_t)(new_offset << non_imm_bits) == ((int64_t)new_offset) << non_imm_bits); - // or in opcode for first byte. set remaining bytes. - const auto mask24 = ((1<<24)-1); - const auto trimmed_offset = new_offset & mask24; - memory_space[from_addr+3] = (trimmed_offset>> 0)&0xff; - memory_space[from_addr+2] = (trimmed_offset>> 8)&0xff; - memory_space[from_addr+1] = (trimmed_offset>>16)&0xff; - memory_space[from_addr+0] |= (trimmed_offset>>24)&0x02; - } + assert(first_byte == 0x10); // beq $0 +#endif + + const auto new_offset = (int32_t)((to_addr) - (from_addr+4)) >> 2; + + + // Use a branch always. In mips, this will be a beq $0, $0, <label> as there is no branch always. + // format: 0001 00ss sstt iiii iiii iiii iiii iiii + // ssss=0b0000 + // tttt=0b0000 + // i...i = (from_addr-to_addr)>>2 + cout<<"Applying cond branch patch from "<<hex<<from_addr<<" to "<<to_addr<<endl; + const auto non_imm_bits = 16; + // assert there's no overflow. + assert((int64_t)(new_offset << non_imm_bits) == ((int64_t)new_offset) << non_imm_bits); + // or in opcode for first byte. set remaining bytes. + const auto mask16 = ((1<<16)-1); + const auto trimmed_offset = new_offset & mask16; + memory_space[from_addr+3] = (trimmed_offset>> 0)&0xff; + memory_space[from_addr+2] = (trimmed_offset>> 8)&0xff; } diff --git a/src/pinner_mips32.cpp b/src/pinner_mips32.cpp index f006e3a6b6fe7c5af356332cb6b03b432e67611c..2627aa1b157b381a973e345bc9e0412fc4810608 100644 --- a/src/pinner_mips32.cpp +++ b/src/pinner_mips32.cpp @@ -41,9 +41,10 @@ void ZiprPinnerMIPS32_t::doPinning() auto ibta_addr=(RangeAddress_t)insn-> getIndirectBranchTargetAddress()-> getVirtualOffset(); - // put unconditional branch with 24-bit offset in memory - // 1110 1010 0000 0000 0000 0000 0000 0000 - uint8_t bytes[]={'\x18','\x00','\x00','\x00'}; + // put branch with 16-bit offset in memory + // i.e., beq $0, $0, imm16 + // including putting a nop in the delay slot. + uint8_t bytes[]={'\x10','\x00','\x00','\x00', '\x00', '\x00', '\x00', '\x00'}; for(auto i=0U;i<sizeof(bytes);i++) { const auto ibta_byte_addr = ibta_addr+i;