Skip to content

Commit f858b15

Browse files
committed
[Clang][kcfi] Sign extend KCFI typeid rather than zero extend
The KCFI typeid may be negative, but will result in this type of bitcode: module asm ".weak __kcfi_typeid_func" module asm ".set __kcfi_typeid_func, 2874394057" // ... define dso_local i32 @call_unsigned(ptr noundef %f) #0 !kcfi_type !6 { // ... %call = call i32 %0(i32 noundef 37) [ "kcfi"(i32 -1420573239) ] ret i32 %call } declare !kcfi_type !7 noundef i32 @foo(i32 noundef) // ... !7 = !{i32 -1420573239} The __kcfi_typeid_func value doesn't equal the metadata value. Therefore, we sign extend the typeid value rather than zero extend. This also reorganizes the testcase to remove the "-DAG" checks, which are a bit confusing at first. Signed-off-by: Bill Wendling <[email protected]>
1 parent 55678dc commit f858b15

File tree

2 files changed

+57
-27
lines changed

2 files changed

+57
-27
lines changed

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2931,7 +2931,7 @@ void CodeGenModule::finalizeKCFITypes() {
29312931
continue;
29322932

29332933
std::string Asm = (".weak __kcfi_typeid_" + Name + "\n.set __kcfi_typeid_" +
2934-
Name + ", " + Twine(Type->getZExtValue()) + "\n")
2934+
Name + ", " + Twine(Type->getSExtValue()) + "\n")
29352935
.str();
29362936
M.appendModuleInlineAsm(Asm);
29372937
}

clang/test/CodeGen/kcfi.c

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,45 +8,79 @@
88
/// Must emit __kcfi_typeid symbols for address-taken function declarations
99
// CHECK: module asm ".weak __kcfi_typeid_[[F4:[a-zA-Z0-9_]+]]"
1010
// CHECK: module asm ".set __kcfi_typeid_[[F4]], [[#%d,HASH:]]"
11+
// CHECK: module asm ".weak __kcfi_typeid_[[F4_ARG:[a-zA-Z0-9_]+]]"
12+
// CHECK: module asm ".set __kcfi_typeid_[[F4_ARG]], [[#%d,ARG_HASH:]]"
13+
1114
/// Must not __kcfi_typeid symbols for non-address-taken declarations
1215
// CHECK-NOT: module asm ".weak __kcfi_typeid_{{f6|_Z2f6v}}"
1316

1417
// C: @ifunc1 = ifunc i32 (i32), ptr @resolver1
1518
// C: @ifunc2 = ifunc i64 (i64), ptr @resolver2
1619
typedef int (*fn_t)(void);
20+
typedef int (*fn_u_t)(unsigned int);
1721

18-
// CHECK: define dso_local{{.*}} i32 @{{f1|_Z2f1v}}(){{.*}} !kcfi_type ![[#TYPE:]]
19-
int f1(void) { return 0; }
22+
int f1(void);
2023

21-
// CHECK: define dso_local{{.*}} i32 @{{f2|_Z2f2v}}(){{.*}} !kcfi_type ![[#TYPE2:]]
22-
unsigned int f2(void) { return 2; }
24+
unsigned int f2(void);
25+
26+
static int f3(void);
27+
28+
extern int f4(void);
29+
extern int f4_arg(unsigned int);
2330

2431
// CHECK-LABEL: define dso_local{{.*}} i32 @{{__call|_Z6__callPFivE}}(ptr{{.*}} %f)
2532
int __call(fn_t f) __attribute__((__no_sanitize__("kcfi"))) {
2633
// CHECK-NOT: call{{.*}} i32 %{{.}}(){{.*}} [ "kcfi"
2734
return f();
2835
}
2936

30-
// CHECK: define dso_local{{.*}} i32 @{{call|_Z4callPFivE}}(ptr{{.*}} %f){{.*}}
37+
// CHECK-LABEL: define dso_local{{.*}} i32 @{{call|_Z4callPFivE}}(ptr{{.*}} %f)
3138
int call(fn_t f) {
3239
// CHECK: call{{.*}} i32 %{{.}}(){{.*}} [ "kcfi"(i32 [[#HASH]]) ]
3340
return f();
3441
}
3542

36-
// CHECK-DAG: define internal{{.*}} i32 @{{f3|_ZL2f3v}}(){{.*}} !kcfi_type ![[#TYPE]]
43+
// CHECK-LABEL: define dso_local{{.*}} i32 @{{call_with_arg|_Z13call_with_argPFijE}}(ptr{{.*}} %f)
44+
int call_with_arg(fn_u_t f) {
45+
// CHECK: call{{.*}} i32 %0(i32 {{.*}}) [ "kcfi"(i32 [[#ARG_HASH]]) ]
46+
return f(42);
47+
}
48+
49+
static int f5(void);
50+
51+
extern int f6(void);
52+
53+
int test(void) {
54+
return call(f1) +
55+
__call((fn_t)f2) +
56+
call(f3) +
57+
call(f4) +
58+
call_with_arg(f4_arg) +
59+
f5() +
60+
f6();
61+
}
62+
63+
// CHECK-LABEL: define dso_local{{.*}} i32 @{{f1|_Z2f1v}}(){{.*}} !kcfi_type ![[#TYPE:]]
64+
int f1(void) { return 0; }
65+
66+
// CHECK-LABEL: define dso_local{{.*}} i32 @{{f2|_Z2f2v}}(){{.*}} !kcfi_type ![[#TYPE2:]]
67+
unsigned int f2(void) { return 2; }
68+
69+
// CHECK: define internal{{.*}} i32 @{{f3|_ZL2f3v}}(){{.*}} !kcfi_type ![[#TYPE]]
3770
static int f3(void) { return 1; }
3871

39-
// CHECK-DAG: declare !kcfi_type ![[#TYPE]]{{.*}} i32 @[[F4]]()
40-
extern int f4(void);
72+
// CHECK-LABEL: declare !kcfi_type
73+
// CHECK-SAME: ![[#TYPE]]{{.*}} i32 @[[F4]]
74+
// CHECK-LABEL: declare !kcfi_type
75+
// CHECK-SAME: ![[#ARG_TYPE:]]{{.*}} i32 @[[F4_ARG]]
4176

4277
/// Must not emit !kcfi_type for non-address-taken local functions
4378
// CHECK: define internal{{.*}} i32 @{{f5|_ZL2f5v}}()
4479
// CHECK-NOT: !kcfi_type
4580
// CHECK-SAME: {
4681
static int f5(void) { return 2; }
4782

48-
// CHECK-DAG: declare !kcfi_type ![[#TYPE]]{{.*}} i32 @{{f6|_Z2f6v}}()
49-
extern int f6(void);
83+
// CHECK: declare !kcfi_type ![[#TYPE]]{{.*}} i32 @{{f6|_Z2f6v}}()
5084

5185
#ifndef __cplusplus
5286
// C: define internal ptr @resolver1() #[[#]] !kcfi_type ![[#]] {
@@ -58,30 +92,26 @@ static void *resolver2(void) { return 0; }
5892
long ifunc2(long) __attribute__((ifunc("resolver2")));
5993
#endif
6094

61-
int test(void) {
62-
return call(f1) +
63-
__call((fn_t)f2) +
64-
call(f3) +
65-
call(f4) +
66-
f5() +
67-
f6();
68-
}
69-
7095
#ifdef __cplusplus
7196
struct A {
72-
// MEMBER-DAG: define{{.*}} void @_ZN1A1fEv(ptr{{.*}} %this){{.*}} !kcfi_type ![[#TYPE3:]]
7397
void f() {}
7498
};
7599

76100
void test_member_call(void) {
77101
void (A::* p)() = &A::f;
78-
// MEMBER-DAG: call void %[[#]](ptr{{.*}} [ "kcfi"(i32 [[#%d,HASH3:]]) ]
102+
// MEMBER: call void %[[#]](ptr{{.*}} [ "kcfi"(i32 [[#%d,HASH3:]]) ]
79103
(A().*p)();
80104
}
105+
106+
// MEMBER: define{{.*}} void @_ZN1A1fEv(ptr{{.*}} %this){{.*}} !kcfi_type ![[#TYPE3:]]
81107
#endif
82108

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]]}
109+
// CHECK: ![[#]] = !{i32 4, !"kcfi", i32 1}
110+
//
111+
// OFFSET: ![[#]] = !{i32 4, !"kcfi-offset", i32 3}
112+
//
113+
// CHECK: ![[#TYPE]] = !{i32 [[#HASH]]}
114+
// CHECK: ![[#TYPE2]] = !{i32 [[#%d,HASH2:]]}
115+
// CHECK: ![[#ARG_TYPE]] = !{i32 [[#ARG_HASH]]}
116+
//
117+
// MEMBER: ![[#TYPE3]] = !{i32 [[#HASH3]]}

0 commit comments

Comments
 (0)