blob: 7c0855a5e13afe3f6db2988484731e952e5c9962 [file] [log] [blame]
Nate Begemaneb883af2006-08-23 21:08:52 +00001//===-- MachOWriter.cpp - Target-independent Mach-O Writer code -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Nate Begeman and is distributed under the
6// University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the target-independent Mach-O writer. This file writes
11// out the Mach-O file in the following order:
12//
13// #1 FatHeader (universal-only)
14// #2 FatArch (universal-only, 1 per universal arch)
15// Per arch:
16// #3 Header
17// #4 Load Commands
18// #5 Sections
19// #6 Relocations
20// #7 Symbols
21// #8 Strings
22//
23//===----------------------------------------------------------------------===//
24
25#include "llvm/Module.h"
26#include "llvm/CodeGen/MachineCodeEmitter.h"
27#include "llvm/CodeGen/MachineConstantPool.h"
Nate Begeman019f8512006-09-10 23:03:44 +000028#include "llvm/CodeGen/MachineJumpTableInfo.h"
Nate Begemaneb883af2006-08-23 21:08:52 +000029#include "llvm/CodeGen/MachOWriter.h"
Nate Begeman94be2482006-09-08 22:42:09 +000030#include "llvm/ExecutionEngine/ExecutionEngine.h"
Nate Begemaneb883af2006-08-23 21:08:52 +000031#include "llvm/Target/TargetJITInfo.h"
Nate Begemaneb883af2006-08-23 21:08:52 +000032#include "llvm/Support/Mangler.h"
Nate Begemanf8f2c5a2006-08-25 06:36:58 +000033#include "llvm/Support/MathExtras.h"
Nate Begemand2030e62006-08-26 15:46:34 +000034#include <algorithm>
Nate Begemaneb883af2006-08-23 21:08:52 +000035#include <iostream>
36using namespace llvm;
37
38//===----------------------------------------------------------------------===//
39// MachOCodeEmitter Implementation
40//===----------------------------------------------------------------------===//
41
42namespace llvm {
43 /// MachOCodeEmitter - This class is used by the MachOWriter to emit the code
44 /// for functions to the Mach-O file.
45 class MachOCodeEmitter : public MachineCodeEmitter {
46 MachOWriter &MOW;
47
48 /// MOS - The current section we're writing to
49 MachOWriter::MachOSection *MOS;
50
51 /// Relocations - These are the relocations that the function needs, as
52 /// emitted.
53 std::vector<MachineRelocation> Relocations;
Nate Begeman019f8512006-09-10 23:03:44 +000054
55 /// CPLocations - This is a map of constant pool indices to offsets from the
56 /// start of the section for that constant pool index.
57 std::vector<intptr_t> CPLocations;
58
59 /// JTLocations - This is a map of jump table indices to offsets from the
60 /// start of the section for that jump table index.
61 std::vector<intptr_t> JTLocations;
Nate Begemaneb883af2006-08-23 21:08:52 +000062
63 /// MBBLocations - This vector is a mapping from MBB ID's to their address.
64 /// It is filled in by the StartMachineBasicBlock callback and queried by
65 /// the getMachineBasicBlockAddress callback.
66 std::vector<intptr_t> MBBLocations;
67
68 public:
69 MachOCodeEmitter(MachOWriter &mow) : MOW(mow) {}
70
71 void startFunction(MachineFunction &F);
72 bool finishFunction(MachineFunction &F);
73
74 void addRelocation(const MachineRelocation &MR) {
75 Relocations.push_back(MR);
76 }
77
Nate Begeman019f8512006-09-10 23:03:44 +000078 void emitConstantPool(MachineConstantPool *MCP);
79 void emitJumpTables(MachineJumpTableInfo *MJTI);
80
Nate Begemaneb883af2006-08-23 21:08:52 +000081 virtual intptr_t getConstantPoolEntryAddress(unsigned Index) const {
82 assert(0 && "CP not implementated yet!");
83 return 0;
84 }
85 virtual intptr_t getJumpTableEntryAddress(unsigned Index) const {
Nate Begeman019f8512006-09-10 23:03:44 +000086 assert(JTLocations.size() > Index && "JT not emitted!");
87 return JTLocations[Index];
88 }
89
90 virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {
91 if (MBBLocations.size() <= (unsigned)MBB->getNumber())
92 MBBLocations.resize((MBB->getNumber()+1)*2);
93 MBBLocations[MBB->getNumber()] = getCurrentPCOffset();
Nate Begemaneb883af2006-08-23 21:08:52 +000094 }
95
96 virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
97 assert(MBBLocations.size() > (unsigned)MBB->getNumber() &&
98 MBBLocations[MBB->getNumber()] && "MBB not emitted!");
99 return MBBLocations[MBB->getNumber()];
100 }
101
102 /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
Evan Chengce9a5762006-11-16 20:04:04 +0000103 void startFunctionStub(unsigned StubSize, unsigned Alignment = 1) {
Nate Begemaneb883af2006-08-23 21:08:52 +0000104 assert(0 && "JIT specific function called!");
105 abort();
106 }
107 void *finishFunctionStub(const Function *F) {
108 assert(0 && "JIT specific function called!");
109 abort();
110 return 0;
111 }
112 };
113}
114
115/// startFunction - This callback is invoked when a new machine function is
116/// about to be emitted.
117void MachOCodeEmitter::startFunction(MachineFunction &F) {
118 // Align the output buffer to the appropriate alignment, power of 2.
119 // FIXME: GENERICIZE!!
120 unsigned Align = 4;
121
122 // Get the Mach-O Section that this function belongs in.
123 MOS = &MOW.getTextSection();
124
125 // FIXME: better memory management
126 MOS->SectionData.reserve(4096);
127 BufferBegin = &(MOS->SectionData[0]);
128 BufferEnd = BufferBegin + MOS->SectionData.capacity();
129 CurBufferPtr = BufferBegin + MOS->size;
130
131 // Upgrade the section alignment if required.
132 if (MOS->align < Align) MOS->align = Align;
133
Nate Begeman019f8512006-09-10 23:03:44 +0000134 // Clear per-function data structures.
135 CPLocations.clear();
136 JTLocations.clear();
Nate Begemaneb883af2006-08-23 21:08:52 +0000137 MBBLocations.clear();
138}
139
140/// finishFunction - This callback is invoked after the function is completely
141/// finished.
142bool MachOCodeEmitter::finishFunction(MachineFunction &F) {
143 MOS->size += CurBufferPtr - BufferBegin;
144
145 // Get a symbol for the function to add to the symbol table
Nate Begemand2030e62006-08-26 15:46:34 +0000146 const GlobalValue *FuncV = F.getFunction();
Nate Begeman94be2482006-09-08 22:42:09 +0000147 MachOSym FnSym(FuncV, MOW.Mang->getValueName(FuncV), MOS->Index);
148
Nate Begeman019f8512006-09-10 23:03:44 +0000149 // Emit constant pool to appropriate section(s)
150 emitConstantPool(F.getConstantPool());
151
152 // Emit jump tables to appropriate section
153 emitJumpTables(F.getJumpTableInfo());
Nate Begemaneb883af2006-08-23 21:08:52 +0000154
Nate Begeman019f8512006-09-10 23:03:44 +0000155 // If we have emitted any relocations to function-specific objects such as
156 // basic blocks, constant pools entries, or jump tables, record their
157 // addresses now so that we can rewrite them with the correct addresses
158 // later.
Nate Begemaneb883af2006-08-23 21:08:52 +0000159 for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
160 MachineRelocation &MR = Relocations[i];
Nate Begeman019f8512006-09-10 23:03:44 +0000161 intptr_t Addr;
Nate Begemaneb883af2006-08-23 21:08:52 +0000162 if (MR.isBasicBlock()) {
Nate Begeman019f8512006-09-10 23:03:44 +0000163 Addr = getMachineBasicBlockAddress(MR.getBasicBlock());
164 MR.setResultPointer((void *)Addr);
165 } else if (MR.isConstantPoolIndex()) {
166 Addr = getConstantPoolEntryAddress(MR.getConstantPoolIndex());
167 MR.setResultPointer((void *)Addr);
168 } else if (MR.isJumpTableIndex()) {
169 // FIXME: handle PIC codegen
170 Addr = getJumpTableEntryAddress(MR.getJumpTableIndex());
171 MR.setResultPointer((void *)Addr);
Nate Begemaneb883af2006-08-23 21:08:52 +0000172 }
Nate Begeman019f8512006-09-10 23:03:44 +0000173 MOS->Relocations.push_back(MR);
Nate Begemaneb883af2006-08-23 21:08:52 +0000174 }
175 Relocations.clear();
176
177 // Finally, add it to the symtab.
178 MOW.SymbolTable.push_back(FnSym);
179 return false;
180}
181
Nate Begeman019f8512006-09-10 23:03:44 +0000182/// emitConstantPool - For each constant pool entry, figure out which section
183/// the constant should live in, allocate space for it, and emit it to the
184/// Section data buffer.
185void MachOCodeEmitter::emitConstantPool(MachineConstantPool *MCP) {
186}
187
188/// emitJumpTables - Emit all the jump tables for a given jump table info
189/// record to the appropriate section.
190void MachOCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) {
191 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
192 if (JT.empty()) return;
193
194 bool isPIC = MOW.TM.getRelocationModel() == Reloc::PIC_;
195 assert(!isPIC && "PIC codegen not yet handled for mach-o jump tables!");
196
197 MachOWriter::MachOSection &Sec = MOW.getJumpTableSection();
198
199 for (unsigned i = 0, e = JT.size(); i != e; ++i) {
200 // For each jump table, record its offset from the start of the section,
201 // reserve space for the relocations to the MBBs, and add the relocations.
202 const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs;
203 JTLocations.push_back(Sec.SectionData.size());
204 for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) {
205 MachineRelocation MR(MOW.GetJTRelocation(Sec.SectionData.size(),
206 MBBs[mi]));
207 MR.setResultPointer((void *)JTLocations[i]);
208 Sec.Relocations.push_back(MR);
209 MOW.outaddr(Sec.SectionData, 0);
210 }
211 }
212 // FIXME: it really seems like keeping these in sync is redundant, someone
213 // should do something about that (never access section size directly, only
214 // look at buffer size).
215 Sec.size = Sec.SectionData.size();
216}
217
Nate Begemaneb883af2006-08-23 21:08:52 +0000218//===----------------------------------------------------------------------===//
219// MachOWriter Implementation
220//===----------------------------------------------------------------------===//
221
222MachOWriter::MachOWriter(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) {
Nate Begemaneb883af2006-08-23 21:08:52 +0000223 is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
224 isLittleEndian = TM.getTargetData()->isLittleEndian();
225
226 // Create the machine code emitter object for this target.
227 MCE = new MachOCodeEmitter(*this);
228}
229
230MachOWriter::~MachOWriter() {
231 delete MCE;
232}
233
Nate Begemanf8f2c5a2006-08-25 06:36:58 +0000234void MachOWriter::AddSymbolToSection(MachOSection &Sec, GlobalVariable *GV) {
235 const Type *Ty = GV->getType()->getElementType();
236 unsigned Size = TM.getTargetData()->getTypeSize(Ty);
237 unsigned Align = Log2_32(TM.getTargetData()->getTypeAlignment(Ty));
238
Nate Begemand2030e62006-08-26 15:46:34 +0000239 MachOSym Sym(GV, Mang->getValueName(GV), Sec.Index);
Nate Begemanf8f2c5a2006-08-25 06:36:58 +0000240 // Reserve space in the .bss section for this symbol while maintaining the
241 // desired section alignment, which must be at least as much as required by
242 // this symbol.
243 if (Align) {
Chris Lattner94425992006-09-02 17:37:30 +0000244 Sec.align = std::max(unsigned(Sec.align), Align);
Nate Begemanf8f2c5a2006-08-25 06:36:58 +0000245 Sec.size = (Sec.size + Align - 1) & ~(Align-1);
246 }
247 // Record the offset of the symbol, and then allocate space for it.
248 Sym.n_value = Sec.size;
249 Sec.size += Size;
250
251 switch (GV->getLinkage()) {
252 default: // weak/linkonce handled above
253 assert(0 && "Unexpected linkage type!");
254 case GlobalValue::ExternalLinkage:
255 Sym.n_type |= MachOSym::N_EXT;
256 break;
257 case GlobalValue::InternalLinkage:
258 break;
259 }
260 SymbolTable.push_back(Sym);
261}
262
Nate Begemaneb883af2006-08-23 21:08:52 +0000263void MachOWriter::EmitGlobal(GlobalVariable *GV) {
Nate Begemanf8f2c5a2006-08-25 06:36:58 +0000264 const Type *Ty = GV->getType()->getElementType();
265 unsigned Size = TM.getTargetData()->getTypeSize(Ty);
266 bool NoInit = !GV->hasInitializer();
Nate Begemand2030e62006-08-26 15:46:34 +0000267
Nate Begemanf8f2c5a2006-08-25 06:36:58 +0000268 // If this global has a zero initializer, it is part of the .bss or common
269 // section.
270 if (NoInit || GV->getInitializer()->isNullValue()) {
271 // If this global is part of the common block, add it now. Variables are
272 // part of the common block if they are zero initialized and allowed to be
273 // merged with other symbols.
274 if (NoInit || GV->hasLinkOnceLinkage() || GV->hasWeakLinkage()) {
Nate Begeman94be2482006-09-08 22:42:09 +0000275 MachOSym ExtOrCommonSym(GV, Mang->getValueName(GV), MachOSym::NO_SECT);
Nate Begemanf8f2c5a2006-08-25 06:36:58 +0000276 // For undefined (N_UNDF) external (N_EXT) types, n_value is the size in
277 // bytes of the symbol.
278 ExtOrCommonSym.n_value = Size;
279 // If the symbol is external, we'll put it on a list of symbols whose
280 // addition to the symbol table is being pended until we find a reference
281 if (NoInit)
282 PendingSyms.push_back(ExtOrCommonSym);
283 else
284 SymbolTable.push_back(ExtOrCommonSym);
285 return;
286 }
287 // Otherwise, this symbol is part of the .bss section.
288 MachOSection &BSS = getBSSSection();
289 AddSymbolToSection(BSS, GV);
290 return;
291 }
292
293 // Scalar read-only data goes in a literal section if the scalar is 4, 8, or
294 // 16 bytes, or a cstring. Other read only data goes into a regular const
295 // section. Read-write data goes in the data section.
296 MachOSection &Sec = GV->isConstant() ? getConstSection(Ty) : getDataSection();
297 AddSymbolToSection(Sec, GV);
298
Nate Begeman94be2482006-09-08 22:42:09 +0000299 // FIXME: A couple significant changes are required for this to work, even for
300 // trivial cases such as a constant integer:
301 // 0. InitializeMemory needs to be split out of ExecutionEngine. We don't
302 // want to have to create an ExecutionEngine such as JIT just to write
303 // some bytes into a buffer. The only thing necessary for
304 // InitializeMemory to function properly should be TargetData.
305 //
306 // 1. InitializeMemory needs to be enhanced to return MachineRelocations
307 // rather than accessing the address of objects such basic blocks,
308 // constant pools, and jump tables. The client of InitializeMemory such
309 // as an object writer or jit emitter should then handle these relocs
310 // appropriately.
311 //
312 // FIXME: need to allocate memory for the global initializer.
Nate Begemaneb883af2006-08-23 21:08:52 +0000313}
314
315
316bool MachOWriter::runOnMachineFunction(MachineFunction &MF) {
317 // Nothing to do here, this is all done through the MCE object.
318 return false;
319}
320
321bool MachOWriter::doInitialization(Module &M) {
322 // Set the magic value, now that we know the pointer size and endianness
323 Header.setMagic(isLittleEndian, is64Bit);
324
325 // Set the file type
326 // FIXME: this only works for object files, we do not support the creation
327 // of dynamic libraries or executables at this time.
328 Header.filetype = MachOHeader::MH_OBJECT;
329
330 Mang = new Mangler(M);
331 return false;
332}
333
334/// doFinalization - Now that the module has been completely processed, emit
335/// the Mach-O file to 'O'.
336bool MachOWriter::doFinalization(Module &M) {
Nate Begemand2030e62006-08-26 15:46:34 +0000337 // FIXME: we don't handle debug info yet, we should probably do that.
338
Nate Begemaneb883af2006-08-23 21:08:52 +0000339 // Okay, the.text section has been completed, build the .data, .bss, and
340 // "common" sections next.
341 for (Module::global_iterator I = M.global_begin(), E = M.global_end();
342 I != E; ++I)
343 EmitGlobal(I);
344
Nate Begemand2030e62006-08-26 15:46:34 +0000345 // Emit the symbol table to temporary buffers, so that we know the size of
346 // the string table when we write the load commands in the next phase.
347 BufferSymbolAndStringTable();
Nate Begeman94be2482006-09-08 22:42:09 +0000348
Nate Begemaneb883af2006-08-23 21:08:52 +0000349 // Emit the header and load commands.
350 EmitHeaderAndLoadCommands();
351
Nate Begeman019f8512006-09-10 23:03:44 +0000352 // Emit the various sections and their relocation info.
Nate Begemaneb883af2006-08-23 21:08:52 +0000353 EmitSections();
354
Nate Begemand2030e62006-08-26 15:46:34 +0000355 // Write the symbol table and the string table to the end of the file.
356 O.write((char*)&SymT[0], SymT.size());
357 O.write((char*)&StrT[0], StrT.size());
Nate Begemaneb883af2006-08-23 21:08:52 +0000358
359 // We are done with the abstract symbols.
360 SectionList.clear();
361 SymbolTable.clear();
362 DynamicSymbolTable.clear();
363
364 // Release the name mangler object.
365 delete Mang; Mang = 0;
366 return false;
367}
368
369void MachOWriter::EmitHeaderAndLoadCommands() {
370 // Step #0: Fill in the segment load command size, since we need it to figure
371 // out the rest of the header fields
372 MachOSegment SEG("", is64Bit);
373 SEG.nsects = SectionList.size();
374 SEG.cmdsize = SEG.cmdSize(is64Bit) +
375 SEG.nsects * SectionList.begin()->cmdSize(is64Bit);
376
377 // Step #1: calculate the number of load commands. We always have at least
378 // one, for the LC_SEGMENT load command, plus two for the normal
379 // and dynamic symbol tables, if there are any symbols.
380 Header.ncmds = SymbolTable.empty() ? 1 : 3;
381
382 // Step #2: calculate the size of the load commands
383 Header.sizeofcmds = SEG.cmdsize;
384 if (!SymbolTable.empty())
385 Header.sizeofcmds += SymTab.cmdsize + DySymTab.cmdsize;
386
387 // Step #3: write the header to the file
388 // Local alias to shortenify coming code.
389 DataBuffer &FH = Header.HeaderData;
390 outword(FH, Header.magic);
391 outword(FH, Header.cputype);
392 outword(FH, Header.cpusubtype);
393 outword(FH, Header.filetype);
394 outword(FH, Header.ncmds);
395 outword(FH, Header.sizeofcmds);
396 outword(FH, Header.flags);
397 if (is64Bit)
398 outword(FH, Header.reserved);
399
400 // Step #4: Finish filling in the segment load command and write it out
401 for (std::list<MachOSection>::iterator I = SectionList.begin(),
402 E = SectionList.end(); I != E; ++I)
403 SEG.filesize += I->size;
404 SEG.vmsize = SEG.filesize;
405 SEG.fileoff = Header.cmdSize(is64Bit) + Header.sizeofcmds;
406
407 outword(FH, SEG.cmd);
408 outword(FH, SEG.cmdsize);
409 outstring(FH, SEG.segname, 16);
410 outaddr(FH, SEG.vmaddr);
411 outaddr(FH, SEG.vmsize);
412 outaddr(FH, SEG.fileoff);
413 outaddr(FH, SEG.filesize);
414 outword(FH, SEG.maxprot);
415 outword(FH, SEG.initprot);
416 outword(FH, SEG.nsects);
417 outword(FH, SEG.flags);
418
Nate Begeman94be2482006-09-08 22:42:09 +0000419 // Step #5: Finish filling in the fields of the MachOSections
420 uint64_t currentAddr = 0;
Nate Begemaneb883af2006-08-23 21:08:52 +0000421 for (std::list<MachOSection>::iterator I = SectionList.begin(),
422 E = SectionList.end(); I != E; ++I) {
Nate Begeman94be2482006-09-08 22:42:09 +0000423 I->addr = currentAddr;
424 I->offset = currentAddr + SEG.fileoff;
Nate Begeman019f8512006-09-10 23:03:44 +0000425
Nate Begeman94be2482006-09-08 22:42:09 +0000426 // FIXME: do we need to do something with alignment here?
427 currentAddr += I->size;
428 }
429
430 // Step #6: Calculate the number of relocations for each section and write out
431 // the section commands for each section
432 currentAddr += SEG.fileoff;
433 for (std::list<MachOSection>::iterator I = SectionList.begin(),
434 E = SectionList.end(); I != E; ++I) {
435 // calculate the relocation info for this section command
Nate Begeman019f8512006-09-10 23:03:44 +0000436 CalculateRelocations(*I, currentAddr);
437 currentAddr += I->nreloc * 8;
Nate Begeman94be2482006-09-08 22:42:09 +0000438
439 // write the finalized section command to the output buffer
Nate Begemaneb883af2006-08-23 21:08:52 +0000440 outstring(FH, I->sectname, 16);
441 outstring(FH, I->segname, 16);
442 outaddr(FH, I->addr);
443 outaddr(FH, I->size);
444 outword(FH, I->offset);
445 outword(FH, I->align);
446 outword(FH, I->reloff);
447 outword(FH, I->nreloc);
448 outword(FH, I->flags);
449 outword(FH, I->reserved1);
450 outword(FH, I->reserved2);
451 if (is64Bit)
452 outword(FH, I->reserved3);
453 }
454
Nate Begeman94be2482006-09-08 22:42:09 +0000455 // Step #7: Emit LC_SYMTAB/LC_DYSYMTAB load commands
Nate Begemaneb883af2006-08-23 21:08:52 +0000456 // FIXME: add size of relocs
Nate Begeman94be2482006-09-08 22:42:09 +0000457 SymTab.symoff = currentAddr;
Nate Begemaneb883af2006-08-23 21:08:52 +0000458 SymTab.nsyms = SymbolTable.size();
Nate Begemand2030e62006-08-26 15:46:34 +0000459 SymTab.stroff = SymTab.symoff + SymT.size();
460 SymTab.strsize = StrT.size();
Nate Begemaneb883af2006-08-23 21:08:52 +0000461 outword(FH, SymTab.cmd);
462 outword(FH, SymTab.cmdsize);
463 outword(FH, SymTab.symoff);
464 outword(FH, SymTab.nsyms);
465 outword(FH, SymTab.stroff);
466 outword(FH, SymTab.strsize);
467
468 // FIXME: set DySymTab fields appropriately
Nate Begemand2030e62006-08-26 15:46:34 +0000469 // We should probably just update these in BufferSymbolAndStringTable since
470 // thats where we're partitioning up the different kinds of symbols.
Nate Begemaneb883af2006-08-23 21:08:52 +0000471 outword(FH, DySymTab.cmd);
472 outword(FH, DySymTab.cmdsize);
473 outword(FH, DySymTab.ilocalsym);
474 outword(FH, DySymTab.nlocalsym);
475 outword(FH, DySymTab.iextdefsym);
476 outword(FH, DySymTab.nextdefsym);
477 outword(FH, DySymTab.iundefsym);
478 outword(FH, DySymTab.nundefsym);
479 outword(FH, DySymTab.tocoff);
480 outword(FH, DySymTab.ntoc);
481 outword(FH, DySymTab.modtaboff);
482 outword(FH, DySymTab.nmodtab);
483 outword(FH, DySymTab.extrefsymoff);
484 outword(FH, DySymTab.nextrefsyms);
485 outword(FH, DySymTab.indirectsymoff);
486 outword(FH, DySymTab.nindirectsyms);
487 outword(FH, DySymTab.extreloff);
488 outword(FH, DySymTab.nextrel);
489 outword(FH, DySymTab.locreloff);
490 outword(FH, DySymTab.nlocrel);
491
492 O.write((char*)&FH[0], FH.size());
493}
494
495/// EmitSections - Now that we have constructed the file header and load
496/// commands, emit the data for each section to the file.
497void MachOWriter::EmitSections() {
498 for (std::list<MachOSection>::iterator I = SectionList.begin(),
Nate Begeman019f8512006-09-10 23:03:44 +0000499 E = SectionList.end(); I != E; ++I)
500 // Emit the contents of each section
Nate Begemaneb883af2006-08-23 21:08:52 +0000501 O.write((char*)&I->SectionData[0], I->size);
Nate Begeman019f8512006-09-10 23:03:44 +0000502 for (std::list<MachOSection>::iterator I = SectionList.begin(),
503 E = SectionList.end(); I != E; ++I)
504 // Emit the relocation entry data for each section.
505 O.write((char*)&I->RelocBuffer[0], I->RelocBuffer.size());
Nate Begemaneb883af2006-08-23 21:08:52 +0000506}
507
Nate Begemand2030e62006-08-26 15:46:34 +0000508/// PartitionByLocal - Simple boolean predicate that returns true if Sym is
509/// a local symbol rather than an external symbol.
510bool MachOWriter::PartitionByLocal(const MachOSym &Sym) {
511 // FIXME: Not totally sure if private extern counts as external
512 return (Sym.n_type & (MachOSym::N_EXT | MachOSym::N_PEXT)) == 0;
Nate Begemaneb883af2006-08-23 21:08:52 +0000513}
514
Nate Begemand2030e62006-08-26 15:46:34 +0000515/// PartitionByDefined - Simple boolean predicate that returns true if Sym is
516/// defined in this module.
517bool MachOWriter::PartitionByDefined(const MachOSym &Sym) {
518 // FIXME: Do N_ABS or N_INDR count as defined?
519 return (Sym.n_type & MachOSym::N_SECT) == MachOSym::N_SECT;
520}
Nate Begemaneb883af2006-08-23 21:08:52 +0000521
Nate Begemand2030e62006-08-26 15:46:34 +0000522/// BufferSymbolAndStringTable - Sort the symbols we encountered and assign them
523/// each a string table index so that they appear in the correct order in the
524/// output file.
525void MachOWriter::BufferSymbolAndStringTable() {
526 // The order of the symbol table is:
527 // 1. local symbols
528 // 2. defined external symbols (sorted by name)
529 // 3. undefined external symbols (sorted by name)
530
531 // Sort the symbols by name, so that when we partition the symbols by scope
532 // of definition, we won't have to sort by name within each partition.
533 std::sort(SymbolTable.begin(), SymbolTable.end(), MachOSymCmp());
534
535 // Parition the symbol table entries so that all local symbols come before
536 // all symbols with external linkage. { 1 | 2 3 }
537 std::partition(SymbolTable.begin(), SymbolTable.end(), PartitionByLocal);
538
539 // Advance iterator to beginning of external symbols and partition so that
540 // all external symbols defined in this module come before all external
541 // symbols defined elsewhere. { 1 | 2 | 3 }
542 for (std::vector<MachOSym>::iterator I = SymbolTable.begin(),
543 E = SymbolTable.end(); I != E; ++I) {
544 if (!PartitionByLocal(*I)) {
545 std::partition(I, E, PartitionByDefined);
546 break;
547 }
548 }
549
Nate Begemaneb883af2006-08-23 21:08:52 +0000550 // Write out a leading zero byte when emitting string table, for n_strx == 0
551 // which means an empty string.
Nate Begemand2030e62006-08-26 15:46:34 +0000552 outbyte(StrT, 0);
Nate Begemaneb883af2006-08-23 21:08:52 +0000553
Nate Begemand2030e62006-08-26 15:46:34 +0000554 // The order of the string table is:
555 // 1. strings for external symbols
556 // 2. strings for local symbols
557 // Since this is the opposite order from the symbol table, which we have just
558 // sorted, we can walk the symbol table backwards to output the string table.
559 for (std::vector<MachOSym>::reverse_iterator I = SymbolTable.rbegin(),
560 E = SymbolTable.rend(); I != E; ++I) {
561 if (I->GVName == "") {
562 I->n_strx = 0;
563 } else {
564 I->n_strx = StrT.size();
565 outstring(StrT, I->GVName, I->GVName.length()+1);
566 }
Nate Begemaneb883af2006-08-23 21:08:52 +0000567 }
Nate Begemand2030e62006-08-26 15:46:34 +0000568
569 for (std::vector<MachOSym>::iterator I = SymbolTable.begin(),
570 E = SymbolTable.end(); I != E; ++I) {
571 // Emit nlist to buffer
572 outword(SymT, I->n_strx);
573 outbyte(SymT, I->n_type);
574 outbyte(SymT, I->n_sect);
575 outhalf(SymT, I->n_desc);
576 outaddr(SymT, I->n_value);
577 }
Nate Begemaneb883af2006-08-23 21:08:52 +0000578}
Nate Begeman94be2482006-09-08 22:42:09 +0000579
Nate Begeman019f8512006-09-10 23:03:44 +0000580/// CalculateRelocations - For each MachineRelocation in the current section,
581/// calculate the index of the section containing the object to be relocated,
582/// and the offset into that section. From this information, create the
583/// appropriate target-specific MachORelocation type and add buffer it to be
584/// written out after we are finished writing out sections.
585void MachOWriter::CalculateRelocations(MachOSection &MOS, unsigned RelOffset) {
586 for (unsigned i = 0, e = MOS.Relocations.size(); i != e; ++i) {
587 // FIXME: calculate the correct offset and section index for relocated
588 // object.
589 // FIXME: somehow convey the fact that the relocation might be external
590 // to the relocating code.
591 GetTargetRelocation(MOS.Relocations[i], MOS, MOS.Index);
592 }
593 if (MOS.nreloc != 0)
594 MOS.reloff = RelOffset;
595}
596
Nate Begeman94be2482006-09-08 22:42:09 +0000597MachOSym::MachOSym(const GlobalValue *gv, std::string name, uint8_t sect) :
598 GV(gv), GVName(name), n_strx(0), n_type(sect == NO_SECT ? N_UNDF : N_SECT),
599 n_sect(sect), n_desc(0), n_value(0) {
600 // FIXME: take a target machine, and then add the appropriate prefix for
601 // the linkage type based on the TargetAsmInfo
602 switch (GV->getLinkage()) {
603 default:
604 assert(0 && "Unexpected linkage type!");
605 break;
606 case GlobalValue::WeakLinkage:
607 case GlobalValue::LinkOnceLinkage:
608 assert(!isa<Function>(gv) && "Unexpected linkage type for Function!");
609 case GlobalValue::ExternalLinkage:
610 n_type |= N_EXT;
611 break;
612 case GlobalValue::InternalLinkage:
613 break;
614 }
615}