XCOFFObjectWriter.cpp 58 KB

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