/// emitRelocation void ELFObjectWriter::emitRelocation(const LinkerConfig& pConfig, const LDSection& pSection, MemoryRegion& pRegion) const { const RelocData* sect_data = pSection.getRelocData(); assert(NULL != sect_data && "SectionData is NULL in emitRelocation!"); if (pSection.type() == SHT_REL) { if (pConfig.targets().is32Bits()) emitRel<32>(pConfig, *sect_data, pRegion); else if (pConfig.targets().is64Bits()) emitRel<64>(pConfig, *sect_data, pRegion); else { fatal(diag::unsupported_bitclass) << pConfig.targets().triple().str() << pConfig.targets().bitclass(); } } else if (pSection.type() == SHT_RELA) { if (pConfig.targets().is32Bits()) emitRela<32>(pConfig, *sect_data, pRegion); else if (pConfig.targets().is64Bits()) emitRela<64>(pConfig, *sect_data, pRegion); else { fatal(diag::unsupported_bitclass) << pConfig.targets().triple().str() << pConfig.targets().bitclass(); } } else llvm::report_fatal_error("unsupported relocation section type!"); }
/// 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; }
bool ARMGNULDBackend::readSection(Input& pInput, MCLinker& pLinker, LDSection& pInputSectHdr) { LDSection& out_sect = pLinker.getOrCreateOutputSectHdr(pInputSectHdr.name(), pInputSectHdr.kind(), pInputSectHdr.type(), pInputSectHdr.flag()); // FIXME: (Luba) // Handle ARM attributes in the right way. // In current milestone, MCLinker goes through the shortcut. // It reads input's ARM attributes and copies the first ARM attributes // into the output file. The correct way is merge these sections, not // just copy. if ((0 == out_sect.name().compare(".ARM.attributes")) && (0 != out_sect.size())) return true; MemoryRegion* region = pInput.memArea()->request(pInputSectHdr.offset(), pInputSectHdr.size()); llvm::MCSectionData& sect_data = pLinker.getOrCreateSectData(pInputSectHdr); new MCRegionFragment(*region, §_data); out_sect.setSize(out_sect.size() + pInputSectHdr.size()); return true; }
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; }
uint64_t ELFObjectWriter::getSectEntrySize(const LDSection& pSection) const { typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word; typedef typename ELFSizeTraits<SIZE>::Sym ElfXX_Sym; typedef typename ELFSizeTraits<SIZE>::Rel ElfXX_Rel; typedef typename ELFSizeTraits<SIZE>::Rela ElfXX_Rela; typedef typename ELFSizeTraits<SIZE>::Dyn ElfXX_Dyn; if (llvm::ELF::SHT_DYNSYM == pSection.type() || llvm::ELF::SHT_SYMTAB == pSection.type()) return sizeof(ElfXX_Sym); if (llvm::ELF::SHT_REL == pSection.type()) return sizeof(ElfXX_Rel); if (llvm::ELF::SHT_RELA == pSection.type()) return sizeof(ElfXX_Rela); if (llvm::ELF::SHT_HASH == pSection.type() || llvm::ELF::SHT_GNU_HASH == pSection.type()) return sizeof(ElfXX_Word); if (llvm::ELF::SHT_DYNAMIC == pSection.type()) return sizeof(ElfXX_Dyn); return 0x0; }
bool MipsAbiFlags::fillBySection(const Input& pInput, const LDSection& pSection, MipsAbiFlags& mipsAbi) { assert(pSection.type() == llvm::ELF::SHT_MIPS_ABIFLAGS && "Unexpected section type"); if (pSection.size() != size()) { error(diag::error_Mips_abiflags_invalid_size) << pInput.name(); return false; } const SectionData* secData = pSection.getSectionData(); if (secData->size() != 2 || !llvm::isa<RegionFragment>(secData->front())) { error(diag::error_Mips_abiflags_invalid_size) << pInput.name(); return false; } const auto& frag = llvm::cast<RegionFragment>(secData->front()); auto* data = reinterpret_cast<const ElfMipsAbiFlags*>(frag.getRegion().data()); if (data->version != 0) { error(diag::error_Mips_abiflags_invalid_version) << int(data->version) << pInput.name(); return false; } mipsAbi.m_IsaLevel = data->isa_level; mipsAbi.m_IsaRev = data->isa_rev; mipsAbi.m_GprSize = data->gpr_size; mipsAbi.m_Cpr1Size = data->cpr1_size; mipsAbi.m_Cpr2Size = data->cpr2_size; mipsAbi.m_FpAbi = data->fp_abi; mipsAbi.m_IsaExt = data->isa_ext; mipsAbi.m_Ases = data->ases; mipsAbi.m_Flags1 = data->flags1; return true; }
/// getSectLink - compute ElfXX_Shdr::sh_link uint64_t ELFObjectWriter::getSectLink(const LDSection& pSection, const LinkerConfig& pConfig) const { if (llvm::ELF::SHT_SYMTAB == pSection.type()) return target().getOutputFormat()->getStrTab().index(); if (llvm::ELF::SHT_DYNSYM == pSection.type()) return target().getOutputFormat()->getDynStrTab().index(); if (llvm::ELF::SHT_DYNAMIC == pSection.type()) return target().getOutputFormat()->getDynStrTab().index(); if (llvm::ELF::SHT_HASH == pSection.type() || llvm::ELF::SHT_GNU_HASH == pSection.type()) return target().getOutputFormat()->getDynSymTab().index(); if (llvm::ELF::SHT_REL == pSection.type() || llvm::ELF::SHT_RELA == pSection.type()) { if (LinkerConfig::Object == pConfig.codeGenType()) return target().getOutputFormat()->getSymTab().index(); else return target().getOutputFormat()->getDynSymTab().index(); } // FIXME: currently we link ARM_EXIDX section to output text section here if (llvm::ELF::SHT_ARM_EXIDX == pSection.type()) return target().getOutputFormat()->getText().index(); return llvm::ELF::SHN_UNDEF; }