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 using 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 
     67 void ELFFileFormat::initStdSections(ObjectBuilder& pBuilder, unsigned int pBitClass)
     68 {
     69   f_pTextSection     = 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     = pBuilder.CreateSection("",
     75                                               LDFileFormat::Null,
     76                                               llvm::ELF::SHT_NULL,
     77                                               0x0);
     78   f_pReadOnlySection = pBuilder.CreateSection(".rodata",
     79                                               LDFileFormat::TEXT,
     80                                               llvm::ELF::SHT_PROGBITS,
     81                                               llvm::ELF::SHF_ALLOC,
     82                                               0x1);
     83 
     84   f_pBSSSection      = pBuilder.CreateSection(".bss",
     85                                               LDFileFormat::BSS,
     86                                               llvm::ELF::SHT_NOBITS,
     87                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
     88                                               0x1);
     89   f_pComment         = pBuilder.CreateSection(".comment",
     90                                               LDFileFormat::MetaData,
     91                                               llvm::ELF::SHT_PROGBITS,
     92                                               0x0,
     93                                               0x1);
     94   f_pDataSection     = pBuilder.CreateSection(".data",
     95                                               LDFileFormat::DATA,
     96                                               llvm::ELF::SHT_PROGBITS,
     97                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
     98                                               0x1);
     99   f_pData1           = pBuilder.CreateSection(".data1",
    100                                               LDFileFormat::DATA,
    101                                               llvm::ELF::SHT_PROGBITS,
    102                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    103                                               0x1);
    104   f_pDebug           = pBuilder.CreateSection(".debug",
    105                                               LDFileFormat::Debug,
    106                                               llvm::ELF::SHT_PROGBITS,
    107                                               0x0,
    108                                               0x1);
    109   f_pInit            = pBuilder.CreateSection(".init",
    110                                               LDFileFormat::TEXT,
    111                                               llvm::ELF::SHT_PROGBITS,
    112                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
    113                                               0x1);
    114   f_pInitArray       = pBuilder.CreateSection(".init_array",
    115                                               LDFileFormat::DATA,
    116                                               llvm::ELF::SHT_INIT_ARRAY,
    117                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    118                                               0x1);
    119   f_pFini            = pBuilder.CreateSection(".fini",
    120                                               LDFileFormat::TEXT,
    121                                               llvm::ELF::SHT_PROGBITS,
    122                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
    123                                               0x1);
    124   f_pFiniArray       = pBuilder.CreateSection(".fini_array",
    125                                               LDFileFormat::DATA,
    126                                               llvm::ELF::SHT_FINI_ARRAY,
    127                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    128                                               0x1);
    129   f_pLine            = pBuilder.CreateSection(".line",
    130                                               LDFileFormat::Debug,
    131                                               llvm::ELF::SHT_PROGBITS,
    132                                               0x0,
    133                                               0x1);
    134   f_pPreInitArray    = pBuilder.CreateSection(".preinit_array",
    135                                               LDFileFormat::DATA,
    136                                               llvm::ELF::SHT_PREINIT_ARRAY,
    137                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    138                                               0x1);
    139   // the definition of SHF_XXX attributes of rodata in Linux Standard Base
    140   // conflicts with System V standard. We follow System V standard.
    141   f_pROData1         = pBuilder.CreateSection(".rodata1",
    142                                               LDFileFormat::TEXT,
    143                                               llvm::ELF::SHT_PROGBITS,
    144                                               llvm::ELF::SHF_ALLOC,
    145                                               0x1);
    146   f_pShStrTab        = pBuilder.CreateSection(".shstrtab",
    147                                               LDFileFormat::NamePool,
    148                                               llvm::ELF::SHT_STRTAB,
    149                                               0x0,
    150                                               0x1);
    151   // In ELF Spec Book I, p1-16. If symbol table and string table are in
    152   // loadable segments, set the attribute to SHF_ALLOC bit. But in the
    153   // real world, this bit always turn off.
    154   f_pSymTab          = pBuilder.CreateSection(".symtab",
    155                                               LDFileFormat::NamePool,
    156                                               llvm::ELF::SHT_SYMTAB,
    157                                               0x0,
    158                                               pBitClass / 8);
    159 
    160   f_pStrTab          = pBuilder.CreateSection(".strtab",
    161                                               LDFileFormat::NamePool,
    162                                               llvm::ELF::SHT_STRTAB,
    163                                               0x0,
    164                                               0x1);
    165   f_pTBSS            = pBuilder.CreateSection(".tbss",
    166                                               LDFileFormat::BSS,
    167                                               llvm::ELF::SHT_NOBITS,
    168                                               llvm::ELF::SHF_ALLOC |
    169                                               llvm::ELF::SHF_WRITE |
    170                                               llvm::ELF::SHF_TLS,
    171                                               0x1);
    172   f_pTData           = pBuilder.CreateSection(".tdata",
    173                                               LDFileFormat::DATA,
    174                                               llvm::ELF::SHT_PROGBITS,
    175                                               llvm::ELF::SHF_ALLOC |
    176                                               llvm::ELF::SHF_WRITE |
    177                                               llvm::ELF::SHF_TLS,
    178                                               0x1);
    179 
    180   /// @ref 10.3.1.2, ISO/IEC 23360, Part 1:2010(E), p. 24.
    181   f_pCtors           = pBuilder.CreateSection(".ctors",
    182                                               LDFileFormat::DATA,
    183                                               llvm::ELF::SHT_PROGBITS,
    184                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    185                                               0x1);
    186   f_pDataRelRo       = pBuilder.CreateSection(".data.rel.ro",
    187                                               LDFileFormat::DATA,
    188                                               llvm::ELF::SHT_PROGBITS,
    189                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    190                                               0x1);
    191   f_pDtors           = pBuilder.CreateSection(".dtors",
    192                                               LDFileFormat::DATA,
    193                                               llvm::ELF::SHT_PROGBITS,
    194                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    195                                               0x1);
    196   f_pEhFrame         = pBuilder.CreateSection(".eh_frame",
    197                                               LDFileFormat::EhFrame,
    198                                               llvm::ELF::SHT_PROGBITS,
    199                                               llvm::ELF::SHF_ALLOC,
    200                                               0x4);
    201   f_pGCCExceptTable  = pBuilder.CreateSection(".gcc_except_table",
    202                                               LDFileFormat::GCCExceptTable,
    203                                               llvm::ELF::SHT_PROGBITS,
    204                                               llvm::ELF::SHF_ALLOC,
    205                                               0x4);
    206   f_pGNUVersion      = pBuilder.CreateSection(".gnu.version",
    207                                               LDFileFormat::Version,
    208                                               llvm::ELF::SHT_GNU_versym,
    209                                               llvm::ELF::SHF_ALLOC,
    210                                               0x1);
    211   f_pGNUVersionD     = pBuilder.CreateSection(".gnu.version_d",
    212                                               LDFileFormat::Version,
    213                                               llvm::ELF::SHT_GNU_verdef,
    214                                               llvm::ELF::SHF_ALLOC,
    215                                               0x1);
    216   f_pGNUVersionR     = pBuilder.CreateSection(".gnu.version_r",
    217                                               LDFileFormat::Version,
    218                                               llvm::ELF::SHT_GNU_verneed,
    219                                               llvm::ELF::SHF_ALLOC,
    220                                               0x1);
    221   f_pJCR             = pBuilder.CreateSection(".jcr",
    222                                               LDFileFormat::DATA,
    223                                               llvm::ELF::SHT_PROGBITS,
    224                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    225                                               0x1);
    226   f_pStab            = pBuilder.CreateSection(".stab",
    227                                               LDFileFormat::Debug,
    228                                               llvm::ELF::SHT_PROGBITS,
    229                                               0x0,
    230                                               0x1);
    231   f_pStabStr         = pBuilder.CreateSection(".stabstr",
    232                                               LDFileFormat::Debug,
    233                                               llvm::ELF::SHT_STRTAB,
    234                                               0x0,
    235                                               0x1);
    236   f_pStackNote       = pBuilder.CreateSection(".note.GNU-stack",
    237                                               LDFileFormat::StackNote,
    238                                               llvm::ELF::SHT_PROGBITS,
    239                                               0x0,
    240                                               0x1);
    241 
    242   /// @ref GCC convention, see http://www.airs.com/blog/archives/189
    243   f_pDataRelRoLocal  = pBuilder.CreateSection(".data.rel.ro.local",
    244                                               LDFileFormat::DATA,
    245                                               llvm::ELF::SHT_PROGBITS,
    246                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    247                                               0x1);
    248   /// Initialize format dependent sections. (sections for executable and shared
    249   /// objects)
    250   initObjectFormat(pBuilder, pBitClass);
    251 }
    252 
    253