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