bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::MipsABIFlags &Section, ContiguousBlobAccumulator &CBA) { assert(Section.Type == llvm::ELF::SHT_MIPS_ABIFLAGS && "Section type is not SHT_MIPS_ABIFLAGS"); object::Elf_Mips_ABIFlags<ELFT> Flags; zero(Flags); SHeader.sh_entsize = sizeof(Flags); SHeader.sh_size = SHeader.sh_entsize; auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); Flags.version = Section.Version; Flags.isa_level = Section.ISALevel; Flags.isa_rev = Section.ISARevision; Flags.gpr_size = Section.GPRSize; Flags.cpr1_size = Section.CPR1Size; Flags.cpr2_size = Section.CPR2Size; Flags.fp_abi = Section.FpABI; Flags.isa_ext = Section.ISAExtension; Flags.ases = Section.ASEs; Flags.flags1 = Section.Flags1; Flags.flags2 = Section.Flags2; OS.write((const char *)&Flags, sizeof(Flags)); return true; }
bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::Group &Section, ContiguousBlobAccumulator &CBA) { typedef typename object::ELFFile<ELFT>::Elf_Word Elf_Word; assert(Section.Type == llvm::ELF::SHT_GROUP && "Section type is not SHT_GROUP"); SHeader.sh_entsize = sizeof(Elf_Word); SHeader.sh_size = SHeader.sh_entsize * Section.Members.size(); auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); for (auto member : Section.Members) { Elf_Word SIdx; unsigned int sectionIndex = 0; if (member.sectionNameOrType == "GRP_COMDAT") sectionIndex = llvm::ELF::GRP_COMDAT; else if (SN2I.lookup(member.sectionNameOrType, sectionIndex)) { errs() << "error: Unknown section referenced: '" << member.sectionNameOrType << "' at YAML section' " << Section.Name << "\n"; return false; } SIdx = sectionIndex; OS.write((const char *)&SIdx, sizeof(SIdx)); } return true; }
static void createStringTableSectionHeader(Elf_Shdr &SHeader, StringTableBuilder &STB, ContiguousBlobAccumulator &CBA) { SHeader.sh_type = ELF::SHT_STRTAB; STB.writeToStream(CBA.getOSAndAlignedOffset(SHeader.sh_offset)); SHeader.sh_size = STB.size(); SHeader.sh_addralign = 1; }
void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name, StringTableBuilder &STB, ContiguousBlobAccumulator &CBA) { zero(SHeader); SHeader.sh_name = DotShStrtab.getOffset(Name); SHeader.sh_type = ELF::SHT_STRTAB; STB.write(CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign)); SHeader.sh_size = STB.getSize(); SHeader.sh_addralign = 1; }
void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::RawContentSection &Section, ContiguousBlobAccumulator &CBA) { assert(Section.Size >= Section.Content.binary_size() && "Section size and section content are inconsistent"); raw_ostream &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); Section.Content.writeAsBinary(OS); for (auto i = Section.Content.binary_size(); i < Section.Size; ++i) OS.write(0); SHeader.sh_entsize = 0; SHeader.sh_size = Section.Size; }
void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader, SymtabType STType, ContiguousBlobAccumulator &CBA) { zero(SHeader); bool IsStatic = STType == SymtabType::Static; SHeader.sh_name = DotShStrtab.getOffset(IsStatic ? ".symtab" : ".dynsym"); SHeader.sh_type = IsStatic ? ELF::SHT_SYMTAB : ELF::SHT_DYNSYM; SHeader.sh_link = IsStatic ? getDotStrTabSecNo() : getDotDynStrSecNo(); const auto &Symbols = IsStatic ? Doc.Symbols : Doc.DynamicSymbols; auto &Strtab = IsStatic ? DotStrtab : DotDynstr; // One greater than symbol table index of the last local symbol. SHeader.sh_info = Symbols.Local.size() + 1; SHeader.sh_entsize = sizeof(Elf_Sym); SHeader.sh_addralign = 8; std::vector<Elf_Sym> Syms; { // Ensure STN_UNDEF is present Elf_Sym Sym; zero(Sym); Syms.push_back(Sym); } // Add symbol names to .strtab or .dynstr. for (const auto &Sym : Symbols.Local) Strtab.add(Sym.Name); for (const auto &Sym : Symbols.Global) Strtab.add(Sym.Name); for (const auto &Sym : Symbols.Weak) Strtab.add(Sym.Name); Strtab.finalize(); addSymbols(Symbols.Local, Syms, ELF::STB_LOCAL, Strtab); addSymbols(Symbols.Global, Syms, ELF::STB_GLOBAL, Strtab); addSymbols(Symbols.Weak, Syms, ELF::STB_WEAK, Strtab); writeArrayData( CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign), makeArrayRef(Syms)); SHeader.sh_size = arrayDataSize(makeArrayRef(Syms)); }
void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::RawContentSection &Section, ContiguousBlobAccumulator &CBA) { assert(Section.Size >= Section.Content.binary_size() && "Section size and section content are inconsistent"); raw_ostream &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); Section.Content.writeAsBinary(OS); for (auto i = Section.Content.binary_size(); i < Section.Size; ++i) OS.write(0); if (Section.EntSize) SHeader.sh_entsize = *Section.EntSize; else if (Section.Type == llvm::ELF::SHT_RELR) SHeader.sh_entsize = sizeof(Elf_Relr); else if (Section.Type == llvm::ELF::SHT_DYNAMIC) SHeader.sh_entsize = sizeof(Elf_Dyn); else SHeader.sh_entsize = 0; SHeader.sh_size = Section.Size; }
bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::RelocationSection &Section, ContiguousBlobAccumulator &CBA) { assert((Section.Type == llvm::ELF::SHT_REL || Section.Type == llvm::ELF::SHT_RELA) && "Section type is not SHT_REL nor SHT_RELA"); bool IsRela = Section.Type == llvm::ELF::SHT_RELA; SHeader.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); SHeader.sh_size = SHeader.sh_entsize * Section.Relocations.size(); auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); for (const auto &Rel : Section.Relocations) { unsigned SymIdx = 0; // Some special relocation, R_ARM_v4BX for instance, does not have // an external reference. So it ignores the return value of lookup() // here. if (Rel.Symbol) SymN2I.lookup(*Rel.Symbol, SymIdx); if (IsRela) { Elf_Rela REntry; zero(REntry); REntry.r_offset = Rel.Offset; REntry.r_addend = Rel.Addend; REntry.setSymbolAndType(SymIdx, Rel.Type, isMips64EL(Doc)); OS.write((const char *)&REntry, sizeof(REntry)); } else { Elf_Rel REntry; zero(REntry); REntry.r_offset = Rel.Offset; REntry.setSymbolAndType(SymIdx, Rel.Type, isMips64EL(Doc)); OS.write((const char *)&REntry, sizeof(REntry)); } } return true; }
void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader, ContiguousBlobAccumulator &CBA) { zero(SHeader); SHeader.sh_name = DotShStrtab.getOffset(".symtab"); SHeader.sh_type = ELF::SHT_SYMTAB; SHeader.sh_link = getDotStrTabSecNo(); // One greater than symbol table index of the last local symbol. SHeader.sh_info = Doc.Symbols.Local.size() + 1; SHeader.sh_entsize = sizeof(Elf_Sym); SHeader.sh_addralign = 8; std::vector<Elf_Sym> Syms; { // Ensure STN_UNDEF is present Elf_Sym Sym; zero(Sym); Syms.push_back(Sym); } // Add symbol names to .strtab. for (const auto &Sym : Doc.Symbols.Local) DotStrtab.add(Sym.Name); for (const auto &Sym : Doc.Symbols.Global) DotStrtab.add(Sym.Name); for (const auto &Sym : Doc.Symbols.Weak) DotStrtab.add(Sym.Name); DotStrtab.finalize(StringTableBuilder::ELF); addSymbols(Doc.Symbols.Local, Syms, ELF::STB_LOCAL); addSymbols(Doc.Symbols.Global, Syms, ELF::STB_GLOBAL); addSymbols(Doc.Symbols.Weak, Syms, ELF::STB_WEAK); writeArrayData( CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign), makeArrayRef(Syms)); SHeader.sh_size = arrayDataSize(makeArrayRef(Syms)); }
bool ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders, ContiguousBlobAccumulator &CBA) { // Ensure SHN_UNDEF entry is present. An all-zero section header is a // valid SHN_UNDEF entry since SHT_NULL == 0. Elf_Shdr SHeader; zero(SHeader); SHeaders.push_back(SHeader); for (const auto &Sec : Doc.Sections) DotShStrtab.add(Sec->Name); DotShStrtab.finalize(StringTableBuilder::ELF); for (const auto &Sec : Doc.Sections) { zero(SHeader); SHeader.sh_name = DotShStrtab.getOffset(Sec->Name); SHeader.sh_type = Sec->Type; SHeader.sh_flags = Sec->Flags; SHeader.sh_addr = Sec->Address; SHeader.sh_addralign = Sec->AddressAlign; if (!Sec->Link.empty()) { unsigned Index; if (SN2I.lookup(Sec->Link, Index)) { errs() << "error: Unknown section referenced: '" << Sec->Link << "' at YAML section '" << Sec->Name << "'.\n"; return false; } SHeader.sh_link = Index; } if (auto S = dyn_cast<ELFYAML::RawContentSection>(Sec.get())) writeSectionContent(SHeader, *S, CBA); else if (auto S = dyn_cast<ELFYAML::RelocationSection>(Sec.get())) { if (S->Link.empty()) // For relocation section set link to .symtab by default. SHeader.sh_link = getDotSymTabSecNo(); unsigned Index; if (SN2I.lookup(S->Info, Index)) { errs() << "error: Unknown section referenced: '" << S->Info << "' at YAML section '" << S->Name << "'.\n"; return false; } SHeader.sh_info = Index; if (!writeSectionContent(SHeader, *S, CBA)) return false; } else if (auto S = dyn_cast<ELFYAML::Group>(Sec.get())) { unsigned SymIdx; if (SymN2I.lookup(S->Info, SymIdx)) { errs() << "error: Unknown symbol referenced: '" << S->Info << "' at YAML section '" << S->Name << "'.\n"; return false; } SHeader.sh_info = SymIdx; if (!writeSectionContent(SHeader, *S, CBA)) return false; } else if (auto S = dyn_cast<ELFYAML::MipsABIFlags>(Sec.get())) { if (!writeSectionContent(SHeader, *S, CBA)) return false; } else if (auto S = dyn_cast<ELFYAML::NoBitsSection>(Sec.get())) { SHeader.sh_entsize = 0; SHeader.sh_size = S->Size; // SHT_NOBITS section does not have content // so just to setup the section offset. CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); } else llvm_unreachable("Unknown section type"); SHeaders.push_back(SHeader); } return true; }