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
15namespace 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
66void ELFFileFormat::initStdSections(ObjectBuilder& pBuilder,
67                                    unsigned int pBitClass) {
68  f_pTextSection =
69      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 =
75      pBuilder.CreateSection("", LDFileFormat::Null, llvm::ELF::SHT_NULL, 0x0);
76  f_pReadOnlySection = pBuilder.CreateSection(".rodata",
77                                              LDFileFormat::TEXT,
78                                              llvm::ELF::SHT_PROGBITS,
79                                              llvm::ELF::SHF_ALLOC,
80                                              0x1);
81
82  f_pBSSSection =
83      pBuilder.CreateSection(".bss",
84                             LDFileFormat::BSS,
85                             llvm::ELF::SHT_NOBITS,
86                             llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
87                             0x1);
88  f_pComment = pBuilder.CreateSection(
89      ".comment", LDFileFormat::MetaData, llvm::ELF::SHT_PROGBITS, 0x0, 0x1);
90  f_pDataSection =
91      pBuilder.CreateSection(".data",
92                             LDFileFormat::DATA,
93                             llvm::ELF::SHT_PROGBITS,
94                             llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
95                             0x1);
96  f_pData1 = pBuilder.CreateSection(".data1",
97                                    LDFileFormat::DATA,
98                                    llvm::ELF::SHT_PROGBITS,
99                                    llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
100                                    0x1);
101  f_pDebug = pBuilder.CreateSection(
102      ".debug", LDFileFormat::Debug, llvm::ELF::SHT_PROGBITS, 0x0, 0x1);
103  f_pInit =
104      pBuilder.CreateSection(".init",
105                             LDFileFormat::TEXT,
106                             llvm::ELF::SHT_PROGBITS,
107                             llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
108                             0x1);
109  f_pInitArray =
110      pBuilder.CreateSection(".init_array",
111                             LDFileFormat::DATA,
112                             llvm::ELF::SHT_INIT_ARRAY,
113                             llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
114                             0x1);
115  f_pFini =
116      pBuilder.CreateSection(".fini",
117                             LDFileFormat::TEXT,
118                             llvm::ELF::SHT_PROGBITS,
119                             llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
120                             0x1);
121  f_pFiniArray =
122      pBuilder.CreateSection(".fini_array",
123                             LDFileFormat::DATA,
124                             llvm::ELF::SHT_FINI_ARRAY,
125                             llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
126                             0x1);
127  f_pLine = pBuilder.CreateSection(
128      ".line", LDFileFormat::Debug, llvm::ELF::SHT_PROGBITS, 0x0, 0x1);
129  f_pPreInitArray =
130      pBuilder.CreateSection(".preinit_array",
131                             LDFileFormat::DATA,
132                             llvm::ELF::SHT_PREINIT_ARRAY,
133                             llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
134                             0x1);
135  // the definition of SHF_XXX attributes of rodata in Linux Standard Base
136  // conflicts with System V standard. We follow System V standard.
137  f_pROData1 = pBuilder.CreateSection(".rodata1",
138                                      LDFileFormat::TEXT,
139                                      llvm::ELF::SHT_PROGBITS,
140                                      llvm::ELF::SHF_ALLOC,
141                                      0x1);
142  f_pShStrTab = pBuilder.CreateSection(
143      ".shstrtab", LDFileFormat::NamePool, llvm::ELF::SHT_STRTAB, 0x0, 0x1);
144  // In ELF Spec Book I, p1-16. If symbol table and string table are in
145  // loadable segments, set the attribute to SHF_ALLOC bit. But in the
146  // real world, this bit always turn off.
147  f_pSymTab = pBuilder.CreateSection(".symtab",
148                                     LDFileFormat::NamePool,
149                                     llvm::ELF::SHT_SYMTAB,
150                                     0x0,
151                                     pBitClass / 8);
152
153  f_pStrTab = pBuilder.CreateSection(
154      ".strtab", LDFileFormat::NamePool, llvm::ELF::SHT_STRTAB, 0x0, 0x1);
155  f_pTBSS = pBuilder.CreateSection(
156      ".tbss",
157      LDFileFormat::BSS,
158      llvm::ELF::SHT_NOBITS,
159      llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE | llvm::ELF::SHF_TLS,
160      0x1);
161  f_pTData = pBuilder.CreateSection(
162      ".tdata",
163      LDFileFormat::DATA,
164      llvm::ELF::SHT_PROGBITS,
165      llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE | llvm::ELF::SHF_TLS,
166      0x1);
167
168  /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24.
169  f_pCtors = pBuilder.CreateSection(".ctors",
170                                    LDFileFormat::DATA,
171                                    llvm::ELF::SHT_PROGBITS,
172                                    llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
173                                    0x1);
174  f_pDataRelRo =
175      pBuilder.CreateSection(".data.rel.ro",
176                             LDFileFormat::DATA,
177                             llvm::ELF::SHT_PROGBITS,
178                             llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
179                             0x1);
180  f_pDtors = pBuilder.CreateSection(".dtors",
181                                    LDFileFormat::DATA,
182                                    llvm::ELF::SHT_PROGBITS,
183                                    llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
184                                    0x1);
185  f_pEhFrame = pBuilder.CreateSection(".eh_frame",
186                                      LDFileFormat::EhFrame,
187                                      llvm::ELF::SHT_PROGBITS,
188                                      llvm::ELF::SHF_ALLOC,
189                                      0x4);
190  f_pGCCExceptTable = pBuilder.CreateSection(".gcc_except_table",
191                                             LDFileFormat::GCCExceptTable,
192                                             llvm::ELF::SHT_PROGBITS,
193                                             llvm::ELF::SHF_ALLOC,
194                                             0x4);
195  f_pGNUVersion = pBuilder.CreateSection(".gnu.version",
196                                         LDFileFormat::Version,
197                                         llvm::ELF::SHT_GNU_versym,
198                                         llvm::ELF::SHF_ALLOC,
199                                         0x1);
200  f_pGNUVersionD = pBuilder.CreateSection(".gnu.version_d",
201                                          LDFileFormat::Version,
202                                          llvm::ELF::SHT_GNU_verdef,
203                                          llvm::ELF::SHF_ALLOC,
204                                          0x1);
205  f_pGNUVersionR = pBuilder.CreateSection(".gnu.version_r",
206                                          LDFileFormat::Version,
207                                          llvm::ELF::SHT_GNU_verneed,
208                                          llvm::ELF::SHF_ALLOC,
209                                          0x1);
210  f_pJCR = pBuilder.CreateSection(".jcr",
211                                  LDFileFormat::DATA,
212                                  llvm::ELF::SHT_PROGBITS,
213                                  llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
214                                  0x1);
215  f_pStab = pBuilder.CreateSection(
216      ".stab", LDFileFormat::Debug, llvm::ELF::SHT_PROGBITS, 0x0, 0x1);
217  f_pStabStr = pBuilder.CreateSection(
218      ".stabstr", LDFileFormat::Debug, llvm::ELF::SHT_STRTAB, 0x0, 0x1);
219  f_pStackNote = pBuilder.CreateSection(".note.GNU-stack",
220                                        LDFileFormat::StackNote,
221                                        llvm::ELF::SHT_PROGBITS,
222                                        0x0,
223                                        0x1);
224
225  /// @ref GCC convention, see http://www.airs.com/blog/archives/189
226  f_pDataRelRoLocal =
227      pBuilder.CreateSection(".data.rel.ro.local",
228                             LDFileFormat::DATA,
229                             llvm::ELF::SHT_PROGBITS,
230                             llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
231                             0x1);
232  /// Initialize format dependent sections. (sections for executable and shared
233  /// objects)
234  initObjectFormat(pBuilder, pBitClass);
235}
236
237}  // namespace mcld
238