Browse Source

Add tests for dynamic linker

Mateusz Tabaka 4 years ago
parent
commit
675101ac0e

+ 2 - 1
tests/.gitignore

@@ -1,3 +1,4 @@
-/bins/
+/bins_static/
+/bins_dynamic/
 /gen/
 /*.out

+ 68 - 40
tests/Makefile

@@ -6,43 +6,33 @@ EXPECT_NAMES=\
 	assert \
 	constructor \
 	ctype \
-	destructor \
 	dirent/scandir \
 	errno \
 	error \
 	fcntl/create \
 	fcntl/fcntl \
 	fnmatch \
-	futimens \
 	libgen \
 	locale \
 	math \
 	netdb/getaddrinfo \
-	netdb/netdb \
 	ptrace \
 	regex \
 	select \
 	setjmp \
 	sigaction \
 	signal \
-	stdio/all \
-	stdio/buffer \
-	stdio/fgets \
 	stdio/fputs \
 	stdio/fread \
-	stdio/freopen \
 	stdio/fseek \
 	stdio/fwrite \
-	stdio/getc_unget \
 	stdio/mutex \
 	stdio/popen \
 	stdio/printf \
 	stdio/rename \
 	stdio/scanf \
-	stdio/setvbuf \
 	stdio/sprintf \
 	stdio/printf_space_pad \
-	stdio/ungetc_multiple \
 	stdio/ungetc_ftell \
 	stdio/fscanf_offby1 \
 	stdio/fscanf \
@@ -79,12 +69,10 @@ EXPECT_NAMES=\
 	sys_mman \
 	time/asctime \
 	time/gmtime \
-	time/localtime \
 	time/macros \
 	time/mktime \
 	time/strftime \
 	time/time \
-	tls \
 	unistd/access \
 	unistd/brk \
 	unistd/dup \
@@ -93,8 +81,6 @@ EXPECT_NAMES=\
 	unistd/fork \
 	unistd/fsync \
 	unistd/ftruncate \
-	unistd/getopt \
-	unistd/getopt_long \
 	unistd/pipe \
 	unistd/rmdir \
 	unistd/sleep \
@@ -111,14 +97,37 @@ EXPECT_NAMES=\
 	wchar/wcsrchr \
 	wchar/wcsstr \
 	wchar/wcstod \
-	wchar/wcstok \
 	wchar/wcstol \
 	wchar/wcscasecmp \
 	wchar/wcsncasecmp \
-	wctype/towlower \
-	wctype/towupper
 	# TODO: Fix these
 	# mkfifo
+	# netdb/netdb \
+
+# issues with linking stdin, stdout, stderr
+STATIC_ONLY_NAMES=\
+	futimens \
+	stdio/all \
+	stdio/buffer \
+	stdio/fgets \
+	stdio/freopen \
+	stdio/getc_unget \
+	stdio/setvbuf \
+	stdio/ungetc_multiple \
+	time/localtime \
+	wchar/wcstok \
+	wctype/towlower \
+	wctype/towupper \
+# need to call fini in ld_so's _start
+STATIC_ONLY_NAMES+=\
+	destructor \
+# comparison issue
+STATIC_ONLY_NAMES+=\
+	tls \
+# issues with linking optarg, optind etc.
+STATIC_ONLY_NAMES+=\
+	unistd/getopt \
+	unistd/getopt_long \
 
 # Binaries that may generate varied output
 NAMES=\
@@ -147,8 +156,12 @@ NAMES=\
 #	resource/getrusage
 #	time/times
 
-BINS=$(patsubst %,bins/%,$(NAMES))
-EXPECT_BINS=$(patsubst %,bins/%,$(EXPECT_NAMES))
+BINS=$(patsubst %,bins_static/%,$(NAMES))
+BINS+=$(patsubst %,bins_static/%,$(STATIC_ONLY_NAMES))
+BINS+=$(patsubst %,bins_dynamic/%,$(NAMES))
+EXPECT_BINS=$(patsubst %,bins_static/%,$(EXPECT_NAMES))
+EXPECT_BINS+=$(patsubst %,bins_static/%,$(STATIC_ONLY_NAMES))
+EXPECT_BINS+=$(patsubst %,bins_dynamic/%,$(EXPECT_NAMES))
 
 TEST_RUNNER?=sh --
 
@@ -157,61 +170,76 @@ TEST_RUNNER?=sh --
 all: $(BINS)
 
 clean:
-	rm -rf bins gen *.out
+	rm -rf bins_* gen *.out
 
 run: | $(BINS)
-	for name in $(NAMES); \
+	for bin in $(BINS); \
 	do \
-		echo "# $${name} #"; \
-		"bins/$${name}" test args || exit $$?; \
+		echo "# $${bin} #"; \
+		"$${bin}" test args || exit $$?; \
 	done
 
 expected: | $(EXPECT_BINS)
 	rm -rf expected
 	mkdir -p expected
-	for name in $(EXPECT_NAMES); \
+	for bin in $(EXPECT_BINS); \
 	do \
-		echo "# $${name} #"; \
-		mkdir -p expected/`dirname $${name}`; \
-		"bins/$${name}" test args > "expected/$${name}.stdout" 2> "expected/$${name}.stderr" || exit $$?; \
+		echo "# $${bin} #"; \
+		mkdir -p expected/`dirname $${bin}`; \
+		"$${bin}" test args > "expected/$${bin}.stdout" 2> "expected/$${bin}.stderr" || exit $$?; \
 	done
 
 verify: | $(EXPECT_BINS)
-	$(TEST_RUNNER) ./verify.sh $(EXPECT_NAMES)
+	$(TEST_RUNNER) ./verify.sh $(EXPECT_BINS)
 
-CFLAGS=\
+FLAGS=\
 	-std=c11 \
 	-fno-builtin \
 	-fno-stack-protector \
-	-static \
 	-Wall \
 	-pedantic \
 	-g \
 	-I .
 
-LIBS=
+STATIC_FLAGS=\
+	../sysroot/lib/libc.a \
+	-static
 
 NATIVE_RELIBC?=0
 ifeq ($(NATIVE_RELIBC),0)
-CFLAGS+=\
+FLAGS+=\
 	-nostdinc \
 	-nostdlib \
 	-isystem ../sysroot/include \
 	../sysroot/lib/crt0.o \
-	../sysroot/lib/crti.o
-
-LIBS=\
-	../sysroot/lib/libc.a \
+	../sysroot/lib/crti.o \
 	../sysroot/lib/crtn.o
 
 ../sysroot:
 	$(MAKE) -C .. sysroot
 
-bins/%: %.c ../sysroot
+bins_static/%: %.c ../sysroot
+	mkdir -p "$$(dirname "$@")"
+	$(CC) "$<" -o "$@" $(FLAGS) $(STATIC_FLAGS)
+
+SYSROOT_LIB=$(shell realpath ../sysroot/lib/)
+
+DYNAMIC_FLAGS=\
+	-Wl,-dynamic-linker=$(SYSROOT_LIB)/ld64.so.1 \
+	-Wl,--enable-new-dtags \
+	-Wl,-rpath=$(SYSROOT_LIB) \
+	-L $(SYSROOT_LIB) \
+	-lc
+
+bins_dynamic/%: %.c ../sysroot
 	mkdir -p "$$(dirname "$@")"
-	$(CC) $(CFLAGS) "$<" $(LIBS) -o "$@"
+	$(CC) "$<" -o "$@" $(FLAGS) $(DYNAMIC_FLAGS)
 else
-bins/%: %.c
+bins_static/%: %.c
+	mkdir -p "$$(dirname "$@")"
+	$(CC) "$<" -o "$@" $(FLAGS) $(STATIC_FLAGS)
+
+bins_dynamic/%: %.c
 	mkdir -p "$$(dirname "$@")"
-	$(CC) $(CFLAGS) "$<" $(LIBS) -o "$@"
+	$(CC) "$<" -o "$@" $(FLAGS)
 endif

+ 0 - 1
tests/expected/args.stdout

@@ -1 +0,0 @@
-bins/args test args 

+ 0 - 0
tests/expected/args.stderr → tests/expected/bins_dynamic/args.stderr


+ 1 - 0
tests/expected/bins_dynamic/args.stdout

@@ -0,0 +1 @@
+bins_dynamic/args test args 

+ 0 - 0
tests/expected/errno.stderr → tests/expected/bins_dynamic/errno.stderr


+ 4 - 0
tests/expected/bins_dynamic/errno.stdout

@@ -0,0 +1,4 @@
+bins_dynamic/errno
+bins_dynamic/errno
+yes, you can change this
+yes, you can change this

+ 0 - 0
tests/expected/bins_static/args.stderr


+ 1 - 0
tests/expected/bins_static/args.stdout

@@ -0,0 +1 @@
+bins_static/args test args 

+ 0 - 0
tests/expected/bins_static/errno.stderr


+ 2 - 2
tests/expected/errno.stdout → tests/expected/bins_static/errno.stdout

@@ -1,4 +1,4 @@
-bins/errno
-bins/errno
+bins_static/errno
+bins_static/errno
 yes, you can change this
 yes, you can change this

+ 35 - 16
tests/verify.sh

@@ -3,42 +3,61 @@
 rm -rf gen || exit 1
 mkdir -p gen || exit 1
 
+summary=""
+
 while [ "$#" -gt 0 ]
 do
-    name="$1"
+    bin="$1"
     shift
 
-	echo "# ${name} #"
-	mkdir -p "gen/$(dirname ${name})" || exit 1
+    echo "# ${bin} #"
+    mkdir -p "gen/$(dirname ${bin})" || exit 1
 
-	"bins/${name}" test args > "gen/${name}.stdout" 2> "gen/${name}.stderr"
-    status="$?"
+    "${bin}" test args > "gen/${bin}.stdout" 2> "gen/${bin}.stderr"
+    retcode="$?"
+    status=""
 
     for output in stdout stderr
     do
-        gen="$(sha256sum "gen/${name}.${output}" | cut -d " " -f 1)"
-        expected="$(sha256sum "expected/${name}.${output}" | cut -d " " -f 1)"
+        gen="$(sha256sum "gen/${bin}.${output}" | cut -d " " -f 1)"
+
+        # look for expected output file that is specific to binary type (either static or dynamic)
+        expected_file="expected/${bin}.${output}"
+        if [ ! -e $expected_file ]
+        then
+            # if unable to find above, the expected output file is the same to both static and dynamic binary
+            name=$(echo $bin | cut -d "/" -f2-)
+            expected_file="expected/${name}.${output}"
+        fi
+        expected="$(sha256sum "${expected_file}" | cut -d " " -f 1)"
         if [ "${gen}" != "${expected}" ]
         then
-            echo "# ${name}: ${output}: expected #"
-            cat "expected/${name}.${output}"
+            echo "# ${bin}: ${output}: expected #"
+            cat "${expected_file}"
 
-            echo "# ${name}: ${output}: generated #"
-            cat "gen/${name}.${output}"
+            echo "# ${bin}: ${output}: generated #"
+            cat "gen/${bin}.${output}"
 
             # FIXME: Make diff available on Redox
             if [ $(uname) != "Redox" ]
             then
-                echo "# ${name}: ${output}: diff #"
-                diff --color -u "expected/${name}.${output}" "gen/${name}.${output}"
+                echo "# ${bin}: ${output}: diff #"
+                diff --color -u "${expected_file}" "gen/${bin}.${output}"
             fi
 
-            status="${status}, ${output} mismatch"
+            status="${bin} failed - retcode ${retcode}, ${output} mismatch"
+            summary="${summary}${status}\n"
         fi
     done
 
-    if [ "${status}" != "0" ]
+    if [ -n "${status}" ]
     then
-        echo "# ${name}: failed with status ${status} #"
+        echo "# ${status} #"
     fi
 done
+
+if [ -n "$summary" ]
+then
+    echo -e "$summary"
+    exit 1
+fi