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
15using namespace mcld;
16
17ELFFileFormat::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
67void 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