1 //===- FragmentLinker.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 // 10 // This file implements the FragmentLinker class 11 // 12 //===----------------------------------------------------------------------===// 13 #include <mcld/Fragment/FragmentLinker.h> 14 15 #include <llvm/Support/Host.h> 16 #include <llvm/Support/raw_ostream.h> 17 #include <llvm/Support/Casting.h> 18 19 #include <mcld/LinkerConfig.h> 20 #include <mcld/Module.h> 21 #include <mcld/MC/MCLDInput.h> 22 #include <mcld/LD/BranchIslandFactory.h> 23 #include <mcld/LD/Resolver.h> 24 #include <mcld/LD/LDContext.h> 25 #include <mcld/LD/RelocationFactory.h> 26 #include <mcld/LD/RelocData.h> 27 #include <mcld/LD/SectionRules.h> 28 #include <mcld/Support/MemoryRegion.h> 29 #include <mcld/Support/MemoryArea.h> 30 #include <mcld/Support/FileHandle.h> 31 #include <mcld/Support/MsgHandling.h> 32 #include <mcld/Target/TargetLDBackend.h> 33 #include <mcld/Fragment/Relocation.h> 34 35 using namespace mcld; 36 37 //===----------------------------------------------------------------------===// 38 // FragmentLinker 39 //===----------------------------------------------------------------------===// 40 /// Constructor 41 FragmentLinker::FragmentLinker(const LinkerConfig& pConfig, 42 Module& pModule, 43 TargetLDBackend& pBackend) 44 45 : m_Config(pConfig), 46 m_Module(pModule), 47 m_Backend(pBackend) { 48 } 49 50 /// Destructor 51 FragmentLinker::~FragmentLinker() 52 { 53 } 54 55 bool FragmentLinker::finalizeSymbols() 56 { 57 Module::sym_iterator symbol, symEnd = m_Module.sym_end(); 58 for (symbol = m_Module.sym_begin(); symbol != symEnd; ++symbol) { 59 60 if ((*symbol)->resolveInfo()->isAbsolute() || 61 (*symbol)->resolveInfo()->type() == ResolveInfo::File) { 62 // absolute symbols or symbols with function type should have 63 // zero value 64 (*symbol)->setValue(0x0); 65 continue; 66 } 67 68 if ((*symbol)->resolveInfo()->type() == ResolveInfo::ThreadLocal) { 69 m_Backend.finalizeTLSSymbol(**symbol); 70 continue; 71 } 72 73 if ((*symbol)->hasFragRef()) { 74 // set the virtual address of the symbol. If the output file is 75 // relocatable object file, the section's virtual address becomes zero. 76 // And the symbol's value become section relative offset. 77 uint64_t value = (*symbol)->fragRef()->getOutputOffset(); 78 assert(NULL != (*symbol)->fragRef()->frag()); 79 uint64_t addr = (*symbol)->fragRef()->frag()->getParent()->getSection().addr(); 80 (*symbol)->setValue(value + addr); 81 continue; 82 } 83 } 84 85 return true; 86 } 87 88 //===----------------------------------------------------------------------===// 89 // Relocation Operations 90 //===----------------------------------------------------------------------===// 91 bool FragmentLinker::applyRelocations() 92 { 93 // when producing relocatables, no need to apply relocation 94 if (LinkerConfig::Object == m_Config.codeGenType()) 95 return true; 96 97 // apply all relocations of all inputs 98 Module::obj_iterator input, inEnd = m_Module.obj_end(); 99 for (input = m_Module.obj_begin(); input != inEnd; ++input) { 100 LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); 101 for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 102 // bypass the reloc section if 103 // 1. its section kind is changed to Ignore. (The target section is a 104 // discarded group section.) 105 // 2. it has no reloc data. (All symbols in the input relocs are in the 106 // discarded group sections) 107 if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData()) 108 continue; 109 RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end(); 110 for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) { 111 Relocation* relocation = llvm::cast<Relocation>(reloc); 112 relocation->apply(*m_Backend.getRelocator()); 113 } // for all relocations 114 } // for all relocation section 115 } // for all inputs 116 117 // apply relocations created by relaxation 118 BranchIslandFactory* br_factory = m_Backend.getBRIslandFactory(); 119 BranchIslandFactory::iterator facIter, facEnd = br_factory->end(); 120 for (facIter = br_factory->begin(); facIter != facEnd; ++facIter) { 121 BranchIsland& island = *facIter; 122 BranchIsland::reloc_iterator iter, iterEnd = island.reloc_end(); 123 for (iter = island.reloc_begin(); iter != iterEnd; ++iter) 124 (*iter)->apply(*m_Backend.getRelocator()); 125 } 126 return true; 127 } 128 129 130 void FragmentLinker::syncRelocationResult(MemoryArea& pOutput) 131 { 132 if (LinkerConfig::Object != m_Config.codeGenType()) 133 normalSyncRelocationResult(pOutput); 134 else 135 partialSyncRelocationResult(pOutput); 136 return; 137 } 138 139 void FragmentLinker::normalSyncRelocationResult(MemoryArea& pOutput) 140 { 141 MemoryRegion* region = pOutput.request(0, pOutput.handler()->size()); 142 143 uint8_t* data = region->getBuffer(); 144 145 // sync all relocations of all inputs 146 Module::obj_iterator input, inEnd = m_Module.obj_end(); 147 for (input = m_Module.obj_begin(); input != inEnd; ++input) { 148 LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); 149 for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 150 // bypass the reloc section if 151 // 1. its section kind is changed to Ignore. (The target section is a 152 // discarded group section.) 153 // 2. it has no reloc data. (All symbols in the input relocs are in the 154 // discarded group sections) 155 if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData()) 156 continue; 157 RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end(); 158 for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) { 159 Relocation* relocation = llvm::cast<Relocation>(reloc); 160 161 // bypass the relocation with NONE type. This is to avoid overwrite the 162 // target result by NONE type relocation if there is a place which has 163 // two relocations to apply to, and one of it is NONE type. The result 164 // we want is the value of the other relocation result. For example, 165 // in .exidx, there are usually an R_ARM_NONE and R_ARM_PREL31 apply to 166 // the same place 167 if (0x0 == relocation->type()) 168 continue; 169 writeRelocationResult(*relocation, data); 170 } // for all relocations 171 } // for all relocation section 172 } // for all inputs 173 174 // sync relocations created by relaxation 175 BranchIslandFactory* br_factory = m_Backend.getBRIslandFactory(); 176 BranchIslandFactory::iterator facIter, facEnd = br_factory->end(); 177 for (facIter = br_factory->begin(); facIter != facEnd; ++facIter) { 178 BranchIsland& island = *facIter; 179 BranchIsland::reloc_iterator iter, iterEnd = island.reloc_end(); 180 for (iter = island.reloc_begin(); iter != iterEnd; ++iter) { 181 Relocation* reloc = *iter; 182 writeRelocationResult(*reloc, data); 183 } 184 } 185 186 pOutput.clear(); 187 } 188 189 void FragmentLinker::partialSyncRelocationResult(MemoryArea& pOutput) 190 { 191 MemoryRegion* region = pOutput.request(0, pOutput.handler()->size()); 192 193 uint8_t* data = region->getBuffer(); 194 195 // traverse outputs' LDSection to get RelocData 196 Module::iterator sectIter, sectEnd = m_Module.end(); 197 for (sectIter = m_Module.begin(); sectIter != sectEnd; ++sectIter) { 198 if (LDFileFormat::Relocation != (*sectIter)->kind()) 199 continue; 200 201 RelocData* reloc_data = (*sectIter)->getRelocData(); 202 RelocData::iterator relocIter, relocEnd = reloc_data->end(); 203 for (relocIter = reloc_data->begin(); relocIter != relocEnd; ++relocIter) { 204 Relocation* reloc = llvm::cast<Relocation>(relocIter); 205 206 // bypass the relocation with NONE type. This is to avoid overwrite the 207 // target result by NONE type relocation if there is a place which has 208 // two relocations to apply to, and one of it is NONE type. The result 209 // we want is the value of the other relocation result. For example, 210 // in .exidx, there are usually an R_ARM_NONE and R_ARM_PREL31 apply to 211 // the same place 212 if (0x0 == reloc->type()) 213 continue; 214 writeRelocationResult(*reloc, data); 215 } 216 } 217 218 pOutput.clear(); 219 } 220 221 void FragmentLinker::writeRelocationResult(Relocation& pReloc, uint8_t* pOutput) 222 { 223 // get output file offset 224 size_t out_offset = 225 pReloc.targetRef().frag()->getParent()->getSection().offset() + 226 pReloc.targetRef().getOutputOffset(); 227 228 uint8_t* target_addr = pOutput + out_offset; 229 // byte swapping if target and host has different endian, and then write back 230 if(llvm::sys::isLittleEndianHost() != m_Config.targets().isLittleEndian()) { 231 uint64_t tmp_data = 0; 232 233 switch(pReloc.size(*m_Backend.getRelocator())) { 234 case 8u: 235 std::memcpy(target_addr, &pReloc.target(), 1); 236 break; 237 238 case 16u: 239 tmp_data = mcld::bswap16(pReloc.target()); 240 std::memcpy(target_addr, &tmp_data, 2); 241 break; 242 243 case 32u: 244 tmp_data = mcld::bswap32(pReloc.target()); 245 std::memcpy(target_addr, &tmp_data, 4); 246 break; 247 248 case 64u: 249 tmp_data = mcld::bswap64(pReloc.target()); 250 std::memcpy(target_addr, &tmp_data, 8); 251 break; 252 253 default: 254 break; 255 } 256 } 257 else 258 std::memcpy(target_addr, &pReloc.target(), 259 pReloc.size(*m_Backend.getRelocator())/8); 260 } 261 262