[ELF] scanRelocations: support .crel.eh_frame
authorFangrui Song <i@maskray.me>
Thu, 8 Aug 2024 19:02:44 +0000 (12:02 -0700)
committerTobias Hieta <tobias@hieta.se>
Sat, 10 Aug 2024 10:15:26 +0000 (12:15 +0200)
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
lld/test/ELF/crel.s

index e19b1e6c8efb80d35cc4313153dc51f39a8467f8..707768dee6d388ffdbc2e39609191e7e235ce1fd 100644 (file)
@@ -459,7 +459,8 @@ private:
 // 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())
index d7c87be9a54025751240df81b4583cb4701b3921..1de3f314fc6770c3e4785891d2390f7006e9195e 100644 (file)
@@ -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>
 
 # 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