fix: code quality improvements across C codebase
- Replace sprintf with snprintf (1024-byte errbuf) in hmmmm.c, base_device.c, compose_device.c, config.c - Fix WRITE_MEM macro: use smartAddrWriteHandlers for write ident (was incorrectly reading from smartAddrReadHandlers) - Replace alloca with malloc+free in dispatchMemAccessNotifications - Guard closeBaseDevice against NULL lib/partial initialization - Simplify intercept context storage to single contiguous allocation - Add NULL checks after calloc in config handler with proper cleanup - Guard find_device_by_id against zero-length path Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
105
devices/avr_generic/inc/instr.h
Normal file
105
devices/avr_generic/inc/instr.h
Normal file
@@ -0,0 +1,105 @@
|
||||
#ifndef __INSTR_H__
|
||||
#define __INSTR_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "mem.h"
|
||||
|
||||
|
||||
#ifndef OPCODE_WORDSIZE
|
||||
#error OPCODE_WORDSIZE must be provided
|
||||
// #define OPCODE_WORDSIZE 1
|
||||
#endif
|
||||
#if OPCODE_WORDSIZE == 1
|
||||
typedef uint8_t opcode_t;
|
||||
#elif OPCODE_WORDSIZE == 2
|
||||
typedef uint16_t opcode_t;
|
||||
#elif OPCODE_WORDSIZE == 3
|
||||
typedef uint32_t opcode_t;
|
||||
#elif OPCODE_WORDSIZE == 4
|
||||
typedef uint32_t opcode_t;
|
||||
#else
|
||||
#error OPCODE_WORDSIZE must be one of 1,2,3,
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef PC_WORDSIZE
|
||||
#error PC_WORDSIZE must be provided
|
||||
// #define PC_WORDSIZE 1
|
||||
#endif
|
||||
#if PC_WORDSIZE == 1
|
||||
typedef uint8_t prog_counter_t;
|
||||
#elif PC_WORDSIZE == 2
|
||||
typedef uint16_t prog_counter_t;
|
||||
#elif PC_WORDSIZE == 3
|
||||
typedef uint32_t prog_counter_t;
|
||||
#elif PC_WORDSIZE == 4
|
||||
typedef uint32_t prog_counter_t;
|
||||
#else
|
||||
#error PC_WORDSIZE must be one of 1,2,3,4
|
||||
#endif
|
||||
|
||||
typedef uint8_t (*instr_h_func)(prog_counter_t*, device_mem_t*);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
instr_h_func h;
|
||||
opcode_t base;
|
||||
opcode_t argsMask;
|
||||
uint8_t opcodeLen;
|
||||
|
||||
} instruction_metadata_t;
|
||||
|
||||
instr_h_func* genInstrArray(char* errbuf);
|
||||
void setOpcodeSizes(uint8_t* opcodeSizes);
|
||||
opcode_t extractOpcode(device_mem_t* devMem, prog_counter_t programCounter);
|
||||
|
||||
|
||||
|
||||
|
||||
#define AVRe 1
|
||||
#define AVRxm 2
|
||||
#define AVRxt 3
|
||||
#define AVRrc 4
|
||||
|
||||
#ifndef ARCH
|
||||
#define ARCH AVRe
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define READ_MEM(__tgt, __mem, __segno, __addr, __cell_t) \
|
||||
{\
|
||||
uint64_t __globalAddr = __mem->memsegShifts[__segno] + __addr; \
|
||||
if (__mem->smartAddrReadHandlers[__globalAddr].func != NULL) \
|
||||
{ \
|
||||
__tgt = *(__cell_t*)__mem->smartAddrReadHandlers[__globalAddr].func(__mem->smartAddrReadHandlers[__globalAddr].ident, __addr, __mem->rawCells + __mem->memsegShifts[__segno]); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
__tgt = ((__cell_t*)__mem->cells[__segno])[__addr]; \
|
||||
} \
|
||||
__mem->memreadCellAddrs[__mem->memreadLen] = __globalAddr; \
|
||||
__mem->memreadLen += 1; \
|
||||
}
|
||||
|
||||
#define WRITE_MEM(__mem, __segno, __addr, __cell_t, __val) \
|
||||
{ \
|
||||
uint64_t __globalAddr = __mem->memsegShifts[__segno] + __addr; \
|
||||
if (__mem->smartAddrWriteHandlers[__globalAddr].func != NULL) \
|
||||
{ \
|
||||
__cell_t __dat = (__cell_t)(__val); \
|
||||
__mem->smartAddrWriteHandlers[__globalAddr].func(__mem->smartAddrWriteHandlers[__globalAddr].ident, __addr, __mem->rawCells + __mem->memsegShifts[__segno], (void*)&__dat); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
((__cell_t*)__mem->cells[__segno])[__addr] = (__cell_t)(__val); \
|
||||
} \
|
||||
__mem->memwriteCellAddrs[__mem->memwriteLen] = __globalAddr; \
|
||||
__mem->memwriteLen += 1; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // ifndef __INSTR_H__
|
||||
@@ -32,7 +32,7 @@ typedef struct {
|
||||
uint8_t** devicesMem;
|
||||
size_t devicesCount;
|
||||
void** deviceHandles; // device_handle_t** — dynamically loaded devices
|
||||
void** interceptCtxs; // intercept_ctx_t** — heap-allocated intercept contexts
|
||||
void* interceptCtxs; // contiguous intercept_ctx_t array (freed as single block)
|
||||
size_t interceptCtxCount;
|
||||
flatcc_builder_t stream_builder;
|
||||
} EmulContext;
|
||||
|
||||
@@ -7,24 +7,31 @@
|
||||
|
||||
void closeBaseDevice(device_handle_t* devHandle)
|
||||
{
|
||||
if(devHandle == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(devHandle->ctx != NULL)
|
||||
{
|
||||
if(devHandle->specs != NULL)
|
||||
if(devHandle->specs != NULL && devHandle->lib != NULL)
|
||||
{
|
||||
devHandle->lib->freeSpecs(devHandle->specs);
|
||||
}
|
||||
if(devHandle->ctx->deviceMem != NULL)
|
||||
if(devHandle->ctx->deviceMem != NULL && devHandle->lib != NULL)
|
||||
{
|
||||
devHandle->lib->freeDevMem(devHandle->ctx->deviceMem);
|
||||
}
|
||||
free(devHandle->ctx);
|
||||
}
|
||||
if(devHandle->lib->extendedHandlers != NULL)
|
||||
if(devHandle->lib != NULL)
|
||||
{
|
||||
free(devHandle->lib->extendedHandlers);
|
||||
if(devHandle->lib->extendedHandlers != NULL)
|
||||
{
|
||||
free(devHandle->lib->extendedHandlers);
|
||||
}
|
||||
dlclose(devHandle->lib->_dlhandl);
|
||||
free(devHandle->lib);
|
||||
}
|
||||
dlclose(devHandle->lib->_dlhandl);
|
||||
free(devHandle->lib);
|
||||
}
|
||||
|
||||
device_handle_t* openBaseDevice(conf_dev_t* devConf, char* errbuf)
|
||||
@@ -32,7 +39,7 @@ device_handle_t* openBaseDevice(conf_dev_t* devConf, char* errbuf)
|
||||
device_handle_t* ret = malloc(sizeof(device_handle_t));
|
||||
if (ret == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to allocate device handle struct");
|
||||
snprintf(errbuf, 1024, "unable to allocate device handle struct");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -41,7 +48,7 @@ device_handle_t* openBaseDevice(conf_dev_t* devConf, char* errbuf)
|
||||
device_lib_t* devLib = loadDeviceLib(devConf->libPath, intErrbuf);
|
||||
if (devLib == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to load device library %s: %s", devConf->libPath, intErrbuf);
|
||||
snprintf(errbuf, 1024, "unable to load device library %s: %s", devConf->libPath, intErrbuf);
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
@@ -50,7 +57,7 @@ device_handle_t* openBaseDevice(conf_dev_t* devConf, char* errbuf)
|
||||
|
||||
if (devSpecs == NULL)
|
||||
{
|
||||
sprintf(errbuf, "device config parse error: %s", intErrbuf);
|
||||
snprintf(errbuf, 1024, "device config parse error: %s", intErrbuf);
|
||||
dlclose(devLib->_dlhandl);
|
||||
free(ret);
|
||||
free(devLib);
|
||||
|
||||
@@ -13,7 +13,7 @@ char** appendId(char** prev, const char* cur, char* errbuf)
|
||||
prev = malloc(sizeof(char*) * 2);
|
||||
if(prev == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to allocate id");
|
||||
snprintf(errbuf, 1024, "unable to allocate id");
|
||||
return NULL;
|
||||
}
|
||||
prev[0] = NULL;
|
||||
@@ -29,7 +29,7 @@ char** appendId(char** prev, const char* cur, char* errbuf)
|
||||
|
||||
if(new == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to reallocate id");
|
||||
snprintf(errbuf, 1024, "unable to reallocate id");
|
||||
freeComposeId(prev);
|
||||
return NULL;
|
||||
}
|
||||
@@ -40,7 +40,7 @@ char** appendId(char** prev, const char* cur, char* errbuf)
|
||||
prev[clockIdLen - 1] = malloc(sizeof(char) * (idLen + 1));
|
||||
if(prev[clockIdLen - 1] == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to allocate new id entry");
|
||||
snprintf(errbuf, 1024, "unable to allocate new id entry");
|
||||
freeComposeId(prev);
|
||||
return NULL;
|
||||
}
|
||||
@@ -91,7 +91,7 @@ device_handle_t** openComposeDevice(compose_dev_conf_t* conf, char* errbuf)
|
||||
|
||||
if(devHandlers == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to allocate dev handlers");
|
||||
snprintf(errbuf, 1024, "unable to allocate dev handlers");
|
||||
return NULL;
|
||||
}
|
||||
devHandlers[devIdx] = NULL;
|
||||
@@ -104,7 +104,7 @@ device_handle_t** openComposeDevice(compose_dev_conf_t* conf, char* errbuf)
|
||||
device_handle_t* devHandle = openBaseDevice(devConf, intErrbuf);
|
||||
if(devHandle == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to open base device %s: %s", devConf->id[0], intErrbuf);
|
||||
snprintf(errbuf, 1024, "unable to open base device %s: %s", devConf->id[0], intErrbuf);
|
||||
for(size_t j = 0; j < i; j++)
|
||||
{
|
||||
closeBaseDevice(devHandlers[j]);
|
||||
|
||||
20
src/hmmmm.c
20
src/hmmmm.c
@@ -92,14 +92,14 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
||||
|
||||
if (dev == NULL)
|
||||
{
|
||||
sprintf(errbuf, "unable to allocate device lib struct");
|
||||
snprintf(errbuf, 1024, "unable to allocate device lib struct");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *handle = dlopen(libpath, RTLD_NOW);
|
||||
|
||||
if (!handle) {
|
||||
sprintf(errbuf, "unable to open dl handle");
|
||||
snprintf(errbuf, 1024, "unable to open dl handle");
|
||||
free(dev);
|
||||
return NULL;
|
||||
}
|
||||
@@ -110,7 +110,7 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
||||
|
||||
const char *dlsym_init_error = dlerror();
|
||||
if (dlsym_init_error) {
|
||||
sprintf(errbuf, "unable to find init symbol: %s", dlsym_init_error);
|
||||
snprintf(errbuf, 1024, "unable to find init symbol: %s", dlsym_init_error);
|
||||
dlclose(handle);
|
||||
free(dev);
|
||||
return NULL;
|
||||
@@ -121,7 +121,7 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
||||
|
||||
const char *dlsym_maketick_error = dlerror();
|
||||
if (dlsym_maketick_error) {
|
||||
sprintf(errbuf, "unable to find makeDeviceTick symbol: %s", dlsym_maketick_error);
|
||||
snprintf(errbuf, 1024, "unable to find makeDeviceTick symbol: %s", dlsym_maketick_error);
|
||||
dlclose(handle);
|
||||
free(dev);
|
||||
return NULL;
|
||||
@@ -133,7 +133,7 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
||||
|
||||
const char *_dlib_parseSpecsFromConfig_error = dlerror();
|
||||
if (_dlib_parseSpecsFromConfig_error) {
|
||||
sprintf(errbuf, "unable to find parseSpecsFromConfig symbol: %s", _dlib_parseSpecsFromConfig_error);
|
||||
snprintf(errbuf, 1024, "unable to find parseSpecsFromConfig symbol: %s", _dlib_parseSpecsFromConfig_error);
|
||||
dlclose(handle);
|
||||
free(dev);
|
||||
return NULL;
|
||||
@@ -145,7 +145,7 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
||||
|
||||
const char *_dlib_fillSmartReadSpecs_error = dlerror();
|
||||
if (_dlib_fillSmartReadSpecs_error) {
|
||||
sprintf(errbuf, "unable to find fillSmartReadSpecs symbol: %s", _dlib_fillSmartReadSpecs_error);
|
||||
snprintf(errbuf, 1024, "unable to find fillSmartReadSpecs symbol: %s", _dlib_fillSmartReadSpecs_error);
|
||||
dlclose(handle);
|
||||
free(dev);
|
||||
return NULL;
|
||||
@@ -157,7 +157,7 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
||||
|
||||
const char *_dlib_fillSmartWriteSpecs_error = dlerror();
|
||||
if (_dlib_fillSmartWriteSpecs_error) {
|
||||
sprintf(errbuf, "unable to find fillSmartWriteSpecs symbol: %s", _dlib_fillSmartWriteSpecs_error);
|
||||
snprintf(errbuf, 1024, "unable to find fillSmartWriteSpecs symbol: %s", _dlib_fillSmartWriteSpecs_error);
|
||||
dlclose(handle);
|
||||
free(dev);
|
||||
return NULL;
|
||||
@@ -168,7 +168,7 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
||||
|
||||
const char *dlib_deviceType_error = dlerror();
|
||||
if (dlib_deviceType_error) {
|
||||
sprintf(errbuf, "unable to find pubDeviceType symbol: %s", dlib_deviceType_error);
|
||||
snprintf(errbuf, 1024, "unable to find pubDeviceType symbol: %s", dlib_deviceType_error);
|
||||
dlclose(handle);
|
||||
free(dev);
|
||||
return NULL;
|
||||
@@ -181,7 +181,7 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
||||
|
||||
const char *dlib_freeSpecs_error = dlerror();
|
||||
if (dlib_freeSpecs_error) {
|
||||
sprintf(errbuf, "unable to find freeSpecs symbol: %s", dlib_freeSpecs_error);
|
||||
snprintf(errbuf, 1024, "unable to find freeSpecs symbol: %s", dlib_freeSpecs_error);
|
||||
dlclose(handle);
|
||||
free(dev);
|
||||
return NULL;
|
||||
@@ -192,7 +192,7 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
||||
|
||||
const char *dlib_freeDevMem_error = dlerror();
|
||||
if (dlib_freeDevMem_error) {
|
||||
sprintf(errbuf, "unable to find freeDevMem symbol: %s", dlib_freeDevMem_error);
|
||||
snprintf(errbuf, 1024, "unable to find freeDevMem symbol: %s", dlib_freeDevMem_error);
|
||||
dlclose(handle);
|
||||
free(dev);
|
||||
return NULL;
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <alloca.h>
|
||||
|
||||
|
||||
|
||||
@@ -263,7 +262,7 @@ void dispatchMemAccessNotifications(EmulContext* emulContext, DeviceSegStreamReg
|
||||
// printf("No stream regs\n");
|
||||
return;
|
||||
}
|
||||
StreamReg** dispatchRegs = alloca(sizeof(StreamReg*) * deviceRegs->regCount);
|
||||
StreamReg** dispatchRegs = malloc(sizeof(StreamReg*) * deviceRegs->regCount);
|
||||
NULL_GUARD(dispatchRegs);
|
||||
size_t dispatchRegsCnt = 0;
|
||||
|
||||
@@ -305,6 +304,7 @@ void dispatchMemAccessNotifications(EmulContext* emulContext, DeviceSegStreamReg
|
||||
{
|
||||
dispatchStreamSegment(emulContext, dispatchRegs[i], mem);
|
||||
}
|
||||
free(dispatchRegs);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
|
||||
@@ -25,32 +25,32 @@ static conf_dev_t* conf_from_fb(
|
||||
char* errbuf)
|
||||
{
|
||||
conf_dev_t* dc = calloc(1, sizeof(conf_dev_t));
|
||||
if (!dc) { sprintf(errbuf, "alloc conf_dev_t"); return NULL; }
|
||||
if (!dc) { snprintf(errbuf, 1024, "alloc conf_dev_t"); return NULL; }
|
||||
|
||||
dc->clockDivider = 1;
|
||||
dc->clockMultipler = 1;
|
||||
|
||||
flatbuffers_string_t lp = hmmmm_config_BaseDeviceConfig_libpath(base);
|
||||
if (!lp) { sprintf(errbuf, "missing libpath"); free(dc); return NULL; }
|
||||
if (!lp) { snprintf(errbuf, 1024, "missing libpath"); free(dc); return NULL; }
|
||||
dc->libPath = strdup(lp);
|
||||
|
||||
hmmmm_config_MemSegment_vec_t segs = hmmmm_config_BaseDeviceConfig_mem_segments(base);
|
||||
size_t seg_n = segs ? hmmmm_config_MemSegment_vec_len(segs) : 0;
|
||||
|
||||
dc->memConf = calloc(1, sizeof(conf_mem_t));
|
||||
if (!dc->memConf) { free(dc->libPath); free(dc); sprintf(errbuf, "alloc memConf"); return NULL; }
|
||||
if (!dc->memConf) { free(dc->libPath); free(dc); snprintf(errbuf, 1024, "alloc memConf"); return NULL; }
|
||||
|
||||
dc->memConf->memSegConfs = calloc(seg_n + 1, sizeof(conf_mem_seg_t*));
|
||||
if (!dc->memConf->memSegConfs) {
|
||||
free(dc->memConf); free(dc->libPath); free(dc);
|
||||
sprintf(errbuf, "alloc memSegConfs");
|
||||
snprintf(errbuf, 1024, "alloc memSegConfs");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < seg_n; i++) {
|
||||
hmmmm_config_MemSegment_table_t seg = hmmmm_config_MemSegment_vec_at(segs, i);
|
||||
conf_mem_seg_t* s = calloc(1, sizeof(conf_mem_seg_t));
|
||||
if (!s) { sprintf(errbuf, "alloc seg %zu", i); goto fail; }
|
||||
if (!s) { snprintf(errbuf, 1024, "alloc seg %zu", i); goto fail; }
|
||||
|
||||
flatbuffers_string_t sname = hmmmm_config_MemSegment_name(seg);
|
||||
s->name = strdup(sname ? sname : "");
|
||||
@@ -96,10 +96,10 @@ static int load_devices_recursive(
|
||||
hmmmm_config_DeviceEntry_vec_at(entries, i);
|
||||
|
||||
flatbuffers_string_t id = hmmmm_config_DeviceEntry_id(entry);
|
||||
if (!id) { sprintf(errbuf, "device entry missing id"); return -1; }
|
||||
if (!id) { snprintf(errbuf, 1024, "device entry missing id"); return -1; }
|
||||
|
||||
if (st->depth >= MAX_DEPTH) {
|
||||
sprintf(errbuf, "device tree too deep");
|
||||
snprintf(errbuf, 1024, "device tree too deep");
|
||||
return -1;
|
||||
}
|
||||
st->path_stack[st->depth] = id;
|
||||
@@ -110,7 +110,7 @@ static int load_devices_recursive(
|
||||
|
||||
if (ctype == hmmmm_config_DeviceConfig_BaseDeviceConfig) {
|
||||
if (st->count >= MAX_DEVICES) {
|
||||
sprintf(errbuf, "too many devices");
|
||||
snprintf(errbuf, 1024, "too many devices");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ static int load_devices_recursive(
|
||||
st->path_lens[idx] = st->depth;
|
||||
st->paths[idx] = calloc(st->depth + 1, sizeof(char*));
|
||||
if (!st->paths[idx]) {
|
||||
sprintf(errbuf, "alloc path array");
|
||||
snprintf(errbuf, 1024, "alloc path array");
|
||||
return -1;
|
||||
}
|
||||
for (size_t p = 0; p < st->depth; p++) {
|
||||
@@ -167,7 +167,7 @@ static int load_devices_recursive(
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
sprintf(errbuf, "unknown device config type %u", ctype);
|
||||
snprintf(errbuf, 1024, "unknown device config type %u", ctype);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -194,6 +194,7 @@ static void free_load_state_paths(LoadState* st)
|
||||
static size_t find_device_by_id(LoadState* st, const char* id)
|
||||
{
|
||||
for (size_t i = 0; i < st->count; i++) {
|
||||
if (st->path_lens[i] == 0) continue;
|
||||
// Match by last path component (the device's own ID)
|
||||
const char* leaf = st->paths[i][st->path_lens[i] - 1];
|
||||
if (strcmp(leaf, id) == 0) return i;
|
||||
@@ -233,26 +234,26 @@ static int apply_projections(
|
||||
uint32_t shift = hmmmm_config_Projection_shift(proj);
|
||||
|
||||
if (!base_at || !base_seg || !target_at || !target_seg) {
|
||||
sprintf(errbuf, "projection %zu: missing field", i);
|
||||
snprintf(errbuf, 1024, "projection %zu: missing field", i);
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t base_idx = find_device_by_id(st, base_at);
|
||||
if (base_idx == (size_t)~0) {
|
||||
sprintf(errbuf, "projection %zu: base device '%s' not found", i, base_at);
|
||||
snprintf(errbuf, 1024, "projection %zu: base device '%s' not found", i, base_at);
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t target_idx = find_device_by_id(st, target_at);
|
||||
if (target_idx == (size_t)~0) {
|
||||
sprintf(errbuf, "projection %zu: target device '%s' not found", i, target_at);
|
||||
snprintf(errbuf, 1024, "projection %zu: target device '%s' not found", i, target_at);
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t base_seg_idx = find_seg_by_name(
|
||||
st->handles[base_idx], st->seg_counts[base_idx], base_seg);
|
||||
if (base_seg_idx == (size_t)~0) {
|
||||
sprintf(errbuf, "projection %zu: base segment '%s' not found in '%s'",
|
||||
snprintf(errbuf, 1024, "projection %zu: base segment '%s' not found in '%s'",
|
||||
i, base_seg, base_at);
|
||||
return -1;
|
||||
}
|
||||
@@ -260,7 +261,7 @@ static int apply_projections(
|
||||
size_t target_seg_idx = find_seg_by_name(
|
||||
st->handles[target_idx], st->seg_counts[target_idx], target_seg);
|
||||
if (target_seg_idx == (size_t)~0) {
|
||||
sprintf(errbuf, "projection %zu: target segment '%s' not found in '%s'",
|
||||
snprintf(errbuf, 1024, "projection %zu: target segment '%s' not found in '%s'",
|
||||
i, target_seg, target_at);
|
||||
return -1;
|
||||
}
|
||||
@@ -324,13 +325,13 @@ static int apply_intercepts(
|
||||
*out_ctx_count = 0;
|
||||
if (icpt_n == 0) { *out_ctxs = NULL; return 0; }
|
||||
if (icpt_n > MAX_INTERCEPTS) {
|
||||
sprintf(errbuf, "too many intercepts (%zu)", icpt_n);
|
||||
snprintf(errbuf, 1024, "too many intercepts (%zu)", icpt_n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Allocate array of intercept contexts (one per intercept)
|
||||
intercept_ctx_t* ctxs = calloc(icpt_n, sizeof(intercept_ctx_t));
|
||||
if (!ctxs) { sprintf(errbuf, "alloc intercept contexts"); return -1; }
|
||||
if (!ctxs) { snprintf(errbuf, 1024, "alloc intercept contexts"); return -1; }
|
||||
|
||||
for (size_t i = 0; i < icpt_n; i++) {
|
||||
hmmmm_config_Intercept_table_t icpt =
|
||||
@@ -349,7 +350,7 @@ static int apply_intercepts(
|
||||
uint32_t point_addr = hmmmm_config_Intercept_point_addr(icpt);
|
||||
|
||||
if (!base_at || !base_seg || !point_at || !point_seg) {
|
||||
sprintf(errbuf, "intercept %zu: missing field", i);
|
||||
snprintf(errbuf, 1024, "intercept %zu: missing field", i);
|
||||
free(ctxs);
|
||||
return -1;
|
||||
}
|
||||
@@ -357,13 +358,13 @@ static int apply_intercepts(
|
||||
// Resolve base device + segment
|
||||
size_t base_idx = find_device_by_id(st, base_at);
|
||||
if (base_idx == (size_t)~0) {
|
||||
sprintf(errbuf, "intercept %zu: base device '%s' not found", i, base_at);
|
||||
snprintf(errbuf, 1024, "intercept %zu: base device '%s' not found", i, base_at);
|
||||
free(ctxs); return -1;
|
||||
}
|
||||
size_t base_seg_idx = find_seg_by_name(
|
||||
st->handles[base_idx], st->seg_counts[base_idx], base_seg);
|
||||
if (base_seg_idx == (size_t)~0) {
|
||||
sprintf(errbuf, "intercept %zu: base segment '%s' not found in '%s'",
|
||||
snprintf(errbuf, 1024, "intercept %zu: base segment '%s' not found in '%s'",
|
||||
i, base_seg, base_at);
|
||||
free(ctxs); return -1;
|
||||
}
|
||||
@@ -371,13 +372,13 @@ static int apply_intercepts(
|
||||
// Resolve point device + segment
|
||||
size_t point_idx = find_device_by_id(st, point_at);
|
||||
if (point_idx == (size_t)~0) {
|
||||
sprintf(errbuf, "intercept %zu: point device '%s' not found", i, point_at);
|
||||
snprintf(errbuf, 1024, "intercept %zu: point device '%s' not found", i, point_at);
|
||||
free(ctxs); return -1;
|
||||
}
|
||||
size_t point_seg_idx = find_seg_by_name(
|
||||
st->handles[point_idx], st->seg_counts[point_idx], point_seg);
|
||||
if (point_seg_idx == (size_t)~0) {
|
||||
sprintf(errbuf, "intercept %zu: point segment '%s' not found in '%s'",
|
||||
snprintf(errbuf, 1024, "intercept %zu: point segment '%s' not found in '%s'",
|
||||
i, point_seg, point_at);
|
||||
free(ctxs); return -1;
|
||||
}
|
||||
@@ -402,34 +403,29 @@ static int apply_intercepts(
|
||||
|
||||
uint64_t ident = (uint64_t)(uintptr_t)ctx;
|
||||
|
||||
// NOTE: WRITE_MEM macro reads ident from smartAddrReadHandlers, not
|
||||
// smartAddrWriteHandlers. Always set ident on both arrays so that
|
||||
// write handlers receive the correct context pointer.
|
||||
base_mem->smartAddrReadHandlers[base_global].ident = ident;
|
||||
base_mem->smartAddrWriteHandlers[base_global].ident = ident;
|
||||
|
||||
if (mode == hmmmm_config_InterceptMode_shadow_replace) {
|
||||
// Replace: redirect read and/or write
|
||||
if (op == hmmmm_config_InterceptOp_op_read ||
|
||||
op == hmmmm_config_InterceptOp_op_both) {
|
||||
base_mem->smartAddrReadHandlers[base_global].func = intercept_replace_read;
|
||||
base_mem->smartAddrReadHandlers[base_global].ident = ident;
|
||||
}
|
||||
if (op == hmmmm_config_InterceptOp_op_write ||
|
||||
op == hmmmm_config_InterceptOp_op_both) {
|
||||
base_mem->smartAddrWriteHandlers[base_global].func = intercept_replace_write;
|
||||
base_mem->smartAddrWriteHandlers[base_global].ident = ident;
|
||||
}
|
||||
} else if (mode == hmmmm_config_InterceptMode_shadow_copy) {
|
||||
// Copy: only affects writes (read stays at base)
|
||||
if (op == hmmmm_config_InterceptOp_op_write ||
|
||||
op == hmmmm_config_InterceptOp_op_both) {
|
||||
base_mem->smartAddrWriteHandlers[base_global].func = intercept_copy_write;
|
||||
base_mem->smartAddrWriteHandlers[base_global].ident = ident;
|
||||
}
|
||||
} else if (mode == hmmmm_config_InterceptMode_callback) {
|
||||
// Callback mode: not implemented yet — skip with warning
|
||||
printf("[CTRL/CONFIG] intercept %zu '%s': callback mode not yet implemented\n",
|
||||
i, name ? name : "(unnamed)");
|
||||
} else {
|
||||
sprintf(errbuf, "intercept %zu: unknown mode %d", i, mode);
|
||||
snprintf(errbuf, 1024, "intercept %zu: unknown mode %d", i, mode);
|
||||
free(ctxs); return -1;
|
||||
}
|
||||
|
||||
@@ -450,11 +446,8 @@ static void free_old_config(EmulContext* emulContext)
|
||||
{
|
||||
if (emulContext->devicesCount == 0) return;
|
||||
|
||||
// Free intercept contexts
|
||||
// Free intercept context array (single contiguous allocation)
|
||||
if (emulContext->interceptCtxs) {
|
||||
for (size_t i = 0; i < emulContext->interceptCtxCount; i++) {
|
||||
free(emulContext->interceptCtxs[i]);
|
||||
}
|
||||
free(emulContext->interceptCtxs);
|
||||
emulContext->interceptCtxs = NULL;
|
||||
emulContext->interceptCtxCount = 0;
|
||||
@@ -493,7 +486,7 @@ void handleConfigCtrlMessage(
|
||||
|
||||
// Must be in STILL state
|
||||
if (*emulContext->emulState != EMUL_STATE_STILL) {
|
||||
sprintf(errbuf, "config load requires STILL state");
|
||||
snprintf(errbuf, 1024, "config load requires STILL state");
|
||||
printf("[CTRL/CONFIG] error: %s\n", errbuf);
|
||||
|
||||
size_t msg_len;
|
||||
@@ -506,7 +499,7 @@ void handleConfigCtrlMessage(
|
||||
hmmmm_ctrl_config_ctrl_ConfigCtrlMessage_config(msg);
|
||||
|
||||
if (!econf) {
|
||||
sprintf(errbuf, "missing EmulationConfig");
|
||||
snprintf(errbuf, 1024, "missing EmulationConfig");
|
||||
printf("[CTRL/CONFIG] error: %s\n", errbuf);
|
||||
|
||||
size_t msg_len;
|
||||
@@ -520,7 +513,7 @@ void handleConfigCtrlMessage(
|
||||
hmmmm_config_EmulationConfig_root(econf);
|
||||
|
||||
if (!root) {
|
||||
sprintf(errbuf, "missing root ComposeDeviceConfig");
|
||||
snprintf(errbuf, 1024, "missing root ComposeDeviceConfig");
|
||||
printf("[CTRL/CONFIG] error: %s\n", errbuf);
|
||||
|
||||
size_t msg_len;
|
||||
@@ -591,32 +584,51 @@ void handleConfigCtrlMessage(
|
||||
return;
|
||||
}
|
||||
|
||||
// Store intercept contexts for later cleanup
|
||||
if (icpt_ctxs) {
|
||||
emulContext->interceptCtxs = calloc(1, sizeof(void*));
|
||||
emulContext->interceptCtxs[0] = icpt_ctxs;
|
||||
emulContext->interceptCtxCount = 1;
|
||||
} else {
|
||||
emulContext->interceptCtxs = NULL;
|
||||
emulContext->interceptCtxCount = 0;
|
||||
}
|
||||
// Store intercept context array for later cleanup (single contiguous allocation)
|
||||
emulContext->interceptCtxs = icpt_ctxs;
|
||||
emulContext->interceptCtxCount = icpt_count;
|
||||
|
||||
// Allocate new arrays for EmulContext
|
||||
size_t dc = st.count;
|
||||
emulContext->devicesCount = dc;
|
||||
|
||||
emulContext->deviceHandles = calloc(dc, sizeof(void*));
|
||||
emulContext->devicesMem = calloc(dc, sizeof(uint8_t*));
|
||||
emulContext->deviceHandles = calloc(dc, sizeof(void*));
|
||||
emulContext->devicesMem = calloc(dc, sizeof(uint8_t*));
|
||||
emulContext->deviceStreamRegs = calloc(dc, sizeof(DeviceSegStreamReg*));
|
||||
|
||||
if (!emulContext->deviceHandles || !emulContext->devicesMem ||
|
||||
!emulContext->deviceStreamRegs) {
|
||||
free(emulContext->deviceHandles);
|
||||
free(emulContext->devicesMem);
|
||||
free(emulContext->deviceStreamRegs);
|
||||
emulContext->deviceHandles = NULL;
|
||||
emulContext->devicesMem = NULL;
|
||||
emulContext->deviceStreamRegs = NULL;
|
||||
emulContext->devicesCount = 0;
|
||||
|
||||
for (size_t i = 0; i < st.count; i++) {
|
||||
closeBaseDevice(st.handles[i]);
|
||||
free(st.handles[i]);
|
||||
}
|
||||
free_load_state_paths(&st);
|
||||
|
||||
snprintf(errbuf, sizeof(errbuf), "failed to allocate device arrays");
|
||||
size_t msg_len;
|
||||
uint8_t* out = fb_build_config_error(nonce, errbuf, &msg_len);
|
||||
dispatchOutgoingMessage(emulContext->outBufs, ctx->clientId, out, msg_len);
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < dc; i++) {
|
||||
emulContext->deviceHandles[i] = st.handles[i];
|
||||
emulContext->devicesMem[i] = st.handles[i]->ctx->deviceMem->rawCells;
|
||||
|
||||
DeviceSegStreamReg* dsr = calloc(1, sizeof(DeviceSegStreamReg));
|
||||
if (!dsr) { emulContext->deviceStreamRegs[i] = NULL; continue; }
|
||||
dsr->allocatedSize = 4;
|
||||
dsr->regCount = 0;
|
||||
dsr->regs = calloc(4, sizeof(StreamReg));
|
||||
if (!dsr->regs) { free(dsr); emulContext->deviceStreamRegs[i] = NULL; continue; }
|
||||
emulContext->deviceStreamRegs[i] = dsr;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user