1//===- LDFileFormat.h -----------------------------------------------------===//
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#ifndef MCLD_ELF_FILE_FORMAT_H
10#define MCLD_ELF_FILE_FORMAT_H
11#ifdef ENABLE_UNITTEST
12#include <gtest.h>
13#endif
14#include <mcld/LD/LDFileFormat.h>
15#include <mcld/LD/LDSection.h>
16
17namespace mcld
18{
19
20class GNULDBackend;
21class MCLinker;
22
23/** \class ELFFileFormat
24 *  \brief ELFFileFormat describes the common file formats in ELF.
25 *  LDFileFormats control the formats of the output file.
26 *
27 *  @ref "Object Files," Ch. 4, in System V Application Binary Interface,
28 *  Fourth Edition.
29 *
30 *  @ref "Object Format," Ch. 10, in ISO/IEC 23360 Part 1:2010(E), Linux
31 *  Standard Base Core Specification 4.1.
32 */
33class ELFFileFormat : public LDFileFormat
34{
35public:
36  ELFFileFormat(GNULDBackend& pBackend);
37
38  virtual ~ELFFileFormat();
39
40  virtual void initObjectFormat(MCLinker& pLinker);
41
42  virtual void initObjectType(MCLinker& pLinker) = 0;
43
44  // -----  capacity  ----- //
45  /// @ref Special Sections, Ch. 4.17, System V ABI, 4th edition.
46  bool hasNULLSection() const
47  { return (NULL != f_pNULLSection) && (0 != f_pNULLSection->size()); }
48
49  bool hasGOT() const
50  { return (NULL != f_pGOT) && (0 != f_pGOT->size()); }
51
52  bool hasPLT() const
53  { return (NULL != f_pPLT) && (0 != f_pPLT->size()); }
54
55  bool hasRelDyn() const
56  { return (NULL != f_pRelDyn) && (0 != f_pRelDyn->size()); }
57
58  bool hasRelPlt() const
59  { return (NULL != f_pRelPlt) && (0 != f_pRelPlt->size()); }
60
61  bool hasRelaDyn() const
62  { return (NULL != f_pRelaDyn) && (0 != f_pRelaDyn->size()); }
63
64  bool hasRelaPlt() const
65  { return (NULL != f_pRelaPlt) && (0 != f_pRelaPlt->size()); }
66
67  /// @ref 10.3.1.1, ISO/IEC 23360, Part 1:2010(E), p. 21.
68  bool hasComment() const
69  { return (NULL != f_pComment) && (0 != f_pComment->size()); }
70
71  bool hasData1() const
72  { return (NULL != f_pData1) && (0 != f_pData1->size()); }
73
74  bool hasDebug() const
75  { return (NULL != f_pDebug) && (0 != f_pDebug->size()); }
76
77  bool hasDynamic() const
78  { return (NULL != f_pDynamic) && (0 != f_pDynamic->size()); }
79
80  bool hasDynStrTab() const
81  { return (NULL != f_pDynStrTab) && (0 != f_pDynStrTab->size()); }
82
83  bool hasDynSymTab() const
84  { return (NULL != f_pDynSymTab) && (0 != f_pDynSymTab->size()); }
85
86  bool hasFini() const
87  { return (NULL != f_pFini) && (0 != f_pFini->size()); }
88
89  bool hasFiniArray() const
90  { return (NULL != f_pFiniArray) && (0 != f_pFiniArray->size()); }
91
92  bool hasHashTab() const
93  { return (NULL != f_pHashTab) && (0 != f_pHashTab->size()); }
94
95  bool hasInit() const
96  { return (NULL != f_pInit) && (0 != f_pInit->size()); }
97
98  bool hasInitArray() const
99  { return (NULL != f_pInitArray) && (0 != f_pInitArray->size()); }
100
101  bool hasInterp() const
102  { return (NULL != f_pInterp) && (0 != f_pInterp->size()); }
103
104  bool hasLine() const
105  { return (NULL != f_pLine) && (0 != f_pLine->size()); }
106
107  bool hasNote() const
108  { return (NULL != f_pNote) && (0 != f_pNote->size()); }
109
110  bool hasPreInitArray() const
111  { return (NULL != f_pPreInitArray) && (0 != f_pPreInitArray->size()); }
112
113  bool hasROData1() const
114  { return (NULL != f_pROData1) && (0 != f_pROData1->size()); }
115
116  bool hasShStrTab() const
117  { return (NULL != f_pShStrTab) && (0 != f_pShStrTab->size()); }
118
119  bool hasStrTab() const
120  { return (NULL != f_pStrTab) && (0 != f_pStrTab->size()); }
121
122  bool hasSymTab() const
123  { return (NULL != f_pSymTab) && (0 != f_pSymTab->size()); }
124
125  bool hasTBSS() const
126  { return (NULL != f_pTBSS) && (0 != f_pTBSS->size()); }
127
128  bool hasTData() const
129  { return (NULL != f_pTData) && (0 != f_pTData->size()); }
130
131  /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24.
132  bool hasCtors() const
133  { return (NULL != f_pCtors) && (0 != f_pCtors->size()); }
134
135  bool hasDataRelRo() const
136  { return (NULL != f_pDataRelRo) && (0 != f_pDataRelRo->size()); }
137
138  bool hasDtors() const
139  { return (NULL != f_pDtors) && (0 != f_pDtors->size()); }
140
141  bool hasEhFrame() const
142  { return (NULL != f_pEhFrame) && (0 != f_pEhFrame->size()); }
143
144  bool hasEhFrameHdr() const
145  { return (NULL != f_pEhFrameHdr) && (0 != f_pEhFrameHdr->size()); }
146
147  bool hasGCCExceptTable() const
148  { return (NULL != f_pGCCExceptTable) && (0 != f_pGCCExceptTable->size()); }
149
150  bool hasGNUVersion() const
151  { return (NULL != f_pGNUVersion) && (0 != f_pGNUVersion->size()); }
152
153  bool hasGNUVersionD() const
154  { return (NULL != f_pGNUVersionD) && (0 != f_pGNUVersionD->size()); }
155
156  bool hasGNUVersionR() const
157  { return (NULL != f_pGNUVersionR) && (0 != f_pGNUVersionR->size()); }
158
159  bool hasGOTPLT() const
160  { return (NULL != f_pGOTPLT) && (0 != f_pGOTPLT->size()); }
161
162  bool hasJCR() const
163  { return (NULL != f_pJCR) && (0 != f_pJCR->size()); }
164
165  bool hasNoteABITag() const
166  { return (NULL != f_pNoteABITag) && (0 != f_pNoteABITag->size()); }
167
168  bool hasStab() const
169  { return (NULL != f_pStab) && (0 != f_pStab->size()); }
170
171  bool hasStabStr() const
172  { return (NULL != f_pStabStr) && (0 != f_pStabStr->size()); }
173
174  bool hasStack() const
175  { return (NULL != f_pStack) && (0 != f_pStack->size()); }
176
177  // -----  access functions  ----- //
178  /// @ref Special Sections, Ch. 4.17, System V ABI, 4th edition.
179  LDSection& getNULLSection() {
180    assert(NULL != f_pNULLSection);
181    return *f_pNULLSection;
182  }
183
184  const LDSection& getNULLSection() const {
185    assert(NULL != f_pNULLSection);
186    return *f_pNULLSection;
187  }
188
189  LDSection& getGOT() {
190    assert(NULL != f_pGOT);
191    return *f_pGOT;
192  }
193
194  const LDSection& getGOT() const {
195    assert(NULL != f_pGOT);
196    return *f_pGOT;
197  }
198
199  LDSection& getPLT() {
200    assert(NULL != f_pPLT);
201    return *f_pPLT;
202  }
203
204  const LDSection& getPLT() const {
205    assert(NULL != f_pPLT);
206    return *f_pPLT;
207  }
208
209  LDSection& getRelDyn() {
210    assert(NULL != f_pRelDyn);
211    return *f_pRelDyn;
212  }
213
214  const LDSection& getRelDyn() const {
215    assert(NULL != f_pRelDyn);
216    return *f_pRelDyn;
217  }
218
219  LDSection& getRelPlt() {
220    assert(NULL != f_pRelPlt);
221    return *f_pRelPlt;
222  }
223
224  const LDSection& getRelPlt() const {
225    assert(NULL != f_pRelPlt);
226    return *f_pRelPlt;
227  }
228
229  LDSection& getRelaDyn() {
230    assert(NULL != f_pRelaDyn);
231    return *f_pRelaDyn;
232  }
233
234  const LDSection& getRelaDyn() const {
235    assert(NULL != f_pRelaDyn);
236    return *f_pRelaDyn;
237  }
238
239  LDSection& getRelaPlt() {
240    assert(NULL != f_pRelaPlt);
241    return *f_pRelaPlt;
242  }
243
244  const LDSection& getRelaPlt() const {
245    assert(NULL != f_pRelaPlt);
246    return *f_pRelaPlt;
247  }
248
249  LDSection& getComment() {
250    assert(NULL != f_pComment);
251    return *f_pComment;
252  }
253
254  /// @ref 10.3.1.1, ISO/IEC 23360, Part 1:2010(E), p. 21.
255  const LDSection& getComment() const {
256    assert(NULL != f_pComment);
257    return *f_pComment;
258  }
259
260  LDSection& getData1() {
261    assert(NULL != f_pData1);
262    return *f_pData1;
263  }
264
265  const LDSection& getData1() const {
266    assert(NULL != f_pData1);
267    return *f_pData1;
268  }
269
270  LDSection& getDebug() {
271    assert(NULL != f_pDebug);
272    return *f_pDebug;
273  }
274
275  const LDSection& getDebug() const {
276    assert(NULL != f_pDebug);
277    return *f_pDebug;
278  }
279
280  LDSection& getDynamic() {
281    assert(NULL != f_pDynamic);
282    return *f_pDynamic;
283  }
284
285  const LDSection& getDynamic() const {
286    assert(NULL != f_pDynamic);
287    return *f_pDynamic;
288  }
289
290  LDSection& getDynStrTab() {
291    assert(NULL != f_pDynStrTab);
292    return *f_pDynStrTab;
293  }
294
295  const LDSection& getDynStrTab() const {
296    assert(NULL != f_pDynStrTab);
297    return *f_pDynStrTab;
298  }
299
300  LDSection& getDynSymTab() {
301    assert(NULL != f_pDynSymTab);
302    return *f_pDynSymTab;
303  }
304
305  const LDSection& getDynSymTab() const {
306    assert(NULL != f_pDynSymTab);
307    return *f_pDynSymTab;
308  }
309
310  LDSection& getFini() {
311    assert(NULL != f_pFini);
312    return *f_pFini;
313  }
314
315  const LDSection& getFini() const {
316    assert(NULL != f_pFini);
317    return *f_pFini;
318  }
319
320  LDSection& getFiniArray() {
321    assert(NULL != f_pFiniArray);
322    return *f_pFiniArray;
323  }
324
325  const LDSection& getFiniArray() const {
326    assert(NULL != f_pFiniArray);
327    return *f_pFiniArray;
328  }
329
330  LDSection& getHashTab() {
331    assert(NULL != f_pHashTab);
332    return *f_pHashTab;
333  }
334
335  const LDSection& getHashTab() const {
336    assert(NULL != f_pHashTab);
337    return *f_pHashTab;
338  }
339
340  LDSection& getInit() {
341    assert(NULL != f_pInit);
342    return *f_pInit;
343  }
344
345  const LDSection& getInit() const {
346    assert(NULL != f_pInit);
347    return *f_pInit;
348  }
349
350  LDSection& getInitArray() {
351    assert(NULL != f_pInitArray);
352    return *f_pInitArray;
353  }
354
355  const LDSection& getInitArray() const {
356    assert(NULL != f_pInitArray);
357    return *f_pInitArray;
358  }
359
360  LDSection& getInterp() {
361    assert(NULL != f_pInterp);
362    return *f_pInterp;
363  }
364
365  const LDSection& getInterp() const {
366    assert(NULL != f_pInterp);
367    return *f_pInterp;
368  }
369
370  LDSection& getLine() {
371    assert(NULL != f_pLine);
372    return *f_pLine;
373  }
374
375  const LDSection& getLine() const {
376    assert(NULL != f_pLine);
377    return *f_pLine;
378  }
379
380  LDSection& getNote() {
381    assert(NULL != f_pNote);
382    return *f_pNote;
383  }
384
385  const LDSection& getNote() const {
386    assert(NULL != f_pNote);
387    return *f_pNote;
388  }
389
390  LDSection& getPreInitArray() {
391    assert(NULL != f_pPreInitArray);
392    return *f_pPreInitArray;
393  }
394
395  const LDSection& getPreInitArray() const {
396    assert(NULL != f_pPreInitArray);
397    return *f_pPreInitArray;
398  }
399
400  LDSection& getROData1() {
401    assert(NULL != f_pROData1);
402    return *f_pROData1;
403  }
404
405  const LDSection& getROData1() const {
406    assert(NULL != f_pROData1);
407    return *f_pROData1;
408  }
409
410  LDSection& getShStrTab() {
411    assert(NULL != f_pShStrTab);
412    return *f_pShStrTab;
413  }
414
415  const LDSection& getShStrTab() const {
416    assert(NULL != f_pShStrTab);
417    return *f_pShStrTab;
418  }
419
420  LDSection& getStrTab() {
421    assert(NULL != f_pStrTab);
422    return *f_pStrTab;
423  }
424
425  const LDSection& getStrTab() const {
426    assert(NULL != f_pStrTab);
427    return *f_pStrTab;
428  }
429
430  LDSection& getSymTab() {
431    assert(NULL != f_pSymTab);
432    return *f_pSymTab;
433  }
434
435  const LDSection& getSymTab() const {
436    assert(NULL != f_pSymTab);
437    return *f_pSymTab;
438  }
439
440  LDSection& getTBSS() {
441    assert(NULL != f_pTBSS);
442    return *f_pTBSS;
443  }
444
445  const LDSection& getTBSS() const {
446    assert(NULL != f_pTBSS);
447    return *f_pTBSS;
448  }
449
450  LDSection& getTData() {
451    assert(NULL != f_pTData);
452    return *f_pTData;
453  }
454
455  const LDSection& getTData() const {
456    assert(NULL != f_pTData);
457    return *f_pTData;
458  }
459
460  /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24.
461  LDSection& getCtors() {
462    assert(NULL != f_pCtors);
463    return *f_pCtors;
464  }
465
466  const LDSection& getCtors() const {
467    assert(NULL != f_pCtors);
468    return *f_pCtors;
469  }
470
471  LDSection& getDataRelRo() {
472    assert(NULL != f_pDataRelRo);
473    return *f_pDataRelRo;
474  }
475
476  const LDSection& getDataRelRo() const {
477    assert(NULL != f_pDataRelRo);
478    return *f_pDataRelRo;
479  }
480
481  LDSection& getDtors() {
482    assert(NULL != f_pDtors);
483    return *f_pDtors;
484  }
485
486  const LDSection& getDtors() const {
487    assert(NULL != f_pDtors);
488    return *f_pDtors;
489  }
490
491  LDSection& getEhFrame() {
492    assert(NULL != f_pEhFrame);
493    return *f_pEhFrame;
494  }
495
496  const LDSection& getEhFrame() const {
497    assert(NULL != f_pEhFrame);
498    return *f_pEhFrame;
499  }
500
501  LDSection& getEhFrameHdr() {
502    assert(NULL != f_pEhFrameHdr);
503    return *f_pEhFrameHdr;
504  }
505
506  const LDSection& getEhFrameHdr() const {
507    assert(NULL != f_pEhFrameHdr);
508    return *f_pEhFrameHdr;
509  }
510
511  LDSection& getGCCExceptTable() {
512    assert(NULL != f_pGCCExceptTable);
513    return *f_pGCCExceptTable;
514  }
515
516  const LDSection& getGCCExceptTable() const {
517    assert(NULL != f_pGCCExceptTable);
518    return *f_pGCCExceptTable;
519  }
520
521  LDSection& getGNUVersion() {
522    assert(NULL != f_pGNUVersion);
523    return *f_pGNUVersion;
524  }
525
526  const LDSection& getGNUVersion() const {
527    assert(NULL != f_pGNUVersion);
528    return *f_pGNUVersion;
529  }
530
531  LDSection& getGNUVersionD() {
532    assert(NULL != f_pGNUVersionD);
533    return *f_pGNUVersionD;
534  }
535
536  const LDSection& getGNUVersionD() const {
537    assert(NULL != f_pGNUVersionD);
538    return *f_pGNUVersionD;
539  }
540
541  LDSection& getGNUVersionR() {
542    assert(NULL != f_pGNUVersionR);
543    return *f_pGNUVersionR;
544  }
545
546  const LDSection& getGNUVersionR() const {
547    assert(NULL != f_pGNUVersionR);
548    return *f_pGNUVersionR;
549  }
550
551  LDSection& getGOTPLT() {
552    assert(NULL != f_pGOTPLT);
553    return *f_pGOTPLT;
554  }
555
556  const LDSection& getGOTPLT() const {
557    assert(NULL != f_pGOTPLT);
558    return *f_pGOTPLT;
559  }
560
561  LDSection& getJCR() {
562    assert(NULL != f_pJCR);
563    return *f_pJCR;
564  }
565
566  const LDSection& getJCR() const {
567    assert(NULL != f_pJCR);
568    return *f_pJCR;
569  }
570
571  LDSection& getNoteABITag() {
572    assert(NULL != f_pNoteABITag);
573    return *f_pNoteABITag;
574  }
575
576  const LDSection& getNoteABITag() const {
577    assert(NULL != f_pNoteABITag);
578    return *f_pNoteABITag;
579  }
580
581  LDSection& getStab() {
582    assert(NULL != f_pStab);
583    return *f_pStab;
584  }
585
586  const LDSection& getStab() const {
587    assert(NULL != f_pStab);
588    return *f_pStab;
589  }
590
591  LDSection& getStabStr() {
592    assert(NULL != f_pStabStr);
593    return *f_pStabStr;
594  }
595
596  const LDSection& getStabStr() const {
597    assert(NULL != f_pStabStr);
598    return *f_pStabStr;
599  }
600
601  LDSection& getStack() {
602    assert(NULL != f_pStack);
603    return *f_pStack;
604  }
605
606  const LDSection& getStack() const {
607    assert(NULL != f_pStack);
608    return *f_pStack;
609  }
610protected:
611  GNULDBackend& f_Backend;
612
613  //         variable name         :  ELF
614  /// @ref Special Sections, Ch. 4.17, System V ABI, 4th edition.
615  LDSection* f_pNULLSection;
616  LDSection* f_pGOT;               // .got
617  LDSection* f_pPLT;               // .plt
618  LDSection* f_pRelDyn;            // .rel.dyn
619  LDSection* f_pRelPlt;            // .rel.plt
620  LDSection* f_pRelaDyn;           // .rela.dyn
621  LDSection* f_pRelaPlt;           // .rela.plt
622
623  /// @ref 10.3.1.1, ISO/IEC 23360, Part 1:2010(E), p. 21.
624  LDSection* f_pComment;           // .comment
625  LDSection* f_pData1;             // .data1
626  LDSection* f_pDebug;             // .debug
627  LDSection* f_pDynamic;           // .dynamic
628  LDSection* f_pDynStrTab;         // .dynstr
629  LDSection* f_pDynSymTab;         // .dynsym
630  LDSection* f_pFini;              // .fini
631  LDSection* f_pFiniArray;         // .fini_array
632  LDSection* f_pHashTab;           // .hash
633  LDSection* f_pInit;              // .init
634  LDSection* f_pInitArray;         // .init_array
635  LDSection* f_pInterp;            // .interp
636  LDSection* f_pLine;              // .line
637  LDSection* f_pNote;              // .note
638  LDSection* f_pPreInitArray;      // .preinit_array
639  LDSection* f_pROData1;           // .rodata1
640  LDSection* f_pShStrTab;          // .shstrtab
641  LDSection* f_pStrTab;            // .strtab
642  LDSection* f_pSymTab;            // .symtab
643  LDSection* f_pTBSS;              // .tbss
644  LDSection* f_pTData;             // .tdata
645
646  /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24.
647  LDSection* f_pCtors;             // .ctors
648  LDSection* f_pDataRelRo;         // .data.rel.ro
649  LDSection* f_pDtors;             // .dtors
650  LDSection* f_pEhFrame;           // .eh_frame
651  LDSection* f_pEhFrameHdr;        // .eh_frame_hdr
652  LDSection* f_pGCCExceptTable;    // .gcc_except_table
653  LDSection* f_pGNUVersion;        // .gnu.version
654  LDSection* f_pGNUVersionD;       // .gnu.version_d
655  LDSection* f_pGNUVersionR;       // .gnu.version_r
656  LDSection* f_pGOTPLT;            // .got.plt
657  LDSection* f_pJCR;               // .jcr
658  LDSection* f_pNoteABITag;        // .note.ABI-tag
659  LDSection* f_pStab;              // .stab
660  LDSection* f_pStabStr;           // .stabstr
661
662  /// practical
663  LDSection* f_pStack;             // .stack
664};
665
666} // namespace of mcld
667
668#endif
669
670