Home | History | Annotate | Download | only in Target
      1 //===- ELFDynamic.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/Support/MsgHandling.h"
     11 #include "mcld/Target/ELFDynamic.h"
     12 #include "mcld/Target/GNULDBackend.h"
     13 #include "mcld/LinkerConfig.h"
     14 
     15 #include <llvm/Support/ErrorHandling.h>
     16 #include <llvm/Support/Host.h>
     17 
     18 namespace mcld {
     19 namespace elf_dynamic {
     20 
     21 //===----------------------------------------------------------------------===//
     22 // elf_dynamic::EntryIF
     23 //===----------------------------------------------------------------------===//
     24 EntryIF::EntryIF() {
     25 }
     26 
     27 EntryIF::~EntryIF() {
     28 }
     29 
     30 }  // namespace elf_dynamic
     31 
     32 //===----------------------------------------------------------------------===//
     33 // ELFDynamic
     34 //===----------------------------------------------------------------------===//
     35 ELFDynamic::ELFDynamic(const GNULDBackend& pParent, const LinkerConfig& pConfig)
     36     : m_pEntryFactory(NULL), m_Backend(pParent), m_Config(pConfig), m_Idx(0) {
     37   // FIXME: support big-endian machine.
     38   if (m_Config.targets().is32Bits()) {
     39     if (m_Config.targets().isLittleEndian())
     40       m_pEntryFactory = new elf_dynamic::Entry<32, true>();
     41   } else if (m_Config.targets().is64Bits()) {
     42     if (m_Config.targets().isLittleEndian())
     43       m_pEntryFactory = new elf_dynamic::Entry<64, true>();
     44   } else {
     45     fatal(diag::unsupported_bitclass) << m_Config.targets().triple().str()
     46                                       << m_Config.targets().bitclass();
     47   }
     48 }
     49 
     50 ELFDynamic::~ELFDynamic() {
     51   if (m_pEntryFactory != NULL)
     52     delete m_pEntryFactory;
     53 
     54   EntryListType::iterator entry, entryEnd = m_EntryList.end();
     55   for (entry = m_EntryList.begin(); entry != entryEnd; ++entry) {
     56     if (*entry != NULL)
     57       delete (*entry);
     58   }
     59 
     60   entryEnd = m_NeedList.end();
     61   for (entry = m_NeedList.begin(); entry != entryEnd; ++entry) {
     62     if (*entry != NULL)
     63       delete (*entry);
     64   }
     65 }
     66 
     67 size_t ELFDynamic::size() const {
     68   return (m_NeedList.size() + m_EntryList.size());
     69 }
     70 
     71 size_t ELFDynamic::numOfBytes() const {
     72   return size() * entrySize();
     73 }
     74 
     75 size_t ELFDynamic::entrySize() const {
     76   return m_pEntryFactory->size();
     77 }
     78 
     79 void ELFDynamic::reserveOne(uint64_t pTag) {
     80   assert(m_pEntryFactory != NULL);
     81   m_EntryList.push_back(m_pEntryFactory->clone());
     82 }
     83 
     84 void ELFDynamic::applyOne(uint64_t pTag, uint64_t pValue) {
     85   assert(m_Idx < m_EntryList.size());
     86   m_EntryList[m_Idx]->setValue(pTag, pValue);
     87   ++m_Idx;
     88 }
     89 
     90 /// reserveEntries - reserve entries
     91 void ELFDynamic::reserveEntries(const ELFFileFormat& pFormat) {
     92   if (LinkerConfig::DynObj == m_Config.codeGenType()) {
     93     reserveOne(llvm::ELF::DT_SONAME);
     94 
     95     if (m_Config.options().Bsymbolic())
     96       reserveOne(llvm::ELF::DT_SYMBOLIC);
     97   }
     98 
     99   if (pFormat.hasInit())
    100     reserveOne(llvm::ELF::DT_INIT);
    101 
    102   if (pFormat.hasFini())
    103     reserveOne(llvm::ELF::DT_FINI);
    104 
    105   if (pFormat.hasPreInitArray()) {
    106     reserveOne(llvm::ELF::DT_PREINIT_ARRAY);
    107     reserveOne(llvm::ELF::DT_PREINIT_ARRAYSZ);
    108   }
    109 
    110   if (pFormat.hasInitArray()) {
    111     reserveOne(llvm::ELF::DT_INIT_ARRAY);
    112     reserveOne(llvm::ELF::DT_INIT_ARRAYSZ);
    113   }
    114 
    115   if (pFormat.hasFiniArray()) {
    116     reserveOne(llvm::ELF::DT_FINI_ARRAY);
    117     reserveOne(llvm::ELF::DT_FINI_ARRAYSZ);
    118   }
    119 
    120   if (pFormat.hasHashTab())
    121     reserveOne(llvm::ELF::DT_HASH);
    122 
    123   if (pFormat.hasGNUHashTab())
    124     reserveOne(llvm::ELF::DT_GNU_HASH);
    125 
    126   if (pFormat.hasDynSymTab()) {
    127     reserveOne(llvm::ELF::DT_SYMTAB);
    128     reserveOne(llvm::ELF::DT_SYMENT);
    129   }
    130 
    131   if (pFormat.hasDynStrTab()) {
    132     reserveOne(llvm::ELF::DT_STRTAB);
    133     reserveOne(llvm::ELF::DT_STRSZ);
    134   }
    135 
    136   reserveTargetEntries(pFormat);
    137 
    138   if (pFormat.hasRelPlt() || pFormat.hasRelaPlt()) {
    139     reserveOne(llvm::ELF::DT_PLTREL);
    140     reserveOne(llvm::ELF::DT_JMPREL);
    141     reserveOne(llvm::ELF::DT_PLTRELSZ);
    142   }
    143 
    144   if (pFormat.hasRelDyn()) {
    145     reserveOne(llvm::ELF::DT_REL);
    146     reserveOne(llvm::ELF::DT_RELSZ);
    147     reserveOne(llvm::ELF::DT_RELENT);
    148   }
    149 
    150   if (pFormat.hasRelaDyn()) {
    151     reserveOne(llvm::ELF::DT_RELA);
    152     reserveOne(llvm::ELF::DT_RELASZ);
    153     reserveOne(llvm::ELF::DT_RELAENT);
    154   }
    155 
    156   uint64_t dt_flags = 0x0;
    157   if (m_Config.options().hasOrigin())
    158     dt_flags |= llvm::ELF::DF_ORIGIN;
    159   if (m_Config.options().Bsymbolic())
    160     dt_flags |= llvm::ELF::DF_SYMBOLIC;
    161   if (m_Config.options().hasNow())
    162     dt_flags |= llvm::ELF::DF_BIND_NOW;
    163   if (m_Backend.hasTextRel())
    164     dt_flags |= llvm::ELF::DF_TEXTREL;
    165   if (m_Backend.hasStaticTLS() &&
    166       (LinkerConfig::DynObj == m_Config.codeGenType()))
    167     dt_flags |= llvm::ELF::DF_STATIC_TLS;
    168 
    169   if ((m_Config.options().hasNewDTags() && dt_flags != 0x0) ||
    170       (dt_flags & llvm::ELF::DF_STATIC_TLS) != 0x0)
    171     reserveOne(llvm::ELF::DT_FLAGS);
    172 
    173   if (m_Backend.hasTextRel())
    174     reserveOne(llvm::ELF::DT_TEXTREL);
    175 
    176   if (m_Config.options().hasNow() || m_Config.options().hasLoadFltr() ||
    177       m_Config.options().hasOrigin() || m_Config.options().hasInterPose() ||
    178       m_Config.options().hasNoDefaultLib() || m_Config.options().hasNoDump() ||
    179       m_Config.options().Bgroup() ||
    180       ((LinkerConfig::DynObj == m_Config.codeGenType()) &&
    181        (m_Config.options().hasNoDelete() || m_Config.options().hasInitFirst() ||
    182         m_Config.options().hasNoDLOpen()))) {
    183     reserveOne(llvm::ELF::DT_FLAGS_1);
    184   }
    185 
    186   unsigned num_spare_dtags = m_Config.options().getNumSpareDTags();
    187   for (unsigned i = 0; i < num_spare_dtags; ++i) {
    188     reserveOne(llvm::ELF::DT_NULL);
    189   }
    190 }
    191 
    192 /// applyEntries - apply entries
    193 void ELFDynamic::applyEntries(const ELFFileFormat& pFormat) {
    194   if (LinkerConfig::DynObj == m_Config.codeGenType() &&
    195       m_Config.options().Bsymbolic()) {
    196     applyOne(llvm::ELF::DT_SYMBOLIC, 0x0);
    197   }
    198 
    199   if (pFormat.hasInit())
    200     applyOne(llvm::ELF::DT_INIT, pFormat.getInit().addr());
    201 
    202   if (pFormat.hasFini())
    203     applyOne(llvm::ELF::DT_FINI, pFormat.getFini().addr());
    204 
    205   if (pFormat.hasPreInitArray()) {
    206     applyOne(llvm::ELF::DT_PREINIT_ARRAY, pFormat.getPreInitArray().addr());
    207     applyOne(llvm::ELF::DT_PREINIT_ARRAYSZ, pFormat.getPreInitArray().size());
    208   }
    209 
    210   if (pFormat.hasInitArray()) {
    211     applyOne(llvm::ELF::DT_INIT_ARRAY, pFormat.getInitArray().addr());
    212     applyOne(llvm::ELF::DT_INIT_ARRAYSZ, pFormat.getInitArray().size());
    213   }
    214 
    215   if (pFormat.hasFiniArray()) {
    216     applyOne(llvm::ELF::DT_FINI_ARRAY, pFormat.getFiniArray().addr());
    217     applyOne(llvm::ELF::DT_FINI_ARRAYSZ, pFormat.getFiniArray().size());
    218   }
    219 
    220   if (pFormat.hasHashTab())
    221     applyOne(llvm::ELF::DT_HASH, pFormat.getHashTab().addr());
    222 
    223   if (pFormat.hasGNUHashTab())
    224     applyOne(llvm::ELF::DT_GNU_HASH, pFormat.getGNUHashTab().addr());
    225 
    226   if (pFormat.hasDynSymTab()) {
    227     applyOne(llvm::ELF::DT_SYMTAB, pFormat.getDynSymTab().addr());
    228     applyOne(llvm::ELF::DT_SYMENT, symbolSize());
    229   }
    230 
    231   if (pFormat.hasDynStrTab()) {
    232     applyOne(llvm::ELF::DT_STRTAB, pFormat.getDynStrTab().addr());
    233     applyOne(llvm::ELF::DT_STRSZ, pFormat.getDynStrTab().size());
    234   }
    235 
    236   applyTargetEntries(pFormat);
    237 
    238   if (pFormat.hasRelPlt()) {
    239     applyOne(llvm::ELF::DT_PLTREL, llvm::ELF::DT_REL);
    240     applyOne(llvm::ELF::DT_JMPREL, pFormat.getRelPlt().addr());
    241     applyOne(llvm::ELF::DT_PLTRELSZ, pFormat.getRelPlt().size());
    242   } else if (pFormat.hasRelaPlt()) {
    243     applyOne(llvm::ELF::DT_PLTREL, llvm::ELF::DT_RELA);
    244     applyOne(llvm::ELF::DT_JMPREL, pFormat.getRelaPlt().addr());
    245     applyOne(llvm::ELF::DT_PLTRELSZ, pFormat.getRelaPlt().size());
    246   }
    247 
    248   if (pFormat.hasRelDyn()) {
    249     applyOne(llvm::ELF::DT_REL, pFormat.getRelDyn().addr());
    250     applyOne(llvm::ELF::DT_RELSZ, pFormat.getRelDyn().size());
    251     applyOne(llvm::ELF::DT_RELENT, m_pEntryFactory->relSize());
    252   }
    253 
    254   if (pFormat.hasRelaDyn()) {
    255     applyOne(llvm::ELF::DT_RELA, pFormat.getRelaDyn().addr());
    256     applyOne(llvm::ELF::DT_RELASZ, pFormat.getRelaDyn().size());
    257     applyOne(llvm::ELF::DT_RELAENT, m_pEntryFactory->relaSize());
    258   }
    259 
    260   if (m_Backend.hasTextRel()) {
    261     applyOne(llvm::ELF::DT_TEXTREL, 0x0);
    262 
    263     if (m_Config.options().warnSharedTextrel() &&
    264         LinkerConfig::DynObj == m_Config.codeGenType())
    265       mcld::warning(mcld::diag::warn_shared_textrel);
    266   }
    267 
    268   uint64_t dt_flags = 0x0;
    269   if (m_Config.options().hasOrigin())
    270     dt_flags |= llvm::ELF::DF_ORIGIN;
    271   if (m_Config.options().Bsymbolic())
    272     dt_flags |= llvm::ELF::DF_SYMBOLIC;
    273   if (m_Config.options().hasNow())
    274     dt_flags |= llvm::ELF::DF_BIND_NOW;
    275   if (m_Backend.hasTextRel())
    276     dt_flags |= llvm::ELF::DF_TEXTREL;
    277   if (m_Backend.hasStaticTLS() &&
    278       (LinkerConfig::DynObj == m_Config.codeGenType()))
    279     dt_flags |= llvm::ELF::DF_STATIC_TLS;
    280 
    281   if ((m_Config.options().hasNewDTags() && dt_flags != 0x0) ||
    282       (dt_flags & llvm::ELF::DF_STATIC_TLS) != 0)
    283     applyOne(llvm::ELF::DT_FLAGS, dt_flags);
    284 
    285   uint64_t dt_flags_1 = 0x0;
    286   if (m_Config.options().hasNow())
    287     dt_flags_1 |= llvm::ELF::DF_1_NOW;
    288   if (m_Config.options().hasLoadFltr())
    289     dt_flags_1 |= llvm::ELF::DF_1_LOADFLTR;
    290   if (m_Config.options().hasOrigin())
    291     dt_flags_1 |= llvm::ELF::DF_1_ORIGIN;
    292   if (m_Config.options().hasInterPose())
    293     dt_flags_1 |= llvm::ELF::DF_1_INTERPOSE;
    294   if (m_Config.options().hasNoDefaultLib())
    295     dt_flags_1 |= llvm::ELF::DF_1_NODEFLIB;
    296   if (m_Config.options().hasNoDump())
    297     dt_flags_1 |= llvm::ELF::DF_1_NODUMP;
    298   if (m_Config.options().Bgroup())
    299     dt_flags_1 |= llvm::ELF::DF_1_GROUP;
    300   if (LinkerConfig::DynObj == m_Config.codeGenType()) {
    301     if (m_Config.options().hasNoDelete())
    302       dt_flags_1 |= llvm::ELF::DF_1_NODELETE;
    303     if (m_Config.options().hasInitFirst())
    304       dt_flags_1 |= llvm::ELF::DF_1_INITFIRST;
    305     if (m_Config.options().hasNoDLOpen())
    306       dt_flags_1 |= llvm::ELF::DF_1_NOOPEN;
    307   }
    308   if (dt_flags_1 != 0x0)
    309     applyOne(llvm::ELF::DT_FLAGS_1, dt_flags_1);
    310 
    311   unsigned num_spare_dtags = m_Config.options().getNumSpareDTags();
    312   for (unsigned i = 0; i < num_spare_dtags; ++i) {
    313     applyOne(llvm::ELF::DT_NULL, 0x0);
    314   }
    315 }
    316 
    317 /// symbolSize
    318 size_t ELFDynamic::symbolSize() const {
    319   return m_pEntryFactory->symbolSize();
    320 }
    321 
    322 /// reserveNeedEntry - reserve on DT_NEED entry.
    323 void ELFDynamic::reserveNeedEntry() {
    324   m_NeedList.push_back(m_pEntryFactory->clone());
    325 }
    326 
    327 /// emit
    328 void ELFDynamic::emit(const LDSection& pSection, MemoryRegion& pRegion) const {
    329   if (pRegion.size() < pSection.size()) {
    330     llvm::report_fatal_error(llvm::Twine("the given memory is smaller") +
    331                              llvm::Twine(" than the section's demaind.\n"));
    332   }
    333 
    334   uint8_t* address = reinterpret_cast<uint8_t*>(pRegion.begin());
    335   EntryListType::const_iterator entry, entryEnd = m_NeedList.end();
    336   for (entry = m_NeedList.begin(); entry != entryEnd; ++entry)
    337     address += (*entry)->emit(address);
    338 
    339   entryEnd = m_EntryList.end();
    340   for (entry = m_EntryList.begin(); entry != entryEnd; ++entry)
    341     address += (*entry)->emit(address);
    342 }
    343 
    344 void ELFDynamic::applySoname(uint64_t pStrTabIdx) {
    345   applyOne(llvm::ELF::DT_SONAME, pStrTabIdx);
    346 }
    347 
    348 }  // namespace mcld
    349