diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -1071,6 +1071,20 @@ if (Sanitizers.has(SanitizerKind::HWAddress)) { CmdArgs.push_back("-target-feature"); CmdArgs.push_back("+tagged-globals"); + + // Workaround for HWASan not implementing the +tagged-globals feature + // properly in GlobalISel, which is enabled by default at -O0 for aarch64. + // Once GlobalISel is disabled, -O0 uses FastISel, so we disable that as + // well to ensure we get SelectionDagISel where the feature is properly + // implemented. + // TODO(hctim): Implement proper ISel lowering for taking the address of + // tagged globals in at *least* GlobalISel. Probably okay to ignore FastISel + // as it's not part of any defaults set. + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("--aarch64-enable-global-isel-at-O=-1"); // No GlobalISel. + + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-fast-isel=false"); } // MSan: Workaround for PR16386. diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c --- a/clang/test/Driver/fsanitize.c +++ b/clang/test/Driver/fsanitize.c @@ -869,8 +869,12 @@ // RUN: %clang -target x86_64-linux-gnu -fsanitize=hwaddress -fsanitize-hwaddress-abi=foo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-HWASAN-FOO-ABI // CHECK-HWASAN-INTERCEPTOR-ABI: "-default-function-attr" "hwasan-abi=interceptor" // CHECK-HWASAN-INTERCEPTOR-ABI: "-target-feature" "+tagged-globals" +// CHECK-HWASAN-INTERCEPTOR-ABI: "-mllvm" "--aarch64-enable-global-isel-at-O=-1" +// CHECK-HWASAN-INTERCEPTOR-ABI: "-mllvm" "-fast-isel=false" // CHECK-HWASAN-PLATFORM-ABI: "-default-function-attr" "hwasan-abi=platform" // CHECK-HWASAN-PLATFORM-ABI: "-target-feature" "+tagged-globals" +// CHECK-HWASAN-PLATFORM-ABI: "-mllvm" "--aarch64-enable-global-isel-at-O=-1" +// CHECK-HWASAN-PLATFORM-ABI: "-mllvm" "-fast-isel=false" // CHECK-HWASAN-FOO-ABI: error: invalid value 'foo' in '-fsanitize-hwaddress-abi=foo' // RUN: %clang -target x86_64-linux-gnu -fsanitize=address,pointer-compare,pointer-subtract %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-POINTER-ALL diff --git a/compiler-rt/test/hwasan/TestCases/exported-tagged-global.c b/compiler-rt/test/hwasan/TestCases/exported-tagged-global.c new file mode 100644 --- /dev/null +++ b/compiler-rt/test/hwasan/TestCases/exported-tagged-global.c @@ -0,0 +1,16 @@ +// RUN: %clang_hwasan %s -o %t +// RUN: %run %t +// RUN: %clang_hwasan -O1 %s -o %t +// RUN: %run %t + +static int global; + +__attribute__((optnone)) int* address_of_global() { + return &global; +} + +int main(int argc, char **argv) { + int* global_address = address_of_global(); + *global_address = 13; + return 0; +} diff --git a/llvm/test/CodeGen/AArch64/tagged-globals.ll b/llvm/test/CodeGen/AArch64/tagged-globals.ll --- a/llvm/test/CodeGen/AArch64/tagged-globals.ll +++ b/llvm/test/CodeGen/AArch64/tagged-globals.ll @@ -1,31 +1,70 @@ -; RUN: llc < %s | FileCheck %s +; RUN: llc --relocation-model=static < %s | FileCheck %s +; RUN: llc --relocation-model=pic < %s | FileCheck %s -check-prefix=CHECK-PIC target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" target triple = "aarch64-unknown-linux-android" -@global = external hidden global i32 +@global = external global i32 declare void @func() define i32* @global_addr() #0 { ; CHECK: global_addr: - ; CHECK: adrp x0, :pg_hi21_nc:global - ; CHECK: movk x0, #:prel_g3:global+4294967296 - ; CHECK: add x0, x0, :lo12:global + ; CHECK: adrp [[REG:x[0-9]+]], :pg_hi21_nc:global + ; CHECK: movk [[REG]], #:prel_g3:global+4294967296 + ; CHECK: add x0, [[REG]], :lo12:global + ; CHECK: ret + + ; CHECK-PIC: global_addr: + ; CHECK-PIC: adrp [[REG:x[0-9]+]], :got:global + ; CHECK-PIC: ldr x0, {{\[}}[[REG]], :got_lo12:global] + ; CHECK-PIC: ret + ret i32* @global } define i32 @global_load() #0 { ; CHECK: global_load: - ; CHECK: adrp x8, :pg_hi21_nc:global - ; CHECK: ldr w0, [x8, :lo12:global] + ; CHECK: adrp [[REG:x[0-9]+]], :pg_hi21_nc:global + ; CHECK: ldr w0, {{\[}}[[REG]], :lo12:global{{\]}} + ; CHECK: ret + + ; CHECK-PIC: global_load: + ; CHECK-PIC: adrp [[REG:x[0-9]+]], :got:global + ; CHECK-PIC: ldr [[REG]], {{\[}}[[REG]], :got_lo12:global] + ; CHECK-PIC: ldr w0, {{\[}}[[REG]]{{\]}} + ; CHECK-PIC: ret + %load = load i32, i32* @global ret i32 %load } +define void @global_store() #0 { + ; CHECK: global_store: + ; CHECK: adrp [[REG:x[0-9]+]], :pg_hi21_nc:global + ; CHECK: str wzr, {{\[}}[[REG]], :lo12:global{{\]}} + ; CHECK: ret + + ; CHECK-PIC: global_store: + ; CHECK-PIC: adrp [[REG:x[0-9]+]], :got:global + ; CHECK-PIC: ldr [[REG]], {{\[}}[[REG]], :got_lo12:global] + ; CHECK-PIC: str wzr, {{\[}}[[REG]]{{\]}} + ; CHECK-PIC: ret + + store i32 0, i32* @global + ret void +} + define void ()* @func_addr() #0 { ; CHECK: func_addr: - ; CHECK: adrp x0, func - ; CHECK: add x0, x0, :lo12:func + ; CHECK: adrp [[REG:x[0-9]+]], func + ; CHECK: add x0, [[REG]], :lo12:func + ; CHECK: ret + + ; CHECK-PIC: func_addr: + ; CHECK-PIC: adrp [[REG:x[0-9]+]], :got:func + ; CHECK-PIC: ldr x0, {{\[}}[[REG]], :got_lo12:func] + ; CHECK-PIC: ret + ret void ()* @func }