tests: Add kernel symtab test suite

Add (Catch based) test suite to test kernel symbol table (ksymtab)
reading through the result persisted in abigail::corpus.

The test cases are created through simple kernel module C source files
targeting the desired properties ((gpl) exported / local functions /
variables). The kernel binaries are built without debug information to
keep them reasonably small and reproducible. That is just enough
sufficient to analyze ksymtabs. The Makefile that comes with them
recreates the test cases from the sources, given a kernel source tree
with the appropriate version, e.g.

   make KDIR=/path/to/4.14

This covers ksymtab reading and ensuring we detect the kernel binary
correctly. The kernel versions are selected based on features introduced
into the Linux kernel that affect the ksymtab representation.

 - Linux v4.14 - reasonably old kernel to start with (actually v4.14.180)
 - Linux v4.19 - first version having position relative relocations
		 (PREL) in ksymtab entries on some platforms
		 (actually v4.19.123)
 - Linux v5.4  - first version having symbol namespaces (actually v5.4.41)
 - Linux v5.6  - latest released stable kernel as of writing (actually v5.6.13)

	* tests/data/Makefile.am: add new test data for runtestsymtab
	* tests/data/test-symtab/kernel-4.14/Makefile: New test case makefile.
	* tests/data/test-symtab/kernel-4.14/empty.c: Likewise.
	* tests/data/test-symtab/kernel-4.14/one_of_each.c: Likewise.
	* tests/data/test-symtab/kernel-4.14/single_function.c: Likewise.
	* tests/data/test-symtab/kernel-4.14/single_function_gpl.c: Likewise.
	* tests/data/test-symtab/kernel-4.14/single_variable.c: Likewise.
	* tests/data/test-symtab/kernel-4.14/single_variable_gpl.c: Likewise.
	* tests/data/test-symtab/kernel-4.14/empty.ko: New test data.
	* tests/data/test-symtab/kernel-4.14/one_of_each.ko: Likewise.
	* tests/data/test-symtab/kernel-4.14/single_function.ko: Likewise.
	* tests/data/test-symtab/kernel-4.14/single_function_gpl.ko: Likewise.
	* tests/data/test-symtab/kernel-4.14/single_variable.ko: Likewise.
	* tests/data/test-symtab/kernel-4.14/single_variable_gpl.ko: Likewise.
	* tests/data/test-symtab/kernel-4.19/Makefile: New test case makefile.
	* tests/data/test-symtab/kernel-4.19/empty.c: Likewise.
	* tests/data/test-symtab/kernel-4.19/one_of_each.c: Likewise.
	* tests/data/test-symtab/kernel-4.19/single_function.c: Likewise.
	* tests/data/test-symtab/kernel-4.19/single_function_gpl.c: Likewise.
	* tests/data/test-symtab/kernel-4.19/single_variable.c: Likewise.
	* tests/data/test-symtab/kernel-4.19/single_variable_gpl.c: Likewise.
	* tests/data/test-symtab/kernel-4.19/empty.ko: New test data.
	* tests/data/test-symtab/kernel-4.19/one_of_each.ko: Likewise.
	* tests/data/test-symtab/kernel-4.19/single_function.ko: Likewise.
	* tests/data/test-symtab/kernel-4.19/single_function_gpl.ko: Likewise.
	* tests/data/test-symtab/kernel-4.19/single_variable.ko: Likewise.
	* tests/data/test-symtab/kernel-4.19/single_variable_gpl.ko: Likewise.
	* tests/data/test-symtab/kernel-5.4/Makefile: New test case makefile.
	* tests/data/test-symtab/kernel-5.4/empty.c: Likewise.
	* tests/data/test-symtab/kernel-5.4/one_of_each.c: Likewise.
	* tests/data/test-symtab/kernel-5.4/single_function.c: Likewise.
	* tests/data/test-symtab/kernel-5.4/single_function_gpl.c: Likewise.
	* tests/data/test-symtab/kernel-5.4/single_variable.c: Likewise.
	* tests/data/test-symtab/kernel-5.4/single_variable_gpl.c: Likewise.
	* tests/data/test-symtab/kernel-5.4/empty.ko: New test data.
	* tests/data/test-symtab/kernel-5.4/one_of_each.ko: Likewise.
	* tests/data/test-symtab/kernel-5.4/single_function.ko: Likewise.
	* tests/data/test-symtab/kernel-5.4/single_function_gpl.ko: Likewise.
	* tests/data/test-symtab/kernel-5.4/single_variable.ko: Likewise.
	* tests/data/test-symtab/kernel-5.4/single_variable_gpl.ko: Likewise.
	* tests/data/test-symtab/kernel-5.6/Makefile: New test case makefile.
	* tests/data/test-symtab/kernel-5.6/empty.c: Likewise.
	* tests/data/test-symtab/kernel-5.6/one_of_each.c: Likewise.
	* tests/data/test-symtab/kernel-5.6/single_function.c: Likewise.
	* tests/data/test-symtab/kernel-5.6/single_function_gpl.c: Likewise.
	* tests/data/test-symtab/kernel-5.6/single_variable.c: Likewise.
	* tests/data/test-symtab/kernel-5.6/single_variable_gpl.c: Likewise.
	* tests/data/test-symtab/kernel-5.6/empty.ko: New test data.
	* tests/data/test-symtab/kernel-5.6/one_of_each.ko: Likewise.
	* tests/data/test-symtab/kernel-5.6/single_function.ko: Likewise.
	* tests/data/test-symtab/kernel-5.6/single_function_gpl.ko: Likewise.
	* tests/data/test-symtab/kernel-5.6/single_variable.ko: Likewise.
	* tests/data/test-symtab/kernel-5.6/single_variable_gpl.ko: Likewise.
	* tests/data/test-symtab/kernel/Makefile: New test case source file.
	* tests/data/test-symtab/kernel/empty.c: Likewise.
	* tests/data/test-symtab/kernel/one_of_each.c: Likewise.
	* tests/data/test-symtab/kernel/single_function.c: Likewise.
	* tests/data/test-symtab/kernel/single_function_gpl.c: Likewise.
	* tests/data/test-symtab/kernel/single_variable.c: Likewise.
	* tests/data/test-symtab/kernel/single_variable_gpl.c: Likewise.
	* tests/test-symtab.cc: New test case to test kernel symtabs.

Signed-off-by: Matthias Maennich <maennich@google.com>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index f454b85..6592ba3 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -1768,4 +1768,64 @@
 test-symtab/basic/single_undefined_variable.c \
 test-symtab/basic/single_undefined_variable.so \
 test-symtab/basic/single_variable.c \
-test-symtab/basic/single_variable.so
+test-symtab/basic/single_variable.so \
+\
+test-symtab/kernel/Makefile \
+test-symtab/kernel/empty.c \
+test-symtab/kernel/one_of_each.c \
+test-symtab/kernel/single_function.c \
+test-symtab/kernel/single_function_gpl.c \
+test-symtab/kernel/single_variable.c \
+test-symtab/kernel/single_variable_gpl.c \
+test-symtab/kernel-4.14/Makefile \
+test-symtab/kernel-4.14/empty.c \
+test-symtab/kernel-4.14/empty.ko \
+test-symtab/kernel-4.14/one_of_each.c \
+test-symtab/kernel-4.14/one_of_each.ko \
+test-symtab/kernel-4.14/single_function.c \
+test-symtab/kernel-4.14/single_function.ko \
+test-symtab/kernel-4.14/single_function_gpl.c \
+test-symtab/kernel-4.14/single_function_gpl.ko \
+test-symtab/kernel-4.14/single_variable.c \
+test-symtab/kernel-4.14/single_variable.ko \
+test-symtab/kernel-4.14/single_variable_gpl.c \
+test-symtab/kernel-4.14/single_variable_gpl.ko \
+test-symtab/kernel-4.19/Makefile \
+test-symtab/kernel-4.19/empty.c \
+test-symtab/kernel-4.19/empty.ko \
+test-symtab/kernel-4.19/one_of_each.c \
+test-symtab/kernel-4.19/one_of_each.ko \
+test-symtab/kernel-4.19/single_function.c \
+test-symtab/kernel-4.19/single_function.ko \
+test-symtab/kernel-4.19/single_function_gpl.c \
+test-symtab/kernel-4.19/single_function_gpl.ko \
+test-symtab/kernel-4.19/single_variable.c \
+test-symtab/kernel-4.19/single_variable.ko \
+test-symtab/kernel-4.19/single_variable_gpl.c \
+test-symtab/kernel-4.19/single_variable_gpl.ko \
+test-symtab/kernel-5.4/Makefile \
+test-symtab/kernel-5.4/empty.c \
+test-symtab/kernel-5.4/empty.ko \
+test-symtab/kernel-5.4/one_of_each.c \
+test-symtab/kernel-5.4/one_of_each.ko \
+test-symtab/kernel-5.4/single_function.c \
+test-symtab/kernel-5.4/single_function.ko \
+test-symtab/kernel-5.4/single_function_gpl.c \
+test-symtab/kernel-5.4/single_function_gpl.ko \
+test-symtab/kernel-5.4/single_variable.c \
+test-symtab/kernel-5.4/single_variable.ko \
+test-symtab/kernel-5.4/single_variable_gpl.c \
+test-symtab/kernel-5.4/single_variable_gpl.ko \
+test-symtab/kernel-5.6/Makefile \
+test-symtab/kernel-5.6/empty.c \
+test-symtab/kernel-5.6/empty.ko \
+test-symtab/kernel-5.6/one_of_each.c \
+test-symtab/kernel-5.6/one_of_each.ko \
+test-symtab/kernel-5.6/single_function.c \
+test-symtab/kernel-5.6/single_function.ko \
+test-symtab/kernel-5.6/single_function_gpl.c \
+test-symtab/kernel-5.6/single_function_gpl.ko \
+test-symtab/kernel-5.6/single_variable.c \
+test-symtab/kernel-5.6/single_variable.ko \
+test-symtab/kernel-5.6/single_variable_gpl.c \
+test-symtab/kernel-5.6/single_variable_gpl.ko
diff --git a/tests/data/test-symtab/kernel-4.14/Makefile b/tests/data/test-symtab/kernel-4.14/Makefile
new file mode 120000
index 0000000..c7e68bd
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.14/Makefile
@@ -0,0 +1 @@
+../kernel/Makefile
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-4.14/empty.c b/tests/data/test-symtab/kernel-4.14/empty.c
new file mode 120000
index 0000000..ac07d5e
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.14/empty.c
@@ -0,0 +1 @@
+../kernel/empty.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-4.14/empty.ko b/tests/data/test-symtab/kernel-4.14/empty.ko
new file mode 100644
index 0000000..03f62bb
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.14/empty.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-4.14/one_of_each.c b/tests/data/test-symtab/kernel-4.14/one_of_each.c
new file mode 120000
index 0000000..27c87e5
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.14/one_of_each.c
@@ -0,0 +1 @@
+../kernel/one_of_each.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-4.14/one_of_each.ko b/tests/data/test-symtab/kernel-4.14/one_of_each.ko
new file mode 100644
index 0000000..6c5fe2b
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.14/one_of_each.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-4.14/single_function.c b/tests/data/test-symtab/kernel-4.14/single_function.c
new file mode 120000
index 0000000..a005553
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.14/single_function.c
@@ -0,0 +1 @@
+../kernel/single_function.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-4.14/single_function.ko b/tests/data/test-symtab/kernel-4.14/single_function.ko
new file mode 100644
index 0000000..bfa2e2c
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.14/single_function.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-4.14/single_function_gpl.c b/tests/data/test-symtab/kernel-4.14/single_function_gpl.c
new file mode 120000
index 0000000..3f9b47f
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.14/single_function_gpl.c
@@ -0,0 +1 @@
+../kernel/single_function_gpl.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-4.14/single_function_gpl.ko b/tests/data/test-symtab/kernel-4.14/single_function_gpl.ko
new file mode 100644
index 0000000..b05ec4d
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.14/single_function_gpl.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-4.14/single_variable.c b/tests/data/test-symtab/kernel-4.14/single_variable.c
new file mode 120000
index 0000000..196fb4c
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.14/single_variable.c
@@ -0,0 +1 @@
+../kernel/single_variable.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-4.14/single_variable.ko b/tests/data/test-symtab/kernel-4.14/single_variable.ko
new file mode 100644
index 0000000..73ba479
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.14/single_variable.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-4.14/single_variable_gpl.c b/tests/data/test-symtab/kernel-4.14/single_variable_gpl.c
new file mode 120000
index 0000000..dc09c0d
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.14/single_variable_gpl.c
@@ -0,0 +1 @@
+../kernel/single_variable_gpl.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-4.14/single_variable_gpl.ko b/tests/data/test-symtab/kernel-4.14/single_variable_gpl.ko
new file mode 100644
index 0000000..30f9a08
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.14/single_variable_gpl.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-4.19/Makefile b/tests/data/test-symtab/kernel-4.19/Makefile
new file mode 120000
index 0000000..c7e68bd
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.19/Makefile
@@ -0,0 +1 @@
+../kernel/Makefile
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-4.19/empty.c b/tests/data/test-symtab/kernel-4.19/empty.c
new file mode 120000
index 0000000..ac07d5e
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.19/empty.c
@@ -0,0 +1 @@
+../kernel/empty.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-4.19/empty.ko b/tests/data/test-symtab/kernel-4.19/empty.ko
new file mode 100644
index 0000000..e765154
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.19/empty.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-4.19/one_of_each.c b/tests/data/test-symtab/kernel-4.19/one_of_each.c
new file mode 120000
index 0000000..27c87e5
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.19/one_of_each.c
@@ -0,0 +1 @@
+../kernel/one_of_each.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-4.19/one_of_each.ko b/tests/data/test-symtab/kernel-4.19/one_of_each.ko
new file mode 100644
index 0000000..293d07e
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.19/one_of_each.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-4.19/single_function.c b/tests/data/test-symtab/kernel-4.19/single_function.c
new file mode 120000
index 0000000..a005553
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.19/single_function.c
@@ -0,0 +1 @@
+../kernel/single_function.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-4.19/single_function.ko b/tests/data/test-symtab/kernel-4.19/single_function.ko
new file mode 100644
index 0000000..890b125
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.19/single_function.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-4.19/single_function_gpl.c b/tests/data/test-symtab/kernel-4.19/single_function_gpl.c
new file mode 120000
index 0000000..3f9b47f
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.19/single_function_gpl.c
@@ -0,0 +1 @@
+../kernel/single_function_gpl.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-4.19/single_function_gpl.ko b/tests/data/test-symtab/kernel-4.19/single_function_gpl.ko
new file mode 100644
index 0000000..2378325
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.19/single_function_gpl.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-4.19/single_variable.c b/tests/data/test-symtab/kernel-4.19/single_variable.c
new file mode 120000
index 0000000..196fb4c
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.19/single_variable.c
@@ -0,0 +1 @@
+../kernel/single_variable.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-4.19/single_variable.ko b/tests/data/test-symtab/kernel-4.19/single_variable.ko
new file mode 100644
index 0000000..cc81fd9
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.19/single_variable.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-4.19/single_variable_gpl.c b/tests/data/test-symtab/kernel-4.19/single_variable_gpl.c
new file mode 120000
index 0000000..dc09c0d
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.19/single_variable_gpl.c
@@ -0,0 +1 @@
+../kernel/single_variable_gpl.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-4.19/single_variable_gpl.ko b/tests/data/test-symtab/kernel-4.19/single_variable_gpl.ko
new file mode 100644
index 0000000..e574265
--- /dev/null
+++ b/tests/data/test-symtab/kernel-4.19/single_variable_gpl.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-5.4/Makefile b/tests/data/test-symtab/kernel-5.4/Makefile
new file mode 120000
index 0000000..c7e68bd
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.4/Makefile
@@ -0,0 +1 @@
+../kernel/Makefile
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-5.4/empty.c b/tests/data/test-symtab/kernel-5.4/empty.c
new file mode 120000
index 0000000..ac07d5e
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.4/empty.c
@@ -0,0 +1 @@
+../kernel/empty.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-5.4/empty.ko b/tests/data/test-symtab/kernel-5.4/empty.ko
new file mode 100644
index 0000000..6a0769e
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.4/empty.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-5.4/one_of_each.c b/tests/data/test-symtab/kernel-5.4/one_of_each.c
new file mode 120000
index 0000000..27c87e5
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.4/one_of_each.c
@@ -0,0 +1 @@
+../kernel/one_of_each.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-5.4/one_of_each.ko b/tests/data/test-symtab/kernel-5.4/one_of_each.ko
new file mode 100644
index 0000000..2a6e422
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.4/one_of_each.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-5.4/single_function.c b/tests/data/test-symtab/kernel-5.4/single_function.c
new file mode 120000
index 0000000..a005553
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.4/single_function.c
@@ -0,0 +1 @@
+../kernel/single_function.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-5.4/single_function.ko b/tests/data/test-symtab/kernel-5.4/single_function.ko
new file mode 100644
index 0000000..84d1d15
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.4/single_function.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-5.4/single_function_gpl.c b/tests/data/test-symtab/kernel-5.4/single_function_gpl.c
new file mode 120000
index 0000000..3f9b47f
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.4/single_function_gpl.c
@@ -0,0 +1 @@
+../kernel/single_function_gpl.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-5.4/single_function_gpl.ko b/tests/data/test-symtab/kernel-5.4/single_function_gpl.ko
new file mode 100644
index 0000000..d518def
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.4/single_function_gpl.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-5.4/single_variable.c b/tests/data/test-symtab/kernel-5.4/single_variable.c
new file mode 120000
index 0000000..196fb4c
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.4/single_variable.c
@@ -0,0 +1 @@
+../kernel/single_variable.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-5.4/single_variable.ko b/tests/data/test-symtab/kernel-5.4/single_variable.ko
new file mode 100644
index 0000000..d62235e
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.4/single_variable.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-5.4/single_variable_gpl.c b/tests/data/test-symtab/kernel-5.4/single_variable_gpl.c
new file mode 120000
index 0000000..dc09c0d
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.4/single_variable_gpl.c
@@ -0,0 +1 @@
+../kernel/single_variable_gpl.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-5.4/single_variable_gpl.ko b/tests/data/test-symtab/kernel-5.4/single_variable_gpl.ko
new file mode 100644
index 0000000..cdbd6a7
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.4/single_variable_gpl.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-5.6/Makefile b/tests/data/test-symtab/kernel-5.6/Makefile
new file mode 120000
index 0000000..c7e68bd
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.6/Makefile
@@ -0,0 +1 @@
+../kernel/Makefile
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-5.6/empty.c b/tests/data/test-symtab/kernel-5.6/empty.c
new file mode 120000
index 0000000..ac07d5e
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.6/empty.c
@@ -0,0 +1 @@
+../kernel/empty.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-5.6/empty.ko b/tests/data/test-symtab/kernel-5.6/empty.ko
new file mode 100644
index 0000000..265d7ea
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.6/empty.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-5.6/one_of_each.c b/tests/data/test-symtab/kernel-5.6/one_of_each.c
new file mode 120000
index 0000000..27c87e5
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.6/one_of_each.c
@@ -0,0 +1 @@
+../kernel/one_of_each.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-5.6/one_of_each.ko b/tests/data/test-symtab/kernel-5.6/one_of_each.ko
new file mode 100644
index 0000000..72bb8e1
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.6/one_of_each.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-5.6/single_function.c b/tests/data/test-symtab/kernel-5.6/single_function.c
new file mode 120000
index 0000000..a005553
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.6/single_function.c
@@ -0,0 +1 @@
+../kernel/single_function.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-5.6/single_function.ko b/tests/data/test-symtab/kernel-5.6/single_function.ko
new file mode 100644
index 0000000..28e4081
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.6/single_function.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-5.6/single_function_gpl.c b/tests/data/test-symtab/kernel-5.6/single_function_gpl.c
new file mode 120000
index 0000000..3f9b47f
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.6/single_function_gpl.c
@@ -0,0 +1 @@
+../kernel/single_function_gpl.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-5.6/single_function_gpl.ko b/tests/data/test-symtab/kernel-5.6/single_function_gpl.ko
new file mode 100644
index 0000000..d5643b5
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.6/single_function_gpl.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-5.6/single_variable.c b/tests/data/test-symtab/kernel-5.6/single_variable.c
new file mode 120000
index 0000000..196fb4c
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.6/single_variable.c
@@ -0,0 +1 @@
+../kernel/single_variable.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-5.6/single_variable.ko b/tests/data/test-symtab/kernel-5.6/single_variable.ko
new file mode 100644
index 0000000..a3d71e6
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.6/single_variable.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel-5.6/single_variable_gpl.c b/tests/data/test-symtab/kernel-5.6/single_variable_gpl.c
new file mode 120000
index 0000000..dc09c0d
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.6/single_variable_gpl.c
@@ -0,0 +1 @@
+../kernel/single_variable_gpl.c
\ No newline at end of file
diff --git a/tests/data/test-symtab/kernel-5.6/single_variable_gpl.ko b/tests/data/test-symtab/kernel-5.6/single_variable_gpl.ko
new file mode 100644
index 0000000..a2142a6
--- /dev/null
+++ b/tests/data/test-symtab/kernel-5.6/single_variable_gpl.ko
Binary files differ
diff --git a/tests/data/test-symtab/kernel/Makefile b/tests/data/test-symtab/kernel/Makefile
new file mode 100644
index 0000000..223db45
--- /dev/null
+++ b/tests/data/test-symtab/kernel/Makefile
@@ -0,0 +1,19 @@
+obj-m += empty.o
+obj-m += single_function.o
+obj-m += single_function_gpl.o
+obj-m += single_variable.o
+obj-m += single_variable_gpl.o
+obj-m += one_of_each.o
+
+KDIR := /tmp/some/kernel/source/dir
+
+PWD := $(shell pwd)
+default:
+	make -C $(KDIR) tinyconfig
+	pushd $(KDIR); ./scripts/config -e 64BIT -e MODULES; $(MAKE) olddefconfig; popd
+	$(MAKE) -C $(KDIR)
+	$(MAKE) -C $(KDIR) M=$(PWD) modules
+	rm -rf *.mod.c *.o .*.cmd .*.d *.mod modules.order Module.symvers .tmp_versions
+
+clean:
+	rm *.ko
diff --git a/tests/data/test-symtab/kernel/empty.c b/tests/data/test-symtab/kernel/empty.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/data/test-symtab/kernel/empty.c
diff --git a/tests/data/test-symtab/kernel/one_of_each.c b/tests/data/test-symtab/kernel/one_of_each.c
new file mode 100644
index 0000000..9d461fb
--- /dev/null
+++ b/tests/data/test-symtab/kernel/one_of_each.c
@@ -0,0 +1,16 @@
+#include <linux/module.h>
+
+void exported_function(void) {}
+EXPORT_SYMBOL(exported_function);
+
+void exported_function_gpl(void) {}
+EXPORT_SYMBOL_GPL(exported_function_gpl);
+
+int exported_variable = 1;
+EXPORT_SYMBOL(exported_variable);
+
+int exported_variable_gpl = 1;
+EXPORT_SYMBOL_GPL(exported_variable_gpl);
+
+void local_function(void) {}
+int local_variable = 2;
diff --git a/tests/data/test-symtab/kernel/single_function.c b/tests/data/test-symtab/kernel/single_function.c
new file mode 100644
index 0000000..5160865
--- /dev/null
+++ b/tests/data/test-symtab/kernel/single_function.c
@@ -0,0 +1,7 @@
+#include <linux/module.h>
+
+void exported_function(void) {}
+EXPORT_SYMBOL(exported_function);
+
+void local_function(void) {}
+int local_variable = 2;
diff --git a/tests/data/test-symtab/kernel/single_function_gpl.c b/tests/data/test-symtab/kernel/single_function_gpl.c
new file mode 100644
index 0000000..fb5503a
--- /dev/null
+++ b/tests/data/test-symtab/kernel/single_function_gpl.c
@@ -0,0 +1,7 @@
+#include <linux/module.h>
+
+void exported_function_gpl(void) {}
+EXPORT_SYMBOL_GPL(exported_function_gpl);
+
+void local_function(void) {}
+int local_variable = 2;
diff --git a/tests/data/test-symtab/kernel/single_variable.c b/tests/data/test-symtab/kernel/single_variable.c
new file mode 100644
index 0000000..20178f2
--- /dev/null
+++ b/tests/data/test-symtab/kernel/single_variable.c
@@ -0,0 +1,7 @@
+#include <linux/module.h>
+
+int exported_variable = 1;
+EXPORT_SYMBOL(exported_variable);
+
+void local_function(void) {}
+int local_variable = 2;
diff --git a/tests/data/test-symtab/kernel/single_variable_gpl.c b/tests/data/test-symtab/kernel/single_variable_gpl.c
new file mode 100644
index 0000000..552e9b5
--- /dev/null
+++ b/tests/data/test-symtab/kernel/single_variable_gpl.c
@@ -0,0 +1,7 @@
+#include <linux/module.h>
+
+int exported_variable_gpl = 1;
+EXPORT_SYMBOL_GPL(exported_variable_gpl);
+
+void local_function(void) {}
+int local_variable = 2;
diff --git a/tests/test-symtab.cc b/tests/test-symtab.cc
index 62f8998..20e3071 100644
--- a/tests/test-symtab.cc
+++ b/tests/test-symtab.cc
@@ -52,8 +52,9 @@
 
   environment_sptr	    env(new environment);
   const std::vector<char**> debug_info_root_paths;
-  read_context_sptr	    ctxt =
-      create_read_context(absolute_path, debug_info_root_paths, env.get());
+  read_context_sptr	    ctxt = create_read_context(
+      absolute_path, debug_info_root_paths, env.get(),
+      /* load_all_type = */ true, /* linux_kernel_mode = */ true);
 
   dwarf_reader::status status = dwarf_reader::STATUS_UNKNOWN;
   result = read_corpus_from_elf(*ctxt, status);
@@ -105,7 +106,7 @@
   const dwarf_reader::status status = read_corpus(path, corpus_ptr);
   REQUIRE(corpus_ptr);
 
-  REQUIRE(status == dwarf_reader::STATUS_OK);
+  REQUIRE((status & dwarf_reader::STATUS_OK));
   const corpus& corpus = *corpus_ptr;
 
   if (function_symbols != N)
@@ -203,3 +204,90 @@
     const corpus_sptr& corpus = assert_symbol_count(binary, 0, 0, 1, 1);
   }
 }
+
+static const char* kernel_versions[] = { "4.14", "4.19", "5.4", "5.6" };
+static const size_t nr_kernel_versions =
+    sizeof(kernel_versions) / sizeof(kernel_versions[0]);
+
+TEST_CASE("Symtab::SimpleKernelSymtabs", "[symtab, basic, kernel, ksymtab]")
+{
+  for (size_t i = 0; i < nr_kernel_versions; ++i)
+    {
+      const std::string base_path =
+	  "kernel-" + std::string(kernel_versions[i]) + "/";
+
+      GIVEN("The binaries in " + base_path)
+      {
+
+	GIVEN("a kernel module with no exported symbols")
+	{
+	  // TODO: should pass, but does currently not as empty tables are
+	  // treated
+	  //       like the error case, but this is an edge case anyway.
+	  // assert_symbol_count(base_path + "empty.so");
+	}
+
+	GIVEN("a kernel module with a single exported function")
+	{
+	  const std::string	 binary = base_path + "single_function.ko";
+	  const corpus_sptr&	 corpus = assert_symbol_count(binary, 1, 0);
+	  const elf_symbol_sptr& symbol =
+	      corpus->lookup_function_symbol("exported_function");
+	  REQUIRE(symbol);
+	  CHECK(!corpus->lookup_variable_symbol("exported_function"));
+	  CHECK(symbol == corpus->lookup_function_symbol(*symbol));
+	  CHECK(symbol != corpus->lookup_variable_symbol(*symbol));
+	}
+
+	GIVEN("a kernel module with a single GPL exported function")
+	{
+	  const std::string	 binary = base_path + "single_function_gpl.ko";
+	  const corpus_sptr&	 corpus = assert_symbol_count(binary, 1, 0);
+	  const elf_symbol_sptr& symbol =
+	      corpus->lookup_function_symbol("exported_function_gpl");
+	  REQUIRE(symbol);
+	  CHECK(!corpus->lookup_variable_symbol("exported_function_gpl"));
+	  CHECK(symbol == corpus->lookup_function_symbol(*symbol));
+	  CHECK(symbol != corpus->lookup_variable_symbol(*symbol));
+	}
+
+	GIVEN("a binary with a single exported variable")
+	{
+	  const std::string	 binary = base_path + "single_variable.ko";
+	  const corpus_sptr&	 corpus = assert_symbol_count(binary, 0, 1);
+	  const elf_symbol_sptr& symbol =
+	      corpus->lookup_variable_symbol("exported_variable");
+	  REQUIRE(symbol);
+	  CHECK(!corpus->lookup_function_symbol("exported_variable"));
+	  CHECK(symbol == corpus->lookup_variable_symbol(*symbol));
+	  CHECK(symbol != corpus->lookup_function_symbol(*symbol));
+	}
+
+	GIVEN("a binary with a single GPL exported variable")
+	{
+	  const std::string	 binary = base_path + "single_variable_gpl.ko";
+	  const corpus_sptr&	 corpus = assert_symbol_count(binary, 0, 1);
+	  const elf_symbol_sptr& symbol =
+	      corpus->lookup_variable_symbol("exported_variable_gpl");
+	  REQUIRE(symbol);
+	  CHECK(!corpus->lookup_function_symbol("exported_variable_gpl"));
+	  CHECK(symbol == corpus->lookup_variable_symbol(*symbol));
+	  CHECK(symbol != corpus->lookup_function_symbol(*symbol));
+	}
+
+	GIVEN("a binary with one function and one variable (GPL) exported")
+	{
+	  const std::string  binary = base_path + "one_of_each.ko";
+	  const corpus_sptr& corpus = assert_symbol_count(binary, 2, 2);
+	  CHECK(corpus->lookup_function_symbol("exported_function"));
+	  CHECK(!corpus->lookup_variable_symbol("exported_function"));
+	  CHECK(corpus->lookup_function_symbol("exported_function_gpl"));
+	  CHECK(!corpus->lookup_variable_symbol("exported_function_gpl"));
+	  CHECK(corpus->lookup_variable_symbol("exported_variable"));
+	  CHECK(!corpus->lookup_function_symbol("exported_variable"));
+	  CHECK(corpus->lookup_variable_symbol("exported_variable_gpl"));
+	  CHECK(!corpus->lookup_function_symbol("exported_variable_gpl"));
+	}
+      }
+    }
+}