1 //===- Relocator.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 "mcld/LD/Relocator.h" 10 11 #include "mcld/Module.h" 12 #include "mcld/Fragment/Fragment.h" 13 #include "mcld/LD/LDContext.h" 14 #include "mcld/LD/LDSection.h" 15 #include "mcld/LD/LDSymbol.h" 16 #include "mcld/LD/ResolveInfo.h" 17 #include "mcld/LD/SectionData.h" 18 #include "mcld/Support/Demangle.h" 19 #include "mcld/Support/MsgHandling.h" 20 21 #include <sstream> 22 23 namespace mcld { 24 25 //===----------------------------------------------------------------------===// 26 // Relocator 27 //===----------------------------------------------------------------------===// ~Relocator()28Relocator::~Relocator() { 29 } 30 partialScanRelocation(Relocation & pReloc,Module & pModule)31void Relocator::partialScanRelocation(Relocation& pReloc, 32 Module& pModule) { 33 // if we meet a section symbol 34 if (pReloc.symInfo()->type() == ResolveInfo::Section) { 35 LDSymbol* input_sym = pReloc.symInfo()->outSymbol(); 36 37 // 1. update the relocation target offset 38 assert(input_sym->hasFragRef()); 39 uint64_t offset = input_sym->fragRef()->getOutputOffset(); 40 pReloc.target() += offset; 41 42 // 2. get output section symbol 43 // get the output LDSection which the symbol defined in 44 const LDSection& out_sect = 45 input_sym->fragRef()->frag()->getParent()->getSection(); 46 ResolveInfo* sym_info = 47 pModule.getSectionSymbolSet().get(out_sect)->resolveInfo(); 48 // set relocation target symbol to the output section symbol's resolveInfo 49 pReloc.setSymInfo(sym_info); 50 } 51 } 52 issueUndefRef(Relocation & pReloc,LDSection & pSection,Input & pInput)53void Relocator::issueUndefRef(Relocation& pReloc, 54 LDSection& pSection, 55 Input& pInput) { 56 FragmentRef::Offset undef_sym_pos = pReloc.targetRef().offset(); 57 std::string sect_name(pSection.name()); 58 // Drop .rel(a) prefix 59 sect_name = sect_name.substr(sect_name.find('.', /*pos=*/1)); 60 61 std::string reloc_sym(pReloc.symInfo()->name()); 62 reloc_sym = demangleName(reloc_sym); 63 64 std::stringstream ss; 65 ss << "0x" << std::hex << undef_sym_pos; 66 std::string undef_sym_pos_hex(ss.str()); 67 68 if (sect_name.substr(0, 5) != ".text") { 69 // Function name is only valid for text section 70 fatal(diag::undefined_reference) << reloc_sym << pInput.path() << sect_name 71 << undef_sym_pos_hex; 72 return; 73 } 74 75 std::string caller_file_name; 76 std::string caller_func_name; 77 for (LDContext::sym_iterator i = pInput.context()->symTabBegin(), 78 e = pInput.context()->symTabEnd(); 79 i != e; 80 ++i) { 81 LDSymbol& sym = **i; 82 if (sym.resolveInfo()->type() == ResolveInfo::File) 83 caller_file_name = sym.resolveInfo()->name(); 84 85 if (sym.resolveInfo()->type() == ResolveInfo::Function && 86 sym.value() <= undef_sym_pos && 87 sym.value() + sym.size() > undef_sym_pos) { 88 caller_func_name = sym.name(); 89 break; 90 } 91 } 92 93 caller_func_name = demangleName(caller_func_name); 94 95 fatal(diag::undefined_reference_text) << reloc_sym << pInput.path() 96 << caller_file_name << caller_func_name; 97 } 98 99 } // namespace mcld 100