[clang] [flang] [libcxx] [llvm] [compiler-rt] [clang-tools-extra] [BOLT] Read .rela.dyn in static non-pie binary (PR #71635)

Vladislav Khmelevsky via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 9 00:09:41 PST 2023


https://github.com/yota9 updated https://github.com/llvm/llvm-project/pull/71635

>From 1006708c3cff79b9504beb26ea82cadaec3bb594 Mon Sep 17 00:00:00 2001
From: Vladislav Khmelevsky <och95 at yandex.ru>
Date: Wed, 8 Nov 2023 11:57:16 +0400
Subject: [PATCH] [BOLT] Read .rela.dyn in static non-pie binary

Static non-pie binary doesn't have DYNAMIC segment and BOLT skips
reading .rela.dyn segment because of it. But such binaries might have
this section for example to store IFUNC relocation which is resolved
by linked-in startup files, so force reading this section for static
executables.
---
 bolt/include/bolt/Rewrite/RewriteInstance.h |  1 +
 bolt/lib/Rewrite/RewriteInstance.cpp        | 13 +++++++++++
 bolt/test/AArch64/ifunc.c                   | 24 +++++++++++++++++++--
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/bolt/include/bolt/Rewrite/RewriteInstance.h b/bolt/include/bolt/Rewrite/RewriteInstance.h
index 2a421c5cfaa4f89..6e9af61d76e30f6 100644
--- a/bolt/include/bolt/Rewrite/RewriteInstance.h
+++ b/bolt/include/bolt/Rewrite/RewriteInstance.h
@@ -421,6 +421,7 @@ class RewriteInstance {
 
   /// Common section names.
   static StringRef getEHFrameSectionName() { return ".eh_frame"; }
+  static StringRef getRelaDynSectionName() { return ".rela.dyn"; }
 
   /// An instance of the input binary we are processing, externally owned.
   llvm::object::ELFObjectFileBase *InputFile;
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index abdbb79e8eb60ef..2d7df15025e3685 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -2139,6 +2139,19 @@ void RewriteInstance::processDynamicRelocations() {
   }
 
   // The rest of dynamic relocations - DT_RELA.
+  // The static executable might have .rela.dyn secion and not have PT_DYNAMIC
+  if (!DynamicRelocationsSize && BC->IsStaticExecutable) {
+    ErrorOr<BinarySection &> DynamicRelSectionOrErr =
+        BC->getUniqueSectionByName(getRelaDynSectionName());
+    if (DynamicRelSectionOrErr) {
+      DynamicRelocationsAddress = DynamicRelSectionOrErr->getAddress();
+      DynamicRelocationsSize = DynamicRelSectionOrErr->getSize();
+      const SectionRef &SectionRef = DynamicRelSectionOrErr->getSectionRef();
+      DynamicRelativeRelocationsCount = std::distance(
+          SectionRef.relocation_begin(), SectionRef.relocation_end());
+    }
+  }
+
   if (DynamicRelocationsSize > 0) {
     ErrorOr<BinarySection &> DynamicRelSectionOrErr =
         BC->getSectionForAddress(*DynamicRelocationsAddress);
diff --git a/bolt/test/AArch64/ifunc.c b/bolt/test/AArch64/ifunc.c
index dea2cf6bd543f0a..8edb913ee70d5c0 100644
--- a/bolt/test/AArch64/ifunc.c
+++ b/bolt/test/AArch64/ifunc.c
@@ -7,6 +7,20 @@
 // RUN: llvm-bolt %t.O0.exe -o %t.O0.bolt.exe \
 // RUN:   --print-disasm --print-only=_start | \
 // RUN:   FileCheck --check-prefix=O0_CHECK %s
+// RUN: llvm-readelf -aW %t.O0.bolt.exe | \
+// RUN:   FileCheck --check-prefix=REL_CHECK %s
+
+// Non-pie static executable doesn't generate PT_DYNAMIC, check relocation
+// is readed successfully and IPLT trampoline has been identified by bolt.
+// RUN: %clang %cflags -nostdlib -O3 %s -fuse-ld=lld -no-pie \
+// RUN:   -o %t.O3_nopie.exe -Wl,-q
+// RUN: llvm-readelf -l %t.O3_nopie.exe | \
+// RUN:   FileCheck --check-prefix=NON_DYN_CHECK %s
+// RUN: llvm-bolt %t.O3_nopie.exe -o %t.O3_nopie.bolt.exe  \
+// RUN:   --print-disasm --print-only=_start | \
+// RUN:   FileCheck --check-prefix=O3_CHECK %s
+// RUN: llvm-readelf -aW %t.O3_nopie.bolt.exe | \
+// RUN:   FileCheck --check-prefix=REL_CHECK %s
 
 // With -O3 direct call is performed on IPLT trampoline. IPLT trampoline
 // doesn't have associated symbol. The ifunc symbol has the same address as
@@ -16,6 +30,8 @@
 // RUN: llvm-bolt %t.O3_pie.exe -o %t.O3_pie.bolt.exe  \
 // RUN:   --print-disasm --print-only=_start | \
 // RUN:   FileCheck --check-prefix=O3_CHECK %s
+// RUN: llvm-readelf -aW %t.O3_pie.bolt.exe | \
+// RUN:   FileCheck --check-prefix=REL_CHECK %s
 
 // Check that IPLT trampoline located in .plt section are normally handled by
 // BOLT. The gnu-ld linker doesn't use separate .iplt section.
@@ -24,12 +40,16 @@
 // RUN: llvm-bolt %t.iplt_O3_pie.exe -o %t.iplt_O3_pie.bolt.exe  \
 // RUN:   --print-disasm --print-only=_start  | \
 // RUN:   FileCheck --check-prefix=O3_CHECK %s
+// RUN: llvm-readelf -aW %t.iplt_O3_pie.bolt.exe | \
+// RUN:   FileCheck --check-prefix=REL_CHECK %s
+
+// NON_DYN_CHECK-NOT: DYNAMIC
 
 // O0_CHECK: adr x{{[0-9]+}}, ifoo
 // O3_CHECK: b "{{resolver_foo|ifoo}}{{.*}}@PLT"
 
-#include <stdio.h>
-#include <string.h>
+// REL_CHECK: R_AARCH64_IRELATIVE [[#%x,REL_SYMB_ADDR:]]
+// REL_CHECK: [[#REL_SYMB_ADDR]] {{.*}} FUNC {{.*}} resolver_foo
 
 static void foo() {}
 



More information about the cfe-commits mailing list