From dd1c80ff4b1dc6d8bd3e12af197c84a95793307b Mon Sep 17 00:00:00 2001 From: Weining Lu Date: Mon, 2 Sep 2024 11:41:56 +0800 Subject: [PATCH 1/3] [Driver] Support -fsanitize=cfi-icall on loongarch64 Backport from https://github.com/llvm/llvm-project/pull/67310 Signed-off-by: Weining Lu Change-Id: I44c97417410bfd9dee343b181b3527b38c4882ff --- clang/lib/Driver/ToolChain.cpp | 1 + clang/test/Driver/fsanitize.c | 1 + 2 files changed, 2 insertions(+) diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 7a4319ea680f..041b8dc84f4b 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1081,6 +1081,7 @@ SanitizerMask ToolChain::getSupportedSanitizers() const { if (getTriple().getArch() == llvm::Triple::x86 || getTriple().getArch() == llvm::Triple::x86_64 || getTriple().getArch() == llvm::Triple::arm || getTriple().isWasm() || + getTriple().isLoongArch64() || getTriple().isAArch64() || getTriple().isRISCV()) Res |= SanitizerKind::CFIICall; if (getTriple().getArch() == llvm::Triple::x86_64 || diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c index 5e8f4883a2a9..e14d8158cf1b 100644 --- a/clang/test/Driver/fsanitize.c +++ b/clang/test/Driver/fsanitize.c @@ -592,6 +592,7 @@ // RUN: %clang -target aarch64_be -fvisibility=hidden -fsanitize=cfi -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI // RUN: %clang -target riscv32 -fvisibility=hidden -fsanitize=cfi -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI // RUN: %clang -target riscv64 -fvisibility=hidden -fsanitize=cfi -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI +// RUN: %clang -target loongarch64 -fvisibility=hidden -fsanitize=cfi -flto -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI // CHECK-CFI: -emit-llvm-bc{{.*}}-fsanitize=cfi-derived-cast,cfi-icall,cfi-mfcall,cfi-unrelated-cast,cfi-nvcall,cfi-vcall // CHECK-CFI-NOMFCALL: -emit-llvm-bc{{.*}}-fsanitize=cfi-derived-cast,cfi-icall,cfi-unrelated-cast,cfi-nvcall,cfi-vcall // CHECK-CFI-DCAST: -emit-llvm-bc{{.*}}-fsanitize=cfi-derived-cast -- Gitee From 8d2c6363b78e4bb77f3fe7ab65a3218f2294afa0 Mon Sep 17 00:00:00 2001 From: Weining Lu Date: Mon, 2 Sep 2024 13:21:19 +0800 Subject: [PATCH 2/3] [LowerTypeTests] Add loongarch64 to CFI jumptables Backport from https://github.com/llvm/llvm-project/pull/67312 Change-Id: I85c603c96af58c56b16034cc2baa0fdaa79cedcc Signed-off-by: Weining Lu --- llvm/lib/Transforms/IPO/LowerTypeTests.cpp | 9 ++++++++- llvm/test/Transforms/LowerTypeTests/function-weak.ll | 2 ++ llvm/test/Transforms/LowerTypeTests/function.ll | 9 +++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp index e3e4908f085b..ca4d00c05cd3 100644 --- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp +++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp @@ -1182,6 +1182,7 @@ static const unsigned kX86JumpTableEntrySize = 8; static const unsigned kARMJumpTableEntrySize = 4; static const unsigned kARMBTIJumpTableEntrySize = 8; static const unsigned kRISCVJumpTableEntrySize = 8; +static const unsigned kLOONGARCH64JumpTableEntrySize = 8; unsigned LowerTypeTestsModule::getJumpTableEntrySize() { switch (Arch) { @@ -1200,6 +1201,8 @@ unsigned LowerTypeTestsModule::getJumpTableEntrySize() { case Triple::riscv32: case Triple::riscv64: return kRISCVJumpTableEntrySize; + case Triple::loongarch64: + return kLOONGARCH64JumpTableEntrySize; default: report_fatal_error("Unsupported architecture for jump tables"); } @@ -1230,6 +1233,9 @@ void LowerTypeTestsModule::createJumpTableEntry( } else if (JumpTableArch == Triple::riscv32 || JumpTableArch == Triple::riscv64) { AsmOS << "tail $" << ArgIndex << "@plt\n"; + } else if (JumpTableArch == Triple::loongarch64) { + AsmOS << "pcalau12i $$t0, %pc_hi20($" << ArgIndex << ")\n" + << "jirl $$r0, $$t0, %pc_lo12($" << ArgIndex << ")\n"; } else { report_fatal_error("Unsupported architecture for jump tables"); } @@ -1248,7 +1254,8 @@ void LowerTypeTestsModule::buildBitSetsFromFunctions( ArrayRef TypeIds, ArrayRef Functions) { if (Arch == Triple::x86 || Arch == Triple::x86_64 || Arch == Triple::arm || Arch == Triple::thumb || Arch == Triple::aarch64 || - Arch == Triple::riscv32 || Arch == Triple::riscv64) + Arch == Triple::riscv32 || Arch == Triple::riscv64 || + Arch == Triple::loongarch64) buildBitSetsFromFunctionsNative(TypeIds, Functions); else if (Arch == Triple::wasm32 || Arch == Triple::wasm64) buildBitSetsFromFunctionsWASM(TypeIds, Functions); diff --git a/llvm/test/Transforms/LowerTypeTests/function-weak.ll b/llvm/test/Transforms/LowerTypeTests/function-weak.ll index 56d5af5f6152..5148a412fd29 100644 --- a/llvm/test/Transforms/LowerTypeTests/function-weak.ll +++ b/llvm/test/Transforms/LowerTypeTests/function-weak.ll @@ -4,6 +4,7 @@ ; RUN: opt -S -passes=lowertypetests -mtriple=aarch64-unknown-linux-gnu %s | FileCheck --check-prefixes=CHECK,ARM %s ; RUN: opt -S -passes=lowertypetests -mtriple=riscv32-unknown-linux-gnu %s | FileCheck --check-prefixes=CHECK,RISCV %s ; RUN: opt -S -passes=lowertypetests -mtriple=riscv64-unknown-linux-gnu %s | FileCheck --check-prefixes=CHECK,RISCV %s +; RUN: opt -S -passes=lowertypetests -mtriple=loongarch64-unknown-linux-gnu %s | FileCheck --check-prefixes=CHECK,LOONGARCH64 %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @@ -55,6 +56,7 @@ define i1 @foo(i8* %p) { ; X86: define private void @[[JT]]() #{{.*}} align 8 { ; ARM: define private void @[[JT]]() #{{.*}} align 4 { ; RISCV: define private void @[[JT]]() #{{.*}} align 8 { +; LOONGARCH64: define private void @[[JT]]() #{{.*}} align 8 { ; CHECK: define internal void @__cfi_global_var_init() section ".text.startup" { ; CHECK-NEXT: entry: diff --git a/llvm/test/Transforms/LowerTypeTests/function.ll b/llvm/test/Transforms/LowerTypeTests/function.ll index 944c4ee2b5d5..c848ba431584 100644 --- a/llvm/test/Transforms/LowerTypeTests/function.ll +++ b/llvm/test/Transforms/LowerTypeTests/function.ll @@ -8,6 +8,7 @@ ; RUN: opt -S -passes=lowertypetests -mtriple=riscv32-unknown-linux-gnu %s | FileCheck --check-prefixes=RISCV,NATIVE %s ; RUN: opt -S -passes=lowertypetests -mtriple=riscv64-unknown-linux-gnu %s | FileCheck --check-prefixes=RISCV,NATIVE %s ; RUN: opt -S -passes=lowertypetests -mtriple=wasm32-unknown-unknown %s | FileCheck --check-prefix=WASM32 %s +; RUN: opt -S -passes=lowertypetests -mtriple=loongarch64-unknown-unknown %s | FileCheck --check-prefixes=LOONGARCH64,NATIVE %s ; Tests that we correctly handle bitsets containing 2 or more functions. @@ -26,6 +27,7 @@ target datalayout = "e-p:64:64" ; ARM: @g = internal alias void (), bitcast ([4 x i8]* getelementptr inbounds ([2 x [4 x i8]], [2 x [4 x i8]]* bitcast (void ()* @[[JT]] to [2 x [4 x i8]]*), i64 0, i64 1) to void ()*) ; THUMB: @g = internal alias void (), bitcast ([4 x i8]* getelementptr inbounds ([2 x [4 x i8]], [2 x [4 x i8]]* bitcast (void ()* @[[JT]] to [2 x [4 x i8]]*), i64 0, i64 1) to void ()*) ; RISCV: @g = internal alias void (), bitcast ([8 x i8]* getelementptr inbounds ([2 x [8 x i8]], [2 x [8 x i8]]* bitcast (void ()* @[[JT]] to [2 x [8 x i8]]*), i64 0, i64 1) to void ()*) +; LOONGARCH64: @g = internal alias void (), bitcast ([8 x i8]* getelementptr inbounds ([2 x [8 x i8]], [2 x [8 x i8]]* bitcast (void ()* @[[JT]] to [2 x [8 x i8]]*), i64 0, i64 1) to void ()*) ; NATIVE: define hidden void @f.cfi() ; WASM32: define void @f() !type !{{[0-9]+}} !wasm.index ![[I0:[0-9]+]] @@ -56,6 +58,7 @@ define i1 @foo(i8* %p) { ; ARM: define private void @[[JT]]() #[[ATTR:.*]] align 4 { ; THUMB: define private void @[[JT]]() #[[ATTR:.*]] align 4 { ; RISCV: define private void @[[JT]]() #[[ATTR:.*]] align 8 { +; LOONGARCH64: define private void @[[JT]]() #[[ATTR:.*]] align 8 { ; X86: jmp ${0:c}@plt ; X86-SAME: int3 @@ -75,6 +78,11 @@ define i1 @foo(i8* %p) { ; RISCV: tail $0@plt ; RISCV-SAME: tail $1@plt +; LOONGARCH64: pcalau12i $$t0, %pc_hi20($0) +; LOONGARCH64-SAME: jirl $$r0, $$t0, %pc_lo12($0) +; LOONGARCH64-SAME: pcalau12i $$t0, %pc_hi20($1) +; LOONGARCH64-SAME: jirl $$r0, $$t0, %pc_lo12($1) + ; NATIVE-SAME: "s,s"(void ()* @f.cfi, void ()* @g.cfi) ; X86-LINUX: attributes #[[ATTR]] = { naked nounwind } @@ -82,6 +90,7 @@ define i1 @foo(i8* %p) { ; ARM: attributes #[[ATTR]] = { naked nounwind ; THUMB: attributes #[[ATTR]] = { naked nounwind "target-cpu"="cortex-a8" "target-features"="+thumb-mode" } ; RISCV: attributes #[[ATTR]] = { naked nounwind "target-features"="-c,-relax" } +; LOONGARCH64: attributes #[[ATTR]] = { naked nounwind } ; WASM32: ![[I0]] = !{i64 1} ; WASM32: ![[I1]] = !{i64 2} -- Gitee From e5d4033fe6f7a7c578df10e94da068c6dd296eb8 Mon Sep 17 00:00:00 2001 From: Weining Lu Date: Mon, 2 Sep 2024 12:13:22 +0800 Subject: [PATCH 3/3] [CFI] Allow LoongArch Backport from https://github.com/llvm/llvm-project/pull/67314 Signed-off-by: Weining Lu Change-Id: I47da5e1dd68ae1642b53b8fe00a22eddd1c37834 --- compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake | 2 +- compiler-rt/lib/cfi/cfi.cpp | 4 ++++ compiler-rt/test/cfi/cross-dso/icall/dlopen.cpp | 11 +++++++++-- compiler-rt/test/cfi/cross-dso/icall/lit.local.cfg.py | 2 +- compiler-rt/test/cfi/icall/lit.local.cfg.py | 2 +- 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake index 4ac8905cdba8..f085b0f10b58 100644 --- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake +++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake @@ -68,7 +68,7 @@ set(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64} ${MIPS32} ${MIPS64} ${HEXAGON} ${LOONGARCH64}) set(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS64} - ${HEXAGON}) + ${HEXAGON} ${LOONGARCH64}) set(ALL_SCUDO_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${PPC64} ${HEXAGON} ${LOONGARCH64}) set(ALL_SCUDO_STANDALONE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} diff --git a/compiler-rt/lib/cfi/cfi.cpp b/compiler-rt/lib/cfi/cfi.cpp index 22f0b175dd87..ad1c91623514 100644 --- a/compiler-rt/lib/cfi/cfi.cpp +++ b/compiler-rt/lib/cfi/cfi.cpp @@ -51,7 +51,11 @@ using namespace __sanitizer; namespace __cfi { +#if SANITIZER_LOONGARCH64 +#define kCfiShadowLimitsStorageSize 16384 // 16KiB on loongarch64 per page +#else #define kCfiShadowLimitsStorageSize 4096 // 1 page +#endif // Lets hope that the data segment is mapped with 4K pages. // The pointer to the cfi shadow region is stored at the start of this page. // The rest of the page is unused and re-mapped read-only. diff --git a/compiler-rt/test/cfi/cross-dso/icall/dlopen.cpp b/compiler-rt/test/cfi/cross-dso/icall/dlopen.cpp index c9674c3fb412..671d14061985 100644 --- a/compiler-rt/test/cfi/cross-dso/icall/dlopen.cpp +++ b/compiler-rt/test/cfi/cross-dso/icall/dlopen.cpp @@ -53,6 +53,13 @@ struct A { virtual void f(); }; +// The page size of LoongArch is 16KB, aligned to the memory page size. +#ifdef __loongarch__ +# define PAGESIZE 16384 +#else +# define PAGESIZE 4096 +#endif + #ifdef SHARED_LIB #include "../../utils.h" @@ -66,13 +73,13 @@ extern "C" void *create_B() { return (void *)(new B()); } -extern "C" __attribute__((aligned(4096))) void do_nothing() {} +extern "C" __attribute__((aligned(PAGESIZE))) void do_nothing() {} #else void A::f() {} -static const int kCodeAlign = 4096; +static const int kCodeAlign = PAGESIZE; static const int kCodeSize = 4096; static char saved_code[kCodeSize]; static char *real_start; diff --git a/compiler-rt/test/cfi/cross-dso/icall/lit.local.cfg.py b/compiler-rt/test/cfi/cross-dso/icall/lit.local.cfg.py index db08765a2bb2..b807037c83ac 100644 --- a/compiler-rt/test/cfi/cross-dso/icall/lit.local.cfg.py +++ b/compiler-rt/test/cfi/cross-dso/icall/lit.local.cfg.py @@ -1,3 +1,3 @@ # The cfi-icall checker is only supported on x86 and x86_64 for now. -if config.root.host_arch not in ['x86', 'x86_64']: +if config.root.host_arch not in ['x86', 'x86_64', 'loongarch64']: config.unsupported = True diff --git a/compiler-rt/test/cfi/icall/lit.local.cfg.py b/compiler-rt/test/cfi/icall/lit.local.cfg.py index db08765a2bb2..b807037c83ac 100644 --- a/compiler-rt/test/cfi/icall/lit.local.cfg.py +++ b/compiler-rt/test/cfi/icall/lit.local.cfg.py @@ -1,3 +1,3 @@ # The cfi-icall checker is only supported on x86 and x86_64 for now. -if config.root.host_arch not in ['x86', 'x86_64']: +if config.root.host_arch not in ['x86', 'x86_64', 'loongarch64']: config.unsupported = True -- Gitee