[compiler-rt] r287246 - [asan] Create a .ASAN$G(A-Z) section for global registration

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 17 11:02:53 PST 2016


Author: rnk
Date: Thu Nov 17 13:02:53 2016
New Revision: 287246

URL: http://llvm.org/viewvc/llvm-project?rev=287246&view=rev
Log:
[asan] Create a .ASAN$G(A-Z) section for global registration

Summary:
The expectation is that new instrumented code will add global variable
metadata to the .ASAN$GL section, and we will use this new code to
iterate over it.

This technique seems to break when using incremental linking, which
seems to align every global to a 256 byte boundary. Presumably this is
so that it can incrementally cope with global changing size. Clang
already passes -incremental:no as a linker flag when you invoke it to do
the link step.

The two tests added for this feature will fail until the LLVM
instrumentation change in D26770 lands, so they are marked XFAIL for
now.

Reviewers: pcc, kcc, mehdi_amini, kubabrecka

Subscribers: llvm-commits, mgorny

Differential Revision: https://reviews.llvm.org/D26771

Added:
    compiler-rt/trunk/lib/asan/asan_globals_win.cc
    compiler-rt/trunk/lib/asan/asan_globals_win.h
    compiler-rt/trunk/test/asan/TestCases/Windows/dll_global_dead_strip.c
    compiler-rt/trunk/test/asan/TestCases/Windows/global_dead_strip.c
Modified:
    compiler-rt/trunk/lib/asan/CMakeLists.txt
    compiler-rt/trunk/lib/asan/asan_globals.cc
    compiler-rt/trunk/lib/asan/asan_win.cc
    compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc
    compiler-rt/trunk/lib/asan/asan_win_dynamic_runtime_thunk.cc
    compiler-rt/trunk/lib/asan/tests/CMakeLists.txt

Modified: compiler-rt/trunk/lib/asan/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/CMakeLists.txt?rev=287246&r1=287245&r2=287246&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/asan/CMakeLists.txt Thu Nov 17 13:02:53 2016
@@ -9,6 +9,7 @@ set(ASAN_SOURCES
   asan_fake_stack.cc
   asan_flags.cc
   asan_globals.cc
+  asan_globals_win.cc
   asan_interceptors.cc
   asan_linux.cc
   asan_mac.cc
@@ -63,6 +64,7 @@ set(ASAN_DYNAMIC_CFLAGS ${ASAN_CFLAGS})
 append_list_if(COMPILER_RT_HAS_FTLS_MODEL_INITIAL_EXEC
   -ftls-model=initial-exec ASAN_DYNAMIC_CFLAGS)
 append_list_if(MSVC /DEBUG ASAN_DYNAMIC_LINK_FLAGS)
+append_list_if(MSVC /INCREMENTAL:NO ASAN_DYNAMIC_LINK_FLAGS)
 
 append_list_if(COMPILER_RT_HAS_LIBC c ASAN_DYNAMIC_LIBS)
 append_list_if(COMPILER_RT_HAS_LIBDL dl ASAN_DYNAMIC_LIBS)
@@ -205,6 +207,7 @@ else()
         STATIC
         ARCHS ${arch}
         SOURCES asan_win_dll_thunk.cc
+                asan_globals_win.cc
                 $<TARGET_OBJECTS:RTInterception.${arch}>
         CFLAGS ${ASAN_CFLAGS} -DASAN_DLL_THUNK
         DEFS ${ASAN_COMMON_DEFINITIONS}
@@ -221,6 +224,7 @@ else()
         STATIC
         ARCHS ${arch}
         SOURCES asan_win_dynamic_runtime_thunk.cc
+                asan_globals_win.cc
         CFLAGS ${ASAN_CFLAGS} ${DYNAMIC_RUNTIME_THUNK_CFLAGS}
         DEFS ${ASAN_COMMON_DEFINITIONS}
         PARENT_TARGET asan)

Modified: compiler-rt/trunk/lib/asan/asan_globals.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_globals.cc?rev=287246&r1=287245&r2=287246&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_globals.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_globals.cc Thu Nov 17 13:02:53 2016
@@ -192,6 +192,7 @@ static inline bool UseODRIndicator(const
 // This function may be called more than once for every global
 // so we store the globals in a map.
 static void RegisterGlobal(const Global *g) {
+  CHECK(g->beg);
   CHECK(asan_inited);
   if (flags()->report_globals >= 2)
     ReportGlobal(*g, "Added");

Added: compiler-rt/trunk/lib/asan/asan_globals_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_globals_win.cc?rev=287246&view=auto
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_globals_win.cc (added)
+++ compiler-rt/trunk/lib/asan/asan_globals_win.cc Thu Nov 17 13:02:53 2016
@@ -0,0 +1,54 @@
+//===-- asan_globals_win.cc -----------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Global registration code that is linked into every Windows DLL and EXE.
+//
+//===----------------------------------------------------------------------===//
+
+#include "asan_interface_internal.h"
+#if SANITIZER_WINDOWS
+
+namespace __asan {
+
+#pragma section(".ASAN$GA", read, write)  // NOLINT
+#pragma section(".ASAN$GZ", read, write)  // NOLINT
+extern "C" __declspec(allocate(".ASAN$GA"))
+uptr __asan_globals_start = 0;
+extern "C" __declspec(allocate(".ASAN$GZ"))
+uptr __asan_globals_end = 0;
+#pragma comment(linker, "/merge:.ASAN=.data")
+
+static void call_on_globals(void (*hook)(__asan_global *, uptr)) {
+  __asan_global *start = (__asan_global *)(&__asan_globals_start + 1);
+  __asan_global *end = (__asan_global *)&__asan_globals_end;
+  // We know end >= start because the linker sorts the portion after the dollar
+  // sign alphabetically.
+  uptr n = end - start;
+  hook(start, n);
+}
+
+static void register_dso_globals() {
+  call_on_globals(&__asan_register_globals);
+}
+
+static void unregister_dso_globals() {
+  call_on_globals(&__asan_unregister_globals);
+}
+
+// Register globals
+#pragma section(".CRT$XCU", long, read)  // NOLINT
+#pragma section(".CRT$XTX", long, read)  // NOLINT
+extern "C" __declspec(allocate(".CRT$XCU"))
+void (*const __asan_dso_reg_hook)() = &register_dso_globals;
+extern "C" __declspec(allocate(".CRT$XTX"))
+void (*const __asan_dso_unreg_hook)() = &unregister_dso_globals;
+
+} // namespace __asan
+
+#endif  // SANITIZER_WINDOWS

Added: compiler-rt/trunk/lib/asan/asan_globals_win.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_globals_win.h?rev=287246&view=auto
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_globals_win.h (added)
+++ compiler-rt/trunk/lib/asan/asan_globals_win.h Thu Nov 17 13:02:53 2016
@@ -0,0 +1,34 @@
+//===-- asan_globals_win.h --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Interface to the Windows-specific global management code. Separated into a
+// standalone header to allow inclusion from asan_win_dynamic_runtime_thunk,
+// which defines symbols that clash with other sanitizer headers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ASAN_GLOBALS_WIN_H
+#define ASAN_GLOBALS_WIN_H
+
+#if !defined(_MSC_VER)
+#error "this file is Windows-only, and uses MSVC pragmas"
+#endif
+
+#if defined(_WIN64)
+#define SANITIZER_SYM_PREFIX
+#else
+#define SANITIZER_SYM_PREFIX "_"
+#endif
+
+// Use this macro to force linking asan_globals_win.cc into the DSO.
+#define ASAN_LINK_GLOBALS_WIN() \
+  __pragma(                     \
+      comment(linker, "/include:" SANITIZER_SYM_PREFIX "__asan_dso_reg_hook"))
+
+#endif // ASAN_GLOBALS_WIN_H

Modified: compiler-rt/trunk/lib/asan/asan_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_win.cc?rev=287246&r1=287245&r2=287246&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_win.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_win.cc Thu Nov 17 13:02:53 2016
@@ -19,6 +19,7 @@
 
 #include <stdlib.h>
 
+#include "asan_globals_win.h"
 #include "asan_interceptors.h"
 #include "asan_internal.h"
 #include "asan_report.h"
@@ -367,8 +368,9 @@ __declspec(allocate(".CRT$XLAB")) void (
     unsigned long, void *) = asan_thread_init;
 #endif
 
+ASAN_LINK_GLOBALS_WIN()
 
 // }}}
 }  // namespace __asan
 
-#endif  // _WIN32
+#endif  // SANITIZER_WINDOWS

Modified: compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc?rev=287246&r1=287245&r2=287246&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc Thu Nov 17 13:02:53 2016
@@ -20,6 +20,7 @@
 // simplifies the build procedure.
 #ifdef ASAN_DLL_THUNK
 #include "asan_init_version.h"
+#include "asan_globals_win.h"
 #include "interception/interception.h"
 #include "sanitizer_common/sanitizer_platform_interceptors.h"
 
@@ -472,4 +473,6 @@ static void WINAPI asan_thread_init(void
 __declspec(allocate(".CRT$XLAB")) void (WINAPI *__asan_tls_init)(void *,
     unsigned long, void *) = asan_thread_init;
 
+ASAN_LINK_GLOBALS_WIN()
+
 #endif // ASAN_DLL_THUNK

Modified: compiler-rt/trunk/lib/asan/asan_win_dynamic_runtime_thunk.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_win_dynamic_runtime_thunk.cc?rev=287246&r1=287245&r2=287246&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_win_dynamic_runtime_thunk.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_win_dynamic_runtime_thunk.cc Thu Nov 17 13:02:53 2016
@@ -24,6 +24,7 @@
 // Using #ifdef rather than relying on Makefiles etc.
 // simplifies the build procedure.
 #ifdef ASAN_DYNAMIC_RUNTIME_THUNK
+#include "asan_globals_win.h"
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 
@@ -121,4 +122,6 @@ __declspec(allocate(".CRT$XCAB")) int (*
     SetSEHFilter;
 }
 
+ASAN_LINK_GLOBALS_WIN()
+
 #endif // ASAN_DYNAMIC_RUNTIME_THUNK

Modified: compiler-rt/trunk/lib/asan/tests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/tests/CMakeLists.txt?rev=287246&r1=287245&r2=287246&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/tests/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/asan/tests/CMakeLists.txt Thu Nov 17 13:02:53 2016
@@ -47,6 +47,8 @@ else()
 endif()
 if(MSVC)
   list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gcodeview)
+  # Incremental linking appears to break our global registration mechanism.
+  list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -Wl,-incremental:no)
 endif()
 list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -g)
 

Added: compiler-rt/trunk/test/asan/TestCases/Windows/dll_global_dead_strip.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Windows/dll_global_dead_strip.c?rev=287246&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Windows/dll_global_dead_strip.c (added)
+++ compiler-rt/trunk/test/asan/TestCases/Windows/dll_global_dead_strip.c Thu Nov 17 13:02:53 2016
@@ -0,0 +1,31 @@
+// RUN: %clang_cl_asan -O0 %p/dll_host.cc -Fe%t
+//
+// RUN: %clang_cl_asan -LD -O0 %s -Fe%t.dll
+// RUN: %env_asan_opts=report_globals=2 %run %t %t.dll 2>&1 | FileCheck %s --check-prefix=NOSTRIP
+// RUN: %clang_cl_asan -LD -O2 %s -Fe%t.dll -link -opt:ref
+// RUN: %env_asan_opts=report_globals=2 %run %t %t.dll 2>&1 | FileCheck %s --check-prefix=STRIP
+
+// FIXME: Remove the XFAIL once the LLVM instrumentation change lands.
+// XFAIL: *
+
+#include <stdio.h>
+
+int dead_global = 42;
+int live_global = 0;
+
+__declspec(dllexport)
+int test_function() {
+  puts("main");
+  return live_global;
+}
+
+// Check that our global registration scheme works with MSVC's linker dead
+// stripping (/OPT:REF).
+
+// NOSTRIP: Added Global{{.*}}name=dead_global
+// NOSTRIP: Added Global{{.*}}name=live_global
+// NOSTRIP: main
+
+// STRIP-NOT: Added Global{{.*}}name=dead_global
+// STRIP: Added Global{{.*}}name=live_global
+// STRIP: main

Added: compiler-rt/trunk/test/asan/TestCases/Windows/global_dead_strip.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Windows/global_dead_strip.c?rev=287246&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Windows/global_dead_strip.c (added)
+++ compiler-rt/trunk/test/asan/TestCases/Windows/global_dead_strip.c Thu Nov 17 13:02:53 2016
@@ -0,0 +1,26 @@
+// RUN: %clang_cl_asan /O0 %s /Fe%t.exe
+// RUN: %env_asan_opts=report_globals=2 %t.exe 2>&1 | FileCheck %s --check-prefix=NOSTRIP
+// RUN: %clang_cl_asan /O2 %s /Fe%t.exe -link -opt:ref
+// RUN: %env_asan_opts=report_globals=2 %t.exe 2>&1 | FileCheck %s --check-prefix=STRIP
+
+// FIXME: Remove the XFAIL once the LLVM instrumentation change lands.
+// XFAIL: *
+
+#include <stdio.h>
+int dead_global = 42;
+int live_global = 0;
+int main() {
+  puts("main");
+  return live_global;
+}
+
+// Check that our global registration scheme works with MSVC's linker dead
+// stripping (/OPT:REF).
+
+// NOSTRIP: Added Global{{.*}}name=dead_global
+// NOSTRIP: Added Global{{.*}}name=live_global
+// NOSTRIP: main
+
+// STRIP-NOT: Added Global{{.*}}name=dead_global
+// STRIP: Added Global{{.*}}name=live_global
+// STRIP: main




More information about the llvm-commits mailing list