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;
|
uint8_t** devicesMem;
|
||||||
size_t devicesCount;
|
size_t devicesCount;
|
||||||
void** deviceHandles; // device_handle_t** — dynamically loaded devices
|
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;
|
size_t interceptCtxCount;
|
||||||
flatcc_builder_t stream_builder;
|
flatcc_builder_t stream_builder;
|
||||||
} EmulContext;
|
} EmulContext;
|
||||||
|
|||||||
@@ -7,24 +7,31 @@
|
|||||||
|
|
||||||
void closeBaseDevice(device_handle_t* devHandle)
|
void closeBaseDevice(device_handle_t* devHandle)
|
||||||
{
|
{
|
||||||
|
if(devHandle == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(devHandle->ctx != NULL)
|
if(devHandle->ctx != NULL)
|
||||||
{
|
{
|
||||||
if(devHandle->specs != NULL)
|
if(devHandle->specs != NULL && devHandle->lib != NULL)
|
||||||
{
|
{
|
||||||
devHandle->lib->freeSpecs(devHandle->specs);
|
devHandle->lib->freeSpecs(devHandle->specs);
|
||||||
}
|
}
|
||||||
if(devHandle->ctx->deviceMem != NULL)
|
if(devHandle->ctx->deviceMem != NULL && devHandle->lib != NULL)
|
||||||
{
|
{
|
||||||
devHandle->lib->freeDevMem(devHandle->ctx->deviceMem);
|
devHandle->lib->freeDevMem(devHandle->ctx->deviceMem);
|
||||||
}
|
}
|
||||||
free(devHandle->ctx);
|
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)
|
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));
|
device_handle_t* ret = malloc(sizeof(device_handle_t));
|
||||||
if (ret == NULL)
|
if (ret == NULL)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "unable to allocate device handle struct");
|
snprintf(errbuf, 1024, "unable to allocate device handle struct");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +48,7 @@ device_handle_t* openBaseDevice(conf_dev_t* devConf, char* errbuf)
|
|||||||
device_lib_t* devLib = loadDeviceLib(devConf->libPath, intErrbuf);
|
device_lib_t* devLib = loadDeviceLib(devConf->libPath, intErrbuf);
|
||||||
if (devLib == NULL)
|
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);
|
free(ret);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -50,7 +57,7 @@ device_handle_t* openBaseDevice(conf_dev_t* devConf, char* errbuf)
|
|||||||
|
|
||||||
if (devSpecs == NULL)
|
if (devSpecs == NULL)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "device config parse error: %s", intErrbuf);
|
snprintf(errbuf, 1024, "device config parse error: %s", intErrbuf);
|
||||||
dlclose(devLib->_dlhandl);
|
dlclose(devLib->_dlhandl);
|
||||||
free(ret);
|
free(ret);
|
||||||
free(devLib);
|
free(devLib);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ char** appendId(char** prev, const char* cur, char* errbuf)
|
|||||||
prev = malloc(sizeof(char*) * 2);
|
prev = malloc(sizeof(char*) * 2);
|
||||||
if(prev == NULL)
|
if(prev == NULL)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "unable to allocate id");
|
snprintf(errbuf, 1024, "unable to allocate id");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
prev[0] = NULL;
|
prev[0] = NULL;
|
||||||
@@ -29,7 +29,7 @@ char** appendId(char** prev, const char* cur, char* errbuf)
|
|||||||
|
|
||||||
if(new == NULL)
|
if(new == NULL)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "unable to reallocate id");
|
snprintf(errbuf, 1024, "unable to reallocate id");
|
||||||
freeComposeId(prev);
|
freeComposeId(prev);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -40,7 +40,7 @@ char** appendId(char** prev, const char* cur, char* errbuf)
|
|||||||
prev[clockIdLen - 1] = malloc(sizeof(char) * (idLen + 1));
|
prev[clockIdLen - 1] = malloc(sizeof(char) * (idLen + 1));
|
||||||
if(prev[clockIdLen - 1] == NULL)
|
if(prev[clockIdLen - 1] == NULL)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "unable to allocate new id entry");
|
snprintf(errbuf, 1024, "unable to allocate new id entry");
|
||||||
freeComposeId(prev);
|
freeComposeId(prev);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -91,7 +91,7 @@ device_handle_t** openComposeDevice(compose_dev_conf_t* conf, char* errbuf)
|
|||||||
|
|
||||||
if(devHandlers == NULL)
|
if(devHandlers == NULL)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "unable to allocate dev handlers");
|
snprintf(errbuf, 1024, "unable to allocate dev handlers");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
devHandlers[devIdx] = 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);
|
device_handle_t* devHandle = openBaseDevice(devConf, intErrbuf);
|
||||||
if(devHandle == NULL)
|
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++)
|
for(size_t j = 0; j < i; j++)
|
||||||
{
|
{
|
||||||
closeBaseDevice(devHandlers[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)
|
if (dev == NULL)
|
||||||
{
|
{
|
||||||
sprintf(errbuf, "unable to allocate device lib struct");
|
snprintf(errbuf, 1024, "unable to allocate device lib struct");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *handle = dlopen(libpath, RTLD_NOW);
|
void *handle = dlopen(libpath, RTLD_NOW);
|
||||||
|
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
sprintf(errbuf, "unable to open dl handle");
|
snprintf(errbuf, 1024, "unable to open dl handle");
|
||||||
free(dev);
|
free(dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -110,7 +110,7 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
|||||||
|
|
||||||
const char *dlsym_init_error = dlerror();
|
const char *dlsym_init_error = dlerror();
|
||||||
if (dlsym_init_error) {
|
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);
|
dlclose(handle);
|
||||||
free(dev);
|
free(dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -121,7 +121,7 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
|||||||
|
|
||||||
const char *dlsym_maketick_error = dlerror();
|
const char *dlsym_maketick_error = dlerror();
|
||||||
if (dlsym_maketick_error) {
|
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);
|
dlclose(handle);
|
||||||
free(dev);
|
free(dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -133,7 +133,7 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
|||||||
|
|
||||||
const char *_dlib_parseSpecsFromConfig_error = dlerror();
|
const char *_dlib_parseSpecsFromConfig_error = dlerror();
|
||||||
if (_dlib_parseSpecsFromConfig_error) {
|
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);
|
dlclose(handle);
|
||||||
free(dev);
|
free(dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -145,7 +145,7 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
|||||||
|
|
||||||
const char *_dlib_fillSmartReadSpecs_error = dlerror();
|
const char *_dlib_fillSmartReadSpecs_error = dlerror();
|
||||||
if (_dlib_fillSmartReadSpecs_error) {
|
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);
|
dlclose(handle);
|
||||||
free(dev);
|
free(dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -157,7 +157,7 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
|||||||
|
|
||||||
const char *_dlib_fillSmartWriteSpecs_error = dlerror();
|
const char *_dlib_fillSmartWriteSpecs_error = dlerror();
|
||||||
if (_dlib_fillSmartWriteSpecs_error) {
|
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);
|
dlclose(handle);
|
||||||
free(dev);
|
free(dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -168,7 +168,7 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
|||||||
|
|
||||||
const char *dlib_deviceType_error = dlerror();
|
const char *dlib_deviceType_error = dlerror();
|
||||||
if (dlib_deviceType_error) {
|
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);
|
dlclose(handle);
|
||||||
free(dev);
|
free(dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -181,7 +181,7 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
|||||||
|
|
||||||
const char *dlib_freeSpecs_error = dlerror();
|
const char *dlib_freeSpecs_error = dlerror();
|
||||||
if (dlib_freeSpecs_error) {
|
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);
|
dlclose(handle);
|
||||||
free(dev);
|
free(dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -192,7 +192,7 @@ device_lib_t* loadDeviceLib(const char *libpath, char* errbuf)
|
|||||||
|
|
||||||
const char *dlib_freeDevMem_error = dlerror();
|
const char *dlib_freeDevMem_error = dlerror();
|
||||||
if (dlib_freeDevMem_error) {
|
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);
|
dlclose(handle);
|
||||||
free(dev);
|
free(dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -44,7 +44,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <alloca.h>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -263,7 +262,7 @@ void dispatchMemAccessNotifications(EmulContext* emulContext, DeviceSegStreamReg
|
|||||||
// printf("No stream regs\n");
|
// printf("No stream regs\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
StreamReg** dispatchRegs = alloca(sizeof(StreamReg*) * deviceRegs->regCount);
|
StreamReg** dispatchRegs = malloc(sizeof(StreamReg*) * deviceRegs->regCount);
|
||||||
NULL_GUARD(dispatchRegs);
|
NULL_GUARD(dispatchRegs);
|
||||||
size_t dispatchRegsCnt = 0;
|
size_t dispatchRegsCnt = 0;
|
||||||
|
|
||||||
@@ -305,6 +304,7 @@ void dispatchMemAccessNotifications(EmulContext* emulContext, DeviceSegStreamReg
|
|||||||
{
|
{
|
||||||
dispatchStreamSegment(emulContext, dispatchRegs[i], mem);
|
dispatchStreamSegment(emulContext, dispatchRegs[i], mem);
|
||||||
}
|
}
|
||||||
|
free(dispatchRegs);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
|
|||||||
@@ -25,32 +25,32 @@ static conf_dev_t* conf_from_fb(
|
|||||||
char* errbuf)
|
char* errbuf)
|
||||||
{
|
{
|
||||||
conf_dev_t* dc = calloc(1, sizeof(conf_dev_t));
|
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->clockDivider = 1;
|
||||||
dc->clockMultipler = 1;
|
dc->clockMultipler = 1;
|
||||||
|
|
||||||
flatbuffers_string_t lp = hmmmm_config_BaseDeviceConfig_libpath(base);
|
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);
|
dc->libPath = strdup(lp);
|
||||||
|
|
||||||
hmmmm_config_MemSegment_vec_t segs = hmmmm_config_BaseDeviceConfig_mem_segments(base);
|
hmmmm_config_MemSegment_vec_t segs = hmmmm_config_BaseDeviceConfig_mem_segments(base);
|
||||||
size_t seg_n = segs ? hmmmm_config_MemSegment_vec_len(segs) : 0;
|
size_t seg_n = segs ? hmmmm_config_MemSegment_vec_len(segs) : 0;
|
||||||
|
|
||||||
dc->memConf = calloc(1, sizeof(conf_mem_t));
|
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*));
|
dc->memConf->memSegConfs = calloc(seg_n + 1, sizeof(conf_mem_seg_t*));
|
||||||
if (!dc->memConf->memSegConfs) {
|
if (!dc->memConf->memSegConfs) {
|
||||||
free(dc->memConf); free(dc->libPath); free(dc);
|
free(dc->memConf); free(dc->libPath); free(dc);
|
||||||
sprintf(errbuf, "alloc memSegConfs");
|
snprintf(errbuf, 1024, "alloc memSegConfs");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < seg_n; i++) {
|
for (size_t i = 0; i < seg_n; i++) {
|
||||||
hmmmm_config_MemSegment_table_t seg = hmmmm_config_MemSegment_vec_at(segs, 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));
|
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);
|
flatbuffers_string_t sname = hmmmm_config_MemSegment_name(seg);
|
||||||
s->name = strdup(sname ? sname : "");
|
s->name = strdup(sname ? sname : "");
|
||||||
@@ -96,10 +96,10 @@ static int load_devices_recursive(
|
|||||||
hmmmm_config_DeviceEntry_vec_at(entries, i);
|
hmmmm_config_DeviceEntry_vec_at(entries, i);
|
||||||
|
|
||||||
flatbuffers_string_t id = hmmmm_config_DeviceEntry_id(entry);
|
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) {
|
if (st->depth >= MAX_DEPTH) {
|
||||||
sprintf(errbuf, "device tree too deep");
|
snprintf(errbuf, 1024, "device tree too deep");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
st->path_stack[st->depth] = id;
|
st->path_stack[st->depth] = id;
|
||||||
@@ -110,7 +110,7 @@ static int load_devices_recursive(
|
|||||||
|
|
||||||
if (ctype == hmmmm_config_DeviceConfig_BaseDeviceConfig) {
|
if (ctype == hmmmm_config_DeviceConfig_BaseDeviceConfig) {
|
||||||
if (st->count >= MAX_DEVICES) {
|
if (st->count >= MAX_DEVICES) {
|
||||||
sprintf(errbuf, "too many devices");
|
snprintf(errbuf, 1024, "too many devices");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ static int load_devices_recursive(
|
|||||||
st->path_lens[idx] = st->depth;
|
st->path_lens[idx] = st->depth;
|
||||||
st->paths[idx] = calloc(st->depth + 1, sizeof(char*));
|
st->paths[idx] = calloc(st->depth + 1, sizeof(char*));
|
||||||
if (!st->paths[idx]) {
|
if (!st->paths[idx]) {
|
||||||
sprintf(errbuf, "alloc path array");
|
snprintf(errbuf, 1024, "alloc path array");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for (size_t p = 0; p < st->depth; p++) {
|
for (size_t p = 0; p < st->depth; p++) {
|
||||||
@@ -167,7 +167,7 @@ static int load_devices_recursive(
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sprintf(errbuf, "unknown device config type %u", ctype);
|
snprintf(errbuf, 1024, "unknown device config type %u", ctype);
|
||||||
return -1;
|
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)
|
static size_t find_device_by_id(LoadState* st, const char* id)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < st->count; i++) {
|
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)
|
// Match by last path component (the device's own ID)
|
||||||
const char* leaf = st->paths[i][st->path_lens[i] - 1];
|
const char* leaf = st->paths[i][st->path_lens[i] - 1];
|
||||||
if (strcmp(leaf, id) == 0) return i;
|
if (strcmp(leaf, id) == 0) return i;
|
||||||
@@ -233,26 +234,26 @@ static int apply_projections(
|
|||||||
uint32_t shift = hmmmm_config_Projection_shift(proj);
|
uint32_t shift = hmmmm_config_Projection_shift(proj);
|
||||||
|
|
||||||
if (!base_at || !base_seg || !target_at || !target_seg) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t base_idx = find_device_by_id(st, base_at);
|
size_t base_idx = find_device_by_id(st, base_at);
|
||||||
if (base_idx == (size_t)~0) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t target_idx = find_device_by_id(st, target_at);
|
size_t target_idx = find_device_by_id(st, target_at);
|
||||||
if (target_idx == (size_t)~0) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t base_seg_idx = find_seg_by_name(
|
size_t base_seg_idx = find_seg_by_name(
|
||||||
st->handles[base_idx], st->seg_counts[base_idx], base_seg);
|
st->handles[base_idx], st->seg_counts[base_idx], base_seg);
|
||||||
if (base_seg_idx == (size_t)~0) {
|
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);
|
i, base_seg, base_at);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -260,7 +261,7 @@ static int apply_projections(
|
|||||||
size_t target_seg_idx = find_seg_by_name(
|
size_t target_seg_idx = find_seg_by_name(
|
||||||
st->handles[target_idx], st->seg_counts[target_idx], target_seg);
|
st->handles[target_idx], st->seg_counts[target_idx], target_seg);
|
||||||
if (target_seg_idx == (size_t)~0) {
|
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);
|
i, target_seg, target_at);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -324,13 +325,13 @@ static int apply_intercepts(
|
|||||||
*out_ctx_count = 0;
|
*out_ctx_count = 0;
|
||||||
if (icpt_n == 0) { *out_ctxs = NULL; return 0; }
|
if (icpt_n == 0) { *out_ctxs = NULL; return 0; }
|
||||||
if (icpt_n > MAX_INTERCEPTS) {
|
if (icpt_n > MAX_INTERCEPTS) {
|
||||||
sprintf(errbuf, "too many intercepts (%zu)", icpt_n);
|
snprintf(errbuf, 1024, "too many intercepts (%zu)", icpt_n);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate array of intercept contexts (one per intercept)
|
// Allocate array of intercept contexts (one per intercept)
|
||||||
intercept_ctx_t* ctxs = calloc(icpt_n, sizeof(intercept_ctx_t));
|
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++) {
|
for (size_t i = 0; i < icpt_n; i++) {
|
||||||
hmmmm_config_Intercept_table_t icpt =
|
hmmmm_config_Intercept_table_t icpt =
|
||||||
@@ -349,7 +350,7 @@ static int apply_intercepts(
|
|||||||
uint32_t point_addr = hmmmm_config_Intercept_point_addr(icpt);
|
uint32_t point_addr = hmmmm_config_Intercept_point_addr(icpt);
|
||||||
|
|
||||||
if (!base_at || !base_seg || !point_at || !point_seg) {
|
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);
|
free(ctxs);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -357,13 +358,13 @@ static int apply_intercepts(
|
|||||||
// Resolve base device + segment
|
// Resolve base device + segment
|
||||||
size_t base_idx = find_device_by_id(st, base_at);
|
size_t base_idx = find_device_by_id(st, base_at);
|
||||||
if (base_idx == (size_t)~0) {
|
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;
|
free(ctxs); return -1;
|
||||||
}
|
}
|
||||||
size_t base_seg_idx = find_seg_by_name(
|
size_t base_seg_idx = find_seg_by_name(
|
||||||
st->handles[base_idx], st->seg_counts[base_idx], base_seg);
|
st->handles[base_idx], st->seg_counts[base_idx], base_seg);
|
||||||
if (base_seg_idx == (size_t)~0) {
|
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);
|
i, base_seg, base_at);
|
||||||
free(ctxs); return -1;
|
free(ctxs); return -1;
|
||||||
}
|
}
|
||||||
@@ -371,13 +372,13 @@ static int apply_intercepts(
|
|||||||
// Resolve point device + segment
|
// Resolve point device + segment
|
||||||
size_t point_idx = find_device_by_id(st, point_at);
|
size_t point_idx = find_device_by_id(st, point_at);
|
||||||
if (point_idx == (size_t)~0) {
|
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;
|
free(ctxs); return -1;
|
||||||
}
|
}
|
||||||
size_t point_seg_idx = find_seg_by_name(
|
size_t point_seg_idx = find_seg_by_name(
|
||||||
st->handles[point_idx], st->seg_counts[point_idx], point_seg);
|
st->handles[point_idx], st->seg_counts[point_idx], point_seg);
|
||||||
if (point_seg_idx == (size_t)~0) {
|
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);
|
i, point_seg, point_at);
|
||||||
free(ctxs); return -1;
|
free(ctxs); return -1;
|
||||||
}
|
}
|
||||||
@@ -402,34 +403,29 @@ static int apply_intercepts(
|
|||||||
|
|
||||||
uint64_t ident = (uint64_t)(uintptr_t)ctx;
|
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) {
|
if (mode == hmmmm_config_InterceptMode_shadow_replace) {
|
||||||
// Replace: redirect read and/or write
|
|
||||||
if (op == hmmmm_config_InterceptOp_op_read ||
|
if (op == hmmmm_config_InterceptOp_op_read ||
|
||||||
op == hmmmm_config_InterceptOp_op_both) {
|
op == hmmmm_config_InterceptOp_op_both) {
|
||||||
base_mem->smartAddrReadHandlers[base_global].func = intercept_replace_read;
|
base_mem->smartAddrReadHandlers[base_global].func = intercept_replace_read;
|
||||||
|
base_mem->smartAddrReadHandlers[base_global].ident = ident;
|
||||||
}
|
}
|
||||||
if (op == hmmmm_config_InterceptOp_op_write ||
|
if (op == hmmmm_config_InterceptOp_op_write ||
|
||||||
op == hmmmm_config_InterceptOp_op_both) {
|
op == hmmmm_config_InterceptOp_op_both) {
|
||||||
base_mem->smartAddrWriteHandlers[base_global].func = intercept_replace_write;
|
base_mem->smartAddrWriteHandlers[base_global].func = intercept_replace_write;
|
||||||
|
base_mem->smartAddrWriteHandlers[base_global].ident = ident;
|
||||||
}
|
}
|
||||||
} else if (mode == hmmmm_config_InterceptMode_shadow_copy) {
|
} else if (mode == hmmmm_config_InterceptMode_shadow_copy) {
|
||||||
// Copy: only affects writes (read stays at base)
|
|
||||||
if (op == hmmmm_config_InterceptOp_op_write ||
|
if (op == hmmmm_config_InterceptOp_op_write ||
|
||||||
op == hmmmm_config_InterceptOp_op_both) {
|
op == hmmmm_config_InterceptOp_op_both) {
|
||||||
base_mem->smartAddrWriteHandlers[base_global].func = intercept_copy_write;
|
base_mem->smartAddrWriteHandlers[base_global].func = intercept_copy_write;
|
||||||
|
base_mem->smartAddrWriteHandlers[base_global].ident = ident;
|
||||||
}
|
}
|
||||||
} else if (mode == hmmmm_config_InterceptMode_callback) {
|
} else if (mode == hmmmm_config_InterceptMode_callback) {
|
||||||
// Callback mode: not implemented yet — skip with warning
|
// Callback mode: not implemented yet — skip with warning
|
||||||
printf("[CTRL/CONFIG] intercept %zu '%s': callback mode not yet implemented\n",
|
printf("[CTRL/CONFIG] intercept %zu '%s': callback mode not yet implemented\n",
|
||||||
i, name ? name : "(unnamed)");
|
i, name ? name : "(unnamed)");
|
||||||
} else {
|
} else {
|
||||||
sprintf(errbuf, "intercept %zu: unknown mode %d", i, mode);
|
snprintf(errbuf, 1024, "intercept %zu: unknown mode %d", i, mode);
|
||||||
free(ctxs); return -1;
|
free(ctxs); return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,11 +446,8 @@ static void free_old_config(EmulContext* emulContext)
|
|||||||
{
|
{
|
||||||
if (emulContext->devicesCount == 0) return;
|
if (emulContext->devicesCount == 0) return;
|
||||||
|
|
||||||
// Free intercept contexts
|
// Free intercept context array (single contiguous allocation)
|
||||||
if (emulContext->interceptCtxs) {
|
if (emulContext->interceptCtxs) {
|
||||||
for (size_t i = 0; i < emulContext->interceptCtxCount; i++) {
|
|
||||||
free(emulContext->interceptCtxs[i]);
|
|
||||||
}
|
|
||||||
free(emulContext->interceptCtxs);
|
free(emulContext->interceptCtxs);
|
||||||
emulContext->interceptCtxs = NULL;
|
emulContext->interceptCtxs = NULL;
|
||||||
emulContext->interceptCtxCount = 0;
|
emulContext->interceptCtxCount = 0;
|
||||||
@@ -493,7 +486,7 @@ void handleConfigCtrlMessage(
|
|||||||
|
|
||||||
// Must be in STILL state
|
// Must be in STILL state
|
||||||
if (*emulContext->emulState != EMUL_STATE_STILL) {
|
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);
|
printf("[CTRL/CONFIG] error: %s\n", errbuf);
|
||||||
|
|
||||||
size_t msg_len;
|
size_t msg_len;
|
||||||
@@ -506,7 +499,7 @@ void handleConfigCtrlMessage(
|
|||||||
hmmmm_ctrl_config_ctrl_ConfigCtrlMessage_config(msg);
|
hmmmm_ctrl_config_ctrl_ConfigCtrlMessage_config(msg);
|
||||||
|
|
||||||
if (!econf) {
|
if (!econf) {
|
||||||
sprintf(errbuf, "missing EmulationConfig");
|
snprintf(errbuf, 1024, "missing EmulationConfig");
|
||||||
printf("[CTRL/CONFIG] error: %s\n", errbuf);
|
printf("[CTRL/CONFIG] error: %s\n", errbuf);
|
||||||
|
|
||||||
size_t msg_len;
|
size_t msg_len;
|
||||||
@@ -520,7 +513,7 @@ void handleConfigCtrlMessage(
|
|||||||
hmmmm_config_EmulationConfig_root(econf);
|
hmmmm_config_EmulationConfig_root(econf);
|
||||||
|
|
||||||
if (!root) {
|
if (!root) {
|
||||||
sprintf(errbuf, "missing root ComposeDeviceConfig");
|
snprintf(errbuf, 1024, "missing root ComposeDeviceConfig");
|
||||||
printf("[CTRL/CONFIG] error: %s\n", errbuf);
|
printf("[CTRL/CONFIG] error: %s\n", errbuf);
|
||||||
|
|
||||||
size_t msg_len;
|
size_t msg_len;
|
||||||
@@ -591,32 +584,51 @@ void handleConfigCtrlMessage(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store intercept contexts for later cleanup
|
// Store intercept context array for later cleanup (single contiguous allocation)
|
||||||
if (icpt_ctxs) {
|
emulContext->interceptCtxs = icpt_ctxs;
|
||||||
emulContext->interceptCtxs = calloc(1, sizeof(void*));
|
emulContext->interceptCtxCount = icpt_count;
|
||||||
emulContext->interceptCtxs[0] = icpt_ctxs;
|
|
||||||
emulContext->interceptCtxCount = 1;
|
|
||||||
} else {
|
|
||||||
emulContext->interceptCtxs = NULL;
|
|
||||||
emulContext->interceptCtxCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocate new arrays for EmulContext
|
// Allocate new arrays for EmulContext
|
||||||
size_t dc = st.count;
|
size_t dc = st.count;
|
||||||
emulContext->devicesCount = dc;
|
emulContext->devicesCount = dc;
|
||||||
|
|
||||||
emulContext->deviceHandles = calloc(dc, sizeof(void*));
|
emulContext->deviceHandles = calloc(dc, sizeof(void*));
|
||||||
emulContext->devicesMem = calloc(dc, sizeof(uint8_t*));
|
emulContext->devicesMem = calloc(dc, sizeof(uint8_t*));
|
||||||
emulContext->deviceStreamRegs = calloc(dc, sizeof(DeviceSegStreamReg*));
|
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++) {
|
for (size_t i = 0; i < dc; i++) {
|
||||||
emulContext->deviceHandles[i] = st.handles[i];
|
emulContext->deviceHandles[i] = st.handles[i];
|
||||||
emulContext->devicesMem[i] = st.handles[i]->ctx->deviceMem->rawCells;
|
emulContext->devicesMem[i] = st.handles[i]->ctx->deviceMem->rawCells;
|
||||||
|
|
||||||
DeviceSegStreamReg* dsr = calloc(1, sizeof(DeviceSegStreamReg));
|
DeviceSegStreamReg* dsr = calloc(1, sizeof(DeviceSegStreamReg));
|
||||||
|
if (!dsr) { emulContext->deviceStreamRegs[i] = NULL; continue; }
|
||||||
dsr->allocatedSize = 4;
|
dsr->allocatedSize = 4;
|
||||||
dsr->regCount = 0;
|
dsr->regCount = 0;
|
||||||
dsr->regs = calloc(4, sizeof(StreamReg));
|
dsr->regs = calloc(4, sizeof(StreamReg));
|
||||||
|
if (!dsr->regs) { free(dsr); emulContext->deviceStreamRegs[i] = NULL; continue; }
|
||||||
emulContext->deviceStreamRegs[i] = dsr;
|
emulContext->deviceStreamRegs[i] = dsr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user