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/MC/MCLinker.h>
     11 #include <mcld/MC/MCLDFile.h>
     12 #include <llvm/Support/ELF.h>
     13 #include <mcld/Target/GNULDBackend.h>
     14 
     15 using namespace mcld;
     16 
     17 ELFFileFormat::ELFFileFormat(GNULDBackend& pBackend)
     18   : f_Backend(pBackend),
     19     f_pNULLSection(NULL),
     20     f_pGOT(NULL),
     21     f_pPLT(NULL),
     22     f_pRelDyn(NULL),
     23     f_pRelPlt(NULL),
     24     f_pRelaDyn(NULL),
     25     f_pRelaPlt(NULL),
     26     f_pComment(NULL),
     27     f_pData1(NULL),
     28     f_pDebug(NULL),
     29     f_pDynamic(NULL),
     30     f_pDynStrTab(NULL),
     31     f_pDynSymTab(NULL),
     32     f_pFini(NULL),
     33     f_pFiniArray(NULL),
     34     f_pHashTab(NULL),
     35     f_pInit(NULL),
     36     f_pInitArray(NULL),
     37     f_pInterp(NULL),
     38     f_pLine(NULL),
     39     f_pNote(NULL),
     40     f_pPreInitArray(NULL),
     41     f_pROData1(NULL),
     42     f_pShStrTab(NULL),
     43     f_pStrTab(NULL),
     44     f_pSymTab(NULL),
     45     f_pTBSS(NULL),
     46     f_pTData(NULL),
     47     f_pCtors(NULL),
     48     f_pDataRelRo(NULL),
     49     f_pDtors(NULL),
     50     f_pEhFrame(NULL),
     51     f_pEhFrameHdr(NULL),
     52     f_pGCCExceptTable(NULL),
     53     f_pGNUVersion(NULL),
     54     f_pGNUVersionD(NULL),
     55     f_pGNUVersionR(NULL),
     56     f_pGOTPLT(NULL),
     57     f_pJCR(NULL),
     58     f_pNoteABITag(NULL),
     59     f_pStab(NULL),
     60     f_pStabStr(NULL) {
     61 
     62 }
     63 
     64 ELFFileFormat::~ELFFileFormat()
     65 {
     66 }
     67 
     68 void ELFFileFormat::initObjectFormat(MCLinker& pLinker)
     69 {
     70   f_pTextSection     = &pLinker.getOrCreateOutputSectHdr(".text",
     71                                               LDFileFormat::Regular,
     72                                               llvm::ELF::SHT_PROGBITS,
     73                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
     74                                               0x1);
     75   f_pNULLSection     = &pLinker.getOrCreateOutputSectHdr("",
     76                                               LDFileFormat::Null,
     77                                               llvm::ELF::SHT_NULL,
     78                                               0x0);
     79   f_pReadOnlySection = &pLinker.getOrCreateOutputSectHdr(".rodata",
     80                                               LDFileFormat::Regular,
     81                                               llvm::ELF::SHT_PROGBITS,
     82                                               llvm::ELF::SHF_ALLOC,
     83                                               0x1);
     84 
     85   f_pBSSSection      = &pLinker.getOrCreateOutputSectHdr(".bss",
     86                                               LDFileFormat::BSS,
     87                                               llvm::ELF::SHT_NOBITS,
     88                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
     89                                               0x1);
     90   f_pComment         = &pLinker.getOrCreateOutputSectHdr(".comment",
     91                                               LDFileFormat::MetaData,
     92                                               llvm::ELF::SHT_PROGBITS,
     93                                               0x0,
     94                                               0x1);
     95   f_pDataSection     = &pLinker.getOrCreateOutputSectHdr(".data",
     96                                               LDFileFormat::Regular,
     97                                               llvm::ELF::SHT_PROGBITS,
     98                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
     99                                               0x1);
    100   f_pData1           = &pLinker.getOrCreateOutputSectHdr(".data1",
    101                                               LDFileFormat::Regular,
    102                                               llvm::ELF::SHT_PROGBITS,
    103                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    104                                               0x1);
    105   f_pDebug           = &pLinker.getOrCreateOutputSectHdr(".debug",
    106                                               LDFileFormat::Debug,
    107                                               llvm::ELF::SHT_PROGBITS,
    108                                               0x0,
    109                                               0x1);
    110   f_pInit            = &pLinker.getOrCreateOutputSectHdr(".init",
    111                                               LDFileFormat::Regular,
    112                                               llvm::ELF::SHT_PROGBITS,
    113                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
    114                                               0x1);
    115   f_pInitArray       = &pLinker.getOrCreateOutputSectHdr(".init_array",
    116                                               LDFileFormat::Regular,
    117                                               llvm::ELF::SHT_INIT_ARRAY,
    118                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    119                                               0x1);
    120   f_pFini            = &pLinker.getOrCreateOutputSectHdr(".fini",
    121                                               LDFileFormat::Regular,
    122                                               llvm::ELF::SHT_PROGBITS,
    123                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR,
    124                                               0x1);
    125   f_pFiniArray       = &pLinker.getOrCreateOutputSectHdr(".fini_array",
    126                                               LDFileFormat::Regular,
    127                                               llvm::ELF::SHT_FINI_ARRAY,
    128                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    129                                               0x1);
    130   f_pLine            = &pLinker.getOrCreateOutputSectHdr(".line",
    131                                               LDFileFormat::Debug,
    132                                               llvm::ELF::SHT_PROGBITS,
    133                                               0x0,
    134                                               0x1);
    135   f_pPreInitArray    = &pLinker.getOrCreateOutputSectHdr(".preinit_array",
    136                                               LDFileFormat::Regular,
    137                                               llvm::ELF::SHT_PREINIT_ARRAY,
    138                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    139                                               0x1);
    140   // the definition of SHF_XXX attributes of rodata in Linux Standard Base
    141   // conflicts with System V standard. We follow System V standard.
    142   f_pROData1         = &pLinker.getOrCreateOutputSectHdr(".rodata1",
    143                                               LDFileFormat::Regular,
    144                                               llvm::ELF::SHT_PROGBITS,
    145                                               llvm::ELF::SHF_ALLOC,
    146                                               0x1);
    147   f_pShStrTab        = &pLinker.getOrCreateOutputSectHdr(".shstrtab",
    148                                               LDFileFormat::NamePool,
    149                                               llvm::ELF::SHT_STRTAB,
    150                                               0x0,
    151                                               0x1);
    152   // In ELF Spec Book I, p1-16. If symbol table and string table are in
    153   // loadable segments, set the attribute to SHF_ALLOC bit. But in the
    154   // real world, this bit always turn off.
    155   f_pSymTab       = &pLinker.getOrCreateOutputSectHdr(".symtab",
    156                                               LDFileFormat::NamePool,
    157                                               llvm::ELF::SHT_SYMTAB,
    158                                               0x0,
    159                                               f_Backend.bitclass() / 8);
    160   f_pStrTab       = &pLinker.getOrCreateOutputSectHdr(".strtab",
    161                                               LDFileFormat::NamePool,
    162                                               llvm::ELF::SHT_STRTAB,
    163                                               0x0,
    164                                               0x1);
    165   f_pTBSS         = &pLinker.getOrCreateOutputSectHdr(".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        = &pLinker.getOrCreateOutputSectHdr(".tdata",
    173                                               LDFileFormat::Regular,
    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          = &pLinker.getOrCreateOutputSectHdr(".ctor",
    182                                               LDFileFormat::Regular,
    183                                               llvm::ELF::SHT_PROGBITS,
    184                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    185                                               0x1);
    186   f_pDataRelRo      = &pLinker.getOrCreateOutputSectHdr(".data.rel.ro",
    187                                               LDFileFormat::Regular,
    188                                               llvm::ELF::SHT_PROGBITS,
    189                                               llvm::ELF::SHF_ALLOC,
    190                                               0x1);
    191   f_pDtors          = &pLinker.getOrCreateOutputSectHdr(".dtors",
    192                                               LDFileFormat::Regular,
    193                                               llvm::ELF::SHT_PROGBITS,
    194                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    195                                               0x1);
    196   f_pEhFrame        = &pLinker.getOrCreateOutputSectHdr(".eh_frame",
    197                                               LDFileFormat::Exception,
    198                                               llvm::ELF::SHT_PROGBITS,
    199                                               llvm::ELF::SHF_ALLOC,
    200                                               0x1);
    201   f_pEhFrameHdr     = &pLinker.getOrCreateOutputSectHdr(".eh_frame_hdr",
    202                                               LDFileFormat::Exception,
    203                                               llvm::ELF::SHT_PROGBITS,
    204                                               llvm::ELF::SHF_ALLOC,
    205                                               0x1);
    206   f_pGCCExceptTable = &pLinker.getOrCreateOutputSectHdr(".gcc_except_table",
    207                                               LDFileFormat::Exception,
    208                                               llvm::ELF::SHT_PROGBITS,
    209                                               llvm::ELF::SHF_ALLOC,
    210                                               0x1);
    211   f_pGNUVersion     = &pLinker.getOrCreateOutputSectHdr(".gnu.version",
    212                                               LDFileFormat::Version,
    213                                               llvm::ELF::SHT_GNU_versym,
    214                                               llvm::ELF::SHF_ALLOC,
    215                                               0x1);
    216   f_pGNUVersionD    = &pLinker.getOrCreateOutputSectHdr(".gnu.version_d",
    217                                               LDFileFormat::Version,
    218                                               llvm::ELF::SHT_GNU_verdef,
    219                                               llvm::ELF::SHF_ALLOC,
    220                                               0x1);
    221   f_pGNUVersionR    = &pLinker.getOrCreateOutputSectHdr(".gnu.version_r",
    222                                               LDFileFormat::Version,
    223                                               llvm::ELF::SHT_GNU_verneed,
    224                                               llvm::ELF::SHF_ALLOC,
    225                                               0x1);
    226   f_pJCR            = &pLinker.getOrCreateOutputSectHdr(".jcr",
    227                                               LDFileFormat::Regular,
    228                                               llvm::ELF::SHT_PROGBITS,
    229                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE,
    230                                               0x1);
    231   f_pStab           = &pLinker.getOrCreateOutputSectHdr(".stab",
    232                                               LDFileFormat::Debug,
    233                                               llvm::ELF::SHT_PROGBITS,
    234                                               0x0,
    235                                               0x1);
    236   f_pStabStr        = &pLinker.getOrCreateOutputSectHdr(".stabstr",
    237                                               LDFileFormat::Debug,
    238                                               llvm::ELF::SHT_STRTAB,
    239                                               0x0,
    240                                               0x1);
    241 }
    242 
    243