diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -46,6 +46,7 @@ __clang_cuda_math_forward_declares.h __clang_cuda_runtime_wrapper.h cetintrin.h + cet.h cldemoteintrin.h clzerointrin.h cpuid.h diff --git a/clang/lib/Headers/cet.h b/clang/lib/Headers/cet.h new file mode 100644 --- /dev/null +++ b/clang/lib/Headers/cet.h @@ -0,0 +1,66 @@ +/*===------ cet.h -Control-flow Enforcement Technology feature ------------=== + * Add x86 feature with IBT and/or SHSTK bits to ELF program property if they + * are enabled. Otherwise, contents in this header file are unused. This file + * is mainly design for assembly source code which want to enable CET. + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * + *===-----------------------------------------------------------------------=== + */ +#ifndef __CET_H +#define __CET_H + +#ifdef __ASSEMBLER__ + +#ifndef __CET__ +# define _CET_ENDBR +#endif + +#ifdef __CET__ + +# ifdef __LP64__ +# if __CET__ & 0x1 +# define _CET_ENDBR endbr64 +# else +# define _CET_ENDBR +# endif +# else +# if __CET__ & 0x1 +# define _CET_ENDBR endbr32 +# else +# define _CET_ENDBR +# endif +# endif + + +# ifdef __LP64__ +# define __PROPERTY_ALIGN 3 +# else +# define __PROPERTY_ALIGN 2 +# endif + + .pushsection ".note.gnu.property", "a" + .p2align __PROPERTY_ALIGN + .long 1f - 0f /* name length. */ + .long 4f - 1f /* data length. */ + /* NT_GNU_PROPERTY_TYPE_0. */ + .long 5 /* note type. */ +0: + .asciz "GNU" /* vendor name. */ +1: + .p2align __PROPERTY_ALIGN + /* GNU_PROPERTY_X86_FEATURE_1_AND. */ + .long 0xc0000002 /* pr_type. */ + .long 3f - 2f /* pr_datasz. */ +2: + /* GNU_PROPERTY_X86_FEATURE_1_XXX. */ + .long __CET__ +3: + .p2align __PROPERTY_ALIGN +4: + .popsection +#endif +#endif +#endif diff --git a/clang/test/CodeGen/asm-cet.S b/clang/test/CodeGen/asm-cet.S new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/asm-cet.S @@ -0,0 +1,26 @@ +// RUN: %clang --target=x86_64-pc-linux -fcf-protection -include cet.h -c %s -o - | llvm-readelf -n | FileCheck %s +// RUN: %clang --target=x86_64-pc-linux -include cet.h -c %s -o - | llvm-readelf -S | FileCheck %s --check-prefixes=NOCET +// RUN: %clang --target=x86_64-pc-linux -include cet.h -S %s -o - | FileCheck %s --check-prefixes=NOENDBR +// RUN: %clang --target=x86_64-pc-linux -fcf-protection -include cet.h -S %s -o - | FileCheck %s --check-prefixes=ENDBR64 + +// RUN: %clang --target=i386-pc-linux -fcf-protection -include cet.h -c %s -o - | llvm-readelf -n | FileCheck %s +// RUN: %clang --target=i386-pc-linux -include cet.h -c %s -o - | llvm-readelf -S | FileCheck %s --check-prefixes=NOCET +// RUN: %clang --target=i386-pc-linux -include cet.h -S %s -o - | FileCheck %s --check-prefixes=NOENDBR +// RUN: %clang --target=i386-pc-linux -fcf-protection -include cet.h -S %s -o - | FileCheck %s --check-prefixes=ENDBR32 + +// CHECK: IBT, SHSTK + +// NOCET: Section Headers +// NOCET-NOT: .note.gnu.property + +// NOENDBR: foo +// NOENDBR-NOT: endbr + +// ENDBR64: endbr64 +// ENDBR32: endbr32 + .text + .globl foo + .type foo, @function +foo: + _CET_ENDBR + ret