[PATCH] D139395: Add CFI integer types normalization

2023-01-31 Thread Ramon de C Valle via Phabricator via cfe-commits
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

2023-01-31 Thread Ramon de C Valle via Phabricator via cfe-commits
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

2023-01-20 Thread Ramon de C Valle via Phabricator via cfe-commits
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

2023-01-20 Thread Ramon de C Valle via Phabricator via cfe-commits
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

2023-01-20 Thread Ramon de C Valle via Phabricator via cfe-commits
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

2023-02-07 Thread Ramon de C Valle via Phabricator via cfe-commits
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

2023-02-08 Thread Ramon de C Valle via Phabricator via cfe-commits
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

2022-12-05 Thread Ramon de C Valle via Phabricator via cfe-commits
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

2022-12-05 Thread Ramon de C Valle via Phabricator via cfe-commits
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

2022-12-06 Thread Ramon de C Valle via Phabricator via cfe-commits
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

2022-12-06 Thread Ramon de C Valle via Phabricator via cfe-commits
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

2022-12-06 Thread Ramon de C Valle via Phabricator via cfe-commits
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

2022-12-06 Thread Ramon de C Valle via Phabricator via cfe-commits
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

2022-12-07 Thread Ramon de C Valle via Phabricator via cfe-commits
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

2022-12-12 Thread Ramon de C Valle via Phabricator via cfe-commits
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

2022-12-12 Thread Ramon de C Valle via Phabricator via cfe-commits
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

2022-12-12 Thread Ramon de C Valle via Phabricator via cfe-commits
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

2022-12-13 Thread Ramon de C Valle via Phabricator via cfe-commits
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

2022-12-13 Thread Ramon de C Valle via Phabricator via cfe-commits
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{{