Home | History | Annotate | Download | only in LD
      1 //===- SectionMap.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 <cassert>
     10 #include <cstring>
     11 #include <mcld/LD/SectionMap.h>
     12 
     13 using namespace mcld;
     14 
     15 //==========================
     16 // SectionMap
     17 
     18 SectionMap::SectionMap()
     19 {
     20 }
     21 
     22 SectionMap::~SectionMap()
     23 {
     24 }
     25 
     26 const std::string& SectionMap::getOutputSectName(const std::string& pInput)
     27 {
     28   iterator it;
     29   for (it = begin(); it != end(); ++it) {
     30     if (0 == strncmp(pInput.c_str(),
     31                      (*it).inputSubStr.c_str(),
     32                      (*it).inputSubStr.length()))
     33       break;
     34     // wildcard to a user-defined output section.
     35     else if (0 == strcmp("*", (*it).inputSubStr.c_str()))
     36       break;
     37   }
     38   // if still no matching, just let a output seciton has the same input name
     39   if (it == end())
     40     return pInput;
     41 
     42   return (*it).outputStr;
     43 }
     44 
     45 bool SectionMap::push_back(const std::string& pInput,
     46                            const std::string& pOutput,
     47                            const uint64_t pOffset)
     48 {
     49   // Now only check if the mapping exists in the map already
     50   // TODO: handle the cases such as overriding the exist mapping and drawing
     51   //       exception from the given SECTIONS command
     52   iterator it;
     53   for (it = begin(); it != end(); ++it) {
     54     if (pInput == (*it).inputSubStr)
     55       return false;
     56   }
     57   struct Mapping mapping = {
     58     pInput,
     59     pOutput,
     60     pOffset,
     61   };
     62   m_SectMap.push_back(mapping);
     63   return true;
     64 }
     65 
     66 SectionMap::iterator SectionMap::find(const std::string& pInput)
     67 {
     68   iterator it;
     69   for (it = begin(); it != end(); ++it) {
     70     if(pInput == (*it).inputSubStr)
     71       break;
     72   }
     73   return it;
     74 }
     75 
     76 SectionMap::Mapping* SectionMap::at(const std::string& pInput)
     77 {
     78   iterator it;
     79   for (it = begin(); it != end(); ++it) {
     80     if(pInput == (*it).inputSubStr)
     81       break;
     82   }
     83   if (end() == it)
     84     return NULL;
     85   return &(*it);
     86 }
     87 
     88 // Common mappings of ELF and other formants. Now only ELF specific mappings are added
     89 const SectionMap::SectionNameMapping SectionMap::m_StdSectionMap[] =
     90 {
     91   {".text", ".text"},
     92   {".rodata", ".rodata"},
     93   {".data.rel.ro.local", ".data.rel.ro.local"},
     94   {".data.rel.ro", ".data.rel.ro"},
     95   {".data", ".data"},
     96   {".bss", ".bss"},
     97   {".tdata", ".tdata"},
     98   {".tbss", ".tbss"},
     99   {".init_array", ".init_array"},
    100   {".fini_array", ".fini_array"},
    101   // TODO: Support DT_INIT_ARRAY for all constructors?
    102   {".ctors", ".ctors"},
    103   {".dtors", ".dtors"},
    104   {".sdata", ".sdata"},
    105   {".sbss", ".sbss"},
    106   // FIXME: in GNU ld, if we are creating a shared object .sdata2 and .sbss2
    107   // sections would be handled differently.
    108   {".sdata2", ".sdata"},
    109   {".sbss2", ".sbss"},
    110   {".lrodata", ".lrodata"},
    111   {".ldata", ".ldata"},
    112   {".lbss", ".lbss"},
    113   {".gcc_except_table", ".gcc_except_table"},
    114   {".gnu.linkonce.d.rel.ro.local", ".data.rel.ro.local"},
    115   {".gnu.linkonce.d.rel.ro", ".data.rel.ro"},
    116   {".gnu.linkonce.t", ".text"},
    117   {".gnu.linkonce.r", ".rodata"},
    118   {".gnu.linkonce.d", ".data"},
    119   {".gnu.linkonce.b", ".bss"},
    120   {".gnu.linkonce.s", ".sdata"},
    121   {".gnu.linkonce.sb", ".sbss"},
    122   {".gnu.linkonce.s2", ".sdata"},
    123   {".gnu.linkonce.sb2", ".sbss"},
    124   {".gnu.linkonce.wi", ".debug_info"},
    125   {".gnu.linkonce.td", ".tdata"},
    126   {".gnu.linkonce.tb", ".tbss"},
    127   {".gnu.linkonce.lr", ".lrodata"},
    128   {".gnu.linkonce.l", ".ldata"},
    129   {".gnu.linkonce.lb", ".lbss"},
    130 };
    131 
    132 const int SectionMap::m_StdSectionMapSize =
    133   (sizeof(SectionMap::m_StdSectionMap) / sizeof(SectionMap::m_StdSectionMap[0]));
    134 
    135 bool SectionMap::initStdSectionMap()
    136 {
    137   for (int i = 0; i < m_StdSectionMapSize; ++i) {
    138     if (!push_back(m_StdSectionMap[i].from, m_StdSectionMap[i].to))
    139       return false;
    140   }
    141   return true;
    142 }
    143