[llvm-branch-commits] [lld] release/19.x: [ELF] scanRelocations: support .crel.eh_frame (PR #102523)

Tobias Hieta via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sat Aug 10 03:15:33 PDT 2024


https://github.com/tru updated https://github.com/llvm/llvm-project/pull/102523

>From 7aae895c245a00a6bb97d05c966765de825a54d1 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Thu, 8 Aug 2024 00:57:43 -0700
Subject: [PATCH 1/2] [ELF] .llvm.call-graph-profile: support CREL

https://reviews.llvm.org/D105217 added RELA support. This patch adds
CREL support.

(cherry picked from commit 0766a59be3256e83a454a089f01215d6c7f94a48)
---
 lld/ELF/Driver.cpp               | 9 +++++++++
 lld/test/ELF/cgprofile-rela.test | 6 +++++-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 40e095a133d953..eb6734dfd458d5 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -991,6 +991,15 @@ processCallGraphRelocations(SmallVector<uint32_t, 32> &symbolIndices,
   for (size_t i = 0, e = objSections.size(); i < e; ++i) {
     const Elf_Shdr_Impl<ELFT> &sec = objSections[i];
     if (sec.sh_info == inputObj->cgProfileSectionIndex) {
+      if (sec.sh_type == SHT_CREL) {
+        auto crels =
+            CHECK(obj.crels(sec), "could not retrieve cg profile rela section");
+        for (const auto &rel : crels.first)
+          symbolIndices.push_back(rel.getSymbol(false));
+        for (const auto &rel : crels.second)
+          symbolIndices.push_back(rel.getSymbol(false));
+        break;
+      }
       if (sec.sh_type == SHT_RELA) {
         ArrayRef<typename ELFT::Rela> relas =
             CHECK(obj.relas(sec), "could not retrieve cg profile rela section");
diff --git a/lld/test/ELF/cgprofile-rela.test b/lld/test/ELF/cgprofile-rela.test
index 141dfd4c65b1ea..87dad02940b98b 100644
--- a/lld/test/ELF/cgprofile-rela.test
+++ b/lld/test/ELF/cgprofile-rela.test
@@ -8,6 +8,10 @@
 # RUN: ld.lld --no-call-graph-profile-sort %t.o -o %t
 # RUN: llvm-nm --no-sort %t | FileCheck %s --check-prefix=NO-CG
 
+# RUN: yaml2obj -DTYPE=SHT_CREL %s -o %tcrel.o
+# RUN: ld.lld --call-graph-profile-sort=hfsort %tcrel.o -o %t
+# RUN: llvm-nm --no-sort %t | FileCheck %s
+
 # CHECK: 0000000000201124 t D
 # CHECK: 0000000000201122 t C
 # CHECK: 0000000000201128 t B
@@ -60,7 +64,7 @@ Sections:
       - Weight: 30
       - Weight: 90
   - Name: .rela.llvm.call-graph-profile
-    Type: SHT_RELA
+    Type: [[TYPE=SHT_RELA]]
     Info: .llvm.call-graph-profile
     Relocations:
       - Offset: 0x0

>From 39746ee0048e1f4891d2e2b58e7c7583df43c3bc Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Thu, 8 Aug 2024 12:02:44 -0700
Subject: [PATCH 2/2] [ELF] scanRelocations: support .crel.eh_frame

Follow-up to #98115. For EhInputSection, RelocationScanner::scan calls
sortRels, which doesn't support the CREL iterator. We should set
supportsCrel to false to ensure that the initial_location fields in
.eh_frame FDEs are relocated.

(cherry picked from commit a821fee312d15941174827a70cb534c2f2fe1177)
---
 lld/ELF/Relocations.cpp | 10 ++++++----
 lld/test/ELF/crel.s     |  8 ++++++++
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index e19b1e6c8efb80..707768dee6d388 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -459,7 +459,8 @@ class OffsetGetter {
 // InputSectionBase.
 class RelocationScanner {
 public:
-  template <class ELFT> void scanSection(InputSectionBase &s);
+  template <class ELFT>
+  void scanSection(InputSectionBase &s, bool isEH = false);
 
 private:
   InputSectionBase *sec;
@@ -1617,10 +1618,11 @@ void RelocationScanner::scan(Relocs<RelTy> rels) {
                       });
 }
 
-template <class ELFT> void RelocationScanner::scanSection(InputSectionBase &s) {
+template <class ELFT>
+void RelocationScanner::scanSection(InputSectionBase &s, bool isEH) {
   sec = &s;
   getter = OffsetGetter(s);
-  const RelsOrRelas<ELFT> rels = s.template relsOrRelas<ELFT>();
+  const RelsOrRelas<ELFT> rels = s.template relsOrRelas<ELFT>(!isEH);
   if (rels.areRelocsCrel())
     scan<ELFT>(rels.crels);
   else if (rels.areRelocsRel())
@@ -1658,7 +1660,7 @@ template <class ELFT> void elf::scanRelocations() {
     RelocationScanner scanner;
     for (Partition &part : partitions) {
       for (EhInputSection *sec : part.ehFrame->sections)
-        scanner.template scanSection<ELFT>(*sec);
+        scanner.template scanSection<ELFT>(*sec, /*isEH=*/true);
       if (part.armExidx && part.armExidx->isLive())
         for (InputSection *sec : part.armExidx->exidxSections)
           if (sec->isLive())
diff --git a/lld/test/ELF/crel.s b/lld/test/ELF/crel.s
index d7c87be9a54025..1de3f314fc6770 100644
--- a/lld/test/ELF/crel.s
+++ b/lld/test/ELF/crel.s
@@ -5,6 +5,7 @@
 # RUN: ld.lld -pie a.o b.o -o out
 # RUN: llvm-objdump -d out | FileCheck %s
 # RUN: llvm-readelf -Srs out | FileCheck %s --check-prefix=RELOC
+# RUN: llvm-dwarfdump --eh-frame out | FileCheck %s --check-prefix=UNWIND
 
 # CHECK:       <_start>:
 # CHECK-NEXT:    callq {{.*}} <foo>
@@ -18,6 +19,13 @@
 
 # RELOC:  {{0*}}[[#DATA+8]]  0000000000000008 R_X86_64_RELATIVE [[#%x,DATA+0x8000000000000000]]
 
+# RELOC:      00000000000012f4     0 NOTYPE  GLOBAL DEFAULT [[#]] _start
+# RELOC-NEXT: 00000000000012fe     0 NOTYPE  GLOBAL DEFAULT [[#]] foo
+
+## initial_location fields in FDEs are correctly relocated.
+# UNWIND: 00000018 00000010 0000001c FDE cie=00000000 pc=000012f4...000012fe
+# UNWIND: 0000002c 00000010 00000030 FDE cie=00000000 pc=000012fe...0000130c
+
 # RUN: ld.lld -pie --emit-relocs a.o b.o -o out1
 # RUN: llvm-objdump -dr out1 | FileCheck %s --check-prefix=CHECKE
 # RUN: llvm-readelf -Sr out1 | FileCheck %s --check-prefix=RELOCE



More information about the llvm-branch-commits mailing list