122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===- FragmentLinker.cpp -------------------------------------------------===// 25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// The MCLinker Project 45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source 65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details. 75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 1022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// This file implements the FragmentLinker class 115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FragmentLinker.h> 14cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 15cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Host.h> 16cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/raw_ostream.h> 1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/Support/Casting.h> 18cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h> 2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h> 21f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/LD/LDSection.h> 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInput.h> 23f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/LD/LDSection.h> 2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/BranchIslandFactory.h> 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/Resolver.h> 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDContext.h> 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/RelocationFactory.h> 2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/RelocData.h> 29f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/LD/Relocator.h> 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h> 3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MemoryArea.h> 3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/FileHandle.h> 33affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/TargetLDBackend.h> 35d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/Fragment/Relocation.h> 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 39d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===----------------------------------------------------------------------===// 40d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao// FragmentLinker 41d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===----------------------------------------------------------------------===// 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Constructor 4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoFragmentLinker::FragmentLinker(const LinkerConfig& pConfig, 4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module& pModule, 4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao TargetLDBackend& pBackend) 4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao : m_Config(pConfig), 4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_Module(pModule), 4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_Backend(pBackend) { 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Destructor 5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoFragmentLinker::~FragmentLinker() 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool FragmentLinker::finalizeSymbols() 58cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{ 5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::sym_iterator symbol, symEnd = m_Module.sym_end(); 6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (symbol = m_Module.sym_begin(); symbol != symEnd; ++symbol) { 61cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 62cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if ((*symbol)->resolveInfo()->isAbsolute() || 63cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao (*symbol)->resolveInfo()->type() == ResolveInfo::File) { 64cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // absolute symbols or symbols with function type should have 65cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // zero value 66cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao (*symbol)->setValue(0x0); 67cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao continue; 68cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } 69cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if ((*symbol)->resolveInfo()->type() == ResolveInfo::ThreadLocal) { 7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao m_Backend.finalizeTLSSymbol(**symbol); 7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 75cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao if ((*symbol)->hasFragRef()) { 76cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // set the virtual address of the symbol. If the output file is 77cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // relocatable object file, the section's virtual address becomes zero. 78cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao // And the symbol's value become section relative offset. 7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t value = (*symbol)->fragRef()->getOutputOffset(); 80cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao assert(NULL != (*symbol)->fragRef()->frag()); 8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t addr = (*symbol)->fragRef()->frag()->getParent()->getSection().addr(); 82cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao (*symbol)->setValue(value + addr); 83cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao continue; 84cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } 85cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao } 86cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 88cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao} 89cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 90cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 91cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao// Relocation Operations 92cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao//===----------------------------------------------------------------------===// 9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool FragmentLinker::applyRelocations() 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // when producing relocatables, no need to apply relocation 9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object == m_Config.codeGenType()) 9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // apply all relocations of all inputs 10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::obj_iterator input, inEnd = m_Module.obj_end(); 10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (input = m_Module.obj_begin(); input != inEnd; ++input) { 102f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_Backend.getRelocator()->initializeApply(**input); 10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); 10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // bypass the reloc section if 10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 1. its section kind is changed to Ignore. (The target section is a 10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // discarded group section.) 10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 2. it has no reloc data. (All symbols in the input relocs are in the 10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // discarded group sections) 11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData()) 11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end(); 11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) { 11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Relocation* relocation = llvm::cast<Relocation>(reloc); 115d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao relocation->apply(*m_Backend.getRelocator()); 11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // for all relocations 11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // for all relocation section 118f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines m_Backend.getRelocator()->finalizeApply(**input); 11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // for all inputs 12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // apply relocations created by relaxation 12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao BranchIslandFactory* br_factory = m_Backend.getBRIslandFactory(); 12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao BranchIslandFactory::iterator facIter, facEnd = br_factory->end(); 12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (facIter = br_factory->begin(); facIter != facEnd; ++facIter) { 12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao BranchIsland& island = *facIter; 12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao BranchIsland::reloc_iterator iter, iterEnd = island.reloc_end(); 12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (iter = island.reloc_begin(); iter != iterEnd; ++iter) 128d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (*iter)->apply(*m_Backend.getRelocator()); 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return true; 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid FragmentLinker::syncRelocationResult(MemoryArea& pOutput) 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LinkerConfig::Object != m_Config.codeGenType()) 13722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao normalSyncRelocationResult(pOutput); 13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao partialSyncRelocationResult(pOutput); 14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return; 14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid FragmentLinker::normalSyncRelocationResult(MemoryArea& pOutput) 14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* region = pOutput.request(0, pOutput.handler()->size()); 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint8_t* data = region->getBuffer(); 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // sync all relocations of all inputs 15022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::obj_iterator input, inEnd = m_Module.obj_end(); 15122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (input = m_Module.obj_begin(); input != inEnd; ++input) { 15222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd(); 15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) { 15422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // bypass the reloc section if 15522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 1. its section kind is changed to Ignore. (The target section is a 15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // discarded group section.) 15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // 2. it has no reloc data. (All symbols in the input relocs are in the 15822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // discarded group sections) 15922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData()) 16022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 16122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end(); 16222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) { 16322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Relocation* relocation = llvm::cast<Relocation>(reloc); 16422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 16522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // bypass the relocation with NONE type. This is to avoid overwrite the 16622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // target result by NONE type relocation if there is a place which has 16722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // two relocations to apply to, and one of it is NONE type. The result 16822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // we want is the value of the other relocation result. For example, 16922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // in .exidx, there are usually an R_ARM_NONE and R_ARM_PREL31 apply to 17022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // the same place 17122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0x0 == relocation->type()) 17222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 17322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao writeRelocationResult(*relocation, data); 17422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // for all relocations 17522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // for all relocation section 17622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // for all inputs 17722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 17822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // sync relocations created by relaxation 17922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao BranchIslandFactory* br_factory = m_Backend.getBRIslandFactory(); 18022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao BranchIslandFactory::iterator facIter, facEnd = br_factory->end(); 18122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (facIter = br_factory->begin(); facIter != facEnd; ++facIter) { 18222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao BranchIsland& island = *facIter; 18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao BranchIsland::reloc_iterator iter, iterEnd = island.reloc_end(); 18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (iter = island.reloc_begin(); iter != iterEnd; ++iter) { 18522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Relocation* reloc = *iter; 18622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao writeRelocationResult(*reloc, data); 18722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 19022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pOutput.clear(); 19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 19322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid FragmentLinker::partialSyncRelocationResult(MemoryArea& pOutput) 19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 19522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* region = pOutput.request(0, pOutput.handler()->size()); 1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint8_t* data = region->getBuffer(); 1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 19922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // traverse outputs' LDSection to get RelocData 20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator sectIter, sectEnd = m_Module.end(); 20122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (sectIter = m_Module.begin(); sectIter != sectEnd; ++sectIter) { 20222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LDFileFormat::Relocation != (*sectIter)->kind()) 20322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 20522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao RelocData* reloc_data = (*sectIter)->getRelocData(); 20622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao RelocData::iterator relocIter, relocEnd = reloc_data->end(); 20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (relocIter = reloc_data->begin(); relocIter != relocEnd; ++relocIter) { 20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Relocation* reloc = llvm::cast<Relocation>(relocIter); 20922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 21022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // bypass the relocation with NONE type. This is to avoid overwrite the 21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // target result by NONE type relocation if there is a place which has 21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // two relocations to apply to, and one of it is NONE type. The result 21322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // we want is the value of the other relocation result. For example, 21422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // in .exidx, there are usually an R_ARM_NONE and R_ARM_PREL31 apply to 21522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // the same place 21622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0x0 == reloc->type()) 21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao writeRelocationResult(*reloc, data); 2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pOutput.clear(); 2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaovoid FragmentLinker::writeRelocationResult(Relocation& pReloc, uint8_t* pOutput) 226affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 22722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get output file offset 2286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t out_offset = 2296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pReloc.targetRef().frag()->getParent()->getSection().offset() + 2306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pReloc.targetRef().getOutputOffset(); 23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint8_t* target_addr = pOutput + out_offset; 23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // byte swapping if target and host has different endian, and then write back 23421433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if(llvm::sys::IsLittleEndianHost != m_Config.targets().isLittleEndian()) { 23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t tmp_data = 0; 23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines switch(pReloc.size(*m_Backend.getRelocator())) { 2386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case 8u: 2396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::memcpy(target_addr, &pReloc.target(), 1); 2406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 2416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case 16u: 2436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines tmp_data = mcld::bswap16(pReloc.target()); 2446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::memcpy(target_addr, &tmp_data, 2); 2456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 2466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 24722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case 32u: 248d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao tmp_data = mcld::bswap32(pReloc.target()); 24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao std::memcpy(target_addr, &tmp_data, 4); 25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case 64u: 253d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao tmp_data = mcld::bswap64(pReloc.target()); 25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao std::memcpy(target_addr, &tmp_data, 8); 25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 259affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 260affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 2626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::memcpy(target_addr, &pReloc.target(), 2636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pReloc.size(*m_Backend.getRelocator())/8); 264affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 265affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 266