Skip to content

Commit

Permalink
[asan] Fix a false positive ODR violation due to LTO ConstantMerge pa…
Browse files Browse the repository at this point in the history
…ss [llvm part, take 3]

This fixes a false positive ODR violation that is reported by ASan when using LTO. In cases, where two constant globals have the same value, LTO will merge them, which breaks ASan's ODR detection.

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

llvm-svn: 327061
  • Loading branch information
kubamracek committed Mar 8, 2018
1 parent 0f701c4 commit 8842da8
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
10 changes: 10 additions & 0 deletions llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
Expand Up @@ -2158,6 +2158,16 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M, bool
Initializers[i] = Initializer;
}

// Add instrumented globals to llvm.compiler.used list to avoid LTO from
// ConstantMerge'ing them.
SmallVector<GlobalValue *, 16> GlobalsToAddToUsedList;
for (size_t i = 0; i < n; i++) {
GlobalVariable *G = NewGlobals[i];
if (G->getName().empty()) continue;
GlobalsToAddToUsedList.push_back(G);
}
appendToCompilerUsed(M, ArrayRef<GlobalValue *>(GlobalsToAddToUsedList));

std::string ELFUniqueModuleId =
(UseGlobalsGC && TargetTriple.isOSBinFormatELF()) ? getUniqueModuleId(&M)
: "";
Expand Down
30 changes: 30 additions & 0 deletions llvm/test/Instrumentation/AddressSanitizer/global_lto_merge.ll
@@ -0,0 +1,30 @@
; RUN: opt < %s -asan -asan-module -S | FileCheck %s
; RUN: opt < %s -asan -asan-module -constmerge -S | FileCheck %s

target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.11.0"

%struct = type { i64, i64 }

@a = private unnamed_addr constant %struct { i64 16, i64 16 }, align 8
@b = private unnamed_addr constant %struct { i64 16, i64 16 }, align 8

; CHECK: @a = {{.*}} %struct
; CHECK: @b = {{.*}} %struct

; CHECK: @llvm.compiler.used =
; CHECK-SAME: i8* bitcast ({ %struct, [48 x i8] }* @a to i8*)
; CHECK-SAME: i8* bitcast ({ %struct, [48 x i8] }* @b to i8*)

define i32 @main(i32, i8** nocapture readnone) {
%3 = alloca %struct, align 8
%4 = alloca %struct, align 8
%5 = bitcast %struct* %3 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull %5, i8* bitcast (%struct* @a to i8*), i64 16, i32 8, i1 false)
%6 = bitcast %struct* %4 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull %6, i8* bitcast (%struct* @b to i8*), i64 16, i32 8, i1 false)
call void asm sideeffect "", "r,r,~{dirflag},~{fpsr},~{flags}"(%struct* nonnull %3, %struct* nonnull %4)
ret i32 0
}

declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1)

0 comments on commit 8842da8

Please sign in to comment.