Add more methods to gather target specific elf stuff
[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 "llvm/Support/Debug.h"
20 #include "llvm/Target/TargetAsmInfo.h"
21 #include "llvm/Target/TargetELFWriterInfo.h"
22 #include "ELF.h"
23 #include <list>
24 #include <map>
25
26 namespace llvm {
27   class BinaryObject;
28   class ConstantStruct;
29   class ELFCodeEmitter;
30   class GlobalVariable;
31   class Mangler;
32   class MachineCodeEmitter;
33   class raw_ostream;
34
35   /// ELFWriter - This class implements the common target-independent code for
36   /// writing ELF files.  Targets should derive a class from this to
37   /// parameterize the output format.
38   ///
39   class ELFWriter : public MachineFunctionPass {
40     friend class ELFCodeEmitter;
41   public:
42     static char ID;
43
44     MachineCodeEmitter &getMachineCodeEmitter() const {
45       return *(MachineCodeEmitter*)MCE;
46     }
47
48     ELFWriter(raw_ostream &O, TargetMachine &TM);
49     ~ELFWriter();
50
51     typedef std::vector<unsigned char> DataBuffer;
52
53   protected:
54     /// Output stream to send the resultant object file to.
55     raw_ostream &O;
56
57     /// Target machine description.
58     TargetMachine &TM;
59
60     /// Target Elf Writer description.
61     const TargetELFWriterInfo *TEW;
62
63     /// Mang - The object used to perform name mangling for this module.
64     Mangler *Mang;
65
66     /// MCE - The MachineCodeEmitter object that we are exposing to emit machine
67     /// code for functions to the .o file.
68     ELFCodeEmitter *MCE;
69
70     /// TAI - Target Asm Info, provide information about section names for
71     /// globals and other target specific stuff.
72     const TargetAsmInfo *TAI;
73
74     //===------------------------------------------------------------------===//
75     // Properties inferred automatically from the target machine.
76     //===------------------------------------------------------------------===//
77
78     /// is64Bit/isLittleEndian - This information is inferred from the target
79     /// machine directly, indicating whether to emit a 32- or 64-bit ELF file.
80     bool is64Bit, isLittleEndian;
81
82     /// doInitialization - Emit the file header and all of the global variables
83     /// for the module to the ELF file.
84     bool doInitialization(Module &M);
85     bool runOnMachineFunction(MachineFunction &MF);
86
87     /// doFinalization - Now that the module has been completely processed, emit
88     /// the ELF file to 'O'.
89     bool doFinalization(Module &M);
90
91   private:
92     /// Blob containing the Elf header
93     BinaryObject ElfHdr;
94
95     /// SectionList - This is the list of sections that we have emitted to the
96     /// file.  Once the file has been completely built, the section header table
97     /// is constructed from this info.
98     std::list<ELFSection> SectionList;
99     unsigned NumSections;   // Always = SectionList.size()
100
101     /// SectionLookup - This is a mapping from section name to section number in
102     /// the SectionList.
103     std::map<std::string, ELFSection*> SectionLookup;
104
105     /// GblSymLookup - This is a mapping from global value to a symbol index
106     /// in the symbol table. This is useful since relocations symbol references
107     /// must be quickly mapped to a symbol table index
108     std::map<const GlobalValue*, uint32_t> GblSymLookup;
109
110     /// SymbolList - This is the list of symbols emitted to the symbol table
111     /// Local symbols go to the front and Globals to the back.
112     std::list<ELFSym> SymbolList;
113
114     /// PendingGlobals - List of externally defined symbols that we have been
115     /// asked to emit, but have not seen a reference to.  When a reference
116     /// is seen, the symbol will move from this list to the SymbolList.
117     SetVector<GlobalValue*> PendingGlobals;
118
119     /// getSection - Return the section with the specified name, creating a new
120     /// section if one does not already exist.
121     ELFSection &getSection(const std::string &Name, unsigned Type,
122                            unsigned Flags = 0, unsigned Align = 0) {
123       ELFSection *&SN = SectionLookup[Name];
124       if (SN) return *SN;
125
126       // Remove tab from section name prefix. This is necessary becase TAI 
127       // sometimes return a section name prefixed with a "\t" char.
128       std::string SectionName(Name);
129       size_t Pos = SectionName.find("\t");
130       if (Pos != std::string::npos)
131         SectionName.erase(Pos, 1);
132
133       SectionList.push_back(ELFSection(SectionName, isLittleEndian, is64Bit));
134       SN = &SectionList.back();
135       SN->SectionIdx = NumSections++;
136       SN->Type = Type;
137       SN->Flags = Flags;
138       SN->Link = ELFSection::SHN_UNDEF;
139       SN->Align = Align;
140       return *SN;
141     }
142
143     /// TODO: support mangled names here to emit the right .text section
144     /// for c++ object files.
145     ELFSection &getTextSection() {
146       return getSection(".text", ELFSection::SHT_PROGBITS,
147                         ELFSection::SHF_EXECINSTR | ELFSection::SHF_ALLOC);
148     }
149
150     /// Return the relocation section of section 'S'. 'RelA' is true
151     /// if the relocation section contains entries with addends.
152     ELFSection &getRelocSection(std::string SName, bool RelA) {
153       std::string RelSName(".rel");
154       unsigned SHdrTy = RelA ? ELFSection::SHT_RELA : ELFSection::SHT_REL;
155
156       if (RelA) RelSName.append("a");
157       RelSName.append(SName);
158
159       return getSection(RelSName, SHdrTy, 0, TEW->getPrefELFAlignment());
160     }
161
162     ELFSection &getNonExecStackSection() {
163       return getSection(".note.GNU-stack", ELFSection::SHT_PROGBITS, 0, 1);
164     }
165
166     ELFSection &getSymbolTableSection() {
167       return getSection(".symtab", ELFSection::SHT_SYMTAB, 0);
168     }
169
170     ELFSection &getStringTableSection() {
171       return getSection(".strtab", ELFSection::SHT_STRTAB, 0, 1);
172     }
173
174     ELFSection &getDataSection() {
175       return getSection(".data", ELFSection::SHT_PROGBITS,
176                         ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC);
177     }
178
179     ELFSection &getBSSSection() {
180       return getSection(".bss", ELFSection::SHT_NOBITS,
181                         ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC);
182     }
183
184     ELFSection &getNullSection() {
185       return getSection("", ELFSection::SHT_NULL, 0);
186     }
187
188     // As we complete the ELF file, we need to update fields in the ELF header
189     // (e.g. the location of the section table).  These members keep track of
190     // the offset in ELFHeader of these various pieces to update and other
191     // locations in the file.
192     unsigned ELFHdr_e_shoff_Offset;     // e_shoff    in ELF header.
193     unsigned ELFHdr_e_shstrndx_Offset;  // e_shstrndx in ELF header.
194     unsigned ELFHdr_e_shnum_Offset;     // e_shnum    in ELF header.
195
196   private:
197     void EmitFunctionDeclaration(const Function *F);
198     void EmitGlobalVar(const GlobalVariable *GV);
199     void EmitGlobalConstant(const Constant *C, ELFSection &GblS);
200     void EmitGlobalConstantStruct(const ConstantStruct *CVS,
201                                   ELFSection &GblS);
202     unsigned getGlobalELFLinkage(const GlobalVariable *GV);
203     ELFSection &getGlobalSymELFSection(const GlobalVariable *GV, ELFSym &Sym);
204     void EmitRelocations();
205     void EmitRelocation(BinaryObject &RelSec, ELFRelocation &Rel, bool HasRelA);
206     void EmitSectionHeader(BinaryObject &SHdrTab, const ELFSection &SHdr);
207     void EmitSectionTableStringTable();
208     void EmitSymbol(BinaryObject &SymbolTable, ELFSym &Sym);
209     void EmitSymbolTable();
210     void OutputSectionsAndSectionTable();
211   };
212 }
213
214 #endif