[PATCH] Enable sanitizers' libc dependencies on FreeBSD
Viktor Kutuzov
vkutuzov at accesssoftek.com
Thu Mar 6 04:15:16 PST 2014
Refactored as suggested.
Hi kcc, samsonov,
http://llvm-reviews.chandlerc.com/D2938
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D2938?vs=7503&id=7594#toc
Files:
lib/sanitizer_common/sanitizer_linux_libcdep.cc
Index: lib/sanitizer_common/sanitizer_linux_libcdep.cc
===================================================================
--- lib/sanitizer_common/sanitizer_linux_libcdep.cc
+++ lib/sanitizer_common/sanitizer_linux_libcdep.cc
@@ -13,7 +13,7 @@
//===----------------------------------------------------------------------===//
#include "sanitizer_platform.h"
-#if SANITIZER_LINUX
+#if SANITIZER_FREEBSD || SANITIZER_LINUX
#include "sanitizer_common.h"
#include "sanitizer_flags.h"
@@ -26,10 +26,21 @@
#include <dlfcn.h>
#include <pthread.h>
#include <signal.h>
-#include <sys/prctl.h>
#include <sys/resource.h>
+#if SANITIZER_FREEBSD
+#define _GNU_SOURCE // to declare _Unwind_Backtrace() from <unwind.h>
+#endif
#include <unwind.h>
+#if SANITIZER_FREEBSD
+#include <pthread_np.h>
+#define pthread_getattr_np pthread_attr_get_np
+#endif
+
+#if SANITIZER_LINUX
+#include <sys/prctl.h>
+#endif
+
#if !SANITIZER_ANDROID
#include <elf.h>
#include <link.h>
@@ -292,7 +303,7 @@
return g_tls_size;
}
-#if defined(__x86_64__) || defined(__i386__)
+#if (defined(__x86_64__) || defined(__i386__)) && SANITIZER_LINUX
// sizeof(struct thread) from glibc.
static atomic_uintptr_t kThreadDescriptorSize;
@@ -337,31 +348,85 @@
uptr ThreadSelfOffset() {
return kThreadSelfOffset;
}
+#endif // (defined(__x86_64__) || defined(__i386__)) && SANITIZER_LINUX
+
+#if SANITIZER_FREEBSD
+static void **ThreadSelfSegbase() {
+ void **segbase = 0;
+# if defined(__i386__)
+ // sysarch(I386_GET_GSBASE, segbase);
+ __asm __volatile("mov %%gs:0, %0" : "=r" (segbase));
+# elif defined(__x86_64__)
+ // sysarch(AMD64_GET_FSBASE, segbase);
+ __asm __volatile("movq %%fs:0, %0" : "=r" (segbase));
+# else
+# error "unsupported CPU arch for FreeBSD platform"
+# endif
+ return segbase;
+}
+#endif // SANITIZER_FREEBSD
uptr ThreadSelf() {
uptr descr_addr;
-#ifdef __i386__
+
+#if SANITIZER_LINUX
+# if defined(__i386__)
asm("mov %%gs:%c1,%0" : "=r"(descr_addr) : "i"(kThreadSelfOffset));
-#else
+# elif defined(__x86_64__)
asm("mov %%fs:%c1,%0" : "=r"(descr_addr) : "i"(kThreadSelfOffset));
+# else
+# error "Unsupported arch"
+# endif
+#elif SANITIZER_FREEBSD
+ descr_addr = (uptr) ThreadSelfSegbase()[2];
+#else
+# error "Unknown OS"
#endif
+
return descr_addr;
}
-#endif // defined(__x86_64__) || defined(__i386__)
-void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
- uptr *tls_addr, uptr *tls_size) {
-#ifndef SANITIZER_GO
-#if defined(__x86_64__) || defined(__i386__)
- *tls_addr = ThreadSelf();
- *tls_size = GetTlsSize();
- *tls_addr -= *tls_size;
- *tls_addr += ThreadDescriptorSize();
+static void GetTls(uptr *addr, uptr *size) {
+#if SANITIZER_GO
+ *addr = 0;
+ *size = 0;
+#elif SANITIZER_LINUX
+# if defined(__x86_64__) || defined(__i386__)
+ *addr = ThreadSelf();
+ *size = GetTlsSize();
+ *addr -= *size;
+ *addr += ThreadDescriptorSize();
+# else
+ *addr = 0;
+ *size = 0;
+# endif
+#elif SANITIZER_FREEBSD
+ void** segbase = ThreadSelfSegbase();
+ *addr = 0;
+ *size = 0;
+
+ if (segbase != 0) {
+ // tcbalign = 16
+ // tls_size = round(tls_static_space, tcbalign);
+ // dtv = segbase[1];
+ // dtv[2] = segbase - tls_static_space;
+ void **dtv = (void**) segbase[1];
+ *addr = (uptr) dtv[2];
+ *size = (*addr == 0) ? 0 : ((uptr) segbase[0] - (uptr) dtv[2]);
+ }
#else
- *tls_addr = 0;
- *tls_size = 0;
+# error "Unknown OS"
#endif
+}
+
+void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
+ uptr *tls_addr, uptr *tls_size) {
+ GetTls(tls_addr, tls_size);
+#ifdef SANITIZER_GO
+ *stk_addr = 0;
+ *stk_size = 0;
+#else
uptr stack_top, stack_bottom;
GetThreadStackTopAndBottom(main, &stack_top, &stack_bottom);
*stk_addr = stack_bottom;
@@ -376,12 +441,7 @@
*tls_addr = *stk_addr + *stk_size;
}
}
-#else // SANITIZER_GO
- *stk_addr = 0;
- *stk_size = 0;
- *tls_addr = 0;
- *tls_size = 0;
-#endif // SANITIZER_GO
+#endif // !SANITIZER_GO
}
#ifndef SANITIZER_GO
@@ -417,7 +477,9 @@
return memory_mapping.DumpListOfModules(modules, max_modules, filter);
}
#else // SANITIZER_ANDROID
+# if !SANITIZER_FREEBSD
typedef ElfW(Phdr) Elf_Phdr;
+# endif
struct DlIteratePhdrData {
LoadedModule *modules;
@@ -480,4 +542,4 @@
} // namespace __sanitizer
-#endif // SANITIZER_LINUX
+#endif // SANITIZER_FREEBSD || SANITIZER_LINUX
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2938.2.patch
Type: text/x-patch
Size: 4449 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140306/40ef7a7e/attachment.bin>
More information about the llvm-commits
mailing list