From cf9b3de8fcb590eed85112e3427b6223f643c90c Mon Sep 17 00:00:00 2001 From: Paul Oliver Date: Thu, 29 Feb 2024 01:50:44 +0100 Subject: Faults replace instructions randomly. --- src/evolver.c | 8 ++++++++ src/instset.c | 12 ++++++------ src/process.c | 46 +++++++++++++++++++++++++++++++++++++--------- 3 files changed, 51 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/evolver.c b/src/evolver.c index ba043a3..6635097 100644 --- a/src/evolver.c +++ b/src/evolver.c @@ -112,6 +112,14 @@ generateRandomNumber(void) return t; } +void +se_randomizeAt(sword addr) +{ + assert(g_isInit); + assert(sm_isValidAt(addr)); + sm_setInstAt(addr, (sbyte)(generateRandomNumber() % SINST_COUNT)); +} + void se_cycle(void) { diff --git a/src/instset.c b/src/instset.c index 1333ffb..e0556b0 100644 --- a/src/instset.c +++ b/src/instset.c @@ -3,13 +3,13 @@ #include "instset.h" sbool -si_isInst(sbyte inst) +si_isInst(sword inst) { return inst < SINST_COUNT; } static sbool -isBetween(sbyte inst, sbyte lo, sbyte hi) +isBetween(sword inst, sword lo, sword hi) { assert(si_isInst(inst)); assert(lo < SINST_COUNT); @@ -27,28 +27,28 @@ isBetween(sbyte inst, sbyte lo, sbyte hi) } sbool -si_isMod(sbyte inst) +si_isMod(sword inst) { assert(si_isInst(inst)); return isBetween(inst, SNOP0, SNOP3); } sbool -si_isKey(sbyte inst) +si_isKey(sword inst) { assert(si_isInst(inst)); return isBetween(inst, SKEYA, SKEYP); } sbool -si_isLock(sbyte inst) +si_isLock(sword inst) { assert(si_isInst(inst)); return isBetween(inst, SLOKA, SLOKP); } sbool -si_keyLockMatch(sbyte key, sbyte lock) +si_keyLockMatch(sword key, sword lock) { assert(si_isKey(key)); assert(si_isInst(lock)); diff --git a/src/process.c b/src/process.c index e3d3c18..faee0df 100644 --- a/src/process.c +++ b/src/process.c @@ -6,6 +6,7 @@ #include "instset.h" #include "memory.h" #include "process.h" +#include "evolver.h" static sbool g_isInit; static sword g_count; @@ -57,14 +58,14 @@ sp_load(FILE *file) void sp_save(FILE *file) { -assert(g_isInit); -assert(file); -fwrite(&g_isInit, sizeof(sbool), 1, file); -fwrite(&g_count, sizeof(sword), 1, file); -fwrite(&g_cap, sizeof(sword), 1, file); -fwrite(&g_first, sizeof(sword), 1, file); -fwrite(&g_last, sizeof(sword), 1, file); -fwrite(g_procs, sizeof(SProc), g_cap, file); + assert(g_isInit); + assert(file); + fwrite(&g_isInit, sizeof(sbool), 1, file); + fwrite(&g_count, sizeof(sword), 1, file); + fwrite(&g_cap, sizeof(sword), 1, file); + fwrite(&g_first, sizeof(sword), 1, file); + fwrite(&g_last, sizeof(sword), 1, file); + fwrite(g_procs, sizeof(SProc), g_cap, file); } sbool @@ -307,6 +308,18 @@ incrementIP(sword pidx) g_procs[pidx].sp = g_procs[pidx].ip; } +static void +onFault(sword pidx) +{ + sword ip; + assert(g_isInit); + assert(pidx < g_cap); + assert(!sp_isFree(pidx)); + ip = sp_getProc(pidx).ip; + assert(sm_isValidAt(ip)); + se_randomizeAt(ip); +} + static sbool seek(sword pidx, sbool forward) { @@ -319,6 +332,7 @@ seek(sword pidx, sbool forward) nextAddr = g_procs[pidx].ip + 1; if (!sm_isValidAt(nextAddr)) { + onFault(pidx); incrementIP(pidx); return SFALSE; } @@ -326,6 +340,7 @@ seek(sword pidx, sbool forward) nextInst = sm_getInstAt(nextAddr); if (!si_isKey(nextInst)) { + onFault(pidx); incrementIP(pidx); return SFALSE; } @@ -520,6 +535,7 @@ alloc(sword pidx, sbool forward) } if (g_procs[pidx].sp != correctAddr) { + onFault(pidx); incrementIP(pidx); return; } @@ -588,6 +604,8 @@ bswap(sword pidx) g_procs[pidx].mb1s = g_procs[pidx].mb2s; g_procs[pidx].mb2a = addrTmp; g_procs[pidx].mb2s = sizeTmp; + } else { + onFault(pidx); } incrementIP(pidx); @@ -602,6 +620,8 @@ bclear(sword pidx) if (g_procs[pidx].mb2s) { freeMemBlock2Of(pidx); + } else { + onFault(pidx); } incrementIP(pidx); @@ -618,6 +638,8 @@ split(sword pidx) create(g_procs[pidx].mb2a, g_procs[pidx].mb2s, pidx, SFALSE); g_procs[pidx].mb2a = 0; g_procs[pidx].mb2s = 0; + } else { + onFault(pidx); } incrementIP(pidx); @@ -632,8 +654,9 @@ r3op(sword pidx, sbyte inst) assert(!sp_isFree(pidx)); getRegAddrList(pidx, regs, 3, SFALSE); - /* ignore when dividing by zero */ + /* fault when dividing by zero */ if ((inst == SDIVN) && (*regs[2] == 0)) { + onFault(pidx); incrementIP(pidx); return; } @@ -755,6 +778,7 @@ load(sword pidx) getRegAddrList(pidx, regs, 2, SFALSE); if (!sm_isValidAt(*regs[0])) { + onFault(pidx); incrementIP(pidx); return; } @@ -801,11 +825,13 @@ write(sword pidx) getRegAddrList(pidx, regs, 2, SFALSE); if (!sm_isValidAt(*regs[0])) { + onFault(pidx); incrementIP(pidx); return; } if (!si_isInst(*regs[1])) { + onFault(pidx); incrementIP(pidx); return; } @@ -817,6 +843,8 @@ write(sword pidx) } else { if (isWriteableBy(pidx, *regs[0])) { sm_setInstAt(*regs[0], *regs[1]); + } else { + onFault(pidx); } incrementIP(pidx); -- cgit v1.2.1