blob: 96867e45a40e7151c44d5fe0ec075dc8940183c9 [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 Dunbar2df4ceb2010-03-19 10:43:15 +000010#include "llvm/ADT/StringMap.h"
11#include "llvm/ADT/Twine.h"
12#include "llvm/MC/MCAssembler.h"
Daniel Dunbar207e06e2010-03-24 03:43:40 +000013#include "llvm/MC/MCAsmLayout.h"
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +000014#include "llvm/MC/MCExpr.h"
15#include "llvm/MC/MCObjectWriter.h"
16#include "llvm/MC/MCSectionMachO.h"
17#include "llvm/MC/MCSymbol.h"
Kevin Enderbya6eeb6e2010-05-07 21:44:23 +000018#include "llvm/MC/MCMachOSymbolFlags.h"
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +000019#include "llvm/MC/MCValue.h"
Daniel Dunbar821ecd72010-11-27 04:19:38 +000020#include "llvm/Object/MachOFormat.h"
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +000021#include "llvm/Support/ErrorHandling.h"
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +000022#include "llvm/Target/TargetAsmBackend.h"
23
24// FIXME: Gross.
25#include "../Target/X86/X86FixupKinds.h"
26
27#include <vector>
28using namespace llvm;
Daniel Dunbar821ecd72010-11-27 04:19:38 +000029using namespace llvm::object;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +000030
Rafael Espindolaa8c02c32010-09-30 03:11:42 +000031// FIXME: this has been copied from (or to) X86AsmBackend.cpp
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +000032static unsigned getFixupKindLog2Size(unsigned Kind) {
33 switch (Kind) {
Jim Grosbachdff84b02010-12-02 00:28:45 +000034 // FIXME: Until ARM has it's own relocation stuff spun off, it comes
35 // through here and we don't want it to puke all over. Any reasonable
36 // values will only come when ARM relocation support gets added, at which
37 // point this will be X86 only again and the llvm_unreachable can be
38 // re-enabled.
39 default: return 0;// llvm_unreachable("invalid fixup kind!");
Rafael Espindolae04ed7e2010-11-28 14:17:56 +000040 case FK_PCRel_1:
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +000041 case FK_Data_1: return 0;
Rafael Espindolae04ed7e2010-11-28 14:17:56 +000042 case FK_PCRel_2:
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +000043 case FK_Data_2: return 1;
Rafael Espindolae04ed7e2010-11-28 14:17:56 +000044 case FK_PCRel_4:
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +000045 case X86::reloc_riprel_4byte:
Daniel Dunbar602b40f2010-03-19 18:07:55 +000046 case X86::reloc_riprel_4byte_movq_load:
Rafael Espindolaa8c02c32010-09-30 03:11:42 +000047 case X86::reloc_signed_4byte:
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +000048 case FK_Data_4: return 2;
49 case FK_Data_8: return 3;
50 }
51}
52
Daniel Dunbare9460ec2010-05-10 23:15:13 +000053static bool doesSymbolRequireExternRelocation(MCSymbolData *SD) {
54 // Undefined symbols are always extern.
55 if (SD->Symbol->isUndefined())
56 return true;
57
58 // References to weak definitions require external relocation entries; the
59 // definition may not always be the one in the same object file.
60 if (SD->getFlags() & SF_WeakDefinition)
61 return true;
62
63 // Otherwise, we can use an internal relocation.
64 return false;
65}
66
Rafael Espindola70703872010-09-30 02:22:20 +000067static bool isScatteredFixupFullyResolved(const MCAssembler &Asm,
68 const MCValue Target,
69 const MCSymbolData *BaseSymbol) {
70 // The effective fixup address is
71 // addr(atom(A)) + offset(A)
72 // - addr(atom(B)) - offset(B)
73 // - addr(BaseSymbol) + <fixup offset from base symbol>
74 // and the offsets are not relocatable, so the fixup is fully resolved when
75 // addr(atom(A)) - addr(atom(B)) - addr(BaseSymbol) == 0.
76 //
77 // Note that "false" is almost always conservatively correct (it means we emit
78 // a relocation which is unnecessary), except when it would force us to emit a
79 // relocation which the target cannot encode.
80
81 const MCSymbolData *A_Base = 0, *B_Base = 0;
82 if (const MCSymbolRefExpr *A = Target.getSymA()) {
83 // Modified symbol references cannot be resolved.
84 if (A->getKind() != MCSymbolRefExpr::VK_None)
85 return false;
86
87 A_Base = Asm.getAtom(&Asm.getSymbolData(A->getSymbol()));
88 if (!A_Base)
89 return false;
90 }
91
92 if (const MCSymbolRefExpr *B = Target.getSymB()) {
93 // Modified symbol references cannot be resolved.
94 if (B->getKind() != MCSymbolRefExpr::VK_None)
95 return false;
96
97 B_Base = Asm.getAtom(&Asm.getSymbolData(B->getSymbol()));
98 if (!B_Base)
99 return false;
100 }
101
102 // If there is no base, A and B have to be the same atom for this fixup to be
103 // fully resolved.
104 if (!BaseSymbol)
105 return A_Base == B_Base;
106
107 // Otherwise, B must be missing and A must be the base.
108 return !B_Base && BaseSymbol == A_Base;
109}
110
111static bool isScatteredFixupFullyResolvedSimple(const MCAssembler &Asm,
112 const MCValue Target,
113 const MCSection *BaseSection) {
114 // The effective fixup address is
115 // addr(atom(A)) + offset(A)
116 // - addr(atom(B)) - offset(B)
117 // - addr(<base symbol>) + <fixup offset from base symbol>
118 // and the offsets are not relocatable, so the fixup is fully resolved when
119 // addr(atom(A)) - addr(atom(B)) - addr(<base symbol>)) == 0.
120 //
121 // The simple (Darwin, except on x86_64) way of dealing with this was to
122 // assume that any reference to a temporary symbol *must* be a temporary
123 // symbol in the same atom, unless the sections differ. Therefore, any PCrel
124 // relocation to a temporary symbol (in the same section) is fully
125 // resolved. This also works in conjunction with absolutized .set, which
126 // requires the compiler to use .set to absolutize the differences between
127 // symbols which the compiler knows to be assembly time constants, so we don't
128 // need to worry about considering symbol differences fully resolved.
129
130 // Non-relative fixups are only resolved if constant.
131 if (!BaseSection)
132 return Target.isAbsolute();
133
134 // Otherwise, relative fixups are only resolved if not a difference and the
135 // target is a temporary in the same section.
136 if (Target.isAbsolute() || Target.getSymB())
137 return false;
138
139 const MCSymbol *A = &Target.getSymA()->getSymbol();
140 if (!A->isTemporary() || !A->isInSection() ||
141 &A->getSection() != BaseSection)
142 return false;
143
144 return true;
145}
146
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000147namespace {
148
Daniel Dunbar115a3dd2010-11-13 07:33:40 +0000149class MachObjectWriter : public MCObjectWriter {
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000150 /// MachSymbolData - Helper struct for containing some precomputed information
151 /// on symbols.
152 struct MachSymbolData {
153 MCSymbolData *SymbolData;
154 uint64_t StringIndex;
155 uint8_t SectionIndex;
156
157 // Support lexicographic sorting.
158 bool operator<(const MachSymbolData &RHS) const {
Benjamin Kramerc37791e2010-05-20 14:14:22 +0000159 return SymbolData->getSymbol().getName() <
160 RHS.SymbolData->getSymbol().getName();
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000161 }
162 };
163
Daniel Dunbar7e06af82010-12-16 15:42:31 +0000164 /// @name Utility Methods
165 /// @{
166
167 bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) {
168 const MCFixupKindInfo &FKI = Asm.getBackend().getFixupKindInfo(
169 (MCFixupKind) Kind);
170
171 return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel;
172 }
173
174 /// @}
175
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000176 /// @name Relocation Data
177 /// @{
178
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000179 llvm::DenseMap<const MCSectionData*,
Daniel Dunbar90e3e3a2010-11-27 13:39:48 +0000180 std::vector<macho::RelocationEntry> > Relocations;
Daniel Dunbar2ae4bfd2010-05-18 17:28:24 +0000181 llvm::DenseMap<const MCSectionData*, unsigned> IndirectSymBase;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000182
183 /// @}
184 /// @name Symbol Table Data
185 /// @{
186
187 SmallString<256> StringTable;
188 std::vector<MachSymbolData> LocalSymbolData;
189 std::vector<MachSymbolData> ExternalSymbolData;
190 std::vector<MachSymbolData> UndefinedSymbolData;
191
192 /// @}
193
Rafael Espindola85f2ecc2010-12-07 00:27:36 +0000194 SectionAddrMap SectionAddress;
195 uint64_t getSectionAddress(const MCSectionData* SD) const {
196 return SectionAddress.lookup(SD);
197 }
198 uint64_t getSymbolAddress(const MCSymbolData* SD,
199 const MCAsmLayout &Layout) const {
200 return getSectionAddress(SD->getFragment()->getParent()) +
201 Layout.getSymbolOffset(SD);
202 }
203 uint64_t getFragmentAddress(const MCFragment *Fragment,
204 const MCAsmLayout &Layout) const {
205 return getSectionAddress(Fragment->getParent()) +
206 Layout.getFragmentOffset(Fragment);
207 }
208
209 uint64_t getPaddingSize(const MCSectionData *SD,
210 const MCAsmLayout &Layout) const {
211 uint64_t EndAddr = getSectionAddress(SD) + Layout.getSectionAddressSize(SD);
212 unsigned Next = SD->getLayoutOrder() + 1;
213 if (Next >= Layout.getSectionOrder().size())
214 return 0;
215
216 const MCSectionData &NextSD = *Layout.getSectionOrder()[Next];
217 if (NextSD.getSection().isVirtualSection())
218 return 0;
219 return OffsetToAlignment(EndAddr, NextSD.getAlignment());
220 }
221
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000222 unsigned Is64Bit : 1;
223
Jim Grosbachc9d14392010-11-05 18:48:58 +0000224 uint32_t CPUType;
225 uint32_t CPUSubtype;
226
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000227public:
Daniel Dunbar115a3dd2010-11-13 07:33:40 +0000228 MachObjectWriter(raw_ostream &_OS,
229 bool _Is64Bit, uint32_t _CPUType, uint32_t _CPUSubtype,
230 bool _IsLittleEndian)
231 : MCObjectWriter(_OS, _IsLittleEndian),
232 Is64Bit(_Is64Bit), CPUType(_CPUType), CPUSubtype(_CPUSubtype) {
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000233 }
234
235 void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize,
236 bool SubsectionsViaSymbols) {
237 uint32_t Flags = 0;
238
239 if (SubsectionsViaSymbols)
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000240 Flags |= macho::HF_SubsectionsViaSymbols;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000241
242 // struct mach_header (28 bytes) or
243 // struct mach_header_64 (32 bytes)
244
245 uint64_t Start = OS.tell();
246 (void) Start;
247
Daniel Dunbar821ecd72010-11-27 04:19:38 +0000248 Write32(Is64Bit ? macho::HM_Object64 : macho::HM_Object32);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000249
Jim Grosbachc9d14392010-11-05 18:48:58 +0000250 Write32(CPUType);
251 Write32(CPUSubtype);
252
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000253 Write32(macho::HFT_Object);
Daniel Dunbar590956f2010-11-27 07:39:37 +0000254 Write32(NumLoadCommands);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000255 Write32(LoadCommandsSize);
256 Write32(Flags);
257 if (Is64Bit)
258 Write32(0); // reserved
259
Daniel Dunbar821ecd72010-11-27 04:19:38 +0000260 assert(OS.tell() - Start == Is64Bit ?
261 macho::Header64Size : macho::Header32Size);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000262 }
263
264 /// WriteSegmentLoadCommand - Write a segment load command.
265 ///
266 /// \arg NumSections - The number of sections in this segment.
267 /// \arg SectionDataSize - The total size of the sections.
268 void WriteSegmentLoadCommand(unsigned NumSections,
269 uint64_t VMSize,
270 uint64_t SectionDataStartOffset,
271 uint64_t SectionDataSize) {
272 // struct segment_command (56 bytes) or
273 // struct segment_command_64 (72 bytes)
274
275 uint64_t Start = OS.tell();
276 (void) Start;
277
Daniel Dunbar821ecd72010-11-27 04:19:38 +0000278 unsigned SegmentLoadCommandSize = Is64Bit ? macho::SegmentLoadCommand64Size:
279 macho::SegmentLoadCommand32Size;
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000280 Write32(Is64Bit ? macho::LCT_Segment64 : macho::LCT_Segment);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000281 Write32(SegmentLoadCommandSize +
Daniel Dunbar821ecd72010-11-27 04:19:38 +0000282 NumSections * (Is64Bit ? macho::Section64Size :
283 macho::Section32Size));
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000284
285 WriteBytes("", 16);
286 if (Is64Bit) {
287 Write64(0); // vmaddr
288 Write64(VMSize); // vmsize
289 Write64(SectionDataStartOffset); // file offset
290 Write64(SectionDataSize); // file size
291 } else {
292 Write32(0); // vmaddr
293 Write32(VMSize); // vmsize
294 Write32(SectionDataStartOffset); // file offset
295 Write32(SectionDataSize); // file size
296 }
297 Write32(0x7); // maxprot
298 Write32(0x7); // initprot
299 Write32(NumSections);
300 Write32(0); // flags
301
302 assert(OS.tell() - Start == SegmentLoadCommandSize);
303 }
304
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000305 void WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
306 const MCSectionData &SD, uint64_t FileOffset,
307 uint64_t RelocationsStart, unsigned NumRelocations) {
Rafael Espindola85f2ecc2010-12-07 00:27:36 +0000308 uint64_t SectionSize = Layout.getSectionAddressSize(&SD);
Daniel Dunbar5d428512010-03-25 02:00:07 +0000309
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000310 // The offset is unused for virtual sections.
Rafael Espindolaf2dc4aa2010-11-17 20:03:54 +0000311 if (SD.getSection().isVirtualSection()) {
Daniel Dunbarb026d642010-03-25 07:10:05 +0000312 assert(Layout.getSectionFileSize(&SD) == 0 && "Invalid file size!");
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000313 FileOffset = 0;
314 }
315
316 // struct section (68 bytes) or
317 // struct section_64 (80 bytes)
318
319 uint64_t Start = OS.tell();
320 (void) Start;
321
Daniel Dunbar56279f42010-05-18 17:28:20 +0000322 const MCSectionMachO &Section = cast<MCSectionMachO>(SD.getSection());
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000323 WriteBytes(Section.getSectionName(), 16);
324 WriteBytes(Section.getSegmentName(), 16);
325 if (Is64Bit) {
Rafael Espindola85f2ecc2010-12-07 00:27:36 +0000326 Write64(getSectionAddress(&SD)); // address
Daniel Dunbar5d428512010-03-25 02:00:07 +0000327 Write64(SectionSize); // size
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000328 } else {
Rafael Espindola85f2ecc2010-12-07 00:27:36 +0000329 Write32(getSectionAddress(&SD)); // address
Daniel Dunbar5d428512010-03-25 02:00:07 +0000330 Write32(SectionSize); // size
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000331 }
332 Write32(FileOffset);
333
334 unsigned Flags = Section.getTypeAndAttributes();
335 if (SD.hasInstructions())
336 Flags |= MCSectionMachO::S_ATTR_SOME_INSTRUCTIONS;
337
338 assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!");
339 Write32(Log2_32(SD.getAlignment()));
340 Write32(NumRelocations ? RelocationsStart : 0);
341 Write32(NumRelocations);
342 Write32(Flags);
Daniel Dunbar2ae4bfd2010-05-18 17:28:24 +0000343 Write32(IndirectSymBase.lookup(&SD)); // reserved1
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000344 Write32(Section.getStubSize()); // reserved2
345 if (Is64Bit)
346 Write32(0); // reserved3
347
Daniel Dunbar821ecd72010-11-27 04:19:38 +0000348 assert(OS.tell() - Start == Is64Bit ? macho::Section64Size :
349 macho::Section32Size);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000350 }
351
352 void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,
353 uint32_t StringTableOffset,
354 uint32_t StringTableSize) {
355 // struct symtab_command (24 bytes)
356
357 uint64_t Start = OS.tell();
358 (void) Start;
359
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000360 Write32(macho::LCT_Symtab);
Daniel Dunbar821ecd72010-11-27 04:19:38 +0000361 Write32(macho::SymtabLoadCommandSize);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000362 Write32(SymbolOffset);
363 Write32(NumSymbols);
364 Write32(StringTableOffset);
365 Write32(StringTableSize);
366
Daniel Dunbar821ecd72010-11-27 04:19:38 +0000367 assert(OS.tell() - Start == macho::SymtabLoadCommandSize);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000368 }
369
370 void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol,
371 uint32_t NumLocalSymbols,
372 uint32_t FirstExternalSymbol,
373 uint32_t NumExternalSymbols,
374 uint32_t FirstUndefinedSymbol,
375 uint32_t NumUndefinedSymbols,
376 uint32_t IndirectSymbolOffset,
377 uint32_t NumIndirectSymbols) {
378 // struct dysymtab_command (80 bytes)
379
380 uint64_t Start = OS.tell();
381 (void) Start;
382
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000383 Write32(macho::LCT_Dysymtab);
Daniel Dunbar821ecd72010-11-27 04:19:38 +0000384 Write32(macho::DysymtabLoadCommandSize);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000385 Write32(FirstLocalSymbol);
386 Write32(NumLocalSymbols);
387 Write32(FirstExternalSymbol);
388 Write32(NumExternalSymbols);
389 Write32(FirstUndefinedSymbol);
390 Write32(NumUndefinedSymbols);
391 Write32(0); // tocoff
392 Write32(0); // ntoc
393 Write32(0); // modtaboff
394 Write32(0); // nmodtab
395 Write32(0); // extrefsymoff
396 Write32(0); // nextrefsyms
397 Write32(IndirectSymbolOffset);
398 Write32(NumIndirectSymbols);
399 Write32(0); // extreloff
400 Write32(0); // nextrel
401 Write32(0); // locreloff
402 Write32(0); // nlocrel
403
Daniel Dunbar821ecd72010-11-27 04:19:38 +0000404 assert(OS.tell() - Start == macho::DysymtabLoadCommandSize);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000405 }
406
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000407 void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout) {
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000408 MCSymbolData &Data = *MSD.SymbolData;
409 const MCSymbol &Symbol = Data.getSymbol();
410 uint8_t Type = 0;
411 uint16_t Flags = Data.getFlags();
412 uint32_t Address = 0;
413
414 // Set the N_TYPE bits. See <mach-o/nlist.h>.
415 //
416 // FIXME: Are the prebound or indirect fields possible here?
417 if (Symbol.isUndefined())
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000418 Type = macho::STT_Undefined;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000419 else if (Symbol.isAbsolute())
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000420 Type = macho::STT_Absolute;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000421 else
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000422 Type = macho::STT_Section;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000423
424 // FIXME: Set STAB bits.
425
426 if (Data.isPrivateExtern())
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000427 Type |= macho::STF_PrivateExtern;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000428
429 // Set external bit.
430 if (Data.isExternal() || Symbol.isUndefined())
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000431 Type |= macho::STF_External;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000432
433 // Compute the symbol address.
434 if (Symbol.isDefined()) {
435 if (Symbol.isAbsolute()) {
Daniel Dunbar2d7fd612010-05-05 19:01:05 +0000436 Address = cast<MCConstantExpr>(Symbol.getVariableValue())->getValue();
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000437 } else {
Rafael Espindola85f2ecc2010-12-07 00:27:36 +0000438 Address = getSymbolAddress(&Data, Layout);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000439 }
440 } else if (Data.isCommon()) {
441 // Common symbols are encoded with the size in the address
442 // field, and their alignment in the flags.
443 Address = Data.getCommonSize();
444
445 // Common alignment is packed into the 'desc' bits.
446 if (unsigned Align = Data.getCommonAlignment()) {
447 unsigned Log2Size = Log2_32(Align);
448 assert((1U << Log2Size) == Align && "Invalid 'common' alignment!");
449 if (Log2Size > 15)
Chris Lattner75361b62010-04-07 22:58:41 +0000450 report_fatal_error("invalid 'common' alignment '" +
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000451 Twine(Align) + "'");
452 // FIXME: Keep this mask with the SymbolFlags enumeration.
453 Flags = (Flags & 0xF0FF) | (Log2Size << 8);
454 }
455 }
456
457 // struct nlist (12 bytes)
458
459 Write32(MSD.StringIndex);
460 Write8(Type);
461 Write8(MSD.SectionIndex);
462
463 // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc'
464 // value.
465 Write16(Flags);
466 if (Is64Bit)
467 Write64(Address);
468 else
469 Write32(Address);
470 }
471
Daniel Dunbar35b06572010-03-22 23:16:43 +0000472 // FIXME: We really need to improve the relocation validation. Basically, we
473 // want to implement a separate computation which evaluates the relocation
474 // entry as the linker would, and verifies that the resultant fixup value is
475 // exactly what the encoder wanted. This will catch several classes of
476 // problems:
477 //
478 // - Relocation entry bugs, the two algorithms are unlikely to have the same
479 // exact bug.
480 //
481 // - Relaxation issues, where we forget to relax something.
482 //
483 // - Input errors, where something cannot be correctly encoded. 'as' allows
484 // these through in many cases.
485
Daniel Dunbar7e06af82010-12-16 15:42:31 +0000486 static bool isFixupKindRIPRel(unsigned Kind) {
487 return Kind == X86::reloc_riprel_4byte ||
488 Kind == X86::reloc_riprel_4byte_movq_load;
489 }
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000490 void RecordX86_64Relocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
Daniel Dunbarb7514182010-03-22 20:35:50 +0000491 const MCFragment *Fragment,
Daniel Dunbarc90e30a2010-05-26 15:18:56 +0000492 const MCFixup &Fixup, MCValue Target,
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000493 uint64_t &FixedValue) {
Daniel Dunbar7e06af82010-12-16 15:42:31 +0000494 unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind());
Daniel Dunbar482ad802010-05-26 15:18:31 +0000495 unsigned IsRIPRel = isFixupKindRIPRel(Fixup.getKind());
496 unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind());
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000497
498 // See <reloc.h>.
Daniel Dunbar482ad802010-05-26 15:18:31 +0000499 uint32_t FixupOffset =
500 Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
501 uint32_t FixupAddress =
Rafael Espindola85f2ecc2010-12-07 00:27:36 +0000502 getFragmentAddress(Fragment, Layout) + Fixup.getOffset();
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000503 int64_t Value = 0;
504 unsigned Index = 0;
505 unsigned IsExtern = 0;
506 unsigned Type = 0;
507
508 Value = Target.getConstant();
509
510 if (IsPCRel) {
511 // Compensate for the relocation offset, Darwin x86_64 relocations only
512 // have the addend and appear to have attempted to define it to be the
513 // actual expression addend without the PCrel bias. However, instructions
514 // with data following the relocation are not accomodated for (see comment
515 // below regarding SIGNED{1,2,4}), so it isn't exactly that either.
Benjamin Kramer454c4ce2010-04-08 15:25:57 +0000516 Value += 1LL << Log2Size;
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000517 }
518
519 if (Target.isAbsolute()) { // constant
520 // SymbolNum of 0 indicates the absolute section.
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000521 Type = macho::RIT_X86_64_Unsigned;
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000522 Index = 0;
523
524 // FIXME: I believe this is broken, I don't think the linker can
525 // understand it. I think it would require a local relocation, but I'm not
526 // sure if that would work either. The official way to get an absolute
527 // PCrel relocation is to use an absolute symbol (which we don't support
528 // yet).
529 if (IsPCRel) {
530 IsExtern = 1;
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000531 Type = macho::RIT_X86_64_Branch;
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000532 }
533 } else if (Target.getSymB()) { // A - B + constant
534 const MCSymbol *A = &Target.getSymA()->getSymbol();
535 MCSymbolData &A_SD = Asm.getSymbolData(*A);
Rafael Espindolab8141102010-09-27 18:13:03 +0000536 const MCSymbolData *A_Base = Asm.getAtom(&A_SD);
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000537
538 const MCSymbol *B = &Target.getSymB()->getSymbol();
539 MCSymbolData &B_SD = Asm.getSymbolData(*B);
Rafael Espindolab8141102010-09-27 18:13:03 +0000540 const MCSymbolData *B_Base = Asm.getAtom(&B_SD);
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000541
542 // Neither symbol can be modified.
543 if (Target.getSymA()->getKind() != MCSymbolRefExpr::VK_None ||
544 Target.getSymB()->getKind() != MCSymbolRefExpr::VK_None)
Chris Lattner75361b62010-04-07 22:58:41 +0000545 report_fatal_error("unsupported relocation of modified symbol");
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000546
547 // We don't support PCrel relocations of differences. Darwin 'as' doesn't
548 // implement most of these correctly.
549 if (IsPCRel)
Chris Lattner75361b62010-04-07 22:58:41 +0000550 report_fatal_error("unsupported pc-relative relocation of difference");
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000551
Kevin Enderby8c9aa922010-10-02 00:13:41 +0000552 // The support for the situation where one or both of the symbols would
553 // require a local relocation is handled just like if the symbols were
554 // external. This is certainly used in the case of debug sections where
555 // the section has only temporary symbols and thus the symbols don't have
556 // base symbols. This is encoded using the section ordinal and
557 // non-extern relocation entries.
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000558
559 // Darwin 'as' doesn't emit correct relocations for this (it ends up with
Kevin Enderby8c9aa922010-10-02 00:13:41 +0000560 // a single SIGNED relocation); reject it for now. Except the case where
561 // both symbols don't have a base, equal but both NULL.
562 if (A_Base == B_Base && A_Base)
Chris Lattner75361b62010-04-07 22:58:41 +0000563 report_fatal_error("unsupported relocation with identical base");
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000564
Rafael Espindolaf10d2be2010-12-07 01:09:54 +0000565 Value += getSymbolAddress(&A_SD, Layout) -
566 (A_Base == NULL ? 0 : getSymbolAddress(A_Base, Layout));
567 Value -= getSymbolAddress(&B_SD, Layout) -
568 (B_Base == NULL ? 0 : getSymbolAddress(B_Base, Layout));
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000569
Kevin Enderby8c9aa922010-10-02 00:13:41 +0000570 if (A_Base) {
571 Index = A_Base->getIndex();
572 IsExtern = 1;
573 }
574 else {
575 Index = A_SD.getFragment()->getParent()->getOrdinal() + 1;
576 IsExtern = 0;
577 }
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000578 Type = macho::RIT_X86_64_Unsigned;
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000579
Daniel Dunbar90e3e3a2010-11-27 13:39:48 +0000580 macho::RelocationEntry MRE;
Daniel Dunbar640e9482010-05-11 23:53:07 +0000581 MRE.Word0 = FixupOffset;
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000582 MRE.Word1 = ((Index << 0) |
583 (IsPCRel << 24) |
584 (Log2Size << 25) |
585 (IsExtern << 27) |
586 (Type << 28));
Daniel Dunbarb7514182010-03-22 20:35:50 +0000587 Relocations[Fragment->getParent()].push_back(MRE);
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000588
Kevin Enderby8c9aa922010-10-02 00:13:41 +0000589 if (B_Base) {
590 Index = B_Base->getIndex();
591 IsExtern = 1;
592 }
593 else {
594 Index = B_SD.getFragment()->getParent()->getOrdinal() + 1;
595 IsExtern = 0;
596 }
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000597 Type = macho::RIT_X86_64_Subtractor;
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000598 } else {
599 const MCSymbol *Symbol = &Target.getSymA()->getSymbol();
600 MCSymbolData &SD = Asm.getSymbolData(*Symbol);
Rafael Espindolab8141102010-09-27 18:13:03 +0000601 const MCSymbolData *Base = Asm.getAtom(&SD);
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000602
Daniel Dunbarae7fb0b2010-05-05 17:22:39 +0000603 // Relocations inside debug sections always use local relocations when
604 // possible. This seems to be done because the debugger doesn't fully
605 // understand x86_64 relocation entries, and expects to find values that
606 // have already been fixed up.
Daniel Dunbar2d7fd612010-05-05 19:01:05 +0000607 if (Symbol->isInSection()) {
Daniel Dunbarae7fb0b2010-05-05 17:22:39 +0000608 const MCSectionMachO &Section = static_cast<const MCSectionMachO&>(
609 Fragment->getParent()->getSection());
610 if (Section.hasAttribute(MCSectionMachO::S_ATTR_DEBUG))
611 Base = 0;
612 }
613
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000614 // x86_64 almost always uses external relocations, except when there is no
615 // symbol to use as a base address (a local symbol with no preceeding
616 // non-local symbol).
617 if (Base) {
618 Index = Base->getIndex();
619 IsExtern = 1;
620
621 // Add the local offset, if needed.
622 if (Base != &SD)
Rafael Espindola1dda29b2010-12-06 21:51:55 +0000623 Value += Layout.getSymbolOffset(&SD) - Layout.getSymbolOffset(Base);
Daniel Dunbaref4591e2010-05-11 23:53:05 +0000624 } else if (Symbol->isInSection()) {
Daniel Dunbar8fb04032010-03-25 08:08:54 +0000625 // The index is the section ordinal (1-based).
626 Index = SD.getFragment()->getParent()->getOrdinal() + 1;
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000627 IsExtern = 0;
Rafael Espindola85f2ecc2010-12-07 00:27:36 +0000628 Value += getSymbolAddress(&SD, Layout);
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000629
630 if (IsPCRel)
Daniel Dunbardb4c7e62010-05-11 23:53:11 +0000631 Value -= FixupAddress + (1 << Log2Size);
Rafael Espindola85f2ecc2010-12-07 00:27:36 +0000632 } else if (Symbol->isVariable()) {
633 const MCExpr *Value = Symbol->getVariableValue();
634 int64_t Res;
635 bool isAbs = Value->EvaluateAsAbsolute(Res, Layout, SectionAddress);
636 if (isAbs) {
637 FixedValue = Res;
638 return;
639 } else {
640 report_fatal_error("unsupported relocation of variable '" +
641 Symbol->getName() + "'");
642 }
Daniel Dunbaref4591e2010-05-11 23:53:05 +0000643 } else {
644 report_fatal_error("unsupported relocation of undefined symbol '" +
645 Symbol->getName() + "'");
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000646 }
647
648 MCSymbolRefExpr::VariantKind Modifier = Target.getSymA()->getKind();
649 if (IsPCRel) {
650 if (IsRIPRel) {
651 if (Modifier == MCSymbolRefExpr::VK_GOTPCREL) {
652 // x86_64 distinguishes movq foo@GOTPCREL so that the linker can
653 // rewrite the movq to an leaq at link time if the symbol ends up in
654 // the same linkage unit.
Daniel Dunbar482ad802010-05-26 15:18:31 +0000655 if (unsigned(Fixup.getKind()) == X86::reloc_riprel_4byte_movq_load)
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000656 Type = macho::RIT_X86_64_GOTLoad;
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000657 else
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000658 Type = macho::RIT_X86_64_GOT;
Eric Christopheraeed4d82010-05-27 00:52:31 +0000659 } else if (Modifier == MCSymbolRefExpr::VK_TLVP) {
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000660 Type = macho::RIT_X86_64_TLV;
Eric Christopheraeed4d82010-05-27 00:52:31 +0000661 } else if (Modifier != MCSymbolRefExpr::VK_None) {
662 report_fatal_error("unsupported symbol modifier in relocation");
Daniel Dunbarf0f6cdb2010-05-14 18:53:40 +0000663 } else {
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000664 Type = macho::RIT_X86_64_Signed;
Daniel Dunbarf0f6cdb2010-05-14 18:53:40 +0000665
666 // The Darwin x86_64 relocation format has a problem where it cannot
667 // encode an address (L<foo> + <constant>) which is outside the atom
668 // containing L<foo>. Generally, this shouldn't occur but it does
669 // happen when we have a RIPrel instruction with data following the
670 // relocation entry (e.g., movb $012, L0(%rip)). Even with the PCrel
671 // adjustment Darwin x86_64 uses, the offset is still negative and
672 // the linker has no way to recognize this.
673 //
674 // To work around this, Darwin uses several special relocation types
675 // to indicate the offsets. However, the specification or
676 // implementation of these seems to also be incomplete; they should
677 // adjust the addend as well based on the actual encoded instruction
678 // (the additional bias), but instead appear to just look at the
679 // final offset.
680 switch (-(Target.getConstant() + (1LL << Log2Size))) {
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000681 case 1: Type = macho::RIT_X86_64_Signed1; break;
682 case 2: Type = macho::RIT_X86_64_Signed2; break;
683 case 4: Type = macho::RIT_X86_64_Signed4; break;
Daniel Dunbarf0f6cdb2010-05-14 18:53:40 +0000684 }
685 }
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000686 } else {
687 if (Modifier != MCSymbolRefExpr::VK_None)
Chris Lattner75361b62010-04-07 22:58:41 +0000688 report_fatal_error("unsupported symbol modifier in branch "
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000689 "relocation");
690
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000691 Type = macho::RIT_X86_64_Branch;
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000692 }
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000693 } else {
Daniel Dunbar1de558b2010-03-29 23:56:40 +0000694 if (Modifier == MCSymbolRefExpr::VK_GOT) {
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000695 Type = macho::RIT_X86_64_GOT;
Daniel Dunbar1de558b2010-03-29 23:56:40 +0000696 } else if (Modifier == MCSymbolRefExpr::VK_GOTPCREL) {
697 // GOTPCREL is allowed as a modifier on non-PCrel instructions, in
698 // which case all we do is set the PCrel bit in the relocation entry;
699 // this is used with exception handling, for example. The source is
700 // required to include any necessary offset directly.
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000701 Type = macho::RIT_X86_64_GOT;
Daniel Dunbar1de558b2010-03-29 23:56:40 +0000702 IsPCRel = 1;
Eric Christopher96ac5152010-05-26 00:02:12 +0000703 } else if (Modifier == MCSymbolRefExpr::VK_TLVP) {
704 report_fatal_error("TLVP symbol modifier should have been rip-rel");
Daniel Dunbar1de558b2010-03-29 23:56:40 +0000705 } else if (Modifier != MCSymbolRefExpr::VK_None)
Chris Lattner75361b62010-04-07 22:58:41 +0000706 report_fatal_error("unsupported symbol modifier in relocation");
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000707 else
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000708 Type = macho::RIT_X86_64_Unsigned;
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000709 }
710 }
711
712 // x86_64 always writes custom values into the fixups.
713 FixedValue = Value;
714
715 // struct relocation_info (8 bytes)
Daniel Dunbar90e3e3a2010-11-27 13:39:48 +0000716 macho::RelocationEntry MRE;
Daniel Dunbar640e9482010-05-11 23:53:07 +0000717 MRE.Word0 = FixupOffset;
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000718 MRE.Word1 = ((Index << 0) |
719 (IsPCRel << 24) |
720 (Log2Size << 25) |
721 (IsExtern << 27) |
722 (Type << 28));
Daniel Dunbarb7514182010-03-22 20:35:50 +0000723 Relocations[Fragment->getParent()].push_back(MRE);
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000724 }
725
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000726 void RecordScatteredRelocation(const MCAssembler &Asm,
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000727 const MCAsmLayout &Layout,
Daniel Dunbarb7514182010-03-22 20:35:50 +0000728 const MCFragment *Fragment,
Daniel Dunbarc90e30a2010-05-26 15:18:56 +0000729 const MCFixup &Fixup, MCValue Target,
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000730 uint64_t &FixedValue) {
Daniel Dunbar482ad802010-05-26 15:18:31 +0000731 uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
Daniel Dunbar7e06af82010-12-16 15:42:31 +0000732 unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind());
Daniel Dunbar482ad802010-05-26 15:18:31 +0000733 unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind());
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000734 unsigned Type = macho::RIT_Vanilla;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000735
736 // See <reloc.h>.
737 const MCSymbol *A = &Target.getSymA()->getSymbol();
738 MCSymbolData *A_SD = &Asm.getSymbolData(*A);
739
740 if (!A_SD->getFragment())
Chris Lattner75361b62010-04-07 22:58:41 +0000741 report_fatal_error("symbol '" + A->getName() +
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000742 "' can not be undefined in a subtraction expression");
743
Rafael Espindola85f2ecc2010-12-07 00:27:36 +0000744 uint32_t Value = getSymbolAddress(A_SD, Layout);
745 uint64_t SecAddr = getSectionAddress(A_SD->getFragment()->getParent());
746 FixedValue += SecAddr;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000747 uint32_t Value2 = 0;
748
749 if (const MCSymbolRefExpr *B = Target.getSymB()) {
750 MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol());
751
752 if (!B_SD->getFragment())
Chris Lattner75361b62010-04-07 22:58:41 +0000753 report_fatal_error("symbol '" + B->getSymbol().getName() +
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000754 "' can not be undefined in a subtraction expression");
755
756 // Select the appropriate difference relocation type.
757 //
758 // Note that there is no longer any semantic difference between these two
759 // relocation types from the linkers point of view, this is done solely
760 // for pedantic compatibility with 'as'.
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000761 Type = A_SD->isExternal() ? macho::RIT_Difference :
762 macho::RIT_LocalDifference;
Rafael Espindola85f2ecc2010-12-07 00:27:36 +0000763 Value2 = getSymbolAddress(B_SD, Layout);
764 FixedValue -= getSectionAddress(B_SD->getFragment()->getParent());
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000765 }
766
767 // Relocations are written out in reverse order, so the PAIR comes first.
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000768 if (Type == macho::RIT_Difference || Type == macho::RIT_LocalDifference) {
Daniel Dunbar90e3e3a2010-11-27 13:39:48 +0000769 macho::RelocationEntry MRE;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000770 MRE.Word0 = ((0 << 0) |
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000771 (macho::RIT_Pair << 24) |
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000772 (Log2Size << 28) |
773 (IsPCRel << 30) |
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000774 macho::RF_Scattered);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000775 MRE.Word1 = Value2;
Daniel Dunbarb7514182010-03-22 20:35:50 +0000776 Relocations[Fragment->getParent()].push_back(MRE);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000777 }
778
Daniel Dunbar90e3e3a2010-11-27 13:39:48 +0000779 macho::RelocationEntry MRE;
Daniel Dunbar640e9482010-05-11 23:53:07 +0000780 MRE.Word0 = ((FixupOffset << 0) |
781 (Type << 24) |
782 (Log2Size << 28) |
783 (IsPCRel << 30) |
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000784 macho::RF_Scattered);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000785 MRE.Word1 = Value;
Daniel Dunbarb7514182010-03-22 20:35:50 +0000786 Relocations[Fragment->getParent()].push_back(MRE);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000787 }
788
Eric Christopherc9ada472010-06-15 22:59:05 +0000789 void RecordTLVPRelocation(const MCAssembler &Asm,
Eric Christophere48dbf82010-06-16 00:26:36 +0000790 const MCAsmLayout &Layout,
791 const MCFragment *Fragment,
792 const MCFixup &Fixup, MCValue Target,
793 uint64_t &FixedValue) {
Eric Christopherc9ada472010-06-15 22:59:05 +0000794 assert(Target.getSymA()->getKind() == MCSymbolRefExpr::VK_TLVP &&
795 !Is64Bit &&
796 "Should only be called with a 32-bit TLVP relocation!");
797
Eric Christopherc9ada472010-06-15 22:59:05 +0000798 unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind());
799 uint32_t Value = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
800 unsigned IsPCRel = 0;
801
802 // Get the symbol data.
803 MCSymbolData *SD_A = &Asm.getSymbolData(Target.getSymA()->getSymbol());
804 unsigned Index = SD_A->getIndex();
805
Eric Christopherbc067372010-06-16 21:32:38 +0000806 // We're only going to have a second symbol in pic mode and it'll be a
807 // subtraction from the picbase. For 32-bit pic the addend is the difference
Eric Christopher04b8d3c2010-06-17 00:49:46 +0000808 // between the picbase and the next address. For 32-bit static the addend
809 // is zero.
Eric Christopherbc067372010-06-16 21:32:38 +0000810 if (Target.getSymB()) {
Eric Christopher1008d352010-06-22 23:51:47 +0000811 // If this is a subtraction then we're pcrel.
812 uint32_t FixupAddress =
Rafael Espindola85f2ecc2010-12-07 00:27:36 +0000813 getFragmentAddress(Fragment, Layout) + Fixup.getOffset();
Eric Christopher1008d352010-06-22 23:51:47 +0000814 MCSymbolData *SD_B = &Asm.getSymbolData(Target.getSymB()->getSymbol());
Eric Christopherc9ada472010-06-15 22:59:05 +0000815 IsPCRel = 1;
Rafael Espindola85f2ecc2010-12-07 00:27:36 +0000816 FixedValue = (FixupAddress - getSymbolAddress(SD_B, Layout) +
Eric Christopher1008d352010-06-22 23:51:47 +0000817 Target.getConstant());
Chris Lattnerabf8f9c2010-08-16 16:35:20 +0000818 FixedValue += 1ULL << Log2Size;
Eric Christopherbc067372010-06-16 21:32:38 +0000819 } else {
820 FixedValue = 0;
821 }
Jim Grosbach3c384922010-11-11 20:16:23 +0000822
Eric Christopherc9ada472010-06-15 22:59:05 +0000823 // struct relocation_info (8 bytes)
Daniel Dunbar90e3e3a2010-11-27 13:39:48 +0000824 macho::RelocationEntry MRE;
Eric Christopherc9ada472010-06-15 22:59:05 +0000825 MRE.Word0 = Value;
826 MRE.Word1 = ((Index << 0) |
827 (IsPCRel << 24) |
828 (Log2Size << 25) |
829 (1 << 27) | // Extern
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000830 (macho::RIT_TLV << 28)); // Type
Eric Christopherc9ada472010-06-15 22:59:05 +0000831 Relocations[Fragment->getParent()].push_back(MRE);
832 }
Jim Grosbach3c384922010-11-11 20:16:23 +0000833
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000834 void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
Daniel Dunbarc90e30a2010-05-26 15:18:56 +0000835 const MCFragment *Fragment, const MCFixup &Fixup,
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000836 MCValue Target, uint64_t &FixedValue) {
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000837 if (Is64Bit) {
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000838 RecordX86_64Relocation(Asm, Layout, Fragment, Fixup, Target, FixedValue);
Daniel Dunbar602b40f2010-03-19 18:07:55 +0000839 return;
840 }
841
Daniel Dunbar7e06af82010-12-16 15:42:31 +0000842 unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind());
Daniel Dunbar482ad802010-05-26 15:18:31 +0000843 unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind());
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000844
Eric Christopherc9ada472010-06-15 22:59:05 +0000845 // If this is a 32-bit TLVP reloc it's handled a bit differently.
Daniel Dunbar23bea412010-09-17 15:21:50 +0000846 if (Target.getSymA() &&
847 Target.getSymA()->getKind() == MCSymbolRefExpr::VK_TLVP) {
Eric Christopherc9ada472010-06-15 22:59:05 +0000848 RecordTLVPRelocation(Asm, Layout, Fragment, Fixup, Target, FixedValue);
849 return;
850 }
Jim Grosbach3c384922010-11-11 20:16:23 +0000851
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000852 // If this is a difference or a defined symbol plus an offset, then we need
853 // a scattered relocation entry.
Daniel Dunbara8251fa2010-05-10 23:15:20 +0000854 // Differences always require scattered relocations.
855 if (Target.getSymB())
856 return RecordScatteredRelocation(Asm, Layout, Fragment, Fixup,
857 Target, FixedValue);
858
859 // Get the symbol data, if any.
860 MCSymbolData *SD = 0;
861 if (Target.getSymA())
862 SD = &Asm.getSymbolData(Target.getSymA()->getSymbol());
863
864 // If this is an internal relocation with an offset, it also needs a
865 // scattered relocation entry.
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000866 uint32_t Offset = Target.getConstant();
867 if (IsPCRel)
868 Offset += 1 << Log2Size;
Daniel Dunbara8251fa2010-05-10 23:15:20 +0000869 if (Offset && SD && !doesSymbolRequireExternRelocation(SD))
870 return RecordScatteredRelocation(Asm, Layout, Fragment, Fixup,
871 Target, FixedValue);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000872
873 // See <reloc.h>.
Daniel Dunbar482ad802010-05-26 15:18:31 +0000874 uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000875 unsigned Index = 0;
876 unsigned IsExtern = 0;
877 unsigned Type = 0;
878
879 if (Target.isAbsolute()) { // constant
880 // SymbolNum of 0 indicates the absolute section.
881 //
882 // FIXME: Currently, these are never generated (see code below). I cannot
883 // find a case where they are actually emitted.
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000884 Type = macho::RIT_Vanilla;
Rafael Espindola545b77e2010-12-07 17:12:32 +0000885 } else if (SD->getSymbol().isVariable()) {
886 const MCExpr *Value = SD->getSymbol().getVariableValue();
887 int64_t Res;
888 bool isAbs = Value->EvaluateAsAbsolute(Res, Layout, SectionAddress);
889 if (isAbs) {
890 FixedValue = Res;
891 return;
892 } else {
893 report_fatal_error("unsupported relocation of variable '" +
894 SD->getSymbol().getName() + "'");
895 }
Michael J. Spencerb0f3b3e2010-08-10 16:00:49 +0000896 } else {
Daniel Dunbare9460ec2010-05-10 23:15:13 +0000897 // Check whether we need an external or internal relocation.
898 if (doesSymbolRequireExternRelocation(SD)) {
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000899 IsExtern = 1;
900 Index = SD->getIndex();
Daniel Dunbare9460ec2010-05-10 23:15:13 +0000901 // For external relocations, make sure to offset the fixup value to
902 // compensate for the addend of the symbol address, if it was
903 // undefined. This occurs with weak definitions, for example.
904 if (!SD->Symbol->isUndefined())
Rafael Espindola3b3148f2010-12-07 05:57:28 +0000905 FixedValue -= Layout.getSymbolOffset(SD);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000906 } else {
Daniel Dunbar8fb04032010-03-25 08:08:54 +0000907 // The index is the section ordinal (1-based).
908 Index = SD->getFragment()->getParent()->getOrdinal() + 1;
Rafael Espindola85f2ecc2010-12-07 00:27:36 +0000909 FixedValue += getSectionAddress(SD->getFragment()->getParent());
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000910 }
Rafael Espindolabf60dad2010-12-07 03:50:14 +0000911 if (IsPCRel)
912 FixedValue -= getSectionAddress(Fragment->getParent());
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000913
Daniel Dunbarf52788f2010-11-27 04:59:14 +0000914 Type = macho::RIT_Vanilla;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000915 }
916
917 // struct relocation_info (8 bytes)
Daniel Dunbar90e3e3a2010-11-27 13:39:48 +0000918 macho::RelocationEntry MRE;
Daniel Dunbar640e9482010-05-11 23:53:07 +0000919 MRE.Word0 = FixupOffset;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000920 MRE.Word1 = ((Index << 0) |
921 (IsPCRel << 24) |
922 (Log2Size << 25) |
923 (IsExtern << 27) |
924 (Type << 28));
Daniel Dunbarb7514182010-03-22 20:35:50 +0000925 Relocations[Fragment->getParent()].push_back(MRE);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000926 }
927
928 void BindIndirectSymbols(MCAssembler &Asm) {
929 // This is the point where 'as' creates actual symbols for indirect symbols
930 // (in the following two passes). It would be easier for us to do this
931 // sooner when we see the attribute, but that makes getting the order in the
932 // symbol table much more complicated than it is worth.
933 //
934 // FIXME: Revisit this when the dust settles.
935
936 // Bind non lazy symbol pointers first.
Daniel Dunbar2ae4bfd2010-05-18 17:28:24 +0000937 unsigned IndirectIndex = 0;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000938 for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
Daniel Dunbar2ae4bfd2010-05-18 17:28:24 +0000939 ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) {
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000940 const MCSectionMachO &Section =
Daniel Dunbar56279f42010-05-18 17:28:20 +0000941 cast<MCSectionMachO>(it->SectionData->getSection());
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000942
943 if (Section.getType() != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS)
944 continue;
945
Daniel Dunbar2ae4bfd2010-05-18 17:28:24 +0000946 // Initialize the section indirect symbol base, if necessary.
947 if (!IndirectSymBase.count(it->SectionData))
948 IndirectSymBase[it->SectionData] = IndirectIndex;
Jim Grosbach3c384922010-11-11 20:16:23 +0000949
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000950 Asm.getOrCreateSymbolData(*it->Symbol);
951 }
952
953 // Then lazy symbol pointers and symbol stubs.
Daniel Dunbar2ae4bfd2010-05-18 17:28:24 +0000954 IndirectIndex = 0;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000955 for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(),
Daniel Dunbar2ae4bfd2010-05-18 17:28:24 +0000956 ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) {
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000957 const MCSectionMachO &Section =
Daniel Dunbar56279f42010-05-18 17:28:20 +0000958 cast<MCSectionMachO>(it->SectionData->getSection());
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000959
960 if (Section.getType() != MCSectionMachO::S_LAZY_SYMBOL_POINTERS &&
961 Section.getType() != MCSectionMachO::S_SYMBOL_STUBS)
962 continue;
963
Daniel Dunbar2ae4bfd2010-05-18 17:28:24 +0000964 // Initialize the section indirect symbol base, if necessary.
965 if (!IndirectSymBase.count(it->SectionData))
966 IndirectSymBase[it->SectionData] = IndirectIndex;
967
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +0000968 // Set the symbol type to undefined lazy, but only on construction.
969 //
970 // FIXME: Do not hardcode.
971 bool Created;
972 MCSymbolData &Entry = Asm.getOrCreateSymbolData(*it->Symbol, &Created);
973 if (Created)
974 Entry.setFlags(Entry.getFlags() | 0x0001);
975 }
976 }
977
978 /// ComputeSymbolTable - Compute the symbol table data
979 ///
980 /// \param StringTable [out] - The string table data.
981 /// \param StringIndexMap [out] - Map from symbol names to offsets in the
982 /// string table.
983 void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
984 std::vector<MachSymbolData> &LocalSymbolData,
985 std::vector<MachSymbolData> &ExternalSymbolData,
986 std::vector<MachSymbolData> &UndefinedSymbolData) {
987 // Build section lookup table.
988 DenseMap<const MCSection*, uint8_t> SectionIndexMap;
989 unsigned Index = 1;
990 for (MCAssembler::iterator it = Asm.begin(),
991 ie = Asm.end(); it != ie; ++it, ++Index)
992 SectionIndexMap[&it->getSection()] = Index;
993 assert(Index <= 256 && "Too many sections!");
994
995 // Index 0 is always the empty string.
996 StringMap<uint64_t> StringIndexMap;
997 StringTable += '\x00';
998
999 // Build the symbol arrays and the string table, but only for non-local
1000 // symbols.
1001 //
1002 // The particular order that we collect the symbols and create the string
1003 // table, then sort the symbols is chosen to match 'as'. Even though it
1004 // doesn't matter for correctness, this is important for letting us diff .o
1005 // files.
1006 for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
1007 ie = Asm.symbol_end(); it != ie; ++it) {
1008 const MCSymbol &Symbol = it->getSymbol();
1009
1010 // Ignore non-linker visible symbols.
Daniel Dunbar843aa1f2010-06-16 20:04:29 +00001011 if (!Asm.isSymbolLinkerVisible(it->getSymbol()))
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001012 continue;
1013
1014 if (!it->isExternal() && !Symbol.isUndefined())
1015 continue;
1016
1017 uint64_t &Entry = StringIndexMap[Symbol.getName()];
1018 if (!Entry) {
1019 Entry = StringTable.size();
1020 StringTable += Symbol.getName();
1021 StringTable += '\x00';
1022 }
1023
1024 MachSymbolData MSD;
1025 MSD.SymbolData = it;
1026 MSD.StringIndex = Entry;
1027
1028 if (Symbol.isUndefined()) {
1029 MSD.SectionIndex = 0;
1030 UndefinedSymbolData.push_back(MSD);
1031 } else if (Symbol.isAbsolute()) {
1032 MSD.SectionIndex = 0;
1033 ExternalSymbolData.push_back(MSD);
1034 } else {
1035 MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection());
1036 assert(MSD.SectionIndex && "Invalid section index!");
1037 ExternalSymbolData.push_back(MSD);
1038 }
1039 }
1040
1041 // Now add the data for local symbols.
1042 for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
1043 ie = Asm.symbol_end(); it != ie; ++it) {
1044 const MCSymbol &Symbol = it->getSymbol();
1045
1046 // Ignore non-linker visible symbols.
Daniel Dunbar843aa1f2010-06-16 20:04:29 +00001047 if (!Asm.isSymbolLinkerVisible(it->getSymbol()))
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001048 continue;
1049
1050 if (it->isExternal() || Symbol.isUndefined())
1051 continue;
1052
1053 uint64_t &Entry = StringIndexMap[Symbol.getName()];
1054 if (!Entry) {
1055 Entry = StringTable.size();
1056 StringTable += Symbol.getName();
1057 StringTable += '\x00';
1058 }
1059
1060 MachSymbolData MSD;
1061 MSD.SymbolData = it;
1062 MSD.StringIndex = Entry;
1063
1064 if (Symbol.isAbsolute()) {
1065 MSD.SectionIndex = 0;
1066 LocalSymbolData.push_back(MSD);
1067 } else {
1068 MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection());
1069 assert(MSD.SectionIndex && "Invalid section index!");
1070 LocalSymbolData.push_back(MSD);
1071 }
1072 }
1073
1074 // External and undefined symbols are required to be in lexicographic order.
1075 std::sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
1076 std::sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end());
1077
1078 // Set the symbol indices.
1079 Index = 0;
1080 for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
1081 LocalSymbolData[i].SymbolData->setIndex(Index++);
1082 for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
1083 ExternalSymbolData[i].SymbolData->setIndex(Index++);
1084 for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
1085 UndefinedSymbolData[i].SymbolData->setIndex(Index++);
1086
1087 // The string table is padded to a multiple of 4.
1088 while (StringTable.size() % 4)
1089 StringTable += '\x00';
1090 }
1091
Rafael Espindola85f2ecc2010-12-07 00:27:36 +00001092 void computeSectionAddresses(const MCAssembler &Asm,
1093 const MCAsmLayout &Layout) {
1094 uint64_t StartAddress = 0;
1095 const SmallVectorImpl<MCSectionData*> &Order = Layout.getSectionOrder();
1096 for (int i = 0, n = Order.size(); i != n ; ++i) {
1097 const MCSectionData *SD = Order[i];
1098 StartAddress = RoundUpToAlignment(StartAddress, SD->getAlignment());
1099 SectionAddress[SD] = StartAddress;
1100 StartAddress += Layout.getSectionAddressSize(SD);
1101 // Explicitly pad the section to match the alignment requirements of the
1102 // following one. This is for 'gas' compatibility, it shouldn't
1103 /// strictly be necessary.
1104 StartAddress += getPaddingSize(SD, Layout);
1105 }
1106 }
1107
1108 void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) {
1109 computeSectionAddresses(Asm, Layout);
1110
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001111 // Create symbol data for any indirect symbols.
1112 BindIndirectSymbols(Asm);
1113
1114 // Compute symbol table information and bind symbol indices.
1115 ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData,
1116 UndefinedSymbolData);
1117 }
1118
Rafael Espindola70703872010-09-30 02:22:20 +00001119
1120 bool IsFixupFullyResolved(const MCAssembler &Asm,
1121 const MCValue Target,
1122 bool IsPCRel,
1123 const MCFragment *DF) const {
Daniel Dunbar7976b882010-11-27 05:18:48 +00001124 // If we aren't using scattered symbols, the fixup is fully resolved.
1125 if (!Asm.getBackend().hasScatteredSymbols())
1126 return true;
Rafael Espindola70703872010-09-30 02:22:20 +00001127
Daniel Dunbar7976b882010-11-27 05:18:48 +00001128 // Otherwise, determine whether this value is actually resolved; scattering
1129 // may cause atoms to move.
Rafael Espindola70703872010-09-30 02:22:20 +00001130
Daniel Dunbar7976b882010-11-27 05:18:48 +00001131 // Check if we are using the "simple" resolution algorithm (e.g.,
1132 // i386).
1133 if (!Asm.getBackend().hasReliableSymbolDifference()) {
1134 const MCSection *BaseSection = 0;
1135 if (IsPCRel)
1136 BaseSection = &DF->getParent()->getSection();
1137
1138 return isScatteredFixupFullyResolvedSimple(Asm, Target, BaseSection);
Rafael Espindola70703872010-09-30 02:22:20 +00001139 }
Daniel Dunbar7976b882010-11-27 05:18:48 +00001140
1141 // Otherwise, compute the proper answer as reliably as possible.
1142
1143 // If this is a PCrel relocation, find the base atom (identified by its
1144 // symbol) that the fixup value is relative to.
1145 const MCSymbolData *BaseSymbol = 0;
1146 if (IsPCRel) {
1147 BaseSymbol = DF->getAtom();
1148 if (!BaseSymbol)
1149 return false;
1150 }
1151
1152 return isScatteredFixupFullyResolved(Asm, Target, BaseSymbol);
Rafael Espindola70703872010-09-30 02:22:20 +00001153 }
1154
Daniel Dunbar115a3dd2010-11-13 07:33:40 +00001155 void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001156 unsigned NumSections = Asm.size();
1157
1158 // The section data starts after the header, the segment load command (and
1159 // section headers) and the symbol table.
1160 unsigned NumLoadCommands = 1;
1161 uint64_t LoadCommandsSize = Is64Bit ?
Daniel Dunbar821ecd72010-11-27 04:19:38 +00001162 macho::SegmentLoadCommand64Size + NumSections * macho::Section64Size :
1163 macho::SegmentLoadCommand32Size + NumSections * macho::Section32Size;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001164
1165 // Add the symbol table load command sizes, if used.
1166 unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +
1167 UndefinedSymbolData.size();
1168 if (NumSymbols) {
1169 NumLoadCommands += 2;
Daniel Dunbar821ecd72010-11-27 04:19:38 +00001170 LoadCommandsSize += (macho::SymtabLoadCommandSize +
1171 macho::DysymtabLoadCommandSize);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001172 }
1173
1174 // Compute the total size of the section data, as well as its file size and
1175 // vm size.
Daniel Dunbar821ecd72010-11-27 04:19:38 +00001176 uint64_t SectionDataStart = (Is64Bit ? macho::Header64Size :
1177 macho::Header32Size) + LoadCommandsSize;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001178 uint64_t SectionDataSize = 0;
1179 uint64_t SectionDataFileSize = 0;
1180 uint64_t VMSize = 0;
1181 for (MCAssembler::const_iterator it = Asm.begin(),
1182 ie = Asm.end(); it != ie; ++it) {
1183 const MCSectionData &SD = *it;
Rafael Espindola85f2ecc2010-12-07 00:27:36 +00001184 uint64_t Address = getSectionAddress(&SD);
1185 uint64_t Size = Layout.getSectionAddressSize(&SD);
Daniel Dunbar5d428512010-03-25 02:00:07 +00001186 uint64_t FileSize = Layout.getSectionFileSize(&SD);
Rafael Espindola85f2ecc2010-12-07 00:27:36 +00001187 FileSize += getPaddingSize(&SD, Layout);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001188
Daniel Dunbar5d428512010-03-25 02:00:07 +00001189 VMSize = std::max(VMSize, Address + Size);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001190
Rafael Espindolaf2dc4aa2010-11-17 20:03:54 +00001191 if (SD.getSection().isVirtualSection())
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001192 continue;
1193
Daniel Dunbar5d428512010-03-25 02:00:07 +00001194 SectionDataSize = std::max(SectionDataSize, Address + Size);
1195 SectionDataFileSize = std::max(SectionDataFileSize, Address + FileSize);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001196 }
1197
1198 // The section data is padded to 4 bytes.
1199 //
1200 // FIXME: Is this machine dependent?
1201 unsigned SectionDataPadding = OffsetToAlignment(SectionDataFileSize, 4);
1202 SectionDataFileSize += SectionDataPadding;
1203
1204 // Write the prolog, starting with the header and load command...
1205 WriteHeader(NumLoadCommands, LoadCommandsSize,
1206 Asm.getSubsectionsViaSymbols());
1207 WriteSegmentLoadCommand(NumSections, VMSize,
1208 SectionDataStart, SectionDataSize);
1209
1210 // ... and then the section headers.
1211 uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
1212 for (MCAssembler::const_iterator it = Asm.begin(),
1213 ie = Asm.end(); it != ie; ++it) {
Daniel Dunbar90e3e3a2010-11-27 13:39:48 +00001214 std::vector<macho::RelocationEntry> &Relocs = Relocations[it];
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001215 unsigned NumRelocs = Relocs.size();
Rafael Espindola85f2ecc2010-12-07 00:27:36 +00001216 uint64_t SectionStart = SectionDataStart + getSectionAddress(it);
Daniel Dunbar207e06e2010-03-24 03:43:40 +00001217 WriteSection(Asm, Layout, *it, SectionStart, RelocTableEnd, NumRelocs);
Daniel Dunbar821ecd72010-11-27 04:19:38 +00001218 RelocTableEnd += NumRelocs * macho::RelocationInfoSize;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001219 }
1220
1221 // Write the symbol table load command, if used.
1222 if (NumSymbols) {
1223 unsigned FirstLocalSymbol = 0;
1224 unsigned NumLocalSymbols = LocalSymbolData.size();
1225 unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols;
1226 unsigned NumExternalSymbols = ExternalSymbolData.size();
1227 unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols;
1228 unsigned NumUndefinedSymbols = UndefinedSymbolData.size();
1229 unsigned NumIndirectSymbols = Asm.indirect_symbol_size();
1230 unsigned NumSymTabSymbols =
1231 NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols;
1232 uint64_t IndirectSymbolSize = NumIndirectSymbols * 4;
1233 uint64_t IndirectSymbolOffset = 0;
1234
1235 // If used, the indirect symbols are written after the section data.
1236 if (NumIndirectSymbols)
1237 IndirectSymbolOffset = RelocTableEnd;
1238
1239 // The symbol table is written after the indirect symbol data.
1240 uint64_t SymbolTableOffset = RelocTableEnd + IndirectSymbolSize;
1241
1242 // The string table is written after symbol table.
1243 uint64_t StringTableOffset =
Daniel Dunbar821ecd72010-11-27 04:19:38 +00001244 SymbolTableOffset + NumSymTabSymbols * (Is64Bit ? macho::Nlist64Size :
1245 macho::Nlist32Size);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001246 WriteSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols,
1247 StringTableOffset, StringTable.size());
1248
1249 WriteDysymtabLoadCommand(FirstLocalSymbol, NumLocalSymbols,
1250 FirstExternalSymbol, NumExternalSymbols,
1251 FirstUndefinedSymbol, NumUndefinedSymbols,
1252 IndirectSymbolOffset, NumIndirectSymbols);
1253 }
1254
1255 // Write the actual section data.
1256 for (MCAssembler::const_iterator it = Asm.begin(),
Rafael Espindola85f2ecc2010-12-07 00:27:36 +00001257 ie = Asm.end(); it != ie; ++it) {
Daniel Dunbar115a3dd2010-11-13 07:33:40 +00001258 Asm.WriteSectionData(it, Layout, this);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001259
Rafael Espindola85f2ecc2010-12-07 00:27:36 +00001260 uint64_t Pad = getPaddingSize(it, Layout);
1261 for (unsigned int i = 0; i < Pad; ++i)
1262 Write8(0);
1263 }
1264
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001265 // Write the extra padding.
1266 WriteZeros(SectionDataPadding);
1267
1268 // Write the relocation entries.
1269 for (MCAssembler::const_iterator it = Asm.begin(),
1270 ie = Asm.end(); it != ie; ++it) {
1271 // Write the section relocation entries, in reverse order to match 'as'
1272 // (approximately, the exact algorithm is more complicated than this).
Daniel Dunbar90e3e3a2010-11-27 13:39:48 +00001273 std::vector<macho::RelocationEntry> &Relocs = Relocations[it];
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001274 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
1275 Write32(Relocs[e - i - 1].Word0);
1276 Write32(Relocs[e - i - 1].Word1);
1277 }
1278 }
1279
1280 // Write the symbol table data, if used.
1281 if (NumSymbols) {
1282 // Write the indirect symbol entries.
1283 for (MCAssembler::const_indirect_symbol_iterator
1284 it = Asm.indirect_symbol_begin(),
1285 ie = Asm.indirect_symbol_end(); it != ie; ++it) {
1286 // Indirect symbols in the non lazy symbol pointer section have some
1287 // special handling.
1288 const MCSectionMachO &Section =
1289 static_cast<const MCSectionMachO&>(it->SectionData->getSection());
1290 if (Section.getType() == MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS) {
1291 // If this symbol is defined and internal, mark it as such.
1292 if (it->Symbol->isDefined() &&
1293 !Asm.getSymbolData(*it->Symbol).isExternal()) {
Daniel Dunbarf52788f2010-11-27 04:59:14 +00001294 uint32_t Flags = macho::ISF_Local;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001295 if (it->Symbol->isAbsolute())
Daniel Dunbarf52788f2010-11-27 04:59:14 +00001296 Flags |= macho::ISF_Absolute;
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001297 Write32(Flags);
1298 continue;
1299 }
1300 }
1301
1302 Write32(Asm.getSymbolData(*it->Symbol).getIndex());
1303 }
1304
1305 // FIXME: Check that offsets match computed ones.
1306
1307 // Write the symbol table entries.
1308 for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
Daniel Dunbar207e06e2010-03-24 03:43:40 +00001309 WriteNlist(LocalSymbolData[i], Layout);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001310 for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
Daniel Dunbar207e06e2010-03-24 03:43:40 +00001311 WriteNlist(ExternalSymbolData[i], Layout);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001312 for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
Daniel Dunbar207e06e2010-03-24 03:43:40 +00001313 WriteNlist(UndefinedSymbolData[i], Layout);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001314
1315 // Write the string table.
1316 OS << StringTable.str();
1317 }
1318 }
1319};
1320
1321}
1322
Daniel Dunbar115a3dd2010-11-13 07:33:40 +00001323MCObjectWriter *llvm::createMachObjectWriter(raw_ostream &OS, bool is64Bit,
1324 uint32_t CPUType,
1325 uint32_t CPUSubtype,
1326 bool IsLittleEndian) {
1327 return new MachObjectWriter(OS, is64Bit, CPUType, CPUSubtype, IsLittleEndian);
Daniel Dunbar2df4ceb2010-03-19 10:43:15 +00001328}