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