1 //===- ELFFileFormat.cpp --------------------------------------------------===//
2 //
3 //                     The MCLinker Project
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #include <mcld/LD/ELFFileFormat.h>
10 #include <mcld/Object/ObjectBuilder.h>
11 #include <mcld/Target/GNULDBackend.h>
12 
13 #include <llvm/Support/ELF.h>
14 
15 using namespace mcld;
16 
ELFFileFormat()17 ELFFileFormat::ELFFileFormat()
18   : f_pNULLSection(NULL),
19     f_pGOT(NULL),
20     f_pPLT(NULL),
21     f_pRelDyn(NULL),
22     f_pRelPlt(NULL),
23     f_pRelaDyn(NULL),
24     f_pRelaPlt(NULL),
25     f_pComment(NULL),
26     f_pData1(NULL),
27     f_pDebug(NULL),
28     f_pDynamic(NULL),
29     f_pDynStrTab(NULL),
30     f_pDynSymTab(NULL),
31     f_pFini(NULL),
32     f_pFiniArray(NULL),
33     f_pHashTab(NULL),
34     f_pInit(NULL),
35     f_pInitArray(NULL),
36     f_pInterp(NULL),
37     f_pLine(NULL),
38     f_pNote(NULL),
39     f_pPreInitArray(NULL),
40     f_pROData1(NULL),
41     f_pShStrTab(NULL),
42     f_pStrTab(NULL),
43     f_pSymTab(NULL),
44     f_pTBSS(NULL),
45     f_pTData(NULL),
46     f_pCtors(NULL),
47     f_pDataRelRo(NULL),
48     f_pDtors(NULL),
49     f_pEhFrame(NULL),
50     f_pEhFrameHdr(NULL),
51     f_pGCCExceptTable(NULL),
52     f_pGNUVersion(NULL),
53     f_pGNUVersionD(NULL),
54     f_pGNUVersionR(NULL),
55     f_pGOTPLT(NULL),
56     f_pJCR(NULL),
57     f_pNoteABITag(NULL),
58     f_pStab(NULL),
59     f_pStabStr(NULL),
60     f_pStack(NULL),
61     f_pStackNote(NULL),
62     f_pDataRelRoLocal(NULL),
63     f_pGNUHashTab(NULL) {
64 
65 }
66 
initStdSections(ObjectBuilder & pBuilder,unsigned int pBitClass)67 void ELFFileFormat::initStdSections(ObjectBuilder& pBuilder, unsigned int pBitClass)
68 {
69   f_pTextSection     = pBuilder.CreateSection(".text",
70                                               LDFileFormat::TEXT,
71                                               llvm::ELF::SHT_PROGBITS,
72                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
73                                               0x1);
74   f_pNULLSection     = pBuilder.CreateSection("",
75                                               LDFileFormat::Null,
76                                               llvm::ELF::SHT_NULL,
77                                               0x0);
78   f_pReadOnlySection = pBuilder.CreateSection(".rodata",
79                                               LDFileFormat::TEXT,
80                                               llvm::ELF::SHT_PROGBITS,
81                                               llvm::ELF::SHF_ALLOC,
82                                               0x1);
83 
84   f_pBSSSection      = pBuilder.CreateSection(".bss",
85                                               LDFileFormat::BSS,
86                                               llvm::ELF::SHT_NOBITS,
87                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
88                                               0x1);
89   f_pComment         = pBuilder.CreateSection(".comment",
90                                               LDFileFormat::MetaData,
91                                               llvm::ELF::SHT_PROGBITS,
92                                               0x0,
93                                               0x1);
94   f_pDataSection     = pBuilder.CreateSection(".data",
95                                               LDFileFormat::DATA,
96                                               llvm::ELF::SHT_PROGBITS,
97                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
98                                               0x1);
99   f_pData1           = pBuilder.CreateSection(".data1",
100                                               LDFileFormat::DATA,
101                                               llvm::ELF::SHT_PROGBITS,
102                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
103                                               0x1);
104   f_pDebug           = pBuilder.CreateSection(".debug",
105                                               LDFileFormat::Debug,
106                                               llvm::ELF::SHT_PROGBITS,
107                                               0x0,
108                                               0x1);
109   f_pInit            = pBuilder.CreateSection(".init",
110                                               LDFileFormat::TEXT,
111                                               llvm::ELF::SHT_PROGBITS,
112                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
113                                               0x1);
114   f_pInitArray       = pBuilder.CreateSection(".init_array",
115                                               LDFileFormat::DATA,
116                                               llvm::ELF::SHT_INIT_ARRAY,
117                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
118                                               0x1);
119   f_pFini            = pBuilder.CreateSection(".fini",
120                                               LDFileFormat::TEXT,
121                                               llvm::ELF::SHT_PROGBITS,
122                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
123                                               0x1);
124   f_pFiniArray       = pBuilder.CreateSection(".fini_array",
125                                               LDFileFormat::DATA,
126                                               llvm::ELF::SHT_FINI_ARRAY,
127                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
128                                               0x1);
129   f_pLine            = pBuilder.CreateSection(".line",
130                                               LDFileFormat::Debug,
131                                               llvm::ELF::SHT_PROGBITS,
132                                               0x0,
133                                               0x1);
134   f_pPreInitArray    = pBuilder.CreateSection(".preinit_array",
135                                               LDFileFormat::DATA,
136                                               llvm::ELF::SHT_PREINIT_ARRAY,
137                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
138                                               0x1);
139   // the definition of SHF_XXX attributes of rodata in Linux Standard Base
140   // conflicts with System V standard. We follow System V standard.
141   f_pROData1         = pBuilder.CreateSection(".rodata1",
142                                               LDFileFormat::TEXT,
143                                               llvm::ELF::SHT_PROGBITS,
144                                               llvm::ELF::SHF_ALLOC,
145                                               0x1);
146   f_pShStrTab        = pBuilder.CreateSection(".shstrtab",
147                                               LDFileFormat::NamePool,
148                                               llvm::ELF::SHT_STRTAB,
149                                               0x0,
150                                               0x1);
151   // In ELF Spec Book I, p1-16. If symbol table and string table are in
152   // loadable segments, set the attribute to SHF_ALLOC bit. But in the
153   // real world, this bit always turn off.
154   f_pSymTab          = pBuilder.CreateSection(".symtab",
155                                               LDFileFormat::NamePool,
156                                               llvm::ELF::SHT_SYMTAB,
157                                               0x0,
158                                               pBitClass / 8);
159 
160   f_pStrTab          = pBuilder.CreateSection(".strtab",
161                                               LDFileFormat::NamePool,
162                                               llvm::ELF::SHT_STRTAB,
163                                               0x0,
164                                               0x1);
165   f_pTBSS            = pBuilder.CreateSection(".tbss",
166                                               LDFileFormat::BSS,
167                                               llvm::ELF::SHT_NOBITS,
168                                               llvm::ELF::SHF_ALLOC |
169                                               llvm::ELF::SHF_WRITE |
170                                               llvm::ELF::SHF_TLS,
171                                               0x1);
172   f_pTData           = pBuilder.CreateSection(".tdata",
173                                               LDFileFormat::DATA,
174                                               llvm::ELF::SHT_PROGBITS,
175                                               llvm::ELF::SHF_ALLOC |
176                                               llvm::ELF::SHF_WRITE |
177                                               llvm::ELF::SHF_TLS,
178                                               0x1);
179 
180   /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24.
181   f_pCtors           = pBuilder.CreateSection(".ctors",
182                                               LDFileFormat::DATA,
183                                               llvm::ELF::SHT_PROGBITS,
184                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
185                                               0x1);
186   f_pDataRelRo       = pBuilder.CreateSection(".data.rel.ro",
187                                               LDFileFormat::DATA,
188                                               llvm::ELF::SHT_PROGBITS,
189                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
190                                               0x1);
191   f_pDtors           = pBuilder.CreateSection(".dtors",
192                                               LDFileFormat::DATA,
193                                               llvm::ELF::SHT_PROGBITS,
194                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
195                                               0x1);
196   f_pEhFrame         = pBuilder.CreateSection(".eh_frame",
197                                               LDFileFormat::EhFrame,
198                                               llvm::ELF::SHT_PROGBITS,
199                                               llvm::ELF::SHF_ALLOC,
200                                               0x4);
201   f_pGCCExceptTable  = pBuilder.CreateSection(".gcc_except_table",
202                                               LDFileFormat::GCCExceptTable,
203                                               llvm::ELF::SHT_PROGBITS,
204                                               llvm::ELF::SHF_ALLOC,
205                                               0x4);
206   f_pGNUVersion      = pBuilder.CreateSection(".gnu.version",
207                                               LDFileFormat::Version,
208                                               llvm::ELF::SHT_GNU_versym,
209                                               llvm::ELF::SHF_ALLOC,
210                                               0x1);
211   f_pGNUVersionD     = pBuilder.CreateSection(".gnu.version_d",
212                                               LDFileFormat::Version,
213                                               llvm::ELF::SHT_GNU_verdef,
214                                               llvm::ELF::SHF_ALLOC,
215                                               0x1);
216   f_pGNUVersionR     = pBuilder.CreateSection(".gnu.version_r",
217                                               LDFileFormat::Version,
218                                               llvm::ELF::SHT_GNU_verneed,
219                                               llvm::ELF::SHF_ALLOC,
220                                               0x1);
221   f_pJCR             = pBuilder.CreateSection(".jcr",
222                                               LDFileFormat::DATA,
223                                               llvm::ELF::SHT_PROGBITS,
224                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
225                                               0x1);
226   f_pStab            = pBuilder.CreateSection(".stab",
227                                               LDFileFormat::Debug,
228                                               llvm::ELF::SHT_PROGBITS,
229                                               0x0,
230                                               0x1);
231   f_pStabStr         = pBuilder.CreateSection(".stabstr",
232                                               LDFileFormat::Debug,
233                                               llvm::ELF::SHT_STRTAB,
234                                               0x0,
235                                               0x1);
236   f_pStackNote       = pBuilder.CreateSection(".note.GNU-stack",
237                                               LDFileFormat::StackNote,
238                                               llvm::ELF::SHT_PROGBITS,
239                                               0x0,
240                                               0x1);
241 
242   /// @ref GCC convention, see http://www.airs.com/blog/archives/189
243   f_pDataRelRoLocal  = pBuilder.CreateSection(".data.rel.ro.local",
244                                               LDFileFormat::DATA,
245                                               llvm::ELF::SHT_PROGBITS,
246                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
247                                               0x1);
248   /// Initialize format dependent sections. (sections for executable and shared
249   /// objects)
250   initObjectFormat(pBuilder, pBitClass);
251 }
252 
253