[PATCH] Enable sanitizers' libc dependencies on FreeBSD

Viktor Kutuzov vkutuzov at accesssoftek.com
Tue Mar 4 05:56:12 PST 2014


Hi kcc, samsonov,

http://llvm-reviews.chandlerc.com/D2938

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,19 @@
 #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 <sys/prctl.h>
+#else
+#include <pthread_np.h>
+#define pthread_getattr_np pthread_attr_get_np
+#endif
+
 #if !SANITIZER_ANDROID
 #include <elf.h>
 #include <link.h>
@@ -294,7 +303,7 @@
   return g_tls_size;
 }
 
-#if defined(__x86_64__) || defined(__i386__)
+#if (defined(__x86_64__) || defined(__i386__)) && !SANITIZER_FREEBSD
 // sizeof(struct thread) from glibc.
 static atomic_uintptr_t kThreadDescriptorSize;
 
@@ -349,16 +358,59 @@
 #endif
   return descr_addr;
 }
-#endif  // defined(__x86_64__) || defined(__i386__)
+#endif  // (defined(__x86_64__) || defined(__i386__)) && !SANITIZER_FREEBSD
+
+#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;
+}
+
+uptr ThreadSelf() {
+  return (uptr) ThreadSelfSegbase()[2];
+}
+
+static void GetTls(uptr *p, uptr *size) {
+  CHECK_NE(p, 0);
+  CHECK_NE(size, 0);
+
+  void** segbase = ThreadSelfSegbase();
+  *p = 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];
+    *p = (uptr) dtv[2];
+    *size = (*p != 0) ? ((uptr) segbase[0] - (uptr) dtv[2]) : 0;
+  }
+}
+#endif  // SANITIZER_FREEBSD
 
 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__)
+# if SANITIZER_FREEBSD
+  GetTls(tls_addr, tls_size);
+# else
   *tls_addr = ThreadSelf();
   *tls_size = GetTlsSize();
   *tls_addr -= *tls_size;
   *tls_addr += ThreadDescriptorSize();
+# endif
 #else
   *tls_addr = 0;
   *tls_size = 0;
@@ -419,7 +471,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;
@@ -482,4 +536,4 @@
 
 }  // namespace __sanitizer
 
-#endif  // SANITIZER_LINUX
+#endif  // SANITIZER_FREEBSD || SANITIZER_LINUX
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2938.1.patch
Type: text/x-patch
Size: 3186 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140304/b633f521/attachment.bin>


More information about the llvm-commits mailing list