command parser updated

This commit is contained in:
Nicolas 2026-03-19 15:59:27 +01:00
parent 33b833c41a
commit bd49f02dee
7 changed files with 255 additions and 159 deletions

View File

@ -6,7 +6,8 @@ ext = Extension(
"src/coparun/coparun_module.c",
"src/coparun/runmem.c",
"src/coparun/mem_man.c"
]
],
#define_macros=[("ENABLE_BASIC_LOGGING", None)]
)
setup(

View File

@ -64,10 +64,22 @@ int main(int argc, char *argv[]) {
targ.data_memory = NULL;
targ.entr_point = NULL;
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 */
if (argc != 3) {
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);
return ret < 0;
return targ.state_flag < 0;
}

View File

@ -14,7 +14,6 @@ static PyObject* coparun(PyObject* self, PyObject* args) {
PyObject *handle_obj;
const char *buf;
Py_ssize_t buf_len;
int result;
// Expect: handle, bytes
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. */
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
return PyLong_FromLong(result);
return PyLong_FromLong(context->state_flag);
}
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) {
// Allocate a new runmem_t struct, zero-initialized
runmem_t *context = (runmem_t*)calloc(1, sizeof(runmem_t));
if (!context) {
return PyErr_NoMemory();

View File

@ -6,12 +6,46 @@
* handles memory management accordingly.
*/
#include <stdio.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 <string.h>
#include <stdio.h>
/* Windows implementations */
@ -62,6 +96,9 @@ void deallocate_memory(uint8_t *memory, uint32_t memory_len) {
#else
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
/* POSIX implementations */

View File

@ -7,4 +7,10 @@ uint8_t *allocate_buffer_memory(uint32_t num_bytes);
int mark_mem_executable(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 */

View File

@ -5,10 +5,6 @@
* 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 "mem_man.h"
@ -144,33 +140,66 @@ int floor_div(int a, int b) {
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;
uint32_t command;
uint32_t patch_mask;
int32_t patch_scale;
uint32_t offs;
uint32_t size;
int end_flag = 0;
uint32_t rel_entr_point = 0;
uint32_t header_size;
uint8_t *byte_offset = bytes;
while(!end_flag) {
while(bytes < byte_offset + lengths) {
//LOG("# LOOP START: context->rx_state=%i byte_index=%i lengths=%i\n", context->rx_state, bytes - byte_offset, lengths);
if (context->rx_state == RX_STATE_IDLE) {
uint32_t remaining_bytes = (uint32_t)(byte_offset + lengths - bytes);
if (remaining_bytes < 4) {
return bytes - byte_offset; // Return the number of bytes processed
}
command = *(uint32_t*)bytes;
header_size = (command >> 16) & 0xFFFF;
if (remaining_bytes < 4 + header_size) {
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)) end_flag = -4;
if (!update_data_offs(context)) context->state_flag = STATE_FLAG_MEM_DIST;
break;
case COPY_DATA:
offs = *(uint32_t*)bytes; bytes += 4;
size = *(uint32_t*)bytes; bytes += 4;
LOG("COPY_DATA offs=%i size=%i\n", offs, size);
memcpy(context->data_memory + offs, bytes, size); bytes += size;
context->data_src = bytes;
context->data_dest = context->data_memory + offs;
context->data_size = size;
context->rx_state = RX_STATE_DATA;
break;
case ALLOCATE_CODE:
@ -178,14 +207,17 @@ int parse_commands(runmem_t *context, uint8_t *bytes) {
context->executable_memory = allocate_executable_memory(size);
context->executable_memory_len = size;
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;
case COPY_CODE:
offs = *(uint32_t*)bytes; bytes += 4;
size = *(uint32_t*)bytes; bytes += 4;
LOG("COPY_CODE offs=%i size=%i\n", offs, size);
memcpy(context->executable_memory + offs, bytes, size); bytes += size;
context->data_src = bytes;
context->data_dest = context->executable_memory + offs;
context->data_size = size;
context->rx_state = RX_STATE_DATA;
break;
case PATCH_FUNC:
@ -289,9 +321,9 @@ int parse_commands(runmem_t *context, uint8_t *bytes) {
size = *(uint32_t*)bytes; bytes += 4;
BLOG("READ_DATA offs=%i size=%i data=", offs, size);
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;
case FREE_MEMORY:
@ -301,19 +333,20 @@ int parse_commands(runmem_t *context, uint8_t *bytes) {
case DUMP_CODE:
LOG("DUMP_CODE\n");
end_flag = 2;
context->state_flag = STATE_FLAG_DUMP_CODE;
break;
case END_COM:
LOG("END_COM\n");
end_flag = 1;
context->state_flag = STATE_FLAG_END_COM;
break;
default:
LOG("Unknown command\n");
end_flag = -1;
context->state_flag = STATE_FLAG_UNKNOWN_COMMAND;
break;
}
}
return end_flag;
}
return bytes - byte_offset;
}

View File

@ -10,6 +10,13 @@
#include <stdint.h>
#ifdef DATA_MEMORY_ADDR
#define PRINTF(...)
#else
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#endif
#ifdef ENABLE_LOGGING
#define LOG(...) printf(__VA_ARGS__)
#define BLOG(...) printf(__VA_ARGS__)