================
@@ -545,8 +743,68 @@ GOFFObjectWriter::GOFFObjectWriter(
 
 GOFFObjectWriter::~GOFFObjectWriter() = default;
 
+void GOFFObjectWriter::recordRelocation(const MCFragment &F,
+                                        const MCFixup &Fixup, MCValue Target,
+                                        uint64_t &FixedValue) {
+  const MCFixupKindInfo &FKI =
+      Asm->getBackend().getFixupKindInfo(Fixup.getKind());
+  const uint32_t Length = FKI.TargetSize / 8;
+  assert(FKI.TargetSize % 8 == 0 && "Target Size not multiple of 8");
+  const uint64_t FixupOffset = Asm->getFragmentOffset(F) + Fixup.getOffset();
+  bool IsPCRel = Fixup.isPCRel();
+
+  unsigned RelocType = TargetObjectWriter->getRelocType(Target, Fixup, 
IsPCRel);
+
+  const MCSectionGOFF *PSection = static_cast<MCSectionGOFF *>(F.getParent());
+  const auto &A = *static_cast<const MCSymbolGOFF *>(Target.getAddSym());
+  const MCSymbolGOFF *B = static_cast<const MCSymbolGOFF 
*>(Target.getSubSym());
+  if (RelocType == MCGOFFObjectTargetWriter::Reloc_Type_RelImm) {
+    if (A.isUndefined()) {
+      Asm->reportError(
+          Fixup.getLoc(),
+          Twine("symbol ")
+              .concat(A.getName())
+              .concat(" must be defined for a relative immediate relocation"));
+      return;
+    }
+    if (&A.getSection() != PSection) {
+      Asm->reportError(Fixup.getLoc(),
+                       Twine("relative immediate relocation section mismatch: 
")
+                           .concat(A.getSection().getName())
+                           .concat(" of symbol ")
+                           .concat(A.getName())
+                           .concat(" <-> ")
+                           .concat(PSection->getName()));
+      return;
+    }
+    if (B) {
+      Asm->reportError(
+          Fixup.getLoc(),
+          Twine("subtractive symbol ")
+              .concat(B->getName())
+              .concat(" not supported for a relative immediate relocation"));
+      return;
+    }
+    FixedValue = Asm->getSymbolOffset(A) - FixupOffset + Target.getConstant();
+    return;
+  }
+  FixedValue = Target.getConstant();
+
+  // The symbol only has a section-relative offset if it is a temporary symbol.
+  FixedValue += A.isTemporary() ? Asm->getSymbolOffset(A) : 0;
+  A.setUsedInReloc();
+  if (B) {
+    FixedValue -= B->isTemporary() ? Asm->getSymbolOffset(*B) : 0;
+    B->setUsedInReloc();
+  }
+
+  // Save relocation data for later writing.
+  SavedRelocs.emplace_back(PSection, &A, B, RelocType, FixupOffset, Length,
+                           FixedValue);
+}
+
 uint64_t GOFFObjectWriter::writeObject() {
-  uint64_t Size = GOFFWriter(OS, *Asm).writeObject();
+  uint64_t Size = GOFFWriter(OS, *Asm, SavedRelocs).writeObject();
----------------
uweigand wrote:

Precedent e.g. from ELF would be to pass a reference to the whole 
`GOFFObjectWriter` to the `GOFFWriter` rather than just a single field.  Not 
sure which is really better here ...

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