MachObjectWriter.cpp 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085
  1. //===- lib/MC/MachObjectWriter.cpp - Mach-O 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. #include "llvm/ADT/DenseMap.h"
  9. #include "llvm/ADT/Twine.h"
  10. #include "llvm/ADT/iterator_range.h"
  11. #include "llvm/BinaryFormat/MachO.h"
  12. #include "llvm/MC/MCAsmBackend.h"
  13. #include "llvm/MC/MCAsmLayout.h"
  14. #include "llvm/MC/MCAssembler.h"
  15. #include "llvm/MC/MCContext.h"
  16. #include "llvm/MC/MCDirectives.h"
  17. #include "llvm/MC/MCExpr.h"
  18. #include "llvm/MC/MCFixupKindInfo.h"
  19. #include "llvm/MC/MCFragment.h"
  20. #include "llvm/MC/MCMachObjectWriter.h"
  21. #include "llvm/MC/MCObjectWriter.h"
  22. #include "llvm/MC/MCSection.h"
  23. #include "llvm/MC/MCSectionMachO.h"
  24. #include "llvm/MC/MCSymbol.h"
  25. #include "llvm/MC/MCSymbolMachO.h"
  26. #include "llvm/MC/MCValue.h"
  27. #include "llvm/Support/Alignment.h"
  28. #include "llvm/Support/Casting.h"
  29. #include "llvm/Support/Debug.h"
  30. #include "llvm/Support/ErrorHandling.h"
  31. #include "llvm/Support/MathExtras.h"
  32. #include "llvm/Support/raw_ostream.h"
  33. #include <algorithm>
  34. #include <cassert>
  35. #include <cstdint>
  36. #include <string>
  37. #include <utility>
  38. #include <vector>
  39. using namespace llvm;
  40. #define DEBUG_TYPE "mc"
  41. void MachObjectWriter::reset() {
  42. Relocations.clear();
  43. IndirectSymBase.clear();
  44. StringTable.clear();
  45. LocalSymbolData.clear();
  46. ExternalSymbolData.clear();
  47. UndefinedSymbolData.clear();
  48. MCObjectWriter::reset();
  49. }
  50. bool MachObjectWriter::doesSymbolRequireExternRelocation(const MCSymbol &S) {
  51. // Undefined symbols are always extern.
  52. if (S.isUndefined())
  53. return true;
  54. // References to weak definitions require external relocation entries; the
  55. // definition may not always be the one in the same object file.
  56. if (cast<MCSymbolMachO>(S).isWeakDefinition())
  57. return true;
  58. // Otherwise, we can use an internal relocation.
  59. return false;
  60. }
  61. bool MachObjectWriter::
  62. MachSymbolData::operator<(const MachSymbolData &RHS) const {
  63. return Symbol->getName() < RHS.Symbol->getName();
  64. }
  65. bool MachObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {
  66. const MCFixupKindInfo &FKI = Asm.getBackend().getFixupKindInfo(
  67. (MCFixupKind) Kind);
  68. return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel;
  69. }
  70. uint64_t MachObjectWriter::getFragmentAddress(const MCFragment *Fragment,
  71. const MCAsmLayout &Layout) const {
  72. return getSectionAddress(Fragment->getParent()) +
  73. Layout.getFragmentOffset(Fragment);
  74. }
  75. uint64_t MachObjectWriter::getSymbolAddress(const MCSymbol &S,
  76. const MCAsmLayout &Layout) const {
  77. // If this is a variable, then recursively evaluate now.
  78. if (S.isVariable()) {
  79. if (const MCConstantExpr *C =
  80. dyn_cast<const MCConstantExpr>(S.getVariableValue()))
  81. return C->getValue();
  82. MCValue Target;
  83. if (!S.getVariableValue()->evaluateAsRelocatable(Target, &Layout, nullptr))
  84. report_fatal_error("unable to evaluate offset for variable '" +
  85. S.getName() + "'");
  86. // Verify that any used symbols are defined.
  87. if (Target.getSymA() && Target.getSymA()->getSymbol().isUndefined())
  88. report_fatal_error("unable to evaluate offset to undefined symbol '" +
  89. Target.getSymA()->getSymbol().getName() + "'");
  90. if (Target.getSymB() && Target.getSymB()->getSymbol().isUndefined())
  91. report_fatal_error("unable to evaluate offset to undefined symbol '" +
  92. Target.getSymB()->getSymbol().getName() + "'");
  93. uint64_t Address = Target.getConstant();
  94. if (Target.getSymA())
  95. Address += getSymbolAddress(Target.getSymA()->getSymbol(), Layout);
  96. if (Target.getSymB())
  97. Address += getSymbolAddress(Target.getSymB()->getSymbol(), Layout);
  98. return Address;
  99. }
  100. return getSectionAddress(S.getFragment()->getParent()) +
  101. Layout.getSymbolOffset(S);
  102. }
  103. uint64_t MachObjectWriter::getPaddingSize(const MCSection *Sec,
  104. const MCAsmLayout &Layout) const {
  105. uint64_t EndAddr = getSectionAddress(Sec) + Layout.getSectionAddressSize(Sec);
  106. unsigned Next = Sec->getLayoutOrder() + 1;
  107. if (Next >= Layout.getSectionOrder().size())
  108. return 0;
  109. const MCSection &NextSec = *Layout.getSectionOrder()[Next];
  110. if (NextSec.isVirtualSection())
  111. return 0;
  112. return offsetToAlignment(EndAddr, Align(NextSec.getAlignment()));
  113. }
  114. void MachObjectWriter::writeHeader(MachO::HeaderFileType Type,
  115. unsigned NumLoadCommands,
  116. unsigned LoadCommandsSize,
  117. bool SubsectionsViaSymbols) {
  118. uint32_t Flags = 0;
  119. if (SubsectionsViaSymbols)
  120. Flags |= MachO::MH_SUBSECTIONS_VIA_SYMBOLS;
  121. // struct mach_header (28 bytes) or
  122. // struct mach_header_64 (32 bytes)
  123. uint64_t Start = W.OS.tell();
  124. (void) Start;
  125. W.write<uint32_t>(is64Bit() ? MachO::MH_MAGIC_64 : MachO::MH_MAGIC);
  126. W.write<uint32_t>(TargetObjectWriter->getCPUType());
  127. W.write<uint32_t>(TargetObjectWriter->getCPUSubtype());
  128. W.write<uint32_t>(Type);
  129. W.write<uint32_t>(NumLoadCommands);
  130. W.write<uint32_t>(LoadCommandsSize);
  131. W.write<uint32_t>(Flags);
  132. if (is64Bit())
  133. W.write<uint32_t>(0); // reserved
  134. assert(W.OS.tell() - Start == (is64Bit() ? sizeof(MachO::mach_header_64)
  135. : sizeof(MachO::mach_header)));
  136. }
  137. void MachObjectWriter::writeWithPadding(StringRef Str, uint64_t Size) {
  138. assert(Size >= Str.size());
  139. W.OS << Str;
  140. W.OS.write_zeros(Size - Str.size());
  141. }
  142. /// writeSegmentLoadCommand - Write a segment load command.
  143. ///
  144. /// \param NumSections The number of sections in this segment.
  145. /// \param SectionDataSize The total size of the sections.
  146. void MachObjectWriter::writeSegmentLoadCommand(
  147. StringRef Name, unsigned NumSections, uint64_t VMAddr, uint64_t VMSize,
  148. uint64_t SectionDataStartOffset, uint64_t SectionDataSize, uint32_t MaxProt,
  149. uint32_t InitProt) {
  150. // struct segment_command (56 bytes) or
  151. // struct segment_command_64 (72 bytes)
  152. uint64_t Start = W.OS.tell();
  153. (void) Start;
  154. unsigned SegmentLoadCommandSize =
  155. is64Bit() ? sizeof(MachO::segment_command_64):
  156. sizeof(MachO::segment_command);
  157. W.write<uint32_t>(is64Bit() ? MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT);
  158. W.write<uint32_t>(SegmentLoadCommandSize +
  159. NumSections * (is64Bit() ? sizeof(MachO::section_64) :
  160. sizeof(MachO::section)));
  161. writeWithPadding(Name, 16);
  162. if (is64Bit()) {
  163. W.write<uint64_t>(VMAddr); // vmaddr
  164. W.write<uint64_t>(VMSize); // vmsize
  165. W.write<uint64_t>(SectionDataStartOffset); // file offset
  166. W.write<uint64_t>(SectionDataSize); // file size
  167. } else {
  168. W.write<uint32_t>(VMAddr); // vmaddr
  169. W.write<uint32_t>(VMSize); // vmsize
  170. W.write<uint32_t>(SectionDataStartOffset); // file offset
  171. W.write<uint32_t>(SectionDataSize); // file size
  172. }
  173. // maxprot
  174. W.write<uint32_t>(MaxProt);
  175. // initprot
  176. W.write<uint32_t>(InitProt);
  177. W.write<uint32_t>(NumSections);
  178. W.write<uint32_t>(0); // flags
  179. assert(W.OS.tell() - Start == SegmentLoadCommandSize);
  180. }
  181. void MachObjectWriter::writeSection(const MCAsmLayout &Layout,
  182. const MCSection &Sec, uint64_t VMAddr,
  183. uint64_t FileOffset, unsigned Flags,
  184. uint64_t RelocationsStart,
  185. unsigned NumRelocations) {
  186. uint64_t SectionSize = Layout.getSectionAddressSize(&Sec);
  187. const MCSectionMachO &Section = cast<MCSectionMachO>(Sec);
  188. // The offset is unused for virtual sections.
  189. if (Section.isVirtualSection()) {
  190. assert(Layout.getSectionFileSize(&Sec) == 0 && "Invalid file size!");
  191. FileOffset = 0;
  192. }
  193. // struct section (68 bytes) or
  194. // struct section_64 (80 bytes)
  195. uint64_t Start = W.OS.tell();
  196. (void) Start;
  197. writeWithPadding(Section.getName(), 16);
  198. writeWithPadding(Section.getSegmentName(), 16);
  199. if (is64Bit()) {
  200. W.write<uint64_t>(VMAddr); // address
  201. W.write<uint64_t>(SectionSize); // size
  202. } else {
  203. W.write<uint32_t>(VMAddr); // address
  204. W.write<uint32_t>(SectionSize); // size
  205. }
  206. W.write<uint32_t>(FileOffset);
  207. assert(isPowerOf2_32(Section.getAlignment()) && "Invalid alignment!");
  208. W.write<uint32_t>(Log2_32(Section.getAlignment()));
  209. W.write<uint32_t>(NumRelocations ? RelocationsStart : 0);
  210. W.write<uint32_t>(NumRelocations);
  211. W.write<uint32_t>(Flags);
  212. W.write<uint32_t>(IndirectSymBase.lookup(&Sec)); // reserved1
  213. W.write<uint32_t>(Section.getStubSize()); // reserved2
  214. if (is64Bit())
  215. W.write<uint32_t>(0); // reserved3
  216. assert(W.OS.tell() - Start ==
  217. (is64Bit() ? sizeof(MachO::section_64) : sizeof(MachO::section)));
  218. }
  219. void MachObjectWriter::writeSymtabLoadCommand(uint32_t SymbolOffset,
  220. uint32_t NumSymbols,
  221. uint32_t StringTableOffset,
  222. uint32_t StringTableSize) {
  223. // struct symtab_command (24 bytes)
  224. uint64_t Start = W.OS.tell();
  225. (void) Start;
  226. W.write<uint32_t>(MachO::LC_SYMTAB);
  227. W.write<uint32_t>(sizeof(MachO::symtab_command));
  228. W.write<uint32_t>(SymbolOffset);
  229. W.write<uint32_t>(NumSymbols);
  230. W.write<uint32_t>(StringTableOffset);
  231. W.write<uint32_t>(StringTableSize);
  232. assert(W.OS.tell() - Start == sizeof(MachO::symtab_command));
  233. }
  234. void MachObjectWriter::writeDysymtabLoadCommand(uint32_t FirstLocalSymbol,
  235. uint32_t NumLocalSymbols,
  236. uint32_t FirstExternalSymbol,
  237. uint32_t NumExternalSymbols,
  238. uint32_t FirstUndefinedSymbol,
  239. uint32_t NumUndefinedSymbols,
  240. uint32_t IndirectSymbolOffset,
  241. uint32_t NumIndirectSymbols) {
  242. // struct dysymtab_command (80 bytes)
  243. uint64_t Start = W.OS.tell();
  244. (void) Start;
  245. W.write<uint32_t>(MachO::LC_DYSYMTAB);
  246. W.write<uint32_t>(sizeof(MachO::dysymtab_command));
  247. W.write<uint32_t>(FirstLocalSymbol);
  248. W.write<uint32_t>(NumLocalSymbols);
  249. W.write<uint32_t>(FirstExternalSymbol);
  250. W.write<uint32_t>(NumExternalSymbols);
  251. W.write<uint32_t>(FirstUndefinedSymbol);
  252. W.write<uint32_t>(NumUndefinedSymbols);
  253. W.write<uint32_t>(0); // tocoff
  254. W.write<uint32_t>(0); // ntoc
  255. W.write<uint32_t>(0); // modtaboff
  256. W.write<uint32_t>(0); // nmodtab
  257. W.write<uint32_t>(0); // extrefsymoff
  258. W.write<uint32_t>(0); // nextrefsyms
  259. W.write<uint32_t>(IndirectSymbolOffset);
  260. W.write<uint32_t>(NumIndirectSymbols);
  261. W.write<uint32_t>(0); // extreloff
  262. W.write<uint32_t>(0); // nextrel
  263. W.write<uint32_t>(0); // locreloff
  264. W.write<uint32_t>(0); // nlocrel
  265. assert(W.OS.tell() - Start == sizeof(MachO::dysymtab_command));
  266. }
  267. MachObjectWriter::MachSymbolData *
  268. MachObjectWriter::findSymbolData(const MCSymbol &Sym) {
  269. for (auto *SymbolData :
  270. {&LocalSymbolData, &ExternalSymbolData, &UndefinedSymbolData})
  271. for (MachSymbolData &Entry : *SymbolData)
  272. if (Entry.Symbol == &Sym)
  273. return &Entry;
  274. return nullptr;
  275. }
  276. const MCSymbol &MachObjectWriter::findAliasedSymbol(const MCSymbol &Sym) const {
  277. const MCSymbol *S = &Sym;
  278. while (S->isVariable()) {
  279. const MCExpr *Value = S->getVariableValue();
  280. const auto *Ref = dyn_cast<MCSymbolRefExpr>(Value);
  281. if (!Ref)
  282. return *S;
  283. S = &Ref->getSymbol();
  284. }
  285. return *S;
  286. }
  287. void MachObjectWriter::writeNlist(MachSymbolData &MSD,
  288. const MCAsmLayout &Layout) {
  289. const MCSymbol *Symbol = MSD.Symbol;
  290. const MCSymbol &Data = *Symbol;
  291. const MCSymbol *AliasedSymbol = &findAliasedSymbol(*Symbol);
  292. uint8_t SectionIndex = MSD.SectionIndex;
  293. uint8_t Type = 0;
  294. uint64_t Address = 0;
  295. bool IsAlias = Symbol != AliasedSymbol;
  296. const MCSymbol &OrigSymbol = *Symbol;
  297. MachSymbolData *AliaseeInfo;
  298. if (IsAlias) {
  299. AliaseeInfo = findSymbolData(*AliasedSymbol);
  300. if (AliaseeInfo)
  301. SectionIndex = AliaseeInfo->SectionIndex;
  302. Symbol = AliasedSymbol;
  303. // FIXME: Should this update Data as well?
  304. }
  305. // Set the N_TYPE bits. See <mach-o/nlist.h>.
  306. //
  307. // FIXME: Are the prebound or indirect fields possible here?
  308. if (IsAlias && Symbol->isUndefined())
  309. Type = MachO::N_INDR;
  310. else if (Symbol->isUndefined())
  311. Type = MachO::N_UNDF;
  312. else if (Symbol->isAbsolute())
  313. Type = MachO::N_ABS;
  314. else
  315. Type = MachO::N_SECT;
  316. // FIXME: Set STAB bits.
  317. if (Data.isPrivateExtern())
  318. Type |= MachO::N_PEXT;
  319. // Set external bit.
  320. if (Data.isExternal() || (!IsAlias && Symbol->isUndefined()))
  321. Type |= MachO::N_EXT;
  322. // Compute the symbol address.
  323. if (IsAlias && Symbol->isUndefined())
  324. Address = AliaseeInfo->StringIndex;
  325. else if (Symbol->isDefined())
  326. Address = getSymbolAddress(OrigSymbol, Layout);
  327. else if (Symbol->isCommon()) {
  328. // Common symbols are encoded with the size in the address
  329. // field, and their alignment in the flags.
  330. Address = Symbol->getCommonSize();
  331. }
  332. // struct nlist (12 bytes)
  333. W.write<uint32_t>(MSD.StringIndex);
  334. W.OS << char(Type);
  335. W.OS << char(SectionIndex);
  336. // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
  337. // value.
  338. bool EncodeAsAltEntry =
  339. IsAlias && cast<MCSymbolMachO>(OrigSymbol).isAltEntry();
  340. W.write<uint16_t>(cast<MCSymbolMachO>(Symbol)->getEncodedFlags(EncodeAsAltEntry));
  341. if (is64Bit())
  342. W.write<uint64_t>(Address);
  343. else
  344. W.write<uint32_t>(Address);
  345. }
  346. void MachObjectWriter::writeLinkeditLoadCommand(uint32_t Type,
  347. uint32_t DataOffset,
  348. uint32_t DataSize) {
  349. uint64_t Start = W.OS.tell();
  350. (void) Start;
  351. W.write<uint32_t>(Type);
  352. W.write<uint32_t>(sizeof(MachO::linkedit_data_command));
  353. W.write<uint32_t>(DataOffset);
  354. W.write<uint32_t>(DataSize);
  355. assert(W.OS.tell() - Start == sizeof(MachO::linkedit_data_command));
  356. }
  357. static unsigned ComputeLinkerOptionsLoadCommandSize(
  358. const std::vector<std::string> &Options, bool is64Bit)
  359. {
  360. unsigned Size = sizeof(MachO::linker_option_command);
  361. for (const std::string &Option : Options)
  362. Size += Option.size() + 1;
  363. return alignTo(Size, is64Bit ? 8 : 4);
  364. }
  365. void MachObjectWriter::writeLinkerOptionsLoadCommand(
  366. const std::vector<std::string> &Options)
  367. {
  368. unsigned Size = ComputeLinkerOptionsLoadCommandSize(Options, is64Bit());
  369. uint64_t Start = W.OS.tell();
  370. (void) Start;
  371. W.write<uint32_t>(MachO::LC_LINKER_OPTION);
  372. W.write<uint32_t>(Size);
  373. W.write<uint32_t>(Options.size());
  374. uint64_t BytesWritten = sizeof(MachO::linker_option_command);
  375. for (const std::string &Option : Options) {
  376. // Write each string, including the null byte.
  377. W.OS << Option << '\0';
  378. BytesWritten += Option.size() + 1;
  379. }
  380. // Pad to a multiple of the pointer size.
  381. W.OS.write_zeros(
  382. offsetToAlignment(BytesWritten, is64Bit() ? Align(8) : Align(4)));
  383. assert(W.OS.tell() - Start == Size);
  384. }
  385. static bool isFixupTargetValid(const MCValue &Target) {
  386. // Target is (LHS - RHS + cst).
  387. // We don't support the form where LHS is null: -RHS + cst
  388. if (!Target.getSymA() && Target.getSymB())
  389. return false;
  390. return true;
  391. }
  392. void MachObjectWriter::recordRelocation(MCAssembler &Asm,
  393. const MCAsmLayout &Layout,
  394. const MCFragment *Fragment,
  395. const MCFixup &Fixup, MCValue Target,
  396. uint64_t &FixedValue) {
  397. if (!isFixupTargetValid(Target)) {
  398. Asm.getContext().reportError(Fixup.getLoc(),
  399. "unsupported relocation expression");
  400. return;
  401. }
  402. TargetObjectWriter->recordRelocation(this, Asm, Layout, Fragment, Fixup,
  403. Target, FixedValue);
  404. }
  405. void MachObjectWriter::bindIndirectSymbols(MCAssembler &Asm) {
  406. // This is the point where 'as' creates actual symbols for indirect symbols
  407. // (in the following two passes). It would be easier for us to do this sooner
  408. // when we see the attribute, but that makes getting the order in the symbol
  409. // table much more complicated than it is worth.
  410. //
  411. // FIXME: Revisit this when the dust settles.
  412. // Report errors for use of .indirect_symbol not in a symbol pointer section
  413. // or stub section.
  414. for (IndirectSymbolData &ISD : llvm::make_range(Asm.indirect_symbol_begin(),
  415. Asm.indirect_symbol_end())) {
  416. const MCSectionMachO &Section = cast<MCSectionMachO>(*ISD.Section);
  417. if (Section.getType() != MachO::S_NON_LAZY_SYMBOL_POINTERS &&
  418. Section.getType() != MachO::S_LAZY_SYMBOL_POINTERS &&
  419. Section.getType() != MachO::S_THREAD_LOCAL_VARIABLE_POINTERS &&
  420. Section.getType() != MachO::S_SYMBOL_STUBS) {
  421. MCSymbol &Symbol = *ISD.Symbol;
  422. report_fatal_error("indirect symbol '" + Symbol.getName() +
  423. "' not in a symbol pointer or stub section");
  424. }
  425. }
  426. // Bind non-lazy symbol pointers first.
  427. unsigned IndirectIndex = 0;
  428. for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
  429. ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) {
  430. const MCSectionMachO &Section = cast<MCSectionMachO>(*it->Section);
  431. if (Section.getType() != MachO::S_NON_LAZY_SYMBOL_POINTERS &&
  432. Section.getType() != MachO::S_THREAD_LOCAL_VARIABLE_POINTERS)
  433. continue;
  434. // Initialize the section indirect symbol base, if necessary.
  435. IndirectSymBase.insert(std::make_pair(it->Section, IndirectIndex));
  436. Asm.registerSymbol(*it->Symbol);
  437. }
  438. // Then lazy symbol pointers and symbol stubs.
  439. IndirectIndex = 0;
  440. for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
  441. ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) {
  442. const MCSectionMachO &Section = cast<MCSectionMachO>(*it->Section);
  443. if (Section.getType() != MachO::S_LAZY_SYMBOL_POINTERS &&
  444. Section.getType() != MachO::S_SYMBOL_STUBS)
  445. continue;
  446. // Initialize the section indirect symbol base, if necessary.
  447. IndirectSymBase.insert(std::make_pair(it->Section, IndirectIndex));
  448. // Set the symbol type to undefined lazy, but only on construction.
  449. //
  450. // FIXME: Do not hardcode.
  451. bool Created;
  452. Asm.registerSymbol(*it->Symbol, &Created);
  453. if (Created)
  454. cast<MCSymbolMachO>(it->Symbol)->setReferenceTypeUndefinedLazy(true);
  455. }
  456. }
  457. /// computeSymbolTable - Compute the symbol table data
  458. void MachObjectWriter::computeSymbolTable(
  459. MCAssembler &Asm, std::vector<MachSymbolData> &LocalSymbolData,
  460. std::vector<MachSymbolData> &ExternalSymbolData,
  461. std::vector<MachSymbolData> &UndefinedSymbolData) {
  462. // Build section lookup table.
  463. DenseMap<const MCSection*, uint8_t> SectionIndexMap;
  464. unsigned Index = 1;
  465. for (MCAssembler::iterator it = Asm.begin(),
  466. ie = Asm.end(); it != ie; ++it, ++Index)
  467. SectionIndexMap[&*it] = Index;
  468. assert(Index <= 256 && "Too many sections!");
  469. // Build the string table.
  470. for (const MCSymbol &Symbol : Asm.symbols()) {
  471. if (!Asm.isSymbolLinkerVisible(Symbol))
  472. continue;
  473. StringTable.add(Symbol.getName());
  474. }
  475. StringTable.finalize();
  476. // Build the symbol arrays but only for non-local symbols.
  477. //
  478. // The particular order that we collect and then sort the symbols is chosen to
  479. // match 'as'. Even though it doesn't matter for correctness, this is
  480. // important for letting us diff .o files.
  481. for (const MCSymbol &Symbol : Asm.symbols()) {
  482. // Ignore non-linker visible symbols.
  483. if (!Asm.isSymbolLinkerVisible(Symbol))
  484. continue;
  485. if (!Symbol.isExternal() && !Symbol.isUndefined())
  486. continue;
  487. MachSymbolData MSD;
  488. MSD.Symbol = &Symbol;
  489. MSD.StringIndex = StringTable.getOffset(Symbol.getName());
  490. if (Symbol.isUndefined()) {
  491. MSD.SectionIndex = 0;
  492. UndefinedSymbolData.push_back(MSD);
  493. } else if (Symbol.isAbsolute()) {
  494. MSD.SectionIndex = 0;
  495. ExternalSymbolData.push_back(MSD);
  496. } else {
  497. MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection());
  498. assert(MSD.SectionIndex && "Invalid section index!");
  499. ExternalSymbolData.push_back(MSD);
  500. }
  501. }
  502. // Now add the data for local symbols.
  503. for (const MCSymbol &Symbol : Asm.symbols()) {
  504. // Ignore non-linker visible symbols.
  505. if (!Asm.isSymbolLinkerVisible(Symbol))
  506. continue;
  507. if (Symbol.isExternal() || Symbol.isUndefined())
  508. continue;
  509. MachSymbolData MSD;
  510. MSD.Symbol = &Symbol;
  511. MSD.StringIndex = StringTable.getOffset(Symbol.getName());
  512. if (Symbol.isAbsolute()) {
  513. MSD.SectionIndex = 0;
  514. LocalSymbolData.push_back(MSD);
  515. } else {
  516. MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection());
  517. assert(MSD.SectionIndex && "Invalid section index!");
  518. LocalSymbolData.push_back(MSD);
  519. }
  520. }
  521. // External and undefined symbols are required to be in lexicographic order.
  522. llvm::sort(ExternalSymbolData);
  523. llvm::sort(UndefinedSymbolData);
  524. // Set the symbol indices.
  525. Index = 0;
  526. for (auto *SymbolData :
  527. {&LocalSymbolData, &ExternalSymbolData, &UndefinedSymbolData})
  528. for (MachSymbolData &Entry : *SymbolData)
  529. Entry.Symbol->setIndex(Index++);
  530. for (const MCSection &Section : Asm) {
  531. for (RelAndSymbol &Rel : Relocations[&Section]) {
  532. if (!Rel.Sym)
  533. continue;
  534. // Set the Index and the IsExtern bit.
  535. unsigned Index = Rel.Sym->getIndex();
  536. assert(isInt<24>(Index));
  537. if (W.Endian == support::little)
  538. Rel.MRE.r_word1 = (Rel.MRE.r_word1 & (~0U << 24)) | Index | (1 << 27);
  539. else
  540. Rel.MRE.r_word1 = (Rel.MRE.r_word1 & 0xff) | Index << 8 | (1 << 4);
  541. }
  542. }
  543. }
  544. void MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm,
  545. const MCAsmLayout &Layout) {
  546. uint64_t StartAddress = 0;
  547. for (const MCSection *Sec : Layout.getSectionOrder()) {
  548. StartAddress = alignTo(StartAddress, Sec->getAlignment());
  549. SectionAddress[Sec] = StartAddress;
  550. StartAddress += Layout.getSectionAddressSize(Sec);
  551. // Explicitly pad the section to match the alignment requirements of the
  552. // following one. This is for 'gas' compatibility, it shouldn't
  553. /// strictly be necessary.
  554. StartAddress += getPaddingSize(Sec, Layout);
  555. }
  556. }
  557. void MachObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
  558. const MCAsmLayout &Layout) {
  559. computeSectionAddresses(Asm, Layout);
  560. // Create symbol data for any indirect symbols.
  561. bindIndirectSymbols(Asm);
  562. }
  563. bool MachObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
  564. const MCAssembler &Asm, const MCSymbol &A, const MCSymbol &B,
  565. bool InSet) const {
  566. // FIXME: We don't handle things like
  567. // foo = .
  568. // creating atoms.
  569. if (A.isVariable() || B.isVariable())
  570. return false;
  571. return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, A, B,
  572. InSet);
  573. }
  574. bool MachObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
  575. const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB,
  576. bool InSet, bool IsPCRel) const {
  577. if (InSet)
  578. return true;
  579. // The effective address is
  580. // addr(atom(A)) + offset(A)
  581. // - addr(atom(B)) - offset(B)
  582. // and the offsets are not relocatable, so the fixup is fully resolved when
  583. // addr(atom(A)) - addr(atom(B)) == 0.
  584. const MCSymbol &SA = findAliasedSymbol(SymA);
  585. const MCSection &SecA = SA.getSection();
  586. const MCSection &SecB = *FB.getParent();
  587. if (IsPCRel) {
  588. // The simple (Darwin, except on x86_64) way of dealing with this was to
  589. // assume that any reference to a temporary symbol *must* be a temporary
  590. // symbol in the same atom, unless the sections differ. Therefore, any PCrel
  591. // relocation to a temporary symbol (in the same section) is fully
  592. // resolved. This also works in conjunction with absolutized .set, which
  593. // requires the compiler to use .set to absolutize the differences between
  594. // symbols which the compiler knows to be assembly time constants, so we
  595. // don't need to worry about considering symbol differences fully resolved.
  596. //
  597. // If the file isn't using sub-sections-via-symbols, we can make the
  598. // same assumptions about any symbol that we normally make about
  599. // assembler locals.
  600. bool hasReliableSymbolDifference = isX86_64();
  601. if (!hasReliableSymbolDifference) {
  602. if (!SA.isInSection() || &SecA != &SecB ||
  603. (!SA.isTemporary() && FB.getAtom() != SA.getFragment()->getAtom() &&
  604. Asm.getSubsectionsViaSymbols()))
  605. return false;
  606. return true;
  607. }
  608. // For Darwin x86_64, there is one special case when the reference IsPCRel.
  609. // If the fragment with the reference does not have a base symbol but meets
  610. // the simple way of dealing with this, in that it is a temporary symbol in
  611. // the same atom then it is assumed to be fully resolved. This is needed so
  612. // a relocation entry is not created and so the static linker does not
  613. // mess up the reference later.
  614. else if(!FB.getAtom() &&
  615. SA.isTemporary() && SA.isInSection() && &SecA == &SecB){
  616. return true;
  617. }
  618. }
  619. // If they are not in the same section, we can't compute the diff.
  620. if (&SecA != &SecB)
  621. return false;
  622. const MCFragment *FA = SA.getFragment();
  623. // Bail if the symbol has no fragment.
  624. if (!FA)
  625. return false;
  626. // If the atoms are the same, they are guaranteed to have the same address.
  627. if (FA->getAtom() == FB.getAtom())
  628. return true;
  629. // Otherwise, we can't prove this is fully resolved.
  630. return false;
  631. }
  632. static MachO::LoadCommandType getLCFromMCVM(MCVersionMinType Type) {
  633. switch (Type) {
  634. case MCVM_OSXVersionMin: return MachO::LC_VERSION_MIN_MACOSX;
  635. case MCVM_IOSVersionMin: return MachO::LC_VERSION_MIN_IPHONEOS;
  636. case MCVM_TvOSVersionMin: return MachO::LC_VERSION_MIN_TVOS;
  637. case MCVM_WatchOSVersionMin: return MachO::LC_VERSION_MIN_WATCHOS;
  638. }
  639. llvm_unreachable("Invalid mc version min type");
  640. }
  641. uint64_t MachObjectWriter::writeObject(MCAssembler &Asm,
  642. const MCAsmLayout &Layout) {
  643. uint64_t StartOffset = W.OS.tell();
  644. // Compute symbol table information and bind symbol indices.
  645. computeSymbolTable(Asm, LocalSymbolData, ExternalSymbolData,
  646. UndefinedSymbolData);
  647. if (!Asm.CGProfile.empty()) {
  648. MCSection *CGProfileSection = Asm.getContext().getMachOSection(
  649. "__LLVM", "__cg_profile", 0, SectionKind::getMetadata());
  650. MCDataFragment *Frag = dyn_cast_or_null<MCDataFragment>(
  651. &*CGProfileSection->getFragmentList().begin());
  652. assert(Frag && "call graph profile section not reserved");
  653. Frag->getContents().clear();
  654. raw_svector_ostream OS(Frag->getContents());
  655. for (const MCAssembler::CGProfileEntry &CGPE : Asm.CGProfile) {
  656. uint32_t FromIndex = CGPE.From->getSymbol().getIndex();
  657. uint32_t ToIndex = CGPE.To->getSymbol().getIndex();
  658. support::endian::write(OS, FromIndex, W.Endian);
  659. support::endian::write(OS, ToIndex, W.Endian);
  660. support::endian::write(OS, CGPE.Count, W.Endian);
  661. }
  662. }
  663. unsigned NumSections = Asm.size();
  664. const MCAssembler::VersionInfoType &VersionInfo =
  665. Layout.getAssembler().getVersionInfo();
  666. // The section data starts after the header, the segment load command (and
  667. // section headers) and the symbol table.
  668. unsigned NumLoadCommands = 1;
  669. uint64_t LoadCommandsSize = is64Bit() ?
  670. sizeof(MachO::segment_command_64) + NumSections * sizeof(MachO::section_64):
  671. sizeof(MachO::segment_command) + NumSections * sizeof(MachO::section);
  672. // Add the deployment target version info load command size, if used.
  673. if (VersionInfo.Major != 0) {
  674. ++NumLoadCommands;
  675. if (VersionInfo.EmitBuildVersion)
  676. LoadCommandsSize += sizeof(MachO::build_version_command);
  677. else
  678. LoadCommandsSize += sizeof(MachO::version_min_command);
  679. }
  680. const MCAssembler::VersionInfoType &TargetVariantVersionInfo =
  681. Layout.getAssembler().getDarwinTargetVariantVersionInfo();
  682. // Add the target variant version info load command size, if used.
  683. if (TargetVariantVersionInfo.Major != 0) {
  684. ++NumLoadCommands;
  685. assert(TargetVariantVersionInfo.EmitBuildVersion &&
  686. "target variant should use build version");
  687. LoadCommandsSize += sizeof(MachO::build_version_command);
  688. }
  689. // Add the data-in-code load command size, if used.
  690. unsigned NumDataRegions = Asm.getDataRegions().size();
  691. if (NumDataRegions) {
  692. ++NumLoadCommands;
  693. LoadCommandsSize += sizeof(MachO::linkedit_data_command);
  694. }
  695. // Add the loh load command size, if used.
  696. uint64_t LOHRawSize = Asm.getLOHContainer().getEmitSize(*this, Layout);
  697. uint64_t LOHSize = alignTo(LOHRawSize, is64Bit() ? 8 : 4);
  698. if (LOHSize) {
  699. ++NumLoadCommands;
  700. LoadCommandsSize += sizeof(MachO::linkedit_data_command);
  701. }
  702. // Add the symbol table load command sizes, if used.
  703. unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +
  704. UndefinedSymbolData.size();
  705. if (NumSymbols) {
  706. NumLoadCommands += 2;
  707. LoadCommandsSize += (sizeof(MachO::symtab_command) +
  708. sizeof(MachO::dysymtab_command));
  709. }
  710. // Add the linker option load commands sizes.
  711. for (const auto &Option : Asm.getLinkerOptions()) {
  712. ++NumLoadCommands;
  713. LoadCommandsSize += ComputeLinkerOptionsLoadCommandSize(Option, is64Bit());
  714. }
  715. // Compute the total size of the section data, as well as its file size and vm
  716. // size.
  717. uint64_t SectionDataStart = (is64Bit() ? sizeof(MachO::mach_header_64) :
  718. sizeof(MachO::mach_header)) + LoadCommandsSize;
  719. uint64_t SectionDataSize = 0;
  720. uint64_t SectionDataFileSize = 0;
  721. uint64_t VMSize = 0;
  722. for (const MCSection &Sec : Asm) {
  723. uint64_t Address = getSectionAddress(&Sec);
  724. uint64_t Size = Layout.getSectionAddressSize(&Sec);
  725. uint64_t FileSize = Layout.getSectionFileSize(&Sec);
  726. FileSize += getPaddingSize(&Sec, Layout);
  727. VMSize = std::max(VMSize, Address + Size);
  728. if (Sec.isVirtualSection())
  729. continue;
  730. SectionDataSize = std::max(SectionDataSize, Address + Size);
  731. SectionDataFileSize = std::max(SectionDataFileSize, Address + FileSize);
  732. }
  733. // The section data is padded to pointer size bytes.
  734. //
  735. // FIXME: Is this machine dependent?
  736. unsigned SectionDataPadding =
  737. offsetToAlignment(SectionDataFileSize, is64Bit() ? Align(8) : Align(4));
  738. SectionDataFileSize += SectionDataPadding;
  739. // Write the prolog, starting with the header and load command...
  740. writeHeader(MachO::MH_OBJECT, NumLoadCommands, LoadCommandsSize,
  741. Asm.getSubsectionsViaSymbols());
  742. uint32_t Prot =
  743. MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE;
  744. writeSegmentLoadCommand("", NumSections, 0, VMSize, SectionDataStart,
  745. SectionDataSize, Prot, Prot);
  746. // ... and then the section headers.
  747. uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
  748. for (const MCSection &Section : Asm) {
  749. const auto &Sec = cast<MCSectionMachO>(Section);
  750. std::vector<RelAndSymbol> &Relocs = Relocations[&Sec];
  751. unsigned NumRelocs = Relocs.size();
  752. uint64_t SectionStart = SectionDataStart + getSectionAddress(&Sec);
  753. unsigned Flags = Sec.getTypeAndAttributes();
  754. if (Sec.hasInstructions())
  755. Flags |= MachO::S_ATTR_SOME_INSTRUCTIONS;
  756. writeSection(Layout, Sec, getSectionAddress(&Sec), SectionStart, Flags,
  757. RelocTableEnd, NumRelocs);
  758. RelocTableEnd += NumRelocs * sizeof(MachO::any_relocation_info);
  759. }
  760. // Write out the deployment target information, if it's available.
  761. auto EmitDeploymentTargetVersion =
  762. [&](const MCAssembler::VersionInfoType &VersionInfo) {
  763. auto EncodeVersion = [](VersionTuple V) -> uint32_t {
  764. assert(!V.empty() && "empty version");
  765. unsigned Update = V.getSubminor().getValueOr(0);
  766. unsigned Minor = V.getMinor().getValueOr(0);
  767. assert(Update < 256 && "unencodable update target version");
  768. assert(Minor < 256 && "unencodable minor target version");
  769. assert(V.getMajor() < 65536 && "unencodable major target version");
  770. return Update | (Minor << 8) | (V.getMajor() << 16);
  771. };
  772. uint32_t EncodedVersion = EncodeVersion(VersionTuple(
  773. VersionInfo.Major, VersionInfo.Minor, VersionInfo.Update));
  774. uint32_t SDKVersion = !VersionInfo.SDKVersion.empty()
  775. ? EncodeVersion(VersionInfo.SDKVersion)
  776. : 0;
  777. if (VersionInfo.EmitBuildVersion) {
  778. // FIXME: Currently empty tools. Add clang version in the future.
  779. W.write<uint32_t>(MachO::LC_BUILD_VERSION);
  780. W.write<uint32_t>(sizeof(MachO::build_version_command));
  781. W.write<uint32_t>(VersionInfo.TypeOrPlatform.Platform);
  782. W.write<uint32_t>(EncodedVersion);
  783. W.write<uint32_t>(SDKVersion);
  784. W.write<uint32_t>(0); // Empty tools list.
  785. } else {
  786. MachO::LoadCommandType LCType =
  787. getLCFromMCVM(VersionInfo.TypeOrPlatform.Type);
  788. W.write<uint32_t>(LCType);
  789. W.write<uint32_t>(sizeof(MachO::version_min_command));
  790. W.write<uint32_t>(EncodedVersion);
  791. W.write<uint32_t>(SDKVersion);
  792. }
  793. };
  794. if (VersionInfo.Major != 0)
  795. EmitDeploymentTargetVersion(VersionInfo);
  796. if (TargetVariantVersionInfo.Major != 0)
  797. EmitDeploymentTargetVersion(TargetVariantVersionInfo);
  798. // Write the data-in-code load command, if used.
  799. uint64_t DataInCodeTableEnd = RelocTableEnd + NumDataRegions * 8;
  800. if (NumDataRegions) {
  801. uint64_t DataRegionsOffset = RelocTableEnd;
  802. uint64_t DataRegionsSize = NumDataRegions * 8;
  803. writeLinkeditLoadCommand(MachO::LC_DATA_IN_CODE, DataRegionsOffset,
  804. DataRegionsSize);
  805. }
  806. // Write the loh load command, if used.
  807. uint64_t LOHTableEnd = DataInCodeTableEnd + LOHSize;
  808. if (LOHSize)
  809. writeLinkeditLoadCommand(MachO::LC_LINKER_OPTIMIZATION_HINT,
  810. DataInCodeTableEnd, LOHSize);
  811. // Write the symbol table load command, if used.
  812. if (NumSymbols) {
  813. unsigned FirstLocalSymbol = 0;
  814. unsigned NumLocalSymbols = LocalSymbolData.size();
  815. unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols;
  816. unsigned NumExternalSymbols = ExternalSymbolData.size();
  817. unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols;
  818. unsigned NumUndefinedSymbols = UndefinedSymbolData.size();
  819. unsigned NumIndirectSymbols = Asm.indirect_symbol_size();
  820. unsigned NumSymTabSymbols =
  821. NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols;
  822. uint64_t IndirectSymbolSize = NumIndirectSymbols * 4;
  823. uint64_t IndirectSymbolOffset = 0;
  824. // If used, the indirect symbols are written after the section data.
  825. if (NumIndirectSymbols)
  826. IndirectSymbolOffset = LOHTableEnd;
  827. // The symbol table is written after the indirect symbol data.
  828. uint64_t SymbolTableOffset = LOHTableEnd + IndirectSymbolSize;
  829. // The string table is written after symbol table.
  830. uint64_t StringTableOffset =
  831. SymbolTableOffset + NumSymTabSymbols * (is64Bit() ?
  832. sizeof(MachO::nlist_64) :
  833. sizeof(MachO::nlist));
  834. writeSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols,
  835. StringTableOffset, StringTable.getSize());
  836. writeDysymtabLoadCommand(FirstLocalSymbol, NumLocalSymbols,
  837. FirstExternalSymbol, NumExternalSymbols,
  838. FirstUndefinedSymbol, NumUndefinedSymbols,
  839. IndirectSymbolOffset, NumIndirectSymbols);
  840. }
  841. // Write the linker options load commands.
  842. for (const auto &Option : Asm.getLinkerOptions())
  843. writeLinkerOptionsLoadCommand(Option);
  844. // Write the actual section data.
  845. for (const MCSection &Sec : Asm) {
  846. Asm.writeSectionData(W.OS, &Sec, Layout);
  847. uint64_t Pad = getPaddingSize(&Sec, Layout);
  848. W.OS.write_zeros(Pad);
  849. }
  850. // Write the extra padding.
  851. W.OS.write_zeros(SectionDataPadding);
  852. // Write the relocation entries.
  853. for (const MCSection &Sec : Asm) {
  854. // Write the section relocation entries, in reverse order to match 'as'
  855. // (approximately, the exact algorithm is more complicated than this).
  856. std::vector<RelAndSymbol> &Relocs = Relocations[&Sec];
  857. for (const RelAndSymbol &Rel : llvm::reverse(Relocs)) {
  858. W.write<uint32_t>(Rel.MRE.r_word0);
  859. W.write<uint32_t>(Rel.MRE.r_word1);
  860. }
  861. }
  862. // Write out the data-in-code region payload, if there is one.
  863. for (MCAssembler::const_data_region_iterator
  864. it = Asm.data_region_begin(), ie = Asm.data_region_end();
  865. it != ie; ++it) {
  866. const DataRegionData *Data = &(*it);
  867. uint64_t Start = getSymbolAddress(*Data->Start, Layout);
  868. uint64_t End;
  869. if (Data->End)
  870. End = getSymbolAddress(*Data->End, Layout);
  871. else
  872. report_fatal_error("Data region not terminated");
  873. LLVM_DEBUG(dbgs() << "data in code region-- kind: " << Data->Kind
  874. << " start: " << Start << "(" << Data->Start->getName()
  875. << ")"
  876. << " end: " << End << "(" << Data->End->getName() << ")"
  877. << " size: " << End - Start << "\n");
  878. W.write<uint32_t>(Start);
  879. W.write<uint16_t>(End - Start);
  880. W.write<uint16_t>(Data->Kind);
  881. }
  882. // Write out the loh commands, if there is one.
  883. if (LOHSize) {
  884. #ifndef NDEBUG
  885. unsigned Start = W.OS.tell();
  886. #endif
  887. Asm.getLOHContainer().emit(*this, Layout);
  888. // Pad to a multiple of the pointer size.
  889. W.OS.write_zeros(
  890. offsetToAlignment(LOHRawSize, is64Bit() ? Align(8) : Align(4)));
  891. assert(W.OS.tell() - Start == LOHSize);
  892. }
  893. // Write the symbol table data, if used.
  894. if (NumSymbols) {
  895. // Write the indirect symbol entries.
  896. for (MCAssembler::const_indirect_symbol_iterator
  897. it = Asm.indirect_symbol_begin(),
  898. ie = Asm.indirect_symbol_end(); it != ie; ++it) {
  899. // Indirect symbols in the non-lazy symbol pointer section have some
  900. // special handling.
  901. const MCSectionMachO &Section =
  902. static_cast<const MCSectionMachO &>(*it->Section);
  903. if (Section.getType() == MachO::S_NON_LAZY_SYMBOL_POINTERS) {
  904. // If this symbol is defined and internal, mark it as such.
  905. if (it->Symbol->isDefined() && !it->Symbol->isExternal()) {
  906. uint32_t Flags = MachO::INDIRECT_SYMBOL_LOCAL;
  907. if (it->Symbol->isAbsolute())
  908. Flags |= MachO::INDIRECT_SYMBOL_ABS;
  909. W.write<uint32_t>(Flags);
  910. continue;
  911. }
  912. }
  913. W.write<uint32_t>(it->Symbol->getIndex());
  914. }
  915. // FIXME: Check that offsets match computed ones.
  916. // Write the symbol table entries.
  917. for (auto *SymbolData :
  918. {&LocalSymbolData, &ExternalSymbolData, &UndefinedSymbolData})
  919. for (MachSymbolData &Entry : *SymbolData)
  920. writeNlist(Entry, Layout);
  921. // Write the string table.
  922. StringTable.write(W.OS);
  923. }
  924. return W.OS.tell() - StartOffset;
  925. }
  926. std::unique_ptr<MCObjectWriter>
  927. llvm::createMachObjectWriter(std::unique_ptr<MCMachObjectTargetWriter> MOTW,
  928. raw_pwrite_stream &OS, bool IsLittleEndian) {
  929. return std::make_unique<MachObjectWriter>(std::move(MOTW), OS,
  930. IsLittleEndian);
  931. }