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
19class ObjectBuilder;
20
21/** \class ELFFileFormat
22 *  \brief ELFFileFormat describes the common file formats in ELF.
23 *  LDFileFormats control the formats of the output file.
24 *
25 *  @ref "Object Files," Ch. 4, in System V Application Binary Interface,
26 *  Fourth Edition.
27 *
28 *  @ref "Object Format," Ch. 10, in ISO/IEC 23360 Part 1:2010(E), Linux
29 *  Standard Base Core Specification 4.1.
30 */
31class ELFFileFormat : public LDFileFormat
32{
33private:
34  /// initObjectFormat - initialize sections that are dependent on object
35  /// formats. (executable, shared objects or relocatable objects).
36  virtual void
37  initObjectFormat(ObjectBuilder& pBuilder, unsigned int pBitClass) = 0;
38
39public:
40  ELFFileFormat();
41
42  void initStdSections(ObjectBuilder& pBuilder, unsigned int pBitClass);
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  bool hasStackNote() const
178  { return (NULL != f_pStackNote); }
179
180  bool hasDataRelRoLocal() const
181  { return (NULL != f_pDataRelRoLocal) && (0 != f_pDataRelRoLocal->size()); }
182
183  bool hasGNUHashTab() const
184  { return (NULL != f_pGNUHashTab) && (0 != f_pGNUHashTab->size()); }
185
186  // -----  access functions  ----- //
187  /// @ref Special Sections, Ch. 4.17, System V ABI, 4th edition.
188  LDSection& getNULLSection() {
189    assert(NULL != f_pNULLSection);
190    return *f_pNULLSection;
191  }
192
193  const LDSection& getNULLSection() const {
194    assert(NULL != f_pNULLSection);
195    return *f_pNULLSection;
196  }
197
198  LDSection& getGOT() {
199    assert(NULL != f_pGOT);
200    return *f_pGOT;
201  }
202
203  const LDSection& getGOT() const {
204    assert(NULL != f_pGOT);
205    return *f_pGOT;
206  }
207
208  LDSection& getPLT() {
209    assert(NULL != f_pPLT);
210    return *f_pPLT;
211  }
212
213  const LDSection& getPLT() const {
214    assert(NULL != f_pPLT);
215    return *f_pPLT;
216  }
217
218  LDSection& getRelDyn() {
219    assert(NULL != f_pRelDyn);
220    return *f_pRelDyn;
221  }
222
223  const LDSection& getRelDyn() const {
224    assert(NULL != f_pRelDyn);
225    return *f_pRelDyn;
226  }
227
228  LDSection& getRelPlt() {
229    assert(NULL != f_pRelPlt);
230    return *f_pRelPlt;
231  }
232
233  const LDSection& getRelPlt() const {
234    assert(NULL != f_pRelPlt);
235    return *f_pRelPlt;
236  }
237
238  LDSection& getRelaDyn() {
239    assert(NULL != f_pRelaDyn);
240    return *f_pRelaDyn;
241  }
242
243  const LDSection& getRelaDyn() const {
244    assert(NULL != f_pRelaDyn);
245    return *f_pRelaDyn;
246  }
247
248  LDSection& getRelaPlt() {
249    assert(NULL != f_pRelaPlt);
250    return *f_pRelaPlt;
251  }
252
253  const LDSection& getRelaPlt() const {
254    assert(NULL != f_pRelaPlt);
255    return *f_pRelaPlt;
256  }
257
258  LDSection& getComment() {
259    assert(NULL != f_pComment);
260    return *f_pComment;
261  }
262
263  /// @ref 10.3.1.1, ISO/IEC 23360, Part 1:2010(E), p. 21.
264  const LDSection& getComment() const {
265    assert(NULL != f_pComment);
266    return *f_pComment;
267  }
268
269  LDSection& getData1() {
270    assert(NULL != f_pData1);
271    return *f_pData1;
272  }
273
274  const LDSection& getData1() const {
275    assert(NULL != f_pData1);
276    return *f_pData1;
277  }
278
279  LDSection& getDebug() {
280    assert(NULL != f_pDebug);
281    return *f_pDebug;
282  }
283
284  const LDSection& getDebug() const {
285    assert(NULL != f_pDebug);
286    return *f_pDebug;
287  }
288
289  LDSection& getDynamic() {
290    assert(NULL != f_pDynamic);
291    return *f_pDynamic;
292  }
293
294  const LDSection& getDynamic() const {
295    assert(NULL != f_pDynamic);
296    return *f_pDynamic;
297  }
298
299  LDSection& getDynStrTab() {
300    assert(NULL != f_pDynStrTab);
301    return *f_pDynStrTab;
302  }
303
304  const LDSection& getDynStrTab() const {
305    assert(NULL != f_pDynStrTab);
306    return *f_pDynStrTab;
307  }
308
309  LDSection& getDynSymTab() {
310    assert(NULL != f_pDynSymTab);
311    return *f_pDynSymTab;
312  }
313
314  const LDSection& getDynSymTab() const {
315    assert(NULL != f_pDynSymTab);
316    return *f_pDynSymTab;
317  }
318
319  LDSection& getFini() {
320    assert(NULL != f_pFini);
321    return *f_pFini;
322  }
323
324  const LDSection& getFini() const {
325    assert(NULL != f_pFini);
326    return *f_pFini;
327  }
328
329  LDSection& getFiniArray() {
330    assert(NULL != f_pFiniArray);
331    return *f_pFiniArray;
332  }
333
334  const LDSection& getFiniArray() const {
335    assert(NULL != f_pFiniArray);
336    return *f_pFiniArray;
337  }
338
339  LDSection& getHashTab() {
340    assert(NULL != f_pHashTab);
341    return *f_pHashTab;
342  }
343
344  const LDSection& getHashTab() const {
345    assert(NULL != f_pHashTab);
346    return *f_pHashTab;
347  }
348
349  LDSection& getInit() {
350    assert(NULL != f_pInit);
351    return *f_pInit;
352  }
353
354  const LDSection& getInit() const {
355    assert(NULL != f_pInit);
356    return *f_pInit;
357  }
358
359  LDSection& getInitArray() {
360    assert(NULL != f_pInitArray);
361    return *f_pInitArray;
362  }
363
364  const LDSection& getInitArray() const {
365    assert(NULL != f_pInitArray);
366    return *f_pInitArray;
367  }
368
369  LDSection& getInterp() {
370    assert(NULL != f_pInterp);
371    return *f_pInterp;
372  }
373
374  const LDSection& getInterp() const {
375    assert(NULL != f_pInterp);
376    return *f_pInterp;
377  }
378
379  LDSection& getLine() {
380    assert(NULL != f_pLine);
381    return *f_pLine;
382  }
383
384  const LDSection& getLine() const {
385    assert(NULL != f_pLine);
386    return *f_pLine;
387  }
388
389  LDSection& getNote() {
390    assert(NULL != f_pNote);
391    return *f_pNote;
392  }
393
394  const LDSection& getNote() const {
395    assert(NULL != f_pNote);
396    return *f_pNote;
397  }
398
399  LDSection& getPreInitArray() {
400    assert(NULL != f_pPreInitArray);
401    return *f_pPreInitArray;
402  }
403
404  const LDSection& getPreInitArray() const {
405    assert(NULL != f_pPreInitArray);
406    return *f_pPreInitArray;
407  }
408
409  LDSection& getROData1() {
410    assert(NULL != f_pROData1);
411    return *f_pROData1;
412  }
413
414  const LDSection& getROData1() const {
415    assert(NULL != f_pROData1);
416    return *f_pROData1;
417  }
418
419  LDSection& getShStrTab() {
420    assert(NULL != f_pShStrTab);
421    return *f_pShStrTab;
422  }
423
424  const LDSection& getShStrTab() const {
425    assert(NULL != f_pShStrTab);
426    return *f_pShStrTab;
427  }
428
429  LDSection& getStrTab() {
430    assert(NULL != f_pStrTab);
431    return *f_pStrTab;
432  }
433
434  const LDSection& getStrTab() const {
435    assert(NULL != f_pStrTab);
436    return *f_pStrTab;
437  }
438
439  LDSection& getSymTab() {
440    assert(NULL != f_pSymTab);
441    return *f_pSymTab;
442  }
443
444  const LDSection& getSymTab() const {
445    assert(NULL != f_pSymTab);
446    return *f_pSymTab;
447  }
448
449  LDSection& getTBSS() {
450    assert(NULL != f_pTBSS);
451    return *f_pTBSS;
452  }
453
454  const LDSection& getTBSS() const {
455    assert(NULL != f_pTBSS);
456    return *f_pTBSS;
457  }
458
459  LDSection& getTData() {
460    assert(NULL != f_pTData);
461    return *f_pTData;
462  }
463
464  const LDSection& getTData() const {
465    assert(NULL != f_pTData);
466    return *f_pTData;
467  }
468
469  /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24.
470  LDSection& getCtors() {
471    assert(NULL != f_pCtors);
472    return *f_pCtors;
473  }
474
475  const LDSection& getCtors() const {
476    assert(NULL != f_pCtors);
477    return *f_pCtors;
478  }
479
480  LDSection& getDataRelRo() {
481    assert(NULL != f_pDataRelRo);
482    return *f_pDataRelRo;
483  }
484
485  const LDSection& getDataRelRo() const {
486    assert(NULL != f_pDataRelRo);
487    return *f_pDataRelRo;
488  }
489
490  LDSection& getDtors() {
491    assert(NULL != f_pDtors);
492    return *f_pDtors;
493  }
494
495  const LDSection& getDtors() const {
496    assert(NULL != f_pDtors);
497    return *f_pDtors;
498  }
499
500  LDSection& getEhFrame() {
501    assert(NULL != f_pEhFrame);
502    return *f_pEhFrame;
503  }
504
505  const LDSection& getEhFrame() const {
506    assert(NULL != f_pEhFrame);
507    return *f_pEhFrame;
508  }
509
510  LDSection& getEhFrameHdr() {
511    assert(NULL != f_pEhFrameHdr);
512    return *f_pEhFrameHdr;
513  }
514
515  const LDSection& getEhFrameHdr() const {
516    assert(NULL != f_pEhFrameHdr);
517    return *f_pEhFrameHdr;
518  }
519
520  LDSection& getGCCExceptTable() {
521    assert(NULL != f_pGCCExceptTable);
522    return *f_pGCCExceptTable;
523  }
524
525  const LDSection& getGCCExceptTable() const {
526    assert(NULL != f_pGCCExceptTable);
527    return *f_pGCCExceptTable;
528  }
529
530  LDSection& getGNUVersion() {
531    assert(NULL != f_pGNUVersion);
532    return *f_pGNUVersion;
533  }
534
535  const LDSection& getGNUVersion() const {
536    assert(NULL != f_pGNUVersion);
537    return *f_pGNUVersion;
538  }
539
540  LDSection& getGNUVersionD() {
541    assert(NULL != f_pGNUVersionD);
542    return *f_pGNUVersionD;
543  }
544
545  const LDSection& getGNUVersionD() const {
546    assert(NULL != f_pGNUVersionD);
547    return *f_pGNUVersionD;
548  }
549
550  LDSection& getGNUVersionR() {
551    assert(NULL != f_pGNUVersionR);
552    return *f_pGNUVersionR;
553  }
554
555  const LDSection& getGNUVersionR() const {
556    assert(NULL != f_pGNUVersionR);
557    return *f_pGNUVersionR;
558  }
559
560  LDSection& getGOTPLT() {
561    assert(NULL != f_pGOTPLT);
562    return *f_pGOTPLT;
563  }
564
565  const LDSection& getGOTPLT() const {
566    assert(NULL != f_pGOTPLT);
567    return *f_pGOTPLT;
568  }
569
570  LDSection& getJCR() {
571    assert(NULL != f_pJCR);
572    return *f_pJCR;
573  }
574
575  const LDSection& getJCR() const {
576    assert(NULL != f_pJCR);
577    return *f_pJCR;
578  }
579
580  LDSection& getNoteABITag() {
581    assert(NULL != f_pNoteABITag);
582    return *f_pNoteABITag;
583  }
584
585  const LDSection& getNoteABITag() const {
586    assert(NULL != f_pNoteABITag);
587    return *f_pNoteABITag;
588  }
589
590  LDSection& getStab() {
591    assert(NULL != f_pStab);
592    return *f_pStab;
593  }
594
595  const LDSection& getStab() const {
596    assert(NULL != f_pStab);
597    return *f_pStab;
598  }
599
600  LDSection& getStabStr() {
601    assert(NULL != f_pStabStr);
602    return *f_pStabStr;
603  }
604
605  const LDSection& getStabStr() const {
606    assert(NULL != f_pStabStr);
607    return *f_pStabStr;
608  }
609
610  LDSection& getStack() {
611    assert(NULL != f_pStack);
612    return *f_pStack;
613  }
614
615  const LDSection& getStack() const {
616    assert(NULL != f_pStack);
617    return *f_pStack;
618  }
619
620  LDSection& getStackNote() {
621    assert(NULL != f_pStackNote);
622    return *f_pStackNote;
623  }
624
625  const LDSection& getStackNote() const {
626    assert(NULL != f_pStackNote);
627    return *f_pStackNote;
628  }
629
630  LDSection& getDataRelRoLocal() {
631    assert(NULL != f_pDataRelRoLocal);
632    return *f_pDataRelRoLocal;
633  }
634
635  const LDSection& getDataRelRoLocal() const {
636    assert(NULL != f_pDataRelRoLocal);
637    return *f_pDataRelRoLocal;
638  }
639
640  LDSection& getGNUHashTab() {
641    assert(NULL != f_pGNUHashTab);
642    return *f_pGNUHashTab;
643  }
644
645  const LDSection& getGNUHashTab() const {
646    assert(NULL != f_pGNUHashTab);
647    return *f_pGNUHashTab;
648  }
649
650protected:
651  //         variable name         :  ELF
652  /// @ref Special Sections, Ch. 4.17, System V ABI, 4th edition.
653  LDSection* f_pNULLSection;
654  LDSection* f_pGOT;               // .got
655  LDSection* f_pPLT;               // .plt
656  LDSection* f_pRelDyn;            // .rel.dyn
657  LDSection* f_pRelPlt;            // .rel.plt
658  LDSection* f_pRelaDyn;           // .rela.dyn
659  LDSection* f_pRelaPlt;           // .rela.plt
660
661  /// @ref 10.3.1.1, ISO/IEC 23360, Part 1:2010(E), p. 21.
662  LDSection* f_pComment;           // .comment
663  LDSection* f_pData1;             // .data1
664  LDSection* f_pDebug;             // .debug
665  LDSection* f_pDynamic;           // .dynamic
666  LDSection* f_pDynStrTab;         // .dynstr
667  LDSection* f_pDynSymTab;         // .dynsym
668  LDSection* f_pFini;              // .fini
669  LDSection* f_pFiniArray;         // .fini_array
670  LDSection* f_pHashTab;           // .hash
671  LDSection* f_pInit;              // .init
672  LDSection* f_pInitArray;         // .init_array
673  LDSection* f_pInterp;            // .interp
674  LDSection* f_pLine;              // .line
675  LDSection* f_pNote;              // .note
676  LDSection* f_pPreInitArray;      // .preinit_array
677  LDSection* f_pROData1;           // .rodata1
678  LDSection* f_pShStrTab;          // .shstrtab
679  LDSection* f_pStrTab;            // .strtab
680  LDSection* f_pSymTab;            // .symtab
681  LDSection* f_pTBSS;              // .tbss
682  LDSection* f_pTData;             // .tdata
683
684  /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24.
685  LDSection* f_pCtors;             // .ctors
686  LDSection* f_pDataRelRo;         // .data.rel.ro
687  LDSection* f_pDtors;             // .dtors
688  LDSection* f_pEhFrame;           // .eh_frame
689  LDSection* f_pEhFrameHdr;        // .eh_frame_hdr
690  LDSection* f_pGCCExceptTable;    // .gcc_except_table
691  LDSection* f_pGNUVersion;        // .gnu.version
692  LDSection* f_pGNUVersionD;       // .gnu.version_d
693  LDSection* f_pGNUVersionR;       // .gnu.version_r
694  LDSection* f_pGOTPLT;            // .got.plt
695  LDSection* f_pJCR;               // .jcr
696  LDSection* f_pNoteABITag;        // .note.ABI-tag
697  LDSection* f_pStab;              // .stab
698  LDSection* f_pStabStr;           // .stabstr
699
700  /// practical
701  LDSection* f_pStack;             // .stack
702  LDSection* f_pStackNote;         // .note.GNU-stack
703  LDSection* f_pDataRelRoLocal;    // .data.rel.ro.local
704  LDSection* f_pGNUHashTab;        // .gnu.hash
705};
706
707} // namespace of mcld
708
709#endif
710
711