2025-09-20 21:25:07 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
2025-10-18 21:26:35 +00:00
|
|
|
#include <math.h>
|
2025-10-03 21:09:25 +00:00
|
|
|
#include "runmem.h"
|
2025-10-04 20:57:45 +00:00
|
|
|
#include "mem_man.h"
|
2025-09-20 21:25:07 +00:00
|
|
|
|
2025-10-18 21:10:40 +00:00
|
|
|
#ifdef ENABLE_LOGGING
|
|
|
|
|
#define LOG(...) printf(__VA_ARGS__)
|
|
|
|
|
#define BLOG(...) printf(__VA_ARGS__)
|
|
|
|
|
#elif ENABLE_BASIC_LOGGING
|
|
|
|
|
#define LOG(...)
|
|
|
|
|
#define BLOG(...) printf(__VA_ARGS__)
|
|
|
|
|
#else
|
|
|
|
|
#define LOG(...)
|
2025-10-18 21:20:15 +00:00
|
|
|
#define BLOG(...)
|
2025-10-18 21:10:40 +00:00
|
|
|
#endif
|
|
|
|
|
|
2025-10-04 20:57:45 +00:00
|
|
|
/* Globals declared extern in runmem.h */
|
2025-10-03 21:09:25 +00:00
|
|
|
uint8_t *data_memory = NULL;
|
|
|
|
|
uint32_t data_memory_len = 0;
|
|
|
|
|
uint8_t *executable_memory = NULL;
|
|
|
|
|
uint32_t executable_memory_len = 0;
|
|
|
|
|
entry_point_t entr_point = NULL;
|
2025-10-05 21:10:38 +00:00
|
|
|
int data_offs = 0;
|
2025-09-20 21:25:07 +00:00
|
|
|
|
2025-10-04 20:57:45 +00:00
|
|
|
void patch_mem_32(uint8_t *patch_addr, int32_t value) {
|
2025-09-20 21:25:07 +00:00
|
|
|
int32_t *val_ptr = (int32_t*)patch_addr;
|
|
|
|
|
*val_ptr = value;
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-04 20:57:45 +00:00
|
|
|
int patch(uint8_t *patch_addr, uint32_t reloc_type, int32_t value) {
|
|
|
|
|
if (reloc_type == PATCH_RELATIVE_32) {
|
2025-09-20 21:25:07 +00:00
|
|
|
patch_mem_32(patch_addr, value);
|
|
|
|
|
}else{
|
2025-10-18 21:10:40 +00:00
|
|
|
LOG("Not implemented");
|
2025-09-20 21:25:07 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
2025-10-03 21:09:25 +00:00
|
|
|
}
|
|
|
|
|
|
2025-10-04 20:57:45 +00:00
|
|
|
void free_memory() {
|
|
|
|
|
deallocate_memory(executable_memory, executable_memory_len);
|
|
|
|
|
deallocate_memory(data_memory, data_memory_len);
|
2025-10-03 21:09:25 +00:00
|
|
|
executable_memory_len = 0;
|
2025-10-04 20:57:45 +00:00
|
|
|
data_memory_len = 0;
|
2025-10-03 21:09:25 +00:00
|
|
|
}
|
2025-09-20 21:25:07 +00:00
|
|
|
|
2025-10-05 21:10:38 +00:00
|
|
|
int update_data_offs() {
|
|
|
|
|
if (data_memory && executable_memory && (data_memory - executable_memory > 0x7FFFFFFF || executable_memory - data_memory > 0x7FFFFFFF)) {
|
|
|
|
|
perror("Error: code and data memory to far apart");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2025-10-05 21:10:00 +00:00
|
|
|
data_offs = (int)(data_memory - executable_memory);
|
2025-10-05 21:10:38 +00:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-04 20:57:45 +00:00
|
|
|
int parse_commands(uint8_t *bytes) {
|
2025-09-20 21:25:07 +00:00
|
|
|
int32_t value;
|
|
|
|
|
uint32_t command;
|
|
|
|
|
uint32_t reloc_type;
|
|
|
|
|
uint32_t offs;
|
|
|
|
|
uint32_t size;
|
2025-10-07 20:56:04 +00:00
|
|
|
int end_flag = 0;
|
2025-10-12 21:22:58 +00:00
|
|
|
uint32_t rel_entr_point = 0;
|
2025-09-20 21:25:07 +00:00
|
|
|
|
2025-10-07 20:56:04 +00:00
|
|
|
while(!end_flag) {
|
2025-09-20 21:25:07 +00:00
|
|
|
command = *(uint32_t*)bytes;
|
|
|
|
|
bytes += 4;
|
|
|
|
|
switch(command) {
|
2025-10-05 21:10:38 +00:00
|
|
|
case ALLOCATE_DATA:
|
2025-09-20 21:25:07 +00:00
|
|
|
size = *(uint32_t*)bytes; bytes += 4;
|
2025-10-04 20:57:45 +00:00
|
|
|
data_memory = allocate_data_memory(size);
|
2025-10-03 21:09:25 +00:00
|
|
|
data_memory_len = size;
|
2025-10-18 21:10:40 +00:00
|
|
|
LOG("ALLOCATE_DATA size=%i mem_addr=%p\n", size, (void*)data_memory);
|
2025-10-07 20:56:04 +00:00
|
|
|
if (!update_data_offs()) end_flag = -4;
|
2025-09-20 21:25:07 +00:00
|
|
|
break;
|
|
|
|
|
|
2025-10-05 21:10:38 +00:00
|
|
|
case COPY_DATA:
|
2025-09-20 21:25:07 +00:00
|
|
|
offs = *(uint32_t*)bytes; bytes += 4;
|
|
|
|
|
size = *(uint32_t*)bytes; bytes += 4;
|
2025-10-18 21:10:40 +00:00
|
|
|
LOG("COPY_DATA offs=%i size=%i\n", offs, size);
|
2025-09-20 21:25:07 +00:00
|
|
|
memcpy(data_memory + offs, bytes, size); bytes += size;
|
|
|
|
|
break;
|
|
|
|
|
|
2025-10-05 21:10:38 +00:00
|
|
|
case ALLOCATE_CODE:
|
2025-09-20 21:25:07 +00:00
|
|
|
size = *(uint32_t*)bytes; bytes += 4;
|
2025-10-04 20:57:45 +00:00
|
|
|
executable_memory = allocate_executable_memory(size);
|
2025-09-20 21:25:07 +00:00
|
|
|
executable_memory_len = size;
|
2025-10-18 21:10:40 +00:00
|
|
|
LOG("ALLOCATE_CODE size=%i mem_addr=%p\n", size, (void*)executable_memory);
|
|
|
|
|
//LOG("# d %i c %i off %i\n", data_memory, executable_memory, data_offs);
|
2025-10-07 20:56:04 +00:00
|
|
|
if (!update_data_offs()) end_flag = -4;
|
2025-09-20 21:25:07 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case COPY_CODE:
|
|
|
|
|
offs = *(uint32_t*)bytes; bytes += 4;
|
|
|
|
|
size = *(uint32_t*)bytes; bytes += 4;
|
2025-10-18 21:10:40 +00:00
|
|
|
LOG("COPY_CODE offs=%i size=%i\n", offs, size);
|
2025-09-20 21:25:07 +00:00
|
|
|
memcpy(executable_memory + offs, bytes, size); bytes += size;
|
|
|
|
|
break;
|
|
|
|
|
|
2025-09-21 21:08:30 +00:00
|
|
|
case PATCH_FUNC:
|
2025-09-20 21:25:07 +00:00
|
|
|
offs = *(uint32_t*)bytes; bytes += 4;
|
|
|
|
|
reloc_type = *(uint32_t*)bytes; bytes += 4;
|
|
|
|
|
value = *(int32_t*)bytes; bytes += 4;
|
2025-10-18 21:10:40 +00:00
|
|
|
LOG("PATCH_FUNC patch_offs=%i reloc_type=%i value=%i\n",
|
2025-09-20 21:25:07 +00:00
|
|
|
offs, reloc_type, value);
|
2025-09-21 21:08:30 +00:00
|
|
|
patch(executable_memory + offs, reloc_type, value);
|
2025-09-20 21:25:07 +00:00
|
|
|
break;
|
|
|
|
|
|
2025-09-21 21:08:30 +00:00
|
|
|
case PATCH_OBJECT:
|
2025-09-20 21:25:07 +00:00
|
|
|
offs = *(uint32_t*)bytes; bytes += 4;
|
|
|
|
|
reloc_type = *(uint32_t*)bytes; bytes += 4;
|
|
|
|
|
value = *(int32_t*)bytes; bytes += 4;
|
2025-10-18 21:10:40 +00:00
|
|
|
LOG("PATCH_OBJECT patch_offs=%i reloc_type=%i value=%i\n",
|
2025-10-09 20:46:06 +00:00
|
|
|
offs, reloc_type, value);
|
2025-09-30 21:11:14 +00:00
|
|
|
patch(executable_memory + offs, reloc_type, value + data_offs);
|
2025-09-20 21:25:07 +00:00
|
|
|
break;
|
2025-10-12 21:21:34 +00:00
|
|
|
|
2025-10-18 21:26:35 +00:00
|
|
|
case PATCH_MATH_POW:
|
|
|
|
|
break;
|
|
|
|
|
|
2025-10-12 21:21:34 +00:00
|
|
|
case ENTRY_POINT:
|
2025-10-18 21:10:40 +00:00
|
|
|
LOG("ENTRY_POINT rel_entr_point=%i\n", rel_entr_point);
|
2025-09-30 21:11:14 +00:00
|
|
|
rel_entr_point = *(uint32_t*)bytes; bytes += 4;
|
2025-10-07 21:24:22 +00:00
|
|
|
entr_point = (entry_point_t)(executable_memory + rel_entr_point);
|
2025-10-04 20:57:45 +00:00
|
|
|
mark_mem_executable(executable_memory, executable_memory_len);
|
2025-10-12 21:21:34 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case RUN_PROG:
|
2025-10-18 21:10:40 +00:00
|
|
|
LOG("RUN_PROG\n");
|
2025-10-01 21:09:49 +00:00
|
|
|
int ret = entr_point();
|
2025-10-18 21:10:40 +00:00
|
|
|
BLOG("Return value: %i\n", ret);
|
2025-09-20 21:25:07 +00:00
|
|
|
break;
|
|
|
|
|
|
2025-10-01 21:09:49 +00:00
|
|
|
case READ_DATA:
|
|
|
|
|
offs = *(uint32_t*)bytes; bytes += 4;
|
|
|
|
|
size = *(uint32_t*)bytes; bytes += 4;
|
2025-10-18 21:10:40 +00:00
|
|
|
BLOG("READ_DATA offs=%i size=%i data=", offs, size);
|
2025-10-01 21:09:49 +00:00
|
|
|
for (uint32_t i = 0; i < size; i++) {
|
|
|
|
|
printf("%02X ", data_memory[offs + i]);
|
|
|
|
|
}
|
|
|
|
|
printf("\n");
|
|
|
|
|
break;
|
2025-10-04 20:57:45 +00:00
|
|
|
|
|
|
|
|
case FREE_MEMORY:
|
|
|
|
|
free_memory();
|
|
|
|
|
break;
|
|
|
|
|
|
2025-10-12 21:22:12 +00:00
|
|
|
case END_COM:
|
2025-10-18 21:10:40 +00:00
|
|
|
LOG("END_COM\n");
|
2025-10-07 20:56:04 +00:00
|
|
|
end_flag = 1;
|
2025-10-04 20:57:45 +00:00
|
|
|
break;
|
2025-09-20 21:25:07 +00:00
|
|
|
|
2025-10-05 21:10:38 +00:00
|
|
|
default:
|
2025-10-18 21:10:40 +00:00
|
|
|
LOG("Unknown command\n");
|
2025-10-07 20:56:04 +00:00
|
|
|
end_flag = -1;
|
2025-09-20 21:25:07 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-10-07 20:56:04 +00:00
|
|
|
return end_flag;
|
2025-09-20 21:25:07 +00:00
|
|
|
}
|