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