[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