about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
authorAlastair Reid <adreid@google.com>2020-08-01 14:13:47 +0000
committerMartinNowack <2443641+MartinNowack@users.noreply.github.com>2020-08-28 15:09:18 +0100
commita04538aa72092bab9d255fe0c2e3b08dfad1e4e2 (patch)
tree3948e2873125d65e181573c9d18dc2209a467869
parent729ecede246be700bd483ff47d5462814df08b82 (diff)
downloadklee-a04538aa72092bab9d255fe0c2e3b08dfad1e4e2.tar.gz
Definition of __cxa_thread_atexit_impl for the KLEE libc.
This is a thread-local version of __cxa_atexit (but, in the absence
of threads, it is sufficient to just call __cxa_atexit).

The test is based on the existing test for atexit in
test/Runtime/Uclibc/2008-03-04-libc-atexit-uses-dso-handle.c

The motivation for adding this function is to support the Rust standard
library that calls __cxa_thread_atexit_impl.
This function is usually a weak symbol but, in KLEE, this behaves like a call
to an unknown function and chaos ensues.
Worse, it happens just as the program is cleanly shutting itself down,
so programs that are cleanly exiting crash with the wrong message.
-rw-r--r--runtime/klee-libc/__cxa_atexit.c5
-rw-r--r--test/Runtime/klee-libc/cxa_thread_atexit_impl.c20
2 files changed, 25 insertions, 0 deletions
diff --git a/runtime/klee-libc/__cxa_atexit.c b/runtime/klee-libc/__cxa_atexit.c
index 990b645d..eb0c3e41 100644
--- a/runtime/klee-libc/__cxa_atexit.c
+++ b/runtime/klee-libc/__cxa_atexit.c
@@ -47,3 +47,8 @@ int __cxa_atexit(void (*fn)(void*),
   return 0;
 }
 
+// This variant is part of more recent glibc versions and
+// is required by the Rust standard library
+int __cxa_thread_atexit_impl(void (*fn)(void*), void *arg, void *dso_handle) {
+  return __cxa_atexit(fn, arg, dso_handle);
+}
diff --git a/test/Runtime/klee-libc/cxa_thread_atexit_impl.c b/test/Runtime/klee-libc/cxa_thread_atexit_impl.c
new file mode 100644
index 00000000..18dc7e08
--- /dev/null
+++ b/test/Runtime/klee-libc/cxa_thread_atexit_impl.c
@@ -0,0 +1,20 @@
+// RUN: %clang %s -emit-llvm %O0opt -c -o %t1.bc
+// RUN: rm -rf %t.klee-out
+// RUN: %klee --output-dir=%t.klee-out --exit-on-error --libc=klee %t1.bc
+
+// just make sure __cxa_thread_atexit_impl works ok
+
+#include <assert.h>
+
+extern int __cxa_thread_atexit_impl(void (*)(void*), void*, void *);
+
+static int x; // a global whose address we can take
+
+void boo(void *h) {
+  assert(h == (void*)&x);
+}
+
+int main() {
+  __cxa_thread_atexit_impl(boo, (void*)&x, (void*)0);
+  return 0;
+}