Add the Object Code Emitter class. Original patch by Aaron Gray, I did some
[oota-llvm.git] / lib / CodeGen / MachOWriter.h
1 //=== MachOWriter.h - Target-independent Mach-O writer support --*- C++ -*-===//
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 //
10 // This file defines the MachOWriter class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef MACHOWRITER_H
15 #define MACHOWRITER_H
16
17 #include "MachO.h"
18 #include "llvm/Constants.h"
19 #include "llvm/DerivedTypes.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
21 #include "llvm/CodeGen/ObjectCodeEmitter.h"
22 #include "llvm/Target/TargetData.h"
23 #include "llvm/Target/TargetMachine.h"
24 #include "llvm/Target/TargetMachOWriterInfo.h"
25 #include <vector>
26 #include <map>
27
28 namespace llvm {
29   class GlobalVariable;
30   class Mangler;
31   class MachineRelocation;
32   class ObjectCodeEmitter;
33   class MachOCodeEmitter;
34   class TargetData;
35   class TargetMachine;
36   class OutputBuffer;
37   class raw_ostream;
38
39       
40   /// MachOWriter - This class implements the common target-independent code for
41   /// writing Mach-O files.  Targets should derive a class from this to
42   /// parameterize the output format.
43   ///
44   class MachOWriter : public MachineFunctionPass {
45     friend class MachOCodeEmitter;
46   public:
47     static char ID;
48
49     ObjectCodeEmitter *getObjectCodeEmitter() {
50       return reinterpret_cast<ObjectCodeEmitter*>(MachOCE);
51     }
52
53     MachOWriter(raw_ostream &O, TargetMachine &TM);
54     virtual ~MachOWriter();
55
56     virtual const char *getPassName() const {
57       return "Mach-O Writer";
58     }
59
60   protected:
61     /// Output stream to send the resultant object file to.
62     ///
63     raw_ostream &O;
64
65     /// Target machine description.
66     ///
67     TargetMachine &TM;
68
69     /// Mang - The object used to perform name mangling for this module.
70     ///
71     Mangler *Mang;
72     
73     /// MachOCE - The MachineCodeEmitter object that we are exposing to emit machine
74     /// code for functions to the .o file.
75
76     MachOCodeEmitter *MachOCE;
77
78     /// is64Bit/isLittleEndian - This information is inferred from the target
79     /// machine directly, indicating what header values and flags to set.
80
81     bool is64Bit, isLittleEndian;
82
83     // Target Asm Info
84
85     const TargetAsmInfo *TAI;
86
87     /// Header - An instance of MachOHeader that we will update while we build
88     /// the file, and then emit during finalization.
89     
90     MachOHeader Header;
91
92     /// doInitialization - Emit the file header and all of the global variables
93     /// for the module to the Mach-O file.
94
95     bool doInitialization(Module &M);
96
97     bool runOnMachineFunction(MachineFunction &MF);
98
99     /// doFinalization - Now that the module has been completely processed, emit
100     /// the Mach-O file to 'O'.
101
102     bool doFinalization(Module &M);
103
104   private:
105
106     /// SectionList - This is the list of sections that we have emitted to the
107     /// file.  Once the file has been completely built, the segment load command
108     /// SectionCommands are constructed from this info.
109
110     std::vector<MachOSection*> SectionList;
111
112     /// SectionLookup - This is a mapping from section name to SectionList entry
113
114     std::map<std::string, MachOSection*> SectionLookup;
115     
116     /// GVSection - This is a mapping from a GlobalValue to a MachOSection,
117     /// to aid in emitting relocations.
118
119     std::map<GlobalValue*, MachOSection*> GVSection;
120
121     /// GVOffset - This is a mapping from a GlobalValue to an offset from the 
122     /// start of the section in which the GV resides, to aid in emitting
123     /// relocations.
124
125     std::map<GlobalValue*, intptr_t> GVOffset;
126
127     /// getSection - Return the section with the specified name, creating a new
128     /// section if one does not already exist.
129
130     MachOSection *getSection(const std::string &seg, const std::string &sect,
131                              unsigned Flags = 0) {
132       MachOSection *MOS = SectionLookup[seg+sect];
133       if (MOS) return MOS;
134
135       MOS = new MachOSection(seg, sect);
136       SectionList.push_back(MOS);
137       MOS->Index = SectionList.size();
138       MOS->flags = MachOSection::S_REGULAR | Flags;
139       SectionLookup[seg+sect] = MOS;
140       return MOS;
141     }
142     MachOSection *getTextSection(bool isCode = true) {
143       if (isCode)
144         return getSection("__TEXT", "__text", 
145                           MachOSection::S_ATTR_PURE_INSTRUCTIONS |
146                           MachOSection::S_ATTR_SOME_INSTRUCTIONS);
147       else
148         return getSection("__TEXT", "__text");
149     }
150     MachOSection *getBSSSection() {
151       return getSection("__DATA", "__bss", MachOSection::S_ZEROFILL);
152     }
153     MachOSection *getDataSection() {
154       return getSection("__DATA", "__data");
155     }
156     MachOSection *getConstSection(Constant *C) {
157       const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
158       if (CVA && CVA->isCString())
159         return getSection("__TEXT", "__cstring", 
160                           MachOSection::S_CSTRING_LITERALS);
161       
162       const Type *Ty = C->getType();
163       if (Ty->isPrimitiveType() || Ty->isInteger()) {
164         unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty);
165         switch(Size) {
166         default: break; // Fall through to __TEXT,__const
167         case 4:
168           return getSection("__TEXT", "__literal4",
169                             MachOSection::S_4BYTE_LITERALS);
170         case 8:
171           return getSection("__TEXT", "__literal8",
172                             MachOSection::S_8BYTE_LITERALS);
173         case 16:
174           return getSection("__TEXT", "__literal16",
175                             MachOSection::S_16BYTE_LITERALS);
176         }
177       }
178       return getSection("__TEXT", "__const");
179     }
180     MachOSection *getJumpTableSection() {
181       if (TM.getRelocationModel() == Reloc::PIC_)
182         return getTextSection(false);
183       else
184         return getSection("__TEXT", "__const");
185     }
186     
187     /// MachOSymTab - This struct contains information about the offsets and 
188     /// size of symbol table information.
189     /// segment.
190     struct MachOSymTab {
191       uint32_t cmd;     // LC_SYMTAB
192       uint32_t cmdsize; // sizeof( MachOSymTab )
193       uint32_t symoff;  // symbol table offset
194       uint32_t nsyms;   // number of symbol table entries
195       uint32_t stroff;  // string table offset
196       uint32_t strsize; // string table size in bytes
197
198       // Constants for the cmd field
199       // see <mach-o/loader.h>
200       enum { LC_SYMTAB = 0x02  // link-edit stab symbol table info
201       };
202       
203       MachOSymTab() : cmd(LC_SYMTAB), cmdsize(6 * sizeof(uint32_t)), symoff(0),
204         nsyms(0), stroff(0), strsize(0) { }
205     };
206     
207     /// SymTab - The "stab" style symbol table information
208     MachOSymTab   SymTab;     
209     /// DySymTab - symbol table info for the dynamic link editor
210     MachODySymTab DySymTab;
211
212   protected:
213   
214     /// SymbolTable - This is the list of symbols we have emitted to the file.
215     /// This actually gets rearranged before emission to the file (to put the
216     /// local symbols first in the list).
217     std::vector<MachOSym> SymbolTable;
218     
219     /// SymT - A buffer to hold the symbol table before we write it out at the
220     /// appropriate location in the file.
221     DataBuffer SymT;
222     
223     /// StrT - A buffer to hold the string table before we write it out at the
224     /// appropriate location in the file.
225     DataBuffer StrT;
226     
227     /// PendingSyms - This is a list of externally defined symbols that we have
228     /// been asked to emit, but have not seen a reference to.  When a reference
229     /// is seen, the symbol will move from this list to the SymbolTable.
230     std::vector<GlobalValue*> PendingGlobals;
231     
232     /// DynamicSymbolTable - This is just a vector of indices into
233     /// SymbolTable to aid in emitting the DYSYMTAB load command.
234     std::vector<unsigned> DynamicSymbolTable;
235     
236     static void InitMem(const Constant *C,
237                         uintptr_t Offset,
238                         const TargetData *TD, 
239                         MachOSection* mos);
240
241   private:
242     void AddSymbolToSection(MachOSection *MOS, GlobalVariable *GV);
243     void EmitGlobal(GlobalVariable *GV);
244     void EmitHeaderAndLoadCommands();
245     void EmitSections();
246     void EmitRelocations();
247     void BufferSymbolAndStringTable();
248     void CalculateRelocations(MachOSection &MOS);
249
250     MachineRelocation GetJTRelocation(unsigned Offset,
251                                       MachineBasicBlock *MBB) const {
252       return TM.getMachOWriterInfo()->GetJTRelocation(Offset, MBB);
253     }
254
255     /// GetTargetRelocation - Returns the number of relocations.
256     unsigned GetTargetRelocation(MachineRelocation &MR,
257                                  unsigned FromIdx,
258                                  unsigned ToAddr,
259                                  unsigned ToIndex,
260                                  OutputBuffer &RelocOut,
261                                  OutputBuffer &SecOut,
262                                  bool Scattered,
263                                  bool Extern) {
264       return TM.getMachOWriterInfo()->GetTargetRelocation(MR, FromIdx, ToAddr,
265                                                           ToIndex, RelocOut,
266                                                           SecOut, Scattered,
267                                                           Extern);
268     }
269   };
270 }
271
272 #endif