diff --git a/libreborn/src/patch/instruction.cpp b/libreborn/src/patch/instruction.cpp index cb5d2235..eaea9b59 100644 --- a/libreborn/src/patch/instruction.cpp +++ b/libreborn/src/patch/instruction.cpp @@ -1,50 +1,43 @@ #include #include "patch-internal.h" -// Generate A BL Instruction -#define INSTRUCTION_RANGE 32000000 -static uint64_t nice_diff_64(uint64_t a, uint64_t b) { - if (a > b) { - return a - b; - } else { - return b - a; +// Extract Target Address From B(L) Instruction +static void *extract_from_bl_instruction(unsigned char *from, const uint32_t instruction) { + // Extract The Signed 24-Bit Immediate Value + int32_t imm24 = int32_t(instruction) & 0x00ffffff; + // Sign-Extend + if (imm24 & 0x00800000) { + imm24 |= int32_t(0xff000000); } + // Calculate Offset + const int32_t offset = imm24 << 2; + // Compute Target Address + return from + 8 + offset; } -uint32_t generate_bl_instruction(void *from, void *to, int use_b_instruction) { - // Check Instruction Range - if (nice_diff_64((uint64_t) to, (uint64_t) from) > INSTRUCTION_RANGE) { - IMPOSSIBLE(); +void *extract_from_bl_instruction(unsigned char *from) { + return extract_from_bl_instruction(from, *(uint32_t *) from); +} + +// Generate A BL Instruction +uint32_t generate_bl_instruction(void *from, void *to, const int use_b_instruction) { + const uint32_t from_addr = uint32_t(from); + const uint32_t to_addr = uint32_t(to); + + // Calculate The Offset + const int32_t offset = int32_t((to_addr - from_addr - 8) >> 2); // Account For The 2-Bit Shift + + // Create the instruction + uint32_t instruction = use_b_instruction ? B_INSTRUCTION : BL_INSTRUCTION; + instruction *= 0x1000000; + + // Set The Offset (Last 24 Bits) + instruction |= (offset & 0x00FFFFFF); + + // Check + if (to != extract_from_bl_instruction((unsigned char *) from, instruction)) { + ERR("Unable To Create Branch Instruction From %p To %p", from, to); } - // Create New Instruction - uint32_t instruction; - unsigned char *instruction_array = (unsigned char *) &instruction; - instruction_array[3] = use_b_instruction ? B_INSTRUCTION : BL_INSTRUCTION; - - // Determine PC - unsigned char *pc = ((unsigned char *) from) + 8; - int32_t offset = (int32_t) to - (int32_t) pc; - int32_t target = offset >> 2; - - // Set Instruction Offset - unsigned char *target_array = (unsigned char *) ⌖ - instruction_array[0] = target_array[0]; - instruction_array[1] = target_array[1]; - instruction_array[2] = target_array[2]; - // Return return instruction; } - -// Extract Target Address From B(L) Instruction -void *extract_from_bl_instruction(unsigned char *from) { - // Calculate PC - unsigned char *pc = ((unsigned char *) from) + 8; - - // Extract Offset From Instruction - int32_t target = *(int32_t *) from; - target = (target << 8) >> 8; - int32_t offset = target << 2; - // Add PC To Offset - return (void *) (pc + offset); -} diff --git a/media-layer/core/src/media.cpp b/media-layer/core/src/media.cpp index 9d2e3b3d..466e1df6 100644 --- a/media-layer/core/src/media.cpp +++ b/media-layer/core/src/media.cpp @@ -15,7 +15,7 @@ // Allow Disabling Interaction static void update_cursor(); static int is_interactable = 1; -void media_set_interactable(int toggle) { +void media_set_interactable(const int toggle) { if (bool(toggle) != is_interactable) { is_interactable = toggle; update_cursor();