summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2013-10-20 21:29:46 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2013-10-20 21:29:46 +0000
commit9b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535 (patch)
treefbae7a194cba4874ec6393403f354075d5b50914
parent49d29ed950f9e309a7b755b2a0601ed483ce3ade (diff)
downloadcompiler-rt-9b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535.tar.gz
compiler-rt-9b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535.tar.bz2
compiler-rt-9b5f95f5fe1a24be4dfb7436b64cb0e0f8c00535.tar.xz
Runtime support for the indirect function call checker.
Differential Revision: http://llvm-reviews.chandlerc.com/D1339 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@193060 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/asan/CMakeLists.txt2
-rw-r--r--lib/ubsan/lit_tests/CMakeLists.txt1
-rw-r--r--lib/ubsan/lit_tests/TypeCheck/Function/function.cpp17
-rw-r--r--lib/ubsan/lit_tests/TypeCheck/Function/lit.local.cfg3
-rw-r--r--lib/ubsan/lit_tests/lit.cfg3
-rw-r--r--lib/ubsan/ubsan_diag.cc9
-rw-r--r--lib/ubsan/ubsan_diag.h6
-rw-r--r--lib/ubsan/ubsan_handlers.cc20
-rw-r--r--lib/ubsan/ubsan_handlers.h9
9 files changed, 70 insertions, 0 deletions
diff --git a/lib/asan/CMakeLists.txt b/lib/asan/CMakeLists.txt
index 17552b3a..7a54f96f 100644
--- a/lib/asan/CMakeLists.txt
+++ b/lib/asan/CMakeLists.txt
@@ -137,6 +137,8 @@ endif()
add_compiler_rt_resource_file(asan_blacklist asan_blacklist.txt)
+add_custom_target(asan DEPENDS asan_blacklist ${ASAN_RUNTIME_LIBRARIES})
+
if(LLVM_INCLUDE_TESTS)
add_subdirectory(tests)
endif()
diff --git a/lib/ubsan/lit_tests/CMakeLists.txt b/lib/ubsan/lit_tests/CMakeLists.txt
index 7e1a13c7..6abc8a01 100644
--- a/lib/ubsan/lit_tests/CMakeLists.txt
+++ b/lib/ubsan/lit_tests/CMakeLists.txt
@@ -8,6 +8,7 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS)
# working binaries.
set(UBSAN_TEST_DEPS
${SANITIZER_COMMON_LIT_TEST_DEPS}
+ asan
${UBSAN_RUNTIME_LIBRARIES})
set(UBSAN_TEST_PARAMS
ubsan_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
diff --git a/lib/ubsan/lit_tests/TypeCheck/Function/function.cpp b/lib/ubsan/lit_tests/TypeCheck/Function/function.cpp
new file mode 100644
index 00000000..feff0f5a
--- /dev/null
+++ b/lib/ubsan/lit_tests/TypeCheck/Function/function.cpp
@@ -0,0 +1,17 @@
+// RUN: %clangxx -fsanitize=address,function %s -O3 -g -o %t
+// RUN: %t 2>&1 | FileCheck %s
+
+#include <stdint.h>
+
+void f() {}
+
+void g(int x) {}
+
+int main(void) {
+ // CHECK: runtime error: call to function f() through pointer to incorrect function type 'void (*)(int)'
+ // CHECK-NEXT: function.cpp:6: note: f() defined here
+ reinterpret_cast<void (*)(int)>(reinterpret_cast<uintptr_t>(f))(42);
+
+ // CHECK-NOT: runtime error: call to function g
+ reinterpret_cast<void (*)(int)>(reinterpret_cast<uintptr_t>(g))(42);
+}
diff --git a/lib/ubsan/lit_tests/TypeCheck/Function/lit.local.cfg b/lib/ubsan/lit_tests/TypeCheck/Function/lit.local.cfg
new file mode 100644
index 00000000..27c61a34
--- /dev/null
+++ b/lib/ubsan/lit_tests/TypeCheck/Function/lit.local.cfg
@@ -0,0 +1,3 @@
+# The function type checker is only supported on x86 and x86_64 for now.
+if config.root.host_arch not in ['x86', 'x86_64']:
+ config.unsupported = True
diff --git a/lib/ubsan/lit_tests/lit.cfg b/lib/ubsan/lit_tests/lit.cfg
index 4a5bc237..d96912fe 100644
--- a/lib/ubsan/lit_tests/lit.cfg
+++ b/lib/ubsan/lit_tests/lit.cfg
@@ -54,6 +54,9 @@ config.substitutions.append( ("%clang ", (" " + config.clang + " ")) )
config.substitutions.append( ("%clangxx ", (" " + config.clang +
" --driver-mode=g++ ")) )
+# Setup path to external LLVM symbolizer.
+config.environment['ASAN_SYMBOLIZER_PATH'] = config.llvm_symbolizer_path
+
# Default test suffixes.
config.suffixes = ['.c', '.cc', '.cpp']
diff --git a/lib/ubsan/ubsan_diag.cc b/lib/ubsan/ubsan_diag.cc
index e4ca4e4a..968e7790 100644
--- a/lib/ubsan/ubsan_diag.cc
+++ b/lib/ubsan/ubsan_diag.cc
@@ -26,12 +26,21 @@ Location __ubsan::getCallerLocation(uptr CallerLoc) {
return Location();
uptr Loc = StackTrace::GetPreviousInstructionPc(CallerLoc);
+ return getFunctionLocation(Loc, 0);
+}
+
+Location __ubsan::getFunctionLocation(uptr Loc, const char **FName) {
+ if (!Loc)
+ return Location();
AddressInfo Info;
if (!getSymbolizer()->SymbolizeCode(Loc, &Info, 1) ||
!Info.module || !*Info.module)
return Location(Loc);
+ if (FName && Info.function)
+ *FName = Info.function;
+
if (!Info.file)
return ModuleLocation(Info.module, Info.module_offset);
diff --git a/lib/ubsan/ubsan_diag.h b/lib/ubsan/ubsan_diag.h
index 16afffdb..54d15a0c 100644
--- a/lib/ubsan/ubsan_diag.h
+++ b/lib/ubsan/ubsan_diag.h
@@ -80,6 +80,12 @@ public:
/// an invalid location or a module location for the caller.
Location getCallerLocation(uptr CallerLoc = GET_CALLER_PC());
+/// Try to obtain a location for the given function pointer. This might fail,
+/// and produce either an invalid location or a module location for the caller.
+/// If FName is non-null and the name of the function is known, set *FName to
+/// the function name, otherwise *FName is unchanged.
+Location getFunctionLocation(uptr Loc, const char **FName);
+
/// A diagnostic severity level.
enum DiagLevel {
DL_Error, ///< An error.
diff --git a/lib/ubsan/ubsan_handlers.cc b/lib/ubsan/ubsan_handlers.cc
index 5ed0d592..d5564314 100644
--- a/lib/ubsan/ubsan_handlers.cc
+++ b/lib/ubsan/ubsan_handlers.cc
@@ -259,3 +259,23 @@ void __ubsan::__ubsan_handle_load_invalid_value_abort(InvalidValueData *Data,
__ubsan_handle_load_invalid_value(Data, Val);
Die();
}
+
+void __ubsan::__ubsan_handle_function_type_mismatch(
+ FunctionTypeMismatchData *Data,
+ ValueHandle Function) {
+ const char *FName = "(unknown)";
+
+ Location Loc = getFunctionLocation(Function, &FName);
+
+ Diag(Data->Loc, DL_Error,
+ "call to function %0 through pointer to incorrect function type %1")
+ << FName << Data->Type;
+ Diag(Loc, DL_Note, "%0 defined here") << FName;
+}
+
+void __ubsan::__ubsan_handle_function_type_mismatch_abort(
+ FunctionTypeMismatchData *Data,
+ ValueHandle Function) {
+ __ubsan_handle_function_type_mismatch(Data, Function);
+ Die();
+}
diff --git a/lib/ubsan/ubsan_handlers.h b/lib/ubsan/ubsan_handlers.h
index 9406207f..14e6f04c 100644
--- a/lib/ubsan/ubsan_handlers.h
+++ b/lib/ubsan/ubsan_handlers.h
@@ -112,6 +112,15 @@ struct InvalidValueData {
/// \brief Handle a load of an invalid value for the type.
RECOVERABLE(load_invalid_value, InvalidValueData *Data, ValueHandle Val)
+struct FunctionTypeMismatchData {
+ SourceLocation Loc;
+ const TypeDescriptor &Type;
+};
+
+RECOVERABLE(function_type_mismatch,
+ FunctionTypeMismatchData *Data,
+ ValueHandle Val)
+
}
#endif // UBSAN_HANDLERS_H