[lld] [lld][elf] add safe-thunks in ELF (PR #126695)

via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 11 19:56:58 PST 2025


================
@@ -459,6 +467,58 @@ static void combineRelocHashes(unsigned cnt, InputSection *isec,
   isec->eqClass[(cnt + 1) % 2] = hash | (1U << 31);
 }
 
+// Given a range of identical icfInputs, replace address significant functions
+// with a thunk that is just a direct branch to the first function in the
+// series. This way we keep only one main body of the function but we still
+// retain the address uniqueness of relevant functions by having them be a
+// direct branch thunk rather than containing a full copy of the actual function
+// body.
+template <class ELFT>
+void ICF<ELFT>::applySafeThunksToRange(size_t begin, size_t end) {
+  InputSection *masterIsec = sections[begin];
+
+  uint32_t thunkSize = ctx.target->getICFSafeThunkSize();
+  // If the functions we're dealing with are smaller than the thunk size, then
+  // just leave them all as-is - creating thunks would be a net loss.
+  if (masterIsec->getSize() <= thunkSize)
+    return;
+
+  // Find the symbol to create the thunk for.
+  Symbol *masterSym = nullptr;
+  for (Symbol *sym : masterIsec->file->getSymbols()) {
+    if (auto *d = dyn_cast<Defined>(sym)) {
+      if (d->section == masterIsec) {
+        masterSym = sym;
+        break;
+      }
+    }
+  }
+
+  if (!masterSym)
+    return;
+
+  for (size_t i = begin + 1; i < end; ++i) {
+    InputSection *isec = sections[i];
+    if (!isec->keepUnique)
+      break;
+
+    auto *thunk = make<InputSection>(*isec);
+    ctx.target->initICFSafeThunkBody(thunk, masterSym);
+    thunk->markLive();
+    auto *osec = isec->getParent();
+    auto *isd = cast<InputSectionDescription>(osec->commands.back());
+    isd->sections.push_back(thunk);
+    osec->commitSection(thunk);
+    isec->repl = thunk;
+    isec->markDead();
+
+    for (Symbol *sym : thunk->file->getSymbols())
+      if (auto *d = dyn_cast<Defined>(sym))
+        if (d->section == isec)
+          d->size = thunkSize;
----------------
alx32 wrote:

I think we also want to set offset to 0.

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


More information about the llvm-commits mailing list