brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.5 KiB · 7ba1e2f Raw
189 lines · c
1// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -DORIG_ATTR_SYN -o - %s | FileCheck %s2// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -o - %s | FileCheck %s3// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fpatchable-function-entry-offset=3 -DORIG_ATTR_SYN -o - %s | FileCheck %s --check-prefixes=CHECK,OFFSET4// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fpatchable-function-entry-offset=3 -o - %s | FileCheck %s --check-prefixes=CHECK,OFFSET5 6// Note that the interleving of functions, which normally would be in sequence,7// is due to the fact that Clang outputs them in a non-sequential order.8 9#if !__has_feature(kcfi)10#error Missing kcfi?11#endif12 13#ifdef ORIG_ATTR_SYN14#define __cfi_salt       __attribute__((cfi_salt("pepper")))15#define __cfi_salt_empty __attribute__((cfi_salt("")))16#else17#define __cfi_salt       [[clang::cfi_salt("pepper")]]18#define __cfi_salt_empty [[clang::cfi_salt("")]]19#endif20 21typedef int (*fn_t)(void);22typedef int (* __cfi_salt fn_salt_t)(void);23typedef int (* __cfi_salt_empty fn_salt_empty_t)(void);24 25typedef unsigned int (*ufn_t)(void);26typedef unsigned int (* __cfi_salt ufn_salt_t)(void);27 28/// Must emit __kcfi_typeid symbols for address-taken function declarations29// CHECK: module asm ".weak __kcfi_typeid_[[F4:[a-zA-Z0-9_]+]]"30// CHECK: module asm ".set __kcfi_typeid_[[F4]], [[#%d,LOW_SODIUM_HASH:]]"31// CHECK: module asm ".weak __kcfi_typeid_[[F4_SALT:[a-zA-Z0-9_]+]]"32// CHECK: module asm ".set __kcfi_typeid_[[F4_SALT]], [[#%d,ASM_SALTY_HASH:]]"33 34/// Must not __kcfi_typeid symbols for non-address-taken declarations35// CHECK-NOT: module asm ".weak __kcfi_typeid_f6"36 37int f1(void);38int f1_salt(void) __cfi_salt;39 40unsigned int f2(void);41unsigned int f2_salt(void) __cfi_salt;42 43static int f3(void);44static int f3_salt(void) __cfi_salt;45 46extern int f4(void);47extern int f4_salt(void) __cfi_salt;48 49static int f5(void);50static int f5_salt(void) __cfi_salt;51 52extern int f6(void);53extern int f6_salt(void) __cfi_salt;54 55int f8(void);56int f8_salt_empty(void) __cfi_salt_empty;57 58struct cfi_struct {59  fn_t __cfi_salt fptr;60  fn_salt_t td_fptr;61  fn_salt_empty_t td_empty_fptr;62};63 64int f7_salt(struct cfi_struct *ptr);65int f7_typedef_salt(struct cfi_struct *ptr);66 67// CHECK-LABEL: @__call68// CHECK:         call{{.*}} i3269// CHECK-NOT:     "kcfi"70// CHECK-SAME:    ()71__attribute__((__no_sanitize__("kcfi")))72int __call(fn_t f) {73  return f();74}75 76// CHECK-LABEL: @call77// CHECK:         call{{.*}} i32 %{{.}}(){{.*}} [ "kcfi"(i32 [[#LOW_SODIUM_HASH]]) ]78// CHECK-LABEL: @call_salt79// CHECK:         call{{.*}} i32 %{{.}}(){{.*}} [ "kcfi"(i32 [[#%d,SALTY_HASH:]]) ]80// CHECK-LABEL: @call_salt_ty81// CHECK:         call{{.*}} i32 %{{.}}(){{.*}} [ "kcfi"(i32 [[#SALTY_HASH]]) ]82int call(fn_t f) { return f(); }83int call_salt(fn_t __cfi_salt f) { return f(); }84int call_salt_ty(fn_salt_t f) { return f(); }85int call_salt_empty_ty(fn_salt_empty_t f) { return f(); }86 87// CHECK-LABEL: @ucall88// CHECK:         call{{.*}} i32 %{{.}}(){{.*}} [ "kcfi"(i32 [[#%d,LOW_SODIUM_UHASH:]]) ]89// CHECK-LABEL: @ucall_salt90// CHECK:         call{{.*}} i32 %{{.}}(){{.*}} [ "kcfi"(i32 [[#%d,SALTY_UHASH:]]) ]91// CHECK-LABEL: @ucall_salt_ty92// CHECK:         call{{.*}} i32 %{{.}}(){{.*}} [ "kcfi"(i32 [[#SALTY_UHASH]]) ]93unsigned int ucall(ufn_t f) { return f(); }94unsigned int ucall_salt(ufn_t __cfi_salt f) { return f(); }95unsigned int ucall_salt_ty(ufn_salt_t f) { return f(); }96 97int test1(struct cfi_struct *ptr) {98  return call(f1) +99         call_salt(f1_salt) +100         call_salt_ty(f1_salt) +101 102         __call((fn_t)f2) +103         __call((fn_t)f2_salt) +104 105         ucall(f2) +106         ucall_salt(f2_salt) +107         ucall_salt_ty(f2_salt) +108 109         call(f3) +110         call_salt(f3_salt) +111         call_salt_ty(f3_salt) +112 113         call(f4) +114         call_salt(f4_salt) +115         call_salt_ty(f4_salt) +116 117         f5() +118         f5_salt() +119 120         f6() +121         f6_salt() +122 123         f7_salt(ptr) +124         f7_typedef_salt(ptr) +125 126         f8() +127         f8_salt_empty();128}129 130// CHECK-LABEL: define dso_local{{.*}} i32 @f1(){{.*}} !kcfi_type131// CHECK-SAME:  ![[#LOW_SODIUM_TYPE:]]132// CHECK-LABEL: define dso_local{{.*}} i32 @f1_salt(){{.*}} !kcfi_type133// CHECK-SAME:  ![[#SALTY_TYPE:]]134int f1(void) { return 0; }135int f1_salt(void) __cfi_salt { return 0; }136 137// CHECK-LABEL: define dso_local{{.*}} i32 @f2(){{.*}} !kcfi_type138// CHECK-SAME:  ![[#LOW_SODIUM_UTYPE:]]139// CHECK: define dso_local{{.*}} i32 @f2_salt(){{.*}} !kcfi_type140// CHECK-SAME:  ![[#SALTY_UTYPE:]]141unsigned int f2(void) { return 2; }142unsigned int f2_salt(void) __cfi_salt { return 2; }143 144// CHECK-LABEL: define internal{{.*}} i32 @f3(){{.*}} !kcfi_type145// CHECK-SAME:  ![[#LOW_SODIUM_TYPE]]146// CHECK-LABEL: define internal{{.*}} i32 @f3_salt(){{.*}} !kcfi_type147// CHECK-SAME:  ![[#SALTY_TYPE]]148static int f3(void) { return 1; }149static int f3_salt(void) __cfi_salt { return 1; }150 151// CHECK: declare !kcfi_type ![[#LOW_SODIUM_TYPE]]{{.*}} i32 @[[F4]]()152// CHECK: declare !kcfi_type ![[#SALTY_TYPE]]{{.*}} i32 @[[F4_SALT]]()153 154/// Must not emit !kcfi_type for non-address-taken local functions155// CHECK-LABEL: define internal{{.*}} i32 @f5()156// CHECK-NOT:   !kcfi_type157// CHECK-SAME:  {158// CHECK-LABEL: define internal{{.*}} i32 @f5_salt()159// CHECK-NOT:   !kcfi_type160// CHECK-SAME:  {161static int f5(void) { return 2; }162static int f5_salt(void) __cfi_salt { return 2; }163 164// CHECK: declare !kcfi_type ![[#LOW_SODIUM_TYPE]]{{.*}} i32 @f6()165// CHECK: declare !kcfi_type ![[#SALTY_TYPE]]{{.*}} i32 @f6_salt()166 167// CHECK-LABEL: @f7_salt168// CHECK:         call{{.*}} i32 %{{.*}}() [ "kcfi"(i32 [[#SALTY_HASH]]) ]169// CHECK-LABEL: @f7_typedef_salt170// CHECK:         call{{.*}} i32 %{{.*}}() [ "kcfi"(i32 [[#SALTY_HASH]]) ]171int f7_salt(struct cfi_struct *ptr) { return ptr->fptr(); }172int f7_typedef_salt(struct cfi_struct *ptr) { return ptr->td_fptr(); }173 174// CHECK-LABEL: define dso_local{{.*}} i32 @f8(){{.*}} !kcfi_type175// CHECK-SAME:  ![[#LOW_SODIUM_TYPE:]]176// CHECK-LABEL: define dso_local{{.*}} i32 @f8_salt_empty(){{.*}} !kcfi_type177// CHECK-SAME:  ![[#LOW_SODIUM_TYPE:]]178int f8(void) { return 0; }179int f8_salt_empty(void) __cfi_salt_empty { return 0; }180 181// CHECK:  ![[#]] = !{i32 4, !"kcfi", i32 1}182// OFFSET: ![[#]] = !{i32 4, !"kcfi-offset", i32 3}183//184// CHECK:  ![[#LOW_SODIUM_TYPE]] = !{i32 [[#LOW_SODIUM_HASH]]}185// CHECK:  ![[#SALTY_TYPE]] = !{i32 [[#SALTY_HASH]]}186//187// CHECK:  ![[#LOW_SODIUM_UTYPE]] = !{i32 [[#LOW_SODIUM_UHASH]]}188// CHECK:  ![[#SALTY_UTYPE]] = !{i32 [[#SALTY_UHASH]]}189