================
@@ -502,6 +535,169 @@ void GOFFWriter::writeText(const MCSectionGOFF *Section) {
Asm.writeSectionData(S, Section);
}
+namespace {
+// RelocDataItemBuffer provides a static buffer for relocation data items.
+class RelocDataItemBuffer {
+ char Buffer[GOFF::MaxDataLength];
+ char *Ptr;
+
+public:
+ RelocDataItemBuffer() : Ptr(Buffer) {}
+ const char *data() { return Buffer; }
+ size_t size() { return Ptr - Buffer; }
+ void reset() { Ptr = Buffer; }
+ bool fits(size_t S) { return size() + S < GOFF::MaxDataLength; }
+ template <typename T> void writebe(T Val) {
+ assert(fits(sizeof(T)) && "Out-of-bounds write");
+ support::endian::write<T, llvm::endianness::big>(Ptr, Val);
+ Ptr += sizeof(T);
+ }
+};
+} // namespace
+
+void GOFFWriter::writeRelocations() {
+ // Transform a GOFFSavedRelocationEntry to 1 or 2 GOFFRelocationEntry
+ // instances. An expression like SymA - SymB + Const is implemented by
storing
+ // Const in the memory (aka the FixedValue), and then having a relocation to
+ // add SymA, and another relocation to subtract SymB.
+ std::vector<GOFFRelocationEntry> Relocations;
+ for (auto &RelocEntry : SavedRelocs) {
+ auto *PSection = RelocEntry.Section;
+ auto RelocType = RelocEntry.RelocType;
+ auto *A = RelocEntry.SymA;
+ auto *B = RelocEntry.SymB;
+ auto FixupOffset = RelocEntry.FixupOffset;
+ auto Length = RelocEntry.Length;
+
+ auto GetRptr = [](const MCSymbolGOFF *Sym) -> uint32_t {
+ if (Sym->isTemporary())
+ return static_cast<MCSectionGOFF &>(Sym->getSection())
+ .getBeginSymbol()
+ ->getIndex();
+ return Sym->getIndex();
+ };
+
+ const uint32_t Pptr = PSection->getOrdinal();
+ uint32_t RptrA = GetRptr(A);
+ uint32_t RptrB = B ? GetRptr(B) : 0;
+
+ // UseQCon causes class offsets versus absolute addresses to be used. This
+ // is analogous to using QCONs in older OBJ object file format.
+ bool UseQCon = RelocType == MCGOFFObjectTargetWriter::Reloc_Type_QCon;
+
+ GOFF::RLDFetchStore FetchStore =
+ (RelocType == MCGOFFObjectTargetWriter::Reloc_Type_RCon ||
+ RelocType == MCGOFFObjectTargetWriter::Reloc_Type_VCon)
+ ? GOFF::RLDFetchStore::RLD_FS_Store
+ : GOFF::RLDFetchStore::RLD_FS_Fetch;
+ assert(FetchStore == GOFF::RLDFetchStore::RLD_FS_Fetch ||
+ RptrB == 0 && "No dependent relocations expected");
+
+ enum GOFF::RLDReferenceType ReferenceType = GOFF::RLD_RT_RAddress;
+ enum GOFF::RLDReferentType ReferentType = GOFF::RLD_RO_Label;
+ if (UseQCon) {
+ ReferenceType = GOFF::RLD_RT_ROffset;
+ ReferentType = GOFF::RLD_RO_Class;
+ }
+ if (RelocType == MCGOFFObjectTargetWriter::Reloc_Type_RCon)
+ ReferenceType = GOFF::RLD_RT_RTypeConstant;
+
+ if (RptrA) {
----------------
tltao wrote:
Can this ever be 0? If yes, it seems like it would represent some error state?
It also seems a bit unintuitive that these are named "ptr/pointer" but it's
actually an index?
https://github.com/llvm/llvm-project/pull/167054
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits