# primitives for emitting traces to a 'trace' stream, and for tests to make assertions on its contents # # A trace stream looks like a regular stream: # write: int # index at which writes go # read: int # index that we've read until # data: (array byte) # prefixed by size as usual # Usually the trace stream will be in a separate segment set aside for the purpose. # # primitives for operating on traces (arguments in quotes): # - initialize-trace-stream: populates Trace-stream with a new segment of the given 'size' # - trace: adds a 'line' to Trace-stream # - check-trace-contains: scans from Trace-stream's start for a matching 'line', prints a 'message' to stderr on failure # - check-trace-scans-to: scans from Trace-stream's read pointer for a matching 'line', prints a 'message' to stderr on failure == data Trace-stream: # (addr stream byte) # TODO: make this a handle 0/imm32 Trace-segment: 0/imm32/curr 0/imm32/limit # Fake trace-stream for tests. # Also illustrates the layout of the real trace-stream (segment). _test-trace-stream: # (stream byte) # current write index 0/imm32 # current read index 0/imm32 # size 8/imm32 # data 00 00 00 00 00 00 00 00 # 8 bytes == code # instruction effective address register displacement immediate # . op subop mod rm32 base index scale r32 # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes # Allocate a new segment for the trace stream, initialize its size, and save its address to Trace-stream. # The Trace-stream segment will consist of variable-length lines separated by newlines (0x0a) initialize-trace-stream: # n: int # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # . save registers 50/push-eax 51/push-ecx # ecx = n 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx # Trace-segment = new-segment(n) # . . push args 68/push Trace-segment/imm32 51/push-ecx # . . call e8/call new-segment/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # copy Trace-segment->curr to *Trace-stream 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax Trace-segment/disp32 # copy *Trace-segment to eax #? # watch point to catch Trace-stream leaks #? $watch-1: 89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax Trace-stream/disp32 # copy eax to *Trace-stream # Trace-stream->size = n - 12 # . ecx -= 12 81 5/subop/subtract 3/mod/direct 1/rm32/ecx . . . . . 0xc/imm32 # subtract from ecx # . Trace-stream->size = ecx 89/copy 1/mod/*+disp8 0/rm32/eax . . . 1/r32/ecx 8/disp8 . # copy ecx to *(eax+8) $initialize-trace-stream:end: # . restore registers 59/pop-to-ecx 58/pop-to-eax # . epilogue 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return # Append a string to the given trace stream. # Silently give up if it's already full. Or truncate the string if there isn't enough room. trace: # line: (addr
#!/bin/sh
# Run tests for just a subset of layers.
#
# Usage:
# build_and_test_until [file prefix] [test name]
# Provide the second arg to run just a single test.
set -e
# clean previous builds if they were building until a different layer
touch .until
PREV_UNTIL=`cat .until`
if [ "$PREV_UNTIL" != $1 ]
then
./clean top-level
echo $1 > .until
fi
./build3 --until $1 && ./mu_bin test $2