[compiler-rt] r264644 - [asan] Add runtime support for __asan_(un)register_image_globals

Ryan Govostes via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 28 13:28:18 PDT 2016


Author: rgov
Date: Mon Mar 28 15:28:17 2016
New Revision: 264644

URL: http://llvm.org/viewvc/llvm-project?rev=264644&view=rev
Log:
[asan] Add runtime support for __asan_(un)register_image_globals

This change introduces routines that register and unregister all
instrumented globals in a loaded executable image.

These routines are only implemented on Darwin, where globals metadata
is expected to be placed in the __DATA,__asan_globals section.

Review: http://reviews.llvm.org/D16841

Added:
    compiler-rt/trunk/test/asan/TestCases/Darwin/dead-strip.c
Modified:
    compiler-rt/trunk/lib/asan/asan_globals.cc
    compiler-rt/trunk/lib/asan/asan_init_version.h
    compiler-rt/trunk/lib/asan/asan_interface_internal.h
    compiler-rt/trunk/lib/asan/asan_internal.h
    compiler-rt/trunk/lib/asan/asan_linux.cc
    compiler-rt/trunk/lib/asan/asan_mac.cc
    compiler-rt/trunk/lib/asan/asan_win.cc
    compiler-rt/trunk/test/asan/TestCases/initialization-bug.cc

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=264644&r1=264643&r2=264644&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_globals.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_globals.cc Mon Mar 28 15:28:17 2016
@@ -284,6 +284,25 @@ void StopInitOrderChecking() {
 // ---------------------- Interface ---------------- {{{1
 using namespace __asan;  // NOLINT
 
+
+// Apply __asan_register_globals to all globals found in the same loaded
+// executable or shared library as `flag'. The flag tracks whether globals have
+// already been registered or not for this image.
+void __asan_register_image_globals(uptr *flag) {
+  if (*flag)
+    return;
+  AsanApplyToGlobals(__asan_register_globals, flag);
+  *flag = 1;
+}
+
+// This mirrors __asan_register_image_globals.
+void __asan_unregister_image_globals(uptr *flag) {
+  if (!*flag)
+    return;
+  AsanApplyToGlobals(__asan_unregister_globals, flag);
+  *flag = 0;
+}
+
 // Register an array of globals.
 void __asan_register_globals(__asan_global *globals, uptr n) {
   if (!flags()->report_globals) return;

Modified: compiler-rt/trunk/lib/asan/asan_init_version.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_init_version.h?rev=264644&r1=264643&r2=264644&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_init_version.h (original)
+++ compiler-rt/trunk/lib/asan/asan_init_version.h Mon Mar 28 15:28:17 2016
@@ -19,17 +19,20 @@ extern "C" {
   // Every time the ASan ABI changes we also change the version number in the
   // __asan_init function name.  Objects built with incompatible ASan ABI
   // versions will not link with run-time.
+  //
   // Changes between ABI versions:
   // v1=>v2: added 'module_name' to __asan_global
   // v2=>v3: stack frame description (created by the compiler)
-  //         contains the function PC as the 3-rd field (see
-  //         DescribeAddressIfStack).
-  // v3=>v4: added '__asan_global_source_location' to __asan_global.
+  //         contains the function PC as the 3rd field (see
+  //         DescribeAddressIfStack)
+  // v3=>v4: added '__asan_global_source_location' to __asan_global
   // v4=>v5: changed the semantics and format of __asan_stack_malloc_ and
-  //         __asan_stack_free_ functions.
+  //         __asan_stack_free_ functions
   // v5=>v6: changed the name of the version check symbol
-  // v6=>v7: added 'odr_indicator' to __asan_global.
-  #define __asan_version_mismatch_check __asan_version_mismatch_check_v7
+  // v6=>v7: added 'odr_indicator' to __asan_global
+  // v7=>v8: added '__asan_(un)register_image_globals' functions for dead
+  //         stripping support on Mach-O platforms
+  #define __asan_version_mismatch_check __asan_version_mismatch_check_v8
 }
 
 #endif  // ASAN_INIT_VERSION_H

Modified: compiler-rt/trunk/lib/asan/asan_interface_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interface_internal.h?rev=264644&r1=264643&r2=264644&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interface_internal.h (original)
+++ compiler-rt/trunk/lib/asan/asan_interface_internal.h Mon Mar 28 15:28:17 2016
@@ -57,6 +57,14 @@ extern "C" {
     uptr odr_indicator;      // The address of the ODR indicator symbol.
   };
 
+  // These functions can be called on some platforms to find globals in the same
+  // loaded image as `flag' and apply __asan_(un)register_globals to them,
+  // filtering out redundant calls.
+  SANITIZER_INTERFACE_ATTRIBUTE
+  void __asan_register_image_globals(uptr *flag);
+  SANITIZER_INTERFACE_ATTRIBUTE
+  void __asan_unregister_image_globals(uptr *flag);
+
   // These two functions should be called by the instrumented code.
   // 'globals' is an array of structures describing 'n' globals.
   SANITIZER_INTERFACE_ATTRIBUTE

Modified: compiler-rt/trunk/lib/asan/asan_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_internal.h?rev=264644&r1=264643&r2=264644&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_internal.h (original)
+++ compiler-rt/trunk/lib/asan/asan_internal.h Mon Mar 28 15:28:17 2016
@@ -73,6 +73,13 @@ void *AsanDoesNotSupportStaticLinkage();
 void AsanCheckDynamicRTPrereqs();
 void AsanCheckIncompatibleRT();
 
+// Support function for __asan_(un)register_image_globals. Searches for the
+// loaded image containing `needle' and then enumerates all global metadata
+// structures declared in that image, applying `op' (e.g.,
+// __asan_(un)register_globals) to them.
+typedef void (*globals_op_fptr)(__asan_global *, uptr);
+void AsanApplyToGlobals(globals_op_fptr op, const void *needle);
+
 void AsanOnDeadlySignal(int, void *siginfo, void *context);
 
 void ReadContextStack(void *context, uptr *stack, uptr *ssize);

Modified: compiler-rt/trunk/lib/asan/asan_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_linux.cc?rev=264644&r1=264643&r2=264644&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_linux.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_linux.cc Mon Mar 28 15:28:17 2016
@@ -75,6 +75,10 @@ void *AsanDoesNotSupportStaticLinkage()
   return &_DYNAMIC;  // defined in link.h
 }
 
+void AsanApplyToGlobals(globals_op_fptr op, const void *needle) {
+  UNIMPLEMENTED();
+}
+
 #if SANITIZER_ANDROID
 // FIXME: should we do anything for Android?
 void AsanCheckDynamicRTPrereqs() {}

Modified: compiler-rt/trunk/lib/asan/asan_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.cc?rev=264644&r1=264643&r2=264644&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_mac.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_mac.cc Mon Mar 28 15:28:17 2016
@@ -24,9 +24,11 @@
 #include "sanitizer_common/sanitizer_libc.h"
 #include "sanitizer_common/sanitizer_mac.h"
 
+#include <dlfcn.h>
 #include <fcntl.h>
 #include <libkern/OSAtomic.h>
 #include <mach-o/dyld.h>
+#include <mach-o/getsect.h>
 #include <mach-o/loader.h>
 #include <pthread.h>
 #include <stdlib.h>  // for free()
@@ -66,6 +68,30 @@ void AsanCheckDynamicRTPrereqs() {}
 // No-op. Mac does not support static linkage anyway.
 void AsanCheckIncompatibleRT() {}
 
+void AsanApplyToGlobals(globals_op_fptr op, const void *needle) {
+  // Find the Mach-O header for the image containing the needle
+  Dl_info info;
+  int err = dladdr(needle, &info);
+  if (err == 0) return;
+
+#if __LP64__
+  const struct mach_header_64 *mh = (struct mach_header_64 *)info.dli_fbase;
+#else
+  const struct mach_header *mh = (struct mach_header *)info.dli_fbase;
+#endif
+
+  // Look up the __asan_globals section in that image and register its globals
+  unsigned long size = 0;
+  __asan_global *globals = (__asan_global *)getsectiondata(
+      mh,
+      "__DATA", "__asan_globals",
+      &size);
+
+  if (!globals) return;
+  if (size % sizeof(__asan_global) != 0) return;
+  op(globals, size / sizeof(__asan_global));
+}
+
 void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
   UNIMPLEMENTED();
 }

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=264644&r1=264643&r2=264644&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_win.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_win.cc Mon Mar 28 15:28:17 2016
@@ -149,6 +149,10 @@ void InitializePlatformInterceptors() {
       (uptr *)&REAL(NtWaitForWorkViaWorkerFactory)));
 }
 
+void AsanApplyToGlobals(globals_op_fptr op, const void *needle) {
+  UNIMPLEMENTED();
+}
+
 // ---------------------- TSD ---------------- {{{
 static bool tsd_key_inited = false;
 

Added: compiler-rt/trunk/test/asan/TestCases/Darwin/dead-strip.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Darwin/dead-strip.c?rev=264644&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Darwin/dead-strip.c (added)
+++ compiler-rt/trunk/test/asan/TestCases/Darwin/dead-strip.c Mon Mar 28 15:28:17 2016
@@ -0,0 +1,21 @@
+// Test that AddressSanitizer does not re-animate dead globals when dead
+// stripping is turned on.
+//
+// This test verifies that an out-of-bounds access on a global variable is
+// detected after dead stripping has been performed. This proves that the
+// runtime is able to register globals in the __DATA,__asan_globals section.
+
+// RUN: %clang_asan -Xlinker -dead_strip -o %t %s
+// RUN: llvm-nm -format=posix %t | FileCheck --check-prefix NM-CHECK %s
+// RUN: not %run %t 2>&1 | FileCheck --check-prefix ASAN-CHECK %s
+
+int alive[1] = {};
+int dead[1] = {};
+// NM-CHECK: {{^_alive }}
+// NM-CHECK-NOT: {{^_dead }}
+
+int main(int argc, char *argv[]) {
+  alive[argc] = 0;
+  // ASAN-CHECK: {{0x.* is located 0 bytes to the right of global variable}}
+  return 0;
+}

Modified: compiler-rt/trunk/test/asan/TestCases/initialization-bug.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/initialization-bug.cc?rev=264644&r1=264643&r2=264644&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/initialization-bug.cc (original)
+++ compiler-rt/trunk/test/asan/TestCases/initialization-bug.cc Mon Mar 28 15:28:17 2016
@@ -6,7 +6,7 @@
 // Do not test with optimization -- the error may be optimized away.
 
 // FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=186
-// XFAIL: darwin,win32
+// XFAIL: win32
 
 #include <cstdio>
 




More information about the llvm-commits mailing list