MachObjectWriter.cpp 40 KB

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