aboutsummaryrefslogtreecommitdiff
path: root/lib/dfsan
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2015-03-23 12:06:32 -0700
committerStephen Hines <srhines@google.com>2015-03-23 12:06:32 -0700
commit86277eb844c4983c81de62d7c050e92fe7155788 (patch)
treedd4ccdf5db1c2e6f067e302a48bfd21408039ca6 /lib/dfsan
parent3b12a3bc627f48496b30625acfefd10e5941ed6e (diff)
downloadcompiler-rt-86277eb844c4983c81de62d7c050e92fe7155788.tar.gz
Update aosp/master compiler-rt for rebase to r230699.
Change-Id: I6c415fd5f6420e3012d9da76719111721e906dfa
Diffstat (limited to 'lib/dfsan')
-rw-r--r--lib/dfsan/CMakeLists.txt6
-rw-r--r--lib/dfsan/Makefile.mk23
-rw-r--r--lib/dfsan/dfsan.cc57
-rw-r--r--lib/dfsan/dfsan.h20
-rw-r--r--lib/dfsan/dfsan_custom.cc5
-rw-r--r--lib/dfsan/dfsan_flags.inc32
6 files changed, 92 insertions, 51 deletions
diff --git a/lib/dfsan/CMakeLists.txt b/lib/dfsan/CMakeLists.txt
index daad07f33..24ea876f2 100644
--- a/lib/dfsan/CMakeLists.txt
+++ b/lib/dfsan/CMakeLists.txt
@@ -6,13 +6,13 @@ set(DFSAN_RTL_SOURCES
dfsan_custom.cc
dfsan_interceptors.cc)
set(DFSAN_COMMON_CFLAGS ${SANITIZER_COMMON_CFLAGS})
+append_no_rtti_flag(DFSAN_COMMON_CFLAGS)
# Prevent clang from generating libc calls.
append_list_if(COMPILER_RT_HAS_FFREESTANDING_FLAG -ffreestanding DFSAN_COMMON_CFLAGS)
# Static runtime library.
add_custom_target(dfsan)
-set(arch "x86_64")
-if(CAN_TARGET_${arch})
+foreach(arch ${DFSAN_SUPPORTED_ARCH})
set(DFSAN_CFLAGS ${DFSAN_COMMON_CFLAGS})
append_list_if(COMPILER_RT_HAS_FPIE_FLAG -fPIE DFSAN_CFLAGS)
add_compiler_rt_runtime(clang_rt.dfsan-${arch} ${arch} STATIC
@@ -30,7 +30,7 @@ if(CAN_TARGET_${arch})
add_dependencies(dfsan
clang_rt.dfsan-${arch}
clang_rt.dfsan-${arch}-symbols)
-endif()
+endforeach()
set(dfsan_abilist_filename ${COMPILER_RT_OUTPUT_DIR}/dfsan_abilist.txt)
add_custom_target(dfsan_abilist ALL
diff --git a/lib/dfsan/Makefile.mk b/lib/dfsan/Makefile.mk
deleted file mode 100644
index 4aeaac42d..000000000
--- a/lib/dfsan/Makefile.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-#===- lib/dfsan/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 := dfsan
-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)/../sanitizer_common/*.h)
-
-# Define a convenience variable for all the dfsan functions.
-DfsanFunctions := $(Sources:%.cc=%)
diff --git a/lib/dfsan/dfsan.cc b/lib/dfsan/dfsan.cc
index dcc52b1bc..de5b2ce10 100644
--- a/lib/dfsan/dfsan.cc
+++ b/lib/dfsan/dfsan.cc
@@ -22,6 +22,7 @@
#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_flags.h"
+#include "sanitizer_common/sanitizer_flag_parser.h"
#include "sanitizer_common/sanitizer_libc.h"
#include "dfsan/dfsan.h"
@@ -63,12 +64,37 @@ SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL dfsan_label __dfsan_arg_tls[64];
// account for the double byte representation of shadow labels and move the
// address into the shadow memory range. See the function shadow_for below.
+// On Linux/MIPS64, memory is laid out as follows:
+//
+// +--------------------+ 0x10000000000 (top of memory)
+// | application memory |
+// +--------------------+ 0xF000008000 (kAppAddr)
+// | |
+// | unused |
+// | |
+// +--------------------+ 0x2200000000 (kUnusedAddr)
+// | union table |
+// +--------------------+ 0x2000000000 (kUnionTableAddr)
+// | shadow memory |
+// +--------------------+ 0x0000010000 (kShadowAddr)
+// | reserved by kernel |
+// +--------------------+ 0x0000000000
+
typedef atomic_dfsan_label dfsan_union_table_t[kNumLabels][kNumLabels];
+#if defined(__x86_64__)
static const uptr kShadowAddr = 0x10000;
static const uptr kUnionTableAddr = 0x200000000000;
static const uptr kUnusedAddr = kUnionTableAddr + sizeof(dfsan_union_table_t);
static const uptr kAppAddr = 0x700000008000;
+#elif defined(__mips64)
+static const uptr kShadowAddr = 0x10000;
+static const uptr kUnionTableAddr = 0x2000000000;
+static const uptr kUnusedAddr = kUnionTableAddr + sizeof(dfsan_union_table_t);
+static const uptr kAppAddr = 0xF000008000;
+#else
+# error "DFSan not supported for this platform!"
+#endif
static atomic_dfsan_label *union_table(dfsan_label l1, dfsan_label l2) {
return &(*(dfsan_union_table_t *) kUnionTableAddr)[l1][l2];
@@ -231,7 +257,7 @@ dfsan_read_label(const void *addr, uptr size) {
return __dfsan_union_load(shadow_for(addr), size);
}
-SANITIZER_INTERFACE_ATTRIBUTE
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE
const struct dfsan_label_info *dfsan_get_label_info(dfsan_label label) {
return &__dfsan_label_info[label];
}
@@ -285,16 +311,24 @@ dfsan_dump_labels(int fd) {
}
}
-static void InitializeFlags(Flags &f, const char *env) {
- f.warn_unimplemented = true;
- f.warn_nonzero_labels = false;
- f.strict_data_dependencies = true;
- f.dump_labels_at_exit = "";
+void Flags::SetDefaults() {
+#define DFSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
+#include "dfsan_flags.inc"
+#undef DFSAN_FLAG
+}
+
+static void RegisterDfsanFlags(FlagParser *parser, Flags *f) {
+#define DFSAN_FLAG(Type, Name, DefaultValue, Description) \
+ RegisterFlag(parser, #Name, Description, &f->Name);
+#include "dfsan_flags.inc"
+#undef DFSAN_FLAG
+}
- ParseFlag(env, &f.warn_unimplemented, "warn_unimplemented", "");
- ParseFlag(env, &f.warn_nonzero_labels, "warn_nonzero_labels", "");
- ParseFlag(env, &f.strict_data_dependencies, "strict_data_dependencies", "");
- ParseFlag(env, &f.dump_labels_at_exit, "dump_labels_at_exit", "");
+static void InitializeFlags() {
+ FlagParser parser;
+ RegisterDfsanFlags(&parser, &flags());
+ flags().SetDefaults();
+ parser.ParseString(GetEnv("DFSAN_OPTIONS"));
}
static void dfsan_fini() {
@@ -329,8 +363,7 @@ static void dfsan_init(int argc, char **argv, char **envp) {
if (!(init_addr >= kUnusedAddr && init_addr < kAppAddr))
Mprotect(kUnusedAddr, kAppAddr - kUnusedAddr);
- InitializeFlags(flags(), GetEnv("DFSAN_OPTIONS"));
-
+ InitializeFlags();
InitializeInterceptors();
// Register the fini callback to run when the program terminates successfully
diff --git a/lib/dfsan/dfsan.h b/lib/dfsan/dfsan.h
index 1b6c15091..ceba3533a 100644
--- a/lib/dfsan/dfsan.h
+++ b/lib/dfsan/dfsan.h
@@ -44,7 +44,11 @@ namespace __dfsan {
void InitializeInterceptors();
inline dfsan_label *shadow_for(void *ptr) {
+#if defined(__x86_64__)
return (dfsan_label *) ((((uptr) ptr) & ~0x700000000000) << 1);
+#elif defined(__mips64)
+ return (dfsan_label *) ((((uptr) ptr) & ~0xF000000000) << 1);
+#endif
}
inline const dfsan_label *shadow_for(const void *ptr) {
@@ -52,17 +56,11 @@ inline const dfsan_label *shadow_for(const void *ptr) {
}
struct Flags {
- // Whether to warn on unimplemented functions.
- bool warn_unimplemented;
- // Whether to warn on non-zero labels.
- bool warn_nonzero_labels;
- // Whether to propagate labels only when there is an obvious data dependency
- // (e.g., when comparing strings, ignore the fact that the output of the
- // comparison might be data-dependent on the content of the strings). This
- // applies only to the custom functions defined in 'custom.c'.
- bool strict_data_dependencies;
- // The path of the file where to dump the labels when the program terminates.
- const char* dump_labels_at_exit;
+#define DFSAN_FLAG(Type, Name, DefaultValue, Description) Type Name;
+#include "dfsan_flags.inc"
+#undef DFSAN_FLAG
+
+ void SetDefaults();
};
extern Flags flags_data;
diff --git a/lib/dfsan/dfsan_custom.cc b/lib/dfsan/dfsan_custom.cc
index 839a399fa..318ecd6fb 100644
--- a/lib/dfsan/dfsan_custom.cc
+++ b/lib/dfsan/dfsan_custom.cc
@@ -314,11 +314,12 @@ static void unpoison(const void *ptr, uptr size) {
SANITIZER_INTERFACE_ATTRIBUTE void *
__dfsw_dlopen(const char *filename, int flag, dfsan_label filename_label,
dfsan_label flag_label, dfsan_label *ret_label) {
- link_map *map = (link_map *)dlopen(filename, flag);
+ void *handle = dlopen(filename, flag);
+ link_map *map = GET_LINK_MAP_BY_DLOPEN_HANDLE(handle);
if (map)
ForEachMappedRegion(map, unpoison);
*ret_label = 0;
- return (void *)map;
+ return handle;
}
struct pthread_create_info {
diff --git a/lib/dfsan/dfsan_flags.inc b/lib/dfsan/dfsan_flags.inc
new file mode 100644
index 000000000..24fbfcb9e
--- /dev/null
+++ b/lib/dfsan/dfsan_flags.inc
@@ -0,0 +1,32 @@
+//===-- dfsan_flags.inc -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// DFSan runtime flags.
+//
+//===----------------------------------------------------------------------===//
+#ifndef DFSAN_FLAG
+# error "Define DFSAN_FLAG prior to including this file!"
+#endif
+
+// DFSAN_FLAG(Type, Name, DefaultValue, Description)
+// See COMMON_FLAG in sanitizer_flags.inc for more details.
+
+DFSAN_FLAG(bool, warn_unimplemented, true,
+ "Whether to warn on unimplemented functions.")
+DFSAN_FLAG(bool, warn_nonzero_labels, false,
+ "Whether to warn on unimplemented functions.")
+DFSAN_FLAG(
+ bool, strict_data_dependencies, true,
+ "Whether to propagate labels only when there is an obvious data dependency"
+ "(e.g., when comparing strings, ignore the fact that the output of the"
+ "comparison might be data-dependent on the content of the strings). This"
+ "applies only to the custom functions defined in 'custom.c'.")
+DFSAN_FLAG(const char *, dump_labels_at_exit, "", "The path of the file where "
+ "to dump the labels when the "
+ "program terminates.")