[lld] Discard invalid "DW.ref.__gxx_personality_v0" pieces in rela.eh_frame (PR #158590)

via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 15 02:39:42 PDT 2025


https://github.com/MaooJian created https://github.com/llvm/llvm-project/pull/158590

When the "DW.ref.__gxx_personality_v0" section is invalid, the generated relocation may overlap the FDE length. Discard such relocation entries to avoid corrupting the .eh_frame data.

>From 5ed881dfe8917516b6daef5b8859333d32c3dcab Mon Sep 17 00:00:00 2001
From: MaoJian <maojian16 at huawei.com>
Date: Mon, 15 Sep 2025 17:27:48 +0800
Subject: [PATCH] Discard invalid "DW.ref.__gxx_personality_v0" pieces in
 rela.eh_frame

When the "DW.ref.__gxx_personality_v0" section is invalid, the generated relocation may overlap the FDE length. Discard such relocation entries to avoid corrupting the .eh_frame data.
---
 lld/ELF/InputSection.cpp | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index ea6bcc5bb272b..54396cd0515ed 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -491,6 +491,33 @@ void InputSection::copyRelocations(Ctx &ctx, uint8_t *buf,
     p->setSymbolAndType(ctx.in.symTab->getSymbolIndex(sym), type,
                         ctx.arg.isMips64EL);
 
+    // Discard the invalid pieces among those named "DW.ref.__gxx_personality_v0".
+    StringRef symName = sym.getName();
+    if (symName == "DW.ref.__gxx_personality_v0") {
+      if (auto *es = dyn_cast<EhInputSection>(sec)) {
+        auto it = partition_point(es->fdes, [=](EhSectionPiece p) {
+          return p.inputOff <= rel.offset;
+        });
+
+        if (it == es->fdes.begin() ||
+            it[-1].inputOff + it[-1].size <= rel.offset) {
+          it = partition_point(es->cies, [=](EhSectionPiece p) {
+            return p.inputOff <= rel.offset;
+          });
+          if (it == es->cies.begin()) {
+            // invalid piece
+            p->setSymbolAndType(0, 0, false);
+            continue;
+          }
+        }
+
+        if (it[-1].outputOff == -1) {
+          p->setSymbolAndType(0, 0, false);
+          continue;
+        }
+      }
+    }
+    
     if (sym.type == STT_SECTION) {
       // We combine multiple section symbols into only one per
       // section. This means we have to update the addend. That is



More information about the llvm-commits mailing list