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