From ebb049fb4b4d1b2cb6a6f907783791f3949b9dc3 Mon Sep 17 00:00:00 2001 From: heavenlydev Date: Fri, 7 Aug 2026 11:00:06 +0200 Subject: [PATCH] Fix correctness bugs: null-safe symbol resolution, register-buffer bounds, memory-range calculation Three pre-existing bugs in the fault-injection flow, fixed independently of any RISC-V feature work: 1. intercept.c: getSymbolValue() and the serviceHandler variable-trace paths dereferenced a NULL symbol (vmirtGetSymbolAddr/Size/Name) when the traced symbol did not exist, aborting the simulator. Guard every pointer and only read memory when the symbol is found (processor first, SMP-parent fallback). 2. commonStructsAndEnumerators.h + faultInjector.c: possibleRegisters[50] is too small for the ARMv8 list (int+SIMD+END = 66 entries) and overflows in the strcpy copy loop. Size it via MAX_REGISTERS (80) and clamp the loop count so the write can never run past the array. 3. FI.sh: the memory-range block passed FlashSize (a size) as the high address and read RAMEnd from a non-existent .heap section. Compute FlashEnd = EntryAddress + FlashSize and RAMEnd = RAMDataAddress + RAMBSSSize. Verified: all three compile cleanly (-Werror) against a fresh clone of the extensions branch. --- sofia-ovp/FI.sh | 10 +- .../platformOP/commonStructsAndEnumerators.h | 7 +- sofia-ovp/platformOP/harness/faultInjector.c | 4 + sofia-ovp/platformOP/intercept/intercept.c | 147 ++++++++++++------ 4 files changed, 112 insertions(+), 56 deletions(-) diff --git a/sofia-ovp/FI.sh b/sofia-ovp/FI.sh index f8b3bf84..9b6e3296 100755 --- a/sofia-ovp/FI.sh +++ b/sofia-ovp/FI.sh @@ -112,6 +112,8 @@ function generateFaultList2 { EntryAddress=$( A=$(grep "\.text" applicationSections) ; echo "${A#*PROGBITS}" | tr -s ' ' | cut -d " " -f2 ) # Allocated Flash Memory FlashSize=$( A=$(grep "\.text" applicationSections) ; echo "${A#*PROGBITS}" | tr -s ' ' | cut -d " " -f4 ) + # Flash end address = start + size (was passing the size itself as an address) + FlashEnd=$(printf "%016x" $((0x$EntryAddress + 0x$FlashSize))) # RAM entry address RAMDataAddress=$( A=$(grep "\.data" applicationSections) ; echo "${A#*PROGBITS}" | tr -s ' ' | cut -d " " -f2 ) # DATA Allocated RAM @@ -120,19 +122,19 @@ function generateFaultList2 { RAMBSSAddress=$( A=$(grep "\.bss" applicationSections) ; echo "${A#*NOBITS}" | tr -s ' ' | cut -d " " -f2 ) # BSS Allocated RAM RAMBSSSize=$( A=$(grep "\.bss" applicationSections) ; echo "${A#*NOBITS}" | tr -s ' ' | cut -d " " -f4 ) - # RAM Final Address - RAMEnd=$( A=$(grep "\.heap" applicationSections) ; echo "${A#*PROGBITS}" | tr -s ' ' | cut -d " " -f2 ) + # RAM Final Address = data start + bss size (there is no .heap section in baremetal binaries) + RAMEnd=$(printf "%016x" $((0x$RAMDataAddress + 0x$RAMBSSSize))) # Output to memory detailing file echo "$CURRENT_APPLICATION Memory Detailement on $ARCHITECTURE (Sizes are in bytes)" &>> memory_details.log echo "application, flash_start, flash_end, ram_start, ram_end, flash_size, data_size, bss_size, total_ram_size" &>> memory_details.log - echo "$CURRENT_APPLICATION, $EntryAddress, $FlashSize, $RAMDataAddress, $RAMEnd, $( echo "ibase=16;obase=A; $( echo "$FlashSize" | tr "a-z" "A-Z")" | bc ), $( echo "ibase=16;obase=A; $( echo "$RAMDataSize" | tr "a-z" "A-Z")" | bc ), $( echo "ibase=16;obase=A; $( echo "$RAMBSSSize" | tr "a-z" "A-Z")" | bc ), $( echo "ibase=16;obase=A; $( echo "$RAMDataSize+$RAMBSSSize" | tr "a-z" "A-Z")" | bc )" &>> memory_details.log + echo "$CURRENT_APPLICATION, $EntryAddress, $FlashEnd, $RAMDataAddress, $RAMEnd, $( echo "ibase=16;obase=A; $( echo "$FlashSize" | tr "a-z" "A-Z")" | bc ), $( echo "ibase=16;obase=A; $( echo "$RAMDataSize" | tr "a-z" "A-Z")" | bc ), $( echo "ibase=16;obase=A; $( echo "$RAMBSSSize" | tr "a-z" "A-Z")" | bc ), $( echo "ibase=16;obase=A; $( echo "$RAMDataSize+$RAMBSSSize" | tr "a-z" "A-Z")" | bc )" &>> memory_details.log if [ -z $MEMORY_OPTIONS ]; then CMD_FAULT_LIST="$CMD_FAULT_LIST --memlowaddress=$( echo "ibase=16;obase=A; $( echo "$EntryAddress" | tr "a-z" "A-Z")" | bc ) \ --memhighaddress=$( echo "ibase=16;obase=A; $( echo "$RAMEnd" | tr "a-z" "A-Z")" | bc )" else if [ $MEMORY_OPTIONS == "FLASH" ]; then CMD_FAULT_LIST="$CMD_FAULT_LIST --memlowaddress=$( echo "ibase=16;obase=A; $( echo "$EntryAddress" | tr "a-z" "A-Z")" | bc ) \ - --memhighaddress=$( echo "ibase=16;obase=A; $( echo "$FlashSize" | tr "a-z" "A-Z")" | bc )" + --memhighaddress=$( echo "ibase=16;obase=A; $( echo "$FlashEnd" | tr "a-z" "A-Z")" | bc )" fi if [ $MEMORY_OPTIONS == "RAM" ]; then CMD_FAULT_LIST="$CMD_FAULT_LIST --memlowaddress=$( echo "ibase=16;obase=A; $( echo "$RAMDataAddress" | tr "a-z" "A-Z")" | bc ) \ diff --git a/sofia-ovp/platformOP/commonStructsAndEnumerators.h b/sofia-ovp/platformOP/commonStructsAndEnumerators.h index 7a7dc0ba..27e9ecd8 100755 --- a/sofia-ovp/platformOP/commonStructsAndEnumerators.h +++ b/sofia-ovp/platformOP/commonStructsAndEnumerators.h @@ -3,7 +3,12 @@ ///////////////////////////////////////////////////////////////////////// #define END_LIST "EndList@" -char possibleRegisters[50][10]; +// Working buffer that holds the active arch's register list (copied in faultInjector.c). +// Must cover the largest list: ARMv8 int(33)+SIMD(32)+END = 66 entries already exceed 50. +// MAX_REGISTERS gives headroom; bump it if a longer list is ever added. +#define MAX_REGISTERS 80 +#define MAX_REGISTER_NAME_LEN 10 +char possibleRegisters[MAX_REGISTERS][MAX_REGISTER_NAME_LEN]; int numberOfRegistersToCompare; const char possibleRegistersV7[][10] ={"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10","r11","r12","sp","lr","pc","d0","d1","d2","d3","d4","d5","d6","d7","d8","d9","d10","d11","d12","d13","d14","d15",END_LIST}; const char possibleRegistersV8[][10] ={"x0","x1","x2","x3","x4","x5","x6","x7","x8","x9","x10","x11","x12","x13","x14","x15","x16","x17","x18","x19","x20","x21","x22","x23","x24","x25","x26","x27","x28","x29","x30","sp","pc","v0","v1","v2","v3","v4","v5","v6","v7","v8","v9","v10","v11","v12","v13","v14","v15","v16","v17","v18","v19","v20","v21","v22","v23","v24","v25","v26","v27","v28","v29","v30","v31",END_LIST}; diff --git a/sofia-ovp/platformOP/harness/faultInjector.c b/sofia-ovp/platformOP/harness/faultInjector.c index e6294bb9..7efde469 100755 --- a/sofia-ovp/platformOP/harness/faultInjector.c +++ b/sofia-ovp/platformOP/harness/faultInjector.c @@ -186,6 +186,8 @@ void initialize() { do {numberOfRegistersToCompare++;} while(strcmp(END_LIST,possibleRegistersV7[numberOfRegistersToCompare]) != 0 ); + // guard: never write past possibleRegisters[MAX_REGISTERS] + if(numberOfRegistersToCompare > MAX_REGISTERS) numberOfRegistersToCompare = MAX_REGISTERS; for(int i=0; i MAX_REGISTERS) numberOfRegistersToCompare = MAX_REGISTERS; for(int i=0; i MAX_REGISTERS) numberOfRegistersToCompare = MAX_REGISTERS; for(int i=0; ioptions.tracesymbol); - Addr funcSize = vmirtGetSymbolSize(funcSymbol); - // Get final the reference result - char* buffer = (char*) malloc (sizeof(char) * funcSize); - getSymbolValue(processor,processorData->options.tracesymbol,buffer); - // Gold file - sprintf(tempString,FOLDER_DUMPS"/"FILE_NAME_TRACE"-%d",processorData->MACRO_PLATFORM_ID); - fileTrace = fopen (tempString,"wb"); - // Write - fwrite(buffer,sizeof(char),funcSize,fileTrace); - fclose(fileTrace); + // guard: symbol missing -> vmirtGetSymbolSize(NULL) aborts the simulator + if(!funcSymbol) { + vmiMessage("F",PREFIX_FIM_TRACE_FUNCTION,"Symbol '%s' not found \n",processorData->options.tracesymbol); + } else { + Addr funcSize = vmirtGetSymbolSize(funcSymbol); + // Get final the reference result + char* buffer = (char*) malloc (sizeof(char) * funcSize); + getSymbolValue(processor,processorData->options.tracesymbol,buffer); + // Gold file + sprintf(tempString,FOLDER_DUMPS"/"FILE_NAME_TRACE"-%d",processorData->MACRO_PLATFORM_ID); + fileTrace = fopen (tempString,"wb"); + // Write + fwrite(buffer,sizeof(char),funcSize,fileTrace); + fclose(fileTrace); + free(buffer); + } } // Enable trace to a given variable if(processorData->options.tracevariable){ @@ -544,19 +579,24 @@ static VMIOS_INTERCEPT_FN(serviceHandler) { // Cortex-M or baremetal varSymbol = vmirtGetSymbolByName(processor, processorData->options.tracevariable); } - Addr varSize = vmirtGetSymbolSize(varSymbol); - // Get final the reference result - char* buffer = (char*) malloc (sizeof(char) * varSize); - getSymbolValue(processor,processorData->options.tracevariable,buffer); - // Gold file - sprintf(tempString,FOLDER_DUMPS"/trace_gold_variable-%d",processorData->MACRO_PLATFORM_ID); - fileTrace = fopen (tempString,"w+"); - // Write - //fwrite(buffer,sizeof(char),funcSize,fileTrace); - for (int i=0; i vmirtGetSymbolSize(NULL) aborts the simulator + if(!varSymbol) { + vmiMessage("F", PREFIX_FIM, "Traced variable '%s' not found, skipping gold trace\n", processorData->options.tracevariable); + } else { + Addr varSize = vmirtGetSymbolSize(varSymbol); + // Get final the reference result + char* buffer = (char*) malloc (sizeof(char) * varSize); + getSymbolValue(processor,processorData->options.tracevariable,buffer); + // Gold file + sprintf(tempString,FOLDER_DUMPS"/trace_gold_variable-%d",processorData->MACRO_PLATFORM_ID); + fileTrace = fopen (tempString,"w+"); + // Write + for (int i=0; ioptions.tracesymbol); + // guard: symbol missing -> vmirtGetSymbolAddr/Size(NULL) aborts the simulator + if(!funcSymbol) { + vmiMessage("F",PREFIX_FIM_TRACE_FUNCTION,"Symbol '%s' not found, skipping variable comparison\n",processorData->options.tracesymbol); + } else { Addr funcAddress = vmirtGetSymbolAddr(funcSymbol); Addr funcSize = vmirtGetSymbolSize(funcSymbol); @@ -620,13 +664,9 @@ static VMIOS_INTERCEPT_FN(serviceHandler) { vmiPrintf("SDC2\n"); } - //Dump fault final result - //~ sprintf(tempString,FOLDER_DUMPS"/"FILE_NAME_TRACE"-%d",processorData->MACRO_PLATFORM_ID); - //~ fileTrace = fopen (tempString,"wb"); - - // Write - //~ fwrite(buffer,sizeof(char),funcSize,fileTrace); - //~ fclose(fileTrace); + free(buffer); + free(gold); + } // end guard: funcSymbol found } // Enable trace to a given variable if(processorData->options.tracevariable){ @@ -639,19 +679,24 @@ static VMIOS_INTERCEPT_FN(serviceHandler) { // Cortex-M or baremetal varSymbol = vmirtGetSymbolByName(processor, processorData->options.tracevariable); } - Addr varSize = vmirtGetSymbolSize(varSymbol); - // Get final the reference result - char* buffer = (char*) malloc (sizeof(char) * varSize); - getSymbolValue(processor,processorData->options.tracevariable,buffer); - // Gold file - sprintf(tempString,FOLDER_DUMPS"/trace_fault_variable-%d",processorData->MACRO_PLATFORM_ID); - fileTrace = fopen (tempString,"w+"); - // Write - //fwrite(buffer,sizeof(char),funcSize,fileTrace); - for (int i=0; i vmirtGetSymbolSize(NULL) aborts the simulator + if(!varSymbol) { + vmiMessage("F", PREFIX_FIM, "Traced variable '%s' not found, skipping fault trace\n", processorData->options.tracevariable); + } else { + Addr varSize = vmirtGetSymbolSize(varSymbol); + // Get final the reference result + char* buffer = (char*) malloc (sizeof(char) * varSize); + getSymbolValue(processor,processorData->options.tracevariable,buffer); + // Gold file + sprintf(tempString,FOLDER_DUMPS"/trace_fault_variable-%d",processorData->MACRO_PLATFORM_ID); + fileTrace = fopen (tempString,"w+"); + // Write + for (int i=0; i