16f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===- Relocator.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//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/Relocator.h" 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Module.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/Fragment.h" 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDContext.h" 1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSection.h" 1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSymbol.h" 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ResolveInfo.h" 1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/SectionData.h" 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/Demangle.h" 1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h" 2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 2187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <sstream> 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// Relocator 276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 2837b74a387bb3993387029859c2d9d051c41c724eStephen HinesRelocator::~Relocator() { 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 31f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesvoid Relocator::partialScanRelocation(Relocation& pReloc, 3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines Module& pModule) { 33f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // if we meet a section symbol 34f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pReloc.symInfo()->type() == ResolveInfo::Section) { 35f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSymbol* input_sym = pReloc.symInfo()->outSymbol(); 36f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 37f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // 1. update the relocation target offset 38f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines assert(input_sym->hasFragRef()); 39f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines uint64_t offset = input_sym->fragRef()->getOutputOffset(); 40f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pReloc.target() += offset; 41f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 42f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // 2. get output section symbol 43f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // get the output LDSection which the symbol defined in 44f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines const LDSection& out_sect = 4537b74a387bb3993387029859c2d9d051c41c724eStephen Hines input_sym->fragRef()->frag()->getParent()->getSection(); 46f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo* sym_info = 4737b74a387bb3993387029859c2d9d051c41c724eStephen Hines pModule.getSectionSymbolSet().get(out_sect)->resolveInfo(); 48f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // set relocation target symbol to the output section symbol's resolveInfo 49f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pReloc.setSymInfo(sym_info); 50f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 51f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} 52f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 5387f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid Relocator::issueUndefRef(Relocation& pReloc, 5487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection& pSection, 5537b74a387bb3993387029859c2d9d051c41c724eStephen Hines Input& pInput) { 5687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines FragmentRef::Offset undef_sym_pos = pReloc.targetRef().offset(); 5787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines std::string sect_name(pSection.name()); 5837b74a387bb3993387029859c2d9d051c41c724eStephen Hines // Drop .rel(a) prefix 5937b74a387bb3993387029859c2d9d051c41c724eStephen Hines sect_name = sect_name.substr(sect_name.find('.', /*pos=*/1)); 6087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 6187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines std::string reloc_sym(pReloc.symInfo()->name()); 620dea6bc96bb52346737966839ac68644f7939f58Stephen Hines reloc_sym = demangleName(reloc_sym); 6387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 6487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines std::stringstream ss; 6587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ss << "0x" << std::hex << undef_sym_pos; 6687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines std::string undef_sym_pos_hex(ss.str()); 6787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 6887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (sect_name.substr(0, 5) != ".text") { 6987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Function name is only valid for text section 7037b74a387bb3993387029859c2d9d051c41c724eStephen Hines fatal(diag::undefined_reference) << reloc_sym << pInput.path() << sect_name 7187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines << undef_sym_pos_hex; 7287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return; 7387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 7487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 7587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines std::string caller_file_name; 7687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines std::string caller_func_name; 7787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (LDContext::sym_iterator i = pInput.context()->symTabBegin(), 7837b74a387bb3993387029859c2d9d051c41c724eStephen Hines e = pInput.context()->symTabEnd(); 7937b74a387bb3993387029859c2d9d051c41c724eStephen Hines i != e; 8037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++i) { 8187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSymbol& sym = **i; 8287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (sym.resolveInfo()->type() == ResolveInfo::File) 8387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines caller_file_name = sym.resolveInfo()->name(); 8487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 8587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (sym.resolveInfo()->type() == ResolveInfo::Function && 8687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines sym.value() <= undef_sym_pos && 8787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines sym.value() + sym.size() > undef_sym_pos) { 8887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines caller_func_name = sym.name(); 8987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines break; 9087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 9187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 9287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 930dea6bc96bb52346737966839ac68644f7939f58Stephen Hines caller_func_name = demangleName(caller_func_name); 9487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 9537b74a387bb3993387029859c2d9d051c41c724eStephen Hines fatal(diag::undefined_reference_text) << reloc_sym << pInput.path() 9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines << caller_file_name << caller_func_name; 9787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 9837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 9937b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 100