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
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to