void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) { InputSectionBase *Sec = getRelocatedSection(); for (const RelTy &Rel : Rels) { RelType Type = Rel.getType(Config->IsMips64EL); Symbol &Sym = getFile<ELFT>()->getRelocTargetSym(Rel); auto *P = reinterpret_cast<typename ELFT::Rela *>(Buf); Buf += sizeof(RelTy); if (Config->IsRela) P->r_addend = getAddend<ELFT>(Rel); // Output section VA is zero for -r, so r_offset is an offset within the // section, but for --emit-relocs it is an virtual address. P->r_offset = Sec->getOutputSection()->Addr + Sec->getOffset(Rel.r_offset); P->setSymbolAndType(InX::SymTab->getSymbolIndex(&Sym), Type, Config->IsMips64EL); if (Sym.Type == STT_SECTION) { // We combine multiple section symbols into only one per // section. This means we have to update the addend. That is // trivial for Elf_Rela, but for Elf_Rel we have to write to the // section data. We do that by adding to the Relocation vector. // .eh_frame is horribly special and can reference discarded sections. To // avoid having to parse and recreate .eh_frame, we just replace any // relocation in it pointing to discarded sections with R_*_NONE, which // hopefully creates a frame that is ignored at runtime. auto *D = dyn_cast<Defined>(&Sym); if (!D) { error("STT_SECTION symbol should be defined"); continue; } SectionBase *Section = D->Section; if (Section == &InputSection::Discarded) { P->setSymbolAndType(0, 0, false); continue; } if (Config->IsRela) { P->r_addend = Sym.getVA(getAddend<ELFT>(Rel)) - Section->getOutputSection()->Addr; } else if (Config->Relocatable) { const uint8_t *BufLoc = Sec->Data.begin() + Rel.r_offset; Sec->Relocations.push_back({R_ABS, Type, Rel.r_offset, Target->getImplicitAddend(BufLoc, Type), &Sym}); } } } }
template <class ELFT> void OutputSection::finalize() { if (Type == SHT_NOBITS) for (BaseCommand *Base : SectionCommands) if (isa<ByteCommand>(Base)) Type = SHT_PROGBITS; std::vector<InputSection *> V = getInputSections(this); InputSection *First = V.empty() ? nullptr : V[0]; if (Flags & SHF_LINK_ORDER) { // We must preserve the link order dependency of sections with the // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We // need to translate the InputSection sh_link to the OutputSection sh_link, // all InputSections in the OutputSection have the same dependency. if (auto *D = First->getLinkOrderDep()) Link = D->getParent()->SectionIndex; } if (Type == SHT_GROUP) { finalizeShtGroup<ELFT>(this, First); return; } if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL)) return; if (isa<SyntheticSection>(First)) return; Link = In.SymTab->getParent()->SectionIndex; // sh_info for SHT_REL[A] sections should contain the section header index of // the section to which the relocation applies. InputSectionBase *S = First->getRelocatedSection(); Info = S->getOutputSection()->SectionIndex; Flags |= SHF_INFO_LINK; }