quantum created this revision.
quantum added reviewers: tlively, aheejin.
Herald added subscribers: llvm-commits, cfe-commits, sunfish, hiraditya, 
jgravelle-google, sbc100, dschuff.
Herald added projects: clang, LLVM.

This diff enables address sanitizer on Emscripten.

On Emscripten, real memory starts at the value passed to --global-base.

All memory before this is used as shadow memory, and thus the shadow mapping
function is simply dividing by 8.

A symbol __global_base is added so that code may know where the shadow
memory ends and real memory begins.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D63742

Files:
  clang/lib/Driver/ToolChains/WebAssembly.cpp
  clang/test/Driver/wasm-toolchain.c
  lld/test/wasm/global-base.ll
  lld/wasm/Driver.cpp
  lld/wasm/Symbols.cpp
  lld/wasm/Symbols.h
  lld/wasm/Writer.cpp
  llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp

Index: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
===================================================================
--- llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -112,6 +112,7 @@
 static const uint64_t kNetBSDKasan_ShadowOffset64 = 0xdfff900000000000;
 static const uint64_t kPS4CPU_ShadowOffset64 = 1ULL << 40;
 static const uint64_t kWindowsShadowOffset32 = 3ULL << 28;
+static const uint64_t kEmscriptenShadowOffset = 0;
 
 static const uint64_t kMyriadShadowScale = 5;
 static const uint64_t kMyriadMemoryOffset32 = 0x80000000ULL;
@@ -437,6 +438,7 @@
   bool IsWindows = TargetTriple.isOSWindows();
   bool IsFuchsia = TargetTriple.isOSFuchsia();
   bool IsMyriad = TargetTriple.getVendor() == llvm::Triple::Myriad;
+  bool IsEmscripten = TargetTriple.isOSEmscripten();
 
   ShadowMapping Mapping;
 
@@ -459,6 +461,8 @@
       Mapping.Offset = IsX86 ? kIOSSimShadowOffset32 : kIOSShadowOffset32;
     else if (IsWindows)
       Mapping.Offset = kWindowsShadowOffset32;
+    else if (IsEmscripten)
+      Mapping.Offset = kEmscriptenShadowOffset;
     else if (IsMyriad) {
       uint64_t ShadowOffset = (kMyriadMemoryOffset32 + kMyriadMemorySize32 -
                                (kMyriadMemorySize32 >> Mapping.Scale));
Index: lld/wasm/Writer.cpp
===================================================================
--- lld/wasm/Writer.cpp
+++ lld/wasm/Writer.cpp
@@ -224,6 +224,9 @@
     log("mem: global base = " + Twine(Config->GlobalBase));
   }
 
+  if (WasmSym::GlobalBase)
+    WasmSym::GlobalBase->setVirtualAddress(Config->GlobalBase);
+
   uint32_t DataStart = MemoryPtr;
 
   // Arbitrarily set __dso_handle handle to point to the start of the data
Index: lld/wasm/Symbols.h
===================================================================
--- lld/wasm/Symbols.h
+++ lld/wasm/Symbols.h
@@ -415,6 +415,10 @@
 
 // linker-generated symbols
 struct WasmSym {
+  // __global_base
+  // Symbol marking the start of the global section.
+  static DefinedData *GlobalBase;
+
   // __stack_pointer
   // Global that holds the address of the top of the explicit value stack in
   // linear memory.
Index: lld/wasm/Symbols.cpp
===================================================================
--- lld/wasm/Symbols.cpp
+++ lld/wasm/Symbols.cpp
@@ -28,6 +28,7 @@
 DefinedFunction *WasmSym::ApplyRelocs;
 DefinedData *WasmSym::DsoHandle;
 DefinedData *WasmSym::DataEnd;
+DefinedData *WasmSym::GlobalBase;
 DefinedData *WasmSym::HeapBase;
 GlobalSymbol *WasmSym::StackPointer;
 UndefinedGlobal *WasmSym::TableBase;
Index: lld/wasm/Driver.cpp
===================================================================
--- lld/wasm/Driver.cpp
+++ lld/wasm/Driver.cpp
@@ -482,6 +482,7 @@
     WasmSym::StackPointer = Symtab->addSyntheticGlobal(
         "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, StackPointer);
     WasmSym::DataEnd = Symtab->addOptionalDataSymbol("__data_end");
+    WasmSym::GlobalBase = Symtab->addOptionalDataSymbol("__global_base");
     WasmSym::HeapBase = Symtab->addOptionalDataSymbol("__heap_base");
   }
 
Index: lld/test/wasm/global-base.ll
===================================================================
--- /dev/null
+++ lld/test/wasm/global-base.ll
@@ -0,0 +1,73 @@
+; RUN: llc -filetype=obj %s -o %t.o
+
+target triple = "wasm32-unknown-unknown"
+
+; RUN: wasm-ld -no-gc-sections --export=__global_base --export=__data_end --allow-undefined --no-entry -o %t.wasm %t.o
+; RUN: obj2yaml %t.wasm | FileCheck %s  -check-prefix=CHECK-1024
+; CHECK-1024:       - Type:            GLOBAL
+; CHECK-1024-NEXT:    Globals:         
+; CHECK-1024-NEXT:      - Index:           0
+; CHECK-1024-NEXT:        Type:            I32
+; CHECK-1024-NEXT:        Mutable:         true
+; CHECK-1024-NEXT:        InitExpr:        
+; CHECK-1024-NEXT:          Opcode:          I32_CONST
+; CHECK-1024-NEXT:          Value:           66560
+; CHECK-1024-NEXT:      - Index:           1
+; CHECK-1024-NEXT:        Type:            I32
+; CHECK-1024-NEXT:        Mutable:         false
+; CHECK-1024-NEXT:        InitExpr:        
+; CHECK-1024-NEXT:          Opcode:          I32_CONST
+; CHECK-1024-NEXT:          Value:           1024
+; CHECK-1024-NEXT:      - Index:           2
+; CHECK-1024-NEXT:        Type:            I32
+; CHECK-1024-NEXT:        Mutable:         false
+; CHECK-1024-NEXT:        InitExpr:        
+; CHECK-1024-NEXT:          Opcode:          I32_CONST
+; CHECK-1024-NEXT:          Value:           1024
+
+; CHECK-1024:       - Type:            EXPORT
+; CHECK-1024-NEXT:    Exports:         
+; CHECK-1024-NEXT:      - Name:            memory
+; CHECK-1024-NEXT:        Kind:            MEMORY
+; CHECK-1024-NEXT:        Index:           0
+; CHECK-1024-NEXT:      - Name:            __data_end
+; CHECK-1024-NEXT:        Kind:            GLOBAL
+; CHECK-1024-NEXT:        Index:           1
+; CHECK-1024-NEXT:      - Name:            __global_base
+; CHECK-1024-NEXT:        Kind:            GLOBAL
+; CHECK-1024-NEXT:        Index:           2
+
+; RUN: wasm-ld -no-gc-sections --export=__global_base --export=__data_end --allow-undefined --global-base=16777216 --no-entry -o %t.wasm %t.o
+; RUN: obj2yaml %t.wasm | FileCheck %s  -check-prefix=CHECK-16777216
+; CHECK-16777216:       - Type:            GLOBAL
+; CHECK-16777216-NEXT:    Globals:         
+; CHECK-16777216-NEXT:      - Index:           0
+; CHECK-16777216-NEXT:        Type:            I32
+; CHECK-16777216-NEXT:        Mutable:         true
+; CHECK-16777216-NEXT:        InitExpr:        
+; CHECK-16777216-NEXT:          Opcode:          I32_CONST
+; CHECK-16777216-NEXT:          Value:           16842752
+; CHECK-16777216-NEXT:      - Index:           1
+; CHECK-16777216-NEXT:        Type:            I32
+; CHECK-16777216-NEXT:        Mutable:         false
+; CHECK-16777216-NEXT:        InitExpr:        
+; CHECK-16777216-NEXT:          Opcode:          I32_CONST
+; CHECK-16777216-NEXT:          Value:           16777216
+; CHECK-16777216-NEXT:      - Index:           2
+; CHECK-16777216-NEXT:        Type:            I32
+; CHECK-16777216-NEXT:        Mutable:         false
+; CHECK-16777216-NEXT:        InitExpr:        
+; CHECK-16777216-NEXT:          Opcode:          I32_CONST
+; CHECK-16777216-NEXT:          Value:           16777216
+
+; CHECK-16777216:       - Type:            EXPORT
+; CHECK-16777216-NEXT:    Exports:         
+; CHECK-16777216-NEXT:      - Name:            memory
+; CHECK-16777216-NEXT:        Kind:            MEMORY
+; CHECK-16777216-NEXT:        Index:           0
+; CHECK-16777216-NEXT:      - Name:            __data_end
+; CHECK-16777216-NEXT:        Kind:            GLOBAL
+; CHECK-16777216-NEXT:        Index:           1
+; CHECK-16777216-NEXT:      - Name:            __global_base
+; CHECK-16777216-NEXT:        Kind:            GLOBAL
+; CHECK-16777216-NEXT:        Index:           2
Index: clang/test/Driver/wasm-toolchain.c
===================================================================
--- clang/test/Driver/wasm-toolchain.c
+++ clang/test/Driver/wasm-toolchain.c
@@ -49,3 +49,7 @@
 // '-pthread' not allowed with '-mno-atomics'
 // RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s -pthread -mno-atomics 2>&1 | FileCheck -check-prefix=PTHREAD_NO_ATOMICS %s
 // PTHREAD_NO_ATOMICS: invalid argument '-pthread' not allowed with '-mno-atomics'
+
+// RUN: %clang %s -### -fsanitize=address -target wasm32-unknown-emscripten 2>&1 | FileCheck -check-prefix=CHECK-ASAN-EMSCRIPTEN %s
+// CHECK-ASAN-EMSCRIPTEN: "-fsanitize=address"
+// CHECK-ASAN-EMSCRIPTEN: "-fsanitize-address-globals-dead-stripping"
Index: clang/lib/Driver/ToolChains/WebAssembly.cpp
===================================================================
--- clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -211,7 +211,7 @@
 SanitizerMask WebAssembly::getSupportedSanitizers() const {
   SanitizerMask Res = ToolChain::getSupportedSanitizers();
   if (getTriple().isOSEmscripten()) {
-    Res |= SanitizerKind::Vptr | SanitizerKind::Leak;
+    Res |= SanitizerKind::Vptr | SanitizerKind::Leak | SanitizerKind::Address;
   }
   return Res;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to