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