hctim updated this revision to Diff 425379.
hctim added a comment.
Wrong base, updating.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D124493/new/
https://reviews.llvm.org/D124493
Files:
clang/lib/CodeGen/BackendUtil.cpp
clang/lib/CodeGen/CGDecl.cpp
clang/lib/CodeGen/CGExpr.cpp
clang/lib/CodeGen/CGStmt.cpp
clang/lib/CodeGen/CMakeLists.txt
clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/CodeGen/CodeGenModule.cpp
clang/lib/CodeGen/CodeGenModule.h
clang/lib/CodeGen/ItaniumCXXABI.cpp
clang/lib/CodeGen/SanitizerMetadata.cpp
clang/lib/CodeGen/SanitizerMetadata.h
clang/lib/CodeGen/SanitizerMetadataFactory.cpp
clang/lib/CodeGen/SanitizerMetadataFactory.h
clang/test/CodeGen/asan-globals-alias.cpp
clang/test/CodeGen/asan-globals-odr.cpp
clang/test/CodeGen/asan-globals.cpp
clang/test/CodeGen/asan-static-odr.cpp
clang/test/CodeGen/asan-strings.c
clang/test/CodeGen/sanitize-init-order.cpp
clang/test/CodeGen/ubsan-strip-path-components.cpp
clang/test/CodeGenCXX/catch-undef-behavior.cpp
clang/test/CodeGenCXX/type-metadata.cpp
compiler-rt/lib/asan/asan_globals.cpp
compiler-rt/lib/asan/asan_interface_internal.h
compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
compiler-rt/test/asan/TestCases/Linux/odr-violation.cpp
compiler-rt/test/asan/TestCases/global-location.cpp
llvm/include/llvm/AsmParser/LLParser.h
llvm/include/llvm/AsmParser/LLToken.h
llvm/include/llvm/IR/GlobalValue.h
llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
llvm/lib/AsmParser/LLLexer.cpp
llvm/lib/AsmParser/LLParser.cpp
llvm/lib/Bitcode/Reader/BitcodeReader.cpp
llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
llvm/lib/IR/AsmWriter.cpp
llvm/lib/IR/Globals.cpp
llvm/lib/IR/LLVMContextImpl.h
llvm/lib/Passes/PassRegistry.def
llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
llvm/test/Instrumentation/AddressSanitizer/global_metadata.ll
llvm/test/Instrumentation/AddressSanitizer/global_metadata_array.ll
llvm/test/Instrumentation/AddressSanitizer/global_with_comdat.ll
llvm/test/Instrumentation/AddressSanitizer/instrument_global.ll
llvm/test/Instrumentation/AddressSanitizer/instrument_initializer_metadata.ll
llvm/test/Instrumentation/AddressSanitizer/win-string-literal.ll
llvm/test/Instrumentation/SanitizerCoverage/tracing-comdat.ll
llvm/tools/opt/NewPMDriver.cpp
Index: llvm/tools/opt/NewPMDriver.cpp
===================================================================
--- llvm/tools/opt/NewPMDriver.cpp
+++ llvm/tools/opt/NewPMDriver.cpp
@@ -357,8 +357,6 @@
ArrayRef<PassBuilder::PipelineElement>) {
AddressSanitizerOptions Opts;
if (Name == "asan-pipeline") {
- MPM.addPass(
- RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
MPM.addPass(ModuleAddressSanitizerPass(Opts));
return true;
}
Index: llvm/test/Instrumentation/SanitizerCoverage/tracing-comdat.ll
===================================================================
--- llvm/test/Instrumentation/SanitizerCoverage/tracing-comdat.ll
+++ llvm/test/Instrumentation/SanitizerCoverage/tracing-comdat.ll
@@ -2,7 +2,7 @@
; Make sure asan does not instrument __sancov_gen_
; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s
-; RUN: opt < %s -passes='module(require<asan-globals-md>,sancov-module,asan-module)' -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s
+; RUN: opt < %s -passes='module(sancov-module,asan-module)' -sanitizer-coverage-level=3 -sanitizer-coverage-trace-pc-guard -S | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
$Foo = comdat any
Index: llvm/test/Instrumentation/AddressSanitizer/win-string-literal.ll
===================================================================
--- llvm/test/Instrumentation/AddressSanitizer/win-string-literal.ll
+++ llvm/test/Instrumentation/AddressSanitizer/win-string-literal.ll
@@ -10,13 +10,12 @@
; CHECK-SAME: linkonce_odr dso_local constant { [5 x i8], [27 x i8] }
; CHECK-SAME: { [5 x i8] c"asdf\00", [27 x i8] zeroinitializer }, comdat, align 32
-; CHECK: @"__asan_global_??_C@_04JIHMPGLA@asdf?$AA@" =
+; CHECK: @"__asan_global_??_C@_04JIHMPGLA@asdf?$AA@" =
; CHECK-SAME: private global { i64, i64, i64, i64, i64, i64, i64, i64 }
; CHECK-SAME: { i64 ptrtoint ({ [5 x i8], [27 x i8] }* @"??_C@_04JIHMPGLA@asdf?$AA@" to i64),
-; CHECK-SAME: i64 5, i64 32, i64 ptrtoint ([17 x i8]* @___asan_gen_.1 to i64),
-; CHECK-SAME: i64 ptrtoint ([8 x i8]* @___asan_gen_ to i64), i64 0,
-; CHECK-SAME: i64 ptrtoint ({ [6 x i8]*, i32, i32 }* @___asan_gen_.3 to i64), i64 0 },
-; CHECK-SAME: section ".ASAN$GL", comdat($"??_C@_04JIHMPGLA@asdf?$AA@"), align 64
+; CHECK-SAME: i64 5, i64 32, i64 ptrtoint ([7 x i8]* @___asan_gen_.1 to i64), i64 ptrtoint ([8
+; CHECK-SAME: x i8]* @___asan_gen_ to i64), i64 0, i64 0, i64 0 }, section ".ASAN$GL",
+; CHECK-SAME: comdat($"??_C@_04JIHMPGLA@asdf?$AA@"), align 64
; ModuleID = 't.cpp'
source_filename = "t.cpp"
@@ -35,11 +34,9 @@
attributes #0 = { nounwind sanitize_address uwtable }
-!llvm.asan.globals = !{!0}
!llvm.module.flags = !{!2, !3}
!llvm.ident = !{!4}
-!0 = !{[5 x i8]* @"??_C@_04JIHMPGLA@asdf?$AA@", !1, !"<string literal>", i1 false, i1 false}
!1 = !{!"t.cpp", i32 1, i32 31}
!2 = !{i32 1, !"wchar_size", i32 2}
!3 = !{i32 7, !"PIC Level", i32 2}
Index: llvm/test/Instrumentation/AddressSanitizer/instrument_initializer_metadata.ll
===================================================================
--- llvm/test/Instrumentation/AddressSanitizer/instrument_initializer_metadata.ll
+++ llvm/test/Instrumentation/AddressSanitizer/instrument_initializer_metadata.ll
@@ -2,17 +2,10 @@
; RUN: opt < %s -passes='asan-pipeline' -asan-mapping-scale=5 -S | FileCheck %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-unknown-linux-gnu"
-@xxx = internal global i32 0, align 4 ; With dynamic initializer.
-@XXX = global i32 0, align 4 ; With dynamic initializer.
-@yyy = internal global i32 0, align 4 ; W/o dynamic initializer.
-@YYY = global i32 0, align 4 ; W/o dynamic initializer.
-; Clang will emit the following metadata identifying @xxx as dynamically
-; initialized.
-!0 = !{i32* @xxx, null, null, i1 true, i1 false}
-!1 = !{i32* @XXX, null, null, i1 true, i1 false}
-!2 = !{i32* @yyy, null, null, i1 false, i1 false}
-!3 = !{i32* @YYY, null, null, i1 false, i1 false}
-!llvm.asan.globals = !{!0, !1, !2, !3}
+@xxx = internal global i32 0, align 4, sanitize_address, sanitize_address_dyninit ; With dynamic initializer.
+@XXX = global i32 0, align 4, sanitize_address, sanitize_address_dyninit ; With dynamic initializer.
+@yyy = internal global i32 0, align 4, sanitize_address ; W/o dynamic initializer.
+@YYY = global i32 0, align 4, sanitize_address ; W/o dynamic initializer.
define i32 @initializer() uwtable {
entry:
Index: llvm/test/Instrumentation/AddressSanitizer/instrument_global.ll
===================================================================
--- llvm/test/Instrumentation/AddressSanitizer/instrument_global.ll
+++ llvm/test/Instrumentation/AddressSanitizer/instrument_global.ll
@@ -15,9 +15,9 @@
; Test that we don't instrument global arrays with static initializer
; indexed with constants in-bounds. But instrument all other cases.
-@GlobSt = global [10 x i32] zeroinitializer, align 16 ; static initializer
-@GlobDy = global [10 x i32] zeroinitializer, align 16 ; dynamic initializer
-@GlobEx = external global [10 x i32] , align 16 ; extern initializer
+@GlobSt = global [10 x i32] zeroinitializer, align 16, sanitize_address ; static initializer
+@GlobDy = global [10 x i32] zeroinitializer, align 16, sanitize_address, sanitize_address_dyninit ; dynamic initializer
+@GlobEx = external global [10 x i32] , align 16, sanitize_address ; extern initializer
; GlobSt is declared here, and has static initializer -- ok to optimize.
define i32 @AccessGlobSt_0_2() sanitize_address {
@@ -69,10 +69,6 @@
; CHECK: ret i32
}
-
-!llvm.asan.globals = !{!0}
-!0 = !{[10 x i32]* @GlobDy, null, null, i1 true, i1 false}
-
; CHECK-LABEL: define internal void @asan.module_ctor
; CHECK-NOT: ret
; CHECK: call void @__asan_register_elf_globals
Index: llvm/test/Instrumentation/AddressSanitizer/global_with_comdat.ll
===================================================================
--- llvm/test/Instrumentation/AddressSanitizer/global_with_comdat.ll
+++ llvm/test/Instrumentation/AddressSanitizer/global_with_comdat.ll
@@ -43,8 +43,6 @@
; Check emitted location descriptions:
; CHECK: [[VARNAME:@___asan_gen_.[0-9]+]] = private unnamed_addr constant [7 x i8] c"global\00", align 1
-; CHECK: [[FILENAME:@___asan_gen_.[0-9]+]] = private unnamed_addr constant [22 x i8] c"/tmp/asan-globals.cpp\00", align 1
-; CHECK: [[LOCDESCR:@___asan_gen_.[0-9]+]] = private unnamed_addr constant { [22 x i8]*, i32, i32 } { [22 x i8]* [[FILENAME]], i32 5, i32 5 }
; COMDAT: @__asan_global_global = {{.*}}i64 ptrtoint ({ i32, [28 x i8] }* @global to i64){{.*}} section "asan_globals"{{.*}}, !associated
; COMDAT: @__asan_global_.str = {{.*}}i64 ptrtoint ({ [14 x i8], [18 x i8] }* @{{.str|1}} to i64){{.*}} section "asan_globals"{{.*}}, !associated
@@ -81,15 +79,8 @@
attributes #0 = { nounwind sanitize_address }
attributes #1 = { nounwind sanitize_address "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
-!llvm.asan.globals = !{!0, !1, !2, !3, !4}
!llvm.ident = !{!5}
-!0 = !{i32* @global, !6, !"global", i1 false, i1 false}
-!1 = !{i32* @dyn_init_global, !7, !"dyn_init_global", i1 true, i1 false}
-!2 = !{i32* @blocked_global, null, null, i1 false, i1 true}
-!3 = !{i32* @_ZZ4funcvE10static_var, !8, !"static_var", i1 false, i1 false}
-!4 = !{[14 x i8]* @.str, !9, !"<string literal>", i1 false, i1 false}
-
!5 = !{!"clang version 3.5.0 (211282)"}
!6 = !{!"/tmp/asan-globals.cpp", i32 5, i32 5}
Index: llvm/test/Instrumentation/AddressSanitizer/global_metadata_array.ll
===================================================================
--- llvm/test/Instrumentation/AddressSanitizer/global_metadata_array.ll
+++ llvm/test/Instrumentation/AddressSanitizer/global_metadata_array.ll
@@ -19,12 +19,9 @@
; Check emitted location descriptions:
; CHECK: [[VARNAME:@___asan_gen_.[0-9]+]] = private unnamed_addr constant [7 x i8] c"global\00", align 1
-; CHECK: [[FILENAME:@___asan_gen_.[0-9]+]] = private unnamed_addr constant [22 x i8] c"/tmp/asan-globals.cpp\00", align 1
-; CHECK: [[LOCDESCR:@___asan_gen_.[0-9]+]] = private unnamed_addr constant { [22 x i8]*, i32, i32 } { [22 x i8]* [[FILENAME]], i32 5, i32 5 }
; Check that location descriptors and global names were passed into __asan_register_globals:
; CHECK: i64 ptrtoint ([7 x i8]* [[VARNAME]] to i64)
-; CHECK: i64 ptrtoint ({ [22 x i8]*, i32, i32 }* [[LOCDESCR]] to i64)
; Check alignment of metadata_array.
; CHECK-S5-SAME: {{align 32$}}
@@ -54,15 +51,8 @@
attributes #0 = { nounwind sanitize_address }
attributes #1 = { nounwind sanitize_address "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
-!llvm.asan.globals = !{!0, !1, !2, !3, !4}
!llvm.ident = !{!5}
-!0 = !{i32* @global, !6, !"global", i1 false, i1 false}
-!1 = !{i32* @dyn_init_global, !7, !"dyn_init_global", i1 true, i1 false}
-!2 = !{i32* @blocked_global, null, null, i1 false, i1 true}
-!3 = !{i32* @_ZZ4funcvE10static_var, !8, !"static_var", i1 false, i1 false}
-!4 = !{[14 x i8]* @.str, !9, !"<string literal>", i1 false, i1 false}
-
!5 = !{!"clang version 3.5.0 (211282)"}
!6 = !{!"/tmp/asan-globals.cpp", i32 5, i32 5}
Index: llvm/test/Instrumentation/AddressSanitizer/global_metadata.ll
===================================================================
--- llvm/test/Instrumentation/AddressSanitizer/global_metadata.ll
+++ llvm/test/Instrumentation/AddressSanitizer/global_metadata.ll
@@ -21,12 +21,10 @@
; Check emitted location descriptions:
; CHECK: [[VARNAME:@___asan_gen_.[0-9]+]] = private unnamed_addr constant [7 x i8] c"global\00", align 1
-; CHECK: [[FILENAME:@___asan_gen_.[0-9]+]] = private unnamed_addr constant [22 x i8] c"/tmp/asan-globals.cpp\00", align 1
-; CHECK: [[LOCDESCR:@___asan_gen_.[0-9]+]] = private unnamed_addr constant { [22 x i8]*, i32, i32 } { [22 x i8]* [[FILENAME]], i32 5, i32 5 }
; NOALIAS: @__asan_global_global = {{.*}}i64 ptrtoint ({ i32, [28 x i8] }* @global to i64){{.*}} section "asan_globals"{{.*}}, !associated
; NOALIAS: @__asan_global_.str = {{.*}}i64 ptrtoint ({ [14 x i8], [18 x i8] }* @{{.str|1}} to i64){{.*}} section "asan_globals"{{.*}}, !associated
; ALIAS: @__asan_global_global = {{.*}}i64 ptrtoint ({ i32, [28 x i8] }* @0 to i64){{.*}} section "asan_globals"{{.*}}, !associated
-; ALIAS: @__asan_global_.str = {{.*}}i64 ptrtoint ({ [14 x i8], [18 x i8] }* @3 to i64){{.*}} section "asan_globals"{{.*}}, !associated
+; ALIAS: @__asan_global_.str = {{.*}}i64 ptrtoint ({ [14 x i8], [18 x i8] }* @4 to i64){{.*}} section "asan_globals"{{.*}}, !associated
; The metadata has to be inserted to llvm.compiler.used to avoid being stripped
; during LTO.
@@ -61,15 +59,8 @@
attributes #0 = { nounwind sanitize_address }
attributes #1 = { nounwind sanitize_address "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
-!llvm.asan.globals = !{!0, !1, !2, !3, !4}
!llvm.ident = !{!5}
-!0 = !{i32* @global, !6, !"global", i1 false, i1 false}
-!1 = !{i32* @dyn_init_global, !7, !"dyn_init_global", i1 true, i1 false}
-!2 = !{i32* @blocked_global, null, null, i1 false, i1 true}
-!3 = !{i32* @_ZZ4funcvE10static_var, !8, !"static_var", i1 false, i1 false}
-!4 = !{[14 x i8]* @.str, !9, !"<string literal>", i1 false, i1 false}
-
!5 = !{!"clang version 3.5.0 (211282)"}
!6 = !{!"/tmp/asan-globals.cpp", i32 5, i32 5}
Index: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
===================================================================
--- llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -31,6 +31,7 @@
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/Demangle/Demangle.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
@@ -89,6 +90,7 @@
#include <tuple>
using namespace llvm;
+using GlobalSanitizer = GlobalValue::SanitizerMetadata::GlobalSanitizer;
#define DEBUG_TYPE "asan"
@@ -625,8 +627,7 @@
/// AddressSanitizer: instrument the code in module to find memory bugs.
struct AddressSanitizer {
- AddressSanitizer(Module &M, const GlobalsMetadata *GlobalsMD,
- const StackSafetyGlobalInfo *SSGI,
+ AddressSanitizer(Module &M, const StackSafetyGlobalInfo *SSGI,
bool CompileKernel = false, bool Recover = false,
bool UseAfterScope = false,
AsanDetectStackUseAfterReturnMode UseAfterReturn =
@@ -637,7 +638,7 @@
UseAfterScope(UseAfterScope || ClUseAfterScope),
UseAfterReturn(ClUseAfterReturn.getNumOccurrences() ? ClUseAfterReturn
: UseAfterReturn),
- GlobalsMD(*GlobalsMD), SSGI(SSGI) {
+ SSGI(SSGI) {
C = &(M.getContext());
LongSize = M.getDataLayout().getPointerSizeInBits();
IntptrTy = Type::getIntNTy(*C, LongSize);
@@ -750,7 +751,6 @@
FunctionCallee AsanMemmove, AsanMemcpy, AsanMemset;
Value *LocalDynamicShadow = nullptr;
- const GlobalsMetadata &GlobalsMD;
const StackSafetyGlobalInfo *SSGI;
DenseMap<const AllocaInst *, bool> ProcessedAllocas;
@@ -760,12 +760,11 @@
class ModuleAddressSanitizer {
public:
- ModuleAddressSanitizer(Module &M, const GlobalsMetadata *GlobalsMD,
- bool CompileKernel = false, bool Recover = false,
- bool UseGlobalsGC = true, bool UseOdrIndicator = false,
+ ModuleAddressSanitizer(Module &M, bool CompileKernel = false,
+ bool Recover = false, bool UseGlobalsGC = true,
+ bool UseOdrIndicator = false,
AsanDtorKind DestructorKind = AsanDtorKind::Global)
- : GlobalsMD(*GlobalsMD),
- CompileKernel(ClEnableKasan.getNumOccurrences() > 0 ? ClEnableKasan
+ : CompileKernel(ClEnableKasan.getNumOccurrences() > 0 ? ClEnableKasan
: CompileKernel),
Recover(ClRecover.getNumOccurrences() > 0 ? ClRecover : Recover),
UseGlobalsGC(UseGlobalsGC && ClUseGlobalsGC && !this->CompileKernel),
@@ -831,7 +830,6 @@
uint64_t getRedzoneSizeForGlobal(uint64_t SizeInBytes) const;
int GetAsanVersion(const Module &M) const;
- const GlobalsMetadata &GlobalsMD;
bool CompileKernel;
bool Recover;
bool UseGlobalsGC;
@@ -1108,55 +1106,6 @@
} // end anonymous namespace
-void LocationMetadata::parse(MDNode *MDN) {
- assert(MDN->getNumOperands() == 3);
- MDString *DIFilename = cast<MDString>(MDN->getOperand(0));
- Filename = DIFilename->getString();
- LineNo = mdconst::extract<ConstantInt>(MDN->getOperand(1))->getLimitedValue();
- ColumnNo =
- mdconst::extract<ConstantInt>(MDN->getOperand(2))->getLimitedValue();
-}
-
-// FIXME: It would be cleaner to instead attach relevant metadata to the globals
-// we want to sanitize instead and reading this metadata on each pass over a
-// function instead of reading module level metadata at first.
-GlobalsMetadata::GlobalsMetadata(Module &M) {
- NamedMDNode *Globals = M.getNamedMetadata("llvm.asan.globals");
- if (!Globals)
- return;
- for (auto MDN : Globals->operands()) {
- // Metadata node contains the global and the fields of "Entry".
- assert(MDN->getNumOperands() == 5);
- auto *V = mdconst::extract_or_null<Constant>(MDN->getOperand(0));
- // The optimizer may optimize away a global entirely.
- if (!V)
- continue;
- auto *StrippedV = V->stripPointerCasts();
- auto *GV = dyn_cast<GlobalVariable>(StrippedV);
- if (!GV)
- continue;
- // We can already have an entry for GV if it was merged with another
- // global.
- Entry &E = Entries[GV];
- if (auto *Loc = cast_or_null<MDNode>(MDN->getOperand(1)))
- E.SourceLoc.parse(Loc);
- if (auto *Name = cast_or_null<MDString>(MDN->getOperand(2)))
- E.Name = Name->getString();
- ConstantInt *IsDynInit = mdconst::extract<ConstantInt>(MDN->getOperand(3));
- E.IsDynInit |= IsDynInit->isOne();
- ConstantInt *IsExcluded =
- mdconst::extract<ConstantInt>(MDN->getOperand(4));
- E.IsExcluded |= IsExcluded->isOne();
- }
-}
-
-AnalysisKey ASanGlobalsMetadataAnalysis::Key;
-
-GlobalsMetadata ASanGlobalsMetadataAnalysis::run(Module &M,
- ModuleAnalysisManager &AM) {
- return GlobalsMetadata(M);
-}
-
void ModuleAddressSanitizerPass::printPipeline(
raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
static_cast<PassInfoMixin<ModuleAddressSanitizerPass> *>(this)->printPipeline(
@@ -1175,8 +1124,7 @@
PreservedAnalyses ModuleAddressSanitizerPass::run(Module &M,
ModuleAnalysisManager &MAM) {
- GlobalsMetadata &GlobalsMD = MAM.getResult<ASanGlobalsMetadataAnalysis>(M);
- ModuleAddressSanitizer ModuleSanitizer(M, &GlobalsMD, Options.CompileKernel,
+ ModuleAddressSanitizer ModuleSanitizer(M, Options.CompileKernel,
Options.Recover, UseGlobalGC,
UseOdrIndicator, DestructorKind);
bool Modified = false;
@@ -1184,9 +1132,9 @@
const StackSafetyGlobalInfo *const SSGI =
ClUseStackSafety ? &MAM.getResult<StackSafetyGlobalAnalysis>(M) : nullptr;
for (Function &F : M) {
- AddressSanitizer FunctionSanitizer(
- M, &GlobalsMD, SSGI, Options.CompileKernel, Options.Recover,
- Options.UseAfterScope, Options.UseAfterReturn);
+ AddressSanitizer FunctionSanitizer(M, SSGI, Options.CompileKernel,
+ Options.Recover, Options.UseAfterScope,
+ Options.UseAfterReturn);
const TargetLibraryInfo &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
Modified |= FunctionSanitizer.instrumentFunction(F, &TLI);
}
@@ -1200,22 +1148,6 @@
return Res;
}
-/// Create a global describing a source location.
-static GlobalVariable *createPrivateGlobalForSourceLoc(Module &M,
- LocationMetadata MD) {
- Constant *LocData[] = {
- createPrivateGlobalForString(M, MD.Filename, true, kAsanGenPrefix),
- ConstantInt::get(Type::getInt32Ty(M.getContext()), MD.LineNo),
- ConstantInt::get(Type::getInt32Ty(M.getContext()), MD.ColumnNo),
- };
- auto LocStruct = ConstantStruct::getAnon(LocData);
- auto GV = new GlobalVariable(M, LocStruct->getType(), true,
- GlobalValue::PrivateLinkage, LocStruct,
- kAsanGenPrefix);
- GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
- return GV;
-}
-
/// Check if \p G has been created by a trusted compiler pass.
static bool GlobalWasGeneratedByCompiler(GlobalVariable *G) {
// Do not instrument @llvm.global_ctors, @llvm.used, etc.
@@ -1427,10 +1359,10 @@
// If a global variable does not have dynamic initialization we don't
// have to instrument it. However, if a global does not have initializer
// at all, we assume it has dynamic initializer (in other TU).
- //
- // FIXME: Metadata should be attched directly to the global directly instead
- // of being added to llvm.asan.globals.
- return G->hasInitializer() && !GlobalsMD.get(G).IsDynInit;
+ if (G->hasSanitizerMetadata() && G->getSanitizerMetadata().IsDynInit)
+ return false;
+
+ return G->hasInitializer();
}
void AddressSanitizer::instrumentPointerComparisonOrSubtraction(
@@ -1791,9 +1723,9 @@
Type *Ty = G->getValueType();
LLVM_DEBUG(dbgs() << "GLOBAL: " << *G << "\n");
- // FIXME: Metadata should be attched directly to the global directly instead
- // of being added to llvm.asan.globals.
- if (GlobalsMD.get(G).IsExcluded) return false;
+ if (G->hasSanitizerMetadata() &&
+ G->getSanitizerMetadata().Sanitizer != GlobalSanitizer::Address)
+ return false;
if (!Ty->isSized()) return false;
if (!G->hasInitializer()) return false;
// Globals in address space 1 and 4 are supported for AMDGPU.
@@ -2105,8 +2037,8 @@
SmallVector<GlobalValue *, 16> MetadataGlobals(ExtendedGlobals.size());
for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
GlobalVariable *G = ExtendedGlobals[i];
- GlobalVariable *Metadata =
- CreateMetadataGlobal(M, MetadataInitializers[i], G->getName());
+ GlobalVariable *Metadata = CreateMetadataGlobal(
+ M, MetadataInitializers[i], llvm::demangle(std::string(G->getName())));
MDNode *MD = MDNode::get(M.getContext(), ValueAsMetadata::get(G));
Metadata->setMetadata(LLVMContext::MD_associated, MD);
MetadataGlobals[i] = Metadata;
@@ -2172,8 +2104,8 @@
for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
Constant *Initializer = MetadataInitializers[i];
GlobalVariable *G = ExtendedGlobals[i];
- GlobalVariable *Metadata =
- CreateMetadataGlobal(M, Initializer, G->getName());
+ GlobalVariable *Metadata = CreateMetadataGlobal(
+ M, Initializer, llvm::demangle(std::string(G->getName())));
// On recent Mach-O platforms, we emit the global metadata in a way that
// allows the linker to properly strip dead globals.
@@ -2269,8 +2201,18 @@
SmallVector<GlobalVariable *, 16> GlobalsToChange;
for (auto &G : M.globals()) {
- if (!AliasedGlobalExclusions.count(&G) && shouldInstrumentGlobal(&G))
- GlobalsToChange.push_back(&G);
+ if (AliasedGlobalExclusions.count(&G))
+ continue;
+
+ if (!shouldInstrumentGlobal(&G)) {
+ GlobalValue::SanitizerMetadata Meta;
+ if (G.hasSanitizerMetadata())
+ Meta = G.getSanitizerMetadata();
+ Meta.RemoveSanitizer(GlobalSanitizer::Address);
+ G.setSanitizerMetadata(Meta);
+ continue;
+ }
+ GlobalsToChange.push_back(&G);
}
size_t n = GlobalsToChange.size();
@@ -2288,7 +2230,7 @@
// const char *name;
// const char *module_name;
// size_t has_dynamic_init;
- // void *source_location;
+ // size_t padding_for_windows_msvc_incremental_link;
// size_t odr_indicator;
// We initialize an array of such structures and pass it to a run-time call.
StructType *GlobalStructTy =
@@ -2307,15 +2249,19 @@
for (size_t i = 0; i < n; i++) {
GlobalVariable *G = GlobalsToChange[i];
- // FIXME: Metadata should be attched directly to the global directly instead
- // of being added to llvm.asan.globals.
- auto MD = GlobalsMD.get(G);
- StringRef NameForGlobal = G->getName();
+ GlobalValue::SanitizerMetadata Meta;
+ if (G->hasSanitizerMetadata())
+ Meta = G->getSanitizerMetadata();
+ else
+ // Sanitizers weren't notified when this global was created.
+ Meta.Sanitizer = GlobalSanitizer::Address;
+
+ std::string NameForGlobal = llvm::demangle(std::string(G->getName()));
// Create string holding the global name (use global name from metadata
// if it's available, otherwise just write the name of global variable).
- GlobalVariable *Name = createPrivateGlobalForString(
- M, MD.Name.empty() ? NameForGlobal : MD.Name,
- /*AllowMerging*/ true, kAsanGenPrefix);
+ GlobalVariable *Name =
+ createPrivateGlobalForString(M, NameForGlobal,
+ /*AllowMerging*/ true, kAsanGenPrefix);
Type *Ty = G->getValueType();
const uint64_t SizeInBytes = DL.getTypeAllocSize(Ty);
@@ -2363,14 +2309,6 @@
G->eraseFromParent();
NewGlobals[i] = NewGlobal;
- Constant *SourceLoc;
- if (!MD.SourceLoc.empty()) {
- auto SourceLocGlobal = createPrivateGlobalForSourceLoc(M, MD.SourceLoc);
- SourceLoc = ConstantExpr::getPointerCast(SourceLocGlobal, IntptrTy);
- } else {
- SourceLoc = ConstantInt::get(IntptrTy, 0);
- }
-
Constant *ODRIndicator = ConstantExpr::getNullValue(IRB.getInt8PtrTy());
GlobalValue *InstrumentedGlobal = NewGlobal;
@@ -2411,10 +2349,12 @@
ConstantInt::get(IntptrTy, SizeInBytes + RightRedzoneSize),
ConstantExpr::getPointerCast(Name, IntptrTy),
ConstantExpr::getPointerCast(ModuleName, IntptrTy),
- ConstantInt::get(IntptrTy, MD.IsDynInit), SourceLoc,
+ ConstantInt::get(IntptrTy, Meta.IsDynInit),
+ ConstantInt::get(IntptrTy, 0),
ConstantExpr::getPointerCast(ODRIndicator, IntptrTy));
- if (ClInitializers && MD.IsDynInit) HasDynamicallyInitializedGlobals = true;
+ if (ClInitializers && Meta.IsDynInit)
+ HasDynamicallyInitializedGlobals = true;
LLVM_DEBUG(dbgs() << "NEW GLOBAL: " << *NewGlobal << "\n");
Index: llvm/lib/Passes/PassRegistry.def
===================================================================
--- llvm/lib/Passes/PassRegistry.def
+++ llvm/lib/Passes/PassRegistry.def
@@ -26,7 +26,6 @@
MODULE_ANALYSIS("stack-safety", StackSafetyGlobalAnalysis())
MODULE_ANALYSIS("verify", VerifierAnalysis())
MODULE_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis(PIC))
-MODULE_ANALYSIS("asan-globals-md", ASanGlobalsMetadataAnalysis())
MODULE_ANALYSIS("inline-advisor", InlineAdvisorAnalysis())
MODULE_ANALYSIS("ir-similarity", IRSimilarityAnalysis())
Index: llvm/lib/IR/LLVMContextImpl.h
===================================================================
--- llvm/lib/IR/LLVMContextImpl.h
+++ llvm/lib/IR/LLVMContextImpl.h
@@ -1503,6 +1503,9 @@
/// Collection of per-GlobalValue partitions used in this context.
DenseMap<const GlobalValue *, StringRef> GlobalValuePartitions;
+ DenseMap<const GlobalValue *, GlobalValue::SanitizerMetadata>
+ GlobalValueSanitizerMetadata;
+
/// DiscriminatorTable - This table maps file:line locations to an
/// integer representing the next DWARF path discriminator to assign to
/// instructions in different blocks at the same location.
Index: llvm/lib/IR/Globals.cpp
===================================================================
--- llvm/lib/IR/Globals.cpp
+++ llvm/lib/IR/Globals.cpp
@@ -67,6 +67,8 @@
setDLLStorageClass(Src->getDLLStorageClass());
setDSOLocal(Src->isDSOLocal());
setPartition(Src->getPartition());
+ if (Src->hasSanitizerMetadata())
+ setSanitizerMetadata(Src->getSanitizerMetadata());
}
void GlobalValue::removeFromParent() {
@@ -217,6 +219,18 @@
HasPartition = !S.empty();
}
+using SanitizerMetadata = GlobalValue::SanitizerMetadata;
+using GlobalSanitizer = GlobalValue::SanitizerMetadata::GlobalSanitizer;
+const SanitizerMetadata &GlobalValue::getSanitizerMetadata() const {
+ assert(hasSanitizerMetadata());
+ return getContext().pImpl->GlobalValueSanitizerMetadata[this];
+}
+
+void GlobalValue::setSanitizerMetadata(const SanitizerMetadata &Meta) {
+ getContext().pImpl->GlobalValueSanitizerMetadata[this] = Meta;
+ HasSanitizerMetadata = true;
+}
+
StringRef GlobalObject::getSectionImpl() const {
assert(hasSection());
return getContext().pImpl->GlobalObjectSections[this];
Index: llvm/lib/IR/AsmWriter.cpp
===================================================================
--- llvm/lib/IR/AsmWriter.cpp
+++ llvm/lib/IR/AsmWriter.cpp
@@ -100,6 +100,9 @@
using UseListOrderMap =
DenseMap<const Function *, MapVector<const Value *, std::vector<unsigned>>>;
+using SanitizerMetadata = llvm::GlobalValue::SanitizerMetadata;
+using GlobalSanitizer = SanitizerMetadata::GlobalSanitizer;
+
/// Look for a value that might be wrapped as metadata, e.g. a value in a
/// metadata operand. Returns the input value as-is if it is not wrapped.
static const Value *skipMetadataWrapper(const Value *V) {
@@ -3537,6 +3540,28 @@
Out << '"';
}
+ if (GV->hasSanitizerMetadata()) {
+ SanitizerMetadata MD = GV->getSanitizerMetadata();
+ if (MD.HasSanitizer(SanitizerMetadata::NoSanitize)) {
+ Out << ", no_sanitize";
+ } else {
+ if (MD.HasSanitizer(SanitizerMetadata::Address))
+ Out << ", sanitize_address";
+ if (MD.HasSanitizer(SanitizerMetadata::HWAddress))
+ Out << ", sanitize_hwaddress";
+ if (MD.HasSanitizer(SanitizerMetadata::Memtag))
+ Out << ", sanitize_address";
+ if (MD.HasSanitizer(SanitizerMetadata::NoAddress))
+ Out << ", no_sanitize_address";
+ if (MD.HasSanitizer(SanitizerMetadata::NoHWAddress))
+ Out << ", no_sanitize_hwaddress";
+ if (MD.HasSanitizer(SanitizerMetadata::NoMemtag))
+ Out << ", no_sanitize_memtag";
+ if (MD.HasSanitizer(GlobalSanitizer::Address) && MD.IsDynInit)
+ Out << ", sanitize_address_dyninit";
+ }
+ }
+
maybePrintComdat(Out, *GV);
if (MaybeAlign A = GV->getAlign())
Out << ", align " << A->value();
Index: llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
===================================================================
--- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -1341,7 +1341,8 @@
// GLOBALVAR: [strtab offset, strtab size, type, isconst, initid,
// linkage, alignment, section, visibility, threadlocal,
// unnamed_addr, externally_initialized, dllstorageclass,
- // comdat, attributes, DSO_Local]
+ // comdat, attributes, DSO_Local, GlobalSanitizer::Sanitizer,
+ // GlobalSanitizer::IsDynInit]
Vals.push_back(addToStrtab(GV.getName()));
Vals.push_back(GV.getName().size());
Vals.push_back(VE.getTypeID(GV.getValueType()));
@@ -1357,10 +1358,8 @@
GV.getUnnamedAddr() != GlobalValue::UnnamedAddr::None ||
GV.isExternallyInitialized() ||
GV.getDLLStorageClass() != GlobalValue::DefaultStorageClass ||
- GV.hasComdat() ||
- GV.hasAttributes() ||
- GV.isDSOLocal() ||
- GV.hasPartition()) {
+ GV.hasComdat() || GV.hasAttributes() || GV.isDSOLocal() ||
+ GV.hasPartition() || GV.hasSanitizerMetadata()) {
Vals.push_back(getEncodedVisibility(GV));
Vals.push_back(getEncodedThreadLocalMode(GV));
Vals.push_back(getEncodedUnnamedAddr(GV));
@@ -1374,6 +1373,15 @@
Vals.push_back(GV.isDSOLocal());
Vals.push_back(addToStrtab(GV.getPartition()));
Vals.push_back(GV.getPartition().size());
+
+ if (!GV.hasSanitizerMetadata()) {
+ Vals.push_back(UINT_MAX);
+ Vals.push_back(UINT_MAX);
+ } else {
+ const auto &MD = GV.getSanitizerMetadata();
+ Vals.push_back(static_cast<int>(MD.Sanitizer));
+ Vals.push_back(MD.IsDynInit);
+ }
} else {
AbbrevToUse = SimpleGVarAbbrev;
}
Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
===================================================================
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -3536,6 +3536,15 @@
if (Record.size() > 15)
NewGV->setPartition(StringRef(Strtab.data() + Record[14], Record[15]));
+ if (Record.size() > 17 && Record[16] != UINT_MAX && Record[17] != UINT_MAX) {
+ llvm::GlobalValue::SanitizerMetadata Meta;
+ Meta.Sanitizer =
+ static_cast<llvm::GlobalValue::SanitizerMetadata::GlobalSanitizer>(
+ Record[16]);
+ Meta.IsDynInit = static_cast<bool>(Record[17]);
+ NewGV->setSanitizerMetadata(Meta);
+ }
+
return Error::success();
}
Index: llvm/lib/AsmParser/LLParser.cpp
===================================================================
--- llvm/lib/AsmParser/LLParser.cpp
+++ llvm/lib/AsmParser/LLParser.cpp
@@ -52,6 +52,9 @@
using namespace llvm;
+using SanitizerMetadata = GlobalValue::SanitizerMetadata;
+using GlobalSanitizer = SanitizerMetadata::GlobalSanitizer;
+
static std::string getTypeString(Type *T) {
std::string Result;
raw_string_ostream Tmp(Result);
@@ -1101,6 +1104,65 @@
return false;
}
+static bool isSanitizer(lltok::Kind Kind) {
+ switch (Kind) {
+ case lltok::kw_no_sanitize:
+ case lltok::kw_sanitize_address:
+ case lltok::kw_no_sanitize_address:
+ case lltok::kw_sanitize_hwaddress:
+ case lltok::kw_no_sanitize_hwaddress:
+ case lltok::kw_sanitize_memtag:
+ case lltok::kw_no_sanitize_memtag:
+ case lltok::kw_sanitize_address_dyninit:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool LLParser::parseSanitizer(GlobalVariable *GV) {
+ SanitizerMetadata Meta;
+ if (GV->hasSanitizerMetadata())
+ Meta = GV->getSanitizerMetadata();
+
+ switch (Lex.getKind()) {
+ case lltok::kw_no_sanitize:
+ Meta.AddSanitizer(GlobalSanitizer::NoSanitize);
+ break;
+ case lltok::kw_sanitize_address:
+ Meta.AddSanitizer(GlobalSanitizer::Address);
+ break;
+ case lltok::kw_no_sanitize_address:
+ Meta.AddSanitizer(GlobalSanitizer::NoAddress);
+ break;
+ case lltok::kw_sanitize_hwaddress:
+ Meta.AddSanitizer(GlobalSanitizer::HWAddress);
+ break;
+ case lltok::kw_no_sanitize_hwaddress:
+ Meta.AddSanitizer(GlobalSanitizer::NoHWAddress);
+ break;
+ case lltok::kw_sanitize_memtag:
+ Meta.AddSanitizer(GlobalSanitizer::Memtag);
+ break;
+ case lltok::kw_no_sanitize_memtag:
+ Meta.AddSanitizer(GlobalSanitizer::NoMemtag);
+ break;
+ case lltok::kw_sanitize_address_dyninit:
+ if (!GV->hasSanitizerMetadata() ||
+ !GV->getSanitizerMetadata().HasSanitizer(SanitizerMetadata::Address)) {
+ return tokError(
+ "sanitize_address_dyninit must only occur after sanitize_address");
+ }
+ Meta.IsDynInit = true;
+ break;
+ default:
+ return false;
+ }
+ GV->setSanitizerMetadata(Meta);
+ Lex.Lex();
+ return false;
+}
+
/// parseGlobal
/// ::= GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier
/// OptionalVisibility OptionalDLLStorageClass
@@ -1219,6 +1281,9 @@
} else if (Lex.getKind() == lltok::MetadataVar) {
if (parseGlobalObjectMetadataAttachment(*GV))
return true;
+ } else if (isSanitizer(Lex.getKind())) {
+ if (parseSanitizer(GV))
+ return true;
} else {
Comdat *C;
if (parseOptionalComdat(Name, C))
Index: llvm/lib/AsmParser/LLLexer.cpp
===================================================================
--- llvm/lib/AsmParser/LLLexer.cpp
+++ llvm/lib/AsmParser/LLLexer.cpp
@@ -654,6 +654,10 @@
KEYWORD(minsize);
KEYWORD(naked);
KEYWORD(nest);
+ KEYWORD(no_sanitize);
+ KEYWORD(no_sanitize_address);
+ KEYWORD(no_sanitize_hwaddress);
+ KEYWORD(no_sanitize_memtag);
KEYWORD(noalias);
KEYWORD(nobuiltin);
KEYWORD(nocallback);
@@ -694,6 +698,7 @@
KEYWORD(safestack);
KEYWORD(shadowcallstack);
KEYWORD(sanitize_address);
+ KEYWORD(sanitize_address_dyninit);
KEYWORD(sanitize_hwaddress);
KEYWORD(sanitize_memtag);
KEYWORD(sanitize_thread);
Index: llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
===================================================================
--- llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
+++ llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
@@ -25,75 +25,6 @@
class ModulePass;
class raw_ostream;
-/// Frontend-provided metadata for source location.
-struct LocationMetadata {
- StringRef Filename;
- int LineNo = 0;
- int ColumnNo = 0;
-
- LocationMetadata() = default;
-
- bool empty() const { return Filename.empty(); }
- void parse(MDNode *MDN);
-};
-
-/// Frontend-provided metadata for global variables.
-class GlobalsMetadata {
-public:
- struct Entry {
- LocationMetadata SourceLoc;
- StringRef Name;
- bool IsDynInit = false;
- bool IsExcluded = false;
-
- Entry() = default;
- };
-
- /// Create a default uninitialized GlobalsMetadata instance.
- GlobalsMetadata() = default;
-
- /// Create an initialized GlobalsMetadata instance.
- GlobalsMetadata(Module &M);
-
- /// Returns metadata entry for a given global.
- Entry get(GlobalVariable *G) const {
- auto Pos = Entries.find(G);
- return (Pos != Entries.end()) ? Pos->second : Entry();
- }
-
- /// Handle invalidation from the pass manager.
- /// These results are never invalidated.
- bool invalidate(Module &, const PreservedAnalyses &,
- ModuleAnalysisManager::Invalidator &) {
- return false;
- }
- bool invalidate(Function &, const PreservedAnalyses &,
- FunctionAnalysisManager::Invalidator &) {
- return false;
- }
-
-private:
- DenseMap<GlobalVariable *, Entry> Entries;
-};
-
-/// The ASanGlobalsMetadataAnalysis initializes and returns a GlobalsMetadata
-/// object. More specifically, ASan requires looking at all globals registered
-/// in 'llvm.asan.globals' before running, which only depends on reading module
-/// level metadata. This analysis is required to run before running the
-/// AddressSanitizerPass since it collects that metadata.
-/// The legacy pass manager equivalent of this is ASanGlobalsMetadataLegacyPass.
-class ASanGlobalsMetadataAnalysis
- : public AnalysisInfoMixin<ASanGlobalsMetadataAnalysis> {
-public:
- using Result = GlobalsMetadata;
-
- Result run(Module &, ModuleAnalysisManager &);
-
-private:
- friend AnalysisInfoMixin<ASanGlobalsMetadataAnalysis>;
- static AnalysisKey Key;
-};
-
struct AddressSanitizerOptions {
bool CompileKernel = false;
bool Recover = false;
Index: llvm/include/llvm/IR/GlobalValue.h
===================================================================
--- llvm/include/llvm/IR/GlobalValue.h
+++ llvm/include/llvm/IR/GlobalValue.h
@@ -79,14 +79,15 @@
ValueType(Ty), Visibility(DefaultVisibility),
UnnamedAddrVal(unsigned(UnnamedAddr::None)),
DllStorageClass(DefaultStorageClass), ThreadLocal(NotThreadLocal),
- HasLLVMReservedName(false), IsDSOLocal(false), HasPartition(false) {
+ HasLLVMReservedName(false), IsDSOLocal(false), HasPartition(false),
+ HasSanitizerMetadata(false) {
setLinkage(Linkage);
setName(Name);
}
Type *ValueType;
- static const unsigned GlobalValueSubClassDataBits = 16;
+ static const unsigned GlobalValueSubClassDataBits = 15;
// All bitfields use unsigned as the underlying type so that MSVC will pack
// them.
@@ -111,9 +112,14 @@
/// https://lld.llvm.org/Partitions.html).
unsigned HasPartition : 1;
+ /// True if this symbol has sanitizer metadata available. Should only happen
+ /// if sanitizers were enabled when building the translation unit which
+ /// contains this GV.
+ unsigned HasSanitizerMetadata : 1;
+
private:
// Give subclasses access to what otherwise would be wasted padding.
- // (16 + 4 + 2 + 2 + 2 + 3 + 1 + 1 + 1) == 32.
+ // (15 + 4 + 2 + 2 + 2 + 3 + 1 + 1 + 1 + 1) == 32.
unsigned SubClassData : GlobalValueSubClassDataBits;
friend class Constant;
@@ -288,6 +294,47 @@
StringRef getPartition() const;
void setPartition(StringRef Part);
+ struct SanitizerMetadata {
+ enum GlobalSanitizer : unsigned {
+ NoSanitize = 1 << 0,
+ Address = 1 << 1,
+ HWAddress = 1 << 2,
+ Memtag = 1 << 3,
+ NoAddress = 1 << 4,
+ NoHWAddress = 1 << 5,
+ NoMemtag = 1 << 6,
+ };
+ // Bitset of sanitizer options.
+ std::underlying_type<GlobalSanitizer>::type Sanitizer = 0;
+
+ void AddSanitizer(GlobalSanitizer S) { Sanitizer |= S; }
+ void RemoveSanitizer(GlobalSanitizer S) { Sanitizer &= ~S; }
+ bool HasSanitizer(GlobalSanitizer S) const {
+ if (Sanitizer == GlobalSanitizer::NoSanitize)
+ return S == GlobalSanitizer::NoSanitize;
+ switch (S) {
+ case GlobalSanitizer::Address:
+ return (Sanitizer & S) && !(Sanitizer & GlobalSanitizer::NoAddress);
+ case GlobalSanitizer::HWAddress:
+ return (Sanitizer & S) && !(Sanitizer & GlobalSanitizer::NoHWAddress);
+ case GlobalSanitizer::Memtag:
+ return (Sanitizer & S) && !(Sanitizer & GlobalSanitizer::NoMemtag);
+ case GlobalSanitizer::NoSanitize: // clang doesn't see the handling above.
+ case GlobalSanitizer::NoAddress:
+ case GlobalSanitizer::NoHWAddress:
+ case GlobalSanitizer::NoMemtag:
+ return Sanitizer & S;
+ }
+ }
+
+ // Metadata specific to ASan.
+ bool IsDynInit = false;
+ };
+
+ bool hasSanitizerMetadata() const { return HasSanitizerMetadata; }
+ const SanitizerMetadata &getSanitizerMetadata() const;
+ void setSanitizerMetadata(const SanitizerMetadata &Meta);
+
static LinkageTypes getLinkOnceLinkage(bool ODR) {
return ODR ? LinkOnceODRLinkage : LinkOnceAnyLinkage;
}
Index: llvm/include/llvm/AsmParser/LLToken.h
===================================================================
--- llvm/include/llvm/AsmParser/LLToken.h
+++ llvm/include/llvm/AsmParser/LLToken.h
@@ -182,6 +182,7 @@
kw_alwaysinline,
kw_argmemonly,
kw_sanitize_address,
+ kw_sanitize_address_dyninit,
kw_sanitize_hwaddress,
kw_sanitize_memtag,
kw_builtin,
@@ -201,6 +202,10 @@
kw_minsize,
kw_naked,
kw_nest,
+ kw_no_sanitize,
+ kw_no_sanitize_address,
+ kw_no_sanitize_hwaddress,
+ kw_no_sanitize_memtag,
kw_noalias,
kw_noundef,
kw_nobuiltin,
Index: llvm/include/llvm/AsmParser/LLParser.h
===================================================================
--- llvm/include/llvm/AsmParser/LLParser.h
+++ llvm/include/llvm/AsmParser/LLParser.h
@@ -514,6 +514,7 @@
bool parseGlobalValueVector(SmallVectorImpl<Constant *> &Elts,
Optional<unsigned> *InRangeOp = nullptr);
bool parseOptionalComdat(StringRef GlobalName, Comdat *&C);
+ bool parseSanitizer(GlobalVariable *GV);
bool parseMetadataAsValue(Value *&V, PerFunctionState &PFS);
bool parseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg,
PerFunctionState *PFS);
Index: compiler-rt/test/asan/TestCases/global-location.cpp
===================================================================
--- compiler-rt/test/asan/TestCases/global-location.cpp
+++ compiler-rt/test/asan/TestCases/global-location.cpp
@@ -1,21 +1,30 @@
-// RUN: %clangxx_asan -O2 %s -o %t
+// RUN: %clangxx_asan -g -O2 %s -o %t
// RUN: not %run %t g 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=GLOB
// RUN: not %run %t c 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CLASS_STATIC
// RUN: not %run %t f 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=FUNC_STATIC
// RUN: not %run %t l 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=LITERAL
+// RUN: %clangxx_asan -O2 %s -o %t
+// RUN: llvm-strip -s %t
+// RUN: not %run %t g 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=GLOB-NO-G
+// RUN: not %run %t c 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CLASS_STATIC-NO-G
+// RUN: not %run %t f 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=FUNC_STATIC-NO-G
+// RUN: not %run %t l 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=LITERAL-NO-G
+
// CHECK: AddressSanitizer: global-buffer-overflow
#include <string.h>
struct C {
static int array[10];
+ // CLASS_STATIC: 0x{{.*}} is located 4 bytes to the right of global variable 'C::array' defined in '{{.*}}global-location.cpp:[[@LINE-1]]' {{.*}} of size 40
+ // CLASS_STATIC-NO-G: 0x{{.*}} is located 4 bytes to the right of global variable 'C::array' defined in '{{.*}}global-location.cpp' {{.*}} of size 40
};
int global[10];
-// GLOB: 0x{{.*}} is located 4 bytes to the right of global variable 'global' defined in '{{.*}}global-location.cpp:[[@LINE-1]]:5' {{.*}} of size 40
+// GLOB: 0x{{.*}} is located 4 bytes to the right of global variable 'global' defined in '{{.*}}global-location.cpp:[[@LINE-1]]' {{.*}} of size 40
+// GLOB-NO-G: 0x{{.*}} is located 4 bytes to the right of global variable 'global' defined in '{{.*}}global-location.cpp' {{.*}} of size 40
int C::array[10];
-// CLASS_STATIC: 0x{{.*}} is located 4 bytes to the right of global variable 'C::array' defined in '{{.*}}global-location.cpp:[[@LINE-1]]:8' {{.*}} of size 40
int main(int argc, char **argv) {
int one = argc - 1;
@@ -24,12 +33,14 @@
case 'c': return C::array[one * 11];
case 'f':
static int array[10];
- // FUNC_STATIC: 0x{{.*}} is located 4 bytes to the right of global variable 'array' defined in '{{.*}}global-location.cpp:[[@LINE-1]]:16' {{.*}} of size 40
+ // FUNC_STATIC: 0x{{.*}} is located 4 bytes to the right of global variable 'main::array' defined in '{{.*}}global-location.cpp:[[@LINE-1]]' {{.*}} of size 40
+ // FUNC_STATIC-NO-G: 0x{{.*}} is located 4 bytes to the right of global variable 'main::array' defined in '{{.*}}global-location.cpp' {{.*}} of size 40
memset(array, 0, 10);
return array[one * 11];
case 'l':
const char *str = "0123456789";
- // LITERAL: 0x{{.*}} is located 0 bytes to the right of global variable {{.*}} defined in '{{.*}}global-location.cpp:[[@LINE-1]]:23' {{.*}} of size 11
+ // LITERAL: 0x{{.*}} is located 0 bytes to the right of global variable {{.*}} defined in '{{.*}}global-location.cpp:[[@LINE-1]]' {{.*}} of size 11
+ // LITERAL-NO-G: 0x{{.*}} is located 0 bytes to the right of global variable {{.*}} defined in '{{.*}}global-location.cpp' {{.*}} of size 11
return str[one * 11];
}
return 0;
Index: compiler-rt/test/asan/TestCases/Linux/odr-violation.cpp
===================================================================
--- compiler-rt/test/asan/TestCases/Linux/odr-violation.cpp
+++ compiler-rt/test/asan/TestCases/Linux/odr-violation.cpp
@@ -7,15 +7,15 @@
// pointers. This setting is not on by default because it's too expensive.
//
// Different size: detect a bug if detect_odr_violation>=1
-// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %dynamiclib
-// RUN: %clangxx_asan %s %ld_flags_rpath_exe -o %t-ODR-EXE
+// RUN: %clangxx_asan -g -DBUILD_SO=1 -fPIC -shared %s -o %dynamiclib
+// RUN: %clangxx_asan -g %s %ld_flags_rpath_exe -o %t-ODR-EXE
// RUN: %env_asan_opts=fast_unwind_on_malloc=0:detect_odr_violation=1 not %run %t-ODR-EXE 2>&1 | FileCheck %s
// RUN: %env_asan_opts=fast_unwind_on_malloc=0:detect_odr_violation=2 not %run %t-ODR-EXE 2>&1 | FileCheck %s
// RUN: %env_asan_opts=fast_unwind_on_malloc=0:detect_odr_violation=0 %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED
// RUN: %env_asan_opts=fast_unwind_on_malloc=0 not %run %t-ODR-EXE 2>&1 | FileCheck %s
//
// Same size: report a bug only if detect_odr_violation>=2.
-// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %dynamiclib -DSZ=100
+// RUN: %clangxx_asan -g -DBUILD_SO=1 -fPIC -shared %s -o %dynamiclib -DSZ=100
// RUN: %env_asan_opts=fast_unwind_on_malloc=0:detect_odr_violation=1 %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED
// RUN: %env_asan_opts=fast_unwind_on_malloc=0:detect_odr_violation=2 not %run %t-ODR-EXE 2>&1 | FileCheck %s
// RUN: %env_asan_opts=fast_unwind_on_malloc=0 not %run %t-ODR-EXE 2>&1 | FileCheck %s
@@ -26,18 +26,18 @@
// RUN: rm -f %t.supp
//
// Use private aliases for global variables without indicator symbol.
-// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared -mllvm -asan-use-private-alias %s -o %dynamiclib -DSZ=100
-// RUN: %clangxx_asan -mllvm -asan-use-private-alias %s %ld_flags_rpath_exe -o %t-ODR-EXE
+// RUN: %clangxx_asan -g -DBUILD_SO=1 -fPIC -shared -mllvm -asan-use-private-alias %s -o %dynamiclib -DSZ=100
+// RUN: %clangxx_asan -g -mllvm -asan-use-private-alias %s %ld_flags_rpath_exe -o %t-ODR-EXE
// RUN: %env_asan_opts=fast_unwind_on_malloc=0 %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED
// Use private aliases for global variables: use indicator symbol to detect ODR violation.
-// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared -mllvm -asan-use-private-alias -mllvm -asan-use-odr-indicator %s -o %dynamiclib -DSZ=100
-// RUN: %clangxx_asan -mllvm -asan-use-private-alias -mllvm -asan-use-odr-indicator %s %ld_flags_rpath_exe -o %t-ODR-EXE
+// RUN: %clangxx_asan -g -DBUILD_SO=1 -fPIC -shared -mllvm -asan-use-private-alias -mllvm -asan-use-odr-indicator %s -o %dynamiclib -DSZ=100
+// RUN: %clangxx_asan -g -mllvm -asan-use-private-alias -mllvm -asan-use-odr-indicator %s %ld_flags_rpath_exe -o %t-ODR-EXE
// RUN: %env_asan_opts=fast_unwind_on_malloc=0 not %run %t-ODR-EXE 2>&1 | FileCheck %s
// Same as above but with clang switches.
-// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared -fsanitize-address-use-odr-indicator %s -o %dynamiclib -DSZ=100
-// RUN: %clangxx_asan -fsanitize-address-use-odr-indicator %s %ld_flags_rpath_exe -o %t-ODR-EXE
+// RUN: %clangxx_asan -g -DBUILD_SO=1 -fPIC -shared -fsanitize-address-use-odr-indicator %s -o %dynamiclib -DSZ=100
+// RUN: %clangxx_asan -g -fsanitize-address-use-odr-indicator %s %ld_flags_rpath_exe -o %t-ODR-EXE
// RUN: %env_asan_opts=fast_unwind_on_malloc=0 not %run %t-ODR-EXE 2>&1 | FileCheck %s
// GNU driver doesn't handle .so files properly.
@@ -55,7 +55,7 @@
#include <stdio.h>
namespace foo { char G[100]; }
// CHECK: ERROR: AddressSanitizer: odr-violation
-// CHECK: size=100 'foo::G' {{.*}}odr-violation.cpp:[[@LINE-2]]:22
+// CHECK: size=100 'foo::G' {{.*}}odr-violation.cpp:[[@LINE-2]]
// CHECK: size={{4|100}} 'foo::G'
int main(int argc, char **argv) {
printf("PASS: %p\n", &foo::G);
Index: compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
===================================================================
--- compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
+++ compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
@@ -371,6 +371,8 @@
str = ExtractToken(str, "\n", &info->name);
str = ExtractUptr(str, " ", &info->start);
str = ExtractUptr(str, "\n", &info->size);
+ str = ExtractToken(str, ":", &info->file);
+ str = ExtractUptr(str, "\n", &info->line);
}
static void ParseSymbolizeFrameOutput(const char *str,
Index: compiler-rt/lib/asan/asan_interface_internal.h
===================================================================
--- compiler-rt/lib/asan/asan_interface_internal.h
+++ compiler-rt/lib/asan/asan_interface_internal.h
@@ -53,8 +53,9 @@
const char *module_name; // Module name as a C string. This pointer is a
// unique identifier of a module.
uptr has_dynamic_init; // Non-zero if the global has dynamic initializer.
- __asan_global_source_location *location; // Source location of a global,
- // or NULL if it is unknown.
+ uptr windows_padding; // TODO: Figure out how to remove this padding
+ // that's simply here to make the MSVC incremental
+ // linker happy...
uptr odr_indicator; // The address of the ODR indicator symbol.
};
Index: compiler-rt/lib/asan/asan_globals.cpp
===================================================================
--- compiler-rt/lib/asan/asan_globals.cpp
+++ compiler-rt/lib/asan/asan_globals.cpp
@@ -86,10 +86,11 @@
"odr_indicator=%p\n",
prefix, (void *)&g, (void *)g.beg, g.size, g.size_with_redzone, g.name,
g.module_name, g.has_dynamic_init, (void *)g.odr_indicator);
- if (g.location) {
- Report(" location (%p): name=%s[%p], %d %d\n", (void *)g.location,
- g.location->filename, (void *)g.location->filename,
- g.location->line_no, g.location->column_no);
+
+ DataInfo info;
+ Symbolizer::GetOrInit()->SymbolizeData(g.beg, &info);
+ if (info.line != 0) {
+ Report(" location (from debuginfo): name=%s, %d\n", info.file, info.line);
}
}
@@ -295,19 +296,15 @@
(char *)g.beg);
}
-static const char *GlobalFilename(const __asan_global &g) {
- const char *res = g.module_name;
- // Prefer the filename from source location, if is available.
- if (g.location) res = g.location->filename;
- CHECK(res);
- return res;
-}
-
void PrintGlobalLocation(InternalScopedString *str, const __asan_global &g) {
- str->append("%s", GlobalFilename(g));
- if (!g.location) return;
- if (g.location->line_no) str->append(":%d", g.location->line_no);
- if (g.location->column_no) str->append(":%d", g.location->column_no);
+ DataInfo info;
+ Symbolizer::GetOrInit()->SymbolizeData(g.beg, &info);
+
+ if (info.line != 0) {
+ str->append("%s:%d", info.file, info.line);
+ } else {
+ str->append("%s", g.module_name);
+ }
}
} // namespace __asan
Index: clang/test/CodeGenCXX/type-metadata.cpp
===================================================================
--- clang/test/CodeGenCXX/type-metadata.cpp
+++ clang/test/CodeGenCXX/type-metadata.cpp
@@ -36,7 +36,7 @@
// ITANIUM-DIAG-SAME: !type [[ALL32]]
// ITANIUM-SAME: !type [[CF32:![0-9]+]]
-// DIAG: @[[SRC:.*]] = private unnamed_addr constant [{{.*}} x i8] c"{{.*}}type-metadata.cpp\00", align 1
+// DIAG: @[[SRC:.*]] = private unnamed_addr constant [{{.*}} x i8] c"{{.*}}type-metadata.cpp\00", no_sanitize, align 1
// DIAG: @[[TYPE:.*]] = private unnamed_addr constant { i16, i16, [4 x i8] } { i16 -1, i16 0, [4 x i8] c"'A'\00" }
// DIAG: @[[BADTYPESTATIC:.*]] = private unnamed_addr global { i8, { [{{.*}} x i8]*, i32, i32 }, { i16, i16, [4 x i8] }* } { i8 0, { [{{.*}} x i8]*, i32, i32 } { [{{.*}} x i8]* @[[SRC]], i32 123, i32 3 }, { i16, i16, [4 x i8] }* @[[TYPE]] }
Index: clang/test/CodeGenCXX/catch-undef-behavior.cpp
===================================================================
--- clang/test/CodeGenCXX/catch-undef-behavior.cpp
+++ clang/test/CodeGenCXX/catch-undef-behavior.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -std=c++11 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift-base,shift-exponent,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -fsanitize-recover=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift-base,shift-exponent,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -emit-llvm %s -o - -triple x86_64-linux-gnu | opt -instnamer -S | FileCheck %s
+// RUN: %clang_cc1 -Wno-return-type -no-opaque-pointers -no-enable-noundef-analysis -std=c++11 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift-base,shift-exponent,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -fsanitize-recover=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift-base,shift-exponent,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -emit-llvm %s -o - -triple x86_64-linux-gnu | opt -instnamer -S | FileCheck %s
// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -std=c++11 -fsanitize=vptr,address -fsanitize-recover=vptr,address -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-ASAN
// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -std=c++11 -fsanitize=vptr -fsanitize-recover=vptr -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=DOWNCAST-NULL
// RUN: %clang_cc1 -no-opaque-pointers -no-enable-noundef-analysis -std=c++11 -fsanitize=function -emit-llvm %s -o - -triple x86_64-linux-gnux32 | FileCheck %s --check-prefix=CHECK-X32
Index: clang/test/CodeGen/ubsan-strip-path-components.cpp
===================================================================
--- clang/test/CodeGen/ubsan-strip-path-components.cpp
+++ clang/test/CodeGen/ubsan-strip-path-components.cpp
@@ -10,14 +10,14 @@
// RUN: %clang_cc1 -no-opaque-pointers %s -triple=x86_64-linux-gnu -emit-llvm -fsanitize=unreachable -o - -fsanitize-undefined-strip-path-components=-2 | FileCheck %s -check-prefix=LAST-TWO
// RUN: %clang_cc1 -no-opaque-pointers %s -triple=x86_64-linux-gnu -emit-llvm -fsanitize=unreachable -o - -fsanitize-undefined-strip-path-components=-1 | FileCheck %s -check-prefix=LAST-ONLY
-// REGULAR: @[[SRC:[0-9.a-zA-Z_]+]] = private unnamed_addr constant [{{.*}} x i8] c"{{.*test(.|\\\\)CodeGen(.|\\\\)ubsan-strip-path-components\.cpp}}\00", align 1
+// REGULAR: @[[SRC:[0-9.a-zA-Z_]+]] = private unnamed_addr constant [{{.*}} x i8] c"{{.*test(.|\\\\)CodeGen(.|\\\\)ubsan-strip-path-components\.cpp}}\00", no_sanitize, align 1
// First path component: "/" or "$drive_letter:", then a name, or '\\' on Windows
// REMOVE-FIRST-TWO: @[[STR:[0-9.a-zA-Z_]+]] = private unnamed_addr constant [{{.*}} x i8] c"{{(.:|/)([^\\/]*(/|\\\\))}}[[REST:.*ubsan-strip-path-components\.cpp]]\00", align 1
-// REMOVE-FIRST-TWO: @[[SRC:[0-9.a-zA-Z_]+]] = private unnamed_addr constant [{{.*}} x i8] c"[[REST]]\00", align 1
+// REMOVE-FIRST-TWO: @[[SRC:[0-9.a-zA-Z_]+]] = private unnamed_addr constant [{{.*}} x i8] c"[[REST]]\00", no_sanitize, align 1
-// LAST-TWO: @[[SRC:[0-9.a-zA-Z_]+]] = private unnamed_addr constant [{{.*}} x i8] c"CodeGen{{/|\\\\}}ubsan-strip-path-components.cpp\00", align 1
-// LAST-ONLY: @[[SRC:[0-9.a-zA-Z_]+]] = private unnamed_addr constant [{{.*}} x i8] c"ubsan-strip-path-components.cpp\00", align 1
+// LAST-TWO: @[[SRC:[0-9.a-zA-Z_]+]] = private unnamed_addr constant [{{.*}} x i8] c"CodeGen{{/|\\\\}}ubsan-strip-path-components.cpp\00", no_sanitize, align 1
+// LAST-ONLY: @[[SRC:[0-9.a-zA-Z_]+]] = private unnamed_addr constant [{{.*}} x i8] c"ubsan-strip-path-components.cpp\00", no_sanitize, align 1
// CHECK: @[[STATIC_DATA:[0-9.a-zA-Z_]+]] = private unnamed_addr global { { [{{.*}} x i8]*, i32, i32 } } { { [{{.*}} x i8]*, i32, i32 } { [{{.*}} x i8]* @[[SRC]], i32 [[@LINE+6]], i32 3 } }
void g(const char *);
Index: clang/test/CodeGen/sanitize-init-order.cpp
===================================================================
--- clang/test/CodeGen/sanitize-init-order.cpp
+++ clang/test/CodeGen/sanitize-init-order.cpp
@@ -36,14 +36,12 @@
// Check that ASan init-order checking ignores structs with trivial default
// constructor.
-// CHECK: !llvm.asan.globals = !{![[GLOB_1:[0-9]+]], ![[GLOB_2:[0-9]+]], ![[GLOB_3:[0-9]+]], ![[GLOB_4:[0-9]+]]
-// CHECK: ![[GLOB_1]] = !{%struct.PODStruct* {{.*}}, i1 false, i1 false}
-// CHECK: ![[GLOB_2]] = !{%struct.PODWithDtor* {{.*}}, i1 false, i1 false}
-// CHECK: ![[GLOB_3]] = !{%struct.PODWithCtorAndDtor* {{.*}}, i1 true, i1 false}
-// CHECK: ![[GLOB_4]] = !{{{.*}}class.NS::PODWithCtor{{.*}}, i1 true, i1 false}
-
-// IGNORELIST: !llvm.asan.globals = !{![[GLOB_1:[0-9]+]], ![[GLOB_2:[0-9]+]], ![[GLOB_3:[0-9]+]], ![[GLOB_4:[0-9]+]]}
-// IGNORELIST: ![[GLOB_1]] = !{%struct.PODStruct* {{.*}}, i1 false, i1 false}
-// IGNORELIST: ![[GLOB_2]] = !{%struct.PODWithDtor* {{.*}}, i1 false, i1 false}
-// IGNORELIST: ![[GLOB_3]] = !{%struct.PODWithCtorAndDtor* {{.*}}, i1 false, i1 false}
-// IGNORELIST: ![[GLOB_4]] = !{{{.*}}class.NS::PODWithCtor{{.*}}, i1 false, i1 false}
+// CHECK: = global { %struct.PODStruct, {{.*}} sanitize_address
+// CHECK: = global { %struct.PODWithDtor, {{.*}} sanitize_address
+// CHECK: = global { %struct.PODWithCtorAndDtor, {{.*}} sanitize_address, sanitize_address_dyninit
+// CHECK: = global {{.*}} %"class.NS::PODWithCtor"{{.*}} sanitize_address, sanitize_address_dyninit
+
+// IGNORELIST: = global { %struct.PODStruct, {{.*}} sanitize_address
+// IGNORELIST: = global { %struct.PODWithDtor, {{.*}} sanitize_address
+// IGNORELIST: = global { %struct.PODWithCtorAndDtor, {{.*}} sanitize_address
+// IGNORELIST: = global {{.*}} %"class.NS::PODWithCtor"{{.*}} sanitize_address
Index: clang/test/CodeGen/asan-strings.c
===================================================================
--- clang/test/CodeGen/asan-strings.c
+++ clang/test/CodeGen/asan-strings.c
@@ -10,8 +10,8 @@
const char *foo(void) { return "asdf"; }
-// LINUX: @.str = private unnamed_addr constant [5 x i8] c"asdf\00", align 1
+// LINUX: @.str = private unnamed_addr constant [5 x i8] c"asdf\00", sanitize_address, align 1
-// WINDOWS: @"??_C@_04JIHMPGLA@asdf?$AA@" = linkonce_odr dso_local unnamed_addr constant [5 x i8] c"asdf\00", comdat, align 1
+// WINDOWS: @"??_C@_04JIHMPGLA@asdf?$AA@" = linkonce_odr dso_local unnamed_addr constant [5 x i8] c"asdf\00", sanitize_address, comdat, align 1
-// WINWRITE: @.str = private unnamed_addr global [5 x i8] c"asdf\00", align 1
+// WINWRITE: @.str = private unnamed_addr global [5 x i8] c"asdf\00", sanitize_address, align 1
Index: clang/test/CodeGen/asan-static-odr.cpp
===================================================================
--- clang/test/CodeGen/asan-static-odr.cpp
+++ clang/test/CodeGen/asan-static-odr.cpp
@@ -11,7 +11,7 @@
// CHECK-NOT: __odr_asan_gen
// CHECK-NOT: private alias
-// CHECK: [[VAR:@.*global.*]] ={{.*}} global { i32, [28 x i8] } zeroinitializer, align 32
+// CHECK: [[VAR:@.*global.*]] ={{.*}} global { i32, [28 x i8] } zeroinitializer, sanitize_address, align 32
// CHECK: @0 = internal global {{.*}} [[VAR]] to i64), {{.*}}, i64 -1 }]
// CHECK: call void @__asan_register_globals(i64 ptrtoint ([1 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 1)
// CHECK: call void @__asan_unregister_globals(i64 ptrtoint ([1 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 1)
Index: clang/test/CodeGen/asan-globals.cpp
===================================================================
--- clang/test/CodeGen/asan-globals.cpp
+++ clang/test/CodeGen/asan-globals.cpp
@@ -1,7 +1,8 @@
// RUN: echo "int extra_global;" > %t.extra-source.cpp
// RUN: echo "global:*ignorelisted_global*" > %t.ignorelist
-// RUN: %clang_cc1 -include %t.extra-source.cpp -fsanitize=address -fsanitize-ignorelist=%t.ignorelist -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,ASAN
-// RUN: %clang_cc1 -include %t.extra-source.cpp -fsanitize=kernel-address -fsanitize-ignorelist=%t.ignorelist -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,KASAN
+// RUN: %clang_cc1 -include %t.extra-source.cpp -fsanitize=kernel-address -fsanitize-ignorelist=%t.ignorelist -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,GLOBS,KASAN
+
+// RUN: %clang_cc1 -include %t.extra-source.cpp -fsanitize=address -fsanitize-ignorelist=%t.ignorelist -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,GLOBS,ASAN
// The ignorelist file uses regexps, so Windows path backslashes.
// RUN: echo "src:%s" | sed -e 's/\\/\\\\/g' > %t.ignorelist-src
// RUN: %clang_cc1 -include %t.extra-source.cpp -fsanitize=address -fsanitize-ignorelist=%t.ignorelist-src -emit-llvm -o - %s | FileCheck %s --check-prefix=IGNORELIST-SRC
@@ -23,10 +24,22 @@
const char *literal = "Hello, world!";
}
-// ASAN: sectioned_global{{.*}} global { i32, [28 x i8] }{{.*}}, align 32
+// GLOBS: @extra_global = global {{.*}} sanitize_address
+// GLOBS: @global = global {{.*}} sanitize_address
+// GLOBS: @dyn_init_global = global {{.*}} sanitize_address, sanitize_address_dyninit
+// GLOBS: @attributed_global = global {{.*}} no_sanitize_address
+// GLOBS: @disable_instrumentation_global = global {{.*}} no_sanitize
+// GLOBS: @ignorelisted_global = global {{.*}} no_sanitize
+
+// ASAN: sectioned_global{{.*}} global { i32, [28 x i8] }{{.*}}, sanitize_address, align 32
// KASAN: sectioned_global{{.*}} global i32
-// ASAN: @__special_global{{.*}} global { i32, [28 x i8] }{{.*}}, align 32
+// KASAN-NOT: sanitize_address
+// ASAN: @__special_global{{.*}} global { i32, [28 x i8] }{{.*}}, sanitize_address, align 32
// KASAN: @__special_global{{.*}} global i32
+// KASAN-NOT: sanitize_address
+
+// GLOBS: @{{[^ ]*}}static_var{{[^ ]*}} = internal global {{.*}} sanitize_address
+// GLOBS: @.str = internal constant {{.*}}"Hello, world!{{.*}} sanitize_address
/// Without -fasynchronous-unwind-tables, ctor and dtor get the uwtable attribute.
// CHECK-LABEL: define internal void @asan.module_ctor() #[[#ATTR:]] {
@@ -51,34 +64,14 @@
// UWTABLE: attributes #[[#ATTR]] = { nounwind uwtable }
// UWTABLE: ![[#]] = !{i32 7, !"uwtable", i32 2}
-// CHECK: !llvm.asan.globals = !{![[EXTRA_GLOBAL:[0-9]+]], ![[GLOBAL:[0-9]+]], ![[DYN_INIT_GLOBAL:[0-9]+]], ![[ATTR_GLOBAL:[0-9]+]], ![[DISABLE_INSTR_GLOBAL:[0-9]+]], ![[IGNORELISTED_GLOBAL:[0-9]+]], ![[SECTIONED_GLOBAL:[0-9]+]], ![[SPECIAL_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
-// CHECK: ![[EXTRA_GLOBAL]] = !{{{.*}} ![[EXTRA_GLOBAL_LOC:[0-9]+]], !"extra_global", i1 false, i1 false}
-// CHECK: ![[EXTRA_GLOBAL_LOC]] = !{!"{{.*}}extra-source.cpp", i32 1, i32 5}
-// CHECK: ![[GLOBAL]] = !{{{.*}} ![[GLOBAL_LOC:[0-9]+]], !"global", i1 false, i1 false}
-// CHECK: ![[GLOBAL_LOC]] = !{!"{{.*}}asan-globals.cpp", i32 10, i32 5}
-// CHECK: ![[DYN_INIT_GLOBAL]] = !{{{.*}} ![[DYN_INIT_LOC:[0-9]+]], !"dyn_init_global", i1 true, i1 false}
-// CHECK: ![[DYN_INIT_LOC]] = !{!"{{.*}}asan-globals.cpp", i32 11, i32 5}
-// CHECK: ![[ATTR_GLOBAL]] = !{{{.*attributed_global.*}}, null, null, i1 false, i1 true}
-// CHECK: ![[DISABLE_INSTR_GLOBAL]] = !{{{.*disable_instrumentation_global.*}}, null, null, i1 false, i1 true}
-// CHECK: ![[IGNORELISTED_GLOBAL]] = !{{{.*ignorelisted_global.*}}, null, null, i1 false, i1 true}
-// CHECK: ![[SECTIONED_GLOBAL]] = !{{{.*}} ![[SECTIONED_GLOBAL_LOC:[0-9]+]], !"sectioned_global", i1 false, i1 false}
-// CHECK: ![[SECTIONED_GLOBAL_LOC]] = !{!"{{.*}}asan-globals.cpp", i32 16, i32 50}
-// CHECK: ![[SPECIAL_GLOBAL]] = !{{{.*}} ![[SPECIAL_GLOBAL_LOC:[0-9]+]], !"__special_global", i1 false, i1 false}
-// CHECK: ![[SPECIAL_GLOBAL_LOC]] = !{!"{{.*}}asan-globals.cpp", i32 18, i32 5}
-// CHECK: ![[STATIC_VAR]] = !{{{.*}} ![[STATIC_LOC:[0-9]+]], !"static_var", i1 false, i1 false}
-// CHECK: ![[STATIC_LOC]] = !{!"{{.*}}asan-globals.cpp", i32 22, i32 14}
-// CHECK: ![[LITERAL]] = !{{{.*}} ![[LITERAL_LOC:[0-9]+]], !"<string literal>", i1 false, i1 false}
-// CHECK: ![[LITERAL_LOC]] = !{!"{{.*}}asan-globals.cpp", i32 23, i32 25}
-// IGNORELIST-SRC: !llvm.asan.globals = !{![[EXTRA_GLOBAL:[0-9]+]], ![[GLOBAL:[0-9]+]], ![[DYN_INIT_GLOBAL:[0-9]+]], ![[ATTR_GLOBAL:[0-9]+]], ![[DISABLE_INSTR_GLOBAL:[0-9]+]], ![[IGNORELISTED_GLOBAL:[0-9]+]], ![[SECTIONED_GLOBAL:[0-9]+]], ![[SPECIAL_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
-// IGNORELIST-SRC: ![[EXTRA_GLOBAL]] = !{{{.*}} ![[EXTRA_GLOBAL_LOC:[0-9]+]], !"extra_global", i1 false, i1 false}
-// IGNORELIST-SRC: ![[EXTRA_GLOBAL_LOC]] = !{!"{{.*}}extra-source.cpp", i32 1, i32 5}
-// IGNORELIST-SRC: ![[GLOBAL]] = !{{{.*}} null, null, i1 false, i1 true}
-// IGNORELIST-SRC: ![[DYN_INIT_GLOBAL]] = !{{{.*}} null, null, i1 true, i1 true}
-// IGNORELIST-SRC: ![[ATTR_GLOBAL]] = !{{{.*attributed_global.*}}, null, null, i1 false, i1 true}
-// IGNORELIST-SRC: ![[DISABLE_INSTR_GLOBAL]] = !{{{.*disable_instrumentation_global.*}}, null, null, i1 false, i1 true}
-// IGNORELIST-SRC: ![[IGNORELISTED_GLOBAL]] = !{{{.*ignorelisted_global.*}}, null, null, i1 false, i1 true}
-// IGNORELIST-SRC: ![[SECTIONED_GLOBAL]] = !{{{.*}} null, null, i1 false, i1 true}
-// IGNORELIST-SRC: ![[SPECIAL_GLOBAL]] = !{{{.*}} null, null, i1 false, i1 true}
-// IGNORELIST-SRC: ![[STATIC_VAR]] = !{{{.*}} null, null, i1 false, i1 true}
-// IGNORELIST-SRC: ![[LITERAL]] = !{{{.*}} null, null, i1 false, i1 true}
+// IGNORELIST-SRC: @extra_global = global {{.*}} sanitize_address
+// IGNORELIST-SRC: @global = global {{.*}} no_sanitize
+// IGNORELIST-SRC: @dyn_init_global = global {{.*}} no_sanitize,
+// IGNORELIST-SRC: @attributed_global = global {{.*}} no_sanitize
+// IGNORELIST-SRC: @disable_instrumentation_global = global {{.*}} no_sanitize
+// IGNORELIST-SRC: @ignorelisted_global = global {{.*}} no_sanitize
+// IGNORELIST-SRC: @sectioned_global = global {{.*}} no_sanitize
+// IGNORELIST-SRC: @__special_global = global {{.*}} no_sanitize
+// IGNORELIST-SRC: @{{[^ ]*}}static_var{{[^ ]*}} = internal global {{.*}} no_sanitize
+// IGNORELIST-SRC: @.str = {{.*}} constant {{.*}}"Hello, world!{{.*}} no_sanitize
Index: clang/test/CodeGen/asan-globals-odr.cpp
===================================================================
--- clang/test/CodeGen/asan-globals-odr.cpp
+++ clang/test/CodeGen/asan-globals-odr.cpp
@@ -14,7 +14,7 @@
return global;
}
-// CHECK: [[VAR:@.*global.*]] ={{.*}} global { i32, [28 x i8] } zeroinitializer, align 32
+// CHECK: [[VAR:@.*global.*]] ={{.*}} global { i32, [28 x i8] } zeroinitializer, sanitize_address, align 32
// INDICATOR0-NOT: __odr_asan_gen
// INDICATOR1: [[ODR:@.*__odr_asan_gen_.*global.*]] = global i8 0, align 1
Index: clang/test/CodeGen/asan-globals-alias.cpp
===================================================================
--- clang/test/CodeGen/asan-globals-alias.cpp
+++ clang/test/CodeGen/asan-globals-alias.cpp
@@ -22,12 +22,12 @@
struct input_device_id joydev_ids[] = { { {1}, 1234 } }; // KASAN ignored
extern struct input_device_id __attribute__((alias("joydev_ids"))) __mod_joydev_ids_device_table;
-// ASAN: @aliased_global{{.*}} global { i32, [28 x i8] }{{.*}}, align 32
-// ASAN: @aliased_global_2{{.*}} global { i32, [28 x i8] }{{.*}}, align 32
-// ASAN: @joydev_ids{{.*}} global { {{.*}}[56 x i8] zeroinitializer }, align 32
+// ASAN: @aliased_global{{.*}} global { i32, [28 x i8] }{{.*}}, sanitize_address, align 32
+// ASAN: @aliased_global_2{{.*}} global { i32, [28 x i8] }{{.*}}, sanitize_address, align 32
+// ASAN: @joydev_ids{{.*}} global { {{.*}}[56 x i8] zeroinitializer }, sanitize_address, align 32
// KASAN: @aliased_global{{.*}} global i32
// KASAN: @aliased_global_2{{.*}} global i32
-// KASAN: @joydev_ids{{.*}} global [1 x {{.*}}i64 1234 }], align 16
+// KASAN: @joydev_ids{{.*}} global [1 x {{.*}}i64 1234 }], sanitize_address, align 16
// Check the aliases exist:
// CHECK: @__global_alias ={{.*}} alias
Index: clang/lib/CodeGen/SanitizerMetadataFactory.h
===================================================================
--- /dev/null
+++ clang/lib/CodeGen/SanitizerMetadataFactory.h
@@ -0,0 +1,55 @@
+//===--- SanitizerMetadataFactory.h - Metadata for sanitizers ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Class which emits metadata consumed by sanitizer instrumentation passes.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_LIB_CODEGEN_SANITIZERMETADATAFACTORY_H
+#define LLVM_CLANG_LIB_CODEGEN_SANITIZERMETADATAFACTORY_H
+
+#include "clang/AST/Type.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/Sanitizers.h"
+#include "clang/Basic/SourceLocation.h"
+
+#include "llvm/IR/GlobalVariable.h"
+
+namespace llvm {
+class Instruction;
+} // namespace llvm
+
+namespace clang {
+class VarDecl;
+
+namespace CodeGen {
+
+class CodeGenModule;
+
+class SanitizerMetadataFactory {
+ SanitizerMetadataFactory(const SanitizerMetadataFactory &) = delete;
+ void operator=(const SanitizerMetadataFactory &) = delete;
+
+ CodeGenModule &CGM;
+
+public:
+ SanitizerMetadataFactory(CodeGenModule &CGM);
+
+ void reportGlobal(llvm::GlobalVariable *GV, const VarDecl &D,
+ bool IsDynInit = false);
+ void reportGlobal(llvm::GlobalVariable *GV, SourceLocation Loc, QualType Ty,
+ bool IsDynInit = false, SanitizerMask NoSanitizeMask = {});
+ void setASanSpecificMetadata(llvm::GlobalVariable::SanitizerMetadata &Meta,
+ llvm::GlobalVariable *GV, SourceLocation Loc,
+ QualType Ty, bool IsDynInit = false);
+ void disableSanitizerForGlobal(llvm::GlobalVariable *GV);
+ void disableSanitizerForInstruction(llvm::Instruction *I);
+};
+} // end namespace CodeGen
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_CODEGEN_SANITIZERMETADATAFACTORY_H
Index: clang/lib/CodeGen/SanitizerMetadataFactory.cpp
===================================================================
--- /dev/null
+++ clang/lib/CodeGen/SanitizerMetadataFactory.cpp
@@ -0,0 +1,116 @@
+//===--- SanitizerMetadataFactory.cpp - Ignored entities for sanitizers ---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Class which emits metadata consumed by sanitizer instrumentation passes.
+//
+//===----------------------------------------------------------------------===//
+#include "SanitizerMetadataFactory.h"
+#include "CodeGenModule.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/Constants.h"
+
+using GlobalVariable = llvm::GlobalVariable;
+using SanitizerMetadata = GlobalVariable::SanitizerMetadata;
+using GlobalSanitizer = SanitizerMetadata::GlobalSanitizer;
+
+namespace clang {
+namespace CodeGen {
+
+SanitizerMetadataFactory::SanitizerMetadataFactory(CodeGenModule &CGM)
+ : CGM(CGM) {}
+
+void SanitizerMetadataFactory::setASanSpecificMetadata(SanitizerMetadata &Meta,
+ GlobalVariable *GV,
+ SourceLocation Loc,
+ QualType Ty,
+ bool IsDynInit) {
+ IsDynInit &= !CGM.isInNoSanitizeList(GV, Loc, Ty, "init");
+ Meta.IsDynInit = IsDynInit;
+}
+
+void SanitizerMetadataFactory::reportGlobal(GlobalVariable *GV,
+ SourceLocation Loc, QualType Ty,
+ bool IsDynInit,
+ SanitizerMask NoSanitizeMask) {
+
+ SanitizerMetadata Meta;
+ if (GV->hasSanitizerMetadata())
+ Meta = GV->getSanitizerMetadata();
+
+ if (CGM.isInNoSanitizeList(GV, Loc, Ty) ||
+ NoSanitizeMask == SanitizerKind::All) {
+ Meta.AddSanitizer(GlobalSanitizer::NoSanitize);
+ GV->setSanitizerMetadata(Meta);
+ return;
+ }
+
+ auto &SanTarget = CGM.getLangOpts().Sanitize;
+ SanitizerSet NoSanitizeSet;
+ NoSanitizeSet.Mask = NoSanitizeMask;
+
+ if (SanTarget.hasOneOf(SanitizerKind::Address |
+ SanitizerKind::KernelAddress)) {
+ if (NoSanitizeSet.hasOneOf(SanitizerKind::Address |
+ SanitizerKind::KernelAddress))
+ Meta.AddSanitizer(GlobalSanitizer::NoAddress);
+ else
+ Meta.AddSanitizer(GlobalSanitizer::Address);
+
+ setASanSpecificMetadata(Meta, GV, Loc, Ty, IsDynInit);
+ }
+ if (SanTarget.hasOneOf(SanitizerKind::HWAddress |
+ SanitizerKind::KernelHWAddress)) {
+ if (NoSanitizeSet.hasOneOf(SanitizerKind::HWAddress |
+ SanitizerKind::KernelHWAddress))
+ Meta.AddSanitizer(GlobalSanitizer::NoHWAddress);
+ else
+ Meta.AddSanitizer(GlobalSanitizer::HWAddress);
+ }
+
+ if (SanTarget.hasOneOf(SanitizerKind::MemTag)) {
+ if (NoSanitizeSet.hasOneOf(SanitizerKind::MemTag))
+ Meta.AddSanitizer(GlobalSanitizer::NoMemtag);
+ else
+ Meta.AddSanitizer(GlobalSanitizer::Memtag);
+ }
+
+ GV->setSanitizerMetadata(Meta);
+}
+
+void SanitizerMetadataFactory::reportGlobal(GlobalVariable *GV,
+ const VarDecl &D, bool IsDynInit) {
+ if (D.hasAttr<DisableSanitizerInstrumentationAttr>()) {
+ SanitizerMetadata Meta;
+ Meta.AddSanitizer(GlobalSanitizer::NoSanitize);
+ GV->setSanitizerMetadata(Meta);
+ return;
+ }
+
+ SanitizerMask NoSanitizeMask;
+ for (auto Attr : D.specific_attrs<NoSanitizeAttr>()) {
+ NoSanitizeMask |= Attr->getMask();
+ }
+
+ reportGlobal(GV, D.getLocation(), D.getType(), IsDynInit, NoSanitizeMask);
+}
+
+void SanitizerMetadataFactory::disableSanitizerForGlobal(GlobalVariable *GV) {
+ reportGlobal(GV, SourceLocation(), QualType(), false, SanitizerKind::All);
+}
+
+void SanitizerMetadataFactory::disableSanitizerForInstruction(
+ llvm::Instruction *I) {
+ I->setMetadata(CGM.getModule().getMDKindID("nosanitize"),
+ llvm::MDNode::get(CGM.getLLVMContext(), None));
+}
+
+} // namespace CodeGen
+} // namespace clang
Index: clang/lib/CodeGen/SanitizerMetadata.h
===================================================================
--- clang/lib/CodeGen/SanitizerMetadata.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//===--- SanitizerMetadata.h - Metadata for sanitizers ----------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Class which emits metadata consumed by sanitizer instrumentation passes.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_LIB_CODEGEN_SANITIZERMETADATA_H
-#define LLVM_CLANG_LIB_CODEGEN_SANITIZERMETADATA_H
-
-#include "clang/AST/Type.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/SourceLocation.h"
-
-namespace llvm {
-class GlobalVariable;
-class Instruction;
-class MDNode;
-}
-
-namespace clang {
-class VarDecl;
-
-namespace CodeGen {
-
-class CodeGenModule;
-
-class SanitizerMetadata {
- SanitizerMetadata(const SanitizerMetadata &) = delete;
- void operator=(const SanitizerMetadata &) = delete;
-
- CodeGenModule &CGM;
-public:
- SanitizerMetadata(CodeGenModule &CGM);
- void reportGlobalToASan(llvm::GlobalVariable *GV, const VarDecl &D,
- bool IsDynInit = false);
- void reportGlobalToASan(llvm::GlobalVariable *GV, SourceLocation Loc,
- StringRef Name, QualType Ty, bool IsDynInit = false,
- bool IsExcluded = false);
- void disableSanitizerForGlobal(llvm::GlobalVariable *GV);
- void disableSanitizerForInstruction(llvm::Instruction *I);
-private:
- llvm::MDNode *getLocationMetadata(SourceLocation Loc);
-};
-} // end namespace CodeGen
-} // end namespace clang
-
-#endif
Index: clang/lib/CodeGen/SanitizerMetadata.cpp
===================================================================
--- clang/lib/CodeGen/SanitizerMetadata.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-//===--- SanitizerMetadata.cpp - Ignored entities for sanitizers ----------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Class which emits metadata consumed by sanitizer instrumentation passes.
-//
-//===----------------------------------------------------------------------===//
-#include "SanitizerMetadata.h"
-#include "CodeGenModule.h"
-#include "clang/AST/Attr.h"
-#include "clang/AST/Type.h"
-#include "clang/Basic/SourceManager.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/IR/Constants.h"
-
-using namespace clang;
-using namespace CodeGen;
-
-SanitizerMetadata::SanitizerMetadata(CodeGenModule &CGM) : CGM(CGM) {}
-
-static bool isAsanHwasanOrMemTag(const SanitizerSet& SS) {
- return SS.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress |
- SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress |
- SanitizerKind::MemTag);
-}
-
-void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
- SourceLocation Loc, StringRef Name,
- QualType Ty, bool IsDynInit,
- bool IsExcluded) {
- if (!isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize))
- return;
- IsDynInit &= !CGM.isInNoSanitizeList(GV, Loc, Ty, "init");
- IsExcluded |= CGM.isInNoSanitizeList(GV, Loc, Ty);
-
- llvm::Metadata *LocDescr = nullptr;
- llvm::Metadata *GlobalName = nullptr;
- llvm::LLVMContext &VMContext = CGM.getLLVMContext();
- if (!IsExcluded) {
- // Don't generate source location and global name if it is on
- // the NoSanitizeList - it won't be instrumented anyway.
- LocDescr = getLocationMetadata(Loc);
- if (!Name.empty())
- GlobalName = llvm::MDString::get(VMContext, Name);
- }
-
- llvm::Metadata *GlobalMetadata[] = {
- llvm::ConstantAsMetadata::get(GV), LocDescr, GlobalName,
- llvm::ConstantAsMetadata::get(
- llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), IsDynInit)),
- llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
- llvm::Type::getInt1Ty(VMContext), IsExcluded))};
-
- llvm::MDNode *ThisGlobal = llvm::MDNode::get(VMContext, GlobalMetadata);
- llvm::NamedMDNode *AsanGlobals =
- CGM.getModule().getOrInsertNamedMetadata("llvm.asan.globals");
- AsanGlobals->addOperand(ThisGlobal);
-}
-
-void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
- const VarDecl &D, bool IsDynInit) {
- if (!isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize))
- return;
- std::string QualName;
- llvm::raw_string_ostream OS(QualName);
- D.printQualifiedName(OS);
-
- bool IsExcluded = false;
- for (auto Attr : D.specific_attrs<NoSanitizeAttr>())
- if (Attr->getMask() & SanitizerKind::Address)
- IsExcluded = true;
- if (D.hasAttr<DisableSanitizerInstrumentationAttr>())
- IsExcluded = true;
- reportGlobalToASan(GV, D.getLocation(), OS.str(), D.getType(), IsDynInit,
- IsExcluded);
-}
-
-void SanitizerMetadata::disableSanitizerForGlobal(llvm::GlobalVariable *GV) {
- // For now, just make sure the global is not modified by the ASan
- // instrumentation.
- if (isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize))
- reportGlobalToASan(GV, SourceLocation(), "", QualType(), false, true);
-}
-
-void SanitizerMetadata::disableSanitizerForInstruction(llvm::Instruction *I) {
- I->setMetadata(CGM.getModule().getMDKindID("nosanitize"),
- llvm::MDNode::get(CGM.getLLVMContext(), None));
-}
-
-llvm::MDNode *SanitizerMetadata::getLocationMetadata(SourceLocation Loc) {
- PresumedLoc PLoc = CGM.getContext().getSourceManager().getPresumedLoc(Loc);
- if (!PLoc.isValid())
- return nullptr;
- llvm::LLVMContext &VMContext = CGM.getLLVMContext();
- llvm::Metadata *LocMetadata[] = {
- llvm::MDString::get(VMContext, PLoc.getFilename()),
- llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
- llvm::Type::getInt32Ty(VMContext), PLoc.getLine())),
- llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
- llvm::Type::getInt32Ty(VMContext), PLoc.getColumn())),
- };
- return llvm::MDNode::get(VMContext, LocMetadata);
-}
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -2189,7 +2189,7 @@
(expr->getOperatorNew()->isReplaceableGlobalAllocationFunction() ||
CGM.getCodeGenOpts().SanitizeAddressPoisonCustomArrayCookie)) {
// The store to the CookiePtr does not need to be instrumented.
- CGM.getSanitizerMetadata()->disableSanitizerForInstruction(SI);
+ CGM.getSanitizerMetadataFactory()->disableSanitizerForInstruction(SI);
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.getType(), false);
llvm::FunctionCallee F =
Index: clang/lib/CodeGen/CodeGenModule.h
===================================================================
--- clang/lib/CodeGen/CodeGenModule.h
+++ clang/lib/CodeGen/CodeGenModule.h
@@ -16,7 +16,7 @@
#include "CGVTables.h"
#include "CodeGenTypeCache.h"
#include "CodeGenTypes.h"
-#include "SanitizerMetadata.h"
+#include "SanitizerMetadataFactory.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclOpenMP.h"
@@ -550,7 +550,7 @@
/// void @llvm.lifetime.end(i64 %size, i8* nocapture <ptr>)
llvm::Function *LifetimeEndFn = nullptr;
- std::unique_ptr<SanitizerMetadata> SanitizerMD;
+ std::unique_ptr<SanitizerMetadataFactory> SanitizerMDFactory;
llvm::MapVector<const Decl *, bool> DeferredEmptyCoverageMappingDecls;
@@ -1310,8 +1310,8 @@
/// profile instrumentation.
bool isProfileInstrExcluded(llvm::Function *Fn, SourceLocation Loc) const;
- SanitizerMetadata *getSanitizerMetadata() {
- return SanitizerMD.get();
+ SanitizerMetadataFactory *getSanitizerMetadataFactory() {
+ return SanitizerMDFactory.get();
}
void addDeferredVTable(const CXXRecordDecl *RD) {
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -104,7 +104,7 @@
PreprocessorOpts(PPO), CodeGenOpts(CGO), TheModule(M), Diags(diags),
Target(C.getTargetInfo()), ABI(createCXXABI(*this)),
VMContext(M.getContext()), Types(*this), VTables(*this),
- SanitizerMD(new SanitizerMetadata(*this)) {
+ SanitizerMDFactory(new SanitizerMetadataFactory(*this)) {
// Initialize the type cache.
llvm::LLVMContext &LLVMContext = M.getContext();
@@ -2752,18 +2752,11 @@
bool CodeGenModule::isInNoSanitizeList(llvm::GlobalVariable *GV,
SourceLocation Loc, QualType Ty,
StringRef Category) const {
- // For now globals can be ignored only in ASan and KASan.
- const SanitizerMask EnabledAsanMask =
- LangOpts.Sanitize.Mask &
- (SanitizerKind::Address | SanitizerKind::KernelAddress |
- SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress |
- SanitizerKind::MemTag);
- if (!EnabledAsanMask)
- return false;
const auto &NoSanitizeL = getContext().getNoSanitizeList();
- if (NoSanitizeL.containsGlobal(EnabledAsanMask, GV->getName(), Category))
+ if (NoSanitizeL.containsGlobal(LangOpts.Sanitize.Mask, GV->getName(),
+ Category))
return true;
- if (NoSanitizeL.containsLocation(EnabledAsanMask, Loc, Category))
+ if (NoSanitizeL.containsLocation(LangOpts.Sanitize.Mask, Loc, Category))
return true;
// Check global type.
if (!Ty.isNull()) {
@@ -2775,7 +2768,7 @@
// Only record types (classes, structs etc.) are ignored.
if (Ty->isRecordType()) {
std::string TypeStr = Ty.getAsString(getContext().getPrintingPolicy());
- if (NoSanitizeL.containsType(EnabledAsanMask, TypeStr, Category))
+ if (NoSanitizeL.containsType(LangOpts.Sanitize.Mask, TypeStr, Category))
return true;
}
}
@@ -4781,7 +4774,7 @@
if (NeedsGlobalCtor || NeedsGlobalDtor)
EmitCXXGlobalVarDeclInitFunc(D, GV, NeedsGlobalCtor);
- SanitizerMD->reportGlobalToASan(GV, *D, NeedsGlobalCtor);
+ SanitizerMDFactory->reportGlobal(GV, *D, NeedsGlobalCtor);
// Emit global variable debug information.
if (CGDebugInfo *DI = getModuleDebugInfo())
@@ -5667,8 +5660,7 @@
if (Entry)
*Entry = GV;
- SanitizerMD->reportGlobalToASan(GV, S->getStrTokenLoc(0), "<string literal>",
- QualType());
+ SanitizerMDFactory->reportGlobal(GV, S->getStrTokenLoc(0), QualType());
return ConstantAddress(castStringLiteralToDefaultAddressSpace(*this, GV),
GV->getValueType(), Alignment);
Index: clang/lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.cpp
+++ clang/lib/CodeGen/CodeGenFunction.cpp
@@ -2510,7 +2510,7 @@
llvm::BasicBlock::iterator InsertPt) const {
LoopStack.InsertHelper(I);
if (IsSanitizerScope)
- CGM.getSanitizerMetadata()->disableSanitizerForInstruction(I);
+ CGM.getSanitizerMetadataFactory()->disableSanitizerForInstruction(I);
}
void CGBuilderInserter::InsertHelper(
Index: clang/lib/CodeGen/CMakeLists.txt
===================================================================
--- clang/lib/CodeGen/CMakeLists.txt
+++ clang/lib/CodeGen/CMakeLists.txt
@@ -80,7 +80,7 @@
ModuleBuilder.cpp
ObjectFilePCHContainerOperations.cpp
PatternInit.cpp
- SanitizerMetadata.cpp
+ SanitizerMetadataFactory.cpp
SwiftCallingConv.cpp
TargetInfo.cpp
VarBypassDetector.cpp
Index: clang/lib/CodeGen/CGStmt.cpp
===================================================================
--- clang/lib/CodeGen/CGStmt.cpp
+++ clang/lib/CodeGen/CGStmt.cpp
@@ -1263,7 +1263,7 @@
new llvm::GlobalVariable(CGM.getModule(), SLoc->getType(), false,
llvm::GlobalVariable::PrivateLinkage, SLoc);
SLocPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
- CGM.getSanitizerMetadata()->disableSanitizerForGlobal(SLocPtr);
+ CGM.getSanitizerMetadataFactory()->disableSanitizerForGlobal(SLocPtr);
assert(ReturnLocation.isValid() && "No valid return location");
Builder.CreateStore(Builder.CreateBitCast(SLocPtr, Int8PtrTy),
ReturnLocation);
Index: clang/lib/CodeGen/CGExpr.cpp
===================================================================
--- clang/lib/CodeGen/CGExpr.cpp
+++ clang/lib/CodeGen/CGExpr.cpp
@@ -3095,7 +3095,7 @@
CGM.getModule(), Descriptor->getType(),
/*isConstant=*/true, llvm::GlobalVariable::PrivateLinkage, Descriptor);
GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
- CGM.getSanitizerMetadata()->disableSanitizerForGlobal(GV);
+ CGM.getSanitizerMetadataFactory()->disableSanitizerForGlobal(GV);
// Remember the descriptor for this type.
CGM.setTypeDescriptorInMap(T, GV);
@@ -3175,8 +3175,8 @@
auto FilenameGV =
CGM.GetAddrOfConstantCString(std::string(FilenameString), ".src");
- CGM.getSanitizerMetadata()->disableSanitizerForGlobal(
- cast<llvm::GlobalVariable>(FilenameGV.getPointer()));
+ CGM.getSanitizerMetadataFactory()->disableSanitizerForGlobal(
+ cast<llvm::GlobalVariable>(FilenameGV.getPointer()));
Filename = FilenameGV.getPointer();
Line = PLoc.getLine();
Column = PLoc.getColumn();
@@ -3348,7 +3348,7 @@
new llvm::GlobalVariable(CGM.getModule(), Info->getType(), false,
llvm::GlobalVariable::PrivateLinkage, Info);
InfoPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
- CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr);
+ CGM.getSanitizerMetadataFactory()->disableSanitizerForGlobal(InfoPtr);
Args.push_back(Builder.CreateBitCast(InfoPtr, Int8PtrTy));
ArgTypes.push_back(Int8PtrTy);
}
@@ -3409,7 +3409,7 @@
new llvm::GlobalVariable(CGM.getModule(), Info->getType(), false,
llvm::GlobalVariable::PrivateLinkage, Info);
InfoPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
- CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr);
+ CGM.getSanitizerMetadataFactory()->disableSanitizerForGlobal(InfoPtr);
SlowPathFn = CGM.getModule().getOrInsertFunction(
"__cfi_slowpath_diag",
Index: clang/lib/CodeGen/CGDecl.cpp
===================================================================
--- clang/lib/CodeGen/CGDecl.cpp
+++ clang/lib/CodeGen/CGDecl.cpp
@@ -473,7 +473,7 @@
LocalDeclMap.find(&D)->second = Address(castedAddr, elemTy, alignment);
CGM.setStaticLocalDeclAddress(&D, castedAddr);
- CGM.getSanitizerMetadata()->reportGlobalToASan(var, D);
+ CGM.getSanitizerMetadataFactory()->reportGlobal(var, D);
// Emit global variable debug descriptor for static vars.
CGDebugInfo *DI = getDebugInfo();
Index: clang/lib/CodeGen/BackendUtil.cpp
===================================================================
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -672,7 +672,6 @@
Opts.Recover = CodeGenOpts.SanitizeRecover.has(Mask);
Opts.UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope;
Opts.UseAfterReturn = CodeGenOpts.getSanitizeAddressUseAfterReturn();
- MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
MPM.addPass(ModuleAddressSanitizerPass(
Opts, UseGlobalGC, UseOdrIndicator, DestructorKind));
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits