hctim updated this revision to Diff 431810.
hctim added a comment.

Remove extra creation path, turns out it's a duplicate of elsewhere.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D126100/new/

https://reviews.llvm.org/D126100

Files:
  clang/lib/CodeGen/CGDecl.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/SanitizerMetadata.cpp
  clang/lib/CodeGen/SanitizerMetadata.h
  clang/test/CodeGen/asan-globals-alias.cpp
  clang/test/CodeGen/asan-globals-odr.cpp
  clang/test/CodeGen/asan-static-odr.cpp
  clang/test/CodeGen/asan-strings.c
  llvm/docs/LangRef.rst
  llvm/include/llvm/AsmParser/LLParser.h
  llvm/include/llvm/AsmParser/LLToken.h
  llvm/include/llvm/IR/GlobalValue.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

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
@@ -1344,7 +1344,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()));
@@ -1360,10 +1361,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));
@@ -1377,6 +1376,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
@@ -3540,6 +3540,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);
@@ -1103,6 +1106,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() ||
+        !Meta.HasSanitizer(SanitizerMetadata::Address)) {
+      return tokError(
+          "sanitize_address_dyninit must only occur after sanitize_address");
+    }
+    Meta.IsDynInit = true;
+    break;
+  default:
+    return tokError("non-sanitizer token passed to LLParser::parseSanitizer()");
+  }
+  GV->setSanitizerMetadata(Meta);
+  Lex.Lex();
+  return false;
+}
+
 /// parseGlobal
 ///   ::= GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier
 ///       OptionalVisibility OptionalDLLStorageClass
@@ -1221,6 +1283,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
@@ -580,6 +580,18 @@
   KEYWORD(prefix);
   KEYWORD(prologue);
 
+  // Sanitizer keywords. Some are inherited from Attributes.td. See LLToken.h
+  // for more information.
+#define DEFINED_IN_ATTRIBUTES_TD_NO_OP(var)
+  KEYWORD(no_sanitize);
+  DEFINED_IN_ATTRIBUTES_TD_NO_OP(sanitize_address);
+  KEYWORD(no_sanitize_address);
+  KEYWORD(sanitize_address_dyninit);
+  DEFINED_IN_ATTRIBUTES_TD_NO_OP(sanitize_hwaddress);
+  KEYWORD(no_sanitize_hwaddress);
+  DEFINED_IN_ATTRIBUTES_TD_NO_OP(sanitize_memtag);
+  KEYWORD(no_sanitize_memtag);
+
   KEYWORD(ccc);
   KEYWORD(fastcc);
   KEYWORD(coldcc);
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
@@ -423,7 +423,27 @@
   Type,
 
   APFloat, // APFloatVal
-  APSInt   // APSInt
+  APSInt,  // APSInt
+
+// Extra sanitizer attributes that are used for global variables (GV's). Some
+// of the attributes are inherited from Attributes.td, but we have some
+// GV-specific additions.
+#define DEFINED_IN_ATTRIBUTES_TD_NO_OP(var)
+  // GV's mentioned in -fsanitize-ignorelist=<file>.
+  kw_no_sanitize,
+  DEFINED_IN_ATTRIBUTES_TD_NO_OP(kw_sanitize_address)
+  // GV's with __attribute__((no_sanitize("address"))).
+  kw_no_sanitize_address,
+  // GV's where the clang++ frontend (when ASan is used) notes that this is
+  // dynamically initialized, and thus needs ODR detection.
+  kw_sanitize_address_dyninit,
+  DEFINED_IN_ATTRIBUTES_TD_NO_OP(kw_sanitize_hwaddress)
+  // GV's with __attribute__((no_sanitize("hwaddress"))).
+  kw_no_sanitize_hwaddress,
+  DEFINED_IN_ATTRIBUTES_TD_NO_OP(kw_sanitize_memtag)
+  // GV's with __attribute__((no_sanitize("memtag"))).
+  kw_no_sanitize_memtag,
+
 };
 } // end namespace lltok
 } // end namespace llvm
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: llvm/docs/LangRef.rst
===================================================================
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -746,6 +746,10 @@
                          <global | constant> <Type> [<InitializerConstant>]
                          [, section "name"] [, partition "name"]
                          [, comdat [($name)]] [, align <Alignment>]
+                         [, no_sanitize] [, sanitize_address]
+                         [, no_sanitize_address] [, sanitize_hwaddress]
+                         [, no_sanitize_hwaddress] [, sanitize_memtag]
+                         [, no_sanitize_memtag] [, sanitize_address_dyninit]
                          (, !name !N)*
 
 For example, the following defines a global in a numbered address space
@@ -1570,9 +1574,9 @@
     Specify the desired alignment, which must be a power of two, in
     parentheses.
 ``"alloc-family"="FAMILY"``
-    This indicates which "family" an allocator function is part of. To avoid 
-    collisions, the family name should match the mangled name of the primary 
-    allocator function, that is "malloc" for malloc/calloc/realloc/free, 
+    This indicates which "family" an allocator function is part of. To avoid
+    collisions, the family name should match the mangled name of the primary
+    allocator function, that is "malloc" for malloc/calloc/realloc/free,
     "_Znwm" for ``::operator::new`` and ``::operator::delete``, and
     "_ZnwmSt11align_val_t" for aligned ``::operator::new`` and
     ``::operator::delete``. Matching malloc/realloc/free calls within a family
@@ -20461,7 +20465,7 @@
 The '``llvm.vp.fpext``' intrinsic extends the ``value`` from a smaller
 :ref:`floating-point <t_floating>` type to a larger :ref:`floating-point
 <t_floating>` type. The '``llvm.vp.fpext``' cannot be used to make a
-*no-op cast* because it always changes bits. Use ``bitcast`` to make a 
+*no-op cast* because it always changes bits. Use ``bitcast`` to make a
 *no-op cast* for a floating-point cast.
 The conversion is performed on lane positions below the explicit vector length
 and where the vector mask is true.  Masked-off lanes are undefined.
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-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/SanitizerMetadata.h
===================================================================
--- clang/lib/CodeGen/SanitizerMetadata.h
+++ clang/lib/CodeGen/SanitizerMetadata.h
@@ -14,13 +14,15 @@
 
 #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 GlobalVariable;
 class Instruction;
 class MDNode;
-}
+} // namespace llvm
 
 namespace clang {
 class VarDecl;
@@ -34,19 +36,24 @@
   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 reportGlobal(llvm::GlobalVariable *GV, const VarDecl &D,
+                    bool IsDynInit = false);
+  void reportGlobal(llvm::GlobalVariable *GV, SourceLocation Loc,
+                    StringRef Name, QualType Ty, bool IsDynInit = false,
+                    SanitizerMask NoSanitizeMask = {});
   void disableSanitizerForGlobal(llvm::GlobalVariable *GV);
   void disableSanitizerForInstruction(llvm::Instruction *I);
+
 private:
   llvm::MDNode *getLocationMetadata(SourceLocation Loc);
+  void setASanSpecificMetadata(llvm::GlobalVariable::SanitizerMetadata &Meta,
+                               llvm::GlobalVariable *GV, SourceLocation Loc,
+                               QualType Ty, bool IsDynInit = false);
 };
-}  // end namespace CodeGen
-}  // end namespace clang
+} // end namespace CodeGen
+} // end namespace clang
 
 #endif
Index: clang/lib/CodeGen/SanitizerMetadata.cpp
===================================================================
--- clang/lib/CodeGen/SanitizerMetadata.cpp
+++ clang/lib/CodeGen/SanitizerMetadata.cpp
@@ -17,29 +17,92 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/IR/Constants.h"
 
+using GlobalVariable = llvm::GlobalVariable;
+using GVSanitizerMetadata = GlobalVariable::SanitizerMetadata;
+using GlobalSanitizer = GVSanitizerMetadata::GlobalSanitizer;
+
 using namespace clang;
 using namespace CodeGen;
 
 SanitizerMetadata::SanitizerMetadata(CodeGenModule &CGM) : CGM(CGM) {}
 
-static bool isAsanHwasanOrMemTag(const SanitizerSet& SS) {
+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;
+void SanitizerMetadata::setASanSpecificMetadata(GVSanitizerMetadata &Meta,
+                                                GlobalVariable *GV,
+                                                SourceLocation Loc, QualType Ty,
+                                                bool IsDynInit) {
   IsDynInit &= !CGM.isInNoSanitizeList(GV, Loc, Ty, "init");
-  IsExcluded |= CGM.isInNoSanitizeList(GV, Loc, Ty);
+  Meta.IsDynInit = IsDynInit;
+}
+
+void SanitizerMetadata::reportGlobal(GlobalVariable *GV, SourceLocation Loc,
+                                     StringRef Name, QualType Ty,
+                                     bool IsDynInit,
+                                     SanitizerMask NoSanitizeMask) {
+
+  GVSanitizerMetadata Meta;
+  if (GV->hasSanitizerMetadata())
+    Meta = GV->getSanitizerMetadata();
+
+  bool IsExcluded = false;
+  if (CGM.isInNoSanitizeList(GV, Loc, Ty) ||
+      NoSanitizeMask == SanitizerKind::All) {
+    Meta.AddSanitizer(GlobalSanitizer::NoSanitize);
+    IsExcluded = true;
+  }
+
+  auto &SanTarget = CGM.getLangOpts().Sanitize;
+
+  if (!isAsanHwasanOrMemTag(SanTarget))
+    return;
+
+  SanitizerSet NoSanitizeSet;
+  NoSanitizeSet.Mask = NoSanitizeMask;
+
+  llvm::LLVMContext &VMContext = CGM.getLLVMContext();
+
+  if (SanTarget.hasOneOf(SanitizerKind::Address |
+                         SanitizerKind::KernelAddress)) {
+    if (NoSanitizeSet.hasOneOf(SanitizerKind::Address |
+                               SanitizerKind::KernelAddress) ||
+        Meta.HasSanitizer(GlobalSanitizer::NoAddress)) {
+      Meta.AddSanitizer(GlobalSanitizer::NoAddress);
+      IsExcluded = true;
+    } else if (!IsExcluded) {
+      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.HasSanitizer(GlobalSanitizer::NoHWAddress)) {
+      Meta.AddSanitizer(GlobalSanitizer::NoHWAddress);
+      IsExcluded = true;
+    } else if (!IsExcluded) {
+      Meta.AddSanitizer(GlobalSanitizer::HWAddress);
+    }
+  }
+  if (SanTarget.hasOneOf(SanitizerKind::MemTag)) {
+    if (NoSanitizeSet.hasOneOf(SanitizerKind::MemTag) ||
+        Meta.HasSanitizer(GlobalSanitizer::NoMemtag)) {
+      Meta.AddSanitizer(GlobalSanitizer::NoMemtag);
+      IsExcluded = true;
+    } else if (!IsExcluded) {
+      Meta.AddSanitizer(GlobalSanitizer::Memtag);
+    }
+  }
+
+  GV->setSanitizerMetadata(Meta);
 
   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.
@@ -50,8 +113,8 @@
 
   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), Meta.IsDynInit)),
       llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
           llvm::Type::getInt1Ty(VMContext), IsExcluded))};
 
@@ -61,29 +124,27 @@
   AsanGlobals->addOperand(ThisGlobal);
 }
 
-void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
-                                           const VarDecl &D, bool IsDynInit) {
-  if (!isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize))
-    return;
+void SanitizerMetadata::reportGlobal(GlobalVariable *GV, const VarDecl &D,
+                                     bool IsDynInit) {
+  SanitizerMask NoSanitizeMask;
+  for (auto *Attr : D.specific_attrs<NoSanitizeAttr>()) {
+    NoSanitizeMask |= Attr->getMask();
+  }
+
+  if (D.hasAttr<DisableSanitizerInstrumentationAttr>()) {
+    NoSanitizeMask = SanitizerKind::All;
+  }
+
   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);
+  reportGlobal(GV, D.getLocation(), OS.str(), D.getType(), IsDynInit,
+               NoSanitizeMask);
 }
 
-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::disableSanitizerForGlobal(GlobalVariable *GV) {
+  reportGlobal(GV, SourceLocation(), "", QualType(), false, SanitizerKind::All);
 }
 
 void SanitizerMetadata::disableSanitizerForInstruction(llvm::Instruction *I) {
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -2763,18 +2763,10 @@
 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()) {
@@ -2786,7 +2778,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;
     }
   }
@@ -4792,7 +4784,7 @@
   if (NeedsGlobalCtor || NeedsGlobalDtor)
     EmitCXXGlobalVarDeclInitFunc(D, GV, NeedsGlobalCtor);
 
-  SanitizerMD->reportGlobalToASan(GV, *D, NeedsGlobalCtor);
+  SanitizerMD->reportGlobal(GV, *D, NeedsGlobalCtor);
 
   // Emit global variable debug information.
   if (CGDebugInfo *DI = getModuleDebugInfo())
@@ -5678,7 +5670,7 @@
   if (Entry)
     *Entry = GV;
 
-  SanitizerMD->reportGlobalToASan(GV, S->getStrTokenLoc(0), "<string literal>",
+  SanitizerMD->reportGlobal(GV, S->getStrTokenLoc(0), "<string literal>",
                                   QualType());
 
   return ConstantAddress(castStringLiteralToDefaultAddressSpace(*this, GV),
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.getSanitizerMetadata()->reportGlobal(var, D);
 
   // Emit global variable debug descriptor for static vars.
   CGDebugInfo *DI = getDebugInfo();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to