================
@@ -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

Reply via email to