bool ARMGNULDBackend::mergeSection(Module& pModule, const Input& pInput, LDSection& pSection) { switch (pSection.type()) { case llvm::ELF::SHT_ARM_ATTRIBUTES: { return attribute().merge(pInput, pSection); } case llvm::ELF::SHT_ARM_EXIDX: { assert(NULL != pSection.getLink()); if ((pSection.getLink()->kind() == LDFileFormat::Ignore) || (pSection.getLink()->kind() == LDFileFormat::Folded)) { // if the target section of the .ARM.exidx is Ignore, then it should be // ignored as well pSection.setKind(LDFileFormat::Ignore); return true; } } /** fall through **/ default: { ObjectBuilder builder(pModule); builder.MergeSection(pInput, pSection); return true; } } // end of switch return true; }
void HexagonRelocator::scanRelocation(Relocation& pReloc, IRBuilder& pLinker, Module& pModule, LDSection& pSection, Input& pInput) { if (LinkerConfig::Object == config().codeGenType()) return; // rsym - The relocation target symbol ResolveInfo* rsym = pReloc.symInfo(); assert(rsym != NULL && "ResolveInfo of relocation not set while scanRelocation"); if (config().isCodeStatic()) return; assert(pSection.getLink() != NULL); if ((pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC) == 0) return; if (rsym->isLocal()) // rsym is local scanLocalReloc(pReloc, pLinker, pModule, pSection); else // rsym is external scanGlobalReloc(pReloc, pLinker, pModule, pSection); // check if we should issue undefined reference for the relocation target // symbol if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull()) issueUndefRef(pReloc, pSection, pInput); }
void NyuziRelocator::scanRelocation(Relocation& pReloc, IRBuilder& pBuilder, Module& pModule, LDSection& pSection, Input& pInput) { ResolveInfo* rsym = pReloc.symInfo(); assert(NULL != rsym && "ResolveInfo of relocation not set while scanRelocation"); assert(NULL != pSection.getLink()); if (0 == (pSection.getLink()->flag() & llvm::ELF::SHF_ALLOC)) return; // check if we shoule issue undefined reference for the relocation target // symbol if (rsym->isUndef() && !rsym->isDyn() && !rsym->isWeak() && !rsym->isNull()) issueUndefRef(pReloc, pSection, pInput); }
void HexagonRelocator::scanLocalReloc(Relocation& pReloc, IRBuilder& pBuilder, Module& pModule, LDSection& pSection) { // rsym - The relocation target symbol ResolveInfo* rsym = pReloc.symInfo(); switch (pReloc.type()) { case llvm::ELF::R_HEX_LO16: case llvm::ELF::R_HEX_HI16: case llvm::ELF::R_HEX_16: case llvm::ELF::R_HEX_8: case llvm::ELF::R_HEX_32_6_X: case llvm::ELF::R_HEX_16_X: case llvm::ELF::R_HEX_12_X: case llvm::ELF::R_HEX_11_X: case llvm::ELF::R_HEX_10_X: case llvm::ELF::R_HEX_9_X: case llvm::ELF::R_HEX_8_X: case llvm::ELF::R_HEX_7_X: case llvm::ELF::R_HEX_6_X: assert(!(rsym->reserved() & ReserveRel) && "Cannot apply this relocation for read only section"); return; case llvm::ELF::R_HEX_32: // If buiding PIC object (shared library or PIC executable), // a dynamic relocations with RELATIVE type to this location is needed. // Reserve an entry in .rel.dyn if (config().isCodeIndep()) { Relocation& reloc = helper_DynRel_init(rsym, *pReloc.targetRef().frag(), pReloc.targetRef().offset(), llvm::ELF::R_HEX_RELATIVE, *this); // we need to set up the relocation addend at apply relocation, record // the // relocation getRelRelMap().record(pReloc, reloc); // set Rel bit rsym->setReserved(rsym->reserved() | ReserveRel); getTarget().checkAndSetHasTextRel(*pSection.getLink()); } return; default: return; } }
/// getSectInfo - compute ElfXX_Shdr::sh_info uint64_t ELFObjectWriter::getSectInfo(const LDSection& pSection) const { if (llvm::ELF::SHT_SYMTAB == pSection.type() || llvm::ELF::SHT_DYNSYM == pSection.type()) return pSection.getInfo(); if (llvm::ELF::SHT_REL == pSection.type() || llvm::ELF::SHT_RELA == pSection.type()) { const LDSection* info_link = pSection.getLink(); if (NULL != info_link) return info_link->index(); } return 0x0; }
void ARMGNULDBackend::scanInputExceptionSections(Module& pModule, Input& pInput) { std::unique_ptr<ARMInputExMap> exMap(new ARMInputExMap()); // Scan the input and collect all related sections. LDContext* ctx = pInput.context(); for (LDContext::sect_iterator it = ctx->sectBegin(), end = ctx->sectEnd(); it != end; ++it) { LDSection* sect = *it; llvm::StringRef name(sect->name()); if (name.startswith(".ARM.exidx")) { ARMExSectionTuple* exTuple = exMap->getOrCreateByExSection(name); exTuple->setExIdxSection(sect); exTuple->setTextSection(sect->getLink()); } else if (name.startswith(".ARM.extab")) { ARMExSectionTuple* exTuple = exMap->getOrCreateByExSection(name); exTuple->setExTabSection(sect); } else if (name.startswith(".rel.ARM.exidx")) { ARMExSectionTuple* exTuple = exMap->getOrCreateByRelExSection(name); exTuple->setRelExIdxSection(sect); } else if (name.startswith(".rel.ARM.extab")) { ARMExSectionTuple* exTuple = exMap->getOrCreateByRelExSection(name); exTuple->setRelExIdxSection(sect); } } // Remove the invalid exception tuples and convert LDSection to RegionFragment // or RelocData. ARMInputExMap::iterator it = exMap->begin(); ARMInputExMap::iterator end = exMap->end(); while (it != end) { ARMExSectionTuple* exTuple = it->second.get(); LDSection* const text = exTuple->getTextSection(); LDSection* const exIdx = exTuple->getExIdxSection(); LDSection* const exTab = exTuple->getExTabSection(); LDSection* const relExIdx = exTuple->getRelExIdxSection(); LDSection* const relExTab = exTuple->getRelExTabSection(); // Check the .ARM.exidx section. if (!exIdx) { if (exTab) { fatal(diag::eh_missing_exidx_section) << exTab->name() << pInput.name(); } else if (relExIdx) { fatal(diag::eh_missing_exidx_section) << relExIdx->name() << pInput.name(); } else if (relExTab) { fatal(diag::eh_missing_exidx_section) << relExTab->name() << pInput.name(); } else { llvm_unreachable("unexpected bad exception tuple"); } } // Check the text section. if (!text) { fatal(diag::eh_missing_text_section) << exIdx->name() << pInput.name(); } // Ignore the exception section if the text section is ignored. if ((text->kind() == LDFileFormat::Ignore) || (text->kind() == LDFileFormat::Folded)) { // Set the related exception sections as LDFileFormat::Ignore. exIdx->setKind(LDFileFormat::Ignore); if (exTab) { exTab->setKind(LDFileFormat::Ignore); } // Remove this tuple from the input exception map. exMap->erase(it++); continue; } // Get RegionFragment from ".text", ".ARM.exidx", and ".ARM.extab" sections. RegionFragment* textFrag = findRegionFragment(*text); RegionFragment* exIdxFrag = findRegionFragment(*exIdx); RegionFragment* exTabFrag = exTab ? findRegionFragment(*exTab) : NULL; exTuple->setTextFragment(textFrag); exTuple->setExIdxFragment(exIdxFrag); exTuple->setExTabFragment(exTabFrag); // Get the RelocData from ".rel.ARM.exidx" and ".rel.ARM.extab" sections. RelocData* exIdxRD = relExIdx ? relExIdx->getRelocData() : NULL; RelocData* exTabRD = relExTab ? relExTab->getRelocData() : NULL; exTuple->setExIdxRelocData(exIdxRD); exTuple->setExTabRelocData(exTabRD); // If there is no region fragment in the .ARM.extab section, then we can // skip this tuple. if (!exIdxFrag) { exMap->erase(it++); continue; } // TODO: Sort the RelocData w.r.t. the fixup offset. // Check next tuple ++it; } // Add input map m_ExData.addInputMap(&pInput, std::move(exMap)); }
void HexagonRelocator::scanGlobalReloc(Relocation& pReloc, IRBuilder& pBuilder, Module& pModule, LDSection& pSection) { // rsym - The relocation target symbol ResolveInfo* rsym = pReloc.symInfo(); HexagonLDBackend& ld_backend = getTarget(); switch (pReloc.type()) { case llvm::ELF::R_HEX_LO16: case llvm::ELF::R_HEX_HI16: case llvm::ELF::R_HEX_16: case llvm::ELF::R_HEX_8: case llvm::ELF::R_HEX_32_6_X: case llvm::ELF::R_HEX_16_X: case llvm::ELF::R_HEX_12_X: case llvm::ELF::R_HEX_11_X: case llvm::ELF::R_HEX_10_X: case llvm::ELF::R_HEX_9_X: case llvm::ELF::R_HEX_8_X: case llvm::ELF::R_HEX_7_X: case llvm::ELF::R_HEX_6_X: assert(!(rsym->reserved() & ReserveRel) && "Cannot apply this relocation for read only section"); return; case llvm::ELF::R_HEX_32: if (ld_backend.symbolNeedsPLT(*rsym)) { // create PLT for this symbol if it does not have. if (!(rsym->reserved() & ReservePLT)) { helper_PLT_init(pReloc, *this); rsym->setReserved(rsym->reserved() | ReservePLT); } } if (ld_backend.symbolNeedsDynRel( *rsym, (rsym->reserved() & ReservePLT), true)) { if (ld_backend.symbolNeedsCopyReloc(pReloc, *rsym)) { LDSymbol& cpy_sym = defineSymbolforCopyReloc(pBuilder, *rsym, ld_backend); addCopyReloc(*cpy_sym.resolveInfo(), ld_backend); } else { Relocation& reloc = helper_DynRel_init(rsym, *pReloc.targetRef().frag(), pReloc.targetRef().offset(), llvm::ELF::R_HEX_RELATIVE, *this); // we need to set up the relocation addend at apply relocation, record // the // relocation getRelRelMap().record(pReloc, reloc); rsym->setReserved(rsym->reserved() | ReserveRel); ld_backend.checkAndSetHasTextRel(*pSection.getLink()); } } return; case llvm::ELF::R_HEX_GOTREL_LO16: case llvm::ELF::R_HEX_GOTREL_HI16: case llvm::ELF::R_HEX_GOTREL_32: case llvm::ELF::R_HEX_GOTREL_32_6_X: case llvm::ELF::R_HEX_GOTREL_16_X: case llvm::ELF::R_HEX_GOTREL_11_X: // This assumes that GOT exists return; case llvm::ELF::R_HEX_GOT_LO16: case llvm::ELF::R_HEX_GOT_HI16: case llvm::ELF::R_HEX_GOT_32: case llvm::ELF::R_HEX_GOT_16: case llvm::ELF::R_HEX_GOT_32_6_X: case llvm::ELF::R_HEX_GOT_16_X: case llvm::ELF::R_HEX_GOT_11_X: // Symbol needs GOT entry, reserve entry in .got // return if we already create GOT for this symbol if (rsym->reserved() & ReserveGOT) return; // If the GOT is used in statically linked binaries, // the GOT entry is enough and no relocation is needed. if (config().isCodeStatic()) helper_GOT_init(pReloc, false, *this); else helper_GOT_init(pReloc, true, *this); // set GOT bit rsym->setReserved(rsym->reserved() | ReserveGOT); return; case llvm::ELF::R_HEX_B22_PCREL: case llvm::ELF::R_HEX_B15_PCREL: case llvm::ELF::R_HEX_B7_PCREL: case llvm::ELF::R_HEX_B13_PCREL: case llvm::ELF::R_HEX_B9_PCREL: case llvm::ELF::R_HEX_B32_PCREL_X: case llvm::ELF::R_HEX_B22_PCREL_X: case llvm::ELF::R_HEX_B15_PCREL_X: case llvm::ELF::R_HEX_B13_PCREL_X: case llvm::ELF::R_HEX_B9_PCREL_X: case llvm::ELF::R_HEX_B7_PCREL_X: case llvm::ELF::R_HEX_32_PCREL: case llvm::ELF::R_HEX_6_PCREL_X: case llvm::ELF::R_HEX_PLT_B22_PCREL: if (rsym->reserved() & ReservePLT) return; if (ld_backend.symbolNeedsPLT(*rsym) || pReloc.type() == llvm::ELF::R_HEX_PLT_B22_PCREL) { helper_PLT_init(pReloc, *this); rsym->setReserved(rsym->reserved() | ReservePLT); } return; default: break; } // end of switch }