[PATCH] D139395: Add CFI integer types normalization
rcvalle updated this revision to Diff 493732. rcvalle marked an inline comment as done. rcvalle added a comment. Changed as per review Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139395/new/ https://reviews.llvm.org/D139395 Files: clang/docs/ControlFlowIntegrity.rst clang/docs/UsersManual.rst clang/include/clang/AST/Mangle.h clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/include/clang/Driver/SanitizerArgs.h clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/MicrosoftMangle.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/Driver/SanitizerArgs.cpp clang/test/CodeGen/cfi-icall-normalize.c clang/test/CodeGen/cfi-icall-normalize2.c clang/test/CodeGen/kcfi-normalize.c Index: clang/test/CodeGen/kcfi-normalize.c === --- /dev/null +++ clang/test/CodeGen/kcfi-normalize.c @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers -x c++ -o - %s | FileCheck %s +#if !__has_feature(kcfi) +#error Missing kcfi? +#endif + +// Test that normalized type metadata for functions are emitted for cross-language KCFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo(void (*fn)(int), int arg) { +// CHECK-LABEL: define{{.*}}foo +// CHECK-SAME: {{.*}}!kcfi_type ![[TYPE1:[0-9]+]] +// CHECK: call void %0(i32 noundef %1){{.*}}[ "kcfi"(i32 1162514891) ] +fn(arg); +} + +void bar(void (*fn)(int, int), int arg1, int arg2) { +// CHECK-LABEL: define{{.*}}bar +// CHECK-SAME: {{.*}}!kcfi_type ![[TYPE2:[0-9]+]] +// CHECK: call void %0(i32 noundef %1, i32 noundef %2){{.*}}[ "kcfi"(i32 448046469) ] +fn(arg1, arg2); +} + +void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) { +// CHECK-LABEL: define{{.*}}baz +// CHECK-SAME: {{.*}}!kcfi_type ![[TYPE3:[0-9]+]] +// CHECK: call void %0(i32 noundef %1, i32 noundef %2, i32 noundef %3){{.*}}[ "kcfi"(i32 -2049681433) ] +fn(arg1, arg2, arg3); +} + +// CHECK: ![[TYPE1]] = !{i32 -1143117868} +// CHECK: ![[TYPE2]] = !{i32 -460921415} +// CHECK: ![[TYPE3]] = !{i32 -333839615} Index: clang/test/CodeGen/cfi-icall-normalize2.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize2.c @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-experimental-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that normalized type metadata for functions are emitted for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo(void (*fn)(int), int arg) { +// CHECK-LABEL: define{{.*}}foo +// CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFvu3i32E.normalized") +fn(arg); +} + +void bar(void (*fn)(int, int), int arg1, int arg2) { +// CHECK-LABEL: define{{.*}}bar +// CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFvu3i32S_E.normalized") +fn(arg1, arg2); +} + +void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) { +// CHECK-LABEL: define{{.*}}baz +// CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFvu3i32S_S_E.normalized") +fn(arg1, arg2, arg3); +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvPFvu3i32ES_E.normalized"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvPFvu3i32S_ES_S_E.normalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvPFvu3i32S_S_ES_S_S_E.normalized"} Index: clang/test/CodeGen/cfi-icall-normalize.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize.c @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-experimental-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that integer types are normalized for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo0(char arg) { } +// CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] !type !{{[0-9]+}} +void foo1(char arg1, signed char arg2) { } +// CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} +void foo2(char arg1, signed char arg2, signed char arg3) { } +// CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} +void foo3(int arg) { } +// CHECK: define{
[PATCH] D139395: Add CFI integer types normalization
rcvalle marked 4 inline comments as done. rcvalle added inline comments. Comment at: clang/lib/CodeGen/CodeGenModule.cpp:1694 + getCXXABI().getMangleContext().mangleTypeName( + T, Out, !!getCodeGenOpts().SanitizeCfiICallNormalizeIntegers); + pcc wrote: > Is the !! necessary here? Fixed. Thank you! Comment at: clang/lib/CodeGen/CodeGenModule.cpp:6881 +getCXXABI().getMangleContext().mangleTypeName( +T, Out, !!getCodeGenOpts().SanitizeCfiICallNormalizeIntegers); + pcc wrote: > Likewise Fixed. Thank you! Comment at: clang/test/CodeGen/cfi-icall-normalize.c:55-75 +// CHECK: ![[TYPE0]] = !{i64 0, !"_ZTSFv{{u2i8|u2u8}}E.normalized"} +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFv{{u2i8S_|u2u8u2i8}}E.normalized"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFv{{u2i8S_S_|u2u8u2i8S0_}}E.normalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFv{{u3i16|u3i32|u3i64}}E.normalized"} +// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFv{{u3i16|u3i32|u3i64}}S_E.normalized"} +// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFv{{u3i16|u3i32|u3i64}}S_S_E.normalized"} +// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFv{{u3i32|u3i64}}E.normalized"} pcc wrote: > Shouldn't these all be checking for specific types? Since you're specifying a > triple, the width and signedness of the integer types are fixed. Fixed. Thank you! Comment at: clang/test/CodeGen/cfi-icall-normalize2.c:9 +// CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFv{{u3i16|u3i32|u3i64}}E.normalized") +fn(arg); pcc wrote: > Likewise; also below Fixed. Thank you! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139395/new/ https://reviews.llvm.org/D139395 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D139395: Add CFI integer types normalization
rcvalle updated this revision to Diff 490976. rcvalle added a comment. Mark as experimental Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139395/new/ https://reviews.llvm.org/D139395 Files: clang/docs/ControlFlowIntegrity.rst clang/docs/UsersManual.rst clang/include/clang/AST/Mangle.h clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/include/clang/Driver/SanitizerArgs.h clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/MicrosoftMangle.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/Driver/SanitizerArgs.cpp clang/test/CodeGen/cfi-icall-normalize.c clang/test/CodeGen/cfi-icall-normalize2.c clang/test/CodeGen/kcfi-normalize.c Index: clang/test/CodeGen/kcfi-normalize.c === --- /dev/null +++ clang/test/CodeGen/kcfi-normalize.c @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers -x c++ -o - %s | FileCheck %s +#if !__has_feature(kcfi) +#error Missing kcfi? +#endif + +// Test that normalized type metadata for functions are emitted for cross-language KCFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo(void (*fn)(int), int arg) { +// CHECK-LABEL: define{{.*}}foo +// CHECK-SAME: {{.*}}!kcfi_type ![[TYPE1:[0-9]+]] +// CHECK: call void %0(i32 noundef %1){{.*}}[ "kcfi"(i32 1162514891) ] +fn(arg); +} + +void bar(void (*fn)(int, int), int arg1, int arg2) { +// CHECK-LABEL: define{{.*}}bar +// CHECK-SAME: {{.*}}!kcfi_type ![[TYPE2:[0-9]+]] +// CHECK: call void %0(i32 noundef %1, i32 noundef %2){{.*}}[ "kcfi"(i32 448046469) ] +fn(arg1, arg2); +} + +void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) { +// CHECK-LABEL: define{{.*}}baz +// CHECK-SAME: {{.*}}!kcfi_type ![[TYPE3:[0-9]+]] +// CHECK: call void %0(i32 noundef %1, i32 noundef %2, i32 noundef %3){{.*}}[ "kcfi"(i32 -2049681433) ] +fn(arg1, arg2, arg3); +} + +// CHECK: ![[TYPE1]] = !{i32 -1143117868} +// CHECK: ![[TYPE2]] = !{i32 -460921415} +// CHECK: ![[TYPE3]] = !{i32 -333839615} Index: clang/test/CodeGen/cfi-icall-normalize2.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize2.c @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-experimental-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that normalized type metadata for functions are emitted for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo(void (*fn)(int), int arg) { +// CHECK-LABEL: define{{.*}}foo +// CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFv{{u3i16|u3i32|u3i64}}E.normalized") +fn(arg); +} + +void bar(void (*fn)(int, int), int arg1, int arg2) { +// CHECK-LABEL: define{{.*}}bar +// CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFv{{u3i16|u3i32|u3i64}}S_E.normalized") +fn(arg1, arg2); +} + +void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) { +// CHECK-LABEL: define{{.*}}baz +// CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFv{{u3i16|u3i32|u3i64}}S_S_E.normalized") +fn(arg1, arg2, arg3); +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvPFv{{u3i16|u3i32|u3i64}}ES_E.normalized"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvPFv{{u3i16|u3i32|u3i64}}S_ES_S_E.normalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvPFv{{u3i16|u3i32|u3i64}}S_S_ES_S_S_E.normalized"} Index: clang/test/CodeGen/cfi-icall-normalize.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize.c @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-experimental-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that integer types are normalized for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo0(char arg) { } +// CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] !type !{{[0-9]+}} +void foo1(char arg1, signed char arg2) { } +// CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} +void foo2(char arg1, signed char arg2, signed char arg3) { } +// CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !
[PATCH] D139395: Add CFI integer types normalization
rcvalle updated this revision to Diff 491013. rcvalle added a comment. Fixed typo Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139395/new/ https://reviews.llvm.org/D139395 Files: clang/docs/ControlFlowIntegrity.rst clang/docs/UsersManual.rst clang/include/clang/AST/Mangle.h clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/include/clang/Driver/SanitizerArgs.h clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/MicrosoftMangle.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/Driver/SanitizerArgs.cpp clang/test/CodeGen/cfi-icall-normalize.c clang/test/CodeGen/cfi-icall-normalize2.c clang/test/CodeGen/kcfi-normalize.c Index: clang/test/CodeGen/kcfi-normalize.c === --- /dev/null +++ clang/test/CodeGen/kcfi-normalize.c @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers -x c++ -o - %s | FileCheck %s +#if !__has_feature(kcfi) +#error Missing kcfi? +#endif + +// Test that normalized type metadata for functions are emitted for cross-language KCFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo(void (*fn)(int), int arg) { +// CHECK-LABEL: define{{.*}}foo +// CHECK-SAME: {{.*}}!kcfi_type ![[TYPE1:[0-9]+]] +// CHECK: call void %0(i32 noundef %1){{.*}}[ "kcfi"(i32 1162514891) ] +fn(arg); +} + +void bar(void (*fn)(int, int), int arg1, int arg2) { +// CHECK-LABEL: define{{.*}}bar +// CHECK-SAME: {{.*}}!kcfi_type ![[TYPE2:[0-9]+]] +// CHECK: call void %0(i32 noundef %1, i32 noundef %2){{.*}}[ "kcfi"(i32 448046469) ] +fn(arg1, arg2); +} + +void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) { +// CHECK-LABEL: define{{.*}}baz +// CHECK-SAME: {{.*}}!kcfi_type ![[TYPE3:[0-9]+]] +// CHECK: call void %0(i32 noundef %1, i32 noundef %2, i32 noundef %3){{.*}}[ "kcfi"(i32 -2049681433) ] +fn(arg1, arg2, arg3); +} + +// CHECK: ![[TYPE1]] = !{i32 -1143117868} +// CHECK: ![[TYPE2]] = !{i32 -460921415} +// CHECK: ![[TYPE3]] = !{i32 -333839615} Index: clang/test/CodeGen/cfi-icall-normalize2.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize2.c @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-experimental-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that normalized type metadata for functions are emitted for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo(void (*fn)(int), int arg) { +// CHECK-LABEL: define{{.*}}foo +// CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFv{{u3i16|u3i32|u3i64}}E.normalized") +fn(arg); +} + +void bar(void (*fn)(int, int), int arg1, int arg2) { +// CHECK-LABEL: define{{.*}}bar +// CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFv{{u3i16|u3i32|u3i64}}S_E.normalized") +fn(arg1, arg2); +} + +void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) { +// CHECK-LABEL: define{{.*}}baz +// CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFv{{u3i16|u3i32|u3i64}}S_S_E.normalized") +fn(arg1, arg2, arg3); +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvPFv{{u3i16|u3i32|u3i64}}ES_E.normalized"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvPFv{{u3i16|u3i32|u3i64}}S_ES_S_E.normalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvPFv{{u3i16|u3i32|u3i64}}S_S_ES_S_S_E.normalized"} Index: clang/test/CodeGen/cfi-icall-normalize.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize.c @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-experimental-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that integer types are normalized for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo0(char arg) { } +// CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] !type !{{[0-9]+}} +void foo1(char arg1, signed char arg2) { } +// CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} +void foo2(char arg1, signed char arg2, signed char arg3) { } +// CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}}
[PATCH] D139395: Add CFI integer types normalization
rcvalle marked an inline comment as done. rcvalle added inline comments. Comment at: clang/docs/ControlFlowIntegrity.rst:241 + +``-fsanitize-cfi--icall-experimental-normalize-integers`` +- samitolvanen wrote: > An extra dash in the title. Fixed. Thank you! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139395/new/ https://reviews.llvm.org/D139395 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D139395: Add CFI integer types normalization
rcvalle updated this revision to Diff 495718. rcvalle added a comment. Fixed use of uninitialized value Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139395/new/ https://reviews.llvm.org/D139395 Files: clang/docs/ControlFlowIntegrity.rst clang/docs/UsersManual.rst clang/include/clang/AST/Mangle.h clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/include/clang/Driver/SanitizerArgs.h clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/MicrosoftMangle.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/Driver/SanitizerArgs.cpp clang/test/CodeGen/cfi-icall-normalize.c clang/test/CodeGen/cfi-icall-normalize2.c clang/test/CodeGen/kcfi-normalize.c Index: clang/test/CodeGen/kcfi-normalize.c === --- /dev/null +++ clang/test/CodeGen/kcfi-normalize.c @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers -x c++ -o - %s | FileCheck %s +#if !__has_feature(kcfi) +#error Missing kcfi? +#endif + +// Test that normalized type metadata for functions are emitted for cross-language KCFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo(void (*fn)(int), int arg) { +// CHECK-LABEL: define{{.*}}foo +// CHECK-SAME: {{.*}}!kcfi_type ![[TYPE1:[0-9]+]] +// CHECK: call void %0(i32 noundef %1){{.*}}[ "kcfi"(i32 1162514891) ] +fn(arg); +} + +void bar(void (*fn)(int, int), int arg1, int arg2) { +// CHECK-LABEL: define{{.*}}bar +// CHECK-SAME: {{.*}}!kcfi_type ![[TYPE2:[0-9]+]] +// CHECK: call void %0(i32 noundef %1, i32 noundef %2){{.*}}[ "kcfi"(i32 448046469) ] +fn(arg1, arg2); +} + +void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) { +// CHECK-LABEL: define{{.*}}baz +// CHECK-SAME: {{.*}}!kcfi_type ![[TYPE3:[0-9]+]] +// CHECK: call void %0(i32 noundef %1, i32 noundef %2, i32 noundef %3){{.*}}[ "kcfi"(i32 -2049681433) ] +fn(arg1, arg2, arg3); +} + +// CHECK: ![[TYPE1]] = !{i32 -1143117868} +// CHECK: ![[TYPE2]] = !{i32 -460921415} +// CHECK: ![[TYPE3]] = !{i32 -333839615} Index: clang/test/CodeGen/cfi-icall-normalize2.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize2.c @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-experimental-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that normalized type metadata for functions are emitted for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo(void (*fn)(int), int arg) { +// CHECK-LABEL: define{{.*}}foo +// CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFvu3i32E.normalized") +fn(arg); +} + +void bar(void (*fn)(int, int), int arg1, int arg2) { +// CHECK-LABEL: define{{.*}}bar +// CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFvu3i32S_E.normalized") +fn(arg1, arg2); +} + +void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) { +// CHECK-LABEL: define{{.*}}baz +// CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFvu3i32S_S_E.normalized") +fn(arg1, arg2, arg3); +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvPFvu3i32ES_E.normalized"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvPFvu3i32S_ES_S_E.normalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvPFvu3i32S_S_ES_S_S_E.normalized"} Index: clang/test/CodeGen/cfi-icall-normalize.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize.c @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-experimental-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that integer types are normalized for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo0(char arg) { } +// CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] !type !{{[0-9]+}} +void foo1(char arg1, signed char arg2) { } +// CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} +void foo2(char arg1, signed char arg2, signed char arg3) { } +// CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} +void foo3(int arg) { } +// CHECK: define{{.*}}foo3{{.*}}!type ![[TYPE3:[
[PATCH] D139395: Add CFI integer types normalization
rcvalle updated this revision to Diff 495860. rcvalle added a comment. Fixed initialization order warning Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139395/new/ https://reviews.llvm.org/D139395 Files: clang/docs/ControlFlowIntegrity.rst clang/docs/UsersManual.rst clang/include/clang/AST/Mangle.h clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/include/clang/Driver/SanitizerArgs.h clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/MicrosoftMangle.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/Driver/SanitizerArgs.cpp clang/test/CodeGen/cfi-icall-normalize.c clang/test/CodeGen/cfi-icall-normalize2.c clang/test/CodeGen/kcfi-normalize.c Index: clang/test/CodeGen/kcfi-normalize.c === --- /dev/null +++ clang/test/CodeGen/kcfi-normalize.c @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers -x c++ -o - %s | FileCheck %s +#if !__has_feature(kcfi) +#error Missing kcfi? +#endif + +// Test that normalized type metadata for functions are emitted for cross-language KCFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo(void (*fn)(int), int arg) { +// CHECK-LABEL: define{{.*}}foo +// CHECK-SAME: {{.*}}!kcfi_type ![[TYPE1:[0-9]+]] +// CHECK: call void %0(i32 noundef %1){{.*}}[ "kcfi"(i32 1162514891) ] +fn(arg); +} + +void bar(void (*fn)(int, int), int arg1, int arg2) { +// CHECK-LABEL: define{{.*}}bar +// CHECK-SAME: {{.*}}!kcfi_type ![[TYPE2:[0-9]+]] +// CHECK: call void %0(i32 noundef %1, i32 noundef %2){{.*}}[ "kcfi"(i32 448046469) ] +fn(arg1, arg2); +} + +void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) { +// CHECK-LABEL: define{{.*}}baz +// CHECK-SAME: {{.*}}!kcfi_type ![[TYPE3:[0-9]+]] +// CHECK: call void %0(i32 noundef %1, i32 noundef %2, i32 noundef %3){{.*}}[ "kcfi"(i32 -2049681433) ] +fn(arg1, arg2, arg3); +} + +// CHECK: ![[TYPE1]] = !{i32 -1143117868} +// CHECK: ![[TYPE2]] = !{i32 -460921415} +// CHECK: ![[TYPE3]] = !{i32 -333839615} Index: clang/test/CodeGen/cfi-icall-normalize2.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize2.c @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-experimental-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that normalized type metadata for functions are emitted for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo(void (*fn)(int), int arg) { +// CHECK-LABEL: define{{.*}}foo +// CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFvu3i32E.normalized") +fn(arg); +} + +void bar(void (*fn)(int, int), int arg1, int arg2) { +// CHECK-LABEL: define{{.*}}bar +// CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFvu3i32S_E.normalized") +fn(arg1, arg2); +} + +void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) { +// CHECK-LABEL: define{{.*}}baz +// CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFvu3i32S_S_E.normalized") +fn(arg1, arg2, arg3); +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvPFvu3i32ES_E.normalized"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvPFvu3i32S_ES_S_E.normalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvPFvu3i32S_S_ES_S_S_E.normalized"} Index: clang/test/CodeGen/cfi-icall-normalize.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize.c @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-experimental-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that integer types are normalized for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo0(char arg) { } +// CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] !type !{{[0-9]+}} +void foo1(char arg1, signed char arg2) { } +// CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} +void foo2(char arg1, signed char arg2, signed char arg3) { } +// CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} +void foo3(int arg) { } +// CHECK: define{{.*}}foo3{{.*}}!type ![[TYPE3
[PATCH] D139395: Add support for integer types notmalization
rcvalle created this revision. Herald added a subscriber: JDevlieghere. Herald added a project: All. rcvalle requested review of this revision. Herald added subscribers: cfe-commits, MaskRay. Herald added a project: clang. This commit adds support for normalizing integer types as vendor extended types for cross-language LLVM CFI/KCFI support with other languages that can't represent and encode C/C++ integer types. This will help with providing cross-language CFI support with the Rust compiler. For more information about LLVM CFI/KCFI and cross-language LLVM CFI/KCFI support for the Rust compiler, see the design document in the tracking issue rust-lang/rust#89653. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D139395 Files: clang/include/clang/AST/Mangle.h clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/include/clang/Driver/SanitizerArgs.h clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/MicrosoftMangle.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/Driver/SanitizerArgs.cpp clang/test/CodeGen/cfi-icall-normalize.c Index: clang/test/CodeGen/cfi-icall-normalize.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that integer types are normalized for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +// CHECK: define{{.*}}foo{{.*}}!type ![[TYPE1:[0-9]+]]{{.*}}!type ![[TYPE2:[0-9]+]] +int foo(char arg1, short arg2) { + return 0; +} + +void bar(int (*fn)(char arg1, short arg2)) { + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu3i32u2i8u3i16E") + fn(0, 0); +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFu3i32u2i8u3i16E"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFu3i32u2i8u3i16E.generalized"} Index: clang/lib/Driver/SanitizerArgs.cpp === --- clang/lib/Driver/SanitizerArgs.cpp +++ clang/lib/Driver/SanitizerArgs.cpp @@ -715,6 +715,9 @@ CfiICallGeneralizePointers = Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers); +CfiICallNormalizeIntegers = +Args.hasArg(options::OPT_fsanitize_cfi_icall_normalize_integers); + if (CfiCrossDso && CfiICallGeneralizePointers && DiagnoseErrors) D.Diag(diag::err_drv_argument_not_allowed_with) << "-fsanitize-cfi-cross-dso" @@ -1218,6 +1221,9 @@ if (CfiICallGeneralizePointers) CmdArgs.push_back("-fsanitize-cfi-icall-generalize-pointers"); + if (CfiICallNormalizeIntegers) +CmdArgs.push_back("-fsanitize-cfi-icall-normalize-integers"); + if (CfiCanonicalJumpTables) CmdArgs.push_back("-fsanitize-cfi-canonical-jump-tables"); Index: clang/lib/CodeGen/CodeGenModule.cpp === --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -6873,7 +6873,8 @@ if (isExternallyVisible(T->getLinkage())) { std::string OutName; llvm::raw_string_ostream Out(OutName); -getCXXABI().getMangleContext().mangleTypeName(T, Out); +getCXXABI().getMangleContext().mangleTypeName( +T, Out, !!getCodeGenOpts().SanitizeCfiICallNormalizeIntegers); Out << Suffix; InternalId = llvm::MDString::get(getLLVMContext(), Out.str()); Index: clang/lib/AST/MicrosoftMangle.cpp === --- clang/lib/AST/MicrosoftMangle.cpp +++ clang/lib/AST/MicrosoftMangle.cpp @@ -179,7 +179,8 @@ int32_t VBPtrOffset, uint32_t VBIndex, raw_ostream &Out) override; void mangleCXXRTTI(QualType T, raw_ostream &Out) override; - void mangleCXXRTTIName(QualType T, raw_ostream &Out) override; + void mangleCXXRTTIName(QualType T, raw_ostream &Out, + bool NormalizeIntegers) override; void mangleCXXRTTIBaseClassDescriptor(const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBTableOffset, uint32_t Flags, @@ -192,7 +193,8 @@ mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived, ArrayRef BasePath, raw_ostream &Out) override; - void mangleTypeName(QualType T, raw_ostream &) override; + void mangleTypeName(QualType T, raw_ostream &, + bool NormalizeIntegers) override; void mangleReferenceTemporary(const VarDecl *, unsigned ManglingNumber, raw_ostream &) override; void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out) override; @@ -3585,8 +3587,8 @@ Man
[PATCH] D139395: Add support for integer types normalization
rcvalle updated this revision to Diff 480349. rcvalle retitled this revision from "Add support for integer types notmalization" to "Add support for integer types normalization". rcvalle added a comment. Fixed typo in commit message Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139395/new/ https://reviews.llvm.org/D139395 Files: clang/include/clang/AST/Mangle.h clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/include/clang/Driver/SanitizerArgs.h clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/MicrosoftMangle.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/Driver/SanitizerArgs.cpp clang/test/CodeGen/cfi-icall-normalize.c Index: clang/test/CodeGen/cfi-icall-normalize.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that integer types are normalized for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +// CHECK: define{{.*}}foo{{.*}}!type ![[TYPE1:[0-9]+]]{{.*}}!type ![[TYPE2:[0-9]+]] +int foo(char arg1, short arg2) { + return 0; +} + +void bar(int (*fn)(char arg1, short arg2)) { + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu3i32u2i8u3i16E") + fn(0, 0); +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFu3i32u2i8u3i16E"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFu3i32u2i8u3i16E.generalized"} Index: clang/lib/Driver/SanitizerArgs.cpp === --- clang/lib/Driver/SanitizerArgs.cpp +++ clang/lib/Driver/SanitizerArgs.cpp @@ -715,6 +715,9 @@ CfiICallGeneralizePointers = Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers); +CfiICallNormalizeIntegers = +Args.hasArg(options::OPT_fsanitize_cfi_icall_normalize_integers); + if (CfiCrossDso && CfiICallGeneralizePointers && DiagnoseErrors) D.Diag(diag::err_drv_argument_not_allowed_with) << "-fsanitize-cfi-cross-dso" @@ -1218,6 +1221,9 @@ if (CfiICallGeneralizePointers) CmdArgs.push_back("-fsanitize-cfi-icall-generalize-pointers"); + if (CfiICallNormalizeIntegers) +CmdArgs.push_back("-fsanitize-cfi-icall-normalize-integers"); + if (CfiCanonicalJumpTables) CmdArgs.push_back("-fsanitize-cfi-canonical-jump-tables"); Index: clang/lib/CodeGen/CodeGenModule.cpp === --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -6873,7 +6873,8 @@ if (isExternallyVisible(T->getLinkage())) { std::string OutName; llvm::raw_string_ostream Out(OutName); -getCXXABI().getMangleContext().mangleTypeName(T, Out); +getCXXABI().getMangleContext().mangleTypeName( +T, Out, !!getCodeGenOpts().SanitizeCfiICallNormalizeIntegers); Out << Suffix; InternalId = llvm::MDString::get(getLLVMContext(), Out.str()); Index: clang/lib/AST/MicrosoftMangle.cpp === --- clang/lib/AST/MicrosoftMangle.cpp +++ clang/lib/AST/MicrosoftMangle.cpp @@ -179,7 +179,8 @@ int32_t VBPtrOffset, uint32_t VBIndex, raw_ostream &Out) override; void mangleCXXRTTI(QualType T, raw_ostream &Out) override; - void mangleCXXRTTIName(QualType T, raw_ostream &Out) override; + void mangleCXXRTTIName(QualType T, raw_ostream &Out, + bool NormalizeIntegers) override; void mangleCXXRTTIBaseClassDescriptor(const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBTableOffset, uint32_t Flags, @@ -192,7 +193,8 @@ mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived, ArrayRef BasePath, raw_ostream &Out) override; - void mangleTypeName(QualType T, raw_ostream &) override; + void mangleTypeName(QualType T, raw_ostream &, + bool NormalizeIntegers) override; void mangleReferenceTemporary(const VarDecl *, unsigned ManglingNumber, raw_ostream &) override; void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out) override; @@ -3585,8 +3587,8 @@ Mangler.getStream() << "@8"; } -void MicrosoftMangleContextImpl::mangleCXXRTTIName(QualType T, - raw_ostream &Out) { +void MicrosoftMangleContextImpl::mangleCXXRTTIName( +QualType T, raw_ostream &Out, bool NormalizeIntegers = false) { MicrosoftCXXNameMangler Mangler(*this, Out); Mangler.getStream() << '.'; Ma
[PATCH] D139395: Add support for integer types normalization
rcvalle added a comment. FYI, I'll still add (hopefully today) documentation for the new `-fsanitize-cfi-icall-normalize-integers` option and compression for these types. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139395/new/ https://reviews.llvm.org/D139395 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D139395: Add CFI integer types normalization
rcvalle updated this revision to Diff 480700. rcvalle retitled this revision from "Add support for integer types normalization" to "Add CFI integer types normalization". rcvalle edited the summary of this revision. rcvalle added a comment. Added documentation Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139395/new/ https://reviews.llvm.org/D139395 Files: clang/docs/ControlFlowIntegrity.rst clang/docs/UsersManual.rst clang/include/clang/AST/Mangle.h clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/include/clang/Driver/SanitizerArgs.h clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/MicrosoftMangle.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/Driver/SanitizerArgs.cpp clang/test/CodeGen/cfi-icall-normalize.c Index: clang/test/CodeGen/cfi-icall-normalize.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that integer types are normalized for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +// CHECK: define{{.*}}foo{{.*}}!type ![[TYPE1:[0-9]+]]{{.*}}!type ![[TYPE2:[0-9]+]] +int foo(char arg1, short arg2) { + return 0; +} + +void bar(int (*fn)(char arg1, short arg2)) { + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu3i32u2i8u3i16E") + fn(0, 0); +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFu3i32u2i8u3i16E"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFu3i32u2i8u3i16E.generalized"} Index: clang/lib/Driver/SanitizerArgs.cpp === --- clang/lib/Driver/SanitizerArgs.cpp +++ clang/lib/Driver/SanitizerArgs.cpp @@ -715,6 +715,9 @@ CfiICallGeneralizePointers = Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers); +CfiICallNormalizeIntegers = +Args.hasArg(options::OPT_fsanitize_cfi_icall_normalize_integers); + if (CfiCrossDso && CfiICallGeneralizePointers && DiagnoseErrors) D.Diag(diag::err_drv_argument_not_allowed_with) << "-fsanitize-cfi-cross-dso" @@ -1218,6 +1221,9 @@ if (CfiICallGeneralizePointers) CmdArgs.push_back("-fsanitize-cfi-icall-generalize-pointers"); + if (CfiICallNormalizeIntegers) +CmdArgs.push_back("-fsanitize-cfi-icall-normalize-integers"); + if (CfiCanonicalJumpTables) CmdArgs.push_back("-fsanitize-cfi-canonical-jump-tables"); Index: clang/lib/CodeGen/CodeGenModule.cpp === --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -6873,7 +6873,8 @@ if (isExternallyVisible(T->getLinkage())) { std::string OutName; llvm::raw_string_ostream Out(OutName); -getCXXABI().getMangleContext().mangleTypeName(T, Out); +getCXXABI().getMangleContext().mangleTypeName( +T, Out, !!getCodeGenOpts().SanitizeCfiICallNormalizeIntegers); Out << Suffix; InternalId = llvm::MDString::get(getLLVMContext(), Out.str()); Index: clang/lib/AST/MicrosoftMangle.cpp === --- clang/lib/AST/MicrosoftMangle.cpp +++ clang/lib/AST/MicrosoftMangle.cpp @@ -179,7 +179,8 @@ int32_t VBPtrOffset, uint32_t VBIndex, raw_ostream &Out) override; void mangleCXXRTTI(QualType T, raw_ostream &Out) override; - void mangleCXXRTTIName(QualType T, raw_ostream &Out) override; + void mangleCXXRTTIName(QualType T, raw_ostream &Out, + bool NormalizeIntegers) override; void mangleCXXRTTIBaseClassDescriptor(const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBTableOffset, uint32_t Flags, @@ -192,7 +193,8 @@ mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived, ArrayRef BasePath, raw_ostream &Out) override; - void mangleTypeName(QualType T, raw_ostream &) override; + void mangleTypeName(QualType T, raw_ostream &, + bool NormalizeIntegers) override; void mangleReferenceTemporary(const VarDecl *, unsigned ManglingNumber, raw_ostream &) override; void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out) override; @@ -3585,8 +3587,8 @@ Mangler.getStream() << "@8"; } -void MicrosoftMangleContextImpl::mangleCXXRTTIName(QualType T, - raw_ostream &Out) { +void MicrosoftMangleContextImpl::mangleCXXRTTIName( +QualType T, raw_ostream &Out, bool NormalizeIntegers
[PATCH] D139395: Add CFI integer types normalization
rcvalle updated this revision to Diff 480773. rcvalle added a comment. Added compression Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139395/new/ https://reviews.llvm.org/D139395 Files: clang/docs/ControlFlowIntegrity.rst clang/docs/UsersManual.rst clang/include/clang/AST/Mangle.h clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/include/clang/Driver/SanitizerArgs.h clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/MicrosoftMangle.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/Driver/SanitizerArgs.cpp clang/test/CodeGen/cfi-icall-normalize.c Index: clang/test/CodeGen/cfi-icall-normalize.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize.c @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that integer types are normalized for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo(char (*fn)(char), char arg) { + // CHECK-LABEL: define{{.*}}foo + // CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type ![[TYPE2:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu2i8S_E") + fn(arg); +} + +void bar(int (*fn)(short, int), short arg1, int arg2) { + // CHECK-LABEL: define{{.*}}bar + // CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type ![[TYPE4:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu3i32u3i16S_E") + fn(arg1, arg2); +} + +void baz(__int128 (*fn)(long, long long, __int128), long arg1, long long arg2, __int128 arg3) { + // CHECK-LABEL: define{{.*}}baz + // CHECK-SAME: {{.*}}!type ![[TYPE5:[0-9]+]] !type ![[TYPE6:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu4i128u3i64S0_S_E") + fn(arg1, arg2, arg3); +} + +void foo1(unsigned char (*fn)(unsigned char), unsigned char arg) { + // CHECK-LABEL: define{{.*}}foo1 + // CHECK-SAME: {{.*}}!type ![[TYPE7:[0-9]+]] !type ![[TYPE8:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu2u8S_E") + fn(arg); +} + +void bar1(unsigned int (*fn)(unsigned short, unsigned int), unsigned short arg1, unsigned int arg2) { + // CHECK-LABEL: define{{.*}}bar1 + // CHECK-SAME: {{.*}}!type ![[TYPE9:[0-9]+]] !type ![[TYPE10:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu3u32u3u16S_E") + fn(arg1, arg2); +} + +void baz1(unsigned __int128 (*fn)(unsigned long, unsigned long long, unsigned __int128), unsigned long arg1, unsigned long long arg2, unsigned __int128 arg3) { + // CHECK-LABEL: define{{.*}}baz1 + // CHECK-SAME: {{.*}}!type ![[TYPE11:[0-9]+]] !type ![[TYPE12:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu4u128u3u64S0_S_E") + fn(arg1, arg2, arg3); +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvPFu2i8S_ES_E"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvPvu2i8E.generalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvPFu3i32u3i16S_ES0_S_E"} +// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvPvu3i16u3i32E.generalized"} +// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvPFu4i128u3i64S0_S_ES0_S0_S_E"} +// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvPvu3i64S0_u4i128E.generalized"} +// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvPFu2u8S_ES_E"} +// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvPvu2u8E.generalized"} +// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvPFu3u32u3u16S_ES0_S_E"} +// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvPvu3u16u3u32E.generalized"} +// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvPFu4u128u3u64S0_S_ES0_S0_S_E"} +// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvPvu3u64S0_u4u128E.generalized"} Index: clang/lib/Driver/SanitizerArgs.cpp === --- clang/lib/Driver/SanitizerArgs.cpp +++ clang/lib/Driver/SanitizerArgs.cpp @@ -715,6 +715,9 @@ CfiICallGeneralizePointers = Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers); +CfiICallNormalizeIntegers = +Args.hasArg(options::OPT_fsanitize_cfi_icall_normalize_integers); + if (CfiCrossDso && CfiICallGeneralizePointers && DiagnoseErrors) D.Diag(diag::err_drv_argument_not_allowed_with) << "-fsanitize-cfi-cross-dso" @@ -1218,6 +1221,9 @@ if (CfiICallGeneralizePointers) CmdArgs.push_back("-fsanitize-cfi-icall-generalize-pointers"); + if (CfiICallNormalizeIntegers) +CmdArgs.push_back("-fsanitize-cfi-icall-normalize-integers"); + if (CfiCanonicalJumpTables) CmdArgs.push_back("-fsanitize-cfi-canonical-jump-tables"); Index: clang/lib/CodeGen/CodeGenModule.cpp === --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -6873,7 +6873,8 @@ if (isExternallyVisible(T->getLinkage())) { std::string OutName; llvm::ra
[PATCH] D139395: Add CFI integer types normalization
rcvalle updated this revision to Diff 480775. rcvalle added a comment. Fixed comments Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139395/new/ https://reviews.llvm.org/D139395 Files: clang/docs/ControlFlowIntegrity.rst clang/docs/UsersManual.rst clang/include/clang/AST/Mangle.h clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/include/clang/Driver/SanitizerArgs.h clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/MicrosoftMangle.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/Driver/SanitizerArgs.cpp clang/test/CodeGen/cfi-icall-normalize.c Index: clang/test/CodeGen/cfi-icall-normalize.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize.c @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that integer types are normalized for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo(char (*fn)(char), char arg) { + // CHECK-LABEL: define{{.*}}foo + // CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type ![[TYPE2:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu2i8S_E") + fn(arg); +} + +void bar(int (*fn)(short, int), short arg1, int arg2) { + // CHECK-LABEL: define{{.*}}bar + // CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type ![[TYPE4:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu3i32u3i16S_E") + fn(arg1, arg2); +} + +void baz(__int128 (*fn)(long, long long, __int128), long arg1, long long arg2, __int128 arg3) { + // CHECK-LABEL: define{{.*}}baz + // CHECK-SAME: {{.*}}!type ![[TYPE5:[0-9]+]] !type ![[TYPE6:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu4i128u3i64S0_S_E") + fn(arg1, arg2, arg3); +} + +void foo1(unsigned char (*fn)(unsigned char), unsigned char arg) { + // CHECK-LABEL: define{{.*}}foo1 + // CHECK-SAME: {{.*}}!type ![[TYPE7:[0-9]+]] !type ![[TYPE8:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu2u8S_E") + fn(arg); +} + +void bar1(unsigned int (*fn)(unsigned short, unsigned int), unsigned short arg1, unsigned int arg2) { + // CHECK-LABEL: define{{.*}}bar1 + // CHECK-SAME: {{.*}}!type ![[TYPE9:[0-9]+]] !type ![[TYPE10:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu3u32u3u16S_E") + fn(arg1, arg2); +} + +void baz1(unsigned __int128 (*fn)(unsigned long, unsigned long long, unsigned __int128), unsigned long arg1, unsigned long long arg2, unsigned __int128 arg3) { + // CHECK-LABEL: define{{.*}}baz1 + // CHECK-SAME: {{.*}}!type ![[TYPE11:[0-9]+]] !type ![[TYPE12:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu4u128u3u64S0_S_E") + fn(arg1, arg2, arg3); +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvPFu2i8S_ES_E"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvPvu2i8E.generalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvPFu3i32u3i16S_ES0_S_E"} +// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvPvu3i16u3i32E.generalized"} +// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvPFu4i128u3i64S0_S_ES0_S0_S_E"} +// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvPvu3i64S0_u4i128E.generalized"} +// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvPFu2u8S_ES_E"} +// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvPvu2u8E.generalized"} +// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvPFu3u32u3u16S_ES0_S_E"} +// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvPvu3u16u3u32E.generalized"} +// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvPFu4u128u3u64S0_S_ES0_S0_S_E"} +// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvPvu3u64S0_u4u128E.generalized"} Index: clang/lib/Driver/SanitizerArgs.cpp === --- clang/lib/Driver/SanitizerArgs.cpp +++ clang/lib/Driver/SanitizerArgs.cpp @@ -715,6 +715,9 @@ CfiICallGeneralizePointers = Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers); +CfiICallNormalizeIntegers = +Args.hasArg(options::OPT_fsanitize_cfi_icall_normalize_integers); + if (CfiCrossDso && CfiICallGeneralizePointers && DiagnoseErrors) D.Diag(diag::err_drv_argument_not_allowed_with) << "-fsanitize-cfi-cross-dso" @@ -1218,6 +1221,9 @@ if (CfiICallGeneralizePointers) CmdArgs.push_back("-fsanitize-cfi-icall-generalize-pointers"); + if (CfiICallNormalizeIntegers) +CmdArgs.push_back("-fsanitize-cfi-icall-normalize-integers"); + if (CfiCanonicalJumpTables) CmdArgs.push_back("-fsanitize-cfi-canonical-jump-tables"); Index: clang/lib/CodeGen/CodeGenModule.cpp === --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -6873,7 +6873,8 @@ if (isExternallyVisible(T->getLinkage())) { std::string OutName; llvm::raw_s
[PATCH] D139395: Add CFI integer types normalization
rcvalle updated this revision to Diff 481016. rcvalle added a comment. Updated tests Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139395/new/ https://reviews.llvm.org/D139395 Files: clang/docs/ControlFlowIntegrity.rst clang/docs/UsersManual.rst clang/include/clang/AST/Mangle.h clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/include/clang/Driver/SanitizerArgs.h clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/MicrosoftMangle.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/Driver/SanitizerArgs.cpp clang/test/CodeGen/cfi-icall-normalize.c Index: clang/test/CodeGen/cfi-icall-normalize.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize.c @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that integer types are normalized for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +char foo(char (*fn)(char), char arg) { + // CHECK-LABEL: define{{.*}}foo + // CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type ![[TYPE2:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu2i8S_E") + return fn(arg); +} + +short bar(int (*fn)(short, int), short arg1, int arg2) { + // CHECK-LABEL: define{{.*}}bar + // CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type ![[TYPE4:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu3i32u3i16S_E") + return (short)fn(arg1, arg2); +} + +long long baz(__int128 (*fn)(long, long long, __int128), long arg1, long long arg2, __int128 arg3) { + // CHECK-LABEL: define{{.*}}baz + // CHECK-SAME: {{.*}}!type ![[TYPE5:[0-9]+]] !type ![[TYPE6:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu4i128u3i64S0_S_E") + return (long long)fn(arg1, arg2, arg3); +} + +unsigned char foo1(unsigned char (*fn)(unsigned char), unsigned char arg) { + // CHECK-LABEL: define{{.*}}foo1 + // CHECK-SAME: {{.*}}!type ![[TYPE7:[0-9]+]] !type ![[TYPE8:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu2u8S_E") + return fn(arg); +} + +unsigned short bar1(unsigned int (*fn)(unsigned short, unsigned int), unsigned short arg1, unsigned int arg2) { + // CHECK-LABEL: define{{.*}}bar1 + // CHECK-SAME: {{.*}}!type ![[TYPE9:[0-9]+]] !type ![[TYPE10:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu3u32u3u16S_E") + return (unsigned short)fn(arg1, arg2); +} + +unsigned long long baz1(unsigned __int128 (*fn)(unsigned long, unsigned long long, unsigned __int128), unsigned long arg1, unsigned long long arg2, unsigned __int128 arg3) { + // CHECK-LABEL: define{{.*}}baz1 + // CHECK-SAME: {{.*}}!type ![[TYPE11:[0-9]+]] !type ![[TYPE12:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu4u128u3u64S0_S_E") + return (unsigned long long)fn(arg1, arg2, arg3); +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFu2i8PFS_S_ES_E"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFu2i8PvS_E.generalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFu3i16PFu3i32S_S0_ES_S0_E"} +// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFu3i16PvS_u3i32E.generalized"} +// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFu3i64PFu4i128S_S_S0_ES_S_S0_E"} +// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFu3i64PvS_S_u4i128E.generalized"} +// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFu2u8PFS_S_ES_E"} +// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFu2u8PvS_E.generalized"} +// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFu3u16PFu3u32S_S0_ES_S0_E"} +// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFu3u16PvS_u3u32E.generalized"} +// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFu3u64PFu4u128S_S_S0_ES_S_S0_E"} +// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFu3u64PvS_S_u4u128E.generalized"} Index: clang/lib/Driver/SanitizerArgs.cpp === --- clang/lib/Driver/SanitizerArgs.cpp +++ clang/lib/Driver/SanitizerArgs.cpp @@ -715,6 +715,9 @@ CfiICallGeneralizePointers = Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers); +CfiICallNormalizeIntegers = +Args.hasArg(options::OPT_fsanitize_cfi_icall_normalize_integers); + if (CfiCrossDso && CfiICallGeneralizePointers && DiagnoseErrors) D.Diag(diag::err_drv_argument_not_allowed_with) << "-fsanitize-cfi-cross-dso" @@ -1218,6 +1221,9 @@ if (CfiICallGeneralizePointers) CmdArgs.push_back("-fsanitize-cfi-icall-generalize-pointers"); + if (CfiICallNormalizeIntegers) +CmdArgs.push_back("-fsanitize-cfi-icall-normalize-integers"); + if (CfiCanonicalJumpTables) CmdArgs.push_back("-fsanitize-cfi-canonical-jump-tables"); Index: clang/lib/CodeGen/CodeGenModule.cpp === --- clang/lib/CodeGen/CodeGenModule.cpp +++ cla
[PATCH] D139395: Add CFI integer types normalization
rcvalle updated this revision to Diff 482327. rcvalle added a comment. Added ".normalized" suffix Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139395/new/ https://reviews.llvm.org/D139395 Files: clang/docs/ControlFlowIntegrity.rst clang/docs/UsersManual.rst clang/include/clang/AST/Mangle.h clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/include/clang/Driver/SanitizerArgs.h clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/MicrosoftMangle.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/Driver/SanitizerArgs.cpp clang/test/CodeGen/cfi-icall-normalize.c Index: clang/test/CodeGen/cfi-icall-normalize.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize.c @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that integer types are normalized for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +char foo(char (*fn)(char), char arg) { + // CHECK-LABEL: define{{.*}}foo + // CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type ![[TYPE2:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu2i8S_E.normalized") + return fn(arg); +} + +short bar(int (*fn)(short, int), short arg1, int arg2) { + // CHECK-LABEL: define{{.*}}bar + // CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type ![[TYPE4:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu3i32u3i16S_E.normalized") + return (short)fn(arg1, arg2); +} + +long long baz(__int128 (*fn)(long, long long, __int128), long arg1, long long arg2, __int128 arg3) { + // CHECK-LABEL: define{{.*}}baz + // CHECK-SAME: {{.*}}!type ![[TYPE5:[0-9]+]] !type ![[TYPE6:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu4i128u3i64S0_S_E.normalized") + return (long long)fn(arg1, arg2, arg3); +} + +unsigned char foo1(unsigned char (*fn)(unsigned char), unsigned char arg) { + // CHECK-LABEL: define{{.*}}foo1 + // CHECK-SAME: {{.*}}!type ![[TYPE7:[0-9]+]] !type ![[TYPE8:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu2u8S_E.normalized") + return fn(arg); +} + +unsigned short bar1(unsigned int (*fn)(unsigned short, unsigned int), unsigned short arg1, unsigned int arg2) { + // CHECK-LABEL: define{{.*}}bar1 + // CHECK-SAME: {{.*}}!type ![[TYPE9:[0-9]+]] !type ![[TYPE10:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu3u32u3u16S_E.normalized") + return (unsigned short)fn(arg1, arg2); +} + +unsigned long long baz1(unsigned __int128 (*fn)(unsigned long, unsigned long long, unsigned __int128), unsigned long arg1, unsigned long long arg2, unsigned __int128 arg3) { + // CHECK-LABEL: define{{.*}}baz1 + // CHECK-SAME: {{.*}}!type ![[TYPE11:[0-9]+]] !type ![[TYPE12:[0-9]+]] + // CHECK: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFu4u128u3u64S0_S_E.normalized") + return (unsigned long long)fn(arg1, arg2, arg3); +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFu2i8PFS_S_ES_E.normalized"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFu2i8PvS_E.normalized.generalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFu3i16PFu3i32S_S0_ES_S0_E.normalized"} +// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFu3i16PvS_u3i32E.normalized.generalized"} +// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFu3i64PFu4i128S_S_S0_ES_S_S0_E.normalized"} +// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFu3i64PvS_S_u4i128E.normalized.generalized"} +// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFu2u8PFS_S_ES_E.normalized"} +// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFu2u8PvS_E.normalized.generalized"} +// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFu3u16PFu3u32S_S0_ES_S0_E.normalized"} +// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFu3u16PvS_u3u32E.normalized.generalized"} +// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFu3u64PFu4u128S_S_S0_ES_S_S0_E.normalized"} +// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFu3u64PvS_S_u4u128E.normalized.generalized"} Index: clang/lib/Driver/SanitizerArgs.cpp === --- clang/lib/Driver/SanitizerArgs.cpp +++ clang/lib/Driver/SanitizerArgs.cpp @@ -715,6 +715,9 @@ CfiICallGeneralizePointers = Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers); +CfiICallNormalizeIntegers = +Args.hasArg(options::OPT_fsanitize_cfi_icall_normalize_integers); + if (CfiCrossDso && CfiICallGeneralizePointers && DiagnoseErrors) D.Diag(diag::err_drv_argument_not_allowed_with) << "-fsanitize-cfi-cross-dso" @@ -1218,6 +1221,9 @@ if (CfiICallGeneralizePointers) CmdArgs.push_back("-fsanitize-cfi-icall-generalize-pointers"); + if (CfiICallNormalizeIntegers) +CmdArgs.push_back("-fsanitize-cfi-icall-normalize-integers"); + if (CfiCanonicalJumpTables) CmdArgs.
[PATCH] D139395: Add CFI integer types normalization
rcvalle added a comment. I elaborated on the reasons why not use a generalized encoding in the design document in the tracking issue https://github.com/rust-lang/rust/issues/89653. The tl;dr; is that it will result in less comprehensive protection by either using a generalized encoding for all C and C++ -compiled code or across the FFI boundary, and will degrade the security of the program when linking foreign Rust-compiled code into a program written in C or C++ because the program previously used a more comprehensive encoding for all its compiled code, not fixing the issue described in the design document and the RFC https://github.com/rcvalle/rfcs/blob/improve-c-types-for-cross-language-cfi/text/-improve-c-types-for-cross-language-cfi.md#appendix. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139395/new/ https://reviews.llvm.org/D139395 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D139395: Add CFI integer types normalization
rcvalle added inline comments. Comment at: clang/lib/AST/ItaniumMangle.cpp:2952 + // uu + if (NormalizeIntegers && T->isInteger()) { +if (T->isSignedInteger()) { pcc wrote: > `isInteger()` will return true for enums, but only if they are complete. This > would mean that code such as > ``` > void (*f)(enum E *e); > > void g() { > f(0); > } > ``` > would use a different encoding to call `f` depending on whether the TU > completes the enum `E`, if pointee types are considered part of the encoding. Isn't `isIntegerType()` that does that? `isInteger()` definition is: ``` bool isInteger() const { return getKind() >= Bool && getKind() <= Int128; } ``` Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139395/new/ https://reviews.llvm.org/D139395 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D139395: Add CFI integer types normalization
rcvalle updated this revision to Diff 482699. rcvalle added a comment. Updated tests Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139395/new/ https://reviews.llvm.org/D139395 Files: clang/docs/ControlFlowIntegrity.rst clang/docs/UsersManual.rst clang/include/clang/AST/Mangle.h clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/include/clang/Driver/SanitizerArgs.h clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/MicrosoftMangle.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/Driver/SanitizerArgs.cpp clang/test/CodeGen/cfi-icall-normalize.c clang/test/CodeGen/cfi-icall-normalize2.c Index: clang/test/CodeGen/cfi-icall-normalize2.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize2.c @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that normalized type metadata for functions are emitted for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo(void (*fn)(int), int arg) { +// CHECK-LABEL: define{{.*}}foo +// CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFv{{u3i16|u3i32|u3i64}}E.normalized") +fn(arg); +} + +void bar(void (*fn)(int, int), int arg1, int arg2) { +// CHECK-LABEL: define{{.*}}bar +// CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFv{{u3i16|u3i32|u3i64}}S_E.normalized") +fn(arg1, arg2); +} + +void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) { +// CHECK-LABEL: define{{.*}}baz +// CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFv{{u3i16|u3i32|u3i64}}S_S_E.normalized") +fn(arg1, arg2, arg3); +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvPFv{{u3i16|u3i32|u3i64}}ES_E.normalized"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvPFv{{u3i16|u3i32|u3i64}}S_ES_S_E.normalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvPFv{{u3i16|u3i32|u3i64}}S_S_ES_S_S_E.normalized"} Index: clang/test/CodeGen/cfi-icall-normalize.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize.c @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that integer types are normalized for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo0(char arg) { } +// CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] !type !{{[0-9]+}} +void foo1(char arg1, signed char arg2) { } +// CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} +void foo2(char arg1, signed char arg2, signed char arg3) { } +// CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} +void foo3(int arg) { } +// CHECK: define{{.*}}foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} +void foo4(int arg1, int arg2) { } +// CHECK: define{{.*}}foo4{{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}} +void foo5(int arg1, int arg2, int arg3) { } +// CHECK: define{{.*}}foo5{{.*}}!type ![[TYPE5:[0-9]+]] !type !{{[0-9]+}} +void foo6(long arg) { } +// CHECK: define{{.*}}foo6{{.*}}!type ![[TYPE6:[0-9]+]] !type !{{[0-9]+}} +void foo7(long arg1, long long arg2) { } +// CHECK: define{{.*}}foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}} +void foo8(long arg1, long long arg2, long long arg3) { } +// CHECK: define{{.*}}foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} +void foo9(short arg) { } +// CHECK: define{{.*}}foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} +void foo10(short arg1, short arg2) { } +// CHECK: define{{.*}}foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}} +void foo11(short arg1, short arg2, short arg3) { } +// CHECK: define{{.*}}foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}} +void foo12(unsigned char arg) { } +// CHECK: define{{.*}}foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} +void foo13(unsigned char arg1, unsigned char arg2) { } +// CHECK: define{{.*}}foo13{{.*}}!type ![[TYPE13:[0-9]+]] !type !{{[0-9]+}} +void foo14(unsigned char arg1, unsigned char arg2, unsigned char arg3) { } +// CHECK: define{{.*}}foo14{{.*}}!type ![[TYPE14:[0-9]+]] !type !{{[0-9]+}} +void foo15(unsigned int arg) { } +// CHECK: define{{.*}}foo15{{.*}}!type ![[TYPE15:[0-9]+]] !type !{{[0-9]+}} +void foo16(unsigned int arg1, unsigned int arg2) { } +// CHECK: define{{.*}}foo16{{.*}}!type ![[TYPE16:[0-9]+]] !type !{{[0-9]+}} +void foo17(unsigned int arg1, unsigned int arg
[PATCH] D139395: Add CFI integer types normalization
rcvalle updated this revision to Diff 482708. rcvalle added a comment. Added KCFI support Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D139395/new/ https://reviews.llvm.org/D139395 Files: clang/docs/ControlFlowIntegrity.rst clang/docs/UsersManual.rst clang/include/clang/AST/Mangle.h clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/include/clang/Driver/SanitizerArgs.h clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/MicrosoftMangle.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/Driver/SanitizerArgs.cpp clang/test/CodeGen/cfi-icall-normalize.c clang/test/CodeGen/cfi-icall-normalize2.c clang/test/CodeGen/kcfi-normalize.c Index: clang/test/CodeGen/kcfi-normalize.c === --- /dev/null +++ clang/test/CodeGen/kcfi-normalize.c @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fsanitize-cfi-icall-normalize-integers -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fsanitize-cfi-icall-normalize-integers -x c++ -o - %s | FileCheck %s +#if !__has_feature(kcfi) +#error Missing kcfi? +#endif + +// Test that normalized type metadata for functions are emitted for cross-language KCFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo(void (*fn)(int), int arg) { +// CHECK-LABEL: define{{.*}}foo +// CHECK-SAME: {{.*}}!kcfi_type ![[TYPE1:[0-9]+]] +// CHECK: call void %0(i32 noundef %1){{.*}}[ "kcfi"(i32 1162514891) ] +fn(arg); +} + +void bar(void (*fn)(int, int), int arg1, int arg2) { +// CHECK-LABEL: define{{.*}}bar +// CHECK-SAME: {{.*}}!kcfi_type ![[TYPE2:[0-9]+]] +// CHECK: call void %0(i32 noundef %1, i32 noundef %2){{.*}}[ "kcfi"(i32 448046469) ] +fn(arg1, arg2); +} + +void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) { +// CHECK-LABEL: define{{.*}}baz +// CHECK-SAME: {{.*}}!kcfi_type ![[TYPE3:[0-9]+]] +// CHECK: call void %0(i32 noundef %1, i32 noundef %2, i32 noundef %3){{.*}}[ "kcfi"(i32 -2049681433) ] +fn(arg1, arg2, arg3); +} + +// CHECK: ![[TYPE1]] = !{i32 -1143117868} +// CHECK: ![[TYPE2]] = !{i32 -460921415} +// CHECK: ![[TYPE3]] = !{i32 -333839615} Index: clang/test/CodeGen/cfi-icall-normalize2.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize2.c @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that normalized type metadata for functions are emitted for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo(void (*fn)(int), int arg) { +// CHECK-LABEL: define{{.*}}foo +// CHECK-SAME: {{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFv{{u3i16|u3i32|u3i64}}E.normalized") +fn(arg); +} + +void bar(void (*fn)(int, int), int arg1, int arg2) { +// CHECK-LABEL: define{{.*}}bar +// CHECK-SAME: {{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFv{{u3i16|u3i32|u3i64}}S_E.normalized") +fn(arg1, arg2); +} + +void baz(void (*fn)(int, int, int), int arg1, int arg2, int arg3) { +// CHECK-LABEL: define{{.*}}baz +// CHECK-SAME: {{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}} +// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFv{{u3i16|u3i32|u3i64}}S_S_E.normalized") +fn(arg1, arg2, arg3); +} + +// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvPFv{{u3i16|u3i32|u3i64}}ES_E.normalized"} +// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvPFv{{u3i16|u3i32|u3i64}}S_ES_S_E.normalized"} +// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvPFv{{u3i16|u3i32|u3i64}}S_S_ES_S_S_E.normalized"} Index: clang/test/CodeGen/cfi-icall-normalize.c === --- /dev/null +++ clang/test/CodeGen/cfi-icall-normalize.c @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-normalize-integers -emit-llvm -o - %s | FileCheck %s + +// Test that integer types are normalized for cross-language CFI support with +// other languages that can't represent and encode C/C++ integer types. + +void foo0(char arg) { } +// CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] !type !{{[0-9]+}} +void foo1(char arg1, signed char arg2) { } +// CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} +void foo2(char arg1, signed char arg2, signed char arg3) { } +// CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}} +void foo3(int arg) { } +// CHECK: define{{