Home | History | Annotate | Download | only in LD
      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 
     15 namespace mcld {
     16 
     17 ELFFileFormat::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 
     66 void 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