mirror of https://github.com/Nonannet/copapy.git
command parser updated
This commit is contained in:
parent
33b833c41a
commit
bd49f02dee
3
setup.py
3
setup.py
|
|
@ -6,7 +6,8 @@ ext = Extension(
|
||||||
"src/coparun/coparun_module.c",
|
"src/coparun/coparun_module.c",
|
||||||
"src/coparun/runmem.c",
|
"src/coparun/runmem.c",
|
||||||
"src/coparun/mem_man.c"
|
"src/coparun/mem_man.c"
|
||||||
]
|
],
|
||||||
|
#define_macros=[("ENABLE_BASIC_LOGGING", None)]
|
||||||
)
|
)
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,22 @@ int main(int argc, char *argv[]) {
|
||||||
targ.data_memory = NULL;
|
targ.data_memory = NULL;
|
||||||
targ.entr_point = NULL;
|
targ.entr_point = NULL;
|
||||||
targ.data_offs = 0;
|
targ.data_offs = 0;
|
||||||
|
targ.rx_state = RX_STATE_IDLE;
|
||||||
|
targ.state_flag = 0;
|
||||||
|
|
||||||
int ret = parse_commands(&targ, file_buff);
|
int ret = parse_commands(&targ, file_buff, (uint32_t)sz);
|
||||||
|
|
||||||
if (ret == 2) {
|
/*int offs = 0;
|
||||||
|
for (int i = 0; i < sz + 1; i++) {
|
||||||
|
if (i - offs < 0) {
|
||||||
|
printf("Error: parse_commands returned invalid offset i=%i offs=%i\n", i, offs);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
offs += parse_commands(&targ, file_buff + offs, i - offs);
|
||||||
|
printf("> i=%i offs=%i\n", i, offs);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if (targ.state_flag == STATE_FLAG_DUMP_CODE) {
|
||||||
/* Dump code for debugging */
|
/* Dump code for debugging */
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
fprintf(stderr, "Usage: %s <code_file> <memory_dump_file>\n", argv[0]);
|
fprintf(stderr, "Usage: %s <code_file> <memory_dump_file>\n", argv[0]);
|
||||||
|
|
@ -80,5 +92,5 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
free_memory(&targ);
|
free_memory(&targ);
|
||||||
|
|
||||||
return ret < 0;
|
return targ.state_flag < 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ static PyObject* coparun(PyObject* self, PyObject* args) {
|
||||||
PyObject *handle_obj;
|
PyObject *handle_obj;
|
||||||
const char *buf;
|
const char *buf;
|
||||||
Py_ssize_t buf_len;
|
Py_ssize_t buf_len;
|
||||||
int result;
|
|
||||||
|
|
||||||
// Expect: handle, bytes
|
// Expect: handle, bytes
|
||||||
if (!PyArg_ParseTuple(args, "Oy#", &handle_obj, &buf, &buf_len)) {
|
if (!PyArg_ParseTuple(args, "Oy#", &handle_obj, &buf, &buf_len)) {
|
||||||
|
|
@ -30,10 +29,10 @@ static PyObject* coparun(PyObject* self, PyObject* args) {
|
||||||
|
|
||||||
/* If parse_commands may run for a long time, release the GIL. */
|
/* If parse_commands may run for a long time, release the GIL. */
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
result = parse_commands(context, (uint8_t*)buf);
|
parse_commands(context, (uint8_t*)buf, (uint32_t)buf_len);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
return PyLong_FromLong(result);
|
return PyLong_FromLong(context->state_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject* read_data_mem(PyObject* self, PyObject* args) {
|
static PyObject* read_data_mem(PyObject* self, PyObject* args) {
|
||||||
|
|
@ -74,6 +73,7 @@ static PyObject* read_data_mem(PyObject* self, PyObject* args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject* create_target(PyObject* self, PyObject* args) {
|
static PyObject* create_target(PyObject* self, PyObject* args) {
|
||||||
|
// Allocate a new runmem_t struct, zero-initialized
|
||||||
runmem_t *context = (runmem_t*)calloc(1, sizeof(runmem_t));
|
runmem_t *context = (runmem_t*)calloc(1, sizeof(runmem_t));
|
||||||
if (!context) {
|
if (!context) {
|
||||||
return PyErr_NoMemory();
|
return PyErr_NoMemory();
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,46 @@
|
||||||
* handles memory management accordingly.
|
* handles memory management accordingly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
#if defined DATA_MEMORY_ADDR || defined EXECUTABLE_MEMORY_ADDR
|
||||||
|
/* Bare metal implementations */
|
||||||
|
#if not defined(EXECUTABLE_MEMORY_ADDR) || not defined(DATA_MEMORY_ADDR)
|
||||||
|
#error "For bare metal, you must define DATA_MEMORY_ADDR and DATA_EXECUTABLE_MEMORY_ADDR."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8_t *allocate_executable_memory(uint32_t num_bytes) {
|
||||||
|
return (uint8_t*)EXECUTABLE_MEMORY_ADDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *allocate_data_memory(uint32_t num_bytes) {
|
||||||
|
return (uint8_t*)DATA_MEMORY_ADDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mark_mem_executable(uint8_t *memory, uint32_t memory_len) {
|
||||||
|
/* No-op for bare metal */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate_memory(uint8_t *memory, uint32_t memory_len) {
|
||||||
|
/* No-op for bare metal */
|
||||||
|
}
|
||||||
|
|
||||||
|
void memcpy(void *dest, const void *src, size_t n) {
|
||||||
|
uint8_t *d = (uint8_t*)dest;
|
||||||
|
const uint8_t *s = (const uint8_t*)src;
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
d[i] = s[i];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
/* Windows implementations */
|
/* Windows implementations */
|
||||||
|
|
||||||
|
|
@ -62,6 +96,9 @@ void deallocate_memory(uint8_t *memory, uint32_t memory_len) {
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
/* POSIX implementations */
|
/* POSIX implementations */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,10 @@ uint8_t *allocate_buffer_memory(uint32_t num_bytes);
|
||||||
int mark_mem_executable(uint8_t *memory, uint32_t memory_len);
|
int mark_mem_executable(uint8_t *memory, uint32_t memory_len);
|
||||||
void deallocate_memory(uint8_t *memory, uint32_t memory_len);
|
void deallocate_memory(uint8_t *memory, uint32_t memory_len);
|
||||||
|
|
||||||
|
#ifdef DATA_MEMORY_ADDR
|
||||||
|
void memcpy(void *dest, const void *src, size_t n);
|
||||||
|
#else
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* MEM_MAN_H */
|
#endif /* MEM_MAN_H */
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,6 @@
|
||||||
* and jumps to the entry point of the copapy program
|
* and jumps to the entry point of the copapy program
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include "runmem.h"
|
#include "runmem.h"
|
||||||
#include "mem_man.h"
|
#include "mem_man.h"
|
||||||
|
|
||||||
|
|
@ -60,7 +56,7 @@ void patch_arm32_abs(uint8_t *patch_addr, uint32_t imm16)
|
||||||
void patch_arm_thm_abs(uint8_t *patch_addr, uint32_t imm16)
|
void patch_arm_thm_abs(uint8_t *patch_addr, uint32_t imm16)
|
||||||
{
|
{
|
||||||
// Thumb MOVW (T3) / MOVT (T1) encoding
|
// Thumb MOVW (T3) / MOVT (T1) encoding
|
||||||
|
|
||||||
uint16_t *instr16 = (uint16_t *)patch_addr;
|
uint16_t *instr16 = (uint16_t *)patch_addr;
|
||||||
uint16_t first_half = instr16[0];
|
uint16_t first_half = instr16[0];
|
||||||
uint16_t second_half = instr16[1];
|
uint16_t second_half = instr16[1];
|
||||||
|
|
@ -144,176 +140,213 @@ int floor_div(int a, int b) {
|
||||||
return a / b - ((a % b != 0) && ((a < 0) != (b < 0)));
|
return a / b - ((a % b != 0) && ((a < 0) != (b < 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_commands(runmem_t *context, uint8_t *bytes) {
|
int parse_commands(runmem_t *context, uint8_t *bytes, uint32_t lengths) {
|
||||||
int32_t value;
|
int32_t value;
|
||||||
uint32_t command;
|
uint32_t command;
|
||||||
uint32_t patch_mask;
|
uint32_t patch_mask;
|
||||||
int32_t patch_scale;
|
int32_t patch_scale;
|
||||||
uint32_t offs;
|
uint32_t offs;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
int end_flag = 0;
|
|
||||||
uint32_t rel_entr_point = 0;
|
uint32_t rel_entr_point = 0;
|
||||||
|
uint32_t header_size;
|
||||||
|
uint8_t *byte_offset = bytes;
|
||||||
|
|
||||||
while(!end_flag) {
|
while(bytes < byte_offset + lengths) {
|
||||||
command = *(uint32_t*)bytes;
|
//LOG("# LOOP START: context->rx_state=%i byte_index=%i lengths=%i\n", context->rx_state, bytes - byte_offset, lengths);
|
||||||
bytes += 4;
|
if (context->rx_state == RX_STATE_IDLE) {
|
||||||
switch(command) {
|
uint32_t remaining_bytes = (uint32_t)(byte_offset + lengths - bytes);
|
||||||
case ALLOCATE_DATA:
|
if (remaining_bytes < 4) {
|
||||||
size = *(uint32_t*)bytes; bytes += 4;
|
return bytes - byte_offset; // Return the number of bytes processed
|
||||||
context->data_memory = allocate_data_memory(size);
|
}
|
||||||
context->data_memory_len = size;
|
command = *(uint32_t*)bytes;
|
||||||
LOG("ALLOCATE_DATA size=%i mem_addr=%p\n", size, (void*)context->data_memory);
|
header_size = (command >> 16) & 0xFFFF;
|
||||||
if (!update_data_offs(context)) end_flag = -4;
|
if (remaining_bytes < 4 + header_size) {
|
||||||
break;
|
return bytes - byte_offset; // Return the number of bytes processed
|
||||||
|
}
|
||||||
|
//LOG("+ Switch to RX_STATE_HEADER; context->rx_state=%i byte_index=%i lengths=%i\n", context->rx_state, bytes - byte_offset, lengths);
|
||||||
|
context->rx_state = RX_STATE_HEADER;
|
||||||
|
} else if (context->rx_state == RX_STATE_DATA) {
|
||||||
|
uint32_t chunk_size = context->data_size;
|
||||||
|
if (lengths - (bytes - byte_offset) < chunk_size) {
|
||||||
|
chunk_size = lengths - (bytes - byte_offset);
|
||||||
|
}
|
||||||
|
//LOG(" -> COPY_DATA chunk_size=%i remaining_data_size=%i\n", chunk_size, context->data_size);
|
||||||
|
memcpy(context->data_dest, context->data_src, chunk_size);
|
||||||
|
context->data_dest += chunk_size;
|
||||||
|
context->data_src += chunk_size;
|
||||||
|
context->data_size -= chunk_size;
|
||||||
|
bytes += chunk_size;
|
||||||
|
if (context->data_size == 0) {
|
||||||
|
//LOG(" -> COPY_DATA completed\n");
|
||||||
|
context->rx_state = RX_STATE_IDLE;
|
||||||
|
}
|
||||||
|
} else if (context->rx_state == RX_STATE_HEADER) {
|
||||||
|
bytes += 4;
|
||||||
|
context->rx_state = RX_STATE_IDLE;
|
||||||
|
switch(command) {
|
||||||
|
case ALLOCATE_DATA:
|
||||||
|
size = *(uint32_t*)bytes; bytes += 4;
|
||||||
|
context->data_memory = allocate_data_memory(size);
|
||||||
|
context->data_memory_len = size;
|
||||||
|
LOG("ALLOCATE_DATA size=%i mem_addr=%p\n", size, (void*)context->data_memory);
|
||||||
|
if (!update_data_offs(context)) context->state_flag = STATE_FLAG_MEM_DIST;
|
||||||
|
break;
|
||||||
|
|
||||||
case COPY_DATA:
|
case COPY_DATA:
|
||||||
offs = *(uint32_t*)bytes; bytes += 4;
|
offs = *(uint32_t*)bytes; bytes += 4;
|
||||||
size = *(uint32_t*)bytes; bytes += 4;
|
size = *(uint32_t*)bytes; bytes += 4;
|
||||||
LOG("COPY_DATA offs=%i size=%i\n", offs, size);
|
LOG("COPY_DATA offs=%i size=%i\n", offs, size);
|
||||||
memcpy(context->data_memory + offs, bytes, size); bytes += size;
|
context->data_src = bytes;
|
||||||
break;
|
context->data_dest = context->data_memory + offs;
|
||||||
|
context->data_size = size;
|
||||||
|
context->rx_state = RX_STATE_DATA;
|
||||||
|
break;
|
||||||
|
|
||||||
case ALLOCATE_CODE:
|
case ALLOCATE_CODE:
|
||||||
size = *(uint32_t*)bytes; bytes += 4;
|
size = *(uint32_t*)bytes; bytes += 4;
|
||||||
context->executable_memory = allocate_executable_memory(size);
|
context->executable_memory = allocate_executable_memory(size);
|
||||||
context->executable_memory_len = size;
|
context->executable_memory_len = size;
|
||||||
LOG("ALLOCATE_CODE size=%i mem_addr=%p\n", size, (void*)context->executable_memory);
|
LOG("ALLOCATE_CODE size=%i mem_addr=%p\n", size, (void*)context->executable_memory);
|
||||||
if (!update_data_offs(context)) end_flag = -4;
|
if (!update_data_offs(context)) context->state_flag = STATE_FLAG_MEM_DIST;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COPY_CODE:
|
case COPY_CODE:
|
||||||
offs = *(uint32_t*)bytes; bytes += 4;
|
offs = *(uint32_t*)bytes; bytes += 4;
|
||||||
size = *(uint32_t*)bytes; bytes += 4;
|
size = *(uint32_t*)bytes; bytes += 4;
|
||||||
LOG("COPY_CODE offs=%i size=%i\n", offs, size);
|
LOG("COPY_CODE offs=%i size=%i\n", offs, size);
|
||||||
memcpy(context->executable_memory + offs, bytes, size); bytes += size;
|
context->data_src = bytes;
|
||||||
break;
|
context->data_dest = context->executable_memory + offs;
|
||||||
|
context->data_size = size;
|
||||||
|
context->rx_state = RX_STATE_DATA;
|
||||||
|
break;
|
||||||
|
|
||||||
case PATCH_FUNC:
|
case PATCH_FUNC:
|
||||||
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_FUNC patch_offs=%i patch_mask=%#08x scale=%i value=%i\n",
|
LOG("PATCH_FUNC patch_offs=%i patch_mask=%#08x scale=%i value=%i\n",
|
||||||
offs, patch_mask, patch_scale, value);
|
offs, patch_mask, patch_scale, value);
|
||||||
patch(context->executable_memory + offs, patch_mask, value / patch_scale);
|
patch(context->executable_memory + offs, patch_mask, value / patch_scale);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PATCH_OBJECT:
|
case PATCH_OBJECT:
|
||||||
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 patch_offs=%i patch_mask=%#08x scale=%i value=%i\n",
|
LOG("PATCH_OBJECT patch_offs=%i patch_mask=%#08x scale=%i value=%i\n",
|
||||||
offs, patch_mask, patch_scale, value);
|
offs, patch_mask, patch_scale, value);
|
||||||
patch(context->executable_memory + offs, patch_mask, value / patch_scale + context->data_offs / patch_scale);
|
patch(context->executable_memory + offs, patch_mask, value / patch_scale + context->data_offs / patch_scale);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PATCH_OBJECT_ABS:
|
case PATCH_OBJECT_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_ABS patch_offs=%i patch_mask=%#08x scale=%i value=%i\n",
|
LOG("PATCH_OBJECT_ABS patch_offs=%i patch_mask=%#08x scale=%i value=%i\n",
|
||||||
offs, patch_mask, patch_scale, value);
|
offs, patch_mask, patch_scale, value);
|
||||||
patch(context->executable_memory + offs, patch_mask, value / patch_scale);
|
patch(context->executable_memory + offs, patch_mask, value / patch_scale);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PATCH_OBJECT_REL:
|
case PATCH_OBJECT_REL:
|
||||||
offs = *(uint32_t*)bytes; bytes += 4;
|
offs = *(uint32_t*)bytes; bytes += 4;
|
||||||
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",
|
||||||
offs, (void*)(context->data_memory + value), patch_scale, value);
|
offs, (void*)(context->data_memory + value), patch_scale, value);
|
||||||
*(void **)(context->executable_memory + offs) = context->data_memory + value;
|
*(void **)(context->executable_memory + offs) = context->data_memory + value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PATCH_OBJECT_HI21:
|
case PATCH_OBJECT_HI21:
|
||||||
offs = *(uint32_t*)bytes; bytes += 4;
|
offs = *(uint32_t*)bytes; bytes += 4;
|
||||||
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_HI21 patch_offs=%i scale=%i value=%i res_value=%i\n",
|
LOG("PATCH_OBJECT_HI21 patch_offs=%i scale=%i value=%i res_value=%i\n",
|
||||||
offs, patch_scale, value, floor_div(context->data_offs + value, patch_scale) - (int32_t)offs / patch_scale);
|
offs, patch_scale, value, floor_div(context->data_offs + value, patch_scale) - (int32_t)offs / patch_scale);
|
||||||
patch_hi21(context->executable_memory + offs, floor_div(context->data_offs + value, patch_scale) - (int32_t)offs / patch_scale);
|
patch_hi21(context->executable_memory + offs, floor_div(context->data_offs + value, patch_scale) - (int32_t)offs / patch_scale);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PATCH_OBJECT_ARM32_ABS:
|
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_ARM32_ABS patch_offs=%i patch_mask=%#08x scale=%i value=%i imm16=%#04x\n",
|
LOG("PATCH_OBJECT_ARM32_ABS patch_offs=%i patch_mask=%#08x scale=%i value=%i imm16=%#04x\n",
|
||||||
offs, patch_mask, patch_scale, value, (uint32_t)((uintptr_t)(context->data_memory + value) & patch_mask) / (uint32_t)patch_scale);
|
offs, patch_mask, patch_scale, value, (uint32_t)((uintptr_t)(context->data_memory + value) & patch_mask) / (uint32_t)patch_scale);
|
||||||
patch_arm32_abs(context->executable_memory + offs, (uint32_t)((uintptr_t)(context->data_memory + value) & patch_mask) / (uint32_t)patch_scale);
|
patch_arm32_abs(context->executable_memory + offs, (uint32_t)((uintptr_t)(context->data_memory + value) & patch_mask) / (uint32_t)patch_scale);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PATCH_FUNC_ARM32_THM:
|
case PATCH_FUNC_ARM32_THM:
|
||||||
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_FUNC_ARM32_THM patch_offs=%i patch_mask=%#08x scale=%i value=%i\n",
|
LOG("PATCH_FUNC_ARM32_THM patch_offs=%i patch_mask=%#08x scale=%i value=%i\n",
|
||||||
offs, patch_mask, patch_scale, value);
|
offs, patch_mask, patch_scale, value);
|
||||||
patch_arm_thm_jump24(context->executable_memory + offs, value);
|
patch_arm_thm_jump24(context->executable_memory + offs, value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PATCH_OBJECT_ARM32_ABS_THM:
|
case PATCH_OBJECT_ARM32_ABS_THM:
|
||||||
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_ARM32_ABS_THM patch_offs=%i patch_mask=%#08x scale=%i value=%i imm16=%#04x\n",
|
LOG("PATCH_OBJECT_ARM32_ABS_THM patch_offs=%i patch_mask=%#08x scale=%i value=%i imm16=%#04x\n",
|
||||||
offs, patch_mask, patch_scale, value, (uint32_t)((uintptr_t)(context->data_memory + value) & patch_mask) / (uint32_t)patch_scale);
|
offs, patch_mask, patch_scale, value, (uint32_t)((uintptr_t)(context->data_memory + value) & patch_mask) / (uint32_t)patch_scale);
|
||||||
patch_arm_thm_abs(context->executable_memory + offs, (uint32_t)((uintptr_t)(context->data_memory + value) & patch_mask) / (uint32_t)patch_scale);
|
patch_arm_thm_abs(context->executable_memory + offs, (uint32_t)((uintptr_t)(context->data_memory + value) & patch_mask) / (uint32_t)patch_scale);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ENTRY_POINT:
|
case ENTRY_POINT:
|
||||||
rel_entr_point = *(uint32_t*)bytes; bytes += 4;
|
rel_entr_point = *(uint32_t*)bytes; bytes += 4;
|
||||||
context->entr_point = (entry_point_t)(context->executable_memory + rel_entr_point);
|
context->entr_point = (entry_point_t)(context->executable_memory + rel_entr_point);
|
||||||
LOG("ENTRY_POINT rel_entr_point=%i\n", rel_entr_point);
|
LOG("ENTRY_POINT rel_entr_point=%i\n", rel_entr_point);
|
||||||
mark_mem_executable(context->executable_memory, context->executable_memory_len);
|
mark_mem_executable(context->executable_memory, context->executable_memory_len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RUN_PROG:
|
case RUN_PROG:
|
||||||
LOG("RUN_PROG\n");
|
LOG("RUN_PROG\n");
|
||||||
{
|
{
|
||||||
int ret = context->entr_point();
|
int ret = context->entr_point();
|
||||||
(void)ret;
|
(void)ret;
|
||||||
BLOG("Return value: %i\n", ret);
|
BLOG("Return value: %i\n", ret);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case READ_DATA:
|
case READ_DATA:
|
||||||
offs = *(uint32_t*)bytes; bytes += 4;
|
offs = *(uint32_t*)bytes; bytes += 4;
|
||||||
size = *(uint32_t*)bytes; bytes += 4;
|
size = *(uint32_t*)bytes; bytes += 4;
|
||||||
BLOG("READ_DATA offs=%i size=%i data=", offs, size);
|
BLOG("READ_DATA offs=%i size=%i data=", offs, size);
|
||||||
for (uint32_t i = 0; i < size; i++) {
|
for (uint32_t i = 0; i < size; i++) {
|
||||||
printf("%02X ", context->data_memory[offs + i]);
|
PRINTF("%02X ", context->data_memory[offs + i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
PRINTF("\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FREE_MEMORY:
|
case FREE_MEMORY:
|
||||||
LOG("FREE_MENORY\n");
|
LOG("FREE_MENORY\n");
|
||||||
free_memory(context);
|
free_memory(context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DUMP_CODE:
|
case DUMP_CODE:
|
||||||
LOG("DUMP_CODE\n");
|
LOG("DUMP_CODE\n");
|
||||||
end_flag = 2;
|
context->state_flag = STATE_FLAG_DUMP_CODE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case END_COM:
|
case END_COM:
|
||||||
LOG("END_COM\n");
|
LOG("END_COM\n");
|
||||||
end_flag = 1;
|
context->state_flag = STATE_FLAG_END_COM;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG("Unknown command\n");
|
LOG("Unknown command\n");
|
||||||
end_flag = -1;
|
context->state_flag = STATE_FLAG_UNKNOWN_COMMAND;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return end_flag;
|
return bytes - byte_offset;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,13 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef DATA_MEMORY_ADDR
|
||||||
|
#define PRINTF(...)
|
||||||
|
#else
|
||||||
|
#include <stdio.h>
|
||||||
|
#define PRINTF(...) printf(__VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_LOGGING
|
#ifdef ENABLE_LOGGING
|
||||||
#define LOG(...) printf(__VA_ARGS__)
|
#define LOG(...) printf(__VA_ARGS__)
|
||||||
#define BLOG(...) printf(__VA_ARGS__)
|
#define BLOG(...) printf(__VA_ARGS__)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue