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