Fix getting IP, BP and SP for address sanitizer's needs on FreeBSD in 32-bit mode
authorViktor Kutuzov <vkutuzov@accesssoftek.com>
Sun, 15 Jun 2014 13:56:28 +0000 (13:56 +0000)
committerViktor Kutuzov <vkutuzov@accesssoftek.com>
Sun, 15 Jun 2014 13:56:28 +0000 (13:56 +0000)
llvm-svn: 210988

compiler-rt/lib/asan/asan_linux.cc
compiler-rt/lib/sanitizer_common/sanitizer_freebsd.h [new file with mode: 0644]

index b3c45ee..fdd009c 100644 (file)
@@ -19,6 +19,7 @@
 #include "asan_internal.h"
 #include "asan_thread.h"
 #include "sanitizer_common/sanitizer_flags.h"
+#include "sanitizer_common/sanitizer_freebsd.h"
 #include "sanitizer_common/sanitizer_libc.h"
 #include "sanitizer_common/sanitizer_procmaps.h"
 
@@ -46,15 +47,11 @@ extern "C" void* _DYNAMIC;
 #include <link.h>
 #endif
 
-// x86_64 FreeBSD 9.2 and older define 64-bit register names in both 64-bit
-// and 32-bit modes.
-#if SANITIZER_FREEBSD
-#include <sys/param.h>
-# if __FreeBSD_version <= 902001  // v9.2
-#  define mc_eip mc_rip
-#  define mc_ebp mc_rbp
-#  define mc_esp mc_rsp
-# endif
+// x86-64 FreeBSD 9.2 and older define 'ucontext_t' incorrectly in
+// 32-bit mode.
+#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32) && \
+  __FreeBSD_version <= 902001  // v9.2
+#define ucontext_t xucontext_t
 #endif
 
 typedef enum {
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_freebsd.h b/compiler-rt/lib/sanitizer_common/sanitizer_freebsd.h
new file mode 100644 (file)
index 0000000..52a2a85
--- /dev/null
@@ -0,0 +1,82 @@
+//===-- sanitizer_freebsd.h -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of Sanitizer runtime. It contains FreeBSD-specific
+// definitions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SANITIZER_FREEBSD_H
+#define SANITIZER_FREEBSD_H
+
+#include "sanitizer_internal_defs.h"
+
+// x86-64 FreeBSD 9.2 and older define 'ucontext_t' incorrectly in
+// 32-bit mode.
+#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)
+# include <osreldate.h>
+# if __FreeBSD_version <= 902001  // v9.2
+#  include <ucontext.h>
+
+namespace __sanitizer {
+
+typedef __int32_t __xregister_t;
+
+typedef struct __xmcontext {
+  __xregister_t mc_onstack;
+  __xregister_t mc_gs;
+  __xregister_t mc_fs;
+  __xregister_t mc_es;
+  __xregister_t mc_ds;
+  __xregister_t mc_edi;
+  __xregister_t mc_esi;
+  __xregister_t mc_ebp;
+  __xregister_t mc_isp;
+  __xregister_t mc_ebx;
+  __xregister_t mc_edx;
+  __xregister_t mc_ecx;
+  __xregister_t mc_eax;
+  __xregister_t mc_trapno;
+  __xregister_t mc_err;
+  __xregister_t mc_eip;
+  __xregister_t mc_cs;
+  __xregister_t mc_eflags;
+  __xregister_t mc_esp;
+  __xregister_t mc_ss;
+
+  int mc_len;
+  int mc_fpformat;
+  int mc_ownedfp;
+  __xregister_t mc_flags;
+
+  int mc_fpstate[128] __aligned(16);
+  __xregister_t mc_fsbase;
+  __xregister_t mc_gsbase;
+  __xregister_t mc_xfpustate;
+  __xregister_t mc_xfpustate_len;
+
+  int mc_spare2[4];
+} xmcontext_t;
+
+typedef struct __xucontext {
+  sigset_t  uc_sigmask;
+  xmcontext_t  uc_mcontext;
+
+  struct __ucontext *uc_link;
+  stack_t uc_stack;
+  int uc_flags;
+  int __spare__[4];
+} xucontext_t;
+
+}  // namespace __sanitizer
+
+# endif  // __FreeBSD_version <= 902001
+#endif  // SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)
+
+#endif  // SANITIZER_FREEBSD_H