[llvm] [BOLT][RelVTable] Skip special handling on non virtual function pointer relocations (PR #137406)

YongKang Zhu via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 28 19:02:25 PDT 2025


https://github.com/yozhu updated https://github.com/llvm/llvm-project/pull/137406

>From c2ea84a98526d435a00a4741a076135bcb314bee Mon Sep 17 00:00:00 2001
From: YongKang Zhu <yongzhu at fb.com>
Date: Thu, 24 Apr 2025 20:31:55 -0700
Subject: [PATCH 1/4] [BOLT] Skip special handling on non virtual function
 pointer relocation in relative vtable

Besides virtual function pointers vtable could also contain other kinds of
entries like the one for RTTI data that requires relocation too. We need to
skip the special handling on the relocations for non virtual function pointers
in relative vtable.
---
 bolt/lib/Rewrite/RewriteInstance.cpp | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 69fb736d7bde0..1c24200059035 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -2697,20 +2697,19 @@ void RewriteInstance::handleRelocation(const SectionRef &RelocatedSection,
                BD->nameStartsWith("_ZTCN"))) { // construction vtable
       BinaryFunction *BF = BC->getBinaryFunctionContainingAddress(
           SymbolAddress, /*CheckPastEnd*/ false, /*UseMaxSize*/ true);
-      if (!BF || BF->getAddress() != SymbolAddress) {
-        BC->errs()
-            << "BOLT-ERROR: the virtual function table entry at offset 0x"
-            << Twine::utohexstr(Rel.getOffset());
-        if (BF)
-          BC->errs() << " points to the middle of a function @ 0x"
-                     << Twine::utohexstr(BF->getAddress()) << "\n";
-        else
-          BC->errs() << " does not point to any function\n";
-        exit(1);
+      if (BF) {
+        if (BF->getAddress() != SymbolAddress) {
+          BC->errs()
+              << "BOLT-ERROR: the virtual function table entry at offset 0x"
+              << Twine::utohexstr(Rel.getOffset())
+              << " points to the middle of a function @ 0x"
+              << Twine::utohexstr(BF->getAddress()) << "\n";
+          exit(1);
+        }
+        BC->addRelocation(Rel.getOffset(), BF->getSymbol(), RType, Addend,
+                          ExtractedValue);
+        return;
       }
-      BC->addRelocation(Rel.getOffset(), BF->getSymbol(), RType, Addend,
-                        ExtractedValue);
-      return;
     }
   }
 

>From a9e5abe09168f3e9327737dfbec46732e5aa55e0 Mon Sep 17 00:00:00 2001
From: YongKang Zhu <yongzhu at fb.com>
Date: Mon, 28 Apr 2025 12:14:40 -0700
Subject: [PATCH 2/4] Add a test case

---
 ...-non-vfuncptr-reloc-in-relative-vtable.cpp | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)
 create mode 100644 bolt/test/X86/skip-non-vfuncptr-reloc-in-relative-vtable.cpp

diff --git a/bolt/test/X86/skip-non-vfuncptr-reloc-in-relative-vtable.cpp b/bolt/test/X86/skip-non-vfuncptr-reloc-in-relative-vtable.cpp
new file mode 100644
index 0000000000000..d7062022b3100
--- /dev/null
+++ b/bolt/test/X86/skip-non-vfuncptr-reloc-in-relative-vtable.cpp
@@ -0,0 +1,25 @@
+// Test the fix that BOLT should skip speical handling of any non virtual
+// function pointer relocations in relative vtable.
+
+// RUN: %clang -fuse-ld=lld -o %t.so %s -Wl,-q \
+// RUN:     -fexperimental-relative-c++-abi-vtables
+// RUN: llvm-bolt %t.so -o %t.bolted.so
+
+extern "C" unsigned long long _ZTVN10__cxxabiv117__class_type_infoE = 0;
+extern "C" unsigned long long _ZTVN10__cxxabiv120__si_class_type_infoE = 0;
+
+class A {
+public:
+  virtual void foo() {}
+};
+
+class B : public A {
+  virtual void foo() override {}
+};
+
+int main() {
+  B b;
+  A *p = &b;
+  p->foo();
+  return 0;
+}

>From ec0c93c6b0ce33014913fd033a239aa245dcbfc6 Mon Sep 17 00:00:00 2001
From: YongKang Zhu <yongzhu at fb.com>
Date: Mon, 28 Apr 2025 16:47:33 -0700
Subject: [PATCH 3/4] Update test

---
 ...p-non-vfuncptr-reloc-in-relative-vtable.ll | 17 +++++++++++++
 ...-non-vfuncptr-reloc-in-relative-vtable.cpp | 25 -------------------
 2 files changed, 17 insertions(+), 25 deletions(-)
 create mode 100644 bolt/test/AArch64/skip-non-vfuncptr-reloc-in-relative-vtable.ll
 delete mode 100644 bolt/test/X86/skip-non-vfuncptr-reloc-in-relative-vtable.cpp

diff --git a/bolt/test/AArch64/skip-non-vfuncptr-reloc-in-relative-vtable.ll b/bolt/test/AArch64/skip-non-vfuncptr-reloc-in-relative-vtable.ll
new file mode 100644
index 0000000000000..05c2cedd5e99e
--- /dev/null
+++ b/bolt/test/AArch64/skip-non-vfuncptr-reloc-in-relative-vtable.ll
@@ -0,0 +1,17 @@
+; Test the fix that BOLT should skip speical handling of any non virtual
+; function pointer relocations in relative vtable.
+
+; RUN: llc --filetype=obj -mtriple=aarch64-none-linux-gnu \
+; RUN:     --relocation-model=pic -o %t.o %s
+; RUN: %clang %cxxflags -fuse-ld=lld %t.o -o %t.so -Wl,-q
+; RUN: llvm-bolt %t.so -o %t.bolted.so
+
+$_fake_rtti_data = comdat any
+ at _fake_rtti_data = internal unnamed_addr constant [16 x i8] c"_FAKE_RTTI_DATA_", comdat, align 8
+
+ at _ZTV3gooE = internal unnamed_addr constant { { [3 x i32] } } { { [3 x i32] } { [3 x i32] [i32 0, i32 trunc (i64 sub (i64 ptrtoint (ptr @_fake_rtti_data to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [3 x i32] }, ptr @_ZTV3gooE, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @foo to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [3 x i32] }, ptr @_ZTV3gooE, i32 0, i32 0, i32 2) to i64)) to i32)] } }, align 4
+
+define internal ptr @foo(ptr %this) {
+  %1 = load ptr, ptr @_ZTV3gooE, align 8
+  ret ptr %1
+}
diff --git a/bolt/test/X86/skip-non-vfuncptr-reloc-in-relative-vtable.cpp b/bolt/test/X86/skip-non-vfuncptr-reloc-in-relative-vtable.cpp
deleted file mode 100644
index d7062022b3100..0000000000000
--- a/bolt/test/X86/skip-non-vfuncptr-reloc-in-relative-vtable.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// Test the fix that BOLT should skip speical handling of any non virtual
-// function pointer relocations in relative vtable.
-
-// RUN: %clang -fuse-ld=lld -o %t.so %s -Wl,-q \
-// RUN:     -fexperimental-relative-c++-abi-vtables
-// RUN: llvm-bolt %t.so -o %t.bolted.so
-
-extern "C" unsigned long long _ZTVN10__cxxabiv117__class_type_infoE = 0;
-extern "C" unsigned long long _ZTVN10__cxxabiv120__si_class_type_infoE = 0;
-
-class A {
-public:
-  virtual void foo() {}
-};
-
-class B : public A {
-  virtual void foo() override {}
-};
-
-int main() {
-  B b;
-  A *p = &b;
-  p->foo();
-  return 0;
-}

>From 8628cdaa3b8bcc28bc2f53125a0ee86f30ef9d9f Mon Sep 17 00:00:00 2001
From: YongKang Zhu <yongzhu at fb.com>
Date: Mon, 28 Apr 2025 19:02:03 -0700
Subject: [PATCH 4/4] Update test - replace '.ll' with '.s'

---
 ...p-non-vfuncptr-reloc-in-relative-vtable.ll | 17 ---------
 ...ip-non-vfuncptr-reloc-in-relative-vtable.s | 35 +++++++++++++++++++
 2 files changed, 35 insertions(+), 17 deletions(-)
 delete mode 100644 bolt/test/AArch64/skip-non-vfuncptr-reloc-in-relative-vtable.ll
 create mode 100644 bolt/test/AArch64/skip-non-vfuncptr-reloc-in-relative-vtable.s

diff --git a/bolt/test/AArch64/skip-non-vfuncptr-reloc-in-relative-vtable.ll b/bolt/test/AArch64/skip-non-vfuncptr-reloc-in-relative-vtable.ll
deleted file mode 100644
index 05c2cedd5e99e..0000000000000
--- a/bolt/test/AArch64/skip-non-vfuncptr-reloc-in-relative-vtable.ll
+++ /dev/null
@@ -1,17 +0,0 @@
-; Test the fix that BOLT should skip speical handling of any non virtual
-; function pointer relocations in relative vtable.
-
-; RUN: llc --filetype=obj -mtriple=aarch64-none-linux-gnu \
-; RUN:     --relocation-model=pic -o %t.o %s
-; RUN: %clang %cxxflags -fuse-ld=lld %t.o -o %t.so -Wl,-q
-; RUN: llvm-bolt %t.so -o %t.bolted.so
-
-$_fake_rtti_data = comdat any
- at _fake_rtti_data = internal unnamed_addr constant [16 x i8] c"_FAKE_RTTI_DATA_", comdat, align 8
-
- at _ZTV3gooE = internal unnamed_addr constant { { [3 x i32] } } { { [3 x i32] } { [3 x i32] [i32 0, i32 trunc (i64 sub (i64 ptrtoint (ptr @_fake_rtti_data to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [3 x i32] }, ptr @_ZTV3gooE, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @foo to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [3 x i32] }, ptr @_ZTV3gooE, i32 0, i32 0, i32 2) to i64)) to i32)] } }, align 4
-
-define internal ptr @foo(ptr %this) {
-  %1 = load ptr, ptr @_ZTV3gooE, align 8
-  ret ptr %1
-}
diff --git a/bolt/test/AArch64/skip-non-vfuncptr-reloc-in-relative-vtable.s b/bolt/test/AArch64/skip-non-vfuncptr-reloc-in-relative-vtable.s
new file mode 100644
index 0000000000000..bf5ed40a48649
--- /dev/null
+++ b/bolt/test/AArch64/skip-non-vfuncptr-reloc-in-relative-vtable.s
@@ -0,0 +1,35 @@
+// Test the fix that BOLT should skip speical handling of any non virtual
+// function pointer relocations in relative vtable.
+
+// RUN: llvm-mc -filetype=obj -triple aarch64-unknown-gnu %s -o %t.o
+// RUN: %clang %cxxflags -fuse-ld=lld %t.o -o %t.so -Wl,-q
+// RUN: llvm-bolt %t.so -o %t.bolted.so
+
+	.text
+	.p2align	2
+	.type	foo, at function
+foo:
+	.cfi_startproc
+	adrp	x8, _ZTV3gooE
+	add	x8, x8, :lo12:_ZTV3gooE
+	ldr	x0, [x8]
+	ret
+.Lfunc_end0:
+	.size	foo, .Lfunc_end0-foo
+	.cfi_endproc
+
+	.type	_fake_rtti_data, at object
+	.section	.rodata.cst16._fake_rtti_data,"aMG", at progbits,16,_fake_rtti_data,comdat
+	.p2align	3, 0x0
+_fake_rtti_data:
+	.ascii	"_FAKE_RTTI_DATA_"
+	.size	_fake_rtti_data, 16
+
+	.type	_ZTV3gooE, at object
+	.section	.rodata,"a", at progbits
+	.p2align	2, 0x0
+_ZTV3gooE:
+	.word	0
+	.word	_fake_rtti_data-_ZTV3gooE-8
+	.word	foo at PLT-_ZTV3gooE-8
+	.size	_ZTV3gooE, 12



More information about the llvm-commits mailing list