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
--- /dev/null
+../kernel/Makefile
\ No newline at end of file
--- /dev/null
+../kernel/empty.c
\ No newline at end of file
--- /dev/null
+../kernel/one_of_each.c
\ No newline at end of file
--- /dev/null
+../kernel/single_function.c
\ No newline at end of file
--- /dev/null
+../kernel/single_function_gpl.c
\ No newline at end of file
--- /dev/null
+../kernel/single_variable.c
\ No newline at end of file
--- /dev/null
+../kernel/single_variable_gpl.c
\ No newline at end of file
--- /dev/null
+../kernel/Makefile
\ No newline at end of file
--- /dev/null
+../kernel/empty.c
\ No newline at end of file
--- /dev/null
+../kernel/one_of_each.c
\ No newline at end of file
--- /dev/null
+../kernel/single_function.c
\ No newline at end of file
--- /dev/null
+../kernel/single_function_gpl.c
\ No newline at end of file
--- /dev/null
+../kernel/single_variable.c
\ No newline at end of file
--- /dev/null
+../kernel/single_variable_gpl.c
\ No newline at end of file
--- /dev/null
+../kernel/Makefile
\ No newline at end of file
--- /dev/null
+../kernel/empty.c
\ No newline at end of file
--- /dev/null
+../kernel/one_of_each.c
\ No newline at end of file
--- /dev/null
+../kernel/single_function.c
\ No newline at end of file
--- /dev/null
+../kernel/single_function_gpl.c
\ No newline at end of file
--- /dev/null
+../kernel/single_variable.c
\ No newline at end of file
--- /dev/null
+../kernel/single_variable_gpl.c
\ No newline at end of file
--- /dev/null
+../kernel/Makefile
\ No newline at end of file
--- /dev/null
+../kernel/empty.c
\ No newline at end of file
--- /dev/null
+../kernel/one_of_each.c
\ No newline at end of file
--- /dev/null
+../kernel/single_function.c
\ No newline at end of file
--- /dev/null
+../kernel/single_function_gpl.c
\ No newline at end of file
--- /dev/null
+../kernel/single_variable.c
\ No newline at end of file
--- /dev/null
+../kernel/single_variable_gpl.c
\ No newline at end of file
--- /dev/null
+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
--- /dev/null
+#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;
--- /dev/null
+#include <linux/module.h>
+
+void exported_function(void) {}
+EXPORT_SYMBOL(exported_function);
+
+void local_function(void) {}
+int local_variable = 2;
--- /dev/null
+#include <linux/module.h>
+
+void exported_function_gpl(void) {}
+EXPORT_SYMBOL_GPL(exported_function_gpl);
+
+void local_function(void) {}
+int local_variable = 2;
--- /dev/null
+#include <linux/module.h>
+
+int exported_variable = 1;
+EXPORT_SYMBOL(exported_variable);
+
+void local_function(void) {}
+int local_variable = 2;
--- /dev/null
+#include <linux/module.h>
+
+int exported_variable_gpl = 1;
+EXPORT_SYMBOL_GPL(exported_variable_gpl);
+
+void local_function(void) {}
+int local_variable = 2;
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);
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)
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"));
+ }
+ }
+ }
+}