[llvm] [BOLT] Preserve dynamic relocations for LSDA type tables (PR #220407)

Farid Zakaria via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 1 15:46:04 PDT 2026


================
@@ -4491,6 +4540,51 @@ void BinaryFunction::updateOutputValues(const BOLTLinker &Linker) {
   setOutputAddress(SymbolInfo->Address);
   setOutputSize(SymbolInfo->Size);
 
+  // Move the dynamic relocations that supplied LSDA type table entries onto
+  // the re-emitted table. Otherwise the loader keeps patching the original
+  // copy, which is no longer read, and a zero entry means catch-all to the
+  // personality routine.
+  //
+  // The emitted section has no input address, so match it on the output range.
+  auto findOutputSection = [&](uint64_t Address) -> BinarySection * {
+    for (BinarySection &Section : BC.sections()) {
+      const uint64_t Start = Section.getOutputAddress();
+      if (Start && Address >= Start &&
+          Address < Start + Section.getOutputSize())
+        return &Section;
+    }
+    return nullptr;
+  };
+
+  for (auto &KV : getLSDATypeTableDynRelocs()) {
+    LSDATypeTableDynRelocTy &DynReloc = KV.second;
+    if (DynReloc.OutputLabels.empty())
+      continue;
+
+    // The relocation is moved, not copied: .rela.dyn is rewritten in place and
+    // cannot grow. SplitFunctions keeps the EH ranges of such a function in a
+    // single fragment so that only one copy of the table is emitted.
+    assert(DynReloc.OutputLabels.size() == 1 &&
----------------
fzakaria wrote:

Without this we needed to grow the `.rela.dyn` section and doing so looked like a lot more work; so it was easier to add this guard & constraint. 

The relocation count isn't known until after section addresses are assigned, so a grown .rela.dyn has to be allocated late in rewriteFile with a new PT_LOAD. which I was led to believe would be too much change to the codebase.

We can explore it if need be though.

https://github.com/llvm/llvm-project/pull/220407


More information about the llvm-commits mailing list