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]+}}
+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 arg2, unsigned int arg3) { }
+// CHECK: define{{.*}}foo17{{.*}}!type ![[TYPE17:[0-9]+]] !type !{{[0-9]+}}
+void foo18(unsigned long arg) { }
+// CHECK: define{{.*}}foo18{{.*}}!type ![[TYPE18:[0-9]+]] !type !{{[0-9]+}}
+void foo19(unsigned long arg1, unsigned long long arg2) { }
+// CHECK: define{{.*}}foo19{{.*}}!type ![[TYPE19:[0-9]+]] !type !{{[0-9]+}}
+void foo20(unsigned long arg1, unsigned long long arg2, unsigned long long arg3) { }
+// CHECK: define{{.*}}foo20{{.*}}!type ![[TYPE20:[0-9]+]] !type !{{[0-9]+}}
+void foo21(unsigned short arg) { }
+// CHECK: define{{.*}}foo21{{.*}}!type ![[TYPE21:[0-9]+]] !type !{{[0-9]+}}
+void foo22(unsigned short arg1, unsigned short arg2) { }
+// CHECK: define{{.*}}foo22{{.*}}!type ![[TYPE22:[0-9]+]] !type !{{[0-9]+}}
+void foo23(unsigned short arg1, unsigned short arg2, unsigned short arg3) { }
+// CHECK: define{{.*}}foo23{{.*}}!type ![[TYPE23:[0-9]+]] !type !{{[0-9]+}}
+
+// 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"}
+// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFv{{u3i32u3i64|u3i64S_}}E.normalized"}
+// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFv{{u3i32u3i64S0_|u3i64S_S_}}E.normalized"}
+// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvu3i16E.normalized"}
+// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvu3i16S_E.normalized"}
+// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvu3i16S_S_E.normalized"}
+// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvu2u8E.normalized"}
+// CHECK: ![[TYPE13]] = !{i64 0, !"_ZTSFvu2u8S_E.normalized"}
+// CHECK: ![[TYPE14]] = !{i64 0, !"_ZTSFvu2u8S_S_E.normalized"}
+// CHECK: ![[TYPE15]] = !{i64 0, !"_ZTSFv{{u3u16|u3u32|u3u64}}E.normalized"}
+// CHECK: ![[TYPE16]] = !{i64 0, !"_ZTSFv{{u3u16|u3u32|u3u64}}S_E.normalized"}
+// CHECK: ![[TYPE17]] = !{i64 0, !"_ZTSFv{{u3u16|u3u32|u3u64}}S_S_E.normalized"}
+// CHECK: ![[TYPE18]] = !{i64 0, !"_ZTSFv{{u3u32|u3u64}}E.normalized"}
+// CHECK: ![[TYPE19]] = !{i64 0, !"_ZTSFv{{u3u32u3u64|u3u64S_}}E.normalized"}
+// CHECK: ![[TYPE20]] = !{i64 0, !"_ZTSFv{{u3u32u3u64S0_|u3u64S_S_}}E.normalized"}
+// CHECK: ![[TYPE21]] = !{i64 0, !"_ZTSFvu3u16E.normalized"}
+// CHECK: ![[TYPE22]] = !{i64 0, !"_ZTSFvu3u16S_E.normalized"}
+// CHECK: ![[TYPE23]] = !{i64 0, !"_ZTSFvu3u16S_S_E.normalized"}
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-experimental-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
@@ -1690,7 +1690,11 @@
std::string OutName;
llvm::raw_string_ostream Out(OutName);
- getCXXABI().getMangleContext().mangleTypeName(T, Out);
+ getCXXABI().getMangleContext().mangleTypeName(
+ T, Out, !!getCodeGenOpts().SanitizeCfiICallNormalizeIntegers);
+
+ if (getCodeGenOpts().SanitizeCfiICallNormalizeIntegers)
+ Out << ".normalized";
return llvm::ConstantInt::get(Int32Ty,
static_cast<uint32_t>(llvm::xxHash64(OutName)));
@@ -6873,7 +6877,12 @@
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);
+
+ if (getCodeGenOpts().SanitizeCfiICallNormalizeIntegers)
+ Out << ".normalized";
+
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<const CXXRecordDecl *> 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() << '.';
Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
@@ -3753,7 +3755,8 @@
Mangler.mangleName(EnclosingDecl);
}
-void MicrosoftMangleContextImpl::mangleTypeName(QualType T, raw_ostream &Out) {
+void MicrosoftMangleContextImpl::mangleTypeName(
+ QualType T, raw_ostream &Out, bool NormalizeIntegers = false) {
// This is just a made up unique string for the purposes of tbaa. undname
// does *not* know how to demangle it.
MicrosoftCXXNameMangler Mangler(*this, Out);
Index: clang/lib/AST/ItaniumMangle.cpp
===================================================================
--- clang/lib/AST/ItaniumMangle.cpp
+++ clang/lib/AST/ItaniumMangle.cpp
@@ -108,8 +108,10 @@
void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
const CXXRecordDecl *Type, raw_ostream &) override;
void mangleCXXRTTI(QualType T, raw_ostream &) override;
- void mangleCXXRTTIName(QualType T, raw_ostream &) override;
- void mangleTypeName(QualType T, raw_ostream &) override;
+ void mangleCXXRTTIName(QualType T, raw_ostream &,
+ bool NormalizeIntegers) override;
+ void mangleTypeName(QualType T, raw_ostream &,
+ bool NormalizeIntegers) override;
void mangleCXXCtorComdat(const CXXConstructorDecl *D, raw_ostream &) override;
void mangleCXXDtorComdat(const CXXDestructorDecl *D, raw_ostream &) override;
@@ -214,6 +216,10 @@
class CXXNameMangler {
ItaniumMangleContextImpl &Context;
raw_ostream &Out;
+ /// Normalize integer types for cross-language CFI support with other
+ /// languages that can't represent and encode C/C++ integer types.
+ bool NormalizeIntegers = false;
+
bool NullOut = false;
/// In the "DisableDerivedAbiTags" mode derived ABI tags are not calculated.
/// This mode is used when mangler creates another mangler recursively to
@@ -412,6 +418,10 @@
: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
AbiTagsRoot(AbiTags) {}
+ CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_,
+ bool NormalizeIntegers_)
+ : Context(C), Out(Out_), NormalizeIntegers(NormalizeIntegers_),
+ NullOut(false), AbiTagsRoot(AbiTags) {}
CXXNameMangler(CXXNameMangler &Outer, raw_ostream &Out_)
: Context(Outer.Context), Out(Out_), Structor(Outer.Structor),
StructorType(Outer.StructorType), SeqID(Outer.SeqID),
@@ -2936,6 +2946,85 @@
// ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
// ::= u <source-name> # vendor extended type
std::string type_name;
+ // Normalize integer types as vendor extended types:
+ // u<length>i<type size>
+ // u<length>u<type size>
+ if (NormalizeIntegers && T->isInteger()) {
+ if (T->isSignedInteger()) {
+ switch (getASTContext().getTypeSize(T)) {
+ case 8:
+ // Pick a representative for each integer size in the substitution
+ // dictionary. (Its actual defined size is not relevant.)
+ if (mangleSubstitution(BuiltinType::SChar))
+ break;
+ Out << "u2i8";
+ addSubstitution(BuiltinType::SChar);
+ break;
+ case 16:
+ if (mangleSubstitution(BuiltinType::Short))
+ break;
+ Out << "u3i16";
+ addSubstitution(BuiltinType::Short);
+ break;
+ case 32:
+ if (mangleSubstitution(BuiltinType::Int))
+ break;
+ Out << "u3i32";
+ addSubstitution(BuiltinType::Int);
+ break;
+ case 64:
+ if (mangleSubstitution(BuiltinType::Long))
+ break;
+ Out << "u3i64";
+ addSubstitution(BuiltinType::Long);
+ break;
+ case 128:
+ if (mangleSubstitution(BuiltinType::Int128))
+ break;
+ Out << "u4i128";
+ addSubstitution(BuiltinType::Int128);
+ break;
+ default:
+ llvm_unreachable("Unknown integer size for normalization");
+ }
+ } else {
+ switch (getASTContext().getTypeSize(T)) {
+ case 8:
+ if (mangleSubstitution(BuiltinType::UChar))
+ break;
+ Out << "u2u8";
+ addSubstitution(BuiltinType::UChar);
+ break;
+ case 16:
+ if (mangleSubstitution(BuiltinType::UShort))
+ break;
+ Out << "u3u16";
+ addSubstitution(BuiltinType::UShort);
+ break;
+ case 32:
+ if (mangleSubstitution(BuiltinType::UInt))
+ break;
+ Out << "u3u32";
+ addSubstitution(BuiltinType::UInt);
+ break;
+ case 64:
+ if (mangleSubstitution(BuiltinType::ULong))
+ break;
+ Out << "u3u64";
+ addSubstitution(BuiltinType::ULong);
+ break;
+ case 128:
+ if (mangleSubstitution(BuiltinType::UInt128))
+ break;
+ Out << "u4u128";
+ addSubstitution(BuiltinType::UInt128);
+ break;
+ default:
+ llvm_unreachable("Unknown integer size for normalization");
+ }
+ }
+ return;
+ }
switch (T->getKind()) {
case BuiltinType::Void:
Out << 'v';
@@ -6517,16 +6606,17 @@
Mangler.mangleType(Ty);
}
-void ItaniumMangleContextImpl::mangleCXXRTTIName(QualType Ty,
- raw_ostream &Out) {
+void ItaniumMangleContextImpl::mangleCXXRTTIName(
+ QualType Ty, raw_ostream &Out, bool NormalizeIntegers = false) {
// <special-name> ::= TS <type> # typeinfo name (null terminated byte string)
- CXXNameMangler Mangler(*this, Out);
+ CXXNameMangler Mangler(*this, Out, NormalizeIntegers);
Mangler.getStream() << "_ZTS";
Mangler.mangleType(Ty);
}
-void ItaniumMangleContextImpl::mangleTypeName(QualType Ty, raw_ostream &Out) {
- mangleCXXRTTIName(Ty, Out);
+void ItaniumMangleContextImpl::mangleTypeName(QualType Ty, raw_ostream &Out,
+ bool NormalizeIntegers = false) {
+ mangleCXXRTTIName(Ty, Out, NormalizeIntegers);
}
void ItaniumMangleContextImpl::mangleStringLiteral(const StringLiteral *, raw_ostream &) {
Index: clang/include/clang/Driver/SanitizerArgs.h
===================================================================
--- clang/include/clang/Driver/SanitizerArgs.h
+++ clang/include/clang/Driver/SanitizerArgs.h
@@ -37,6 +37,7 @@
bool MsanParamRetval = true;
bool CfiCrossDso = false;
bool CfiICallGeneralizePointers = false;
+ bool CfiICallNormalizeIntegers = false;
bool CfiCanonicalJumpTables = false;
int AsanFieldPadding = 0;
bool SharedRuntime = false;
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1845,6 +1845,10 @@
Group<f_clang_Group>,
HelpText<"Generalize pointers in CFI indirect call type signature checks">,
MarshallingInfoFlag<CodeGenOpts<"SanitizeCfiICallGeneralizePointers">>;
+def fsanitize_cfi_icall_normalize_integers : Flag<["-"], "fsanitize-cfi-icall-experimental-normalize-integers">,
+ Group<f_clang_Group>,
+ HelpText<"Normalize integers in CFI indirect call type signature checks">,
+ MarshallingInfoFlag<CodeGenOpts<"SanitizeCfiICallNormalizeIntegers">>;
defm sanitize_cfi_canonical_jump_tables : BoolOption<"f", "sanitize-cfi-canonical-jump-tables",
CodeGenOpts<"SanitizeCfiCanonicalJumpTables">, DefaultFalse,
PosFlag<SetTrue, [], "Make">, NegFlag<SetFalse, [CoreOption, NoXarchOption], "Do not make">,
Index: clang/include/clang/Basic/CodeGenOptions.def
===================================================================
--- clang/include/clang/Basic/CodeGenOptions.def
+++ clang/include/clang/Basic/CodeGenOptions.def
@@ -258,6 +258,8 @@
///< diagnostics.
CODEGENOPT(SanitizeCfiICallGeneralizePointers, 1, 0) ///< Generalize pointer types in
///< CFI icall function signatures
+CODEGENOPT(SanitizeCfiICallNormalizeIntegers, 1, 0) ///< Normalize integer types in
+ ///< CFI icall function signatures
CODEGENOPT(SanitizeCfiCanonicalJumpTables, 1, 0) ///< Make jump table symbols canonical
///< instead of creating a local jump table.
CODEGENOPT(SanitizeCoverageType, 2, 0) ///< Type of sanitizer coverage
Index: clang/include/clang/AST/Mangle.h
===================================================================
--- clang/include/clang/AST/Mangle.h
+++ clang/include/clang/AST/Mangle.h
@@ -139,7 +139,8 @@
unsigned ManglingNumber,
raw_ostream &) = 0;
virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
- virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
+ virtual void mangleCXXRTTIName(QualType T, raw_ostream &,
+ bool NormalizeIntegers = false) = 0;
virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream&);
@@ -176,7 +177,8 @@
/// or type uniquing.
/// TODO: Extend this to internal types by generating names that are unique
/// across translation units so it can be used with LTO.
- virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
+ virtual void mangleTypeName(QualType T, raw_ostream &,
+ bool NormalizeIntegers = false) = 0;
/// @}
};
Index: clang/docs/UsersManual.rst
===================================================================
--- clang/docs/UsersManual.rst
+++ clang/docs/UsersManual.rst
@@ -1951,6 +1951,14 @@
checked by Control Flow Integrity indirect call checking. See
:doc:`ControlFlowIntegrity` for more details.
+.. option:: -fsanitize-cfi-icall-experimental-normalize-integers
+
+ Normalize integers in return and argument types in function type signatures
+ checked by Control Flow Integrity indirect call checking. See
+ :doc:`ControlFlowIntegrity` for more details.
+
+ This option is currently experimental.
+
.. option:: -fstrict-vtable-pointers
Enable optimizations based on the strict rules for overwriting polymorphic
Index: clang/docs/ControlFlowIntegrity.rst
===================================================================
--- clang/docs/ControlFlowIntegrity.rst
+++ clang/docs/ControlFlowIntegrity.rst
@@ -236,6 +236,25 @@
``-fsanitize-cfi-icall-generalize-pointers`` is not compatible with
``-fsanitize-cfi-cross-dso``.
+.. _cfi-icall-experimental-normalize-integers:
+
+``-fsanitize-cfi-icall-experimental-normalize-integers``
+--------------------------------------------------------
+
+This option enables 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.
+
+Specifically, integer types are encoded as their defined representations (e.g.,
+8-bit signed integer, 16-bit signed integer, 32-bit signed integer, ...) for
+compatibility with languages that define explicitly-sized integer types (e.g.,
+i8, i16, i32, ..., in Rust).
+
+``-fsanitize-cfi-icall-experimental-normalize-integers`` is compatible with
+``-fsanitize-cfi-icall-generalize-pointers``.
+
+This option is currently experimental.
+
.. _cfi-canonical-jump-tables:
``-fsanitize-cfi-canonical-jump-tables``
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits