[clang] [clang] Implement type/address discrimination of type_info vtable. (PR #99726)

Daniil Kovalev via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 31 13:25:21 PDT 2024


================
@@ -0,0 +1,87 @@
+// RUN: %clang_cc1 -DENABLE_TID=0 -I%S -std=c++11 -triple=arm64e-apple-darwin \
+// RUN:   -fptrauth-calls -fptrauth-intrinsics \
+// RUN:   -fptrauth-vtable-pointer-type-discrimination \
+// RUN:   -fptrauth-vtable-pointer-address-discrimination \
+// RUN:   %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,NODISC
+
+// RUN: %clang_cc1 -DENABLE_TID=1 -I%S -std=c++11 -triple=arm64e-apple-darwin \
+// RUN:   -fptrauth-calls -fptrauth-intrinsics \
+// RUN:   -fptrauth-vtable-pointer-type-discrimination \
+// RUN:   -fptrauth-vtable-pointer-address-discrimination \
+// RUN:   -fptrauth-type-info-vtable-pointer-discrimination \
+// RUN:   %s -emit-llvm -o - | FileCheck %s --check-prefixes=CHECK,DISC
+
+// copied from typeinfo
+namespace std {
+
+#if __has_cpp_attribute(clang::ptrauth_vtable_pointer)
+#  if __has_feature(ptrauth_type_info_vtable_pointer_discrimination)
+#    define _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH \
+       [[clang::ptrauth_vtable_pointer(process_independent, address_discrimination, type_discrimination)]]
+#  else
+#    define _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH \
+       [[clang::ptrauth_vtable_pointer(process_independent, no_address_discrimination, no_extra_discrimination)]]
+#  endif
+#else
+#  define _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH
+#endif
+
+  class _LIBCPP_TYPE_INFO_VTABLE_POINTER_AUTH type_info
+  {
+    type_info& operator=(const type_info&);
+    type_info(const type_info&);
+
+  protected:
+      explicit type_info(const char* __n);
+
+  public:
+      virtual ~type_info();
+
+      virtual void test_method();
+  };
+} // namespace std
+
+static_assert(__has_feature(ptrauth_type_info_vtable_pointer_discrimination) == ENABLE_TID, "incorrect feature state");
+
+// CHECK: @disc_std_type_info = global i32 [[STDTYPEINFO_DISC:45546]]
+extern "C" int disc_std_type_info = __builtin_ptrauth_string_discriminator("_ZTVSt9type_info");
+
+// CHECK: @_ZTV10TestStruct = unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTI10TestStruct, ptr ptrauth (ptr @_ZN10TestStructD1Ev, i32 0, i64 52216, ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV10TestStruct, i32 0, i32 0, i32 2)), ptr ptrauth (ptr @_ZN10TestStructD0Ev, i32 0, i64 39671, ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV10TestStruct, i32 0, i32 0, i32 3))] }, align 8
+// CHECK: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
+// CHECK: @_ZTS10TestStruct = constant [13 x i8] c"10TestStruct\00", align 1
+
+// NODISC: @_ZTI10TestStruct = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr @_ZTS10TestStruct }, align 8
+
+// DISC: @_ZTI10TestStruct = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2, i64 [[STDTYPEINFO_DISC]]), ptr @_ZTS10TestStruct }, align 8
----------------
kovdan01 wrote:

@ahmedbougacha Here, we have

```
ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2, i64 [[STDTYPEINFO_DISC]])
```

This has constant discriminator, but does not have address discrimination, while it should be enabled with `-fptrauth-type-info-vtable-pointer-discrimination`. The correct output should be smth like (if we use a placeholder value `ptr inttoptr (i64 1 to ptr)` as storage address)

```
ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2, i64 [[STDTYPEINFO_DISC]], ptr inttoptr (i64 1 to ptr))
```

The root cause is described in my previous comment https://github.com/llvm/llvm-project/pull/99726/#issuecomment-2259839809.


https://github.com/llvm/llvm-project/pull/99726


More information about the cfe-commits mailing list