Hi theraven,
This patch adds runtime support for the Safe Stack protection to compiler-rt
(see http://reviews.llvm.org/D6094 for the detailed description of the Safe
Stack).
This patch is our implementation of the safe stack on top of the current SVN
HEAD of compiler-rt (r220991). The patch adds basic runtime support for the
safe stack to compiler-rt that manages unsafe stack allocation/deallocation for
each thread.
http://reviews.llvm.org/D6096
Files:
CMakeLists.txt
cmake/config-ix.cmake
include/CMakeLists.txt
include/safestack_interface.h
lib/CMakeLists.txt
lib/Makefile.mk
lib/safestack/CMakeLists.txt
lib/safestack/Makefile.mk
lib/safestack/safestack.cc
make/platform/clang_darwin.mk
make/platform/clang_linux.mk
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt
+++ CMakeLists.txt
@@ -239,6 +239,7 @@
append_list_if(COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG -fomit-frame-pointer SANITIZER_COMMON_CFLAGS)
append_list_if(COMPILER_RT_HAS_FUNWIND_TABLES_FLAG -funwind-tables SANITIZER_COMMON_CFLAGS)
append_list_if(COMPILER_RT_HAS_FNO_STACK_PROTECTOR_FLAG -fno-stack-protector SANITIZER_COMMON_CFLAGS)
+append_list_if(COMPILER_RT_HAS_FNO_SAFE_STACK_FLAG -fno-safe-stack SANITIZER_COMMON_CFLAGS)
append_list_if(COMPILER_RT_HAS_FVISIBILITY_HIDDEN_FLAG -fvisibility=hidden SANITIZER_COMMON_CFLAGS)
append_list_if(COMPILER_RT_HAS_FNO_FUNCTION_SECTIONS_FLAG -fno-function-sections SANITIZER_COMMON_CFLAGS)
Index: cmake/config-ix.cmake
===================================================================
--- cmake/config-ix.cmake
+++ cmake/config-ix.cmake
@@ -10,6 +10,7 @@
check_cxx_compiler_flag(-fomit-frame-pointer COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG)
check_cxx_compiler_flag(-funwind-tables COMPILER_RT_HAS_FUNWIND_TABLES_FLAG)
check_cxx_compiler_flag(-fno-stack-protector COMPILER_RT_HAS_FNO_STACK_PROTECTOR_FLAG)
+check_cxx_compiler_flag(-fno-safe-stack COMPILER_RT_HAS_FNO_SAFE_STACK_FLAG)
check_cxx_compiler_flag(-fvisibility=hidden COMPILER_RT_HAS_FVISIBILITY_HIDDEN_FLAG)
check_cxx_compiler_flag(-fno-rtti COMPILER_RT_HAS_FNO_RTTI_FLAG)
check_cxx_compiler_flag(-ffreestanding COMPILER_RT_HAS_FFREESTANDING_FLAG)
@@ -182,6 +183,7 @@
filter_available_targets(PROFILE_SUPPORTED_ARCH x86_64 i386 i686 arm mips mips64 mipsel mips64el aarch64)
filter_available_targets(TSAN_SUPPORTED_ARCH x86_64)
filter_available_targets(UBSAN_SUPPORTED_ARCH x86_64 i386 i686 arm aarch64 mips mipsel)
+filter_available_targets(SAFESTACK_SUPPORTED_ARCH x86_64 i386 i686)
if(ANDROID)
set(OS_NAME "Android")
Index: include/CMakeLists.txt
===================================================================
--- include/CMakeLists.txt
+++ include/CMakeLists.txt
@@ -6,7 +6,8 @@
sanitizer/linux_syscall_hooks.h
sanitizer/lsan_interface.h
sanitizer/msan_interface.h
- sanitizer/tsan_interface_atomic.h)
+ sanitizer/tsan_interface_atomic.h
+ safestack_interface.h)
set(output_dir ${COMPILER_RT_OUTPUT_DIR}/include)
Index: include/safestack_interface.h
===================================================================
--- /dev/null
+++ include/safestack_interface.h
@@ -0,0 +1,20 @@
+#ifndef SAFESTACK_INTERFACE_H
+#define SAFESTACK_INTERFACE_H
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *__safestack_get_unsafe_stack_start();
+void *__safestack_get_unsafe_stack_ptr();
+size_t __safestack_get_unsafe_stack_size();
+
+void *__safestack_get_safe_stack_ptr();
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // SAFESTACK_INTERFACE_H
Index: lib/CMakeLists.txt
===================================================================
--- lib/CMakeLists.txt
+++ lib/CMakeLists.txt
@@ -41,3 +41,4 @@
add_subdirectory(ubsan)
endif()
+add_subdirectory(safestack)
Index: lib/Makefile.mk
===================================================================
--- lib/Makefile.mk
+++ lib/Makefile.mk
@@ -20,3 +20,4 @@
SubDirs += sanitizer_common
SubDirs += tsan
SubDirs += ubsan
+SubDirs += safestack
Index: lib/safestack/CMakeLists.txt
===================================================================
--- /dev/null
+++ lib/safestack/CMakeLists.txt
@@ -0,0 +1,26 @@
+add_custom_target(safestack)
+
+set(SAFESTACK_SOURCES safestack.cc)
+
+include_directories(..)
+
+set(SAFESTACK_CFLAGS ${SANITIZER_COMMON_CFLAGS})
+
+if(APPLE)
+ # Build universal binary on APPLE.
+ add_compiler_rt_osx_static_runtime(clang_rt.safestack_osx
+ ARCH ${SAFESTACK_SUPPORTED_ARCH}
+ SOURCES ${SAFESTACK_SOURCES}
+ $<TARGET_OBJECTS:RTInterception.osx>
+ CFLAGS ${SAFESTACK_CFLAGS})
+ add_dependencies(safestack clang_rt.safestack_osx)
+else()
+ # Otherwise, build separate libraries for each target.
+ foreach(arch ${SAFESTACK_SUPPORTED_ARCH})
+ add_compiler_rt_runtime(clang_rt.safestack-${arch} ${arch} STATIC
+ SOURCES ${SAFESTACK_SOURCES}
+ $<TARGET_OBJECTS:RTInterception.${arch}>
+ CFLAGS ${SAFESTACK_CFLAGS})
+ add_dependencies(safestack clang_rt.safestack-${arch})
+ endforeach()
+endif()
Index: lib/safestack/Makefile.mk
===================================================================
--- /dev/null
+++ lib/safestack/Makefile.mk
@@ -0,0 +1,23 @@
+#===- lib/safestack/Makefile.mk ------------------------------*- Makefile -*--===#
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+ModuleName := safestack
+SubDirs :=
+
+Sources := $(foreach file,$(wildcard $(Dir)/*.cc),$(notdir $(file)))
+ObjNames := $(Sources:%.cc=%.o)
+
+Implementation := Generic
+
+# FIXME: use automatic dependencies?
+Dependencies := $(wildcard $(Dir)/*.h)
+Dependencies += $(wildcard $(Dir)/../interception/*.h)
+
+# Define a convenience variable for all the safestack functions.
+SafeStackFunctions := $(Sources:%.cc=%)
Index: lib/safestack/safestack.cc
===================================================================
--- /dev/null
+++ lib/safestack/safestack.cc
@@ -0,0 +1,347 @@
+//===-- safestack.cc --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the runtime support for the safe stack protection
+// mechanism. The runtime manages allocation/deallocation of the unsafe stack
+// for the main thread, as well as all pthreads threads that are
+// created/destroyed during program execution.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <assert.h>
+#include <dlfcn.h>
+#include <limits.h>
+#include <sys/mman.h>
+#include <sys/user.h>
+#include <pthread.h>
+
+#if defined(__linux__)
+#include <unistd.h>
+#include <sys/syscall.h>
+#endif
+
+// FIXME: is this in some header?
+#define STACK_ALIGN 16
+
+// Should we make the following configurable?
+#define __SAFESTACK_DEFAULT_STACK_SIZE 0x2800000
+
+#include "interception/interception.h"
+
+namespace __llvm__safestack {
+
+// We don't know whether pthread is linked in or not, so we resolve
+// all symbols from pthread that we use dynamically
+#define __DECLARE_WRAPPER(fn) __typeof__(fn)* __d_ ## fn = NULL;
+
+__DECLARE_WRAPPER(pthread_attr_init)
+__DECLARE_WRAPPER(pthread_attr_destroy)
+__DECLARE_WRAPPER(pthread_attr_getstacksize)
+__DECLARE_WRAPPER(pthread_attr_getguardsize)
+__DECLARE_WRAPPER(pthread_key_create)
+__DECLARE_WRAPPER(pthread_setspecific)
+
+// The unsafe stack pointer is stored in the TCB structure on these platforms
+#if defined(__i386__)
+# define MOVPTR "movl"
+# ifdef __pic__
+# define IMM_MODE "nr"
+# else
+# define IMM_MODE "ir"
+# endif
+#elif defined(__x86_64__)
+# define MOVPTR "movq"
+# define IMM_MODE "nr"
+#endif
+
+#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
+
+# define __THREAD_GETMEM_L(offset) \
+ __extension__ ({ unsigned long __v; \
+ asm volatile (MOVPTR " %%fs:%P1,%q0" \
+ : "=r" (__v) : "i" (offset)); __v; })
+
+# define __THREAD_SETMEM_L(offset, value) \
+ asm volatile (MOVPTR " %q0,%%fs:%P1" : \
+ : IMM_MODE ((unsigned long) (value)), "i" (offset))
+
+// The following locations are platform-specific
+# define __GET_UNSAFE_STACK_PTR() (void*) __THREAD_GETMEM_L(0x280)
+# define __SET_UNSAFE_STACK_PTR(value) __THREAD_SETMEM_L(0x280, value)
+
+# define __GET_UNSAFE_STACK_START() (void*) __THREAD_GETMEM_L(0x288)
+# define __SET_UNSAFE_STACK_START(value) __THREAD_SETMEM_L(0x288, value)
+
+# define __GET_UNSAFE_STACK_SIZE() (size_t) __THREAD_GETMEM_L(0x290)
+# define __SET_UNSAFE_STACK_SIZE(value) __THREAD_SETMEM_L(0x290, value)
+
+# define __GET_UNSAFE_STACK_GUARD() (size_t) __THREAD_GETMEM_L(0x298)
+# define __SET_UNSAFE_STACK_GUARD(value) __THREAD_SETMEM_L(0x298, value)
+
+#elif defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__))
+
+// OSX uses %gs to directly index thread-specific slots
+# define __THREAD_GETMEM_L(slot) \
+ __extension__ ({ unsigned long __v; \
+ asm volatile (MOVPTR " %%gs:%P1,%q0" : "=r" (__v) \
+ : "i" ((slot) * sizeof(void*))); __v; })
+
+# define __THREAD_SETMEM_L(slot, value) \
+ asm volatile (MOVPTR " %q0,%%gs:%P1" : \
+ : IMM_MODE ((unsigned long) (value)), \
+ "i" ((slot) * sizeof(void*)))
+
+// Thread-specific slots 0-256 are reserved for the systems on OSX.
+// Slots 192 - 195 seems unused at the moment, so we claim them.
+
+// The following locations are platform-specific
+# define __GET_UNSAFE_STACK_PTR() (void*) __THREAD_GETMEM_L(192)
+# define __SET_UNSAFE_STACK_PTR(value) __THREAD_SETMEM_L(192, value)
+
+# define __GET_UNSAFE_STACK_START() (void*) __THREAD_GETMEM_L(193)
+# define __SET_UNSAFE_STACK_START(value) __THREAD_SETMEM_L(193, value)
+
+# define __GET_UNSAFE_STACK_SIZE() (size_t) __THREAD_GETMEM_L(194)
+# define __SET_UNSAFE_STACK_SIZE(value) __THREAD_SETMEM_L(194, value)
+
+# define __GET_UNSAFE_STACK_GUARD() (size_t) __THREAD_GETMEM_L(195)
+# define __SET_UNSAFE_STACK_GUARD(value) __THREAD_SETMEM_L(195, value)
+
+#else
+// The unsafe stack is stored in a thread-local variable on these platforms
+extern "C" {
+ __attribute__((visibility ("default")))
+ __thread void *__llvm__unsafe_stack_ptr = 0;
+}
+
+__thread void *unsafe_stack_start = 0;
+__thread size_t unsafe_stack_size = 0;
+__thread size_t unsafe_stack_guard = 0;
+
+# define __GET_UNSAFE_STACK_PTR() __llvm__unsafe_stack_ptr
+# define __SET_UNSAFE_STACK_PTR(value) __llvm__unsafe_stack_ptr = (value)
+
+# define __GET_UNSAFE_STACK_START() unsafe_stack_start
+# define __SET_UNSAFE_STACK_START(value) unsafe_stack_start = (value)
+
+# define __GET_UNSAFE_STACK_SIZE() unsafe_stack_size
+# define __SET_UNSAFE_STACK_SIZE(value) unsafe_stack_size = (value)
+
+# define __GET_UNSAFE_STACK_GUARD() unsafe_stack_guard
+# define __SET_UNSAFE_STACK_GUARD(value) unsafe_stack_guard = (value)
+
+#endif
+
+static inline void *unsafe_stack_alloc(size_t size, size_t guard) {
+ void *addr =
+#if defined(__linux__)
+ (void*) syscall(SYS_mmap,
+#else
+ mmap(
+#endif
+ NULL, size + guard, PROT_WRITE | PROT_READ,
+ MAP_PRIVATE | MAP_ANON
+#if defined(__linux__)
+ | MAP_STACK | MAP_GROWSDOWN
+#endif
+ , -1, 0);
+ mprotect(addr, guard, PROT_NONE);
+ return (char*) addr + guard;
+}
+
+static inline void unsafe_stack_setup(void *start, size_t size, size_t guard) {
+ void* stack_ptr = (char*) start + size;
+ assert((((size_t)stack_ptr) & (STACK_ALIGN-1)) == 0);
+
+ __SET_UNSAFE_STACK_PTR(stack_ptr);
+ __SET_UNSAFE_STACK_START(start);
+ __SET_UNSAFE_STACK_SIZE(size);
+ __SET_UNSAFE_STACK_GUARD(guard);
+}
+
+static void unsafe_stack_free() {
+ if (__GET_UNSAFE_STACK_START()) {
+#if defined(__linux__)
+ syscall(SYS_munmap,
+#else
+ munmap(
+#endif
+ (char*) __GET_UNSAFE_STACK_START() - __GET_UNSAFE_STACK_GUARD(),
+ __GET_UNSAFE_STACK_SIZE() + __GET_UNSAFE_STACK_GUARD());
+ }
+ __SET_UNSAFE_STACK_START(0);
+}
+
+/// Thread data for the cleanup handler
+pthread_key_t thread_cleanup_key;
+
+/// Safe stack per-thread information passed to the thread_start function
+struct tinfo {
+ void *(*start_routine)(void*);
+ void *start_routine_arg;
+
+ void *unsafe_stack_start;
+ size_t unsafe_stack_size;
+ size_t unsafe_stack_guard;
+};
+
+/// Wrap the thread function in order to deallocate the unsafe stack when the
+/// thread terminates by returning from its main function.
+static void* thread_start(void *arg) {
+ struct tinfo *tinfo = (struct tinfo*) arg;
+
+ void *(*start_routine)(void*) = tinfo->start_routine;
+ void *start_routine_arg = tinfo->start_routine_arg;
+
+ // Setup the unsafe stack; this will destroy tinfo content
+ unsafe_stack_setup(tinfo->unsafe_stack_start,
+ tinfo->unsafe_stack_size,
+ tinfo->unsafe_stack_guard);
+
+ // Make sure out thread-specific destructor will be called
+ // FIXME: we can do this only any other specific key is set by
+ // intersepting the pthread_setspecific function itself
+ __d_pthread_setspecific(thread_cleanup_key, (void*) 1);
+
+ // Start the original thread rutine
+ return start_routine(start_routine_arg);
+}
+
+/// Intercept thread creation operation to allocate and setup the unsafe stack
+INTERCEPTOR(int, pthread_create, pthread_t *thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine)(void*), void *arg) {
+
+ size_t size = 0;
+ size_t guard = 0;
+
+ if (attr != NULL) {
+ __d_pthread_attr_getstacksize(attr, &size);
+ __d_pthread_attr_getguardsize(attr, &guard);
+ } else {
+ // get pthread default stack size
+ pthread_attr_t tmpattr;
+ __d_pthread_attr_init(&tmpattr);
+ __d_pthread_attr_getstacksize(&tmpattr, &size);
+ __d_pthread_attr_getguardsize(&tmpattr, &guard);
+ __d_pthread_attr_destroy(&tmpattr);
+ }
+
+ assert(size != 0);
+ assert((size & (STACK_ALIGN-1)) == 0);
+ assert((guard & (PAGE_SIZE-1)) == 0);
+
+ void *addr = unsafe_stack_alloc(size, guard);
+ struct tinfo *tinfo = (struct tinfo*) (
+ ((char*)addr) + size - sizeof(struct tinfo));
+ tinfo->start_routine = start_routine;
+ tinfo->start_routine_arg = arg;
+ tinfo->unsafe_stack_start = addr;
+ tinfo->unsafe_stack_size = size;
+ tinfo->unsafe_stack_guard = guard;
+
+ return REAL(pthread_create)(thread, attr, thread_start, tinfo);
+}
+
+/// Thread-specific data destructor
+void thread_cleanup_handler(void* _iter) {
+ // We want to free the unsafe stack only after all other destructors
+ // have already run. We force this function to be called multiple times.
+ size_t iter = (size_t) _iter;
+ if (iter < PTHREAD_DESTRUCTOR_ITERATIONS) {
+ __d_pthread_setspecific(thread_cleanup_key, (void*) (iter + 1));
+ } else {
+ // This is the last iteration
+ unsafe_stack_free();
+ }
+}
+
+int inited = 0;
+
+extern "C"
+__attribute__((visibility ("default")))
+#ifndef __linux__
+__attribute__((constructor(0)))
+#endif
+void __llvm__safestack_init() {
+ if (inited)
+ return;
+
+ inited = 1;
+
+ // Allocate unsafe stack for main thread
+ size_t size = __SAFESTACK_DEFAULT_STACK_SIZE;
+ size_t guard = 4096;
+ void *addr = unsafe_stack_alloc(size, guard);
+ unsafe_stack_setup(addr, size, guard);
+
+ // Initialize pthread interceptors for thread allocation
+ INTERCEPT_FUNCTION(pthread_create);
+
+ #define __FIND_FUNCTION(fn) \
+ __d_ ## fn = __extension__ (__typeof__(__d_ ## fn)) dlsym(RTLD_DEFAULT, #fn);
+
+ // Find pthread functions that we need
+ __FIND_FUNCTION(pthread_attr_init)
+ __FIND_FUNCTION(pthread_attr_destroy)
+ __FIND_FUNCTION(pthread_attr_getstacksize)
+ __FIND_FUNCTION(pthread_attr_getguardsize)
+ __FIND_FUNCTION(pthread_key_create)
+ __FIND_FUNCTION(pthread_setspecific)
+
+ if (__d_pthread_key_create != NULL) {
+ // We're using pthreads, setup the cleanup handler
+ __d_pthread_key_create(&thread_cleanup_key, thread_cleanup_handler);
+ }
+}
+
+#ifndef NDEBUG
+extern "C"
+__attribute__((visibility ("default")))
+void __llvm__safestack_dump() {
+ fprintf(stderr,
+ "Unsafe stack addr = %p, ptr = %p, size = 0x%lx, guard = 0x%lx\n",
+ __GET_UNSAFE_STACK_START(), __GET_UNSAFE_STACK_PTR(),
+ __GET_UNSAFE_STACK_SIZE(), __GET_UNSAFE_STACK_GUARD());
+}
+
+#endif
+
+extern "C"
+__attribute__((visibility ("default")))
+__attribute__((noinline))
+void *__safestack_get_unsafe_stack_start() {
+ return __GET_UNSAFE_STACK_START();
+}
+
+extern "C"
+__attribute__((visibility ("default")))
+__attribute__((noinline))
+void *__safestack_get_unsafe_stack_ptr() {
+ return __GET_UNSAFE_STACK_PTR();
+}
+
+extern "C"
+__attribute__((visibility ("default")))
+__attribute__((noinline))
+void *__safestack_get_safe_stack_ptr() {
+ return (char*) __builtin_frame_address(0) + 2*sizeof(void*);
+}
+
+#ifdef __linux__
+// Run safestack initialization before any other constructors
+// FIXME: can we do something similar on Mac or FreeBSD?
+extern "C" {
+__attribute__((section(".preinit_array"), used))
+void (*__llvm__safestack_preinit)(void) = __llvm__safestack_init;
+}
+#endif
+
+} // namespace __llvm__safestack
Index: make/platform/clang_darwin.mk
===================================================================
--- make/platform/clang_darwin.mk
+++ make/platform/clang_darwin.mk
@@ -106,6 +106,10 @@
Configs += ubsan_osx
UniversalArchs.ubsan_osx := $(call CheckArches,i386 x86_64 x86_64h,ubsan_osx)
+# Configurations which define the safestack support functions.
+Configs += safestack_osx
+UniversalArchs.safestack_osx = $(call CheckArches,i386 x86_64 x86_64h,safestack_osx)
+
# Darwin 10.6 has a bug in cctools that makes it unable to use ranlib on our ARM
# object files. If we are on that platform, strip out all ARM archs. We still
# build the libraries themselves so that Clang can find them where it expects
@@ -170,6 +174,10 @@
CFLAGS.ubsan_osx := $(CFLAGS) -mmacosx-version-min=10.6 -fno-builtin
+CFLAGS.safestack_osx := \
+ $(CFLAGS) -fno-rtti -fno-exceptions -fno-builtin \
+ -fno-stack-protector -fno-safe-stack
+
CFLAGS.ios.i386 := $(CFLAGS) $(IOSSIM_DEPLOYMENT_ARGS)
CFLAGS.ios.x86_64 := $(CFLAGS) $(IOSSIM_DEPLOYMENT_ARGS)
CFLAGS.ios.x86_64h := $(CFLAGS) $(IOSSIM_DEPLOYMENT_ARGS)
@@ -244,6 +252,8 @@
FUNCTIONS.ubsan_osx := $(UbsanFunctions) $(UbsanCXXFunctions) \
$(SanitizerCommonFunctions)
+FUNCTIONS.safestack_osx := $(SafeStackFunctions) $(InterceptionFunctions)
+
CCKEXT_COMMON_FUNCTIONS := \
absvdi2 \
absvsi2 \
Index: make/platform/clang_linux.mk
===================================================================
--- make/platform/clang_linux.mk
+++ make/platform/clang_linux.mk
@@ -50,21 +50,22 @@
# Build runtime libraries for i386.
ifeq ($(call contains,$(SupportedArches),i386),true)
Configs += builtins-i386 profile-i386 san-i386 asan-i386 asan_cxx-i386 \
- ubsan-i386 ubsan_cxx-i386
+ ubsan-i386 ubsan_cxx-i386 safestack-i386
Arch.builtins-i386 := i386
Arch.profile-i386 := i386
Arch.san-i386 := i386
Arch.asan-i386 := i386
Arch.asan_cxx-i386 := i386
Arch.ubsan-i386 := i386
Arch.ubsan_cxx-i386 := i386
+Arch.safestack-i386 := i386
endif
# Build runtime libraries for x86_64.
ifeq ($(call contains,$(SupportedArches),x86_64),true)
Configs += builtins-x86_64 profile-x86_64 san-x86_64 asan-x86_64 asan_cxx-x86_64 \
tsan-x86_64 msan-x86_64 ubsan-x86_64 ubsan_cxx-x86_64 dfsan-x86_64 \
- lsan-x86_64
+ lsan-x86_64 safestack-x86_64
Arch.builtins-x86_64 := x86_64
Arch.profile-x86_64 := x86_64
Arch.san-x86_64 := x86_64
@@ -76,6 +77,7 @@
Arch.ubsan_cxx-x86_64 := x86_64
Arch.dfsan-x86_64 := x86_64
Arch.lsan-x86_64 := x86_64
+Arch.safestack-x86_64 := x86_64
endif
endif
@@ -110,6 +112,10 @@
CFLAGS.ubsan_cxx-x86_64 := $(CFLAGS) -m64 $(SANITIZER_CFLAGS)
CFLAGS.dfsan-x86_64 := $(CFLAGS) -m64 $(SANITIZER_CFLAGS) -fno-rtti
CFLAGS.lsan-x86_64 := $(CFLAGS) -m64 $(SANITIZER_CFLAGS) -fno-rtti
+CFLAGS.safestack-i386 := $(CFLAGS) -m32 -fPIE -fno-builtin -fno-exceptions \
+ -fno-rtti -fno-stack-protector -fno-safe-stack
+CFLAGS.safestack-x86_64 := $(CFLAGS) -m64 -fPIE -fno-builtin -fno-exceptions \
+ -fno-rtti -fno-stack-protector -fno-safe-stack
SHARED_LIBRARY.asan-arm-android := 1
ANDROID_COMMON_FLAGS := -target arm-linux-androideabi \
@@ -156,6 +162,8 @@
$(SanitizerCommonFunctions)
FUNCTIONS.lsan-x86_64 := $(LsanFunctions) $(InterceptionFunctions) \
$(SanitizerCommonFunctions)
+FUNCTIONS.safestack-i386 := $(SafeStackFunctions) $(InterceptionFunctions)
+FUNCTIONS.safestack-x86_64 := $(SafeStackFunctions) $(InterceptionFunctions)
# Always use optimized variants.
OPTIMIZED := 1
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits