blob: 3c1888c153ac8ef7ce3d162f2d4ffd43c3762ff8 [file] [log] [blame]
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001//===- lib/MC/MachObjectWriter.cpp - Mach-O File Writer -------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Daniel Dunbarae5abd52010-12-16 16:09:19 +000010#include "llvm/MC/MCMachObjectWriter.h"
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +000011#include "llvm/ADT/StringMap.h"
12#include "llvm/ADT/Twine.h"
Evan Cheng78c10ee2011-07-25 23:24:55 +000013#include "llvm/MC/MCAsmBackend.h"
Daniel Dunbar207e06e2010-03-24 03:43:40 +000014#include "llvm/MC/MCAsmLayout.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000015#include "llvm/MC/MCAssembler.h"
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +000016#include "llvm/MC/MCExpr.h"
Craig Topperf1d0f772012-03-26 06:58:25 +000017#include "llvm/MC/MCFixupKindInfo.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000018#include "llvm/MC/MCMachOSymbolFlags.h"
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +000019#include "llvm/MC/MCObjectWriter.h"
20#include "llvm/MC/MCSectionMachO.h"
21#include "llvm/MC/MCSymbol.h"
22#include "llvm/MC/MCValue.h"
Charles Davisf69a29b2013-08-27 05:38:30 +000023#include "llvm/Object/MachOFormat.h"
Jim Grosbach3e965312012-05-18 19:12:01 +000024#include "llvm/Support/Debug.h"
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +000025#include "llvm/Support/ErrorHandling.h"
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +000026#include <vector>
27using namespace llvm;
Charles Davisf69a29b2013-08-27 05:38:30 +000028using namespace llvm::object;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +000029
Pedro Artigas99cbdde2012-12-14 18:52:11 +000030void MachObjectWriter::reset() {
31 Relocations.clear();
32 IndirectSymBase.clear();
33 StringTable.clear();
34 LocalSymbolData.clear();
35 ExternalSymbolData.clear();
36 UndefinedSymbolData.clear();
37 MCObjectWriter::reset();
38}
39
Jim Grosbachba8297e2011-06-24 23:44:37 +000040bool MachObjectWriter::
41doesSymbolRequireExternRelocation(const MCSymbolData *SD) {
Daniel Dunbare9460ec2010-05-10 23:15:13 +000042 // Undefined symbols are always extern.
43 if (SD->Symbol->isUndefined())
44 return true;
45
46 // References to weak definitions require external relocation entries; the
47 // definition may not always be the one in the same object file.
48 if (SD->getFlags() & SF_WeakDefinition)
49 return true;
50
51 // Otherwise, we can use an internal relocation.
52 return false;
53}
54
Jim Grosbachba8297e2011-06-24 23:44:37 +000055bool MachObjectWriter::
56MachSymbolData::operator<(const MachSymbolData &RHS) const {
57 return SymbolData->getSymbol().getName() <
58 RHS.SymbolData->getSymbol().getName();
59}
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +000060
Jim Grosbachba8297e2011-06-24 23:44:37 +000061bool MachObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {
62 const MCFixupKindInfo &FKI = Asm.getBackend().getFixupKindInfo(
63 (MCFixupKind) Kind);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +000064
Jim Grosbachba8297e2011-06-24 23:44:37 +000065 return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel;
66}
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +000067
Jim Grosbachba8297e2011-06-24 23:44:37 +000068uint64_t MachObjectWriter::getFragmentAddress(const MCFragment *Fragment,
69 const MCAsmLayout &Layout) const {
70 return getSectionAddress(Fragment->getParent()) +
71 Layout.getFragmentOffset(Fragment);
72}
Bill Wendlingbbdffa92011-06-22 21:07:27 +000073
74uint64_t MachObjectWriter::getSymbolAddress(const MCSymbolData* SD,
75 const MCAsmLayout &Layout) const {
76 const MCSymbol &S = SD->getSymbol();
77
78 // If this is a variable, then recursively evaluate now.
79 if (S.isVariable()) {
Jim Grosbach45d81bd2012-09-13 23:11:25 +000080 if (const MCConstantExpr *C =
81 dyn_cast<const MCConstantExpr>(S.getVariableValue()))
82 return C->getValue();
83
84
Bill Wendlingbbdffa92011-06-22 21:07:27 +000085 MCValue Target;
86 if (!S.getVariableValue()->EvaluateAsRelocatable(Target, Layout))
87 report_fatal_error("unable to evaluate offset for variable '" +
88 S.getName() + "'");
89
90 // Verify that any used symbols are defined.
91 if (Target.getSymA() && Target.getSymA()->getSymbol().isUndefined())
92 report_fatal_error("unable to evaluate offset to undefined symbol '" +
93 Target.getSymA()->getSymbol().getName() + "'");
94 if (Target.getSymB() && Target.getSymB()->getSymbol().isUndefined())
95 report_fatal_error("unable to evaluate offset to undefined symbol '" +
96 Target.getSymB()->getSymbol().getName() + "'");
97
98 uint64_t Address = Target.getConstant();
99 if (Target.getSymA())
100 Address += getSymbolAddress(&Layout.getAssembler().getSymbolData(
101 Target.getSymA()->getSymbol()), Layout);
102 if (Target.getSymB())
103 Address += getSymbolAddress(&Layout.getAssembler().getSymbolData(
104 Target.getSymB()->getSymbol()), Layout);
105 return Address;
106 }
107
108 return getSectionAddress(SD->getFragment()->getParent()) +
109 Layout.getSymbolOffset(SD);
110}
111
112uint64_t MachObjectWriter::getPaddingSize(const MCSectionData *SD,
113 const MCAsmLayout &Layout) const {
114 uint64_t EndAddr = getSectionAddress(SD) + Layout.getSectionAddressSize(SD);
115 unsigned Next = SD->getLayoutOrder() + 1;
116 if (Next >= Layout.getSectionOrder().size())
117 return 0;
118
119 const MCSectionData &NextSD = *Layout.getSectionOrder()[Next];
120 if (NextSD.getSection().isVirtualSection())
121 return 0;
122 return OffsetToAlignment(EndAddr, NextSD.getAlignment());
123}
124
125void MachObjectWriter::WriteHeader(unsigned NumLoadCommands,
126 unsigned LoadCommandsSize,
127 bool SubsectionsViaSymbols) {
128 uint32_t Flags = 0;
129
130 if (SubsectionsViaSymbols)
Charles Davisf69a29b2013-08-27 05:38:30 +0000131 Flags |= macho::HF_SubsectionsViaSymbols;
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000132
133 // struct mach_header (28 bytes) or
134 // struct mach_header_64 (32 bytes)
135
136 uint64_t Start = OS.tell();
137 (void) Start;
138
Charles Davisf69a29b2013-08-27 05:38:30 +0000139 Write32(is64Bit() ? macho::HM_Object64 : macho::HM_Object32);
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000140
141 Write32(TargetObjectWriter->getCPUType());
142 Write32(TargetObjectWriter->getCPUSubtype());
143
Charles Davisf69a29b2013-08-27 05:38:30 +0000144 Write32(macho::HFT_Object);
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000145 Write32(NumLoadCommands);
146 Write32(LoadCommandsSize);
147 Write32(Flags);
148 if (is64Bit())
149 Write32(0); // reserved
150
151 assert(OS.tell() - Start ==
Charles Davisf69a29b2013-08-27 05:38:30 +0000152 (is64Bit() ? macho::Header64Size : macho::Header32Size));
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000153}
154
155/// WriteSegmentLoadCommand - Write a segment load command.
156///
Dmitri Gribenkoc5252da2012-09-14 14:57:36 +0000157/// \param NumSections The number of sections in this segment.
158/// \param SectionDataSize The total size of the sections.
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000159void MachObjectWriter::WriteSegmentLoadCommand(unsigned NumSections,
160 uint64_t VMSize,
161 uint64_t SectionDataStartOffset,
162 uint64_t SectionDataSize) {
163 // struct segment_command (56 bytes) or
164 // struct segment_command_64 (72 bytes)
165
166 uint64_t Start = OS.tell();
167 (void) Start;
168
169 unsigned SegmentLoadCommandSize =
Charles Davisf69a29b2013-08-27 05:38:30 +0000170 is64Bit() ? macho::SegmentLoadCommand64Size:
171 macho::SegmentLoadCommand32Size;
172 Write32(is64Bit() ? macho::LCT_Segment64 : macho::LCT_Segment);
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000173 Write32(SegmentLoadCommandSize +
Charles Davisf69a29b2013-08-27 05:38:30 +0000174 NumSections * (is64Bit() ? macho::Section64Size :
175 macho::Section32Size));
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000176
177 WriteBytes("", 16);
178 if (is64Bit()) {
179 Write64(0); // vmaddr
180 Write64(VMSize); // vmsize
181 Write64(SectionDataStartOffset); // file offset
182 Write64(SectionDataSize); // file size
183 } else {
184 Write32(0); // vmaddr
185 Write32(VMSize); // vmsize
186 Write32(SectionDataStartOffset); // file offset
187 Write32(SectionDataSize); // file size
188 }
189 Write32(0x7); // maxprot
190 Write32(0x7); // initprot
191 Write32(NumSections);
192 Write32(0); // flags
193
194 assert(OS.tell() - Start == SegmentLoadCommandSize);
195}
196
197void MachObjectWriter::WriteSection(const MCAssembler &Asm,
198 const MCAsmLayout &Layout,
199 const MCSectionData &SD,
200 uint64_t FileOffset,
201 uint64_t RelocationsStart,
202 unsigned NumRelocations) {
203 uint64_t SectionSize = Layout.getSectionAddressSize(&SD);
204
205 // The offset is unused for virtual sections.
206 if (SD.getSection().isVirtualSection()) {
207 assert(Layout.getSectionFileSize(&SD) == 0 && "Invalid file size!");
208 FileOffset = 0;
209 }
210
211 // struct section (68 bytes) or
212 // struct section_64 (80 bytes)
213
214 uint64_t Start = OS.tell();
215 (void) Start;
216
217 const MCSectionMachO &Section = cast<MCSectionMachO>(SD.getSection());
218 WriteBytes(Section.getSectionName(), 16);
219 WriteBytes(Section.getSegmentName(), 16);
220 if (is64Bit()) {
221 Write64(getSectionAddress(&SD)); // address
222 Write64(SectionSize); // size
223 } else {
224 Write32(getSectionAddress(&SD)); // address
225 Write32(SectionSize); // size
226 }
227 Write32(FileOffset);
228
229 unsigned Flags = Section.getTypeAndAttributes();
230 if (SD.hasInstructions())
231 Flags |= MCSectionMachO::S_ATTR_SOME_INSTRUCTIONS;
232
233 assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!");
234 Write32(Log2_32(SD.getAlignment()));
235 Write32(NumRelocations ? RelocationsStart : 0);
236 Write32(NumRelocations);
237 Write32(Flags);
238 Write32(IndirectSymBase.lookup(&SD)); // reserved1
239 Write32(Section.getStubSize()); // reserved2
240 if (is64Bit())
241 Write32(0); // reserved3
242
Charles Davisf69a29b2013-08-27 05:38:30 +0000243 assert(OS.tell() - Start == (is64Bit() ? macho::Section64Size :
244 macho::Section32Size));
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000245}
246
247void MachObjectWriter::WriteSymtabLoadCommand(uint32_t SymbolOffset,
248 uint32_t NumSymbols,
249 uint32_t StringTableOffset,
250 uint32_t StringTableSize) {
251 // struct symtab_command (24 bytes)
252
253 uint64_t Start = OS.tell();
254 (void) Start;
255
Charles Davisf69a29b2013-08-27 05:38:30 +0000256 Write32(macho::LCT_Symtab);
257 Write32(macho::SymtabLoadCommandSize);
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000258 Write32(SymbolOffset);
259 Write32(NumSymbols);
260 Write32(StringTableOffset);
261 Write32(StringTableSize);
262
Charles Davisf69a29b2013-08-27 05:38:30 +0000263 assert(OS.tell() - Start == macho::SymtabLoadCommandSize);
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000264}
265
266void MachObjectWriter::WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol,
267 uint32_t NumLocalSymbols,
268 uint32_t FirstExternalSymbol,
269 uint32_t NumExternalSymbols,
270 uint32_t FirstUndefinedSymbol,
271 uint32_t NumUndefinedSymbols,
272 uint32_t IndirectSymbolOffset,
273 uint32_t NumIndirectSymbols) {
274 // struct dysymtab_command (80 bytes)
275
276 uint64_t Start = OS.tell();
277 (void) Start;
278
Charles Davisf69a29b2013-08-27 05:38:30 +0000279 Write32(macho::LCT_Dysymtab);
280 Write32(macho::DysymtabLoadCommandSize);
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000281 Write32(FirstLocalSymbol);
282 Write32(NumLocalSymbols);
283 Write32(FirstExternalSymbol);
284 Write32(NumExternalSymbols);
285 Write32(FirstUndefinedSymbol);
286 Write32(NumUndefinedSymbols);
287 Write32(0); // tocoff
288 Write32(0); // ntoc
289 Write32(0); // modtaboff
290 Write32(0); // nmodtab
291 Write32(0); // extrefsymoff
292 Write32(0); // nextrefsyms
293 Write32(IndirectSymbolOffset);
294 Write32(NumIndirectSymbols);
295 Write32(0); // extreloff
296 Write32(0); // nextrel
297 Write32(0); // locreloff
298 Write32(0); // nlocrel
299
Charles Davisf69a29b2013-08-27 05:38:30 +0000300 assert(OS.tell() - Start == macho::DysymtabLoadCommandSize);
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000301}
302
Bill Wendling3f2ea822011-06-23 00:09:43 +0000303void MachObjectWriter::WriteNlist(MachSymbolData &MSD,
304 const MCAsmLayout &Layout) {
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000305 MCSymbolData &Data = *MSD.SymbolData;
306 const MCSymbol &Symbol = Data.getSymbol();
307 uint8_t Type = 0;
308 uint16_t Flags = Data.getFlags();
Jim Grosbach739b5572011-08-09 22:12:37 +0000309 uint64_t Address = 0;
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000310
311 // Set the N_TYPE bits. See <mach-o/nlist.h>.
312 //
313 // FIXME: Are the prebound or indirect fields possible here?
314 if (Symbol.isUndefined())
Charles Davisf69a29b2013-08-27 05:38:30 +0000315 Type = macho::STT_Undefined;
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000316 else if (Symbol.isAbsolute())
Charles Davisf69a29b2013-08-27 05:38:30 +0000317 Type = macho::STT_Absolute;
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000318 else
Charles Davisf69a29b2013-08-27 05:38:30 +0000319 Type = macho::STT_Section;
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000320
321 // FIXME: Set STAB bits.
322
323 if (Data.isPrivateExtern())
Charles Davisf69a29b2013-08-27 05:38:30 +0000324 Type |= macho::STF_PrivateExtern;
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000325
326 // Set external bit.
327 if (Data.isExternal() || Symbol.isUndefined())
Charles Davisf69a29b2013-08-27 05:38:30 +0000328 Type |= macho::STF_External;
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000329
330 // Compute the symbol address.
331 if (Symbol.isDefined()) {
Jim Grosbach45d81bd2012-09-13 23:11:25 +0000332 Address = getSymbolAddress(&Data, Layout);
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000333 } else if (Data.isCommon()) {
334 // Common symbols are encoded with the size in the address
335 // field, and their alignment in the flags.
336 Address = Data.getCommonSize();
337
338 // Common alignment is packed into the 'desc' bits.
339 if (unsigned Align = Data.getCommonAlignment()) {
340 unsigned Log2Size = Log2_32(Align);
341 assert((1U << Log2Size) == Align && "Invalid 'common' alignment!");
342 if (Log2Size > 15)
343 report_fatal_error("invalid 'common' alignment '" +
344 Twine(Align) + "'");
345 // FIXME: Keep this mask with the SymbolFlags enumeration.
346 Flags = (Flags & 0xF0FF) | (Log2Size << 8);
347 }
348 }
349
350 // struct nlist (12 bytes)
351
352 Write32(MSD.StringIndex);
353 Write8(Type);
354 Write8(MSD.SectionIndex);
355
356 // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
357 // value.
358 Write16(Flags);
359 if (is64Bit())
360 Write64(Address);
361 else
362 Write32(Address);
363}
364
Jim Grosbach3e965312012-05-18 19:12:01 +0000365void MachObjectWriter::WriteLinkeditLoadCommand(uint32_t Type,
366 uint32_t DataOffset,
367 uint32_t DataSize) {
368 uint64_t Start = OS.tell();
369 (void) Start;
370
371 Write32(Type);
Charles Davisf69a29b2013-08-27 05:38:30 +0000372 Write32(macho::LinkeditLoadCommandSize);
Jim Grosbach3e965312012-05-18 19:12:01 +0000373 Write32(DataOffset);
374 Write32(DataSize);
375
Charles Davisf69a29b2013-08-27 05:38:30 +0000376 assert(OS.tell() - Start == macho::LinkeditLoadCommandSize);
Jim Grosbach3e965312012-05-18 19:12:01 +0000377}
378
Daniel Dunbara94c3392013-01-18 01:26:07 +0000379static unsigned ComputeLinkerOptionsLoadCommandSize(
Daniel Dunbar84920962013-01-22 03:42:49 +0000380 const std::vector<std::string> &Options, bool is64Bit)
Daniel Dunbara94c3392013-01-18 01:26:07 +0000381{
Charles Davisf69a29b2013-08-27 05:38:30 +0000382 unsigned Size = sizeof(macho::LinkerOptionsLoadCommand);
Daniel Dunbara94c3392013-01-18 01:26:07 +0000383 for (unsigned i = 0, e = Options.size(); i != e; ++i)
384 Size += Options[i].size() + 1;
Daniel Dunbar84920962013-01-22 03:42:49 +0000385 return RoundUpToAlignment(Size, is64Bit ? 8 : 4);
Daniel Dunbara94c3392013-01-18 01:26:07 +0000386}
387
388void MachObjectWriter::WriteLinkerOptionsLoadCommand(
389 const std::vector<std::string> &Options)
390{
Daniel Dunbar84920962013-01-22 03:42:49 +0000391 unsigned Size = ComputeLinkerOptionsLoadCommandSize(Options, is64Bit());
Daniel Dunbara94c3392013-01-18 01:26:07 +0000392 uint64_t Start = OS.tell();
393 (void) Start;
394
Charles Davisf69a29b2013-08-27 05:38:30 +0000395 Write32(macho::LCT_LinkerOptions);
Daniel Dunbara94c3392013-01-18 01:26:07 +0000396 Write32(Size);
397 Write32(Options.size());
Charles Davisf69a29b2013-08-27 05:38:30 +0000398 uint64_t BytesWritten = sizeof(macho::LinkerOptionsLoadCommand);
Daniel Dunbara94c3392013-01-18 01:26:07 +0000399 for (unsigned i = 0, e = Options.size(); i != e; ++i) {
400 // Write each string, including the null byte.
401 const std::string &Option = Options[i];
402 WriteBytes(Option.c_str(), Option.size() + 1);
403 BytesWritten += Option.size() + 1;
404 }
405
Daniel Dunbar84920962013-01-22 03:42:49 +0000406 // Pad to a multiple of the pointer size.
407 WriteBytes("", OffsetToAlignment(BytesWritten, is64Bit() ? 8 : 4));
Daniel Dunbara94c3392013-01-18 01:26:07 +0000408
409 assert(OS.tell() - Start == Size);
410}
411
Jim Grosbach3e965312012-05-18 19:12:01 +0000412
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000413void MachObjectWriter::RecordRelocation(const MCAssembler &Asm,
414 const MCAsmLayout &Layout,
415 const MCFragment *Fragment,
416 const MCFixup &Fixup,
417 MCValue Target,
418 uint64_t &FixedValue) {
Jim Grosbachba8297e2011-06-24 23:44:37 +0000419 TargetObjectWriter->RecordRelocation(this, Asm, Layout, Fragment, Fixup,
420 Target, FixedValue);
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000421}
422
423void MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) {
424 // This is the point where 'as' creates actual symbols for indirect symbols
425 // (in the following two passes). It would be easier for us to do this sooner
426 // when we see the attribute, but that makes getting the order in the symbol
427 // table much more complicated than it is worth.
428 //
429 // FIXME: Revisit this when the dust settles.
430
Kevin Enderby4f066b62013-08-28 17:50:59 +0000431 // Report errors for use of .indirect_symbol not in a symbol pointer section
432 // or stub section.
433 for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
434 ie = Asm.indirect_symbol_end(); it != ie; ++it) {
435 const MCSectionMachO &Section =
436 cast<MCSectionMachO>(it->SectionData->getSection());
437
438 if (Section.getType() != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS &&
439 Section.getType() != MCSectionMachO::S_LAZY_SYMBOL_POINTERS &&
440 Section.getType() != MCSectionMachO::S_SYMBOL_STUBS) {
441 MCSymbol &Symbol = *it->Symbol;
442 report_fatal_error("indirect symbol '" + Symbol.getName() +
443 "' not in a symbol pointer or stub section");
444 }
445 }
446
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000447 // Bind non lazy symbol pointers first.
448 unsigned IndirectIndex = 0;
449 for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
450 ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) {
451 const MCSectionMachO &Section =
452 cast<MCSectionMachO>(it->SectionData->getSection());
453
454 if (Section.getType() != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS)
455 continue;
456
457 // Initialize the section indirect symbol base, if necessary.
Benjamin Kramer05d96f92012-08-22 15:37:57 +0000458 IndirectSymBase.insert(std::make_pair(it->SectionData, IndirectIndex));
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000459
460 Asm.getOrCreateSymbolData(*it->Symbol);
461 }
462
463 // Then lazy symbol pointers and symbol stubs.
464 IndirectIndex = 0;
465 for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
466 ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) {
467 const MCSectionMachO &Section =
468 cast<MCSectionMachO>(it->SectionData->getSection());
469
470 if (Section.getType() != MCSectionMachO::S_LAZY_SYMBOL_POINTERS &&
471 Section.getType() != MCSectionMachO::S_SYMBOL_STUBS)
472 continue;
473
474 // Initialize the section indirect symbol base, if necessary.
Benjamin Kramer05d96f92012-08-22 15:37:57 +0000475 IndirectSymBase.insert(std::make_pair(it->SectionData, IndirectIndex));
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000476
477 // Set the symbol type to undefined lazy, but only on construction.
478 //
479 // FIXME: Do not hardcode.
480 bool Created;
481 MCSymbolData &Entry = Asm.getOrCreateSymbolData(*it->Symbol, &Created);
482 if (Created)
483 Entry.setFlags(Entry.getFlags() | 0x0001);
484 }
485}
486
487/// ComputeSymbolTable - Compute the symbol table data
488///
489/// \param StringTable [out] - The string table data.
490/// \param StringIndexMap [out] - Map from symbol names to offsets in the
491/// string table.
Bill Wendling3f2ea822011-06-23 00:09:43 +0000492void MachObjectWriter::
493ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
494 std::vector<MachSymbolData> &LocalSymbolData,
495 std::vector<MachSymbolData> &ExternalSymbolData,
496 std::vector<MachSymbolData> &UndefinedSymbolData) {
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000497 // Build section lookup table.
498 DenseMap<const MCSection*, uint8_t> SectionIndexMap;
499 unsigned Index = 1;
500 for (MCAssembler::iterator it = Asm.begin(),
501 ie = Asm.end(); it != ie; ++it, ++Index)
502 SectionIndexMap[&it->getSection()] = Index;
503 assert(Index <= 256 && "Too many sections!");
504
505 // Index 0 is always the empty string.
506 StringMap<uint64_t> StringIndexMap;
507 StringTable += '\x00';
508
509 // Build the symbol arrays and the string table, but only for non-local
510 // symbols.
511 //
512 // The particular order that we collect the symbols and create the string
513 // table, then sort the symbols is chosen to match 'as'. Even though it
514 // doesn't matter for correctness, this is important for letting us diff .o
515 // files.
516 for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
517 ie = Asm.symbol_end(); it != ie; ++it) {
518 const MCSymbol &Symbol = it->getSymbol();
519
520 // Ignore non-linker visible symbols.
521 if (!Asm.isSymbolLinkerVisible(it->getSymbol()))
522 continue;
523
524 if (!it->isExternal() && !Symbol.isUndefined())
525 continue;
526
527 uint64_t &Entry = StringIndexMap[Symbol.getName()];
528 if (!Entry) {
529 Entry = StringTable.size();
530 StringTable += Symbol.getName();
531 StringTable += '\x00';
532 }
533
534 MachSymbolData MSD;
535 MSD.SymbolData = it;
536 MSD.StringIndex = Entry;
537
538 if (Symbol.isUndefined()) {
539 MSD.SectionIndex = 0;
540 UndefinedSymbolData.push_back(MSD);
541 } else if (Symbol.isAbsolute()) {
542 MSD.SectionIndex = 0;
543 ExternalSymbolData.push_back(MSD);
544 } else {
545 MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection());
546 assert(MSD.SectionIndex && "Invalid section index!");
547 ExternalSymbolData.push_back(MSD);
548 }
549 }
550
551 // Now add the data for local symbols.
552 for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
553 ie = Asm.symbol_end(); it != ie; ++it) {
554 const MCSymbol &Symbol = it->getSymbol();
555
556 // Ignore non-linker visible symbols.
557 if (!Asm.isSymbolLinkerVisible(it->getSymbol()))
558 continue;
559
560 if (it->isExternal() || Symbol.isUndefined())
561 continue;
562
563 uint64_t &Entry = StringIndexMap[Symbol.getName()];
564 if (!Entry) {
565 Entry = StringTable.size();
566 StringTable += Symbol.getName();
567 StringTable += '\x00';
568 }
569
570 MachSymbolData MSD;
571 MSD.SymbolData = it;
572 MSD.StringIndex = Entry;
573
574 if (Symbol.isAbsolute()) {
575 MSD.SectionIndex = 0;
576 LocalSymbolData.push_back(MSD);
577 } else {
578 MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection());
579 assert(MSD.SectionIndex && "Invalid section index!");
580 LocalSymbolData.push_back(MSD);
581 }
582 }
583
584 // External and undefined symbols are required to be in lexicographic order.
585 std::sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
586 std::sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end());
587
588 // Set the symbol indices.
589 Index = 0;
590 for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
591 LocalSymbolData[i].SymbolData->setIndex(Index++);
592 for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
593 ExternalSymbolData[i].SymbolData->setIndex(Index++);
594 for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
595 UndefinedSymbolData[i].SymbolData->setIndex(Index++);
596
597 // The string table is padded to a multiple of 4.
598 while (StringTable.size() % 4)
599 StringTable += '\x00';
600}
601
602void MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm,
603 const MCAsmLayout &Layout) {
604 uint64_t StartAddress = 0;
605 const SmallVectorImpl<MCSectionData*> &Order = Layout.getSectionOrder();
606 for (int i = 0, n = Order.size(); i != n ; ++i) {
607 const MCSectionData *SD = Order[i];
608 StartAddress = RoundUpToAlignment(StartAddress, SD->getAlignment());
609 SectionAddress[SD] = StartAddress;
610 StartAddress += Layout.getSectionAddressSize(SD);
611
612 // Explicitly pad the section to match the alignment requirements of the
613 // following one. This is for 'gas' compatibility, it shouldn't
614 /// strictly be necessary.
615 StartAddress += getPaddingSize(SD, Layout);
616 }
617}
618
Jim Grosbach45d81bd2012-09-13 23:11:25 +0000619void MachObjectWriter::markAbsoluteVariableSymbols(MCAssembler &Asm,
620 const MCAsmLayout &Layout) {
621 for (MCAssembler::symbol_iterator i = Asm.symbol_begin(),
622 e = Asm.symbol_end();
623 i != e; ++i) {
624 MCSymbolData &SD = *i;
625 if (!SD.getSymbol().isVariable())
626 continue;
627
628 // Is the variable is a symbol difference (SA - SB + C) expression,
629 // and neither symbol is external, mark the variable as absolute.
630 const MCExpr *Expr = SD.getSymbol().getVariableValue();
631 MCValue Value;
632 if (Expr->EvaluateAsRelocatable(Value, Layout)) {
633 if (Value.getSymA() && Value.getSymB())
634 const_cast<MCSymbol*>(&SD.getSymbol())->setAbsolute();
635 }
636 }
637}
638
Bill Wendling3f2ea822011-06-23 00:09:43 +0000639void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
640 const MCAsmLayout &Layout) {
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000641 computeSectionAddresses(Asm, Layout);
642
643 // Create symbol data for any indirect symbols.
644 BindIndirectSymbols(Asm);
645
Jim Grosbach45d81bd2012-09-13 23:11:25 +0000646 // Mark symbol difference expressions in variables (from .set or = directives)
647 // as absolute.
648 markAbsoluteVariableSymbols(Asm, Layout);
649
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000650 // Compute symbol table information and bind symbol indices.
651 ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData,
652 UndefinedSymbolData);
653}
654
Bill Wendling3f2ea822011-06-23 00:09:43 +0000655bool MachObjectWriter::
656IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
657 const MCSymbolData &DataA,
658 const MCFragment &FB,
659 bool InSet,
660 bool IsPCRel) const {
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000661 if (InSet)
662 return true;
663
664 // The effective address is
665 // addr(atom(A)) + offset(A)
666 // - addr(atom(B)) - offset(B)
667 // and the offsets are not relocatable, so the fixup is fully resolved when
668 // addr(atom(A)) - addr(atom(B)) == 0.
669 const MCSymbolData *A_Base = 0, *B_Base = 0;
670
671 const MCSymbol &SA = DataA.getSymbol().AliasedSymbol();
672 const MCSection &SecA = SA.getSection();
673 const MCSection &SecB = FB.getParent()->getSection();
674
675 if (IsPCRel) {
676 // The simple (Darwin, except on x86_64) way of dealing with this was to
677 // assume that any reference to a temporary symbol *must* be a temporary
678 // symbol in the same atom, unless the sections differ. Therefore, any PCrel
679 // relocation to a temporary symbol (in the same section) is fully
680 // resolved. This also works in conjunction with absolutized .set, which
681 // requires the compiler to use .set to absolutize the differences between
682 // symbols which the compiler knows to be assembly time constants, so we
683 // don't need to worry about considering symbol differences fully resolved.
Jim Grosbach577b0912011-12-07 19:46:59 +0000684 //
685 // If the file isn't using sub-sections-via-symbols, we can make the
686 // same assumptions about any symbol that we normally make about
687 // assembler locals.
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000688
689 if (!Asm.getBackend().hasReliableSymbolDifference()) {
Jim Grosbach8b9300b2012-01-17 22:14:39 +0000690 if (!SA.isInSection() || &SecA != &SecB ||
Jim Grosbachec4ceb72012-01-18 21:54:12 +0000691 (!SA.isTemporary() &&
Jim Grosbachc389af92012-01-24 21:45:25 +0000692 FB.getAtom() != Asm.getSymbolData(SA).getFragment()->getAtom() &&
693 Asm.getSubsectionsViaSymbols()))
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000694 return false;
695 return true;
696 }
Kevin Enderby5afc1902011-09-08 20:53:44 +0000697 // For Darwin x86_64, there is one special case when the reference IsPCRel.
698 // If the fragment with the reference does not have a base symbol but meets
699 // the simple way of dealing with this, in that it is a temporary symbol in
700 // the same atom then it is assumed to be fully resolved. This is needed so
Eric Christopherd1e002a2011-09-08 22:17:40 +0000701 // a relocation entry is not created and so the static linker does not
Kevin Enderby5afc1902011-09-08 20:53:44 +0000702 // mess up the reference later.
703 else if(!FB.getAtom() &&
704 SA.isTemporary() && SA.isInSection() && &SecA == &SecB){
705 return true;
706 }
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000707 } else {
708 if (!TargetObjectWriter->useAggressiveSymbolFolding())
709 return false;
710 }
711
Benjamin Kramer0d46ccf2011-08-12 01:51:29 +0000712 const MCFragment *FA = Asm.getSymbolData(SA).getFragment();
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000713
Benjamin Kramer0d46ccf2011-08-12 01:51:29 +0000714 // Bail if the symbol has no fragment.
715 if (!FA)
716 return false;
717
718 A_Base = FA->getAtom();
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000719 if (!A_Base)
720 return false;
721
722 B_Base = FB.getAtom();
723 if (!B_Base)
724 return false;
725
726 // If the atoms are the same, they are guaranteed to have the same address.
727 if (A_Base == B_Base)
728 return true;
729
730 // Otherwise, we can't prove this is fully resolved.
731 return false;
732}
733
Eric Christopherd1e002a2011-09-08 22:17:40 +0000734void MachObjectWriter::WriteObject(MCAssembler &Asm,
Jim Grosbachf68a26b2011-12-06 00:13:09 +0000735 const MCAsmLayout &Layout) {
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000736 unsigned NumSections = Asm.size();
737
738 // The section data starts after the header, the segment load command (and
739 // section headers) and the symbol table.
740 unsigned NumLoadCommands = 1;
741 uint64_t LoadCommandsSize = is64Bit() ?
Charles Davisf69a29b2013-08-27 05:38:30 +0000742 macho::SegmentLoadCommand64Size + NumSections * macho::Section64Size :
743 macho::SegmentLoadCommand32Size + NumSections * macho::Section32Size;
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000744
Daniel Dunbara94c3392013-01-18 01:26:07 +0000745 // Add the data-in-code load command size, if used.
746 unsigned NumDataRegions = Asm.getDataRegions().size();
747 if (NumDataRegions) {
748 ++NumLoadCommands;
Charles Davisf69a29b2013-08-27 05:38:30 +0000749 LoadCommandsSize += macho::LinkeditLoadCommandSize;
Daniel Dunbara94c3392013-01-18 01:26:07 +0000750 }
751
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000752 // Add the symbol table load command sizes, if used.
753 unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +
754 UndefinedSymbolData.size();
755 if (NumSymbols) {
756 NumLoadCommands += 2;
Charles Davisf69a29b2013-08-27 05:38:30 +0000757 LoadCommandsSize += (macho::SymtabLoadCommandSize +
758 macho::DysymtabLoadCommandSize);
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000759 }
760
Daniel Dunbara94c3392013-01-18 01:26:07 +0000761 // Add the linker option load commands sizes.
762 const std::vector<std::vector<std::string> > &LinkerOptions =
763 Asm.getLinkerOptions();
764 for (unsigned i = 0, e = LinkerOptions.size(); i != e; ++i) {
Jim Grosbach3e965312012-05-18 19:12:01 +0000765 ++NumLoadCommands;
Daniel Dunbar84920962013-01-22 03:42:49 +0000766 LoadCommandsSize += ComputeLinkerOptionsLoadCommandSize(LinkerOptions[i],
767 is64Bit());
Jim Grosbach3e965312012-05-18 19:12:01 +0000768 }
Daniel Dunbara94c3392013-01-18 01:26:07 +0000769
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000770 // Compute the total size of the section data, as well as its file size and vm
771 // size.
Charles Davisf69a29b2013-08-27 05:38:30 +0000772 uint64_t SectionDataStart = (is64Bit() ? macho::Header64Size :
773 macho::Header32Size) + LoadCommandsSize;
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000774 uint64_t SectionDataSize = 0;
775 uint64_t SectionDataFileSize = 0;
776 uint64_t VMSize = 0;
777 for (MCAssembler::const_iterator it = Asm.begin(),
778 ie = Asm.end(); it != ie; ++it) {
779 const MCSectionData &SD = *it;
780 uint64_t Address = getSectionAddress(&SD);
781 uint64_t Size = Layout.getSectionAddressSize(&SD);
782 uint64_t FileSize = Layout.getSectionFileSize(&SD);
783 FileSize += getPaddingSize(&SD, Layout);
784
785 VMSize = std::max(VMSize, Address + Size);
786
787 if (SD.getSection().isVirtualSection())
788 continue;
789
790 SectionDataSize = std::max(SectionDataSize, Address + Size);
791 SectionDataFileSize = std::max(SectionDataFileSize, Address + FileSize);
792 }
793
794 // The section data is padded to 4 bytes.
795 //
796 // FIXME: Is this machine dependent?
797 unsigned SectionDataPadding = OffsetToAlignment(SectionDataFileSize, 4);
798 SectionDataFileSize += SectionDataPadding;
799
800 // Write the prolog, starting with the header and load command...
801 WriteHeader(NumLoadCommands, LoadCommandsSize,
802 Asm.getSubsectionsViaSymbols());
803 WriteSegmentLoadCommand(NumSections, VMSize,
804 SectionDataStart, SectionDataSize);
805
806 // ... and then the section headers.
807 uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
808 for (MCAssembler::const_iterator it = Asm.begin(),
809 ie = Asm.end(); it != ie; ++it) {
Charles Davisf69a29b2013-08-27 05:38:30 +0000810 std::vector<macho::RelocationEntry> &Relocs = Relocations[it];
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000811 unsigned NumRelocs = Relocs.size();
812 uint64_t SectionStart = SectionDataStart + getSectionAddress(it);
813 WriteSection(Asm, Layout, *it, SectionStart, RelocTableEnd, NumRelocs);
Charles Davisf69a29b2013-08-27 05:38:30 +0000814 RelocTableEnd += NumRelocs * macho::RelocationInfoSize;
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000815 }
816
Jim Grosbach3e965312012-05-18 19:12:01 +0000817 // Write the data-in-code load command, if used.
818 uint64_t DataInCodeTableEnd = RelocTableEnd + NumDataRegions * 8;
819 if (NumDataRegions) {
820 uint64_t DataRegionsOffset = RelocTableEnd;
821 uint64_t DataRegionsSize = NumDataRegions * 8;
Charles Davisf69a29b2013-08-27 05:38:30 +0000822 WriteLinkeditLoadCommand(macho::LCT_DataInCode, DataRegionsOffset,
Jim Grosbach3e965312012-05-18 19:12:01 +0000823 DataRegionsSize);
824 }
825
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000826 // 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
840 // If used, the indirect symbols are written after the section data.
841 if (NumIndirectSymbols)
Jim Grosbach3e965312012-05-18 19:12:01 +0000842 IndirectSymbolOffset = DataInCodeTableEnd;
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000843
844 // The symbol table is written after the indirect symbol data.
Jim Grosbach3e965312012-05-18 19:12:01 +0000845 uint64_t SymbolTableOffset = DataInCodeTableEnd + IndirectSymbolSize;
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000846
847 // The string table is written after symbol table.
848 uint64_t StringTableOffset =
Charles Davisf69a29b2013-08-27 05:38:30 +0000849 SymbolTableOffset + NumSymTabSymbols * (is64Bit() ? macho::Nlist64Size :
850 macho::Nlist32Size);
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000851 WriteSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols,
852 StringTableOffset, StringTable.size());
853
854 WriteDysymtabLoadCommand(FirstLocalSymbol, NumLocalSymbols,
855 FirstExternalSymbol, NumExternalSymbols,
856 FirstUndefinedSymbol, NumUndefinedSymbols,
857 IndirectSymbolOffset, NumIndirectSymbols);
858 }
859
Daniel Dunbara94c3392013-01-18 01:26:07 +0000860 // Write the linker options load commands.
861 for (unsigned i = 0, e = LinkerOptions.size(); i != e; ++i) {
862 WriteLinkerOptionsLoadCommand(LinkerOptions[i]);
863 }
864
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000865 // Write the actual section data.
866 for (MCAssembler::const_iterator it = Asm.begin(),
867 ie = Asm.end(); it != ie; ++it) {
Jim Grosbachf77d5b12011-12-06 00:03:48 +0000868 Asm.writeSectionData(it, Layout);
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000869
870 uint64_t Pad = getPaddingSize(it, Layout);
871 for (unsigned int i = 0; i < Pad; ++i)
872 Write8(0);
873 }
874
875 // Write the extra padding.
876 WriteZeros(SectionDataPadding);
877
878 // Write the relocation entries.
879 for (MCAssembler::const_iterator it = Asm.begin(),
880 ie = Asm.end(); it != ie; ++it) {
881 // Write the section relocation entries, in reverse order to match 'as'
882 // (approximately, the exact algorithm is more complicated than this).
Charles Davisf69a29b2013-08-27 05:38:30 +0000883 std::vector<macho::RelocationEntry> &Relocs = Relocations[it];
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000884 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
Charles Davisf69a29b2013-08-27 05:38:30 +0000885 Write32(Relocs[e - i - 1].Word0);
886 Write32(Relocs[e - i - 1].Word1);
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000887 }
888 }
889
Jim Grosbach3e965312012-05-18 19:12:01 +0000890 // Write out the data-in-code region payload, if there is one.
891 for (MCAssembler::const_data_region_iterator
892 it = Asm.data_region_begin(), ie = Asm.data_region_end();
893 it != ie; ++it) {
894 const DataRegionData *Data = &(*it);
Jim Grosbache75a9832012-09-18 23:05:12 +0000895 uint64_t Start =
896 getSymbolAddress(&Layout.getAssembler().getSymbolData(*Data->Start),
897 Layout);
898 uint64_t End =
899 getSymbolAddress(&Layout.getAssembler().getSymbolData(*Data->End),
900 Layout);
Jim Grosbach3e965312012-05-18 19:12:01 +0000901 DEBUG(dbgs() << "data in code region-- kind: " << Data->Kind
902 << " start: " << Start << "(" << Data->Start->getName() << ")"
903 << " end: " << End << "(" << Data->End->getName() << ")"
904 << " size: " << End - Start
905 << "\n");
906 Write32(Start);
907 Write16(End - Start);
908 Write16(Data->Kind);
909 }
910
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000911 // Write the symbol table data, if used.
912 if (NumSymbols) {
913 // Write the indirect symbol entries.
914 for (MCAssembler::const_indirect_symbol_iterator
915 it = Asm.indirect_symbol_begin(),
916 ie = Asm.indirect_symbol_end(); it != ie; ++it) {
917 // Indirect symbols in the non lazy symbol pointer section have some
918 // special handling.
919 const MCSectionMachO &Section =
920 static_cast<const MCSectionMachO&>(it->SectionData->getSection());
921 if (Section.getType() == MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS) {
922 // If this symbol is defined and internal, mark it as such.
923 if (it->Symbol->isDefined() &&
924 !Asm.getSymbolData(*it->Symbol).isExternal()) {
Charles Davisf69a29b2013-08-27 05:38:30 +0000925 uint32_t Flags = macho::ISF_Local;
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000926 if (it->Symbol->isAbsolute())
Charles Davisf69a29b2013-08-27 05:38:30 +0000927 Flags |= macho::ISF_Absolute;
Bill Wendlingbbdffa92011-06-22 21:07:27 +0000928 Write32(Flags);
929 continue;
930 }
931 }
932
933 Write32(Asm.getSymbolData(*it->Symbol).getIndex());
934 }
935
936 // FIXME: Check that offsets match computed ones.
937
938 // Write the symbol table entries.
939 for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
940 WriteNlist(LocalSymbolData[i], Layout);
941 for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
942 WriteNlist(ExternalSymbolData[i], Layout);
943 for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
944 WriteNlist(UndefinedSymbolData[i], Layout);
945
946 // Write the string table.
947 OS << StringTable.str();
948 }
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000949}
950
Daniel Dunbarae5abd52010-12-16 16:09:19 +0000951MCObjectWriter *llvm::createMachObjectWriter(MCMachObjectTargetWriter *MOTW,
Daniel Dunbar5d05d972010-12-16 17:21:02 +0000952 raw_ostream &OS,
Daniel Dunbar115a3dd2010-11-13 07:33:40 +0000953 bool IsLittleEndian) {
Daniel Dunbar5d05d972010-12-16 17:21:02 +0000954 return new MachObjectWriter(MOTW, OS, IsLittleEndian);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000955}