Rework the tests to run on pc86; lots of test fixes for the brk() test, which

was nearly useless; lots of fixes to qemuppc and pc86 sbrk(), which was broken;
change the pc86 console to echo output to the serial port (needed for running
tests on qemu).
This commit is contained in:
David Given 2016-11-26 11:23:25 +01:00
parent 5f66f06dc6
commit 8a58614aef
21 changed files with 155 additions and 55 deletions

View file

@ -8,6 +8,7 @@ addons:
packages: packages:
- ed - ed
- openbios-ppc - openbios-ppc
- qemu-system-i386
git: git:
depth: 10 depth: 10

View file

@ -15,6 +15,7 @@ vars.plats = {
} }
vars.plats_with_tests = { vars.plats_with_tests = {
"qemuppc", "qemuppc",
"pc86",
} }
local plat_packages = {} local plat_packages = {}

View file

@ -23,7 +23,7 @@
! If you ever need to change the boot code, this needs adjusting. I recommend ! If you ever need to change the boot code, this needs adjusting. I recommend
! a hex editor. ! a hex editor.
PADDING = 0xB7 PADDING = 0xB3
! Some definitions. ! Some definitions.
@ -271,9 +271,12 @@ finished:
! Push standard parameters onto the stack and go. ! Push standard parameters onto the stack and go.
push envp ! envp mov ax, envp
push argv ! argv push ax
push 1 ! argc mov ax, argv
push ax
mov ax, 1
push ax
call __m_a_i_n call __m_a_i_n
! fall through into the exit routine. ! fall through into the exit routine.

View file

@ -37,6 +37,7 @@ extern char** environ;
extern void _exit(int); extern void _exit(int);
extern pid_t getpid(void); extern pid_t getpid(void);
extern int brk(void* addr);
extern void* sbrk(int increment); extern void* sbrk(int increment);
extern int isatty(int d); extern int isatty(int d);
extern off_t lseek(int fildes, off_t offset, int whence); extern off_t lseek(int fildes, off_t offset, int whence);

View file

@ -22,7 +22,10 @@ int brk(void* newend)
if ((p > (&dummy - STACK_BUFFER)) || if ((p > (&dummy - STACK_BUFFER)) ||
(p < _end)) (p < _end))
{
errno = ENOMEM;
return -1; return -1;
}
current = p; current = p;
return 0; return 0;
@ -31,13 +34,26 @@ int brk(void* newend)
void* sbrk(int increment) void* sbrk(int increment)
{ {
char* old; char* old;
char* new;
if (increment == 0) if (increment == 0)
return current; return current;
old = current; old = current;
if (brk(old + increment) < 0)
return OUT_OF_MEMORY; new = old + increment;
if ((increment > 0) && (new <= old))
goto out_of_memory;
else if ((increment < 0) && (new >= old))
goto out_of_memory;
if (brk(new) < 0)
goto out_of_memory;
return old; return old;
out_of_memory:
errno = ENOMEM;
return OUT_OF_MEMORY;
} }

View file

@ -0,0 +1,7 @@
include("tests/plat/build.lua")
plat_testsuite {
name = "tests",
plat = "pc86",
method = "qemu-system-i386"
}

View file

@ -34,13 +34,26 @@ int brk(void* newend)
void* sbrk(int increment) void* sbrk(int increment)
{ {
char* old; char* old;
char* new;
if (increment == 0) if (increment == 0)
return current; return current;
old = current; old = current;
if (brk(old + increment) < 0)
return OUT_OF_MEMORY; new = old + increment;
if ((increment > 0) && (new <= old))
goto out_of_memory;
else if ((increment < 0) && (new >= old))
goto out_of_memory;
if (brk(new) < 0)
goto out_of_memory;
return old; return old;
out_of_memory:
errno = ENOMEM;
return OUT_OF_MEMORY;
} }

View file

@ -6,3 +6,4 @@ void _m_a_i_n(void)
ASSERT(0 == 0); ASSERT(0 == 0);
finished(); finished();
} }

View file

@ -7,9 +7,11 @@
int main(int argc, const char* argv[]) int main(int argc, const char* argv[])
{ {
void* p; char* o;
char* p;
ASSERT(-1 == (intptr_t)brk((void*)0xffffffff)); errno = 0;
ASSERT(-1 == brk((void*)-1));
ASSERT(ENOMEM == errno); ASSERT(ENOMEM == errno);
p = sbrk(0); p = sbrk(0);
@ -19,9 +21,29 @@ int main(int argc, const char* argv[])
ASSERT(p != sbrk(-8)); ASSERT(p != sbrk(-8));
ASSERT(p == sbrk(0)); ASSERT(p == sbrk(0));
/* We assume the test environment has less than 2GB of RAM. */ errno = 0;
ASSERT(-1 == (intptr_t)sbrk(INT_MAX)); o = sbrk(INT_MAX);
ASSERT(-1 == (intptr_t)sbrk(INT_MIN)); if (o == (char*)-1)
ASSERT(ENOMEM == errno);
else
{
ASSERT(0 == errno);
p = sbrk(0);
ASSERT(p > o);
brk(o);
}
errno = 0;
o = sbrk(INT_MIN);
if (o == (char*)-1)
ASSERT(ENOMEM == errno);
else
{
ASSERT(0 == errno);
p = sbrk(0);
ASSERT(p < o);
brk(o);
}
finished(); finished();
} }

View file

@ -14,6 +14,13 @@ definerule("plat_testsuite",
"tests/plat/*.p" "tests/plat/*.p"
) )
acklibrary {
name = "lib",
srcs = { "tests/plat/lib/test.c" },
hdrs = { "tests/plat/lib/test.h" },
vars = { plat = e.plat },
}
local tests = {} local tests = {}
for _, f in ipairs(testfiles) do for _, f in ipairs(testfiles) do
local fs = replace(basename(f), "%..$", "") local fs = replace(basename(f), "%..$", "")
@ -25,7 +32,7 @@ definerule("plat_testsuite",
local bin = ackprogram { local bin = ackprogram {
name = fs.."_bin", name = fs.."_bin",
srcs = { f }, srcs = { f },
deps = { "tests/plat/lib+lib" }, deps = { "+lib" },
vars = { vars = {
plat = e.plat, plat = e.plat,
lang = lang, lang = lang,

View file

@ -1,11 +1,12 @@
#include <limits.h>
#include "test.h" #include "test.h"
/* Constants in globals to defeat constant folding. */ /* Constants in globals to defeat constant folding. */
double one = 1.0; double one = 1.0;
double zero = 0.0; double zero = 0.0;
double minusone = -1.0; double minusone = -1.0;
double big = 2147483647.0; double big = (double)INT_MAX;
double minusbig = -2147483648.0; double minusbig = (double)INT_MIN;
/* Bypasses the CRT, so there's no stdio or BSS initialisation. */ /* Bypasses the CRT, so there's no stdio or BSS initialisation. */
void _m_a_i_n(void) void _m_a_i_n(void)
@ -13,8 +14,8 @@ void _m_a_i_n(void)
ASSERT((int)zero == 0); ASSERT((int)zero == 0);
ASSERT((int)one == 1); ASSERT((int)one == 1);
ASSERT((int)minusone == -1); ASSERT((int)minusone == -1);
ASSERT((int)big == 2147483647); ASSERT((int)big == INT_MAX);
ASSERT((int)minusbig == -2147483648); ASSERT((int)minusbig == INT_MIN);
finished(); finished();
} }

View file

@ -1,16 +1,17 @@
#include <limits.h>
#include "test.h" #include "test.h"
/* Constants in globals to defeat constant folding. */ /* Constants in globals to defeat constant folding. */
double one = 1.0; double one = 1.0;
double zero = 0.0; double zero = 0.0;
double big = 4294967295.0; double big = (double)UINT_MAX;
/* Bypasses the CRT, so there's no stdio or BSS initialisation. */ /* Bypasses the CRT, so there's no stdio or BSS initialisation. */
void _m_a_i_n(void) void _m_a_i_n(void)
{ {
ASSERT((unsigned int)zero == 0); ASSERT((unsigned int)zero == 0);
ASSERT((unsigned int)one == 1); ASSERT((unsigned int)one == 1);
ASSERT((unsigned int)big == 4294967295); ASSERT((unsigned int)big == UINT_MAX);
finished(); finished();
} }

View file

@ -1,11 +1,12 @@
#include <limits.h>
#include "test.h" #include "test.h"
/* Constants in globals to defeat constant folding. */ /* Constants in globals to defeat constant folding. */
int one = 1; int one = 1;
int zero = 0; int zero = 0;
int minusone = -1; int minusone = -1;
int big = 0x7fffffff; int big = INT_MAX;
int minusbig = -0x8000000; int minusbig = INT_MIN;
/* Bypasses the CRT, so there's no stdio or BSS initialisation. */ /* Bypasses the CRT, so there's no stdio or BSS initialisation. */
void _m_a_i_n(void) void _m_a_i_n(void)
@ -13,8 +14,8 @@ void _m_a_i_n(void)
ASSERT((double)zero == 0.0); ASSERT((double)zero == 0.0);
ASSERT((double)one == 1.0); ASSERT((double)one == 1.0);
ASSERT((double)minusone == -1.0); ASSERT((double)minusone == -1.0);
ASSERT((double)big == 2147483647.0); ASSERT((double)big == (double)INT_MAX);
/* ASSERT((double)minusbig == -2147483648.0); FIXME: fails for now */ /* ASSERT((double)minusbig == (double)INT_MIN); FIXME: fails for now */
finished(); finished();
} }

View file

@ -1,16 +1,17 @@
#include <limits.h>
#include "test.h" #include "test.h"
/* Constants in globals to defeat constant folding. */ /* Constants in globals to defeat constant folding. */
unsigned int one_u = 1; unsigned int one_u = 1;
unsigned int zero_u = 0; unsigned int zero_u = 0;
unsigned int big_u = 0xffffffff; unsigned int big_u = UINT_MAX;
/* Bypasses the CRT, so there's no stdio or BSS initialisation. */ /* Bypasses the CRT, so there's no stdio or BSS initialisation. */
void _m_a_i_n(void) void _m_a_i_n(void)
{ {
ASSERT((double)zero_u == 0.0); ASSERT((double)zero_u == 0.0);
ASSERT((double)one_u == 1.0); ASSERT((double)one_u == 1.0);
ASSERT((double)big_u == 4294967295.0); ASSERT((double)big_u == (double)UINT_MAX);
finished(); finished();
} }

View file

@ -1,5 +1,5 @@
# #
mes 2, 4, 4 mes 2, EM_WSIZE, EM_PSIZE
exp $_m_a_i_n exp $_m_a_i_n
pro $_m_a_i_n, 0 pro $_m_a_i_n, 0
@ -10,12 +10,12 @@
rom 0I1, 0I1, 0I1, 0I1 rom 0I1, 0I1, 0I1, 0I1
loe .1 loe .1
loc 1 /* bit number */ loc 1 /* bit number */
inn 4 inn EM_WSIZE
zeq *1 zeq *1
loc __LINE__ loc __LINE__
cal $fail cal $fail
ass 4 ass EM_WSIZE
1 1
/* Test existent bit */ /* Test existent bit */
@ -24,12 +24,12 @@
rom 2I1, 0I1, 0I1, 0I1 rom 2I1, 0I1, 0I1, 0I1
loe .2 loe .2
loc 1 /* bit number */ loc 1 /* bit number */
inn 4 inn EM_WSIZE
zne *2 zne *2
loc __LINE__ loc __LINE__
cal $fail cal $fail
ass 4 ass EM_WSIZE
2 2
/* Test non-existent high bit */ /* Test non-existent high bit */
@ -38,36 +38,44 @@
rom 0I1, 0I1, 0I1, 0I1 rom 0I1, 0I1, 0I1, 0I1
rom 0I1, 0I1, 0I1, 0I1 rom 0I1, 0I1, 0I1, 0I1
.31 .31
rom 33 /* to defeat constant folding */ rom (EM_WSIZE*8)+1 /* to defeat constant folding */
lae .3 lae .3
loi 8 loi EM_WSIZE*2
loe .31 /* bit number */ loe .31 /* bit number */
inn 8 inn EM_WSIZE*2
zeq *3 zeq *3
loc __LINE__ loc __LINE__
cal $fail cal $fail
ass 4 ass EM_WSIZE
3 3
/* Test existent high bit */ /* Test existent high bit */
.4 .4
#if EM_WSIZE == 2
rom 0I1, 0I1
rom 2I1, 0I1
#elif EM_WSIZE == 4
rom 0I1, 0I1, 0I1, 0I1 rom 0I1, 0I1, 0I1, 0I1
rom 2I1, 0I1, 0I1, 0I1 rom 2I1, 0I1, 0I1, 0I1
#else
#error Unknown word size
#endif
.41 .41
rom 33 /* to defeat constant folding */ rom (EM_WSIZE*8)+1 /* to defeat constant folding */
lae .4 lae .4
loi 8 loi EM_WSIZE*2
loe .41 /* bit number */ loe .41 /* bit number */
inn 8 inn EM_WSIZE*2
zne *4 zne *4
loc __LINE__ loc __LINE__
cal $fail cal $fail
ass 4 ass EM_WSIZE
4 4
cal $finished cal $finished

View file

@ -1,3 +1,4 @@
#include <limits.h>
#include "test.h" #include "test.h"
/* Constants in globals to defeat constant folding. */ /* Constants in globals to defeat constant folding. */
@ -25,8 +26,8 @@ void _m_a_i_n(void)
ASSERT(((unsigned int)one >>(unsigned int)zero) == 1); ASSERT(((unsigned int)one >>(unsigned int)zero) == 1);
ASSERT(((unsigned int)one >>(unsigned int)one) == 0); ASSERT(((unsigned int)one >>(unsigned int)one) == 0);
ASSERT(((unsigned int)minusone>>(unsigned int)zero) == 0xffffffff); ASSERT(((unsigned int)minusone>>(unsigned int)zero) == UINT_MAX);
ASSERT(((unsigned int)minusone>>(unsigned int)one) == 0x7fffffff); ASSERT(((unsigned int)minusone>>(unsigned int)one) == (UINT_MAX>>1));
ASSERT((one <<0) == 1); ASSERT((one <<0) == 1);
ASSERT((one <<1) == 2); ASSERT((one <<1) == 2);
@ -45,8 +46,8 @@ void _m_a_i_n(void)
ASSERT(((unsigned int)one >>(unsigned int)0) == 1); ASSERT(((unsigned int)one >>(unsigned int)0) == 1);
ASSERT(((unsigned int)one >>(unsigned int)1) == 0); ASSERT(((unsigned int)one >>(unsigned int)1) == 0);
ASSERT(((unsigned int)minusone>>(unsigned int)0) == 0xffffffff); ASSERT(((unsigned int)minusone>>(unsigned int)0) == UINT_MAX);
ASSERT(((unsigned int)minusone>>(unsigned int)1) == 0x7fffffff); ASSERT(((unsigned int)minusone>>(unsigned int)1) == (UINT_MAX>>1));
finished(); finished();
} }

View file

@ -1,3 +1,4 @@
#include <limits.h>
#include "test.h" #include "test.h"
/* Constants in globals to defeat constant folding. */ /* Constants in globals to defeat constant folding. */
@ -19,13 +20,13 @@ void _m_a_i_n(void)
ASSERT((1 - two) == -1); ASSERT((1 - two) == -1);
ASSERT(((unsigned int)two - (unsigned int)one) == 1); ASSERT(((unsigned int)two - (unsigned int)one) == 1);
ASSERT(((unsigned int)one - (unsigned int)two) == 0xffffffff); ASSERT(((unsigned int)one - (unsigned int)two) == UINT_MAX);
ASSERT(((unsigned int)two - (unsigned int)1) == 1); ASSERT(((unsigned int)two - (unsigned int)1) == 1);
ASSERT(((unsigned int)one - (unsigned int)2) == 0xffffffff); ASSERT(((unsigned int)one - (unsigned int)2) == UINT_MAX);
ASSERT(((unsigned int)2 - (unsigned int)one) == 1); ASSERT(((unsigned int)2 - (unsigned int)one) == 1);
ASSERT(((unsigned int)1 - (unsigned int)two) == 0xffffffff); ASSERT(((unsigned int)1 - (unsigned int)two) == UINT_MAX);
finished(); finished();
} }

View file

@ -4,5 +4,4 @@ acklibrary {
name = "lib", name = "lib",
srcs = { "./test.c" }, srcs = { "./test.c" },
hdrs = { "./test.h" }, hdrs = { "./test.h" },
vars = { plat = "qemuppc" }
} }

View file

@ -25,7 +25,7 @@ void writehex(uint32_t code)
void fail(uint32_t code) void fail(uint32_t code)
{ {
write(1, "@@FAIL on line 0x", 7); write(1, "@@FAIL 0x", 10);
writehex(code); writehex(code);
write(1, "\n", 1); write(1, "\n", 1);
} }

View file

@ -9,6 +9,6 @@ extern void writehex(uint32_t code);
extern void fail(uint32_t code); extern void fail(uint32_t code);
#define ASSERT(condition) \ #define ASSERT(condition) \
if (!(condition)) fail(__LINE__) do { if (!(condition)) fail(__LINE__); } while(0)
#endif #endif

View file

@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
qemu=$1 method=$1
img=$2 img=$2
timeout=$3 timeout=$3
@ -13,10 +13,25 @@ trap "rm -f $result" EXIT
pidfile=/tmp/$$.testdriver.pid pidfile=/tmp/$$.testdriver.pid
trap "rm -f $pidfile" EXIT trap "rm -f $pidfile" EXIT
( $qemu -nographic -kernel $img 2>&1 & echo $! > $pidfile ) \ case $method in
| tee $result \ qemu-system-*)
| ( timeout $timeout grep -l -q @@FINISHED ; echo ) \ if ! hash $method 2>/dev/null; then
| ( read dummy && kill $(cat $pidfile) ) echo "Warning: $method not installed, skipping test"
exit 0
fi
case $method in
qemu-system-i386) img="-drive file=$img,if=floppy,format=raw" ;;
qemu-system-ppc) img="-kernel $img" ;;
esac
( $method -nographic $img 2>&1 & echo $! > $pidfile ) \
| tee $result \
| ( timeout $timeout grep -l -q @@FINISHED ; echo ) \
| ( read dummy && kill $(cat $pidfile) )
;;
esac
( grep -q @@FAIL $result || ! grep -q @@FINISHED $result ) && cat $result && exit 1 ( grep -q @@FAIL $result || ! grep -q @@FINISHED $result ) && cat $result && exit 1
exit 0 exit 0