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