[lld] [ELF] Support relocatable files using CREL (PR #98115)

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 26 09:02:54 PDT 2024


================
@@ -592,6 +608,113 @@ static void finalizeShtGroup(OutputSection *os, InputSection *section) {
   os->size = (1 + seen.size()) * sizeof(uint32_t);
 }
 
+template <class uint>
+LLVM_ATTRIBUTE_ALWAYS_INLINE static void
+encodeOneCrel(raw_svector_ostream &os, uint &outOffset, uint32_t &outSymidx,
+              uint32_t &outType, uint &outAddend, uint offset,
+              const Symbol &sym, uint32_t type, uint addend) {
+  const auto deltaOffset = static_cast<uint64_t>(offset - outOffset);
+  outOffset = offset;
+  int64_t symidx = in.symTab->getSymbolIndex(sym);
+  if (sym.type == STT_SECTION) {
+    auto *d = dyn_cast<Defined>(&sym);
+    if (d) {
+      SectionBase *section = d->section;
+      assert(section->isLive());
+      addend = sym.getVA(addend) - section->getOutputSection()->addr;
+    } else {
+      // Encode R_*_NONE(symidx=0).
+      symidx = type = addend = 0;
+    }
+  }
+
+  // Similar to llvm::ELF::encodeCrel.
+  uint8_t b = deltaOffset * 8 + (outSymidx != symidx) +
+              (outType != type ? 2 : 0) + (outAddend != addend ? 4 : 0);
+  if (deltaOffset < 0x10) {
+    os << char(b);
+  } else {
+    os << char(b | 0x80);
+    encodeULEB128(deltaOffset >> 4, os);
+  }
+  if (b & 1) {
+    encodeSLEB128(static_cast<int32_t>(symidx - outSymidx), os);
+    outSymidx = symidx;
+  }
+  if (b & 2) {
+    encodeSLEB128(static_cast<int32_t>(type - outType), os);
+    outType = type;
+  }
+  if (b & 4) {
+    encodeSLEB128(std::make_signed_t<uint>(addend - outAddend), os);
+    outAddend = addend;
+  }
+}
+
+template <class ELFT>
+static size_t relToCrel(raw_svector_ostream &os, typename ELFT::uint &outOffset,
+                        uint32_t &outSymidx, uint32_t &outType,
+                        typename ELFT::uint &outAddend, InputSection *relSec,
+                        InputSectionBase *sec) {
+  const auto &file = *cast<ELFFileBase>(relSec->file);
+  if (relSec->type == SHT_REL) {
----------------
smithp35 wrote:

Is this is a temporary limitation or a fundamental one?

If it is the latter it may be worth erroring at a much earlier point, likely in commitSection.

I'm guessing from the comment below
```
// Convert REL[A] to CREL.
```
That this is a temporary limitation?



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


More information about the llvm-commits mailing list