[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:40:41 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld-elf
@llvm/pr-subscribers-lld
Author: MaoJian (MaooJian)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/158590.diff
1 Files Affected:
- (modified) lld/ELF/InputSection.cpp (+27)
``````````diff
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
``````````
</details>
https://github.com/llvm/llvm-project/pull/158590
More information about the llvm-commits
mailing list