mirror of https://github.com/Nonannet/copapy.git
PATCH_OBJECT_ARM32_ABS patching added to support 32 bit ARM
This commit is contained in:
parent
ff5987f5d1
commit
6aca675e65
|
|
@ -10,6 +10,7 @@ Command = Enum('Command', [('ALLOCATE_DATA', 1), ('COPY_DATA', 2),
|
||||||
('PATCH_OBJECT_HI21', 0x2001),
|
('PATCH_OBJECT_HI21', 0x2001),
|
||||||
('PATCH_OBJECT_ABS', 0x2002),
|
('PATCH_OBJECT_ABS', 0x2002),
|
||||||
('PATCH_OBJECT_REL', 0x2003),
|
('PATCH_OBJECT_REL', 0x2003),
|
||||||
|
('PATCH_OBJECT_ARM32_ABS', 0x2004),
|
||||||
('ENTRY_POINT', 7),
|
('ENTRY_POINT', 7),
|
||||||
('RUN_PROG', 64), ('READ_DATA', 65),
|
('RUN_PROG', 64), ('READ_DATA', 65),
|
||||||
('END_COM', 256), ('FREE_MEMORY', 257), ('DUMP_CODE', 258)])
|
('END_COM', 256), ('FREE_MEMORY', 257), ('DUMP_CODE', 258)])
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,30 @@ void patch_hi21(uint8_t *patch_addr, int32_t page_offset) {
|
||||||
*(uint32_t *)patch_addr = instr;
|
*(uint32_t *)patch_addr = instr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void patch_arm32_abs(uint8_t *patch_addr, uint32_t imm16)
|
||||||
|
{
|
||||||
|
uint32_t i = (imm16 >> 11) & 0x1;
|
||||||
|
uint32_t imm4 = (imm16 >> 12) & 0xF;
|
||||||
|
uint32_t imm3 = (imm16 >> 8) & 0x7;
|
||||||
|
uint32_t imm8 = imm16 & 0xFF;
|
||||||
|
|
||||||
|
uint32_t instr = *((uint32_t *)patch_addr);
|
||||||
|
|
||||||
|
// Clear the fields we are going to replace:
|
||||||
|
// imm4 → bits 19:16
|
||||||
|
// imm3 → bits 14:12
|
||||||
|
// i → bit 26
|
||||||
|
// imm8 → bits 7:0
|
||||||
|
instr &= ~(uint32_t)((0xF << 16) | (0x7 << 12) | (1 << 26) | 0xFF);
|
||||||
|
|
||||||
|
instr |= (imm4 << 16);
|
||||||
|
instr |= (imm3 << 12);
|
||||||
|
instr |= (i << 26);
|
||||||
|
instr |= (imm8);
|
||||||
|
|
||||||
|
*((uint32_t *)patch_addr) = instr;
|
||||||
|
}
|
||||||
|
|
||||||
void free_memory() {
|
void free_memory() {
|
||||||
deallocate_memory(executable_memory, executable_memory_len);
|
deallocate_memory(executable_memory, executable_memory_len);
|
||||||
deallocate_memory(data_memory, data_memory_len);
|
deallocate_memory(data_memory, data_memory_len);
|
||||||
|
|
@ -141,7 +165,7 @@ int parse_commands(uint8_t *bytes) {
|
||||||
|
|
||||||
case PATCH_OBJECT_REL:
|
case PATCH_OBJECT_REL:
|
||||||
offs = *(uint32_t*)bytes; bytes += 4;
|
offs = *(uint32_t*)bytes; bytes += 4;
|
||||||
patch_mask = *(uint32_t*)bytes; bytes += 4;
|
bytes += 4;
|
||||||
patch_scale = *(int32_t*)bytes; bytes += 4;
|
patch_scale = *(int32_t*)bytes; bytes += 4;
|
||||||
value = *(int32_t*)bytes; bytes += 4;
|
value = *(int32_t*)bytes; bytes += 4;
|
||||||
LOG("PATCH_OBJECT_REL patch_offs=%i patch_addr=%p scale=%i value=%i\n",
|
LOG("PATCH_OBJECT_REL patch_offs=%i patch_addr=%p scale=%i value=%i\n",
|
||||||
|
|
@ -150,13 +174,23 @@ int parse_commands(uint8_t *bytes) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PATCH_OBJECT_HI21:
|
case PATCH_OBJECT_HI21:
|
||||||
|
offs = *(uint32_t*)bytes; bytes += 4;
|
||||||
|
bytes += 4;
|
||||||
|
patch_scale = *(int32_t*)bytes; bytes += 4;
|
||||||
|
value = *(int32_t*)bytes; bytes += 4;
|
||||||
|
LOG("PATCH_OBJECT_HI21 patch_offs=%i scale=%i value=%i res_value=%i\n",
|
||||||
|
offs, patch_scale, value, floor_div(data_offs + value, patch_scale) - (int32_t)offs / patch_scale);
|
||||||
|
patch_hi21(executable_memory + offs, floor_div(data_offs + value, patch_scale) - (int32_t)offs / patch_scale);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PATCH_OBJECT_ARM32_ABS:
|
||||||
offs = *(uint32_t*)bytes; bytes += 4;
|
offs = *(uint32_t*)bytes; bytes += 4;
|
||||||
patch_mask = *(uint32_t*)bytes; bytes += 4;
|
patch_mask = *(uint32_t*)bytes; bytes += 4;
|
||||||
patch_scale = *(int32_t*)bytes; bytes += 4;
|
patch_scale = *(int32_t*)bytes; bytes += 4;
|
||||||
value = *(int32_t*)bytes; bytes += 4;
|
value = *(int32_t*)bytes; bytes += 4;
|
||||||
LOG("PATCH_OBJECT_HI21 patch_offs=%i patch_mask=%#08x scale=%i value=%i res_value=%i\n",
|
LOG("PATCH_OBJECT_MOVW_ABS patch_offs=%i value=%i\n",
|
||||||
offs, patch_mask, patch_scale, value, floor_div(data_offs + value, patch_scale) - (int32_t)offs / patch_scale);
|
offs, value);
|
||||||
patch_hi21(executable_memory + offs, floor_div(data_offs + value, patch_scale) - (int32_t)offs / patch_scale);
|
patch_arm32_abs(executable_memory + offs, (uint32_t)((uintptr_t)(data_memory + value) & patch_mask) / (uint32_t)patch_scale);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ENTRY_POINT:
|
case ENTRY_POINT:
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
#define PATCH_OBJECT_HI21 0x2001
|
#define PATCH_OBJECT_HI21 0x2001
|
||||||
#define PATCH_OBJECT_ABS 0x2002
|
#define PATCH_OBJECT_ABS 0x2002
|
||||||
#define PATCH_OBJECT_REL 0x2003
|
#define PATCH_OBJECT_REL 0x2003
|
||||||
|
#define PATCH_OBJECT_ARM32_ABS 0x2004
|
||||||
#define ENTRY_POINT 7
|
#define ENTRY_POINT 7
|
||||||
#define RUN_PROG 64
|
#define RUN_PROG 64
|
||||||
#define READ_DATA 65
|
#define READ_DATA 65
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue