diff --git a/tests/build_recoverytest.sh b/tests/build_recoverytest.sh new file mode 100755 index 000000000..8ec3726fb --- /dev/null +++ b/tests/build_recoverytest.sh @@ -0,0 +1,115 @@ +#!/bin/sh + +set -eu + +cp recoverytest.c rcvrtest.c + +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 \ +-DRCVR_CPOOL_STATES \ +-Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I ../h \ +../c/alloc.c \ +../c/cellpool.c \ +../c/collections.c \ +../c/le.c \ +../c/logging.c \ +../c/metalio.c \ +../c/qsam.c \ +../c/recovery.c \ +../c/scheduling.c \ +../c/timeutls.c \ +../c/utils.c \ +../c/zos.c \ +srb_harness.c \ +rcvrtest.c + +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=alloc.asm -o alloc.o alloc.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=cellpool.asm -o cellpool.o cellpool.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=collections.asm -o collections.o collections.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=le.asm -o le.o le.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=logging.asm -o logging.o logging.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=metalio.asm -o metalio.o metalio.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=qsam.asm -o qsam.o qsam.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=recovery.asm -o recovery.o recovery.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=scheduling.asm -o scheduling.o scheduling.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=timeutls.asm -o timeutls.o timeutls.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=utils.asm -o utils.o utils.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=zos.asm -o zos.o zos.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=srb_harness.asm -o srb_harness.o srb_harness.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=rcvrtest.asm -o rcvrtest.o rcvrtest.s + +export _LD_SYSLIB="//'SYS1.CSSLIB'://'CEE.SCEELKEX'://'CEE.SCEELKED'://'CEE.SCEERUN'://'CEE.SCEERUN2'://'CSF.SCSFMOD0'" +ld -V -b ac=1 -b rent -b case=mixed -b map -b xref -b reus -e main -o "//'$USER.DEV.LOADLIB(RCVRTST1)'" \ +rcvrtest.o alloc.o cellpool.o collections.o le.o logging.o metalio.o qsam.o recovery.o scheduling.o timeutls.o utils.o zos.o srb_harness.o > RCVRTST1.link + + + + +xlc -S -M -qmetal -q64 -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 \ +-DRCVR_CPOOL_STATES \ +-Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname,lp64" -I ../h \ +../c/alloc.c \ +../c/cellpool.c \ +../c/collections.c \ +../c/le.c \ +../c/logging.c \ +../c/metalio.c \ +../c/qsam.c \ +../c/recovery.c \ +../c/scheduling.c \ +../c/timeutls.c \ +../c/utils.c \ +../c/zos.c \ +srb_harness.c \ +rcvrtest.c + +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=alloc.asm -o alloc.o alloc.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=cellpool.asm -o cellpool.o cellpool.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=collections.asm -o collections.o collections.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=le.asm -o le.o le.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=logging.asm -o logging.o logging.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=metalio.asm -o metalio.o metalio.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=qsam.asm -o qsam.o qsam.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=recovery.asm -o recovery.o recovery.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=scheduling.asm -o scheduling.o scheduling.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=timeutls.asm -o timeutls.o timeutls.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=utils.asm -o utils.o utils.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=zos.asm -o zos.o zos.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=srb_harness.asm -o srb_harness.o srb_harness.s +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=rcvrtest.asm -o rcvrtest.o rcvrtest.s + +export _LD_SYSLIB="//'SYS1.CSSLIB'://'CEE.SCEELKEX'://'CEE.SCEELKED'://'CEE.SCEERUN'://'CEE.SCEERUN2'://'CSF.SCSFMOD0'" +ld -V -b ac=1 -b rent -b case=mixed -b map -b xref -b reus -e main -o "//'$USER.DEV.LOADLIB(RCVRTST4)'" \ +rcvrtest.o alloc.o cellpool.o collections.o le.o logging.o metalio.o qsam.o recovery.o scheduling.o timeutls.o utils.o zos.o srb_harness.o > RCVRTST4.link + + + + +xlc -D_OPEN_THREADS=1 "-Wa,goff" "-Wc,LANGLVL(EXTC99),FLOAT(HEX),agg,exp,list(),so(),goff,xref,gonum,roconst,gonum,ASM,ASMLIB('SYS1.MACLIB'),ASMLIB('CEE.SCEEMAC')" '-Wl,ac=1' \ +-DRCVR_CPOOL_STATES \ +-I ../h -o recoverytest31 recoverytest.c \ +../c/alloc.c \ +../c/cellpool.c \ +../c/collections.c \ +../c/le.c \ +../c/logging.c \ +../c/recovery.c \ +../c/scheduling.c \ +../c/timeutls.c \ +../c/utils.c \ +../c/zos.c + + +xlc -D_OPEN_THREADS=1 "-Wa,goff" "-Wc,LP64,XPLINK,LANGLVL(EXTC99),FLOAT(HEX),agg,exp,list(),so(),goff,xref,gonum,roconst,gonum,ASM,ASMLIB('SYS1.MACLIB'),ASMLIB('CEE.SCEEMAC')" '-Wl,ac=1' \ +-DRCVR_CPOOL_STATES \ +-I ../h -o recoverytest64 recoverytest.c \ +../c/alloc.c \ +../c/cellpool.c \ +../c/collections.c \ +../c/le.c \ +../c/logging.c \ +../c/recovery.c \ +../c/scheduling.c \ +../c/timeutls.c \ +../c/utils.c \ +../c/zos.c + diff --git a/tests/recoverytest.c b/tests/recoverytest.c new file mode 100644 index 000000000..36f8131f0 --- /dev/null +++ b/tests/recoverytest.c @@ -0,0 +1,571 @@ +#ifdef METTLE +#include +#include +#include +#include +#include +#include +#include "metalio.h" +#else +#include "stdbool.h" +#include "stddef.h" +#include "stdlib.h" +#include "stdio.h" +#include "string.h" +#endif + +/* + +Metal C 31-bit: + +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I ../h -o alloc.s ../c/alloc.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=alloc.asm -o alloc.o alloc.s +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I ../h -o collections.s ../c/collections.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=collections.asm -o collections.o collections.s +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I ../h -o le.s ../c/le.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=le.asm -o le.o le.s +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I ../h -o logging.s ../c/logging.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=logging.asm -o logging.o logging.s +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I ../h -o metalio.s ../c/metalio.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=metalio.asm -o metalio.o metalio.s +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I ../h -o qsam.s ../c/qsam.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=qsam.asm -o qsam.o qsam.s +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I ../h -o recovery.s ../c/recovery.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=recovery.asm -o recovery.o recovery.s +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I ../h -o scheduling.s ../c/scheduling.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=scheduling.asm -o scheduling.o scheduling.s +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I ../h -o timeutls.s ../c/timeutls.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=timeutls.asm -o timeutls.o timeutls.s +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I ../h -o utils.s ../c/utils.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=utils.asm -o utils.o utils.s +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I ../h -o zos.s ../c/zos.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=zos.asm -o zos.o zos.s + +cp recoverytest.c rcvrtest.c +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I h -I ../h -o rcvrtest.s rcvrtest.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=rcvrtest.asm -o rcvrtest.o rcvrtest.s + +export _LD_SYSLIB="//'SYS1.CSSLIB'://'CEE.SCEELKEX'://'CEE.SCEELKED'://'CEE.SCEERUN'://'CEE.SCEERUN2'://'CSF.SCSFMOD0'" +ld -V -b ac=1 -b rent -b case=mixed -b map -b xref -b reus -e main -o "//'$USER.DEV.LOADLIB(RECVRTST)'" \ +rcvrtest.o alloc.o collections.o le.o logging.o metalio.o qsam.o recovery.o scheduling.o timeutls.o utils.o zos.o > rcvrtest.link + +Metal C 64-bit: + +xlc -S -M -qmetal -q64 -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname,lp64" -I ../h -o alloc.s ../c/alloc.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=alloc.asm -o alloc.o alloc.s +xlc -S -M -qmetal -q64 -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname,lp64" -I ../h -o collections.s ../c/collections.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=collections.asm -o collections.o collections.s +xlc -S -M -qmetal -q64 -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname,lp64" -I ../h -o le.s ../c/le.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=le.asm -o le.o le.s +xlc -S -M -qmetal -q64 -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname,lp64" -I ../h -o metalio.s ../c/metalio.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=metalio.asm -o metalio.o metalio.s +xlc -S -M -qmetal -q64 -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname,lp64" -I ../h -o qsam.s ../c/qsam.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=qsam.asm -o qsam.o qsam.s +xlc -S -M -qmetal -q64 -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname,lp64" -I ../h -o recovery.s ../c/recovery.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=recovery.asm -o recovery.o recovery.s +xlc -S -M -qmetal -q64 -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname,lp64" -I ../h -o scheduling.s ../c/scheduling.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=scheduling.asm -o scheduling.o scheduling.s +xlc -S -M -qmetal -q64 -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname,lp64" -I ../h -o timeutls.s ../c/timeutls.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=timeutls.asm -o timeutls.o timeutls.s +xlc -S -M -qmetal -q64 -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname,lp64" -I ../h -o utils.s ../c/utils.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=utils.asm -o utils.o utils.s +xlc -S -M -qmetal -q64 -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname,lp64" -I ../h -o zos.s ../c/zos.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=zos.asm -o zos.o zos.s + +cp recoverytest.c rcvrtest.c +xlc -S -M -qmetal -q64 -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname,lp64" -I h -I ../h -o rcvrtest.s rcvrtest.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=rcvrtest.asm -o rcvrtest.o rcvrtest.s + +export _LD_SYSLIB="//'SYS1.CSSLIB'://'CEE.SCEELKEX'://'CEE.SCEELKED'://'CEE.SCEERUN'://'CEE.SCEERUN2'://'CSF.SCSFMOD0'" +ld -V -b ac=1 -b rent -b case=mixed -b map -b xref -b reus -e main -o "//'$USER.DEV.LOADLIB(RECVRTST)'" \ +rcvrtest.o alloc.o collections.o le.o logging.o metalio.o qsam.o recovery.o scheduling.o timeutls.o utils.o zos.o > rcvrtest.link + +LE 31-bit: + +xlc -D_OPEN_THREADS=1 "-Wa,goff" "-Wc,LANGLVL(EXTC99),FLOAT(HEX),agg,exp,list(),so(),goff,xref,gonum,roconst,gonum,ASM,ASMLIB('SYS1.MACLIB'),ASMLIB('CEE.SCEEMAC')" '-Wl,ac=1' \ +-I ../h -o recoverytest recoverytest.c ../c/alloc.c ../c/collections.c ../c/le.c ../c/logging.c ../c/recovery.c ../c/scheduling.c ../c/timeutls.c ../c/utils.c ../c/zos.c + +LE 64-bit: + +xlc -D_OPEN_THREADS=1 "-Wa,goff" "-Wc,LP64,XPLINK,LANGLVL(EXTC99),FLOAT(HEX),agg,exp,list(),so(),goff,xref,gonum,roconst,gonum,ASM,ASMLIB('SYS1.MACLIB'),ASMLIB('CEE.SCEEMAC')" '-Wl,ac=1' \ +-I ../h -o recoverytest recoverytest.c ../c/alloc.c ../c/collections.c ../c/le.c ../c/logging.c ../c/recovery.c ../c/scheduling.c ../c/timeutls.c ../c/utils.c ../c/zos.c + +AIX 32-bit: + +/tools/AIX-7.2/xlc-13.1.3.0/opt/IBM/xlC/13.1.3/bin/xlc_r -qtls -qlist -I ../h -o recoverytest recoverytest.c ../c/alloc.c ../c/recovery.c ../c/utils.c + +AIX 64-bit: + +/tools/AIX-7.2/xlc-13.1.3.0/opt/IBM/xlC/13.1.3/bin/xlc_r -q64 -qtls -qlist -I ../h -o recoverytest recoverytest.c ../c/alloc.c ../c/recovery.c ../c/utils.c + +Linux GCC: + +gcc -pthread -I ../h -o recoverytest recoverytest.c ../c/alloc.c ../c/recovery.c ../c/utils.c + +*/ + +#include "zowetypes.h" +#include "alloc.h" +#include "openprims.h" +#include "recovery.h" +#include "utils.h" + +#ifdef __ZOWE_OS_ZOS +#include "le.h" +#endif + +#if defined(__ZOWE_OS_AIX) || defined(__ZOWE_OS_LINUX) +#include "unistd.h" +#endif + +#ifdef __ZOWE_OS_ZOS + +#define INIT_ZOS_ENV_IF_NEEDED()\ +do {\ + CAA *caa = (CAA *)getCAA();\ + caa->rleTask = (RLETask *)safeMalloc31(sizeof(RLETask), "dummy RLE task");\ +} while (0) + +static void testAnalysisFunction(RecoveryContext * __ptr32 context, + SDWA * __ptr32 sdwa, + void * __ptr32 userData) { + printf("testAnalysisFunction: context=0x%p\n", context); + dumpbuffer((char *)context, sizeof(RecoveryContext)); + printf("testAnalysisFunction: SDWA=0x%p\n", sdwa); + dumpbuffer((char *)sdwa, sizeof(SDWA)); + sprintf(userData, "hello from testAnalysisFunction, SDWA address is 0x%p", + sdwa); +} + +static void testCleanupFunction(RecoveryContext * __ptr32 context, + SDWA * __ptr32 sdwa, + void * __ptr32 userData) { + printf("testCleanupFunction: context=0x%p\n", context); + dumpbuffer((char *)context, sizeof(RecoveryContext)); + printf("testCleanupFunction: SDWA=0x%p\n", sdwa); + dumpbuffer((char *)sdwa, sizeof(SDWA)); + sprintf(userData, "hello from testCleanupFunction, SDWA address is 0x%p", sdwa); +} + +static void printMessage(RecoveryContext * __ptr32 context, + SDWA * __ptr32 sdwa, + void * __ptr32 userData) { + printf("%s\n", userData); +} + +static void testRecoveryOnNewLSFrame(int level, bool optinLSQuery) { + + if (level == 5) return; + + __asm( +#ifdef _LP64 + " OILL %[retAddr],X'0001' \n" +#else + " OILH %[retAddr],X'8000' \n" +#endif + " BAKR %[retAddr],0 \n" + : + : [retAddr]"r"(&&exit_func) + : + ); + + printf("testRecoveryOnNewLSFrame entered (level=%d, optinLSQuery=%d)\n", + level, optinLSQuery); + + int flags = RCVR_FLAG_RETRY | RCVR_FLAG_DELETE_ON_RETRY; + if (optinLSQuery) flags |= RCVR_FLAG_QUERY_LSTACK; + + int pushRC = recoveryPush("testBAKR()", flags, + "Recovery dump", + NULL, NULL, + NULL, NULL); + + if (pushRC == RC_RCV_OK) { + testRecoveryOnNewLSFrame(level + 1, optinLSQuery); + printf("about to abend at level %d\n", level); + int i = 9 / 0; + } else { + printf("testRecoveryOnNewLSFrame recovered from an ABEND, pushRC=%d\n", pushRC); + } + + if (pushRC == RC_RCV_OK) { + recoveryPop(); + } + + char regs[128]; + + __asm volatile ( + " STMG 1,15,0(%[regs]) \n" + " PR , \n" + : + : [regs]"NR:r15"(®s) + : "r15" + ); + + exit_func: + + __asm volatile ( + " LMG 1,15,0(15) \n" + ); + + printf("testRecoveryOnNewLSFrame ended (level=%d, optinLSQuery=%d)\n", + level, optinLSQuery); + +} + +#ifdef METTLE + +#include "srb_harness.h" + +#define SRB_TEST_EXPECTED_RETURN_VALUE 0xABCD9876 + +static void srbFunction(uint32_t parm) { + + uint32_t *returnValue = (uint32_t *)parm; + +#ifdef METTLE + establishGlobalEnvironment(makeRLEAnchor()); +#endif + INIT_ZOS_ENV_IF_NEEDED(); + + recoveryEstablishRouter(0); + + int pushRC = recoveryPush("srb_routine()", + RCVR_FLAG_RETRY | RCVR_FLAG_DELETE_ON_RETRY, + "Recovery dump", + NULL, NULL, + NULL, NULL); + + if (pushRC == RC_RCV_OK) { + int i = 9 / 0; + } else { + *returnValue = SRB_TEST_EXPECTED_RETURN_VALUE; + } + + if (pushRC == RC_RCV_OK) { + recoveryPop(); + } + + recoveryRemoveRouter(); + +} + +static int testRecoveryInSRB(void) { + + uint32_t srbReturnValue = 0; + + int runRC = run_in_srb(srbFunction, (uint32_t)&srbReturnValue); + + if (runRC != 0) { + printf("error: SRB not run, rc = %d\n", runRC); + return 8; + } + + if (srbReturnValue != SRB_TEST_EXPECTED_RETURN_VALUE) { + printf("error: unexpected value from SRB test - %u\n", srbReturnValue); + return 8; + } + + return 0; +} + +#endif /* METTLE */ + +#else /* zOS targets */ + +#define INIT_ZOS_ENV_IF_NEEDED()\ +do {\ +} while (0) + +static void testAnalysisFunction(RecoveryContext *context, + int signal, + siginfo_t *info, + void *userData) { + sprintf(userData, "hello from testAnalysisFunction, " + "signal=%d, si_errno=%d, si_code=%d, si_addr=%p", + signal, info->si_errno, info->si_code, info->si_addr); +} + +static void testCleanupFunction(RecoveryContext *context, + int signal, + siginfo_t *info, + void *userData) { + sprintf(userData, "hello form testCleanupFunction, " + "signal=%d, si_errno=%d, si_code=%d, si_addr=%p", + signal, info->si_errno, info->si_code, info->si_addr); +} + +static void printMessage(RecoveryContext *context, + int signal, + siginfo_t *info, + void *userData) { + printf("%s\n", (char *)userData); +} + +#endif /* Unix */ + +static void testRecursiveFunction(int depth) { + + if (depth > 10) { + return; + } + + char buffer[1024]; + snprintf(buffer, sizeof(buffer), "calling a recursive function, depth = %d", + depth); + printf("%s (%d)\n", buffer, depth); + + testRecursiveFunction(depth + 1); +} + +static void callBadInstruction() { + +#ifdef __ZOWE_OS_ZOS + __asm(" DS H'0'"); +#elif defined(__ZOWE_OS_AIX) + char buff[1024]; + memset(buff, 0, sizeof(buff)); + ((void (*)())buff)(); +#elif defined(__ZOWE_OS_LINUX) + asm("ud2"); +#endif + +} + +static void *thread1(void *data) { + INIT_ZOS_ENV_IF_NEEDED(); + + printf("hello from thread #1\n"); + int establishRC = recoveryEstablishRouter(RCVR_ROUTER_FLAG_NONE); + if (establishRC == RC_RCV_OK) { + + int pushRC1 = recoveryPush(NULL, RCVR_FLAG_RETRY, NULL, + NULL, NULL, + NULL, NULL); + if (pushRC1 != RC_RCV_OK) { + printf("warn: something went wrong in thread #1\n"); + } + else { + sleep(3); + testRecursiveFunction(0); + char *badPtr = (char *)0xFFCC; + badPtr[3] = 3; + } + recoveryPop(); + + printf("thread #1 after the first ABEND\n"); + + int pushRC2 = recoveryPush(NULL, RCVR_FLAG_RETRY, NULL, + NULL, NULL, + NULL, NULL); + if (pushRC2 != RC_RCV_OK) { + printf("warn: something went wrong in thread #1\n"); + } + else { + sleep(3); + testRecursiveFunction(0); + char *badPtr = (char *)0xFFCC; + badPtr[3] = 3; + } + recoveryPop(); + + printf("thread #1 after the second ABEND\n"); + + for (int i = 0; i < 7; i ++) { + printf("hello from thread #1\n"); + sleep(2); + } + + recoveryRemoveRouter(); + } + else { + printf("error: recovery router not established\n"); + } + + return NULL; +} + +static void *thread2(void *data) { + INIT_ZOS_ENV_IF_NEEDED(); + + printf("hello from thread #2\n"); + sleep(15); + + int establishRC = recoveryEstablishRouter(RCVR_ROUTER_FLAG_NONE); + if (establishRC == RC_RCV_OK) { + + int pushRC = recoveryPush(NULL, RCVR_FLAG_RETRY, NULL, + NULL, NULL, + NULL, NULL); + if (pushRC != RC_RCV_OK) { + printf("warn: something went wrong in thread #2\n"); + } + else { + testRecursiveFunction(0); + char *badPtr = (char *)0xFFCC; + badPtr[3] = 3; + } + recoveryPop(); + + + for (int i = 0; i < 5; i ++) { + printf("hello from thread #2\n"); + sleep(2); + } + + char *message = safeMalloc31(1024, "message"); + pushRC = recoveryPush(NULL, RCVR_FLAG_RETRY, NULL, + testAnalysisFunction, message, + NULL, NULL); + if (pushRC == RC_RCV_OK) { + callBadInstruction(); + } else { + printf("warn: executed a bad instruction but recovered (\'%s\')\n", + message); + } + recoveryPop(); + + recoveryRemoveRouter(); + } + else { + printf("error: recovery router not established\n"); + } + + return NULL; +} + + +int main() { +#ifdef METTLE + establishGlobalEnvironment(makeRLEAnchor()); +#endif + INIT_ZOS_ENV_IF_NEEDED(); + + printf("info: hello from recoverytest.c\n"); + + int establishRC = recoveryEstablishRouter(RCVR_ROUTER_FLAG_NONE); + if (establishRC == RC_RCV_OK) { + +#ifdef __ZOWE_OS_ZOS + recoveryUpdateRouterServiceInfo("RSRCVSTS", "MAINFUNC", "TSTRCVR", + NULL, NULL, + "09/09/17", "1.0RC1", "1357", + NULL); +#endif + + int pushRC = RC_RCV_OK; + + /* recovery #1 */ + pushRC = recoveryPush("state01", RCVR_FLAG_RETRY, "Recovery test #1", + printMessage, "top level recovery", + NULL, NULL); + + if (pushRC != RC_RCV_OK) { + printf("warn: something went wrong #1\n"); + } + else { + + testRecursiveFunction(0); + + recoveryPush("nstate01", RCVR_FLAG_RETRY, NULL, + printMessage, "nested recovery #1", + NULL, NULL); + + printf("about to push another recovery state...\n"); + + recoveryPush("nstate02", RCVR_FLAG_RETRY, NULL, + printMessage, "nested recovery #2", + NULL, NULL); + + printf("about to ABEND...\n"); + + int i = 9 / 0; + + } + recoveryPop(); + + /* recovery #2 */ + char *messageBuffer1 = safeMalloc31(1024, "messageBuffer1"); + char *messageBuffer2 = safeMalloc31(1024, "messageBuffer2"); + pushRC = recoveryPush("state2", RCVR_FLAG_RETRY | RCVR_FLAG_SDWA_TO_LOGREC, + "Recovery test dump", + testAnalysisFunction, messageBuffer1, + testCleanupFunction, messageBuffer2); + if (pushRC != RC_RCV_OK) { + printf("warn: something went wrong #2, " + "messageBuffer1=\'%s\', messageBuffer2=\'%s\'\n", + messageBuffer1, messageBuffer2); + } + else { + recoverySetDumpTitle("brand new dump title for our recovery test"); + +#ifdef __ZOWE_OS_ZOS + recoveryUpdateStateServiceInfo(NULL, NULL, NULL, + "2", "rcvr test component #2", + NULL, NULL, NULL, + "newState2"); +#endif + + recoveryPush("state3", RCVR_FLAG_DISABLE, NULL, NULL, NULL, NULL, NULL); + recoveryPush("state4", RCVR_FLAG_DISABLE, NULL, NULL, NULL, NULL, NULL); + recoveryPush("state5", RCVR_FLAG_DISABLE, NULL, NULL, NULL, NULL, NULL); + + testRecursiveFunction(0); + void *nullPointer = NULL; + memset(nullPointer, 0, 1); + } + recoveryPop(); + + /* recovery #3 */ + pushRC = recoveryPush(NULL, RCVR_FLAG_RETRY, NULL, NULL, NULL, NULL, NULL); + if (pushRC != RC_RCV_OK) { + printf("warn: something went wrong #3\n"); + } + else { + printf("info: recovery #3 should not be triggered...\n"); + } + recoveryPop(); + + printf("info: we just survived a couple of ABENDs, continue..\n"); + + } + else { + printf("error: recovery router not established\n"); + return 8; + } + +#ifndef METTLE + printf("info: about to start a couple of threads\n"); + OSThread osThreadData1, osThreadData2; + OSThread *osThread1 = &osThreadData1, *osThread2 = &osThreadData2; + threadCreate(osThread1, thread1, NULL); + threadCreate(osThread2, thread2, NULL); + + pthread_join(osThread1->threadID, NULL); + pthread_join(osThread2->threadID, NULL); +#endif + +#ifdef __ZOWE_OS_ZOS + + recoveryEstablishRouter(RCVR_ROUTER_FLAG_NONE); + testRecoveryOnNewLSFrame(0, false); + recoveryRemoveRouter(); + + recoveryEstablishRouter(RCVR_ROUTER_FLAG_SKIP_LSTACK_QUERY); + testRecoveryOnNewLSFrame(0, true); + recoveryRemoveRouter(); + +#ifdef METTLE + int srbTestRC = testRecoveryInSRB(); + if (srbTestRC != 0) { + return 8; + } +#endif + +#endif + + printf("info: recovery test successful\n"); + + return 0; +} + diff --git a/tests/srb_harness.c b/tests/srb_harness.c new file mode 100644 index 000000000..1cea6af73 --- /dev/null +++ b/tests/srb_harness.c @@ -0,0 +1,336 @@ +#ifdef METTLE +#include +#include +#include +#include +#include +#include +#include "metalio.h" +#else +#include "stdarg.h" +#include "stddef.h" +#include "stdint.h" +#include "stdlib.h" +#include "stdio.h" +#include "string.h" +#endif + +/* + +Metal C 31-bit: + +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I ../h -o alloc.s ../c/alloc.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=alloc.asm -o alloc.o alloc.s +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I ../h -o metalio.s ../c/metalio.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=metalio.asm -o metalio.o metalio.s +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I ../h -o qsam.s ../c/qsam.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=qsam.asm -o qsam.o qsam.s +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I ../h -o timeutls.s ../c/timeutls.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=timeutls.asm -o timeutls.o timeutls.s +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I ../h -o utils.s ../c/utils.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=utils.asm -o utils.o utils.s +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I ../h -o zos.s ../c/zos.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=zos.asm -o zos.o zos.s + +cp srb_harness.c srb_harness.c +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname" -I h -I ../h -o srb_harness.s srb_harness.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=srb_harness.asm -o srb_harness.o srb_harness.s + +export _LD_SYSLIB="//'SYS1.CSSLIB'://'CEE.SCEELKEX'://'CEE.SCEELKED'://'CEE.SCEERUN'://'CEE.SCEERUN2'://'CSF.SCSFMOD0'" +ld -V -b ac=1 -b rent -b case=mixed -b map -b xref -b reus -e main -o "//'$USER.DEV.LOADLIB(SRBTEST)'" \ +srb_harness.o alloc.o metalio.o qsam.o timeutls.o utils.o zos.o > srb_harness.link + +Metal C 64-bit: + +xlc -S -M -qmetal -q64 -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname,lp64" -I ../h -o alloc.s ../c/alloc.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=alloc.asm -o alloc.o alloc.s +xlc -S -M -qmetal -q64 -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname,lp64" -I ../h -o metalio.s ../c/metalio.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=metalio.asm -o metalio.o metalio.s +xlc -S -M -qmetal -q64 -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname,lp64" -I ../h -o qsam.s ../c/qsam.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=qsam.asm -o qsam.o qsam.s +xlc -S -M -qmetal -q64 -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname,lp64" -I ../h -o timeutls.s ../c/timeutls.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=timeutls.asm -o timeutls.o timeutls.s +xlc -S -M -qmetal -q64 -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname,lp64" -I ../h -o utils.s ../c/utils.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=utils.asm -o utils.o utils.s +xlc -S -M -qmetal -q64 -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname,lp64" -I ../h -o zos.s ../c/zos.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=zos.asm -o zos.o zos.s + +xlc -S -M -qmetal -q64 -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"IDX"' -qreserved_reg=r12 -Wc,"arch(8),agg,exp,list(),so(),off,xref,roconst,longname,lp64" -I h -I ../h -o srb_harness.s srb_harness.c +as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=srb_harness.asm -o srb_harness.o srb_harness.s + +export _LD_SYSLIB="//'SYS1.CSSLIB'://'CEE.SCEELKEX'://'CEE.SCEELKED'://'CEE.SCEERUN'://'CEE.SCEERUN2'://'CSF.SCSFMOD0'" +ld -V -b ac=1 -b rent -b case=mixed -b map -b xref -b reus -e main -o "//'$USER.DEV.LOADLIB(SRBTEST)'" \ +srb_harness.o alloc.o metalio.o qsam.o timeutls.o utils.o zos.o > srb_harness.link + + +*/ + +#include "zowetypes.h" +#include "alloc.h" +#include "utils.h" +#include "zos.h" + +#ifdef _LP64 + +#pragma prolog(srb_routine,\ +" PUSH USING \n\ +SRBPRLG DS 0H \n\ + BAKR 14,0 \n\ + SAM64 \n\ + LARL 10,SRBPRLG \n\ + USING SRBPRLG,10 \n\ + LA 2,128 \n\ + SPKA 0(2) \n\ + STORAGE OBTAIN,COND=YES,LENGTH=8192,KEY=8,SP=230,LOC=31,BNDRY=PAGE \n\ + LTR 15,15 \n\ + JNZ SRBRET \n\ +SRBINIT DS 0H \n\ + LLGFR 13,1 \n\ + USING SRBSTACK,13 \n\ + EREGG 0,1 \n\ + LA 13,SRBSA \n\ +\ + J SRBHNDLR \n\ +\ + LTORG \n\ + DROP 10 \n\ +SRBHNDLR DS 0H \n\ + DROP \n\ + POP USING ") + +#else + +#pragma prolog(srb_routine,\ +" PUSH USING \n\ +SRBPRLG DS 0H \n\ + BAKR 14,0 \n\ + SAM31 \n\ + LARL 10,SRBPRLG \n\ + USING SRBPRLG,10 \n\ + LA 2,128 \n\ + SPKA 0(2) \n\ + STORAGE OBTAIN,COND=YES,LENGTH=8192,KEY=8,SP=230,LOC=31,BNDRY=PAGE \n\ + LTR 15,15 \n\ + JNZ SRBRET \n\ +SRBINIT DS 0H \n\ + LLGFR 13,1 \n\ + USING SRBSTACK,13 \n\ + EREGG 0,1 \n\ + LA 13,SRBSA \n\ +\ + J SRBHNDLR \n\ +\ + LTORG \n\ + DROP 10 \n\ +SRBHNDLR DS 0H \n\ + DROP \n\ + POP USING ") + +#endif + +#pragma epilog(srb_routine,\ +" PUSH USING \n\ +SRBEPLG DS 0H \n\ + LARL 10,SRBEPLG \n\ + USING SRBEPLG,10 \n\ + SLFI 13,SRBPARML \n\ + LR 1,13 \n\ + STORAGE RELEASE,COND=NO,LENGTH=8192,KEY=8,SP=230,ADDR=(1) \n\ +SRBRET DS 0H \n\ + DROP 10 \n\ + LR 15,0 \n\ + EREGG 0,1 \n\ + SPKA 0 \n\ + PR \n\ + DROP \n\ + POP USING ") + +static void wto(const char *format, ...) { + + __packed struct { + __packed struct { + uint8_t reply_buff_len; + uint8_t length; + uint8_t flags1; + uint8_t flags2; + } header; + char msg_buff[126]; + } wto_parm = {0}; + + va_list args; + va_start(args, format); + int print_rc = vsnprintf(wto_parm.msg_buff, sizeof(wto_parm.msg_buff), + format, args); + va_end(args); + + if (print_rc >= 0) { + wto_parm.header.length = + sizeof(wto_parm.header) + strlen(wto_parm.msg_buff); + } else { + return; + } + + __asm( +#ifdef _LP64 + " SAM31 \n" + " SYSSTATE AMODE64=NO \n" +#endif + " WTO LINKAGE=BRANCH,MF=(E,%[parm]) \n" +#ifdef _LP64 + " SAM64 \n" + " SYSSTATE AMODE64=YES \n" +#endif + : + : [parm]"m"(wto_parm) + : "r0", "r1", "r14", "r15" + ); + +} + + typedef struct stoken_t { + char value[8]; + } stoken_t; + +static int sched_sync_srb(void * __ptr32 ep, + void * __ptr32 parm, + stoken_t token, + void * __ptr32 frr_addr, + int * __ptr32 comp_code, + int * __ptr32 srb_rc, + int * __ptr32 srb_rsn) { + + char macro_parm_list[512]; + + int rc = 0; + + unsigned int local_ep = ((int)ep) | 0x80000000; + unsigned int local_parm = (int)parm; + unsigned int local_frr_addr = + (frr_addr != NULL) ? (((int)frr_addr) | 0x80000000) : 0; + stoken_t local_stoken = token; + + __asm( + ASM_PREFIX + +#ifdef _LP64 + " SAM31 \n" + " SYSSTATE AMODE64=NO \n" +#endif + + " IEAMSCHD EPADDR=(%[ep])" + ",ENV=STOKEN" + ",PRIORITY=LOCAL" + ",SYNCH=YES" + ",PARM=(%[parm])" + ",TARGETSTOKEN=(%[stoken])" + ",FRRADDR=(%[frr])" + ",SYNCHCOMPADDR=%[cc]" + ",SYNCHCODEADDR=%[srb_rc]" + ",SYNCHRSNADDR=%[srb_rsn]" + ",RETCODE=%[rc]" + ",MF=(E,(%[macro_parm_list]),COMPLETE) \n" + +#ifdef _LP64 + " SAM64 \n" + " SYSSTATE AMODE64=YES \n" +#endif + + : [rc]"=m"(rc), + [cc]"=m"(comp_code), + [srb_rc]"=m"(srb_rc), + [srb_rsn]"=m"(srb_rsn) + + : [ep]"r"(&local_ep), + [parm]"r"(&local_parm), + [stoken]"r"(&local_stoken), + [frr]"r"(&local_frr_addr), + [macro_parm_list]"r"(¯o_parm_list) + + : "r0", "r1", "r14", "r15" + + ); + + return rc; +} + +static stoken_t get_my_stoken(void) { + + ASSB *assb = getASSB(getASCB()); + + stoken_t token = *(stoken_t *)&assb->assbstkn; + + return token; +} + +typedef struct srb_context_t { + void (*func)(uint32_t parm); + uint32_t parm; +} srb_context; + + + +static void srb_routine(void) { + + srb_context * __ptr32 cntx = 0; + __asm(" ST 1,%[cntx] " : [cntx]"=m"(cntx)); + + cntx->func(cntx->parm); + +} + +int run_in_srb(void (*func)(uint32_t parm), uint32_t parm) { + + int was_prob = supervisorMode(TRUE); + + stoken_t my_stoken = get_my_stoken(); + + int32_t sched_rc = 0; + int32_t cc = 0; + int32_t srb_rc = 0; + int32_t srb_rsn = 0; + + srb_context cntx = {.func = func, .parm = parm}; + + printf("cntx=%p\n", &cntx); + + sched_rc = sched_sync_srb((void *)srb_routine, &cntx, my_stoken, NULL, + &cc, &srb_rc, &srb_rsn); + + printf("testSRB: sched_rc=%d, cc=%d, srb_rc=0x%08x, srb_rsn=0x%08x\n", + sched_rc, cc, srb_rc, srb_rsn); + + if (was_prob) { + supervisorMode(FALSE); + } + + return cc ? -1 : 0; + +} + +void srb_test_dsect() { + + __asm( + " DS 0F \n" + "SRBSTACK DSECT , \n" + /* parameters on stack */ + "SRBPARM DS 0F SRB exit parm list \n" + "SRBTPRM1 DS A parm #1 \n" + "SRBTPRM DS A parm #1 \n" + "SRBPLPAD DS 0F padding \n" + "SRBPARML EQU *-SRBPARM \n" + /* 31-bit save area */ + "SRBSA DS 0F \n" + "SRBSARSV DS CL4 \n" + "SRBSAPRV DS A previous save area \n" + "SRBSANXT DS A next save area \n" + "SRBSAGPR DS 15F GPRs \n" + "SRBSTCKL EQU *-SRBSTACK \n" + " EJECT , \n" +#ifdef METTLE + " CSECT , \n" + " RMODE ANY \n" +#endif + + ); + +} diff --git a/tests/srb_harness.h b/tests/srb_harness.h new file mode 100644 index 000000000..2a5944870 --- /dev/null +++ b/tests/srb_harness.h @@ -0,0 +1,16 @@ +#ifndef TEST_SRB_HARNESS_H_ +#define TEST_SRB_HARNESS_H_ + +#ifdef METTLE +#include +#include +#include +#include "metalio.h" +#else +#include "stddef.h" +#include "stdint.h" +#endif + +int run_in_srb(void (*func)(uint32_t parm), uint32_t parm); + +#endif /* TEST_SRB_HARNESS_H_ */