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