[llvm] [Object][GOFF] Support RLD records (PR #216780)

James Henderson via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 17 08:52:33 PDT 2026


================
@@ -759,3 +765,115 @@ basic_symbol_iterator GOFFObjectFile::symbol_end() const {
   DataRefImpl Symb;
   return basic_symbol_iterator(SymbolRef(Symb, this));
 }
+
+inline constexpr uint8_t SAME_R_ID = 0x80;
+inline constexpr uint8_t SAME_P_ID = 0x40;
+inline constexpr uint8_t SAME_OFFSET = 0x20;
+inline constexpr uint8_t EXT_ATTR_PRESENT = 0x04;
+inline constexpr uint8_t BYTE_OFFSET_8 = 0x02;
+
+// Populate the relocation entries.
+void GOFFObjectFile::setRelocationData(const uint8_t *RldRecord) {
+  SmallVector<uint8_t, 8> RelocationData;
+  int DataIndex = 6;
+  uint16_t DataLength;
+  RLDRecord::getDataLength(RldRecord, DataLength);
+
+  // The record is already flattened if it's continued.
+  const uint8_t *RldI = RldRecord + DataIndex;
+  const uint8_t *RldE = RldI + DataLength;
+  uint32_t CurREsdId = 0;
+  uint32_t CurPEsdId = 0;
+  uint64_t CurPOffset = 0;
+  for (const uint8_t *Rld = RldI; Rld < RldE;) {
+    GOFFRelEntry RelEntry;
+    uint8_t Flags = Rld[0];
+    int32_t Length = 8;
+    if (!(Flags & SAME_R_ID)) {
+      CurREsdId = support::endian::read32be(&Rld[Length]);
+      Length += 4;
+    }
+    if (!(Flags & SAME_P_ID)) {
+      CurPEsdId = support::endian::read32be(&Rld[Length]);
+      Length += 4;
+    }
+    if (!(Flags & SAME_OFFSET)) {
+      if (Flags & BYTE_OFFSET_8) {
+        CurPOffset = support::endian::read64be(&Rld[Length]);
+        Length += 8;
+      } else {
+        CurPOffset = support::endian::read32be(&Rld[Length]);
+        Length += 4;
+      }
+    }
+    if (Flags & EXT_ATTR_PRESENT)
+      Length += 8;
+
+    RelEntry.PEsdId = CurPEsdId;
+    RelEntry.REsdId = CurREsdId;
+    RelEntry.POffset = CurPOffset;
+    RelEntry.RelType = getRldType(Rld);
+    RelEntries.emplace_back(RelEntry);
+
+    Rld += Length;
+    assert(Rld <= RldE && "RLD length?");
+  }
+}
+
+void GOFFObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
+  for (size_t I = Rel.d.b + 1, E = RelEntries.size(); I < E; ++I) {
+    const GOFFRelEntry &RelEntry = RelEntries[I];
+    if (Rel.d.a == RelEntry.PEsdId) {
+      Rel.d.b = I;
+      return;
+    }
+  }
+
+  Rel.d.b = 0;
+}
+
+uint64_t GOFFObjectFile::getRelocationOffset(DataRefImpl Rel) const {
+  assert(Rel.d.b > 0 && Rel.d.b < RelEntries.size() &&
+         "Rel Index out of boundary");
+  const GOFFRelEntry &RelEntry = RelEntries[Rel.d.b];
+  return RelEntry.POffset;
+}
+
+symbol_iterator GOFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
+  assert(Rel.d.b > 0 && Rel.d.b < RelEntries.size() &&
+         "Rel Index out of boundary");
+  const GOFFRelEntry &RelEntry = RelEntries[Rel.d.b];
+  DataRefImpl RefSym;
+  RefSym.d.a = RelEntry.REsdId;
+  return basic_symbol_iterator(SymbolRef(RefSym, this));
+}
+
+uint64_t GOFFObjectFile::getRelocationType(DataRefImpl Rel) const {
+  assert(Rel.d.b > 0 && Rel.d.b < RelEntries.size() &&
+         "Rel Index out of boundary");
+  const GOFFRelEntry &RelEntry = RelEntries[Rel.d.b];
+  return RelEntry.RelType;
+}
+
+void GOFFObjectFile::getRelocationTypeName(
+    DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
+  uint64_t RelType = getRelocationType(Rel);
+  char Buf[16];
+  sprintf(Buf, "R_%08lx", RelType);
----------------
jh7370 wrote:

Perhaps we should use something more C++ like `stringstream` or `formatv`?

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


More information about the llvm-commits mailing list