WinCOFFObjectWriter.cpp 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179
  1. //===- llvm/MC/WinCOFFObjectWriter.cpp ------------------------------------===//
  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 contains an implementation of a Win32 COFF object file writer.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/ADT/DenseMap.h"
  13. #include "llvm/ADT/DenseSet.h"
  14. #include "llvm/ADT/STLExtras.h"
  15. #include "llvm/ADT/SmallString.h"
  16. #include "llvm/ADT/SmallVector.h"
  17. #include "llvm/ADT/StringRef.h"
  18. #include "llvm/ADT/Twine.h"
  19. #include "llvm/BinaryFormat/COFF.h"
  20. #include "llvm/MC/MCAsmLayout.h"
  21. #include "llvm/MC/MCAssembler.h"
  22. #include "llvm/MC/MCContext.h"
  23. #include "llvm/MC/MCExpr.h"
  24. #include "llvm/MC/MCFixup.h"
  25. #include "llvm/MC/MCFragment.h"
  26. #include "llvm/MC/MCObjectWriter.h"
  27. #include "llvm/MC/MCSection.h"
  28. #include "llvm/MC/MCSectionCOFF.h"
  29. #include "llvm/MC/MCSymbol.h"
  30. #include "llvm/MC/MCSymbolCOFF.h"
  31. #include "llvm/MC/MCValue.h"
  32. #include "llvm/MC/MCWinCOFFObjectWriter.h"
  33. #include "llvm/MC/StringTableBuilder.h"
  34. #include "llvm/Support/CRC.h"
  35. #include "llvm/Support/Casting.h"
  36. #include "llvm/Support/EndianStream.h"
  37. #include "llvm/Support/ErrorHandling.h"
  38. #include "llvm/Support/LEB128.h"
  39. #include "llvm/Support/MathExtras.h"
  40. #include "llvm/Support/raw_ostream.h"
  41. #include <algorithm>
  42. #include <cassert>
  43. #include <cstdint>
  44. #include <cstring>
  45. #include <ctime>
  46. #include <memory>
  47. #include <string>
  48. #include <vector>
  49. using namespace llvm;
  50. using llvm::support::endian::write32le;
  51. #define DEBUG_TYPE "WinCOFFObjectWriter"
  52. namespace {
  53. constexpr int OffsetLabelIntervalBits = 20;
  54. using name = SmallString<COFF::NameSize>;
  55. enum AuxiliaryType {
  56. ATWeakExternal,
  57. ATFile,
  58. ATSectionDefinition
  59. };
  60. struct AuxSymbol {
  61. AuxiliaryType AuxType;
  62. COFF::Auxiliary Aux;
  63. };
  64. class COFFSection;
  65. class COFFSymbol {
  66. public:
  67. COFF::symbol Data = {};
  68. using AuxiliarySymbols = SmallVector<AuxSymbol, 1>;
  69. name Name;
  70. int Index;
  71. AuxiliarySymbols Aux;
  72. COFFSymbol *Other = nullptr;
  73. COFFSection *Section = nullptr;
  74. int Relocations = 0;
  75. const MCSymbol *MC = nullptr;
  76. COFFSymbol(StringRef Name) : Name(Name) {}
  77. void set_name_offset(uint32_t Offset);
  78. int64_t getIndex() const { return Index; }
  79. void setIndex(int Value) {
  80. Index = Value;
  81. if (MC)
  82. MC->setIndex(static_cast<uint32_t>(Value));
  83. }
  84. };
  85. // This class contains staging data for a COFF relocation entry.
  86. struct COFFRelocation {
  87. COFF::relocation Data;
  88. COFFSymbol *Symb = nullptr;
  89. COFFRelocation() = default;
  90. static size_t size() { return COFF::RelocationSize; }
  91. };
  92. using relocations = std::vector<COFFRelocation>;
  93. class COFFSection {
  94. public:
  95. COFF::section Header = {};
  96. std::string Name;
  97. int Number;
  98. MCSectionCOFF const *MCSection = nullptr;
  99. COFFSymbol *Symbol = nullptr;
  100. relocations Relocations;
  101. COFFSection(StringRef Name) : Name(std::string(Name)) {}
  102. SmallVector<COFFSymbol *, 1> OffsetSymbols;
  103. };
  104. class WinCOFFObjectWriter : public MCObjectWriter {
  105. public:
  106. support::endian::Writer W;
  107. using symbols = std::vector<std::unique_ptr<COFFSymbol>>;
  108. using sections = std::vector<std::unique_ptr<COFFSection>>;
  109. using symbol_map = DenseMap<MCSymbol const *, COFFSymbol *>;
  110. using section_map = DenseMap<MCSection const *, COFFSection *>;
  111. using symbol_list = DenseSet<COFFSymbol *>;
  112. std::unique_ptr<MCWinCOFFObjectTargetWriter> TargetObjectWriter;
  113. // Root level file contents.
  114. COFF::header Header = {};
  115. sections Sections;
  116. symbols Symbols;
  117. StringTableBuilder Strings{StringTableBuilder::WinCOFF};
  118. // Maps used during object file creation.
  119. section_map SectionMap;
  120. symbol_map SymbolMap;
  121. symbol_list WeakDefaults;
  122. bool UseBigObj;
  123. bool UseOffsetLabels = false;
  124. MCSectionCOFF *AddrsigSection;
  125. MCSectionCOFF *CGProfileSection = nullptr;
  126. WinCOFFObjectWriter(std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW,
  127. raw_pwrite_stream &OS);
  128. void reset() override {
  129. memset(&Header, 0, sizeof(Header));
  130. Header.Machine = TargetObjectWriter->getMachine();
  131. Sections.clear();
  132. Symbols.clear();
  133. Strings.clear();
  134. SectionMap.clear();
  135. SymbolMap.clear();
  136. WeakDefaults.clear();
  137. MCObjectWriter::reset();
  138. }
  139. COFFSymbol *createSymbol(StringRef Name);
  140. COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol *Symbol);
  141. COFFSection *createSection(StringRef Name);
  142. void defineSection(MCSectionCOFF const &Sec, const MCAsmLayout &Layout);
  143. COFFSymbol *getLinkedSymbol(const MCSymbol &Symbol);
  144. void DefineSymbol(const MCSymbol &Symbol, MCAssembler &Assembler,
  145. const MCAsmLayout &Layout);
  146. void SetSymbolName(COFFSymbol &S);
  147. void SetSectionName(COFFSection &S);
  148. bool IsPhysicalSection(COFFSection *S);
  149. // Entity writing methods.
  150. void WriteFileHeader(const COFF::header &Header);
  151. void WriteSymbol(const COFFSymbol &S);
  152. void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S);
  153. void writeSectionHeaders();
  154. void WriteRelocation(const COFF::relocation &R);
  155. uint32_t writeSectionContents(MCAssembler &Asm, const MCAsmLayout &Layout,
  156. const MCSection &MCSec);
  157. void writeSection(MCAssembler &Asm, const MCAsmLayout &Layout,
  158. const COFFSection &Sec, const MCSection &MCSec);
  159. // MCObjectWriter interface implementation.
  160. void executePostLayoutBinding(MCAssembler &Asm,
  161. const MCAsmLayout &Layout) override;
  162. bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
  163. const MCSymbol &SymA,
  164. const MCFragment &FB, bool InSet,
  165. bool IsPCRel) const override;
  166. void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
  167. const MCFragment *Fragment, const MCFixup &Fixup,
  168. MCValue Target, uint64_t &FixedValue) override;
  169. void createFileSymbols(MCAssembler &Asm);
  170. void setWeakDefaultNames();
  171. void assignSectionNumbers();
  172. void assignFileOffsets(MCAssembler &Asm, const MCAsmLayout &Layout);
  173. uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
  174. };
  175. } // end anonymous namespace
  176. //------------------------------------------------------------------------------
  177. // Symbol class implementation
  178. // In the case that the name does not fit within 8 bytes, the offset
  179. // into the string table is stored in the last 4 bytes instead, leaving
  180. // the first 4 bytes as 0.
  181. void COFFSymbol::set_name_offset(uint32_t Offset) {
  182. write32le(Data.Name + 0, 0);
  183. write32le(Data.Name + 4, Offset);
  184. }
  185. //------------------------------------------------------------------------------
  186. // WinCOFFObjectWriter class implementation
  187. WinCOFFObjectWriter::WinCOFFObjectWriter(
  188. std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS)
  189. : W(OS, support::little), TargetObjectWriter(std::move(MOTW)) {
  190. Header.Machine = TargetObjectWriter->getMachine();
  191. // Some relocations on ARM64 (the 21 bit ADRP relocations) have a slightly
  192. // limited range for the immediate offset (+/- 1 MB); create extra offset
  193. // label symbols with regular intervals to allow referencing a
  194. // non-temporary symbol that is close enough.
  195. UseOffsetLabels = Header.Machine == COFF::IMAGE_FILE_MACHINE_ARM64;
  196. }
  197. COFFSymbol *WinCOFFObjectWriter::createSymbol(StringRef Name) {
  198. Symbols.push_back(std::make_unique<COFFSymbol>(Name));
  199. return Symbols.back().get();
  200. }
  201. COFFSymbol *WinCOFFObjectWriter::GetOrCreateCOFFSymbol(const MCSymbol *Symbol) {
  202. COFFSymbol *&Ret = SymbolMap[Symbol];
  203. if (!Ret)
  204. Ret = createSymbol(Symbol->getName());
  205. return Ret;
  206. }
  207. COFFSection *WinCOFFObjectWriter::createSection(StringRef Name) {
  208. Sections.emplace_back(std::make_unique<COFFSection>(Name));
  209. return Sections.back().get();
  210. }
  211. static uint32_t getAlignment(const MCSectionCOFF &Sec) {
  212. switch (Sec.getAlign().value()) {
  213. case 1:
  214. return COFF::IMAGE_SCN_ALIGN_1BYTES;
  215. case 2:
  216. return COFF::IMAGE_SCN_ALIGN_2BYTES;
  217. case 4:
  218. return COFF::IMAGE_SCN_ALIGN_4BYTES;
  219. case 8:
  220. return COFF::IMAGE_SCN_ALIGN_8BYTES;
  221. case 16:
  222. return COFF::IMAGE_SCN_ALIGN_16BYTES;
  223. case 32:
  224. return COFF::IMAGE_SCN_ALIGN_32BYTES;
  225. case 64:
  226. return COFF::IMAGE_SCN_ALIGN_64BYTES;
  227. case 128:
  228. return COFF::IMAGE_SCN_ALIGN_128BYTES;
  229. case 256:
  230. return COFF::IMAGE_SCN_ALIGN_256BYTES;
  231. case 512:
  232. return COFF::IMAGE_SCN_ALIGN_512BYTES;
  233. case 1024:
  234. return COFF::IMAGE_SCN_ALIGN_1024BYTES;
  235. case 2048:
  236. return COFF::IMAGE_SCN_ALIGN_2048BYTES;
  237. case 4096:
  238. return COFF::IMAGE_SCN_ALIGN_4096BYTES;
  239. case 8192:
  240. return COFF::IMAGE_SCN_ALIGN_8192BYTES;
  241. }
  242. llvm_unreachable("unsupported section alignment");
  243. }
  244. /// This function takes a section data object from the assembler
  245. /// and creates the associated COFF section staging object.
  246. void WinCOFFObjectWriter::defineSection(const MCSectionCOFF &MCSec,
  247. const MCAsmLayout &Layout) {
  248. COFFSection *Section = createSection(MCSec.getName());
  249. COFFSymbol *Symbol = createSymbol(MCSec.getName());
  250. Section->Symbol = Symbol;
  251. Symbol->Section = Section;
  252. Symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC;
  253. // Create a COMDAT symbol if needed.
  254. if (MCSec.getSelection() != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
  255. if (const MCSymbol *S = MCSec.getCOMDATSymbol()) {
  256. COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(S);
  257. if (COMDATSymbol->Section)
  258. report_fatal_error("two sections have the same comdat");
  259. COMDATSymbol->Section = Section;
  260. }
  261. }
  262. // In this case the auxiliary symbol is a Section Definition.
  263. Symbol->Aux.resize(1);
  264. Symbol->Aux[0] = {};
  265. Symbol->Aux[0].AuxType = ATSectionDefinition;
  266. Symbol->Aux[0].Aux.SectionDefinition.Selection = MCSec.getSelection();
  267. // Set section alignment.
  268. Section->Header.Characteristics = MCSec.getCharacteristics();
  269. Section->Header.Characteristics |= getAlignment(MCSec);
  270. // Bind internal COFF section to MC section.
  271. Section->MCSection = &MCSec;
  272. SectionMap[&MCSec] = Section;
  273. if (UseOffsetLabels && !MCSec.getFragmentList().empty()) {
  274. const uint32_t Interval = 1 << OffsetLabelIntervalBits;
  275. uint32_t N = 1;
  276. for (uint32_t Off = Interval, E = Layout.getSectionAddressSize(&MCSec);
  277. Off < E; Off += Interval) {
  278. auto Name = ("$L" + MCSec.getName() + "_" + Twine(N++)).str();
  279. COFFSymbol *Label = createSymbol(Name);
  280. Label->Section = Section;
  281. Label->Data.StorageClass = COFF::IMAGE_SYM_CLASS_LABEL;
  282. Label->Data.Value = Off;
  283. Section->OffsetSymbols.push_back(Label);
  284. }
  285. }
  286. }
  287. static uint64_t getSymbolValue(const MCSymbol &Symbol,
  288. const MCAsmLayout &Layout) {
  289. if (Symbol.isCommon() && Symbol.isExternal())
  290. return Symbol.getCommonSize();
  291. uint64_t Res;
  292. if (!Layout.getSymbolOffset(Symbol, Res))
  293. return 0;
  294. return Res;
  295. }
  296. COFFSymbol *WinCOFFObjectWriter::getLinkedSymbol(const MCSymbol &Symbol) {
  297. if (!Symbol.isVariable())
  298. return nullptr;
  299. const MCSymbolRefExpr *SymRef =
  300. dyn_cast<MCSymbolRefExpr>(Symbol.getVariableValue());
  301. if (!SymRef)
  302. return nullptr;
  303. const MCSymbol &Aliasee = SymRef->getSymbol();
  304. if (Aliasee.isUndefined() || Aliasee.isExternal())
  305. return GetOrCreateCOFFSymbol(&Aliasee);
  306. else
  307. return nullptr;
  308. }
  309. /// This function takes a symbol data object from the assembler
  310. /// and creates the associated COFF symbol staging object.
  311. void WinCOFFObjectWriter::DefineSymbol(const MCSymbol &MCSym,
  312. MCAssembler &Assembler,
  313. const MCAsmLayout &Layout) {
  314. COFFSymbol *Sym = GetOrCreateCOFFSymbol(&MCSym);
  315. const MCSymbol *Base = Layout.getBaseSymbol(MCSym);
  316. COFFSection *Sec = nullptr;
  317. if (Base && Base->getFragment()) {
  318. Sec = SectionMap[Base->getFragment()->getParent()];
  319. if (Sym->Section && Sym->Section != Sec)
  320. report_fatal_error("conflicting sections for symbol");
  321. }
  322. COFFSymbol *Local = nullptr;
  323. if (cast<MCSymbolCOFF>(MCSym).isWeakExternal()) {
  324. Sym->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
  325. Sym->Section = nullptr;
  326. COFFSymbol *WeakDefault = getLinkedSymbol(MCSym);
  327. if (!WeakDefault) {
  328. std::string WeakName = (".weak." + MCSym.getName() + ".default").str();
  329. WeakDefault = createSymbol(WeakName);
  330. if (!Sec)
  331. WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
  332. else
  333. WeakDefault->Section = Sec;
  334. WeakDefaults.insert(WeakDefault);
  335. Local = WeakDefault;
  336. }
  337. Sym->Other = WeakDefault;
  338. // Setup the Weak External auxiliary symbol.
  339. Sym->Aux.resize(1);
  340. memset(&Sym->Aux[0], 0, sizeof(Sym->Aux[0]));
  341. Sym->Aux[0].AuxType = ATWeakExternal;
  342. Sym->Aux[0].Aux.WeakExternal.TagIndex = 0;
  343. Sym->Aux[0].Aux.WeakExternal.Characteristics =
  344. COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS;
  345. } else {
  346. if (!Base)
  347. Sym->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
  348. else
  349. Sym->Section = Sec;
  350. Local = Sym;
  351. }
  352. if (Local) {
  353. Local->Data.Value = getSymbolValue(MCSym, Layout);
  354. const MCSymbolCOFF &SymbolCOFF = cast<MCSymbolCOFF>(MCSym);
  355. Local->Data.Type = SymbolCOFF.getType();
  356. Local->Data.StorageClass = SymbolCOFF.getClass();
  357. // If no storage class was specified in the streamer, define it here.
  358. if (Local->Data.StorageClass == COFF::IMAGE_SYM_CLASS_NULL) {
  359. bool IsExternal = MCSym.isExternal() ||
  360. (!MCSym.getFragment() && !MCSym.isVariable());
  361. Local->Data.StorageClass = IsExternal ? COFF::IMAGE_SYM_CLASS_EXTERNAL
  362. : COFF::IMAGE_SYM_CLASS_STATIC;
  363. }
  364. }
  365. Sym->MC = &MCSym;
  366. }
  367. void WinCOFFObjectWriter::SetSectionName(COFFSection &S) {
  368. if (S.Name.size() <= COFF::NameSize) {
  369. std::memcpy(S.Header.Name, S.Name.c_str(), S.Name.size());
  370. return;
  371. }
  372. uint64_t StringTableEntry = Strings.getOffset(S.Name);
  373. if (!COFF::encodeSectionName(S.Header.Name, StringTableEntry))
  374. report_fatal_error("COFF string table is greater than 64 GB.");
  375. }
  376. void WinCOFFObjectWriter::SetSymbolName(COFFSymbol &S) {
  377. if (S.Name.size() > COFF::NameSize)
  378. S.set_name_offset(Strings.getOffset(S.Name));
  379. else
  380. std::memcpy(S.Data.Name, S.Name.c_str(), S.Name.size());
  381. }
  382. bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) {
  383. return (S->Header.Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) ==
  384. 0;
  385. }
  386. //------------------------------------------------------------------------------
  387. // entity writing methods
  388. void WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) {
  389. if (UseBigObj) {
  390. W.write<uint16_t>(COFF::IMAGE_FILE_MACHINE_UNKNOWN);
  391. W.write<uint16_t>(0xFFFF);
  392. W.write<uint16_t>(COFF::BigObjHeader::MinBigObjectVersion);
  393. W.write<uint16_t>(Header.Machine);
  394. W.write<uint32_t>(Header.TimeDateStamp);
  395. W.OS.write(COFF::BigObjMagic, sizeof(COFF::BigObjMagic));
  396. W.write<uint32_t>(0);
  397. W.write<uint32_t>(0);
  398. W.write<uint32_t>(0);
  399. W.write<uint32_t>(0);
  400. W.write<uint32_t>(Header.NumberOfSections);
  401. W.write<uint32_t>(Header.PointerToSymbolTable);
  402. W.write<uint32_t>(Header.NumberOfSymbols);
  403. } else {
  404. W.write<uint16_t>(Header.Machine);
  405. W.write<uint16_t>(static_cast<int16_t>(Header.NumberOfSections));
  406. W.write<uint32_t>(Header.TimeDateStamp);
  407. W.write<uint32_t>(Header.PointerToSymbolTable);
  408. W.write<uint32_t>(Header.NumberOfSymbols);
  409. W.write<uint16_t>(Header.SizeOfOptionalHeader);
  410. W.write<uint16_t>(Header.Characteristics);
  411. }
  412. }
  413. void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol &S) {
  414. W.OS.write(S.Data.Name, COFF::NameSize);
  415. W.write<uint32_t>(S.Data.Value);
  416. if (UseBigObj)
  417. W.write<uint32_t>(S.Data.SectionNumber);
  418. else
  419. W.write<uint16_t>(static_cast<int16_t>(S.Data.SectionNumber));
  420. W.write<uint16_t>(S.Data.Type);
  421. W.OS << char(S.Data.StorageClass);
  422. W.OS << char(S.Data.NumberOfAuxSymbols);
  423. WriteAuxiliarySymbols(S.Aux);
  424. }
  425. void WinCOFFObjectWriter::WriteAuxiliarySymbols(
  426. const COFFSymbol::AuxiliarySymbols &S) {
  427. for (const AuxSymbol &i : S) {
  428. switch (i.AuxType) {
  429. case ATWeakExternal:
  430. W.write<uint32_t>(i.Aux.WeakExternal.TagIndex);
  431. W.write<uint32_t>(i.Aux.WeakExternal.Characteristics);
  432. W.OS.write_zeros(sizeof(i.Aux.WeakExternal.unused));
  433. if (UseBigObj)
  434. W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size);
  435. break;
  436. case ATFile:
  437. W.OS.write(reinterpret_cast<const char *>(&i.Aux),
  438. UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size);
  439. break;
  440. case ATSectionDefinition:
  441. W.write<uint32_t>(i.Aux.SectionDefinition.Length);
  442. W.write<uint16_t>(i.Aux.SectionDefinition.NumberOfRelocations);
  443. W.write<uint16_t>(i.Aux.SectionDefinition.NumberOfLinenumbers);
  444. W.write<uint32_t>(i.Aux.SectionDefinition.CheckSum);
  445. W.write<uint16_t>(static_cast<int16_t>(i.Aux.SectionDefinition.Number));
  446. W.OS << char(i.Aux.SectionDefinition.Selection);
  447. W.OS.write_zeros(sizeof(i.Aux.SectionDefinition.unused));
  448. W.write<uint16_t>(static_cast<int16_t>(i.Aux.SectionDefinition.Number >> 16));
  449. if (UseBigObj)
  450. W.OS.write_zeros(COFF::Symbol32Size - COFF::Symbol16Size);
  451. break;
  452. }
  453. }
  454. }
  455. // Write the section header.
  456. void WinCOFFObjectWriter::writeSectionHeaders() {
  457. // Section numbers must be monotonically increasing in the section
  458. // header, but our Sections array is not sorted by section number,
  459. // so make a copy of Sections and sort it.
  460. std::vector<COFFSection *> Arr;
  461. for (auto &Section : Sections)
  462. Arr.push_back(Section.get());
  463. llvm::sort(Arr, [](const COFFSection *A, const COFFSection *B) {
  464. return A->Number < B->Number;
  465. });
  466. for (auto &Section : Arr) {
  467. if (Section->Number == -1)
  468. continue;
  469. COFF::section &S = Section->Header;
  470. if (Section->Relocations.size() >= 0xffff)
  471. S.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL;
  472. W.OS.write(S.Name, COFF::NameSize);
  473. W.write<uint32_t>(S.VirtualSize);
  474. W.write<uint32_t>(S.VirtualAddress);
  475. W.write<uint32_t>(S.SizeOfRawData);
  476. W.write<uint32_t>(S.PointerToRawData);
  477. W.write<uint32_t>(S.PointerToRelocations);
  478. W.write<uint32_t>(S.PointerToLineNumbers);
  479. W.write<uint16_t>(S.NumberOfRelocations);
  480. W.write<uint16_t>(S.NumberOfLineNumbers);
  481. W.write<uint32_t>(S.Characteristics);
  482. }
  483. }
  484. void WinCOFFObjectWriter::WriteRelocation(const COFF::relocation &R) {
  485. W.write<uint32_t>(R.VirtualAddress);
  486. W.write<uint32_t>(R.SymbolTableIndex);
  487. W.write<uint16_t>(R.Type);
  488. }
  489. // Write MCSec's contents. What this function does is essentially
  490. // "Asm.writeSectionData(&MCSec, Layout)", but it's a bit complicated
  491. // because it needs to compute a CRC.
  492. uint32_t WinCOFFObjectWriter::writeSectionContents(MCAssembler &Asm,
  493. const MCAsmLayout &Layout,
  494. const MCSection &MCSec) {
  495. // Save the contents of the section to a temporary buffer, we need this
  496. // to CRC the data before we dump it into the object file.
  497. SmallVector<char, 128> Buf;
  498. raw_svector_ostream VecOS(Buf);
  499. Asm.writeSectionData(VecOS, &MCSec, Layout);
  500. // Write the section contents to the object file.
  501. W.OS << Buf;
  502. // Calculate our CRC with an initial value of '0', this is not how
  503. // JamCRC is specified but it aligns with the expected output.
  504. JamCRC JC(/*Init=*/0);
  505. JC.update(ArrayRef(reinterpret_cast<uint8_t *>(Buf.data()), Buf.size()));
  506. return JC.getCRC();
  507. }
  508. void WinCOFFObjectWriter::writeSection(MCAssembler &Asm,
  509. const MCAsmLayout &Layout,
  510. const COFFSection &Sec,
  511. const MCSection &MCSec) {
  512. if (Sec.Number == -1)
  513. return;
  514. // Write the section contents.
  515. if (Sec.Header.PointerToRawData != 0) {
  516. assert(W.OS.tell() == Sec.Header.PointerToRawData &&
  517. "Section::PointerToRawData is insane!");
  518. uint32_t CRC = writeSectionContents(Asm, Layout, MCSec);
  519. // Update the section definition auxiliary symbol to record the CRC.
  520. COFFSection *Sec = SectionMap[&MCSec];
  521. COFFSymbol::AuxiliarySymbols &AuxSyms = Sec->Symbol->Aux;
  522. assert(AuxSyms.size() == 1 && AuxSyms[0].AuxType == ATSectionDefinition);
  523. AuxSymbol &SecDef = AuxSyms[0];
  524. SecDef.Aux.SectionDefinition.CheckSum = CRC;
  525. }
  526. // Write relocations for this section.
  527. if (Sec.Relocations.empty()) {
  528. assert(Sec.Header.PointerToRelocations == 0 &&
  529. "Section::PointerToRelocations is insane!");
  530. return;
  531. }
  532. assert(W.OS.tell() == Sec.Header.PointerToRelocations &&
  533. "Section::PointerToRelocations is insane!");
  534. if (Sec.Relocations.size() >= 0xffff) {
  535. // In case of overflow, write actual relocation count as first
  536. // relocation. Including the synthetic reloc itself (+ 1).
  537. COFF::relocation R;
  538. R.VirtualAddress = Sec.Relocations.size() + 1;
  539. R.SymbolTableIndex = 0;
  540. R.Type = 0;
  541. WriteRelocation(R);
  542. }
  543. for (const auto &Relocation : Sec.Relocations)
  544. WriteRelocation(Relocation.Data);
  545. }
  546. ////////////////////////////////////////////////////////////////////////////////
  547. // MCObjectWriter interface implementations
  548. void WinCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
  549. const MCAsmLayout &Layout) {
  550. if (EmitAddrsigSection) {
  551. AddrsigSection = Asm.getContext().getCOFFSection(
  552. ".llvm_addrsig", COFF::IMAGE_SCN_LNK_REMOVE,
  553. SectionKind::getMetadata());
  554. Asm.registerSection(*AddrsigSection);
  555. }
  556. if (!Asm.CGProfile.empty()) {
  557. CGProfileSection = Asm.getContext().getCOFFSection(
  558. ".llvm.call-graph-profile", COFF::IMAGE_SCN_LNK_REMOVE,
  559. SectionKind::getMetadata());
  560. Asm.registerSection(*CGProfileSection);
  561. }
  562. // "Define" each section & symbol. This creates section & symbol
  563. // entries in the staging area.
  564. for (const auto &Section : Asm)
  565. defineSection(static_cast<const MCSectionCOFF &>(Section), Layout);
  566. for (const MCSymbol &Symbol : Asm.symbols())
  567. if (!Symbol.isTemporary())
  568. DefineSymbol(Symbol, Asm, Layout);
  569. }
  570. bool WinCOFFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
  571. const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB,
  572. bool InSet, bool IsPCRel) const {
  573. // Don't drop relocations between functions, even if they are in the same text
  574. // section. Multiple Visual C++ linker features depend on having the
  575. // relocations present. The /INCREMENTAL flag will cause these relocations to
  576. // point to thunks, and the /GUARD:CF flag assumes that it can use relocations
  577. // to approximate the set of all address taken functions. LLD's implementation
  578. // of /GUARD:CF also relies on the existance of these relocations.
  579. uint16_t Type = cast<MCSymbolCOFF>(SymA).getType();
  580. if ((Type >> COFF::SCT_COMPLEX_TYPE_SHIFT) == COFF::IMAGE_SYM_DTYPE_FUNCTION)
  581. return false;
  582. return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB,
  583. InSet, IsPCRel);
  584. }
  585. void WinCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
  586. const MCAsmLayout &Layout,
  587. const MCFragment *Fragment,
  588. const MCFixup &Fixup, MCValue Target,
  589. uint64_t &FixedValue) {
  590. assert(Target.getSymA() && "Relocation must reference a symbol!");
  591. const MCSymbol &A = Target.getSymA()->getSymbol();
  592. if (!A.isRegistered()) {
  593. Asm.getContext().reportError(Fixup.getLoc(),
  594. Twine("symbol '") + A.getName() +
  595. "' can not be undefined");
  596. return;
  597. }
  598. if (A.isTemporary() && A.isUndefined()) {
  599. Asm.getContext().reportError(Fixup.getLoc(),
  600. Twine("assembler label '") + A.getName() +
  601. "' can not be undefined");
  602. return;
  603. }
  604. MCSection *MCSec = Fragment->getParent();
  605. // Mark this symbol as requiring an entry in the symbol table.
  606. assert(SectionMap.find(MCSec) != SectionMap.end() &&
  607. "Section must already have been defined in executePostLayoutBinding!");
  608. COFFSection *Sec = SectionMap[MCSec];
  609. const MCSymbolRefExpr *SymB = Target.getSymB();
  610. if (SymB) {
  611. const MCSymbol *B = &SymB->getSymbol();
  612. if (!B->getFragment()) {
  613. Asm.getContext().reportError(
  614. Fixup.getLoc(),
  615. Twine("symbol '") + B->getName() +
  616. "' can not be undefined in a subtraction expression");
  617. return;
  618. }
  619. // Offset of the symbol in the section
  620. int64_t OffsetOfB = Layout.getSymbolOffset(*B);
  621. // Offset of the relocation in the section
  622. int64_t OffsetOfRelocation =
  623. Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
  624. FixedValue = (OffsetOfRelocation - OffsetOfB) + Target.getConstant();
  625. } else {
  626. FixedValue = Target.getConstant();
  627. }
  628. COFFRelocation Reloc;
  629. Reloc.Data.SymbolTableIndex = 0;
  630. Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment);
  631. // Turn relocations for temporary symbols into section relocations.
  632. if (A.isTemporary()) {
  633. MCSection *TargetSection = &A.getSection();
  634. assert(
  635. SectionMap.find(TargetSection) != SectionMap.end() &&
  636. "Section must already have been defined in executePostLayoutBinding!");
  637. COFFSection *Section = SectionMap[TargetSection];
  638. Reloc.Symb = Section->Symbol;
  639. FixedValue += Layout.getSymbolOffset(A);
  640. // Technically, we should do the final adjustments of FixedValue (below)
  641. // before picking an offset symbol, otherwise we might choose one which
  642. // is slightly too far away. The relocations where it really matters
  643. // (arm64 adrp relocations) don't get any offset though.
  644. if (UseOffsetLabels && !Section->OffsetSymbols.empty()) {
  645. uint64_t LabelIndex = FixedValue >> OffsetLabelIntervalBits;
  646. if (LabelIndex > 0) {
  647. if (LabelIndex <= Section->OffsetSymbols.size())
  648. Reloc.Symb = Section->OffsetSymbols[LabelIndex - 1];
  649. else
  650. Reloc.Symb = Section->OffsetSymbols.back();
  651. FixedValue -= Reloc.Symb->Data.Value;
  652. }
  653. }
  654. } else {
  655. assert(
  656. SymbolMap.find(&A) != SymbolMap.end() &&
  657. "Symbol must already have been defined in executePostLayoutBinding!");
  658. Reloc.Symb = SymbolMap[&A];
  659. }
  660. ++Reloc.Symb->Relocations;
  661. Reloc.Data.VirtualAddress += Fixup.getOffset();
  662. Reloc.Data.Type = TargetObjectWriter->getRelocType(
  663. Asm.getContext(), Target, Fixup, SymB, Asm.getBackend());
  664. // The *_REL32 relocations are relative to the end of the relocation,
  665. // not to the start.
  666. if ((Header.Machine == COFF::IMAGE_FILE_MACHINE_AMD64 &&
  667. Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32) ||
  668. (Header.Machine == COFF::IMAGE_FILE_MACHINE_I386 &&
  669. Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32) ||
  670. (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT &&
  671. Reloc.Data.Type == COFF::IMAGE_REL_ARM_REL32) ||
  672. (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARM64 &&
  673. Reloc.Data.Type == COFF::IMAGE_REL_ARM64_REL32))
  674. FixedValue += 4;
  675. if (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT) {
  676. switch (Reloc.Data.Type) {
  677. case COFF::IMAGE_REL_ARM_ABSOLUTE:
  678. case COFF::IMAGE_REL_ARM_ADDR32:
  679. case COFF::IMAGE_REL_ARM_ADDR32NB:
  680. case COFF::IMAGE_REL_ARM_TOKEN:
  681. case COFF::IMAGE_REL_ARM_SECTION:
  682. case COFF::IMAGE_REL_ARM_SECREL:
  683. break;
  684. case COFF::IMAGE_REL_ARM_BRANCH11:
  685. case COFF::IMAGE_REL_ARM_BLX11:
  686. // IMAGE_REL_ARM_BRANCH11 and IMAGE_REL_ARM_BLX11 are only used for
  687. // pre-ARMv7, which implicitly rules it out of ARMNT (it would be valid
  688. // for Windows CE).
  689. case COFF::IMAGE_REL_ARM_BRANCH24:
  690. case COFF::IMAGE_REL_ARM_BLX24:
  691. case COFF::IMAGE_REL_ARM_MOV32A:
  692. // IMAGE_REL_ARM_BRANCH24, IMAGE_REL_ARM_BLX24, IMAGE_REL_ARM_MOV32A are
  693. // only used for ARM mode code, which is documented as being unsupported
  694. // by Windows on ARM. Empirical proof indicates that masm is able to
  695. // generate the relocations however the rest of the MSVC toolchain is
  696. // unable to handle it.
  697. llvm_unreachable("unsupported relocation");
  698. break;
  699. case COFF::IMAGE_REL_ARM_MOV32T:
  700. break;
  701. case COFF::IMAGE_REL_ARM_BRANCH20T:
  702. case COFF::IMAGE_REL_ARM_BRANCH24T:
  703. case COFF::IMAGE_REL_ARM_BLX23T:
  704. // IMAGE_REL_BRANCH20T, IMAGE_REL_ARM_BRANCH24T, IMAGE_REL_ARM_BLX23T all
  705. // perform a 4 byte adjustment to the relocation. Relative branches are
  706. // offset by 4 on ARM, however, because there is no RELA relocations, all
  707. // branches are offset by 4.
  708. FixedValue = FixedValue + 4;
  709. break;
  710. }
  711. }
  712. // The fixed value never makes sense for section indices, ignore it.
  713. if (Fixup.getKind() == FK_SecRel_2)
  714. FixedValue = 0;
  715. if (TargetObjectWriter->recordRelocation(Fixup))
  716. Sec->Relocations.push_back(Reloc);
  717. }
  718. static std::time_t getTime() {
  719. std::time_t Now = time(nullptr);
  720. if (Now < 0 || !isUInt<32>(Now))
  721. return UINT32_MAX;
  722. return Now;
  723. }
  724. // Create .file symbols.
  725. void WinCOFFObjectWriter::createFileSymbols(MCAssembler &Asm) {
  726. for (const std::pair<std::string, size_t> &It : Asm.getFileNames()) {
  727. // round up to calculate the number of auxiliary symbols required
  728. const std::string &Name = It.first;
  729. unsigned SymbolSize = UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size;
  730. unsigned Count = (Name.size() + SymbolSize - 1) / SymbolSize;
  731. COFFSymbol *File = createSymbol(".file");
  732. File->Data.SectionNumber = COFF::IMAGE_SYM_DEBUG;
  733. File->Data.StorageClass = COFF::IMAGE_SYM_CLASS_FILE;
  734. File->Aux.resize(Count);
  735. unsigned Offset = 0;
  736. unsigned Length = Name.size();
  737. for (auto &Aux : File->Aux) {
  738. Aux.AuxType = ATFile;
  739. if (Length > SymbolSize) {
  740. memcpy(&Aux.Aux, Name.c_str() + Offset, SymbolSize);
  741. Length = Length - SymbolSize;
  742. } else {
  743. memcpy(&Aux.Aux, Name.c_str() + Offset, Length);
  744. memset((char *)&Aux.Aux + Length, 0, SymbolSize - Length);
  745. break;
  746. }
  747. Offset += SymbolSize;
  748. }
  749. }
  750. }
  751. void WinCOFFObjectWriter::setWeakDefaultNames() {
  752. if (WeakDefaults.empty())
  753. return;
  754. // If multiple object files use a weak symbol (either with a regular
  755. // defined default, or an absolute zero symbol as default), the defaults
  756. // cause duplicate definitions unless their names are made unique. Look
  757. // for a defined extern symbol, that isn't comdat - that should be unique
  758. // unless there are other duplicate definitions. And if none is found,
  759. // allow picking a comdat symbol, as that's still better than nothing.
  760. COFFSymbol *Unique = nullptr;
  761. for (bool AllowComdat : {false, true}) {
  762. for (auto &Sym : Symbols) {
  763. // Don't include the names of the defaults themselves
  764. if (WeakDefaults.count(Sym.get()))
  765. continue;
  766. // Only consider external symbols
  767. if (Sym->Data.StorageClass != COFF::IMAGE_SYM_CLASS_EXTERNAL)
  768. continue;
  769. // Only consider symbols defined in a section or that are absolute
  770. if (!Sym->Section && Sym->Data.SectionNumber != COFF::IMAGE_SYM_ABSOLUTE)
  771. continue;
  772. if (!AllowComdat && Sym->Section &&
  773. Sym->Section->Header.Characteristics & COFF::IMAGE_SCN_LNK_COMDAT)
  774. continue;
  775. Unique = Sym.get();
  776. break;
  777. }
  778. if (Unique)
  779. break;
  780. }
  781. // If we didn't find any unique symbol to use for the names, just skip this.
  782. if (!Unique)
  783. return;
  784. for (auto *Sym : WeakDefaults) {
  785. Sym->Name.append(".");
  786. Sym->Name.append(Unique->Name);
  787. }
  788. }
  789. static bool isAssociative(const COFFSection &Section) {
  790. return Section.Symbol->Aux[0].Aux.SectionDefinition.Selection ==
  791. COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE;
  792. }
  793. void WinCOFFObjectWriter::assignSectionNumbers() {
  794. size_t I = 1;
  795. auto Assign = [&](COFFSection &Section) {
  796. Section.Number = I;
  797. Section.Symbol->Data.SectionNumber = I;
  798. Section.Symbol->Aux[0].Aux.SectionDefinition.Number = I;
  799. ++I;
  800. };
  801. // Although it is not explicitly requested by the Microsoft COFF spec,
  802. // we should avoid emitting forward associative section references,
  803. // because MSVC link.exe as of 2017 cannot handle that.
  804. for (const std::unique_ptr<COFFSection> &Section : Sections)
  805. if (!isAssociative(*Section))
  806. Assign(*Section);
  807. for (const std::unique_ptr<COFFSection> &Section : Sections)
  808. if (isAssociative(*Section))
  809. Assign(*Section);
  810. }
  811. // Assign file offsets to COFF object file structures.
  812. void WinCOFFObjectWriter::assignFileOffsets(MCAssembler &Asm,
  813. const MCAsmLayout &Layout) {
  814. unsigned Offset = W.OS.tell();
  815. Offset += UseBigObj ? COFF::Header32Size : COFF::Header16Size;
  816. Offset += COFF::SectionSize * Header.NumberOfSections;
  817. for (const auto &Section : Asm) {
  818. COFFSection *Sec = SectionMap[&Section];
  819. if (!Sec || Sec->Number == -1)
  820. continue;
  821. Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(&Section);
  822. if (IsPhysicalSection(Sec)) {
  823. Sec->Header.PointerToRawData = Offset;
  824. Offset += Sec->Header.SizeOfRawData;
  825. }
  826. if (!Sec->Relocations.empty()) {
  827. bool RelocationsOverflow = Sec->Relocations.size() >= 0xffff;
  828. if (RelocationsOverflow) {
  829. // Signal overflow by setting NumberOfRelocations to max value. Actual
  830. // size is found in reloc #0. Microsoft tools understand this.
  831. Sec->Header.NumberOfRelocations = 0xffff;
  832. } else {
  833. Sec->Header.NumberOfRelocations = Sec->Relocations.size();
  834. }
  835. Sec->Header.PointerToRelocations = Offset;
  836. if (RelocationsOverflow) {
  837. // Reloc #0 will contain actual count, so make room for it.
  838. Offset += COFF::RelocationSize;
  839. }
  840. Offset += COFF::RelocationSize * Sec->Relocations.size();
  841. for (auto &Relocation : Sec->Relocations) {
  842. assert(Relocation.Symb->getIndex() != -1);
  843. Relocation.Data.SymbolTableIndex = Relocation.Symb->getIndex();
  844. }
  845. }
  846. assert(Sec->Symbol->Aux.size() == 1 &&
  847. "Section's symbol must have one aux!");
  848. AuxSymbol &Aux = Sec->Symbol->Aux[0];
  849. assert(Aux.AuxType == ATSectionDefinition &&
  850. "Section's symbol's aux symbol must be a Section Definition!");
  851. Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData;
  852. Aux.Aux.SectionDefinition.NumberOfRelocations =
  853. Sec->Header.NumberOfRelocations;
  854. Aux.Aux.SectionDefinition.NumberOfLinenumbers =
  855. Sec->Header.NumberOfLineNumbers;
  856. }
  857. Header.PointerToSymbolTable = Offset;
  858. }
  859. uint64_t WinCOFFObjectWriter::writeObject(MCAssembler &Asm,
  860. const MCAsmLayout &Layout) {
  861. uint64_t StartOffset = W.OS.tell();
  862. if (Sections.size() > INT32_MAX)
  863. report_fatal_error(
  864. "PE COFF object files can't have more than 2147483647 sections");
  865. UseBigObj = Sections.size() > COFF::MaxNumberOfSections16;
  866. Header.NumberOfSections = Sections.size();
  867. Header.NumberOfSymbols = 0;
  868. setWeakDefaultNames();
  869. assignSectionNumbers();
  870. createFileSymbols(Asm);
  871. for (auto &Symbol : Symbols) {
  872. // Update section number & offset for symbols that have them.
  873. if (Symbol->Section)
  874. Symbol->Data.SectionNumber = Symbol->Section->Number;
  875. Symbol->setIndex(Header.NumberOfSymbols++);
  876. // Update auxiliary symbol info.
  877. Symbol->Data.NumberOfAuxSymbols = Symbol->Aux.size();
  878. Header.NumberOfSymbols += Symbol->Data.NumberOfAuxSymbols;
  879. }
  880. // Build string table.
  881. for (const auto &S : Sections)
  882. if (S->Name.size() > COFF::NameSize)
  883. Strings.add(S->Name);
  884. for (const auto &S : Symbols)
  885. if (S->Name.size() > COFF::NameSize)
  886. Strings.add(S->Name);
  887. Strings.finalize();
  888. // Set names.
  889. for (const auto &S : Sections)
  890. SetSectionName(*S);
  891. for (auto &S : Symbols)
  892. SetSymbolName(*S);
  893. // Fixup weak external references.
  894. for (auto &Symbol : Symbols) {
  895. if (Symbol->Other) {
  896. assert(Symbol->getIndex() != -1);
  897. assert(Symbol->Aux.size() == 1 && "Symbol must contain one aux symbol!");
  898. assert(Symbol->Aux[0].AuxType == ATWeakExternal &&
  899. "Symbol's aux symbol must be a Weak External!");
  900. Symbol->Aux[0].Aux.WeakExternal.TagIndex = Symbol->Other->getIndex();
  901. }
  902. }
  903. // Fixup associative COMDAT sections.
  904. for (auto &Section : Sections) {
  905. if (Section->Symbol->Aux[0].Aux.SectionDefinition.Selection !=
  906. COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
  907. continue;
  908. const MCSectionCOFF &MCSec = *Section->MCSection;
  909. const MCSymbol *AssocMCSym = MCSec.getCOMDATSymbol();
  910. assert(AssocMCSym);
  911. // It's an error to try to associate with an undefined symbol or a symbol
  912. // without a section.
  913. if (!AssocMCSym->isInSection()) {
  914. Asm.getContext().reportError(
  915. SMLoc(), Twine("cannot make section ") + MCSec.getName() +
  916. Twine(" associative with sectionless symbol ") +
  917. AssocMCSym->getName());
  918. continue;
  919. }
  920. const auto *AssocMCSec = cast<MCSectionCOFF>(&AssocMCSym->getSection());
  921. assert(SectionMap.count(AssocMCSec));
  922. COFFSection *AssocSec = SectionMap[AssocMCSec];
  923. // Skip this section if the associated section is unused.
  924. if (AssocSec->Number == -1)
  925. continue;
  926. Section->Symbol->Aux[0].Aux.SectionDefinition.Number = AssocSec->Number;
  927. }
  928. // Create the contents of the .llvm_addrsig section.
  929. if (EmitAddrsigSection) {
  930. auto Frag = new MCDataFragment(AddrsigSection);
  931. Frag->setLayoutOrder(0);
  932. raw_svector_ostream OS(Frag->getContents());
  933. for (const MCSymbol *S : AddrsigSyms) {
  934. if (!S->isRegistered())
  935. continue;
  936. if (!S->isTemporary()) {
  937. encodeULEB128(S->getIndex(), OS);
  938. continue;
  939. }
  940. MCSection *TargetSection = &S->getSection();
  941. assert(SectionMap.find(TargetSection) != SectionMap.end() &&
  942. "Section must already have been defined in "
  943. "executePostLayoutBinding!");
  944. encodeULEB128(SectionMap[TargetSection]->Symbol->getIndex(), OS);
  945. }
  946. }
  947. // Create the contents of the .llvm.call-graph-profile section.
  948. if (CGProfileSection) {
  949. auto *Frag = new MCDataFragment(CGProfileSection);
  950. Frag->setLayoutOrder(0);
  951. raw_svector_ostream OS(Frag->getContents());
  952. for (const MCAssembler::CGProfileEntry &CGPE : Asm.CGProfile) {
  953. uint32_t FromIndex = CGPE.From->getSymbol().getIndex();
  954. uint32_t ToIndex = CGPE.To->getSymbol().getIndex();
  955. support::endian::write(OS, FromIndex, W.Endian);
  956. support::endian::write(OS, ToIndex, W.Endian);
  957. support::endian::write(OS, CGPE.Count, W.Endian);
  958. }
  959. }
  960. assignFileOffsets(Asm, Layout);
  961. // MS LINK expects to be able to use this timestamp to implement their
  962. // /INCREMENTAL feature.
  963. if (Asm.isIncrementalLinkerCompatible()) {
  964. Header.TimeDateStamp = getTime();
  965. } else {
  966. // Have deterministic output if /INCREMENTAL isn't needed. Also matches GNU.
  967. Header.TimeDateStamp = 0;
  968. }
  969. // Write it all to disk...
  970. WriteFileHeader(Header);
  971. writeSectionHeaders();
  972. // Write section contents.
  973. sections::iterator I = Sections.begin();
  974. sections::iterator IE = Sections.end();
  975. MCAssembler::iterator J = Asm.begin();
  976. MCAssembler::iterator JE = Asm.end();
  977. for (; I != IE && J != JE; ++I, ++J)
  978. writeSection(Asm, Layout, **I, *J);
  979. assert(W.OS.tell() == Header.PointerToSymbolTable &&
  980. "Header::PointerToSymbolTable is insane!");
  981. // Write a symbol table.
  982. for (auto &Symbol : Symbols)
  983. if (Symbol->getIndex() != -1)
  984. WriteSymbol(*Symbol);
  985. // Write a string table, which completes the entire COFF file.
  986. Strings.write(W.OS);
  987. return W.OS.tell() - StartOffset;
  988. }
  989. MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_)
  990. : Machine(Machine_) {}
  991. // Pin the vtable to this file.
  992. void MCWinCOFFObjectTargetWriter::anchor() {}
  993. //------------------------------------------------------------------------------
  994. // WinCOFFObjectWriter factory function
  995. std::unique_ptr<MCObjectWriter> llvm::createWinCOFFObjectWriter(
  996. std::unique_ptr<MCWinCOFFObjectTargetWriter> MOTW, raw_pwrite_stream &OS) {
  997. return std::make_unique<WinCOFFObjectWriter>(std::move(MOTW), OS);
  998. }