From d2f93094b2c848b839b25b7565cb6d4bde7f15c2 Mon Sep 17 00:00:00 2001
From: Jason Hiser <jdhiser@gmail.com>
Date: Mon, 2 Dec 2019 09:42:36 -0500
Subject: [PATCH] mips updates

---
 include/arch/arch_mips32.hpp |  4 +--
 src/patcher_mips32.cpp       | 57 +++++++++++++-----------------------
 src/pinner_mips32.cpp        |  7 +++--
 3 files changed, 27 insertions(+), 41 deletions(-)

diff --git a/include/arch/arch_mips32.hpp b/include/arch/arch_mips32.hpp
index 0d1bf4352..5746425db 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 ec147ecd4..392a57175 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 f006e3a6b..2627aa1b1 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;
-- 
GitLab