[PATCH] D11004: [asan] Change ABI versioning to include release numbers

Kuba Brecka kuba.brecka at gmail.com
Tue Jul 7 10:38:48 PDT 2015


kubabrecka added reviewers: glider, samsonov, kcc.
kubabrecka added subscribers: llvm-commits, glider, samsonov, kcc, zaks.anna.

Hi everyone,

I'd like to propose a change in the way we version the ASan libraries (and other sanitizers as well), and I'd like to get feedback on this proposal.  We currently have the "ABI version" number embedded into the ASan initializer symbol name (`__asan_init_v5`), which is occasionally bumped when there is a significant ABI-breaking change.  My understanding is that this number doesn't guarantee compatibility.  It indicates that the ABI changed, but there might have been smaller incompatible changes when the version is unchanged.  This can easily cause issues especially when using dynamic libraries (.dylib, .so), because they are (and need to be) distributed with applications and libraries, so users can easily end up using a stale version of the ASan library.

I'd like to include the LLVM release number into that symbol name so users are actually forced to use the library that was distributed with the compiler they used.  We should also provide a way for vendors who make their own releases to change this version to indicate that it's a different build than the open-source one.  Local (development) builds should also have a different version.  This could reuse a version-string schema already used by Clang.

Secondly, I'd like to make the error message about a version mismatch clearer by changing the name of the undefined symbol to be something like `__asan_version_mismatch_check_xxx` (following by the version string).  We obviously don't want the initializer to be named like that, so it's a separate symbol.

Attached is an incomplete (work in progress, llvm backend part missing) patch which outlines how this could be done.

Any feedback is welcome!

Kuba


http://reviews.llvm.org/D11004

Files:
  CMakeLists.txt
  lib/asan/asan_init_version.h
  lib/asan/asan_rtl.cc

Index: lib/asan/asan_rtl.cc
===================================================================
--- lib/asan/asan_rtl.cc
+++ lib/asan/asan_rtl.cc
@@ -578,3 +578,7 @@
   AsanActivate();
   AsanInitInternal();
 }
+
+void __asan_version_mismatch_check() {
+  // Do nothing.
+}
Index: lib/asan/asan_init_version.h
===================================================================
--- lib/asan/asan_init_version.h
+++ lib/asan/asan_init_version.h
@@ -27,8 +27,15 @@
   // 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.
-  #define __asan_init __asan_init_v5
-  #define __asan_init_name "__asan_init_v5"
+  // v5=>v6: changed versioning scheme to include LLVM release number
+
+  #define ABI_VERSION v6
+
+  #define CONCAT(x, y) CONCAT2(x, y)
+  #define CONCAT2(x, y) __asan_version_mismatch_check__abi_ ## x ## __ ## y
+  #define __asan_version_mismatch_check CONCAT(ABI_VERSION, COMPILER_RT_VERSION_STRING)
+  
+  SANITIZER_INTERFACE_ATTRIBUTE void __asan_version_mismatch_check();
 }
 
 #endif  // ASAN_INIT_VERSION_H
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt
+++ CMakeLists.txt
@@ -49,6 +49,14 @@
   #        in Clang cmake files, instead of copying the rules here.
   string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" CLANG_VERSION
          ${PACKAGE_VERSION})
+
+  # Compute the version identifier that will be used in a symbol name to prevent version mismatches.
+  set(DEFAULT_COMPILER_RT_VERSION_STRING "llvm-${PACKAGE_VERSION}")
+  set(COMPILER_RT_VERSION_STRING ${DEFAULT_COMPILER_RT_VERSION_STRING} CACHE STRING
+    "Version identifier for the compiler-rt libraries.")
+  string(REGEX REPLACE "[^a-zA-Z0-9]" "_" COMPILER_RT_VERSION_STRING ${COMPILER_RT_VERSION_STRING})
+  list(APPEND SANITIZER_COMMON_CFLAGS -DCOMPILER_RT_VERSION_STRING=${COMPILER_RT_VERSION_STRING})
+
   # Setup the paths where compiler-rt runtimes and headers should be stored.
   set(COMPILER_RT_OUTPUT_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION})
   set(COMPILER_RT_EXEC_OUTPUT_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D11004.29191.patch
Type: text/x-patch
Size: 2210 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150707/9a4d09db/attachment.bin>


More information about the llvm-commits mailing list