XCOFFObjectWriter.cpp 44 KB

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