Use a range insert instead of an explicit loop.
[oota-llvm.git] / lib / CodeGen / ELFWriter.h
1 //===-- ELFWriter.h - Target-independent ELF 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 ELFWriter class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef ELFWRITER_H
15 #define ELFWRITER_H
16
17 #include "llvm/ADT/SetVector.h"
18 #include "llvm/CodeGen/MachineFunctionPass.h"
19 #include <map>
20
21 namespace llvm {
22   class BinaryObject;
23   class Constant;
24   class ConstantStruct;
25   class ELFCodeEmitter;
26   class ELFRelocation;
27   class ELFSection;
28   struct ELFSym;
29   class GlobalVariable;
30   class Mangler;
31   class MachineCodeEmitter;
32   class MachineConstantPoolEntry;
33   class ObjectCodeEmitter;
34   class TargetAsmInfo;
35   class TargetELFWriterInfo;
36   class raw_ostream;
37   class SectionKind;
38   class MCContext;
39
40   typedef std::vector<ELFSym*>::iterator ELFSymIter;
41   typedef std::vector<ELFSection*>::iterator ELFSectionIter;
42   typedef SetVector<const GlobalValue*>::const_iterator PendingGblsIter;
43   typedef SetVector<const char *>::const_iterator PendingExtsIter;
44
45   /// ELFWriter - This class implements the common target-independent code for
46   /// writing ELF files.  Targets should derive a class from this to
47   /// parameterize the output format.
48   ///
49   class ELFWriter : public MachineFunctionPass {
50     friend class ELFCodeEmitter;
51   public:
52     static char ID;
53
54     /// Return the ELFCodeEmitter as an instance of ObjectCodeEmitter
55     ObjectCodeEmitter *getObjectCodeEmitter() {
56       return reinterpret_cast<ObjectCodeEmitter*>(ElfCE);
57     }
58
59     ELFWriter(raw_ostream &O, TargetMachine &TM);
60     ~ELFWriter();
61
62   protected:
63     /// Output stream to send the resultant object file to.
64     raw_ostream &O;
65
66     /// Target machine description.
67     TargetMachine &TM;
68
69     MCContext &OutContext;
70     
71     /// Target Elf Writer description.
72     const TargetELFWriterInfo *TEW;
73
74     /// Mang - The object used to perform name mangling for this module.
75     Mangler *Mang;
76
77     /// MCE - The MachineCodeEmitter object that we are exposing to emit machine
78     /// code for functions to the .o file.
79     ELFCodeEmitter *ElfCE;
80
81     /// TAI - Target Asm Info, provide information about section names for
82     /// globals and other target specific stuff.
83     const TargetAsmInfo *TAI;
84
85     //===------------------------------------------------------------------===//
86     // Properties inferred automatically from the target machine.
87     //===------------------------------------------------------------------===//
88
89     /// is64Bit/isLittleEndian - This information is inferred from the target
90     /// machine directly, indicating whether to emit a 32- or 64-bit ELF file.
91     bool is64Bit, isLittleEndian;
92
93     /// doInitialization - Emit the file header and all of the global variables
94     /// for the module to the ELF file.
95     bool doInitialization(Module &M);
96     bool runOnMachineFunction(MachineFunction &MF);
97
98     /// doFinalization - Now that the module has been completely processed, emit
99     /// the ELF file to 'O'.
100     bool doFinalization(Module &M);
101
102   private:
103     /// Blob containing the Elf header
104     BinaryObject ElfHdr;
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 section header table
108     /// is constructed from this info.
109     std::vector<ELFSection*> SectionList;
110     unsigned NumSections;   // Always = SectionList.size()
111
112     /// SectionLookup - This is a mapping from section name to section number in
113     /// the SectionList. Used to quickly gather the Section Index from TAI names
114     std::map<std::string, ELFSection*> SectionLookup;
115
116     /// PendingGlobals - Globals not processed as symbols yet.
117     SetVector<const GlobalValue*> PendingGlobals;
118
119     /// GblSymLookup - This is a mapping from global value to a symbol index
120     /// in the symbol table or private symbols list. This is useful since reloc
121     /// symbol references must be quickly mapped to their indices on the lists.
122     std::map<const GlobalValue*, uint32_t> GblSymLookup;
123
124     /// PendingExternals - Externals not processed as symbols yet.
125     SetVector<const char *> PendingExternals;
126
127     /// ExtSymLookup - This is a mapping from externals to a symbol index
128     /// in the symbol table list. This is useful since reloc symbol references
129     /// must be quickly mapped to their symbol table indices.
130     std::map<const char *, uint32_t> ExtSymLookup;
131
132     /// SymbolList - This is the list of symbols emitted to the symbol table.
133     /// When the SymbolList is finally built, local symbols must be placed in
134     /// the beginning while non-locals at the end.
135     std::vector<ELFSym*> SymbolList;
136
137     /// PrivateSyms - Record private symbols, every symbol here must never be
138     /// present in the SymbolList.
139     std::vector<ELFSym*> PrivateSyms;
140
141     // Remove tab from section name prefix. This is necessary becase TAI
142     // sometimes return a section name prefixed with elf unused chars. This is
143     // a little bit dirty. FIXME: find a better approach, maybe add more
144     // methods to TAI to get the clean name?
145     void fixNameForSection(std::string &Name) {
146       size_t Pos = Name.find("\t");
147       if (Pos != std::string::npos)
148         Name.erase(Pos, 1);
149
150       Pos = Name.find(".section ");
151       if (Pos != std::string::npos)
152         Name.erase(Pos, 9);
153
154       Pos = Name.find("\n");
155       if (Pos != std::string::npos)
156         Name.erase(Pos, 1);
157     }
158
159     /// getSection - Return the section with the specified name, creating a new
160     /// section if one does not already exist.
161     ELFSection &getSection(const std::string &Name, unsigned Type,
162                            unsigned Flags = 0, unsigned Align = 0) {
163       std::string SName(Name);
164       fixNameForSection(SName);
165
166       ELFSection *&SN = SectionLookup[SName];
167       if (SN) return *SN;
168
169       SectionList.push_back(new ELFSection(SName, isLittleEndian, is64Bit));
170       SN = SectionList.back();
171       SN->SectionIdx = NumSections++;
172       SN->Type = Type;
173       SN->Flags = Flags;
174       SN->Link = ELFSection::SHN_UNDEF;
175       SN->Align = Align;
176       return *SN;
177     }
178
179     /// TODO: support mangled names here to emit the right .text section
180     /// for c++ object files.
181     ELFSection &getTextSection() {
182       return getSection(".text", ELFSection::SHT_PROGBITS,
183                         ELFSection::SHF_EXECINSTR | ELFSection::SHF_ALLOC);
184     }
185
186     ELFSection &getNonExecStackSection() {
187       return getSection(".note.GNU-stack", ELFSection::SHT_PROGBITS, 0, 1);
188     }
189
190     ELFSection &getSymbolTableSection() {
191       return getSection(".symtab", ELFSection::SHT_SYMTAB, 0);
192     }
193
194     ELFSection &getStringTableSection() {
195       return getSection(".strtab", ELFSection::SHT_STRTAB, 0, 1);
196     }
197
198     ELFSection &getSectionHeaderStringTableSection() {
199       return getSection(".shstrtab", ELFSection::SHT_STRTAB, 0, 1);
200     }
201
202     ELFSection &getDataSection() {
203       return getSection(".data", ELFSection::SHT_PROGBITS,
204                         ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC, 4);
205     }
206
207     ELFSection &getBSSSection() {
208       return getSection(".bss", ELFSection::SHT_NOBITS,
209                         ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC, 4);
210     }
211
212     ELFSection &getNullSection() {
213       return getSection("", ELFSection::SHT_NULL, 0);
214     }
215
216     ELFSection &getJumpTableSection();
217     ELFSection &getConstantPoolSection(MachineConstantPoolEntry &CPE);
218     ELFSection &getRelocSection(ELFSection &S);
219
220     // Helpers for obtaining ELF specific info.
221     unsigned getGlobalELFBinding(const GlobalValue *GV);
222     unsigned getGlobalELFType(const GlobalValue *GV);
223     unsigned getGlobalELFVisibility(const GlobalValue *GV);
224     unsigned getElfSectionFlags(SectionKind Kind);
225
226     // addGlobalSymbol - Add a global to be processed and to the
227     // global symbol lookup, use a zero index for non private symbols
228     // because the table index will be determined later.
229     void addGlobalSymbol(const GlobalValue *GV);
230
231     // addExternalSymbol - Add the external to be processed and to the
232     // external symbol lookup, use a zero index because the symbol
233     // table index will be determined later
234     void addExternalSymbol(const char *External);
235
236     // As we complete the ELF file, we need to update fields in the ELF header
237     // (e.g. the location of the section table).  These members keep track of
238     // the offset in ELFHeader of these various pieces to update and other
239     // locations in the file.
240     unsigned ELFHdr_e_shoff_Offset;     // e_shoff    in ELF header.
241     unsigned ELFHdr_e_shstrndx_Offset;  // e_shstrndx in ELF header.
242     unsigned ELFHdr_e_shnum_Offset;     // e_shnum    in ELF header.
243
244   private:
245     void EmitGlobal(const GlobalValue *GV);
246     void EmitGlobalConstant(const Constant *C, ELFSection &GblS);
247     void EmitGlobalConstantStruct(const ConstantStruct *CVS,
248                                   ELFSection &GblS);
249     ELFSection &getGlobalSymELFSection(const GlobalVariable *GV, ELFSym &Sym);
250     void EmitRelocations();
251     void EmitRelocation(BinaryObject &RelSec, ELFRelocation &Rel, bool HasRelA);
252     void EmitSectionHeader(BinaryObject &SHdrTab, const ELFSection &SHdr);
253     void EmitSectionTableStringTable();
254     void EmitSymbol(BinaryObject &SymbolTable, ELFSym &Sym);
255     void EmitSymbolTable();
256     void EmitStringTable(const std::string &ModuleName);
257     void OutputSectionsAndSectionTable();
258     void RelocateField(BinaryObject &BO, uint32_t Offset, int64_t Value,
259                        unsigned Size);
260     unsigned SortSymbols();
261   };
262 }
263
264 #endif