brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.0 KiB · 622843c Raw
88 lines · c
1// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -o - %s | FileCheck %s --check-prefixes=CHECK,C2// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -x c++ -o - %s | FileCheck %s --check-prefixes=CHECK,MEMBER3// 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,OFFSET4#if !__has_feature(kcfi)5#error Missing kcfi?6#endif7 8/// Must emit __kcfi_typeid symbols for address-taken function declarations9// CHECK: module asm ".weak __kcfi_typeid_[[F4:[a-zA-Z0-9_]+]]"10// CHECK: module asm ".set __kcfi_typeid_[[F4]], [[#%d,HASH:]]"11/// Must not __kcfi_typeid symbols for non-address-taken declarations12// CHECK-NOT: module asm ".weak __kcfi_typeid_{{f6|_Z2f6v}}"13 14// C: @ifunc1 = ifunc i32 (i32), ptr @resolver115// C: @ifunc2 = ifunc i64 (i64), ptr @resolver216typedef int (*fn_t)(void);17 18// CHECK: define dso_local{{.*}} i32 @{{f1|_Z2f1v}}(){{.*}} !kcfi_type ![[#TYPE:]]19int f1(void) { return 0; }20 21// CHECK: define dso_local{{.*}} i32 @{{f2|_Z2f2v}}(){{.*}} !kcfi_type ![[#TYPE2:]]22unsigned int f2(void) { return 2; }23 24// CHECK-LABEL: define dso_local{{.*}} i32 @{{__call|_Z6__callPFivE}}(ptr{{.*}} %f)25int __call(fn_t f) __attribute__((__no_sanitize__("kcfi"))) {26  // CHECK-NOT: call{{.*}} i32 %{{.}}(){{.*}} [ "kcfi"27  return f();28}29 30// CHECK: define dso_local{{.*}} i32 @{{call|_Z4callPFivE}}(ptr{{.*}} %f){{.*}}31int call(fn_t f) {32  // CHECK: call{{.*}} i32 %{{.}}(){{.*}} [ "kcfi"(i32 [[#HASH]]) ]33  return f();34}35 36// CHECK-DAG: define internal{{.*}} i32 @{{f3|_ZL2f3v}}(){{.*}} !kcfi_type ![[#TYPE]]37static int f3(void) { return 1; }38 39// CHECK-DAG: declare !kcfi_type ![[#TYPE]]{{.*}} i32 @[[F4]]()40extern int f4(void);41 42/// Must not emit !kcfi_type for non-address-taken local functions43// CHECK: define internal{{.*}} i32 @{{f5|_ZL2f5v}}()44// CHECK-NOT: !kcfi_type45// CHECK-SAME: {46static int f5(void) { return 2; }47 48// CHECK-DAG: declare !kcfi_type ![[#TYPE]]{{.*}} i32 @{{f6|_Z2f6v}}()49extern int f6(void);50 51#ifndef __cplusplus52// C: define internal ptr @resolver1() #[[#]] !kcfi_type ![[#]] {53int ifunc1(int) __attribute__((ifunc("resolver1")));54static void *resolver1(void) { return 0; }55 56// C: define internal ptr @resolver2() #[[#]] !kcfi_type ![[#]] {57static void *resolver2(void) { return 0; }58long ifunc2(long) __attribute__((ifunc("resolver2")));59#endif60 61int test(void) {62  return call(f1) +63         __call((fn_t)f2) +64         call(f3) +65         call(f4) +66         f5() +67         f6();68}69 70#ifdef __cplusplus71struct A {72  // MEMBER-DAG: define{{.*}} void @_ZN1A1fEv(ptr{{.*}} %this){{.*}} !kcfi_type ![[#TYPE3:]]73  void f() {}74};75 76void test_member_call(void) {77  void (A::* p)() = &A::f;78  // MEMBER-DAG: call void %[[#]](ptr{{.*}} [ "kcfi"(i32 [[#%d,HASH3:]]) ]79  (A().*p)();80}81#endif82 83// CHECK-DAG: ![[#]] = !{i32 4, !"kcfi", i32 1}84// OFFSET-DAG: ![[#]] = !{i32 4, !"kcfi-offset", i32 3}85// CHECK-DAG: ![[#TYPE]] = !{i32 [[#HASH]]}86// CHECK-DAG: ![[#TYPE2]] = !{i32 [[#%d,HASH2:]]}87// MEMBER-DAG: ![[#TYPE3]] = !{i32 [[#HASH3]]}88