vitalybuka updated this revision to Diff 434955.
vitalybuka added a comment.

fix rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D126100

Files:
  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
  llvm/test/Assembler/globalvariable-attributes.ll
  llvm/test/Bitcode/compatibility.ll

Index: llvm/test/Bitcode/compatibility.ll
===================================================================
--- llvm/test/Bitcode/compatibility.ll
+++ llvm/test/Bitcode/compatibility.ll
@@ -203,6 +203,16 @@
 @llvm.global_dtors = appending global [1 x %pri.func.data] [%pri.func.data { i32 0, void ()* @g.f1, i8* @g.used3 }], section "llvm.metadata"
 ; CHECK: @llvm.global_dtors = appending global [1 x %pri.func.data] [%pri.func.data { i32 0, void ()* @g.f1, i8* @g.used3 }], section "llvm.metadata"
 
+; Global Variables -- sanitizers
+@g.no_sanitize = global i32 0, no_sanitize
+@g.no_sanitize_address = global i32 0, no_sanitize_address
+@g.no_sanitize_hwaddress = global i32 0, no_sanitize_hwaddress
+@g.sanitize_address_dyninit = global i32 0, sanitize_address_dyninit
+; CHECK: @g.no_sanitize = global i32 0, no_sanitize
+; CHECK: @g.no_sanitize_address = global i32 0, no_sanitize_address
+; CHECK: @g.no_sanitize_hwaddress = global i32 0, no_sanitize_hwaddress
+; CHECK: @g.sanitize_address_dyninit = global i32 0, sanitize_address_dyninit
+
 ;; Aliases
 ; Format: @<Name> = [Linkage] [Visibility] [DLLStorageClass] [ThreadLocal]
 ;                   [unnamed_addr] alias <AliaseeTy> @<Aliasee>
Index: llvm/test/Assembler/globalvariable-attributes.ll
===================================================================
--- llvm/test/Assembler/globalvariable-attributes.ll
+++ llvm/test/Assembler/globalvariable-attributes.ll
@@ -4,6 +4,11 @@
 @g2 = global i32 2, align 4 "key3" = "value3"
 @g3 = global i32 2 #0
 @g4 = global i32 2, align 4 "key5" = "value5" #0
+@g5 = global i32 2, no_sanitize, align 4
+@g6 = global i32 2, no_sanitize_address, align 4
+@g7 = global i32 2, no_sanitize_hwaddress, align 4
+@g8 = global i32 2, no_sanitize_address, no_sanitize_hwaddress, align 4
+@g9 = global i32 2, no_sanitize, no_sanitize_address, no_sanitize_hwaddress, align 4
 
 attributes #0 = { "string" = "value" nobuiltin norecurse }
 
@@ -11,6 +16,15 @@
 ; CHECK: @g2 = global i32 2, align 4 #1
 ; CHECK: @g3 = global i32 2 #2
 ; CHECK: @g4 = global i32 2, align 4 #3
+; CHECK: @g5 = global i32 2, no_sanitize, align 4
+; CHECK: @g6 = global i32 2, no_sanitize_address, align 4
+; CHECK: @g7 = global i32 2, no_sanitize_hwaddress, align 4
+; CHECK: @g8 = global i32 2, no_sanitize_address, no_sanitize_hwaddress, align 4
+
+;; no_sanitize attribute should override and turncate other sanitize_* attrs.
+; CHECK: @g9 = global i32 2, no_sanitize, align 4
+; CHECK-NOT: no_sanitize_address
+; CHECK-NOT: no_sanitize_hwaddress
 
 ; CHECK: attributes #0 = { "key"="value" "key2"="value2" }
 ; CHECK: attributes #1 = { "key3"="value3" }
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;
+const SanitizerMetadata &GlobalValue::getSanitizerMetadata() const {
+  assert(hasSanitizerMetadata());
+  assert(getContext().pImpl->GlobalValueSanitizerMetadata.count(this));
+  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
@@ -3535,6 +3535,21 @@
     Out << '"';
   }
 
+  using SanitizerMetadata = llvm::GlobalValue::SanitizerMetadata;
+  if (GV->hasSanitizerMetadata()) {
+    SanitizerMetadata MD = GV->getSanitizerMetadata();
+    if (MD.NoSanitize) {
+      Out << ", no_sanitize";
+    } else {
+      if (MD.NoAddress)
+        Out << ", no_sanitize_address";
+      if (MD.NoHWAddress)
+        Out << ", no_sanitize_hwaddress";
+      if (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
@@ -1346,7 +1346,7 @@
     // 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]
     Vals.push_back(addToStrtab(GV.getName()));
     Vals.push_back(GV.getName().size());
     Vals.push_back(VE.getTypeID(GV.getValueType()));
@@ -1363,7 +1363,7 @@
         GV.isExternallyInitialized() ||
         GV.getDLLStorageClass() != GlobalValue::DefaultStorageClass ||
         GV.hasComdat() || GV.hasAttributes() || GV.isDSOLocal() ||
-        GV.hasPartition()) {
+        GV.hasPartition() || GV.hasSanitizerMetadata()) {
       Vals.push_back(getEncodedVisibility(GV));
       Vals.push_back(getEncodedThreadLocalMode(GV));
       Vals.push_back(getEncodedUnnamedAddr(GV));
@@ -1377,6 +1377,11 @@
       Vals.push_back(GV.isDSOLocal());
       Vals.push_back(addToStrtab(GV.getPartition()));
       Vals.push_back(GV.getPartition().size());
+
+      if (GV.hasSanitizerMetadata())
+        Vals.push_back(GV.getSanitizerMetadata().serialize());
+      else
+        Vals.push_back(UINT_MAX);
     } else {
       AbbrevToUse = SimpleGVarAbbrev;
     }
Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
===================================================================
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -3544,6 +3544,12 @@
   if (Record.size() > 15)
     NewGV->setPartition(StringRef(Strtab.data() + Record[14], Record[15]));
 
+  if (Record.size() > 16 && Record[16] != UINT_MAX) {
+    llvm::GlobalValue::SanitizerMetadata Meta;
+    Meta.deserialize(Record[16]);
+    NewGV->setSanitizerMetadata(Meta);
+  }
+
   return Error::success();
 }
 
Index: llvm/lib/AsmParser/LLParser.cpp
===================================================================
--- llvm/lib/AsmParser/LLParser.cpp
+++ llvm/lib/AsmParser/LLParser.cpp
@@ -1103,6 +1103,45 @@
   return false;
 }
 
+static bool isSanitizer(lltok::Kind Kind) {
+  switch (Kind) {
+  case lltok::kw_no_sanitize:
+  case lltok::kw_no_sanitize_address:
+  case lltok::kw_no_sanitize_hwaddress:
+  case lltok::kw_sanitize_address_dyninit:
+    return true;
+  default:
+    return false;
+  }
+}
+
+bool LLParser::parseSanitizer(GlobalVariable *GV) {
+  using SanitizerMetadata = GlobalValue::SanitizerMetadata;
+  SanitizerMetadata Meta;
+  if (GV->hasSanitizerMetadata())
+    Meta = GV->getSanitizerMetadata();
+
+  switch (Lex.getKind()) {
+  case lltok::kw_no_sanitize:
+    Meta.NoSanitize = true;
+    break;
+  case lltok::kw_no_sanitize_address:
+    Meta.NoAddress = true;
+    break;
+  case lltok::kw_no_sanitize_hwaddress:
+    Meta.NoHWAddress = true;
+    break;
+  case lltok::kw_sanitize_address_dyninit:
+    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 +1260,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,12 @@
   KEYWORD(prefix);
   KEYWORD(prologue);
 
+  // Sanitizer keywords.
+  KEYWORD(no_sanitize);
+  KEYWORD(no_sanitize_address);
+  KEYWORD(no_sanitize_hwaddress);
+  KEYWORD(sanitize_address_dyninit);
+
   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,53 @@
   StringRef getPartition() const;
   void setPartition(StringRef Part);
 
+  // ASan, HWASan and Memtag sanitizers have some instrumentation that applies
+  // specifically to global variables. This instrumentation is implicitly
+  // applied to all global variables when built with -fsanitize=*. What we need
+  // is a way to persist the information that a certain global variable should
+  // *not* have sanitizers applied, which occurs if:
+  //   1. The global variable is in the sanitizer ignore list, or
+  //   2. The global variable is created by the sanitizers itself for internal
+  //      usage, or
+  //   3. The global variable has __attribute__((no_sanitize("..."))) or
+  //      __attribute__((disable_sanitizer_instrumentation)).
+  //
+  // This is important, a some IR passes like GlobalMerge can delete global
+  // variables and replace them with new ones. If the old variables were marked
+  // to be unsanitized, then the new ones should also be.
+  struct SanitizerMetadata {
+    SanitizerMetadata()
+        : NoSanitize(false), NoAddress(false), NoHWAddress(false),
+          NoMemtag(false), IsDynInit(false) {}
+    unsigned NoSanitize : 1;
+    unsigned NoAddress : 1;
+    unsigned NoHWAddress : 1;
+    unsigned NoMemtag : 1;
+
+    // ASan-specific metadata. Is this global variable dynamically initialized
+    // (from a C++ language perspective), and should therefore be checked for
+    // ODR violations.
+    unsigned IsDynInit : 1;
+
+    unsigned serialize() const {
+      return NoSanitize | (NoAddress << 1) | (NoHWAddress << 2) |
+             (NoMemtag << 3) | (IsDynInit << 4);
+    }
+    void deserialize(unsigned V) {
+      if (V & (1 << 0)) NoSanitize = true;
+      if (V & (1 << 1)) NoAddress = true;
+      if (V & (1 << 2)) NoHWAddress = true;
+      if (V & (1 << 3)) NoMemtag = true;
+      if (V & (1 << 4)) IsDynInit = true;
+    }
+  };
+  static_assert(sizeof(SanitizerMetadata) <= sizeof(unsigned),
+                "Sanitizer Metadata is too large for naive serialization.");
+
+  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
@@ -391,6 +391,17 @@
   kw_bit,
   kw_varFlags,
 
+  // Extra sanitizer attributes that are used for global variables (GV's).
+  // GV's mentioned in -fsanitize-ignorelist=<file>.
+  kw_no_sanitize,
+  // 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,
+  // GV's with __attribute__((no_sanitize("hwaddress"))).
+  kw_no_sanitize_hwaddress,
+
   // Unsigned Valued tokens (UIntVal).
   LabelID,    // 42:
   GlobalID,   // @42
Index: llvm/include/llvm/AsmParser/LLParser.h
===================================================================
--- llvm/include/llvm/AsmParser/LLParser.h
+++ llvm/include/llvm/AsmParser/LLParser.h
@@ -515,6 +515,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);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to