1 //===-- lib/MC/XCOFFObjectWriter.cpp - XCOFF file writer ------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements XCOFF object file writer information.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "llvm/BinaryFormat/XCOFF.h"
14 #include "llvm/MC/MCAsmBackend.h"
15 #include "llvm/MC/MCAsmLayout.h"
16 #include "llvm/MC/MCAssembler.h"
17 #include "llvm/MC/MCFixup.h"
18 #include "llvm/MC/MCFixupKindInfo.h"
19 #include "llvm/MC/MCObjectWriter.h"
20 #include "llvm/MC/MCSectionXCOFF.h"
21 #include "llvm/MC/MCSymbolXCOFF.h"
22 #include "llvm/MC/MCValue.h"
23 #include "llvm/MC/MCXCOFFObjectWriter.h"
24 #include "llvm/MC/StringTableBuilder.h"
25 #include "llvm/Support/Casting.h"
26 #include "llvm/Support/EndianStream.h"
27 #include "llvm/Support/ErrorHandling.h"
28 #include "llvm/Support/MathExtras.h"
29 
30 #include <deque>
31 
32 using namespace llvm;
33 
34 // An XCOFF object file has a limited set of predefined sections. The most
35 // important ones for us (right now) are:
36 // .text --> contains program code and read-only data.
37 // .data --> contains initialized data, function descriptors, and the TOC.
38 // .bss  --> contains uninitialized data.
39 // Each of these sections is composed of 'Control Sections'. A Control Section
40 // is more commonly referred to as a csect. A csect is an indivisible unit of
41 // code or data, and acts as a container for symbols. A csect is mapped
42 // into a section based on its storage-mapping class, with the exception of
43 // XMC_RW which gets mapped to either .data or .bss based on whether it's
44 // explicitly initialized or not.
45 //
46 // We don't represent the sections in the MC layer as there is nothing
47 // interesting about them at at that level: they carry information that is
48 // only relevant to the ObjectWriter, so we materialize them in this class.
49 namespace {
50 
51 constexpr unsigned DefaultSectionAlign = 4;
52 constexpr int16_t MaxSectionIndex = INT16_MAX;
53 
54 // Packs the csect's alignment and type into a byte.
55 uint8_t getEncodedType(const MCSectionXCOFF *);
56 
57 struct XCOFFRelocation {
58   uint32_t SymbolTableIndex;
59   uint32_t FixupOffsetInCsect;
60   uint8_t SignAndSize;
61   uint8_t Type;
62 };
63 
64 // Wrapper around an MCSymbolXCOFF.
65 struct Symbol {
66   const MCSymbolXCOFF *const MCSym;
67   uint32_t SymbolTableIndex;
68 
69   XCOFF::VisibilityType getVisibilityType() const {
70     return MCSym->getVisibilityType();
71   }
72 
73   XCOFF::StorageClass getStorageClass() const {
74     return MCSym->getStorageClass();
75   }
76   StringRef getSymbolTableName() const { return MCSym->getSymbolTableName(); }
77   Symbol(const MCSymbolXCOFF *MCSym) : MCSym(MCSym), SymbolTableIndex(-1) {}
78 };
79 
80 // Wrapper for an MCSectionXCOFF.
81 // It can be a Csect or debug section or DWARF section and so on.
82 struct XCOFFSection {
83   const MCSectionXCOFF *const MCSec;
84   uint32_t SymbolTableIndex;
85   uint64_t Address;
86   uint64_t Size;
87 
88   SmallVector<Symbol, 1> Syms;
89   SmallVector<XCOFFRelocation, 1> Relocations;
90   StringRef getSymbolTableName() const { return MCSec->getSymbolTableName(); }
91   XCOFF::VisibilityType getVisibilityType() const {
92     return MCSec->getVisibilityType();
93   }
94   XCOFFSection(const MCSectionXCOFF *MCSec)
95       : MCSec(MCSec), SymbolTableIndex(-1), Address(-1), Size(0) {}
96 };
97 
98 // Type to be used for a container representing a set of csects with
99 // (approximately) the same storage mapping class. For example all the csects
100 // with a storage mapping class of `xmc_pr` will get placed into the same
101 // container.
102 using CsectGroup = std::deque<XCOFFSection>;
103 using CsectGroups = std::deque<CsectGroup *>;
104 
105 // The basic section entry defination. This Section represents a section entry
106 // in XCOFF section header table.
107 struct SectionEntry {
108   char Name[XCOFF::NameSize];
109   // The physical/virtual address of the section. For an object file
110   // these values are equivalent.
111   uint64_t Address;
112   uint64_t Size;
113   uint64_t FileOffsetToData;
114   uint64_t FileOffsetToRelocations;
115   uint32_t RelocationCount;
116   int32_t Flags;
117 
118   int16_t Index;
119 
120   // XCOFF has special section numbers for symbols:
121   // -2 Specifies N_DEBUG, a special symbolic debugging symbol.
122   // -1 Specifies N_ABS, an absolute symbol. The symbol has a value but is not
123   // relocatable.
124   //  0 Specifies N_UNDEF, an undefined external symbol.
125   // Therefore, we choose -3 (N_DEBUG - 1) to represent a section index that
126   // hasn't been initialized.
127   static constexpr int16_t UninitializedIndex =
128       XCOFF::ReservedSectionNum::N_DEBUG - 1;
129 
130   SectionEntry(StringRef N, int32_t Flags)
131       : Name(), Address(0), Size(0), FileOffsetToData(0),
132         FileOffsetToRelocations(0), RelocationCount(0), Flags(Flags),
133         Index(UninitializedIndex) {
134     assert(N.size() <= XCOFF::NameSize && "section name too long");
135     memcpy(Name, N.data(), N.size());
136   }
137 
138   virtual void reset() {
139     Address = 0;
140     Size = 0;
141     FileOffsetToData = 0;
142     FileOffsetToRelocations = 0;
143     RelocationCount = 0;
144     Index = UninitializedIndex;
145   }
146 
147   virtual ~SectionEntry() = default;
148 };
149 
150 // Represents the data related to a section excluding the csects that make up
151 // the raw data of the section. The csects are stored separately as not all
152 // sections contain csects, and some sections contain csects which are better
153 // stored separately, e.g. the .data section containing read-write, descriptor,
154 // TOCBase and TOC-entry csects.
155 struct CsectSectionEntry : public SectionEntry {
156   // Virtual sections do not need storage allocated in the object file.
157   const bool IsVirtual;
158 
159   // This is a section containing csect groups.
160   CsectGroups Groups;
161 
162   CsectSectionEntry(StringRef N, XCOFF::SectionTypeFlags Flags, bool IsVirtual,
163                     CsectGroups Groups)
164       : SectionEntry(N, Flags), IsVirtual(IsVirtual), Groups(Groups) {
165     assert(N.size() <= XCOFF::NameSize && "section name too long");
166     memcpy(Name, N.data(), N.size());
167   }
168 
169   void reset() override {
170     SectionEntry::reset();
171     // Clear any csects we have stored.
172     for (auto *Group : Groups)
173       Group->clear();
174   }
175 
176   virtual ~CsectSectionEntry() = default;
177 };
178 
179 struct DwarfSectionEntry : public SectionEntry {
180   // For DWARF section entry.
181   std::unique_ptr<XCOFFSection> DwarfSect;
182 
183   // For DWARF section, we must use real size in the section header. MemorySize
184   // is for the size the DWARF section occupies including paddings.
185   uint32_t MemorySize;
186 
187   DwarfSectionEntry(StringRef N, int32_t Flags,
188                     std::unique_ptr<XCOFFSection> Sect)
189       : SectionEntry(N, Flags | XCOFF::STYP_DWARF), DwarfSect(std::move(Sect)),
190         MemorySize(0) {
191     assert(DwarfSect->MCSec->isDwarfSect() &&
192            "This should be a DWARF section!");
193     assert(N.size() <= XCOFF::NameSize && "section name too long");
194     memcpy(Name, N.data(), N.size());
195   }
196 
197   DwarfSectionEntry(DwarfSectionEntry &&s) = default;
198 
199   virtual ~DwarfSectionEntry() = default;
200 };
201 
202 class XCOFFObjectWriter : public MCObjectWriter {
203 
204   uint32_t SymbolTableEntryCount = 0;
205   uint64_t SymbolTableOffset = 0;
206   uint16_t SectionCount = 0;
207   uint64_t RelocationEntryOffset = 0;
208   StringRef SourceFileName = ".file";
209   std::vector<std::pair<std::string, size_t>> FileNames;
210 
211   support::endian::Writer W;
212   std::unique_ptr<MCXCOFFObjectTargetWriter> TargetObjectWriter;
213   StringTableBuilder Strings;
214 
215   const uint64_t MaxRawDataSize =
216       TargetObjectWriter->is64Bit() ? UINT64_MAX : UINT32_MAX;
217 
218   // Maps the MCSection representation to its corresponding XCOFFSection
219   // wrapper. Needed for finding the XCOFFSection to insert an MCSymbol into
220   // from its containing MCSectionXCOFF.
221   DenseMap<const MCSectionXCOFF *, XCOFFSection *> SectionMap;
222 
223   // Maps the MCSymbol representation to its corrresponding symbol table index.
224   // Needed for relocation.
225   DenseMap<const MCSymbol *, uint32_t> SymbolIndexMap;
226 
227   // CsectGroups. These store the csects which make up different parts of
228   // the sections. Should have one for each set of csects that get mapped into
229   // the same section and get handled in a 'similar' way.
230   CsectGroup UndefinedCsects;
231   CsectGroup ProgramCodeCsects;
232   CsectGroup ReadOnlyCsects;
233   CsectGroup DataCsects;
234   CsectGroup FuncDSCsects;
235   CsectGroup TOCCsects;
236   CsectGroup BSSCsects;
237   CsectGroup TDataCsects;
238   CsectGroup TBSSCsects;
239 
240   // The Predefined sections.
241   CsectSectionEntry Text;
242   CsectSectionEntry Data;
243   CsectSectionEntry BSS;
244   CsectSectionEntry TData;
245   CsectSectionEntry TBSS;
246 
247   // All the XCOFF sections, in the order they will appear in the section header
248   // table.
249   std::array<CsectSectionEntry *const, 5> Sections{
250       {&Text, &Data, &BSS, &TData, &TBSS}};
251 
252   std::vector<DwarfSectionEntry> DwarfSections;
253 
254   CsectGroup &getCsectGroup(const MCSectionXCOFF *MCSec);
255 
256   virtual void reset() override;
257 
258   void executePostLayoutBinding(MCAssembler &, const MCAsmLayout &) override;
259 
260   void recordRelocation(MCAssembler &, const MCAsmLayout &, const MCFragment *,
261                         const MCFixup &, MCValue, uint64_t &) override;
262 
263   uint64_t writeObject(MCAssembler &, const MCAsmLayout &) override;
264 
265   bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
266   bool nameShouldBeInStringTable(const StringRef &);
267   void writeSymbolName(const StringRef &);
268 
269   void writeSymbolEntryForCsectMemberLabel(const Symbol &SymbolRef,
270                                            const XCOFFSection &CSectionRef,
271                                            int16_t SectionIndex,
272                                            uint64_t SymbolOffset);
273   void writeSymbolEntryForControlSection(const XCOFFSection &CSectionRef,
274                                          int16_t SectionIndex,
275                                          XCOFF::StorageClass StorageClass);
276   void writeSymbolEntryForDwarfSection(const XCOFFSection &DwarfSectionRef,
277                                        int16_t SectionIndex);
278   void writeFileHeader();
279   void writeSectionHeaderTable();
280   void writeSections(const MCAssembler &Asm, const MCAsmLayout &Layout);
281   void writeSectionForControlSectionEntry(const MCAssembler &Asm,
282                                           const MCAsmLayout &Layout,
283                                           const CsectSectionEntry &CsectEntry,
284                                           uint64_t &CurrentAddressLocation);
285   void writeSectionForDwarfSectionEntry(const MCAssembler &Asm,
286                                         const MCAsmLayout &Layout,
287                                         const DwarfSectionEntry &DwarfEntry,
288                                         uint64_t &CurrentAddressLocation);
289   void writeSymbolTable(const MCAsmLayout &Layout);
290   void writeSymbolAuxDwarfEntry(uint64_t LengthOfSectionPortion,
291                                 uint64_t NumberOfRelocEnt = 0);
292   void writeSymbolAuxCsectEntry(uint64_t SectionOrLength,
293                                 uint8_t SymbolAlignmentAndType,
294                                 uint8_t StorageMappingClass);
295   void writeSymbolEntry(StringRef SymbolName, uint64_t Value,
296                         int16_t SectionNumber, uint16_t SymbolType,
297                         uint8_t StorageClass, uint8_t NumberOfAuxEntries = 1);
298   void writeRelocations();
299   void writeRelocation(XCOFFRelocation Reloc, const XCOFFSection &Section);
300 
301   // Called after all the csects and symbols have been processed by
302   // `executePostLayoutBinding`, this function handles building up the majority
303   // of the structures in the object file representation. Namely:
304   // *) Calculates physical/virtual addresses, raw-pointer offsets, and section
305   //    sizes.
306   // *) Assigns symbol table indices.
307   // *) Builds up the section header table by adding any non-empty sections to
308   //    `Sections`.
309   void assignAddressesAndIndices(const MCAsmLayout &);
310   void finalizeSectionInfo();
311 
312   // TODO aux header support not implemented.
313   bool needsAuxiliaryHeader() const { return false; }
314 
315   // Returns the size of the auxiliary header to be written to the object file.
316   size_t auxiliaryHeaderSize() const {
317     assert(!needsAuxiliaryHeader() &&
318            "Auxiliary header support not implemented.");
319     return 0;
320   }
321 
322 public:
323   XCOFFObjectWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW,
324                     raw_pwrite_stream &OS);
325 
326   void writeWord(uint64_t Word) {
327     is64Bit() ? W.write<uint64_t>(Word) : W.write<uint32_t>(Word);
328   }
329 };
330 
331 XCOFFObjectWriter::XCOFFObjectWriter(
332     std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS)
333     : W(OS, support::big), TargetObjectWriter(std::move(MOTW)),
334       Strings(StringTableBuilder::XCOFF),
335       Text(".text", XCOFF::STYP_TEXT, /* IsVirtual */ false,
336            CsectGroups{&ProgramCodeCsects, &ReadOnlyCsects}),
337       Data(".data", XCOFF::STYP_DATA, /* IsVirtual */ false,
338            CsectGroups{&DataCsects, &FuncDSCsects, &TOCCsects}),
339       BSS(".bss", XCOFF::STYP_BSS, /* IsVirtual */ true,
340           CsectGroups{&BSSCsects}),
341       TData(".tdata", XCOFF::STYP_TDATA, /* IsVirtual */ false,
342             CsectGroups{&TDataCsects}),
343       TBSS(".tbss", XCOFF::STYP_TBSS, /* IsVirtual */ true,
344            CsectGroups{&TBSSCsects}) {}
345 
346 void XCOFFObjectWriter::reset() {
347   // Clear the mappings we created.
348   SymbolIndexMap.clear();
349   SectionMap.clear();
350 
351   UndefinedCsects.clear();
352   // Reset any sections we have written to, and empty the section header table.
353   for (auto *Sec : Sections)
354     Sec->reset();
355   for (auto &DwarfSec : DwarfSections)
356     DwarfSec.reset();
357 
358   // Reset states in XCOFFObjectWriter.
359   SymbolTableEntryCount = 0;
360   SymbolTableOffset = 0;
361   SectionCount = 0;
362   RelocationEntryOffset = 0;
363   Strings.clear();
364 
365   MCObjectWriter::reset();
366 }
367 
368 CsectGroup &XCOFFObjectWriter::getCsectGroup(const MCSectionXCOFF *MCSec) {
369   switch (MCSec->getMappingClass()) {
370   case XCOFF::XMC_PR:
371     assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
372            "Only an initialized csect can contain program code.");
373     return ProgramCodeCsects;
374   case XCOFF::XMC_RO:
375     assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
376            "Only an initialized csect can contain read only data.");
377     return ReadOnlyCsects;
378   case XCOFF::XMC_RW:
379     if (XCOFF::XTY_CM == MCSec->getCSectType())
380       return BSSCsects;
381 
382     if (XCOFF::XTY_SD == MCSec->getCSectType())
383       return DataCsects;
384 
385     report_fatal_error("Unhandled mapping of read-write csect to section.");
386   case XCOFF::XMC_DS:
387     return FuncDSCsects;
388   case XCOFF::XMC_BS:
389     assert(XCOFF::XTY_CM == MCSec->getCSectType() &&
390            "Mapping invalid csect. CSECT with bss storage class must be "
391            "common type.");
392     return BSSCsects;
393   case XCOFF::XMC_TL:
394     assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
395            "Mapping invalid csect. CSECT with tdata storage class must be "
396            "an initialized csect.");
397     return TDataCsects;
398   case XCOFF::XMC_UL:
399     assert(XCOFF::XTY_CM == MCSec->getCSectType() &&
400            "Mapping invalid csect. CSECT with tbss storage class must be "
401            "an uninitialized csect.");
402     return TBSSCsects;
403   case XCOFF::XMC_TC0:
404     assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
405            "Only an initialized csect can contain TOC-base.");
406     assert(TOCCsects.empty() &&
407            "We should have only one TOC-base, and it should be the first csect "
408            "in this CsectGroup.");
409     return TOCCsects;
410   case XCOFF::XMC_TC:
411   case XCOFF::XMC_TE:
412     assert(XCOFF::XTY_SD == MCSec->getCSectType() &&
413            "Only an initialized csect can contain TC entry.");
414     assert(!TOCCsects.empty() &&
415            "We should at least have a TOC-base in this CsectGroup.");
416     return TOCCsects;
417   case XCOFF::XMC_TD:
418     report_fatal_error("toc-data not yet supported when writing object files.");
419   default:
420     report_fatal_error("Unhandled mapping of csect to section.");
421   }
422 }
423 
424 static MCSectionXCOFF *getContainingCsect(const MCSymbolXCOFF *XSym) {
425   if (XSym->isDefined())
426     return cast<MCSectionXCOFF>(XSym->getFragment()->getParent());
427   return XSym->getRepresentedCsect();
428 }
429 
430 void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
431                                                  const MCAsmLayout &Layout) {
432   for (const auto &S : Asm) {
433     const auto *MCSec = cast<const MCSectionXCOFF>(&S);
434     assert(SectionMap.find(MCSec) == SectionMap.end() &&
435            "Cannot add a section twice.");
436 
437     // If the name does not fit in the storage provided in the symbol table
438     // entry, add it to the string table.
439     if (nameShouldBeInStringTable(MCSec->getSymbolTableName()))
440       Strings.add(MCSec->getSymbolTableName());
441     if (MCSec->isCsect()) {
442       // A new control section. Its CsectSectionEntry should already be staticly
443       // generated as Text/Data/BSS/TDATA/TBSS. Add this section to the group of
444       // the CsectSectionEntry.
445       assert(XCOFF::XTY_ER != MCSec->getCSectType() &&
446              "An undefined csect should not get registered.");
447       CsectGroup &Group = getCsectGroup(MCSec);
448       Group.emplace_back(MCSec);
449       SectionMap[MCSec] = &Group.back();
450     } else if (MCSec->isDwarfSect()) {
451       // A new DwarfSectionEntry.
452       std::unique_ptr<XCOFFSection> DwarfSec =
453           std::make_unique<XCOFFSection>(MCSec);
454       SectionMap[MCSec] = DwarfSec.get();
455 
456       DwarfSectionEntry SecEntry(MCSec->getName(),
457                                  *MCSec->getDwarfSubtypeFlags(),
458                                  std::move(DwarfSec));
459       DwarfSections.push_back(std::move(SecEntry));
460     } else
461       llvm_unreachable("unsupport section type!");
462   }
463 
464   for (const MCSymbol &S : Asm.symbols()) {
465     // Nothing to do for temporary symbols.
466     if (S.isTemporary())
467       continue;
468 
469     const MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(&S);
470     const MCSectionXCOFF *ContainingCsect = getContainingCsect(XSym);
471 
472     if (ContainingCsect->getCSectType() == XCOFF::XTY_ER) {
473       // Handle undefined symbol.
474       UndefinedCsects.emplace_back(ContainingCsect);
475       SectionMap[ContainingCsect] = &UndefinedCsects.back();
476       if (nameShouldBeInStringTable(ContainingCsect->getSymbolTableName()))
477         Strings.add(ContainingCsect->getSymbolTableName());
478       continue;
479     }
480 
481     // If the symbol is the csect itself, we don't need to put the symbol
482     // into csect's Syms.
483     if (XSym == ContainingCsect->getQualNameSymbol())
484       continue;
485 
486     // Only put a label into the symbol table when it is an external label.
487     if (!XSym->isExternal())
488       continue;
489 
490     assert(SectionMap.find(ContainingCsect) != SectionMap.end() &&
491            "Expected containing csect to exist in map");
492     XCOFFSection *Csect = SectionMap[ContainingCsect];
493     // Lookup the containing csect and add the symbol to it.
494     assert(Csect->MCSec->isCsect() && "only csect is supported now!");
495     Csect->Syms.emplace_back(XSym);
496 
497     // If the name does not fit in the storage provided in the symbol table
498     // entry, add it to the string table.
499     if (nameShouldBeInStringTable(XSym->getSymbolTableName()))
500       Strings.add(XSym->getSymbolTableName());
501   }
502 
503   FileNames = Asm.getFileNames();
504   // Emit ".file" as the source file name when there is no file name.
505   if (FileNames.empty())
506     FileNames.emplace_back(".file", 0);
507   for (const std::pair<std::string, size_t> &F : FileNames) {
508     if (nameShouldBeInStringTable(F.first))
509       Strings.add(F.first);
510   }
511 
512   Strings.finalize();
513   assignAddressesAndIndices(Layout);
514 }
515 
516 void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
517                                          const MCAsmLayout &Layout,
518                                          const MCFragment *Fragment,
519                                          const MCFixup &Fixup, MCValue Target,
520                                          uint64_t &FixedValue) {
521   auto getIndex = [this](const MCSymbol *Sym,
522                          const MCSectionXCOFF *ContainingCsect) {
523     // If we could not find the symbol directly in SymbolIndexMap, this symbol
524     // could either be a temporary symbol or an undefined symbol. In this case,
525     // we would need to have the relocation reference its csect instead.
526     return SymbolIndexMap.find(Sym) != SymbolIndexMap.end()
527                ? SymbolIndexMap[Sym]
528                : SymbolIndexMap[ContainingCsect->getQualNameSymbol()];
529   };
530 
531   auto getVirtualAddress =
532       [this, &Layout](const MCSymbol *Sym,
533                       const MCSectionXCOFF *ContainingSect) -> uint64_t {
534     // A DWARF section.
535     if (ContainingSect->isDwarfSect())
536       return Layout.getSymbolOffset(*Sym);
537 
538     // A csect.
539     if (!Sym->isDefined())
540       return SectionMap[ContainingSect]->Address;
541 
542     // A label.
543     assert(Sym->isDefined() && "not a valid object that has address!");
544     return SectionMap[ContainingSect]->Address + Layout.getSymbolOffset(*Sym);
545   };
546 
547   const MCSymbol *const SymA = &Target.getSymA()->getSymbol();
548 
549   MCAsmBackend &Backend = Asm.getBackend();
550   bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
551                  MCFixupKindInfo::FKF_IsPCRel;
552 
553   uint8_t Type;
554   uint8_t SignAndSize;
555   std::tie(Type, SignAndSize) =
556       TargetObjectWriter->getRelocTypeAndSignSize(Target, Fixup, IsPCRel);
557 
558   const MCSectionXCOFF *SymASec = getContainingCsect(cast<MCSymbolXCOFF>(SymA));
559 
560   if (SymASec->isCsect() && SymASec->getMappingClass() == XCOFF::XMC_TD)
561     report_fatal_error("toc-data not yet supported when writing object files.");
562 
563   assert(SectionMap.find(SymASec) != SectionMap.end() &&
564          "Expected containing csect to exist in map.");
565 
566   const uint32_t Index = getIndex(SymA, SymASec);
567   if (Type == XCOFF::RelocationType::R_POS ||
568       Type == XCOFF::RelocationType::R_TLS)
569     // The FixedValue should be symbol's virtual address in this object file
570     // plus any constant value that we might get.
571     FixedValue = getVirtualAddress(SymA, SymASec) + Target.getConstant();
572   else if (Type == XCOFF::RelocationType::R_TLSM)
573     // The FixedValue should always be zero since the region handle is only
574     // known at load time.
575     FixedValue = 0;
576   else if (Type == XCOFF::RelocationType::R_TOC ||
577            Type == XCOFF::RelocationType::R_TOCL) {
578     // The FixedValue should be the TOC entry offset from the TOC-base plus any
579     // constant offset value.
580     const int64_t TOCEntryOffset = SectionMap[SymASec]->Address -
581                                    TOCCsects.front().Address +
582                                    Target.getConstant();
583     if (Type == XCOFF::RelocationType::R_TOC && !isInt<16>(TOCEntryOffset))
584       report_fatal_error("TOCEntryOffset overflows in small code model mode");
585 
586     FixedValue = TOCEntryOffset;
587   }
588 
589   assert((Fixup.getOffset() <=
590           MaxRawDataSize - Layout.getFragmentOffset(Fragment)) &&
591          "Fragment offset + fixup offset is overflowed.");
592   uint32_t FixupOffsetInCsect =
593       Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
594 
595   XCOFFRelocation Reloc = {Index, FixupOffsetInCsect, SignAndSize, Type};
596   MCSectionXCOFF *RelocationSec = cast<MCSectionXCOFF>(Fragment->getParent());
597   assert(SectionMap.find(RelocationSec) != SectionMap.end() &&
598          "Expected containing csect to exist in map.");
599   SectionMap[RelocationSec]->Relocations.push_back(Reloc);
600 
601   if (!Target.getSymB())
602     return;
603 
604   const MCSymbol *const SymB = &Target.getSymB()->getSymbol();
605   if (SymA == SymB)
606     report_fatal_error("relocation for opposite term is not yet supported");
607 
608   const MCSectionXCOFF *SymBSec = getContainingCsect(cast<MCSymbolXCOFF>(SymB));
609   assert(SectionMap.find(SymBSec) != SectionMap.end() &&
610          "Expected containing csect to exist in map.");
611   if (SymASec == SymBSec)
612     report_fatal_error(
613         "relocation for paired relocatable term is not yet supported");
614 
615   assert(Type == XCOFF::RelocationType::R_POS &&
616          "SymA must be R_POS here if it's not opposite term or paired "
617          "relocatable term.");
618   const uint32_t IndexB = getIndex(SymB, SymBSec);
619   // SymB must be R_NEG here, given the general form of Target(MCValue) is
620   // "SymbolA - SymbolB + imm64".
621   const uint8_t TypeB = XCOFF::RelocationType::R_NEG;
622   XCOFFRelocation RelocB = {IndexB, FixupOffsetInCsect, SignAndSize, TypeB};
623   SectionMap[RelocationSec]->Relocations.push_back(RelocB);
624   // We already folded "SymbolA + imm64" above when Type is R_POS for SymbolA,
625   // now we just need to fold "- SymbolB" here.
626   FixedValue -= getVirtualAddress(SymB, SymBSec);
627 }
628 
629 void XCOFFObjectWriter::writeSections(const MCAssembler &Asm,
630                                       const MCAsmLayout &Layout) {
631   uint64_t CurrentAddressLocation = 0;
632   for (const auto *Section : Sections)
633     writeSectionForControlSectionEntry(Asm, Layout, *Section,
634                                        CurrentAddressLocation);
635   for (const auto &DwarfSection : DwarfSections)
636     writeSectionForDwarfSectionEntry(Asm, Layout, DwarfSection,
637                                      CurrentAddressLocation);
638 }
639 
640 uint64_t XCOFFObjectWriter::writeObject(MCAssembler &Asm,
641                                         const MCAsmLayout &Layout) {
642   // We always emit a timestamp of 0 for reproducibility, so ensure incremental
643   // linking is not enabled, in case, like with Windows COFF, such a timestamp
644   // is incompatible with incremental linking of XCOFF.
645   if (Asm.isIncrementalLinkerCompatible())
646     report_fatal_error("Incremental linking not supported for XCOFF.");
647 
648   finalizeSectionInfo();
649   uint64_t StartOffset = W.OS.tell();
650 
651   writeFileHeader();
652   writeSectionHeaderTable();
653   writeSections(Asm, Layout);
654   writeRelocations();
655   writeSymbolTable(Layout);
656   // Write the string table.
657   Strings.write(W.OS);
658 
659   return W.OS.tell() - StartOffset;
660 }
661 
662 bool XCOFFObjectWriter::nameShouldBeInStringTable(const StringRef &SymbolName) {
663   return SymbolName.size() > XCOFF::NameSize || is64Bit();
664 }
665 
666 void XCOFFObjectWriter::writeSymbolName(const StringRef &SymbolName) {
667   // Magic, Offset or SymbolName.
668   if (nameShouldBeInStringTable(SymbolName)) {
669     W.write<int32_t>(0);
670     W.write<uint32_t>(Strings.getOffset(SymbolName));
671   } else {
672     char Name[XCOFF::NameSize + 1];
673     std::strncpy(Name, SymbolName.data(), XCOFF::NameSize);
674     ArrayRef<char> NameRef(Name, XCOFF::NameSize);
675     W.write(NameRef);
676   }
677 }
678 
679 void XCOFFObjectWriter::writeSymbolEntry(StringRef SymbolName, uint64_t Value,
680                                          int16_t SectionNumber,
681                                          uint16_t SymbolType,
682                                          uint8_t StorageClass,
683                                          uint8_t NumberOfAuxEntries) {
684   if (is64Bit()) {
685     W.write<uint64_t>(Value);
686     W.write<uint32_t>(Strings.getOffset(SymbolName));
687   } else {
688     writeSymbolName(SymbolName);
689     W.write<uint32_t>(Value);
690   }
691   W.write<int16_t>(SectionNumber);
692   // Basic/Derived type. See the description of the n_type field for symbol
693   // table entries for a detailed description. Since we don't yet support
694   // visibility, and all other bits are either optionally set or reserved, this
695   // is always zero.
696   if (SymbolType != 0)
697     report_fatal_error("Emitting non-zero visibilities is not supported yet.");
698   // TODO Set the function indicator (bit 10, 0x0020) for functions
699   // when debugging is enabled.
700   W.write<uint16_t>(SymbolType);
701   W.write<uint8_t>(StorageClass);
702   W.write<uint8_t>(NumberOfAuxEntries);
703 }
704 
705 void XCOFFObjectWriter::writeSymbolAuxCsectEntry(uint64_t SectionOrLength,
706                                                  uint8_t SymbolAlignmentAndType,
707                                                  uint8_t StorageMappingClass) {
708   W.write<uint32_t>(is64Bit() ? Lo_32(SectionOrLength) : SectionOrLength);
709   W.write<uint32_t>(0); // ParameterHashIndex
710   W.write<uint16_t>(0); // TypeChkSectNum
711   W.write<uint8_t>(SymbolAlignmentAndType);
712   W.write<uint8_t>(StorageMappingClass);
713   if (is64Bit()) {
714     W.write<uint32_t>(Hi_32(SectionOrLength));
715     W.OS.write_zeros(1); // Reserved
716     W.write<uint8_t>(XCOFF::AUX_CSECT);
717   } else {
718     W.write<uint32_t>(0); // StabInfoIndex
719     W.write<uint16_t>(0); // StabSectNum
720   }
721 }
722 
723 void XCOFFObjectWriter::writeSymbolAuxDwarfEntry(
724     uint64_t LengthOfSectionPortion, uint64_t NumberOfRelocEnt) {
725   writeWord(LengthOfSectionPortion);
726   if (!is64Bit())
727     W.OS.write_zeros(4); // Reserved
728   writeWord(NumberOfRelocEnt);
729   if (is64Bit()) {
730     W.OS.write_zeros(1); // Reserved
731     W.write<uint8_t>(XCOFF::AUX_SECT);
732   } else {
733     W.OS.write_zeros(6); // Reserved
734   }
735 }
736 
737 void XCOFFObjectWriter::writeSymbolEntryForCsectMemberLabel(
738     const Symbol &SymbolRef, const XCOFFSection &CSectionRef,
739     int16_t SectionIndex, uint64_t SymbolOffset) {
740   assert(SymbolOffset <= MaxRawDataSize - CSectionRef.Address &&
741          "Symbol address overflowed.");
742 
743   writeSymbolEntry(SymbolRef.getSymbolTableName(),
744                    CSectionRef.Address + SymbolOffset, SectionIndex,
745                    SymbolRef.getVisibilityType(), SymbolRef.getStorageClass());
746 
747   writeSymbolAuxCsectEntry(CSectionRef.SymbolTableIndex, XCOFF::XTY_LD,
748                            CSectionRef.MCSec->getMappingClass());
749 }
750 
751 void XCOFFObjectWriter::writeSymbolEntryForDwarfSection(
752     const XCOFFSection &DwarfSectionRef, int16_t SectionIndex) {
753   assert(DwarfSectionRef.MCSec->isDwarfSect() && "Not a DWARF section!");
754 
755   writeSymbolEntry(DwarfSectionRef.getSymbolTableName(), /*Value=*/0,
756                    SectionIndex, /*SymbolType=*/0, XCOFF::C_DWARF);
757 
758   writeSymbolAuxDwarfEntry(DwarfSectionRef.Size);
759 }
760 
761 void XCOFFObjectWriter::writeSymbolEntryForControlSection(
762     const XCOFFSection &CSectionRef, int16_t SectionIndex,
763     XCOFF::StorageClass StorageClass) {
764   writeSymbolEntry(CSectionRef.getSymbolTableName(), CSectionRef.Address,
765                    SectionIndex, CSectionRef.getVisibilityType(), StorageClass);
766 
767   writeSymbolAuxCsectEntry(CSectionRef.Size, getEncodedType(CSectionRef.MCSec),
768                            CSectionRef.MCSec->getMappingClass());
769 }
770 
771 void XCOFFObjectWriter::writeFileHeader() {
772   W.write<uint16_t>(is64Bit() ? XCOFF::XCOFF64 : XCOFF::XCOFF32);
773   W.write<uint16_t>(SectionCount);
774   W.write<int32_t>(0); // TimeStamp
775   writeWord(SymbolTableOffset);
776   if (is64Bit()) {
777     W.write<uint16_t>(0); // AuxHeaderSize. No optional header for an object
778                           // file that is not to be loaded.
779     W.write<uint16_t>(0); // Flags
780     W.write<int32_t>(SymbolTableEntryCount);
781   } else {
782     W.write<int32_t>(SymbolTableEntryCount);
783     W.write<uint16_t>(0); // AuxHeaderSize. No optional header for an object
784                           // file that is not to be loaded.
785     W.write<uint16_t>(0); // Flags
786   }
787 }
788 
789 void XCOFFObjectWriter::writeSectionHeaderTable() {
790   auto writeSectionHeader = [&](const SectionEntry *Sec, bool IsDwarf) {
791     // Nothing to write for this Section.
792     if (Sec->Index == SectionEntry::UninitializedIndex)
793       return false;
794 
795     // Write Name.
796     ArrayRef<char> NameRef(Sec->Name, XCOFF::NameSize);
797     W.write(NameRef);
798 
799     // Write the Physical Address and Virtual Address. In an object file these
800     // are the same.
801     // We use 0 for DWARF sections' Physical and Virtual Addresses.
802     writeWord(IsDwarf ? 0 : Sec->Address);
803     writeWord(IsDwarf ? 0 : Sec->Address);
804 
805     writeWord(Sec->Size);
806     writeWord(Sec->FileOffsetToData);
807     writeWord(Sec->FileOffsetToRelocations);
808     writeWord(0); // FileOffsetToLineNumberInfo. Not supported yet.
809 
810     if (is64Bit()) {
811       W.write<uint32_t>(Sec->RelocationCount);
812       W.write<uint32_t>(0); // NumberOfLineNumbers. Not supported yet.
813       W.write<int32_t>(Sec->Flags);
814       W.OS.write_zeros(4);
815     } else {
816       W.write<uint16_t>(Sec->RelocationCount);
817       W.write<uint16_t>(0); // NumberOfLineNumbers. Not supported yet.
818       W.write<int32_t>(Sec->Flags);
819     }
820 
821     return true;
822   };
823 
824   for (const auto *CsectSec : Sections)
825     writeSectionHeader(CsectSec, /* IsDwarf */ false);
826   for (const auto &DwarfSec : DwarfSections)
827     writeSectionHeader(&DwarfSec, /* IsDwarf */ true);
828 }
829 
830 void XCOFFObjectWriter::writeRelocation(XCOFFRelocation Reloc,
831                                         const XCOFFSection &Section) {
832   if (Section.MCSec->isCsect())
833     writeWord(Section.Address + Reloc.FixupOffsetInCsect);
834   else {
835     // DWARF sections' address is set to 0.
836     assert(Section.MCSec->isDwarfSect() && "unsupport section type!");
837     writeWord(Reloc.FixupOffsetInCsect);
838   }
839   W.write<uint32_t>(Reloc.SymbolTableIndex);
840   W.write<uint8_t>(Reloc.SignAndSize);
841   W.write<uint8_t>(Reloc.Type);
842 }
843 
844 void XCOFFObjectWriter::writeRelocations() {
845   for (const auto *Section : Sections) {
846     if (Section->Index == SectionEntry::UninitializedIndex)
847       // Nothing to write for this Section.
848       continue;
849 
850     for (const auto *Group : Section->Groups) {
851       if (Group->empty())
852         continue;
853 
854       for (const auto &Csect : *Group) {
855         for (const auto Reloc : Csect.Relocations)
856           writeRelocation(Reloc, Csect);
857       }
858     }
859   }
860 
861   for (const auto &DwarfSection : DwarfSections)
862     for (const auto &Reloc : DwarfSection.DwarfSect->Relocations)
863       writeRelocation(Reloc, *DwarfSection.DwarfSect);
864 }
865 
866 void XCOFFObjectWriter::writeSymbolTable(const MCAsmLayout &Layout) {
867   // Write C_FILE symbols.
868   // The n_name of a C_FILE symbol is the source file's name when no auxiliary
869   // entries are present.
870   for (const std::pair<std::string, size_t> &F : FileNames) {
871     writeSymbolEntry(F.first, /*Value=*/0, XCOFF::ReservedSectionNum::N_DEBUG,
872                      /*SymbolType=*/0, XCOFF::C_FILE,
873                      /*NumberOfAuxEntries=*/0);
874   }
875 
876   for (const auto &Csect : UndefinedCsects) {
877     writeSymbolEntryForControlSection(Csect, XCOFF::ReservedSectionNum::N_UNDEF,
878                                       Csect.MCSec->getStorageClass());
879   }
880 
881   for (const auto *Section : Sections) {
882     if (Section->Index == SectionEntry::UninitializedIndex)
883       // Nothing to write for this Section.
884       continue;
885 
886     for (const auto *Group : Section->Groups) {
887       if (Group->empty())
888         continue;
889 
890       const int16_t SectionIndex = Section->Index;
891       for (const auto &Csect : *Group) {
892         // Write out the control section first and then each symbol in it.
893         writeSymbolEntryForControlSection(Csect, SectionIndex,
894                                           Csect.MCSec->getStorageClass());
895 
896         for (const auto &Sym : Csect.Syms)
897           writeSymbolEntryForCsectMemberLabel(
898               Sym, Csect, SectionIndex, Layout.getSymbolOffset(*(Sym.MCSym)));
899       }
900     }
901   }
902 
903   for (const auto &DwarfSection : DwarfSections)
904     writeSymbolEntryForDwarfSection(*DwarfSection.DwarfSect,
905                                     DwarfSection.Index);
906 }
907 
908 void XCOFFObjectWriter::finalizeSectionInfo() {
909   for (auto *Section : Sections) {
910     if (Section->Index == SectionEntry::UninitializedIndex)
911       // Nothing to record for this Section.
912       continue;
913 
914     for (const auto *Group : Section->Groups) {
915       if (Group->empty())
916         continue;
917 
918       for (auto &Csect : *Group) {
919         const size_t CsectRelocCount = Csect.Relocations.size();
920         // An XCOFF64 file may not contain an overflow section header.
921         if (!is64Bit() && (CsectRelocCount >= XCOFF::RelocOverflow ||
922                            Section->RelocationCount >=
923                                XCOFF::RelocOverflow - CsectRelocCount))
924           report_fatal_error(
925               "relocation entries overflowed; overflow section is "
926               "not implemented yet");
927 
928         Section->RelocationCount += CsectRelocCount;
929       }
930     }
931   }
932 
933   for (auto &DwarfSection : DwarfSections)
934     DwarfSection.RelocationCount = DwarfSection.DwarfSect->Relocations.size();
935 
936   // Calculate the file offset to the relocation entries.
937   uint64_t RawPointer = RelocationEntryOffset;
938   auto calcOffsetToRelocations = [&](SectionEntry *Sec, bool IsDwarf) {
939     if (!IsDwarf && Sec->Index == SectionEntry::UninitializedIndex)
940       return false;
941 
942     if (!Sec->RelocationCount)
943       return false;
944 
945     Sec->FileOffsetToRelocations = RawPointer;
946     const uint64_t RelocationSizeInSec =
947         Sec->RelocationCount * (is64Bit()
948                                     ? XCOFF::RelocationSerializationSize64
949                                     : XCOFF::RelocationSerializationSize32);
950     RawPointer += RelocationSizeInSec;
951     if (RawPointer > MaxRawDataSize)
952       report_fatal_error("Relocation data overflowed this object file.");
953 
954     return true;
955   };
956 
957   for (auto *Sec : Sections)
958     calcOffsetToRelocations(Sec, /* IsDwarf */ false);
959 
960   for (auto &DwarfSec : DwarfSections)
961     calcOffsetToRelocations(&DwarfSec, /* IsDwarf */ true);
962 
963   // TODO Error check that the number of symbol table entries fits in 32-bits
964   // signed ...
965   if (SymbolTableEntryCount)
966     SymbolTableOffset = RawPointer;
967 }
968 
969 void XCOFFObjectWriter::assignAddressesAndIndices(const MCAsmLayout &Layout) {
970   // The symbol table starts with all the C_FILE symbols.
971   uint32_t SymbolTableIndex = FileNames.size();
972 
973   // Calculate indices for undefined symbols.
974   for (auto &Csect : UndefinedCsects) {
975     Csect.Size = 0;
976     Csect.Address = 0;
977     Csect.SymbolTableIndex = SymbolTableIndex;
978     SymbolIndexMap[Csect.MCSec->getQualNameSymbol()] = Csect.SymbolTableIndex;
979     // 1 main and 1 auxiliary symbol table entry for each contained symbol.
980     SymbolTableIndex += 2;
981   }
982 
983   // The address corrresponds to the address of sections and symbols in the
984   // object file. We place the shared address 0 immediately after the
985   // section header table.
986   uint64_t Address = 0;
987   // Section indices are 1-based in XCOFF.
988   int32_t SectionIndex = 1;
989   bool HasTDataSection = false;
990   uint32_t PaddingsBeforeDwarf = 0;
991 
992   for (auto *Section : Sections) {
993     const bool IsEmpty =
994         llvm::all_of(Section->Groups,
995                      [](const CsectGroup *Group) { return Group->empty(); });
996     if (IsEmpty)
997       continue;
998 
999     if (SectionIndex > MaxSectionIndex)
1000       report_fatal_error("Section index overflow!");
1001     Section->Index = SectionIndex++;
1002     SectionCount++;
1003 
1004     bool SectionAddressSet = false;
1005     // Reset the starting address to 0 for TData section.
1006     if (Section->Flags == XCOFF::STYP_TDATA) {
1007       Address = 0;
1008       HasTDataSection = true;
1009     }
1010     // Reset the starting address to 0 for TBSS section if the object file does
1011     // not contain TData Section.
1012     if ((Section->Flags == XCOFF::STYP_TBSS) && !HasTDataSection)
1013       Address = 0;
1014 
1015     for (auto *Group : Section->Groups) {
1016       if (Group->empty())
1017         continue;
1018 
1019       for (auto &Csect : *Group) {
1020         const MCSectionXCOFF *MCSec = Csect.MCSec;
1021         Csect.Address = alignTo(Address, MCSec->getAlignment());
1022         Csect.Size = Layout.getSectionAddressSize(MCSec);
1023         Address = Csect.Address + Csect.Size;
1024         Csect.SymbolTableIndex = SymbolTableIndex;
1025         SymbolIndexMap[MCSec->getQualNameSymbol()] = Csect.SymbolTableIndex;
1026         // 1 main and 1 auxiliary symbol table entry for the csect.
1027         SymbolTableIndex += 2;
1028 
1029         for (auto &Sym : Csect.Syms) {
1030           Sym.SymbolTableIndex = SymbolTableIndex;
1031           SymbolIndexMap[Sym.MCSym] = Sym.SymbolTableIndex;
1032           // 1 main and 1 auxiliary symbol table entry for each contained
1033           // symbol.
1034           SymbolTableIndex += 2;
1035         }
1036       }
1037 
1038       if (!SectionAddressSet) {
1039         Section->Address = Group->front().Address;
1040         SectionAddressSet = true;
1041       }
1042     }
1043 
1044     // Make sure the address of the next section aligned to
1045     // DefaultSectionAlign.
1046     Address = alignTo(Address, DefaultSectionAlign);
1047     Section->Size = Address - Section->Address;
1048   }
1049 
1050   // Start to generate DWARF sections. Sections other than DWARF section use
1051   // DefaultSectionAlign as the default alignment, while DWARF sections have
1052   // their own alignments. If these two alignments are not the same, we need
1053   // some paddings here and record the paddings bytes for FileOffsetToData
1054   // calculation.
1055   if (!DwarfSections.empty())
1056     PaddingsBeforeDwarf =
1057         alignTo(Address,
1058                 (*DwarfSections.begin()).DwarfSect->MCSec->getAlignment()) -
1059         Address;
1060 
1061   DwarfSectionEntry *LastDwarfSection = nullptr;
1062 
1063   for (auto &DwarfSection : DwarfSections) {
1064     assert((SectionIndex <= MaxSectionIndex) && "Section index overflow!");
1065 
1066     XCOFFSection &DwarfSect = *DwarfSection.DwarfSect;
1067     const MCSectionXCOFF *MCSec = DwarfSect.MCSec;
1068 
1069     // Section index.
1070     DwarfSection.Index = SectionIndex++;
1071     SectionCount++;
1072 
1073     // Symbol index.
1074     DwarfSect.SymbolTableIndex = SymbolTableIndex;
1075     SymbolIndexMap[MCSec->getQualNameSymbol()] = DwarfSect.SymbolTableIndex;
1076     // 1 main and 1 auxiliary symbol table entry for the csect.
1077     SymbolTableIndex += 2;
1078 
1079     // Section address. Make it align to section alignment.
1080     // We use address 0 for DWARF sections' Physical and Virtual Addresses.
1081     // This address is used to tell where is the section in the final object.
1082     // See writeSectionForDwarfSectionEntry().
1083     DwarfSection.Address = DwarfSect.Address =
1084         alignTo(Address, MCSec->getAlignment());
1085 
1086     // Section size.
1087     // For DWARF section, we must use the real size which may be not aligned.
1088     DwarfSection.Size = DwarfSect.Size = Layout.getSectionAddressSize(MCSec);
1089 
1090     Address = DwarfSection.Address + DwarfSection.Size;
1091 
1092     if (LastDwarfSection)
1093       LastDwarfSection->MemorySize =
1094           DwarfSection.Address - LastDwarfSection->Address;
1095     LastDwarfSection = &DwarfSection;
1096   }
1097   if (LastDwarfSection) {
1098     // Make the final DWARF section address align to the default section
1099     // alignment for follow contents.
1100     Address = alignTo(LastDwarfSection->Address + LastDwarfSection->Size,
1101                       DefaultSectionAlign);
1102     LastDwarfSection->MemorySize = Address - LastDwarfSection->Address;
1103   }
1104 
1105   SymbolTableEntryCount = SymbolTableIndex;
1106 
1107   // Calculate the RawPointer value for each section.
1108   uint64_t RawPointer =
1109       (is64Bit() ? (XCOFF::FileHeaderSize64 +
1110                     SectionCount * XCOFF::SectionHeaderSize64)
1111                  : (XCOFF::FileHeaderSize32 +
1112                     SectionCount * XCOFF::SectionHeaderSize32)) +
1113       auxiliaryHeaderSize();
1114 
1115   for (auto *Sec : Sections) {
1116     if (Sec->Index == SectionEntry::UninitializedIndex || Sec->IsVirtual)
1117       continue;
1118 
1119     Sec->FileOffsetToData = RawPointer;
1120     RawPointer += Sec->Size;
1121     if (RawPointer > MaxRawDataSize)
1122       report_fatal_error("Section raw data overflowed this object file.");
1123   }
1124 
1125   // Increase the raw pointer for the padding bytes between csect sections and
1126   // DWARF sections.
1127   if (!DwarfSections.empty())
1128     RawPointer += PaddingsBeforeDwarf;
1129 
1130   for (auto &DwarfSection : DwarfSections) {
1131     DwarfSection.FileOffsetToData = RawPointer;
1132 
1133     RawPointer += DwarfSection.MemorySize;
1134 
1135     assert(RawPointer <= MaxRawDataSize &&
1136            "Section raw data overflowed this object file.");
1137   }
1138 
1139   RelocationEntryOffset = RawPointer;
1140 }
1141 
1142 void XCOFFObjectWriter::writeSectionForControlSectionEntry(
1143     const MCAssembler &Asm, const MCAsmLayout &Layout,
1144     const CsectSectionEntry &CsectEntry, uint64_t &CurrentAddressLocation) {
1145   // Nothing to write for this Section.
1146   if (CsectEntry.Index == SectionEntry::UninitializedIndex)
1147     return;
1148 
1149   // There could be a gap (without corresponding zero padding) between
1150   // sections.
1151   // There could be a gap (without corresponding zero padding) between
1152   // sections.
1153   assert(((CurrentAddressLocation <= CsectEntry.Address) ||
1154           (CsectEntry.Flags == XCOFF::STYP_TDATA) ||
1155           (CsectEntry.Flags == XCOFF::STYP_TBSS)) &&
1156          "CurrentAddressLocation should be less than or equal to section "
1157          "address if the section is not TData or TBSS.");
1158 
1159   CurrentAddressLocation = CsectEntry.Address;
1160 
1161   // For virtual sections, nothing to write. But need to increase
1162   // CurrentAddressLocation for later sections like DWARF section has a correct
1163   // writing location.
1164   if (CsectEntry.IsVirtual) {
1165     CurrentAddressLocation += CsectEntry.Size;
1166     return;
1167   }
1168 
1169   for (const auto &Group : CsectEntry.Groups) {
1170     for (const auto &Csect : *Group) {
1171       if (uint32_t PaddingSize = Csect.Address - CurrentAddressLocation)
1172         W.OS.write_zeros(PaddingSize);
1173       if (Csect.Size)
1174         Asm.writeSectionData(W.OS, Csect.MCSec, Layout);
1175       CurrentAddressLocation = Csect.Address + Csect.Size;
1176     }
1177   }
1178 
1179   // The size of the tail padding in a section is the end virtual address of
1180   // the current section minus the the end virtual address of the last csect
1181   // in that section.
1182   if (uint64_t PaddingSize =
1183           CsectEntry.Address + CsectEntry.Size - CurrentAddressLocation) {
1184     W.OS.write_zeros(PaddingSize);
1185     CurrentAddressLocation += PaddingSize;
1186   }
1187 }
1188 
1189 void XCOFFObjectWriter::writeSectionForDwarfSectionEntry(
1190     const MCAssembler &Asm, const MCAsmLayout &Layout,
1191     const DwarfSectionEntry &DwarfEntry, uint64_t &CurrentAddressLocation) {
1192   // There could be a gap (without corresponding zero padding) between
1193   // sections. For example DWARF section alignment is bigger than
1194   // DefaultSectionAlign.
1195   assert(CurrentAddressLocation <= DwarfEntry.Address &&
1196          "CurrentAddressLocation should be less than or equal to section "
1197          "address.");
1198 
1199   if (uint64_t PaddingSize = DwarfEntry.Address - CurrentAddressLocation)
1200     W.OS.write_zeros(PaddingSize);
1201 
1202   if (DwarfEntry.Size)
1203     Asm.writeSectionData(W.OS, DwarfEntry.DwarfSect->MCSec, Layout);
1204 
1205   CurrentAddressLocation = DwarfEntry.Address + DwarfEntry.Size;
1206 
1207   // DWARF section size is not aligned to DefaultSectionAlign.
1208   // Make sure CurrentAddressLocation is aligned to DefaultSectionAlign.
1209   uint32_t Mod = CurrentAddressLocation % DefaultSectionAlign;
1210   uint32_t TailPaddingSize = Mod ? DefaultSectionAlign - Mod : 0;
1211   if (TailPaddingSize)
1212     W.OS.write_zeros(TailPaddingSize);
1213 
1214   CurrentAddressLocation += TailPaddingSize;
1215 }
1216 
1217 // Takes the log base 2 of the alignment and shifts the result into the 5 most
1218 // significant bits of a byte, then or's in the csect type into the least
1219 // significant 3 bits.
1220 uint8_t getEncodedType(const MCSectionXCOFF *Sec) {
1221   unsigned Align = Sec->getAlignment();
1222   assert(isPowerOf2_32(Align) && "Alignment must be a power of 2.");
1223   unsigned Log2Align = Log2_32(Align);
1224   // Result is a number in the range [0, 31] which fits in the 5 least
1225   // significant bits. Shift this value into the 5 most significant bits, and
1226   // bitwise-or in the csect type.
1227   uint8_t EncodedAlign = Log2Align << 3;
1228   return EncodedAlign | Sec->getCSectType();
1229 }
1230 
1231 } // end anonymous namespace
1232 
1233 std::unique_ptr<MCObjectWriter>
1234 llvm::createXCOFFObjectWriter(std::unique_ptr<MCXCOFFObjectTargetWriter> MOTW,
1235                               raw_pwrite_stream &OS) {
1236   return std::make_unique<XCOFFObjectWriter>(std::move(MOTW), OS);
1237 }
1238