[llvm] [Object][GOFF] Support RLD records (PR #216780)
Shimin Cui via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 26 06:34:30 PDT 2026
https://github.com/scui-ibm updated https://github.com/llvm/llvm-project/pull/216780
>From 17b495f4549040849ae0e1a645578ebbe5b7042d Mon Sep 17 00:00:00 2001
From: Shimin Cui <scui at ca.ibm.com>
Date: Fri, 14 Aug 2026 22:05:09 +0000
Subject: [PATCH 1/3] [Object][GOFF] Support RLD records
---
llvm/include/llvm/Object/GOFF.h | 10 ++
llvm/include/llvm/Object/GOFFObjectFile.h | 65 +++++++---
llvm/lib/Object/GOFFObjectFile.cpp | 123 ++++++++++++++++++-
llvm/unittests/Object/GOFFObjectFileTest.cpp | 25 ++++
4 files changed, 208 insertions(+), 15 deletions(-)
diff --git a/llvm/include/llvm/Object/GOFF.h b/llvm/include/llvm/Object/GOFF.h
index bae7d6d2aba46..145c354a307cc 100644
--- a/llvm/include/llvm/Object/GOFF.h
+++ b/llvm/include/llvm/Object/GOFF.h
@@ -290,6 +290,16 @@ class ESDRecord : public Record {
}
};
+class RLDRecord : public Record {
+public:
+ LLVM_ABI static Error getData(const uint8_t *Record,
+ SmallString<256> &CompleteData);
+
+ static void getDataLength(const uint8_t *Record, uint16_t &Length) {
+ get<uint16_t>(Record, 4, Length);
+ }
+};
+
class ENDRecord : public Record {
public:
LLVM_ABI static Error getData(const uint8_t *Record,
diff --git a/llvm/include/llvm/Object/GOFFObjectFile.h b/llvm/include/llvm/Object/GOFFObjectFile.h
index a07f3edf17d07..0bfbbc8d7acd6 100644
--- a/llvm/include/llvm/Object/GOFFObjectFile.h
+++ b/llvm/include/llvm/Object/GOFFObjectFile.h
@@ -29,11 +29,51 @@ namespace llvm {
namespace object {
+// RLD entry with all populated fields.
+struct GOFFRelEntry {
+ uint32_t REsdId;
+ uint32_t PEsdId;
+ uint64_t POffset;
+ uint64_t RelType;
+
+ DataRefImpl RefSymb; // Symbol referred to.
+};
+
+// GOFFRelEntry::RelType is computed based on RLD fields at offset 1, 2, 4,
+// and 5.
+inline uint64_t getRldType(uint8_t *Rld) {
+ return Rld[1] + (Rld[2] << 8) + (Rld[4] << 16) + (Rld[5] << 24);
+}
+
+// Getters for RLD fields based on GOFFRelEntry::RelType.
+inline GOFF::RLDReferenceType getRLDReferenceType(uint64_t RelType) {
+ return static_cast<GOFF::RLDReferenceType>((RelType >> 4) & 0x0000000F);
+}
+inline GOFF::RLDReferentType getRLDReferentType(uint64_t RelType) {
+ return static_cast<GOFF::RLDReferentType>((RelType) & 0x0000000F);
+}
+inline GOFF::RLDAction getRLDAction(uint64_t RelType) {
+ return static_cast<GOFF::RLDAction>((RelType >> (8 + 1)) & 0x0000007F);
+}
+inline GOFF::RLDFetchStore getRLDFetchStore(uint64_t RelType) {
+ return static_cast<GOFF::RLDFetchStore>((RelType >> 8) & 0x00000001);
+}
+inline uint8_t getRLDTargetLength(uint64_t RelType) {
+ return static_cast<uint8_t>((RelType >> 16) & 0x000000FF);
+}
+inline uint8_t getRLDBitLength(uint64_t RelType) {
+ return static_cast<uint8_t>((RelType >> (24 + 5)) & 0x00000007);
+}
+inline uint8_t getRLDBitOffset(uint64_t RelType) {
+ return static_cast<uint8_t>((RelType >> 24) & 0x00000007);
+}
+
class LLVM_ABI GOFFObjectFile : public ObjectFile {
friend class GOFFSymbolRef;
IndexedMap<const uint8_t *> EsdPtrs; // Indexed by EsdId.
SmallVector<const uint8_t *, 256> TextPtrs;
+ SmallVector<GOFFRelEntry, 256> RelEntries;
mutable DenseMap<uint32_t, std::pair<size_t, std::unique_ptr<char[]>>>
EsdNamesCache;
@@ -58,6 +98,8 @@ class LLVM_ABI GOFFObjectFile : public ObjectFile {
int DataIndex, uint16_t DataLength,
const uint8_t *Record) const;
+ void setRelocationData(const uint8_t *RldRecord);
+
public:
// Get the flattened data structure
const SmallVector<std::pair<GOFF::RecordType, SmallVector<uint8_t>>> &
@@ -123,12 +165,8 @@ class LLVM_ABI GOFFObjectFile : public ObjectFile {
bool isSectionData(DataRefImpl Sec) const override;
bool isSectionBSS(DataRefImpl Sec) const override { return false; }
bool isSectionVirtual(DataRefImpl Sec) const override { return false; }
- relocation_iterator section_rel_begin(DataRefImpl Sec) const override {
- return relocation_iterator(RelocationRef(Sec, this));
- }
- relocation_iterator section_rel_end(DataRefImpl Sec) const override {
- return relocation_iterator(RelocationRef(Sec, this));
- }
+ relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_end(DataRefImpl Sec) const override;
const uint8_t *getSectionEdEsdRecord(DataRefImpl &Sec) const;
const uint8_t *getSectionPrEsdRecord(DataRefImpl &Sec) const;
@@ -137,15 +175,12 @@ class LLVM_ABI GOFFObjectFile : public ObjectFile {
uint32_t getSectionDefEsdId(DataRefImpl &Sec) const;
// RelocationRef.
- void moveRelocationNext(DataRefImpl &Rel) const override {}
- uint64_t getRelocationOffset(DataRefImpl Rel) const override { return 0; }
- symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override {
- DataRefImpl Temp;
- return basic_symbol_iterator(SymbolRef(Temp, this));
- }
- uint64_t getRelocationType(DataRefImpl Rel) const override { return 0; }
+ void moveRelocationNext(DataRefImpl &Rel) const override;
+ uint64_t getRelocationOffset(DataRefImpl Rel) const override;
+ symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+ uint64_t getRelocationType(DataRefImpl Rel) const override;
void getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const override {}
+ SmallVectorImpl<char> &Result) const override;
};
class GOFFSymbolRef : public SymbolRef {
@@ -158,6 +193,8 @@ class GOFFSymbolRef : public SymbolRef {
return cast<GOFFObjectFile>(BasicSymbolRef::getObject());
}
+ uint32_t getSymbolGOFFEsdId() const { return getRawDataRefImpl().d.a; }
+
Expected<uint32_t> getSymbolGOFFFlags() const {
return getObject()->getSymbolFlags(getRawDataRefImpl());
}
diff --git a/llvm/lib/Object/GOFFObjectFile.cpp b/llvm/lib/Object/GOFFObjectFile.cpp
index e18fcfa0f880c..4960aeaae8440 100644
--- a/llvm/lib/Object/GOFFObjectFile.cpp
+++ b/llvm/lib/Object/GOFFObjectFile.cpp
@@ -261,6 +261,11 @@ GOFFObjectFile::GOFFObjectFile(MemoryBufferRef Object, Error &Err)
SectionEntryImpl DummySection;
SectionList.emplace_back(DummySection); // Dummy entry at index 0.
+ // Dummy relocation entry at index 0.
+ GOFFRelEntry DummyRelEntry;
+ DummyRelEntry.PEsdId = 0;
+ RelEntries.emplace_back(DummyRelEntry);
+
for (const auto &[RecordType, Data] : FlattenedData) {
const uint8_t *I = Data.data();
switch (RecordType) {
@@ -323,7 +328,8 @@ GOFFObjectFile::GOFFObjectFile(MemoryBufferRef Object, Error &Err)
LLVM_DEBUG(dbgs() << " -- TXT\n");
break;
case GOFF::RT_RLD:
- LLVM_DEBUG(dbgs() << " -- RLD (GOFF record type) unhandled\n");
+ setRelocationData(I);
+ LLVM_DEBUG(dbgs() << " -- RLD\n");
break;
case GOFF::RT_LEN:
LLVM_DEBUG(dbgs() << " -- LEN (GOFF record type) unhandled\n");
@@ -759,3 +765,118 @@ basic_symbol_iterator GOFFObjectFile::symbol_end() const {
DataRefImpl Symb;
return basic_symbol_iterator(SymbolRef(Symb, this));
}
+
+// 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);
+ Expected<unsigned> BlocksConsumed =
+ getContinuousData(RelocationData, DataIndex, DataLength, RldRecord);
+ if (!BlocksConsumed)
+ llvm::handleAllErrors(BlocksConsumed.takeError(),
+ [](const llvm::ErrorInfoBase &EIB) {
+ llvm::errs() << "ERROR: " << EIB.message() << "\n";
+ });
+ assert(static_cast<size_t>(DataLength + DataIndex) == RelocationData.size() &&
+ "Inconsistent rld size");
+
+ uint8_t *RldI = reinterpret_cast<uint8_t *>(RelocationData.data());
+ uint8_t *RldE = RldI + RelocationData.size();
+ for (uint8_t *Rld = RldI + DataIndex; Rld < RldE;) {
+ GOFFRelEntry RelEntry;
+ uint8_t Flags = Rld[0];
+
+#define SAME_R_ID 0x80
+#define SAME_P_ID 0x40
+#define SAME_OFFSET 0x20
+#define EXT_ATTR_PRESENT 0x04
+#define BYTE_OFFSET_8 0x02
+
+ int32_t Length = 8;
+ if (!(Flags & SAME_R_ID)) {
+ RelEntry.REsdId = support::endian::read32be(&Rld[Length]);
+ Length += 4;
+ }
+ if (!(Flags & SAME_P_ID)) {
+ RelEntry.PEsdId = support::endian::read32be(&Rld[Length]);
+ Length += 4;
+ }
+ if (!(Flags & SAME_OFFSET)) {
+ if (Flags & BYTE_OFFSET_8) {
+ RelEntry.POffset = support::endian::read64be(&Rld[Length]);
+ Length += 8;
+ } else {
+ RelEntry.POffset = support::endian::read32be(&Rld[Length]);
+ Length += 4;
+ }
+ }
+ if (Flags & EXT_ATTR_PRESENT)
+ Length += 8;
+
+ RelEntry.RelType = getRldType(Rld);
+ RelEntry.RefSymb.d.a = RelEntry.REsdId;
+
+ 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];
+ return basic_symbol_iterator(SymbolRef(RelEntry.RefSymb, 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);
+ Result.append(Buf, Buf + strlen(Buf));
+}
+
+relocation_iterator GOFFObjectFile::section_rel_begin(DataRefImpl Sec) const {
+ DataRefImpl Rel;
+ Rel.d.a = getSectionDefEsdId(Sec);
+ Rel.d.b = 0;
+ moveRelocationNext(Rel);
+ return relocation_iterator(RelocationRef(Rel, this));
+}
+
+relocation_iterator GOFFObjectFile::section_rel_end(DataRefImpl Sec) const {
+ DataRefImpl Rel;
+ Rel.d.a = getSectionDefEsdId(Sec);
+ Rel.d.b = 0;
+ return relocation_iterator(RelocationRef(Rel, this));
+}
diff --git a/llvm/unittests/Object/GOFFObjectFileTest.cpp b/llvm/unittests/Object/GOFFObjectFileTest.cpp
index 89096a87618cc..555487a87dcb5 100644
--- a/llvm/unittests/Object/GOFFObjectFileTest.cpp
+++ b/llvm/unittests/Object/GOFFObjectFileTest.cpp
@@ -604,6 +604,16 @@ TEST_F(GOFFObjectFileTest, TXTConstruct) {
GOFFData[Pos + 30] = (char)0xde;
GOFFData[Pos + 31] = (char)0xf0;
+ // RLD record.
+ Pos = addNewRecord();
+ GOFFData[Pos] = (char)0x03;
+ GOFFData[Pos + 1] = (char)0x20;
+ GOFFData[Pos + 5] = (char)0x14; // Length.
+ GOFFData[Pos + 10] = (char)0x04; // Target Length.
+ GOFFData[Pos + 17] = (char)0x03; // R-id.
+ GOFFData[Pos + 21] = (char)0x02; // P-id.
+ GOFFData[Pos + 25] = (char)0x04; // Offset.
+
// END record.
addEndRecord();
@@ -632,6 +642,21 @@ TEST_F(GOFFObjectFileTest, TXTConstruct) {
ASSERT_THAT_EXPECTED(SectionContent, Succeeded());
StringRef Contents = SectionContent.get();
EXPECT_EQ(Contents, "\x12\x34\x56\x78\x9a\xbc\xde\xf0");
+
+ auto Relocations = Section.relocations();
+ ASSERT_EQ(std::distance(Relocations.begin(), Relocations.end()), 1);
+ RelocationRef Relocation = *Relocations.begin();
+ SymbolRef TargetSymbol = *Relocation.getSymbol();
+ Expected<StringRef> TargetSymbolNameOrErr =
+ GOFFObj->getSymbolName(TargetSymbol);
+ ASSERT_THAT_EXPECTED(TargetSymbolNameOrErr, Succeeded());
+ StringRef TargetSymbolName = TargetSymbolNameOrErr.get();
+ EXPECT_EQ(TargetSymbolName, "var#c");
+ SmallString<16> RelTypeName;
+ Relocation.getTypeName(RelTypeName);
+ EXPECT_EQ(RelTypeName, "R_00040000");
+ uint64_t Offset = Relocation.getOffset();
+ EXPECT_EQ(Offset, 4u);
}
TEST_F(GOFFObjectFileTest, GlobalSymbols) {
>From 00fa22db5cb4abce6872a0ade6c9277dacedf26e Mon Sep 17 00:00:00 2001
From: Shimin Cui <scui at ca.ibm.com>
Date: Tue, 25 Aug 2026 19:55:07 +0000
Subject: [PATCH 2/3] To address comments (fix RelEntry population + unittest)
---
llvm/include/llvm/Object/GOFFObjectFile.h | 4 ---
llvm/lib/Object/GOFFObjectFile.cpp | 33 +++++++++++---------
llvm/unittests/Object/GOFFObjectFileTest.cpp | 33 ++++++++++++++++----
3 files changed, 46 insertions(+), 24 deletions(-)
diff --git a/llvm/include/llvm/Object/GOFFObjectFile.h b/llvm/include/llvm/Object/GOFFObjectFile.h
index 0bfbbc8d7acd6..a1553f578a71d 100644
--- a/llvm/include/llvm/Object/GOFFObjectFile.h
+++ b/llvm/include/llvm/Object/GOFFObjectFile.h
@@ -35,8 +35,6 @@ struct GOFFRelEntry {
uint32_t PEsdId;
uint64_t POffset;
uint64_t RelType;
-
- DataRefImpl RefSymb; // Symbol referred to.
};
// GOFFRelEntry::RelType is computed based on RLD fields at offset 1, 2, 4,
@@ -193,8 +191,6 @@ class GOFFSymbolRef : public SymbolRef {
return cast<GOFFObjectFile>(BasicSymbolRef::getObject());
}
- uint32_t getSymbolGOFFEsdId() const { return getRawDataRefImpl().d.a; }
-
Expected<uint32_t> getSymbolGOFFFlags() const {
return getObject()->getSymbolFlags(getRawDataRefImpl());
}
diff --git a/llvm/lib/Object/GOFFObjectFile.cpp b/llvm/lib/Object/GOFFObjectFile.cpp
index 4960aeaae8440..1b03fd8c68199 100644
--- a/llvm/lib/Object/GOFFObjectFile.cpp
+++ b/llvm/lib/Object/GOFFObjectFile.cpp
@@ -766,6 +766,12 @@ basic_symbol_iterator GOFFObjectFile::symbol_end() const {
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;
@@ -784,40 +790,37 @@ void GOFFObjectFile::setRelocationData(const uint8_t *RldRecord) {
uint8_t *RldI = reinterpret_cast<uint8_t *>(RelocationData.data());
uint8_t *RldE = RldI + RelocationData.size();
+ uint32_t CurREsdId = 0;
+ uint32_t CurPEsdId = 0;
+ uint64_t CurPOffset = 0;
for (uint8_t *Rld = RldI + DataIndex; Rld < RldE;) {
GOFFRelEntry RelEntry;
uint8_t Flags = Rld[0];
-
-#define SAME_R_ID 0x80
-#define SAME_P_ID 0x40
-#define SAME_OFFSET 0x20
-#define EXT_ATTR_PRESENT 0x04
-#define BYTE_OFFSET_8 0x02
-
int32_t Length = 8;
if (!(Flags & SAME_R_ID)) {
- RelEntry.REsdId = support::endian::read32be(&Rld[Length]);
+ CurREsdId = support::endian::read32be(&Rld[Length]);
Length += 4;
}
if (!(Flags & SAME_P_ID)) {
- RelEntry.PEsdId = support::endian::read32be(&Rld[Length]);
+ CurPEsdId = support::endian::read32be(&Rld[Length]);
Length += 4;
}
if (!(Flags & SAME_OFFSET)) {
if (Flags & BYTE_OFFSET_8) {
- RelEntry.POffset = support::endian::read64be(&Rld[Length]);
+ CurPOffset = support::endian::read64be(&Rld[Length]);
Length += 8;
} else {
- RelEntry.POffset = support::endian::read32be(&Rld[Length]);
+ 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);
- RelEntry.RefSymb.d.a = RelEntry.REsdId;
-
RelEntries.emplace_back(RelEntry);
Rld += Length;
@@ -848,7 +851,9 @@ 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];
- return basic_symbol_iterator(SymbolRef(RelEntry.RefSymb, this));
+ DataRefImpl RefSym;
+ RefSym.d.a = RelEntry.REsdId;
+ return basic_symbol_iterator(SymbolRef(RefSym, this));
}
uint64_t GOFFObjectFile::getRelocationType(DataRefImpl Rel) const {
diff --git a/llvm/unittests/Object/GOFFObjectFileTest.cpp b/llvm/unittests/Object/GOFFObjectFileTest.cpp
index 555487a87dcb5..493b1fd8e9df1 100644
--- a/llvm/unittests/Object/GOFFObjectFileTest.cpp
+++ b/llvm/unittests/Object/GOFFObjectFileTest.cpp
@@ -604,15 +604,19 @@ TEST_F(GOFFObjectFileTest, TXTConstruct) {
GOFFData[Pos + 30] = (char)0xde;
GOFFData[Pos + 31] = (char)0xf0;
- // RLD record.
+ // RLD record with 2 entries.
Pos = addNewRecord();
GOFFData[Pos] = (char)0x03;
GOFFData[Pos + 1] = (char)0x20;
- GOFFData[Pos + 5] = (char)0x14; // Length.
+ GOFFData[Pos + 5] = (char)0x20; // Length.
GOFFData[Pos + 10] = (char)0x04; // Target Length.
GOFFData[Pos + 17] = (char)0x03; // R-id.
GOFFData[Pos + 21] = (char)0x02; // P-id.
- GOFFData[Pos + 25] = (char)0x04; // Offset.
+ GOFFData[Pos + 25] = (char)0x00; // Offset.
+ GOFFData[Pos + 26] = (char)0xc0; // Same R-id and P-id.
+ GOFFData[Pos + 28] = (char)0x01; // Store
+ GOFFData[Pos + 30] = (char)0x04; // Target Length.
+ GOFFData[Pos + 37] = (char)0x04; // Offset.
// END record.
addEndRecord();
@@ -643,9 +647,13 @@ TEST_F(GOFFObjectFileTest, TXTConstruct) {
StringRef Contents = SectionContent.get();
EXPECT_EQ(Contents, "\x12\x34\x56\x78\x9a\xbc\xde\xf0");
- auto Relocations = Section.relocations();
- ASSERT_EQ(std::distance(Relocations.begin(), Relocations.end()), 1);
- RelocationRef Relocation = *Relocations.begin();
+ iterator_range<object::relocation_iterator> Relocations =
+ Section.relocations();
+ object::relocation_iterator RelI = Relocations.begin();
+ object::relocation_iterator RelIE = Relocations.end();
+ ASSERT_EQ(std::distance(RelI, RelIE), 2);
+ // First relocation entry.
+ RelocationRef Relocation = *RelI;
SymbolRef TargetSymbol = *Relocation.getSymbol();
Expected<StringRef> TargetSymbolNameOrErr =
GOFFObj->getSymbolName(TargetSymbol);
@@ -656,6 +664,19 @@ TEST_F(GOFFObjectFileTest, TXTConstruct) {
Relocation.getTypeName(RelTypeName);
EXPECT_EQ(RelTypeName, "R_00040000");
uint64_t Offset = Relocation.getOffset();
+ EXPECT_EQ(Offset, 0u);
+ // Second relocation entry.
+ ++RelI;
+ Relocation = *RelI;
+ TargetSymbol = *Relocation.getSymbol();
+ TargetSymbolNameOrErr = GOFFObj->getSymbolName(TargetSymbol);
+ ASSERT_THAT_EXPECTED(TargetSymbolNameOrErr, Succeeded());
+ TargetSymbolName = TargetSymbolNameOrErr.get();
+ EXPECT_EQ(TargetSymbolName, "var#c");
+ SmallString<16> RelTypeName2;
+ Relocation.getTypeName(RelTypeName2);
+ EXPECT_EQ(RelTypeName2, "R_00040100");
+ Offset = Relocation.getOffset();
EXPECT_EQ(Offset, 4u);
}
>From 6b3d869407f5cab6d7411504bdca26530481e8af Mon Sep 17 00:00:00 2001
From: Shimin Cui <scui at ca.ibm.com>
Date: Wed, 26 Aug 2026 13:33:00 +0000
Subject: [PATCH 3/3] Fix as record is flattened now
---
llvm/include/llvm/Object/GOFFObjectFile.h | 2 +-
llvm/lib/Object/GOFFObjectFile.cpp | 18 +++++-------------
2 files changed, 6 insertions(+), 14 deletions(-)
diff --git a/llvm/include/llvm/Object/GOFFObjectFile.h b/llvm/include/llvm/Object/GOFFObjectFile.h
index a1553f578a71d..42b62ea0405ee 100644
--- a/llvm/include/llvm/Object/GOFFObjectFile.h
+++ b/llvm/include/llvm/Object/GOFFObjectFile.h
@@ -39,7 +39,7 @@ struct GOFFRelEntry {
// GOFFRelEntry::RelType is computed based on RLD fields at offset 1, 2, 4,
// and 5.
-inline uint64_t getRldType(uint8_t *Rld) {
+inline uint64_t getRldType(const uint8_t *Rld) {
return Rld[1] + (Rld[2] << 8) + (Rld[4] << 16) + (Rld[5] << 24);
}
diff --git a/llvm/lib/Object/GOFFObjectFile.cpp b/llvm/lib/Object/GOFFObjectFile.cpp
index 1b03fd8c68199..2b8e61a994838 100644
--- a/llvm/lib/Object/GOFFObjectFile.cpp
+++ b/llvm/lib/Object/GOFFObjectFile.cpp
@@ -778,22 +778,14 @@ void GOFFObjectFile::setRelocationData(const uint8_t *RldRecord) {
int DataIndex = 6;
uint16_t DataLength;
RLDRecord::getDataLength(RldRecord, DataLength);
- Expected<unsigned> BlocksConsumed =
- getContinuousData(RelocationData, DataIndex, DataLength, RldRecord);
- if (!BlocksConsumed)
- llvm::handleAllErrors(BlocksConsumed.takeError(),
- [](const llvm::ErrorInfoBase &EIB) {
- llvm::errs() << "ERROR: " << EIB.message() << "\n";
- });
- assert(static_cast<size_t>(DataLength + DataIndex) == RelocationData.size() &&
- "Inconsistent rld size");
-
- uint8_t *RldI = reinterpret_cast<uint8_t *>(RelocationData.data());
- uint8_t *RldE = RldI + RelocationData.size();
+
+ // 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 (uint8_t *Rld = RldI + DataIndex; Rld < RldE;) {
+ for (const uint8_t *Rld = RldI; Rld < RldE;) {
GOFFRelEntry RelEntry;
uint8_t Flags = Rld[0];
int32_t Length = 8;
More information about the llvm-commits
mailing list