18bcb0991SDimitry Andric //===- yaml2elf - Convert YAML to a ELF object file -----------------------===// 28bcb0991SDimitry Andric // 38bcb0991SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 48bcb0991SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 58bcb0991SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 68bcb0991SDimitry Andric // 78bcb0991SDimitry Andric //===----------------------------------------------------------------------===// 88bcb0991SDimitry Andric /// 98bcb0991SDimitry Andric /// \file 108bcb0991SDimitry Andric /// The ELF component of yaml2obj. 118bcb0991SDimitry Andric /// 128bcb0991SDimitry Andric //===----------------------------------------------------------------------===// 138bcb0991SDimitry Andric 148bcb0991SDimitry Andric #include "llvm/ADT/ArrayRef.h" 15*480093f4SDimitry Andric #include "llvm/ADT/DenseMap.h" 168bcb0991SDimitry Andric #include "llvm/ADT/StringSet.h" 178bcb0991SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 188bcb0991SDimitry Andric #include "llvm/MC/StringTableBuilder.h" 198bcb0991SDimitry Andric #include "llvm/Object/ELFObjectFile.h" 208bcb0991SDimitry Andric #include "llvm/ObjectYAML/ELFYAML.h" 218bcb0991SDimitry Andric #include "llvm/ObjectYAML/yaml2obj.h" 228bcb0991SDimitry Andric #include "llvm/Support/EndianStream.h" 238bcb0991SDimitry Andric #include "llvm/Support/LEB128.h" 248bcb0991SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 258bcb0991SDimitry Andric #include "llvm/Support/WithColor.h" 268bcb0991SDimitry Andric #include "llvm/Support/YAMLTraits.h" 278bcb0991SDimitry Andric #include "llvm/Support/raw_ostream.h" 288bcb0991SDimitry Andric 298bcb0991SDimitry Andric using namespace llvm; 308bcb0991SDimitry Andric 318bcb0991SDimitry Andric // This class is used to build up a contiguous binary blob while keeping 328bcb0991SDimitry Andric // track of an offset in the output (which notionally begins at 338bcb0991SDimitry Andric // `InitialOffset`). 348bcb0991SDimitry Andric namespace { 358bcb0991SDimitry Andric class ContiguousBlobAccumulator { 368bcb0991SDimitry Andric const uint64_t InitialOffset; 378bcb0991SDimitry Andric SmallVector<char, 128> Buf; 388bcb0991SDimitry Andric raw_svector_ostream OS; 398bcb0991SDimitry Andric 40*480093f4SDimitry Andric public: 41*480093f4SDimitry Andric ContiguousBlobAccumulator(uint64_t InitialOffset_) 42*480093f4SDimitry Andric : InitialOffset(InitialOffset_), Buf(), OS(Buf) {} 43*480093f4SDimitry Andric 44*480093f4SDimitry Andric template <class Integer> 45*480093f4SDimitry Andric raw_ostream &getOSAndAlignedOffset(Integer &Offset, unsigned Align) { 46*480093f4SDimitry Andric Offset = padToAlignment(Align); 47*480093f4SDimitry Andric return OS; 48*480093f4SDimitry Andric } 49*480093f4SDimitry Andric 508bcb0991SDimitry Andric /// \returns The new offset. 518bcb0991SDimitry Andric uint64_t padToAlignment(unsigned Align) { 528bcb0991SDimitry Andric if (Align == 0) 538bcb0991SDimitry Andric Align = 1; 548bcb0991SDimitry Andric uint64_t CurrentOffset = InitialOffset + OS.tell(); 558bcb0991SDimitry Andric uint64_t AlignedOffset = alignTo(CurrentOffset, Align); 568bcb0991SDimitry Andric OS.write_zeros(AlignedOffset - CurrentOffset); 578bcb0991SDimitry Andric return AlignedOffset; // == CurrentOffset; 588bcb0991SDimitry Andric } 598bcb0991SDimitry Andric 608bcb0991SDimitry Andric void writeBlobToStream(raw_ostream &Out) { Out << OS.str(); } 618bcb0991SDimitry Andric }; 628bcb0991SDimitry Andric 638bcb0991SDimitry Andric // Used to keep track of section and symbol names, so that in the YAML file 648bcb0991SDimitry Andric // sections and symbols can be referenced by name instead of by index. 658bcb0991SDimitry Andric class NameToIdxMap { 668bcb0991SDimitry Andric StringMap<unsigned> Map; 678bcb0991SDimitry Andric 688bcb0991SDimitry Andric public: 698bcb0991SDimitry Andric /// \Returns false if name is already present in the map. 708bcb0991SDimitry Andric bool addName(StringRef Name, unsigned Ndx) { 718bcb0991SDimitry Andric return Map.insert({Name, Ndx}).second; 728bcb0991SDimitry Andric } 738bcb0991SDimitry Andric /// \Returns false if name is not present in the map. 748bcb0991SDimitry Andric bool lookup(StringRef Name, unsigned &Idx) const { 758bcb0991SDimitry Andric auto I = Map.find(Name); 768bcb0991SDimitry Andric if (I == Map.end()) 778bcb0991SDimitry Andric return false; 788bcb0991SDimitry Andric Idx = I->getValue(); 798bcb0991SDimitry Andric return true; 808bcb0991SDimitry Andric } 818bcb0991SDimitry Andric /// Asserts if name is not present in the map. 828bcb0991SDimitry Andric unsigned get(StringRef Name) const { 838bcb0991SDimitry Andric unsigned Idx; 848bcb0991SDimitry Andric if (lookup(Name, Idx)) 858bcb0991SDimitry Andric return Idx; 868bcb0991SDimitry Andric assert(false && "Expected section not found in index"); 878bcb0991SDimitry Andric return 0; 888bcb0991SDimitry Andric } 898bcb0991SDimitry Andric unsigned size() const { return Map.size(); } 908bcb0991SDimitry Andric }; 918bcb0991SDimitry Andric 92*480093f4SDimitry Andric namespace { 93*480093f4SDimitry Andric struct Fragment { 94*480093f4SDimitry Andric uint64_t Offset; 95*480093f4SDimitry Andric uint64_t Size; 96*480093f4SDimitry Andric uint32_t Type; 97*480093f4SDimitry Andric uint64_t AddrAlign; 98*480093f4SDimitry Andric }; 99*480093f4SDimitry Andric } // namespace 100*480093f4SDimitry Andric 1018bcb0991SDimitry Andric /// "Single point of truth" for the ELF file construction. 1028bcb0991SDimitry Andric /// TODO: This class still has a ways to go before it is truly a "single 1038bcb0991SDimitry Andric /// point of truth". 1048bcb0991SDimitry Andric template <class ELFT> class ELFState { 1058bcb0991SDimitry Andric typedef typename ELFT::Ehdr Elf_Ehdr; 1068bcb0991SDimitry Andric typedef typename ELFT::Phdr Elf_Phdr; 1078bcb0991SDimitry Andric typedef typename ELFT::Shdr Elf_Shdr; 1088bcb0991SDimitry Andric typedef typename ELFT::Sym Elf_Sym; 1098bcb0991SDimitry Andric typedef typename ELFT::Rel Elf_Rel; 1108bcb0991SDimitry Andric typedef typename ELFT::Rela Elf_Rela; 1118bcb0991SDimitry Andric typedef typename ELFT::Relr Elf_Relr; 1128bcb0991SDimitry Andric typedef typename ELFT::Dyn Elf_Dyn; 113*480093f4SDimitry Andric typedef typename ELFT::uint uintX_t; 1148bcb0991SDimitry Andric 1158bcb0991SDimitry Andric enum class SymtabType { Static, Dynamic }; 1168bcb0991SDimitry Andric 1178bcb0991SDimitry Andric /// The future ".strtab" section. 1188bcb0991SDimitry Andric StringTableBuilder DotStrtab{StringTableBuilder::ELF}; 1198bcb0991SDimitry Andric 1208bcb0991SDimitry Andric /// The future ".shstrtab" section. 1218bcb0991SDimitry Andric StringTableBuilder DotShStrtab{StringTableBuilder::ELF}; 1228bcb0991SDimitry Andric 1238bcb0991SDimitry Andric /// The future ".dynstr" section. 1248bcb0991SDimitry Andric StringTableBuilder DotDynstr{StringTableBuilder::ELF}; 1258bcb0991SDimitry Andric 1268bcb0991SDimitry Andric NameToIdxMap SN2I; 1278bcb0991SDimitry Andric NameToIdxMap SymN2I; 1288bcb0991SDimitry Andric NameToIdxMap DynSymN2I; 1298bcb0991SDimitry Andric ELFYAML::Object &Doc; 1308bcb0991SDimitry Andric 1318bcb0991SDimitry Andric bool HasError = false; 1328bcb0991SDimitry Andric yaml::ErrorHandler ErrHandler; 1338bcb0991SDimitry Andric void reportError(const Twine &Msg); 1348bcb0991SDimitry Andric 1358bcb0991SDimitry Andric std::vector<Elf_Sym> toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols, 1368bcb0991SDimitry Andric const StringTableBuilder &Strtab); 1378bcb0991SDimitry Andric unsigned toSectionIndex(StringRef S, StringRef LocSec, StringRef LocSym = ""); 1388bcb0991SDimitry Andric unsigned toSymbolIndex(StringRef S, StringRef LocSec, bool IsDynamic); 1398bcb0991SDimitry Andric 1408bcb0991SDimitry Andric void buildSectionIndex(); 1418bcb0991SDimitry Andric void buildSymbolIndexes(); 1428bcb0991SDimitry Andric void initProgramHeaders(std::vector<Elf_Phdr> &PHeaders); 1438bcb0991SDimitry Andric bool initImplicitHeader(ContiguousBlobAccumulator &CBA, Elf_Shdr &Header, 1448bcb0991SDimitry Andric StringRef SecName, ELFYAML::Section *YAMLSec); 1458bcb0991SDimitry Andric void initSectionHeaders(std::vector<Elf_Shdr> &SHeaders, 1468bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 1478bcb0991SDimitry Andric void initSymtabSectionHeader(Elf_Shdr &SHeader, SymtabType STType, 1488bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 1498bcb0991SDimitry Andric ELFYAML::Section *YAMLSec); 1508bcb0991SDimitry Andric void initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name, 1518bcb0991SDimitry Andric StringTableBuilder &STB, 1528bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 1538bcb0991SDimitry Andric ELFYAML::Section *YAMLSec); 1548bcb0991SDimitry Andric void setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders, 1558bcb0991SDimitry Andric std::vector<Elf_Shdr> &SHeaders); 156*480093f4SDimitry Andric 157*480093f4SDimitry Andric std::vector<Fragment> 158*480093f4SDimitry Andric getPhdrFragments(const ELFYAML::ProgramHeader &Phdr, 159*480093f4SDimitry Andric ArrayRef<typename ELFT::Shdr> SHeaders); 160*480093f4SDimitry Andric 1618bcb0991SDimitry Andric void finalizeStrings(); 1628bcb0991SDimitry Andric void writeELFHeader(ContiguousBlobAccumulator &CBA, raw_ostream &OS); 1638bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 1648bcb0991SDimitry Andric const ELFYAML::RawContentSection &Section, 1658bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 1668bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 1678bcb0991SDimitry Andric const ELFYAML::RelocationSection &Section, 1688bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 169*480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 170*480093f4SDimitry Andric const ELFYAML::RelrSection &Section, 171*480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 1728bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::Group &Group, 1738bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 1748bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 1758bcb0991SDimitry Andric const ELFYAML::SymtabShndxSection &Shndx, 1768bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 1778bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 1788bcb0991SDimitry Andric const ELFYAML::SymverSection &Section, 1798bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 1808bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 1818bcb0991SDimitry Andric const ELFYAML::VerneedSection &Section, 1828bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 1838bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 1848bcb0991SDimitry Andric const ELFYAML::VerdefSection &Section, 1858bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 1868bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 1878bcb0991SDimitry Andric const ELFYAML::MipsABIFlags &Section, 1888bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 1898bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 1908bcb0991SDimitry Andric const ELFYAML::DynamicSection &Section, 1918bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 1928bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 1938bcb0991SDimitry Andric const ELFYAML::StackSizesSection &Section, 1948bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 1958bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 1968bcb0991SDimitry Andric const ELFYAML::HashSection &Section, 1978bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 1988bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 1998bcb0991SDimitry Andric const ELFYAML::AddrsigSection &Section, 2008bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 201*480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 202*480093f4SDimitry Andric const ELFYAML::NoteSection &Section, 203*480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 204*480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 205*480093f4SDimitry Andric const ELFYAML::GnuHashSection &Section, 206*480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 207*480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 208*480093f4SDimitry Andric const ELFYAML::LinkerOptionsSection &Section, 209*480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 210*480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 211*480093f4SDimitry Andric const ELFYAML::DependentLibrariesSection &Section, 212*480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 213*480093f4SDimitry Andric 214*480093f4SDimitry Andric void writeFill(ELFYAML::Fill &Fill, ContiguousBlobAccumulator &CBA); 2158bcb0991SDimitry Andric 2168bcb0991SDimitry Andric ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH); 2178bcb0991SDimitry Andric 2188bcb0991SDimitry Andric public: 2198bcb0991SDimitry Andric static bool writeELF(raw_ostream &OS, ELFYAML::Object &Doc, 2208bcb0991SDimitry Andric yaml::ErrorHandler EH); 2218bcb0991SDimitry Andric }; 2228bcb0991SDimitry Andric } // end anonymous namespace 2238bcb0991SDimitry Andric 2248bcb0991SDimitry Andric template <class T> static size_t arrayDataSize(ArrayRef<T> A) { 2258bcb0991SDimitry Andric return A.size() * sizeof(T); 2268bcb0991SDimitry Andric } 2278bcb0991SDimitry Andric 2288bcb0991SDimitry Andric template <class T> static void writeArrayData(raw_ostream &OS, ArrayRef<T> A) { 2298bcb0991SDimitry Andric OS.write((const char *)A.data(), arrayDataSize(A)); 2308bcb0991SDimitry Andric } 2318bcb0991SDimitry Andric 2328bcb0991SDimitry Andric template <class T> static void zero(T &Obj) { memset(&Obj, 0, sizeof(Obj)); } 2338bcb0991SDimitry Andric 2348bcb0991SDimitry Andric template <class ELFT> 2358bcb0991SDimitry Andric ELFState<ELFT>::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH) 2368bcb0991SDimitry Andric : Doc(D), ErrHandler(EH) { 237*480093f4SDimitry Andric std::vector<ELFYAML::Section *> Sections = Doc.getSections(); 2388bcb0991SDimitry Andric StringSet<> DocSections; 239*480093f4SDimitry Andric for (const ELFYAML::Section *Sec : Sections) 240*480093f4SDimitry Andric if (!Sec->Name.empty()) 241*480093f4SDimitry Andric DocSections.insert(Sec->Name); 2428bcb0991SDimitry Andric 2438bcb0991SDimitry Andric // Insert SHT_NULL section implicitly when it is not defined in YAML. 244*480093f4SDimitry Andric if (Sections.empty() || Sections.front()->Type != ELF::SHT_NULL) 245*480093f4SDimitry Andric Doc.Chunks.insert( 246*480093f4SDimitry Andric Doc.Chunks.begin(), 2478bcb0991SDimitry Andric std::make_unique<ELFYAML::Section>( 248*480093f4SDimitry Andric ELFYAML::Chunk::ChunkKind::RawContent, /*IsImplicit=*/true)); 2498bcb0991SDimitry Andric 2508bcb0991SDimitry Andric std::vector<StringRef> ImplicitSections; 2518bcb0991SDimitry Andric if (Doc.Symbols) 2528bcb0991SDimitry Andric ImplicitSections.push_back(".symtab"); 2538bcb0991SDimitry Andric ImplicitSections.insert(ImplicitSections.end(), {".strtab", ".shstrtab"}); 2548bcb0991SDimitry Andric 255*480093f4SDimitry Andric if (Doc.DynamicSymbols) 2568bcb0991SDimitry Andric ImplicitSections.insert(ImplicitSections.end(), {".dynsym", ".dynstr"}); 2578bcb0991SDimitry Andric 2588bcb0991SDimitry Andric // Insert placeholders for implicit sections that are not 2598bcb0991SDimitry Andric // defined explicitly in YAML. 2608bcb0991SDimitry Andric for (StringRef SecName : ImplicitSections) { 2618bcb0991SDimitry Andric if (DocSections.count(SecName)) 2628bcb0991SDimitry Andric continue; 2638bcb0991SDimitry Andric 264*480093f4SDimitry Andric std::unique_ptr<ELFYAML::Chunk> Sec = std::make_unique<ELFYAML::Section>( 265*480093f4SDimitry Andric ELFYAML::Chunk::ChunkKind::RawContent, true /*IsImplicit*/); 2668bcb0991SDimitry Andric Sec->Name = SecName; 267*480093f4SDimitry Andric Doc.Chunks.push_back(std::move(Sec)); 2688bcb0991SDimitry Andric } 2698bcb0991SDimitry Andric } 2708bcb0991SDimitry Andric 2718bcb0991SDimitry Andric template <class ELFT> 2728bcb0991SDimitry Andric void ELFState<ELFT>::writeELFHeader(ContiguousBlobAccumulator &CBA, raw_ostream &OS) { 2738bcb0991SDimitry Andric using namespace llvm::ELF; 2748bcb0991SDimitry Andric 2758bcb0991SDimitry Andric Elf_Ehdr Header; 2768bcb0991SDimitry Andric zero(Header); 2778bcb0991SDimitry Andric Header.e_ident[EI_MAG0] = 0x7f; 2788bcb0991SDimitry Andric Header.e_ident[EI_MAG1] = 'E'; 2798bcb0991SDimitry Andric Header.e_ident[EI_MAG2] = 'L'; 2808bcb0991SDimitry Andric Header.e_ident[EI_MAG3] = 'F'; 2818bcb0991SDimitry Andric Header.e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32; 2828bcb0991SDimitry Andric Header.e_ident[EI_DATA] = Doc.Header.Data; 2838bcb0991SDimitry Andric Header.e_ident[EI_VERSION] = EV_CURRENT; 2848bcb0991SDimitry Andric Header.e_ident[EI_OSABI] = Doc.Header.OSABI; 2858bcb0991SDimitry Andric Header.e_ident[EI_ABIVERSION] = Doc.Header.ABIVersion; 2868bcb0991SDimitry Andric Header.e_type = Doc.Header.Type; 2878bcb0991SDimitry Andric Header.e_machine = Doc.Header.Machine; 2888bcb0991SDimitry Andric Header.e_version = EV_CURRENT; 2898bcb0991SDimitry Andric Header.e_entry = Doc.Header.Entry; 2908bcb0991SDimitry Andric Header.e_phoff = Doc.ProgramHeaders.size() ? sizeof(Header) : 0; 2918bcb0991SDimitry Andric Header.e_flags = Doc.Header.Flags; 2928bcb0991SDimitry Andric Header.e_ehsize = sizeof(Elf_Ehdr); 2938bcb0991SDimitry Andric Header.e_phentsize = Doc.ProgramHeaders.size() ? sizeof(Elf_Phdr) : 0; 2948bcb0991SDimitry Andric Header.e_phnum = Doc.ProgramHeaders.size(); 2958bcb0991SDimitry Andric 2968bcb0991SDimitry Andric Header.e_shentsize = 2978bcb0991SDimitry Andric Doc.Header.SHEntSize ? (uint16_t)*Doc.Header.SHEntSize : sizeof(Elf_Shdr); 2988bcb0991SDimitry Andric // Immediately following the ELF header and program headers. 2998bcb0991SDimitry Andric // Align the start of the section header and write the ELF header. 3008bcb0991SDimitry Andric uint64_t SHOff; 3018bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHOff, sizeof(typename ELFT::uint)); 3028bcb0991SDimitry Andric Header.e_shoff = 3038bcb0991SDimitry Andric Doc.Header.SHOff ? typename ELFT::uint(*Doc.Header.SHOff) : SHOff; 3048bcb0991SDimitry Andric Header.e_shnum = 305*480093f4SDimitry Andric Doc.Header.SHNum ? (uint16_t)*Doc.Header.SHNum : Doc.getSections().size(); 3068bcb0991SDimitry Andric Header.e_shstrndx = Doc.Header.SHStrNdx ? (uint16_t)*Doc.Header.SHStrNdx 3078bcb0991SDimitry Andric : SN2I.get(".shstrtab"); 3088bcb0991SDimitry Andric 3098bcb0991SDimitry Andric OS.write((const char *)&Header, sizeof(Header)); 3108bcb0991SDimitry Andric } 3118bcb0991SDimitry Andric 3128bcb0991SDimitry Andric template <class ELFT> 3138bcb0991SDimitry Andric void ELFState<ELFT>::initProgramHeaders(std::vector<Elf_Phdr> &PHeaders) { 3148bcb0991SDimitry Andric for (const auto &YamlPhdr : Doc.ProgramHeaders) { 3158bcb0991SDimitry Andric Elf_Phdr Phdr; 3168bcb0991SDimitry Andric Phdr.p_type = YamlPhdr.Type; 3178bcb0991SDimitry Andric Phdr.p_flags = YamlPhdr.Flags; 3188bcb0991SDimitry Andric Phdr.p_vaddr = YamlPhdr.VAddr; 3198bcb0991SDimitry Andric Phdr.p_paddr = YamlPhdr.PAddr; 3208bcb0991SDimitry Andric PHeaders.push_back(Phdr); 3218bcb0991SDimitry Andric } 3228bcb0991SDimitry Andric } 3238bcb0991SDimitry Andric 3248bcb0991SDimitry Andric template <class ELFT> 3258bcb0991SDimitry Andric unsigned ELFState<ELFT>::toSectionIndex(StringRef S, StringRef LocSec, 3268bcb0991SDimitry Andric StringRef LocSym) { 3278bcb0991SDimitry Andric unsigned Index; 3288bcb0991SDimitry Andric if (SN2I.lookup(S, Index) || to_integer(S, Index)) 3298bcb0991SDimitry Andric return Index; 3308bcb0991SDimitry Andric 3318bcb0991SDimitry Andric assert(LocSec.empty() || LocSym.empty()); 3328bcb0991SDimitry Andric if (!LocSym.empty()) 3338bcb0991SDimitry Andric reportError("unknown section referenced: '" + S + "' by YAML symbol '" + 3348bcb0991SDimitry Andric LocSym + "'"); 3358bcb0991SDimitry Andric else 3368bcb0991SDimitry Andric reportError("unknown section referenced: '" + S + "' by YAML section '" + 3378bcb0991SDimitry Andric LocSec + "'"); 3388bcb0991SDimitry Andric return 0; 3398bcb0991SDimitry Andric } 3408bcb0991SDimitry Andric 3418bcb0991SDimitry Andric template <class ELFT> 3428bcb0991SDimitry Andric unsigned ELFState<ELFT>::toSymbolIndex(StringRef S, StringRef LocSec, 3438bcb0991SDimitry Andric bool IsDynamic) { 3448bcb0991SDimitry Andric const NameToIdxMap &SymMap = IsDynamic ? DynSymN2I : SymN2I; 3458bcb0991SDimitry Andric unsigned Index; 3468bcb0991SDimitry Andric // Here we try to look up S in the symbol table. If it is not there, 3478bcb0991SDimitry Andric // treat its value as a symbol index. 3488bcb0991SDimitry Andric if (!SymMap.lookup(S, Index) && !to_integer(S, Index)) { 3498bcb0991SDimitry Andric reportError("unknown symbol referenced: '" + S + "' by YAML section '" + 3508bcb0991SDimitry Andric LocSec + "'"); 3518bcb0991SDimitry Andric return 0; 3528bcb0991SDimitry Andric } 3538bcb0991SDimitry Andric return Index; 3548bcb0991SDimitry Andric } 3558bcb0991SDimitry Andric 3568bcb0991SDimitry Andric template <class ELFT> 357*480093f4SDimitry Andric static void overrideFields(ELFYAML::Section *From, typename ELFT::Shdr &To) { 358*480093f4SDimitry Andric if (!From) 359*480093f4SDimitry Andric return; 360*480093f4SDimitry Andric if (From->ShFlags) 361*480093f4SDimitry Andric To.sh_flags = *From->ShFlags; 362*480093f4SDimitry Andric if (From->ShName) 363*480093f4SDimitry Andric To.sh_name = *From->ShName; 364*480093f4SDimitry Andric if (From->ShOffset) 365*480093f4SDimitry Andric To.sh_offset = *From->ShOffset; 366*480093f4SDimitry Andric if (From->ShSize) 367*480093f4SDimitry Andric To.sh_size = *From->ShSize; 368*480093f4SDimitry Andric } 369*480093f4SDimitry Andric 370*480093f4SDimitry Andric template <class ELFT> 3718bcb0991SDimitry Andric bool ELFState<ELFT>::initImplicitHeader(ContiguousBlobAccumulator &CBA, 3728bcb0991SDimitry Andric Elf_Shdr &Header, StringRef SecName, 3738bcb0991SDimitry Andric ELFYAML::Section *YAMLSec) { 3748bcb0991SDimitry Andric // Check if the header was already initialized. 3758bcb0991SDimitry Andric if (Header.sh_offset) 3768bcb0991SDimitry Andric return false; 3778bcb0991SDimitry Andric 3788bcb0991SDimitry Andric if (SecName == ".symtab") 3798bcb0991SDimitry Andric initSymtabSectionHeader(Header, SymtabType::Static, CBA, YAMLSec); 3808bcb0991SDimitry Andric else if (SecName == ".strtab") 3818bcb0991SDimitry Andric initStrtabSectionHeader(Header, SecName, DotStrtab, CBA, YAMLSec); 3828bcb0991SDimitry Andric else if (SecName == ".shstrtab") 3838bcb0991SDimitry Andric initStrtabSectionHeader(Header, SecName, DotShStrtab, CBA, YAMLSec); 3848bcb0991SDimitry Andric else if (SecName == ".dynsym") 3858bcb0991SDimitry Andric initSymtabSectionHeader(Header, SymtabType::Dynamic, CBA, YAMLSec); 3868bcb0991SDimitry Andric else if (SecName == ".dynstr") 3878bcb0991SDimitry Andric initStrtabSectionHeader(Header, SecName, DotDynstr, CBA, YAMLSec); 3888bcb0991SDimitry Andric else 3898bcb0991SDimitry Andric return false; 3908bcb0991SDimitry Andric 391*480093f4SDimitry Andric // Override section fields if requested. 392*480093f4SDimitry Andric overrideFields<ELFT>(YAMLSec, Header); 3938bcb0991SDimitry Andric return true; 3948bcb0991SDimitry Andric } 3958bcb0991SDimitry Andric 3968bcb0991SDimitry Andric StringRef llvm::ELFYAML::dropUniqueSuffix(StringRef S) { 3978bcb0991SDimitry Andric size_t SuffixPos = S.rfind(" ["); 3988bcb0991SDimitry Andric if (SuffixPos == StringRef::npos) 3998bcb0991SDimitry Andric return S; 4008bcb0991SDimitry Andric return S.substr(0, SuffixPos); 4018bcb0991SDimitry Andric } 4028bcb0991SDimitry Andric 4038bcb0991SDimitry Andric template <class ELFT> 4048bcb0991SDimitry Andric void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders, 4058bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 4068bcb0991SDimitry Andric // Ensure SHN_UNDEF entry is present. An all-zero section header is a 4078bcb0991SDimitry Andric // valid SHN_UNDEF entry since SHT_NULL == 0. 408*480093f4SDimitry Andric SHeaders.resize(Doc.getSections().size()); 4098bcb0991SDimitry Andric 410*480093f4SDimitry Andric size_t SecNdx = -1; 411*480093f4SDimitry Andric for (const std::unique_ptr<ELFYAML::Chunk> &D : Doc.Chunks) { 412*480093f4SDimitry Andric if (auto S = dyn_cast<ELFYAML::Fill>(D.get())) { 413*480093f4SDimitry Andric writeFill(*S, CBA); 414*480093f4SDimitry Andric continue; 415*480093f4SDimitry Andric } 416*480093f4SDimitry Andric 417*480093f4SDimitry Andric ++SecNdx; 418*480093f4SDimitry Andric ELFYAML::Section *Sec = cast<ELFYAML::Section>(D.get()); 419*480093f4SDimitry Andric if (SecNdx == 0 && Sec->IsImplicit) 4208bcb0991SDimitry Andric continue; 4218bcb0991SDimitry Andric 4228bcb0991SDimitry Andric // We have a few sections like string or symbol tables that are usually 4238bcb0991SDimitry Andric // added implicitly to the end. However, if they are explicitly specified 4248bcb0991SDimitry Andric // in the YAML, we need to write them here. This ensures the file offset 4258bcb0991SDimitry Andric // remains correct. 426*480093f4SDimitry Andric Elf_Shdr &SHeader = SHeaders[SecNdx]; 4278bcb0991SDimitry Andric if (initImplicitHeader(CBA, SHeader, Sec->Name, 4288bcb0991SDimitry Andric Sec->IsImplicit ? nullptr : Sec)) 4298bcb0991SDimitry Andric continue; 4308bcb0991SDimitry Andric 4318bcb0991SDimitry Andric assert(Sec && "It can't be null unless it is an implicit section. But all " 4328bcb0991SDimitry Andric "implicit sections should already have been handled above."); 4338bcb0991SDimitry Andric 4348bcb0991SDimitry Andric SHeader.sh_name = 4358bcb0991SDimitry Andric DotShStrtab.getOffset(ELFYAML::dropUniqueSuffix(Sec->Name)); 4368bcb0991SDimitry Andric SHeader.sh_type = Sec->Type; 4378bcb0991SDimitry Andric if (Sec->Flags) 4388bcb0991SDimitry Andric SHeader.sh_flags = *Sec->Flags; 4398bcb0991SDimitry Andric SHeader.sh_addr = Sec->Address; 4408bcb0991SDimitry Andric SHeader.sh_addralign = Sec->AddressAlign; 4418bcb0991SDimitry Andric 4428bcb0991SDimitry Andric if (!Sec->Link.empty()) 4438bcb0991SDimitry Andric SHeader.sh_link = toSectionIndex(Sec->Link, Sec->Name); 4448bcb0991SDimitry Andric 445*480093f4SDimitry Andric if (SecNdx == 0) { 4468bcb0991SDimitry Andric if (auto RawSec = dyn_cast<ELFYAML::RawContentSection>(Sec)) { 4478bcb0991SDimitry Andric // We do not write any content for special SHN_UNDEF section. 4488bcb0991SDimitry Andric if (RawSec->Size) 4498bcb0991SDimitry Andric SHeader.sh_size = *RawSec->Size; 4508bcb0991SDimitry Andric if (RawSec->Info) 4518bcb0991SDimitry Andric SHeader.sh_info = *RawSec->Info; 4528bcb0991SDimitry Andric } 4538bcb0991SDimitry Andric if (Sec->EntSize) 4548bcb0991SDimitry Andric SHeader.sh_entsize = *Sec->EntSize; 4558bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::RawContentSection>(Sec)) { 4568bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 4578bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::SymtabShndxSection>(Sec)) { 4588bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 4598bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::RelocationSection>(Sec)) { 4608bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 461*480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::RelrSection>(Sec)) { 462*480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 4638bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::Group>(Sec)) { 4648bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 4658bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::MipsABIFlags>(Sec)) { 4668bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 4678bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::NoBitsSection>(Sec)) { 4688bcb0991SDimitry Andric SHeader.sh_entsize = 0; 4698bcb0991SDimitry Andric SHeader.sh_size = S->Size; 4708bcb0991SDimitry Andric // SHT_NOBITS section does not have content 4718bcb0991SDimitry Andric // so just to setup the section offset. 4728bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 4738bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::DynamicSection>(Sec)) { 4748bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 4758bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::SymverSection>(Sec)) { 4768bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 4778bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::VerneedSection>(Sec)) { 4788bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 4798bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::VerdefSection>(Sec)) { 4808bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 4818bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::StackSizesSection>(Sec)) { 4828bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 4838bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::HashSection>(Sec)) { 4848bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 4858bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::AddrsigSection>(Sec)) { 4868bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 487*480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::LinkerOptionsSection>(Sec)) { 488*480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 489*480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::NoteSection>(Sec)) { 490*480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 491*480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::GnuHashSection>(Sec)) { 492*480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 493*480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::DependentLibrariesSection>(Sec)) { 494*480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 4958bcb0991SDimitry Andric } else { 4968bcb0991SDimitry Andric llvm_unreachable("Unknown section type"); 4978bcb0991SDimitry Andric } 4988bcb0991SDimitry Andric 499*480093f4SDimitry Andric // Override section fields if requested. 500*480093f4SDimitry Andric overrideFields<ELFT>(Sec, SHeader); 5018bcb0991SDimitry Andric } 5028bcb0991SDimitry Andric } 5038bcb0991SDimitry Andric 5048bcb0991SDimitry Andric static size_t findFirstNonGlobal(ArrayRef<ELFYAML::Symbol> Symbols) { 5058bcb0991SDimitry Andric for (size_t I = 0; I < Symbols.size(); ++I) 5068bcb0991SDimitry Andric if (Symbols[I].Binding.value != ELF::STB_LOCAL) 5078bcb0991SDimitry Andric return I; 5088bcb0991SDimitry Andric return Symbols.size(); 5098bcb0991SDimitry Andric } 5108bcb0991SDimitry Andric 5118bcb0991SDimitry Andric static uint64_t writeContent(raw_ostream &OS, 5128bcb0991SDimitry Andric const Optional<yaml::BinaryRef> &Content, 5138bcb0991SDimitry Andric const Optional<llvm::yaml::Hex64> &Size) { 5148bcb0991SDimitry Andric size_t ContentSize = 0; 5158bcb0991SDimitry Andric if (Content) { 5168bcb0991SDimitry Andric Content->writeAsBinary(OS); 5178bcb0991SDimitry Andric ContentSize = Content->binary_size(); 5188bcb0991SDimitry Andric } 5198bcb0991SDimitry Andric 5208bcb0991SDimitry Andric if (!Size) 5218bcb0991SDimitry Andric return ContentSize; 5228bcb0991SDimitry Andric 5238bcb0991SDimitry Andric OS.write_zeros(*Size - ContentSize); 5248bcb0991SDimitry Andric return *Size; 5258bcb0991SDimitry Andric } 5268bcb0991SDimitry Andric 5278bcb0991SDimitry Andric template <class ELFT> 5288bcb0991SDimitry Andric std::vector<typename ELFT::Sym> 5298bcb0991SDimitry Andric ELFState<ELFT>::toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols, 5308bcb0991SDimitry Andric const StringTableBuilder &Strtab) { 5318bcb0991SDimitry Andric std::vector<Elf_Sym> Ret; 5328bcb0991SDimitry Andric Ret.resize(Symbols.size() + 1); 5338bcb0991SDimitry Andric 5348bcb0991SDimitry Andric size_t I = 0; 535*480093f4SDimitry Andric for (const ELFYAML::Symbol &Sym : Symbols) { 5368bcb0991SDimitry Andric Elf_Sym &Symbol = Ret[++I]; 5378bcb0991SDimitry Andric 5388bcb0991SDimitry Andric // If NameIndex, which contains the name offset, is explicitly specified, we 5398bcb0991SDimitry Andric // use it. This is useful for preparing broken objects. Otherwise, we add 5408bcb0991SDimitry Andric // the specified Name to the string table builder to get its offset. 5418bcb0991SDimitry Andric if (Sym.NameIndex) 5428bcb0991SDimitry Andric Symbol.st_name = *Sym.NameIndex; 5438bcb0991SDimitry Andric else if (!Sym.Name.empty()) 5448bcb0991SDimitry Andric Symbol.st_name = Strtab.getOffset(ELFYAML::dropUniqueSuffix(Sym.Name)); 5458bcb0991SDimitry Andric 5468bcb0991SDimitry Andric Symbol.setBindingAndType(Sym.Binding, Sym.Type); 5478bcb0991SDimitry Andric if (!Sym.Section.empty()) 5488bcb0991SDimitry Andric Symbol.st_shndx = toSectionIndex(Sym.Section, "", Sym.Name); 5498bcb0991SDimitry Andric else if (Sym.Index) 5508bcb0991SDimitry Andric Symbol.st_shndx = *Sym.Index; 5518bcb0991SDimitry Andric 5528bcb0991SDimitry Andric Symbol.st_value = Sym.Value; 5538bcb0991SDimitry Andric Symbol.st_other = Sym.Other ? *Sym.Other : 0; 5548bcb0991SDimitry Andric Symbol.st_size = Sym.Size; 5558bcb0991SDimitry Andric } 5568bcb0991SDimitry Andric 5578bcb0991SDimitry Andric return Ret; 5588bcb0991SDimitry Andric } 5598bcb0991SDimitry Andric 5608bcb0991SDimitry Andric template <class ELFT> 5618bcb0991SDimitry Andric void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader, 5628bcb0991SDimitry Andric SymtabType STType, 5638bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 5648bcb0991SDimitry Andric ELFYAML::Section *YAMLSec) { 5658bcb0991SDimitry Andric 5668bcb0991SDimitry Andric bool IsStatic = STType == SymtabType::Static; 5678bcb0991SDimitry Andric ArrayRef<ELFYAML::Symbol> Symbols; 5688bcb0991SDimitry Andric if (IsStatic && Doc.Symbols) 5698bcb0991SDimitry Andric Symbols = *Doc.Symbols; 570*480093f4SDimitry Andric else if (!IsStatic && Doc.DynamicSymbols) 571*480093f4SDimitry Andric Symbols = *Doc.DynamicSymbols; 5728bcb0991SDimitry Andric 5738bcb0991SDimitry Andric ELFYAML::RawContentSection *RawSec = 5748bcb0991SDimitry Andric dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec); 575*480093f4SDimitry Andric if (RawSec && (RawSec->Content || RawSec->Size)) { 576*480093f4SDimitry Andric bool HasSymbolsDescription = 577*480093f4SDimitry Andric (IsStatic && Doc.Symbols) || (!IsStatic && Doc.DynamicSymbols); 578*480093f4SDimitry Andric if (HasSymbolsDescription) { 579*480093f4SDimitry Andric StringRef Property = (IsStatic ? "`Symbols`" : "`DynamicSymbols`"); 5808bcb0991SDimitry Andric if (RawSec->Content) 581*480093f4SDimitry Andric reportError("cannot specify both `Content` and " + Property + 5828bcb0991SDimitry Andric " for symbol table section '" + RawSec->Name + "'"); 5838bcb0991SDimitry Andric if (RawSec->Size) 584*480093f4SDimitry Andric reportError("cannot specify both `Size` and " + Property + 5858bcb0991SDimitry Andric " for symbol table section '" + RawSec->Name + "'"); 5868bcb0991SDimitry Andric return; 5878bcb0991SDimitry Andric } 588*480093f4SDimitry Andric } 5898bcb0991SDimitry Andric 5908bcb0991SDimitry Andric zero(SHeader); 5918bcb0991SDimitry Andric SHeader.sh_name = DotShStrtab.getOffset(IsStatic ? ".symtab" : ".dynsym"); 5928bcb0991SDimitry Andric 5938bcb0991SDimitry Andric if (YAMLSec) 5948bcb0991SDimitry Andric SHeader.sh_type = YAMLSec->Type; 5958bcb0991SDimitry Andric else 5968bcb0991SDimitry Andric SHeader.sh_type = IsStatic ? ELF::SHT_SYMTAB : ELF::SHT_DYNSYM; 5978bcb0991SDimitry Andric 5988bcb0991SDimitry Andric if (RawSec && !RawSec->Link.empty()) { 5998bcb0991SDimitry Andric // If the Link field is explicitly defined in the document, 6008bcb0991SDimitry Andric // we should use it. 6018bcb0991SDimitry Andric SHeader.sh_link = toSectionIndex(RawSec->Link, RawSec->Name); 6028bcb0991SDimitry Andric } else { 6038bcb0991SDimitry Andric // When we describe the .dynsym section in the document explicitly, it is 6048bcb0991SDimitry Andric // allowed to omit the "DynamicSymbols" tag. In this case .dynstr is not 6058bcb0991SDimitry Andric // added implicitly and we should be able to leave the Link zeroed if 6068bcb0991SDimitry Andric // .dynstr is not defined. 6078bcb0991SDimitry Andric unsigned Link = 0; 6088bcb0991SDimitry Andric if (IsStatic) 6098bcb0991SDimitry Andric Link = SN2I.get(".strtab"); 6108bcb0991SDimitry Andric else 6118bcb0991SDimitry Andric SN2I.lookup(".dynstr", Link); 6128bcb0991SDimitry Andric SHeader.sh_link = Link; 6138bcb0991SDimitry Andric } 6148bcb0991SDimitry Andric 6158bcb0991SDimitry Andric if (YAMLSec && YAMLSec->Flags) 6168bcb0991SDimitry Andric SHeader.sh_flags = *YAMLSec->Flags; 6178bcb0991SDimitry Andric else if (!IsStatic) 6188bcb0991SDimitry Andric SHeader.sh_flags = ELF::SHF_ALLOC; 6198bcb0991SDimitry Andric 6208bcb0991SDimitry Andric // If the symbol table section is explicitly described in the YAML 6218bcb0991SDimitry Andric // then we should set the fields requested. 6228bcb0991SDimitry Andric SHeader.sh_info = (RawSec && RawSec->Info) ? (unsigned)(*RawSec->Info) 6238bcb0991SDimitry Andric : findFirstNonGlobal(Symbols) + 1; 6248bcb0991SDimitry Andric SHeader.sh_entsize = (YAMLSec && YAMLSec->EntSize) 6258bcb0991SDimitry Andric ? (uint64_t)(*YAMLSec->EntSize) 6268bcb0991SDimitry Andric : sizeof(Elf_Sym); 6278bcb0991SDimitry Andric SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 8; 6288bcb0991SDimitry Andric SHeader.sh_addr = YAMLSec ? (uint64_t)YAMLSec->Address : 0; 6298bcb0991SDimitry Andric 6308bcb0991SDimitry Andric auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 6318bcb0991SDimitry Andric if (RawSec && (RawSec->Content || RawSec->Size)) { 6328bcb0991SDimitry Andric assert(Symbols.empty()); 6338bcb0991SDimitry Andric SHeader.sh_size = writeContent(OS, RawSec->Content, RawSec->Size); 6348bcb0991SDimitry Andric return; 6358bcb0991SDimitry Andric } 6368bcb0991SDimitry Andric 6378bcb0991SDimitry Andric std::vector<Elf_Sym> Syms = 6388bcb0991SDimitry Andric toELFSymbols(Symbols, IsStatic ? DotStrtab : DotDynstr); 6398bcb0991SDimitry Andric writeArrayData(OS, makeArrayRef(Syms)); 6408bcb0991SDimitry Andric SHeader.sh_size = arrayDataSize(makeArrayRef(Syms)); 6418bcb0991SDimitry Andric } 6428bcb0991SDimitry Andric 6438bcb0991SDimitry Andric template <class ELFT> 6448bcb0991SDimitry Andric void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name, 6458bcb0991SDimitry Andric StringTableBuilder &STB, 6468bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 6478bcb0991SDimitry Andric ELFYAML::Section *YAMLSec) { 6488bcb0991SDimitry Andric zero(SHeader); 6498bcb0991SDimitry Andric SHeader.sh_name = DotShStrtab.getOffset(Name); 6508bcb0991SDimitry Andric SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_STRTAB; 6518bcb0991SDimitry Andric SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1; 6528bcb0991SDimitry Andric 6538bcb0991SDimitry Andric ELFYAML::RawContentSection *RawSec = 6548bcb0991SDimitry Andric dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec); 6558bcb0991SDimitry Andric 6568bcb0991SDimitry Andric auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 6578bcb0991SDimitry Andric if (RawSec && (RawSec->Content || RawSec->Size)) { 6588bcb0991SDimitry Andric SHeader.sh_size = writeContent(OS, RawSec->Content, RawSec->Size); 6598bcb0991SDimitry Andric } else { 6608bcb0991SDimitry Andric STB.write(OS); 6618bcb0991SDimitry Andric SHeader.sh_size = STB.getSize(); 6628bcb0991SDimitry Andric } 6638bcb0991SDimitry Andric 6648bcb0991SDimitry Andric if (YAMLSec && YAMLSec->EntSize) 6658bcb0991SDimitry Andric SHeader.sh_entsize = *YAMLSec->EntSize; 6668bcb0991SDimitry Andric 6678bcb0991SDimitry Andric if (RawSec && RawSec->Info) 6688bcb0991SDimitry Andric SHeader.sh_info = *RawSec->Info; 6698bcb0991SDimitry Andric 6708bcb0991SDimitry Andric if (YAMLSec && YAMLSec->Flags) 6718bcb0991SDimitry Andric SHeader.sh_flags = *YAMLSec->Flags; 6728bcb0991SDimitry Andric else if (Name == ".dynstr") 6738bcb0991SDimitry Andric SHeader.sh_flags = ELF::SHF_ALLOC; 6748bcb0991SDimitry Andric 6758bcb0991SDimitry Andric // If the section is explicitly described in the YAML 6768bcb0991SDimitry Andric // then we want to use its section address. 6778bcb0991SDimitry Andric if (YAMLSec) 6788bcb0991SDimitry Andric SHeader.sh_addr = YAMLSec->Address; 6798bcb0991SDimitry Andric } 6808bcb0991SDimitry Andric 6818bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::reportError(const Twine &Msg) { 6828bcb0991SDimitry Andric ErrHandler(Msg); 6838bcb0991SDimitry Andric HasError = true; 6848bcb0991SDimitry Andric } 6858bcb0991SDimitry Andric 6868bcb0991SDimitry Andric template <class ELFT> 687*480093f4SDimitry Andric std::vector<Fragment> 688*480093f4SDimitry Andric ELFState<ELFT>::getPhdrFragments(const ELFYAML::ProgramHeader &Phdr, 689*480093f4SDimitry Andric ArrayRef<typename ELFT::Shdr> SHeaders) { 690*480093f4SDimitry Andric DenseMap<StringRef, ELFYAML::Fill *> NameToFill; 691*480093f4SDimitry Andric for (const std::unique_ptr<ELFYAML::Chunk> &D : Doc.Chunks) 692*480093f4SDimitry Andric if (auto S = dyn_cast<ELFYAML::Fill>(D.get())) 693*480093f4SDimitry Andric NameToFill[S->Name] = S; 694*480093f4SDimitry Andric 695*480093f4SDimitry Andric std::vector<Fragment> Ret; 696*480093f4SDimitry Andric for (const ELFYAML::SectionName &SecName : Phdr.Sections) { 697*480093f4SDimitry Andric unsigned Index; 698*480093f4SDimitry Andric if (SN2I.lookup(SecName.Section, Index)) { 699*480093f4SDimitry Andric const typename ELFT::Shdr &H = SHeaders[Index]; 700*480093f4SDimitry Andric Ret.push_back({H.sh_offset, H.sh_size, H.sh_type, H.sh_addralign}); 701*480093f4SDimitry Andric continue; 702*480093f4SDimitry Andric } 703*480093f4SDimitry Andric 704*480093f4SDimitry Andric if (ELFYAML::Fill *Fill = NameToFill.lookup(SecName.Section)) { 705*480093f4SDimitry Andric Ret.push_back({Fill->ShOffset, Fill->Size, llvm::ELF::SHT_PROGBITS, 706*480093f4SDimitry Andric /*ShAddrAlign=*/1}); 707*480093f4SDimitry Andric continue; 708*480093f4SDimitry Andric } 709*480093f4SDimitry Andric 710*480093f4SDimitry Andric reportError("unknown section or fill referenced: '" + SecName.Section + 711*480093f4SDimitry Andric "' by program header"); 712*480093f4SDimitry Andric } 713*480093f4SDimitry Andric 714*480093f4SDimitry Andric return Ret; 715*480093f4SDimitry Andric } 716*480093f4SDimitry Andric 717*480093f4SDimitry Andric template <class ELFT> 7188bcb0991SDimitry Andric void ELFState<ELFT>::setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders, 7198bcb0991SDimitry Andric std::vector<Elf_Shdr> &SHeaders) { 7208bcb0991SDimitry Andric uint32_t PhdrIdx = 0; 7218bcb0991SDimitry Andric for (auto &YamlPhdr : Doc.ProgramHeaders) { 7228bcb0991SDimitry Andric Elf_Phdr &PHeader = PHeaders[PhdrIdx++]; 723*480093f4SDimitry Andric std::vector<Fragment> Fragments = getPhdrFragments(YamlPhdr, SHeaders); 7248bcb0991SDimitry Andric 7258bcb0991SDimitry Andric if (YamlPhdr.Offset) { 7268bcb0991SDimitry Andric PHeader.p_offset = *YamlPhdr.Offset; 7278bcb0991SDimitry Andric } else { 7288bcb0991SDimitry Andric if (YamlPhdr.Sections.size()) 7298bcb0991SDimitry Andric PHeader.p_offset = UINT32_MAX; 7308bcb0991SDimitry Andric else 7318bcb0991SDimitry Andric PHeader.p_offset = 0; 7328bcb0991SDimitry Andric 7338bcb0991SDimitry Andric // Find the minimum offset for the program header. 734*480093f4SDimitry Andric for (const Fragment &F : Fragments) 735*480093f4SDimitry Andric PHeader.p_offset = std::min((uint64_t)PHeader.p_offset, F.Offset); 7368bcb0991SDimitry Andric } 7378bcb0991SDimitry Andric 7388bcb0991SDimitry Andric // Find the maximum offset of the end of a section in order to set p_filesz 7398bcb0991SDimitry Andric // and p_memsz. When setting p_filesz, trailing SHT_NOBITS sections are not 7408bcb0991SDimitry Andric // counted. 7418bcb0991SDimitry Andric uint64_t FileOffset = PHeader.p_offset, MemOffset = PHeader.p_offset; 742*480093f4SDimitry Andric for (const Fragment &F : Fragments) { 743*480093f4SDimitry Andric uint64_t End = F.Offset + F.Size; 7448bcb0991SDimitry Andric MemOffset = std::max(MemOffset, End); 7458bcb0991SDimitry Andric 746*480093f4SDimitry Andric if (F.Type != llvm::ELF::SHT_NOBITS) 7478bcb0991SDimitry Andric FileOffset = std::max(FileOffset, End); 7488bcb0991SDimitry Andric } 7498bcb0991SDimitry Andric 7508bcb0991SDimitry Andric // Set the file size and the memory size if not set explicitly. 7518bcb0991SDimitry Andric PHeader.p_filesz = YamlPhdr.FileSize ? uint64_t(*YamlPhdr.FileSize) 7528bcb0991SDimitry Andric : FileOffset - PHeader.p_offset; 7538bcb0991SDimitry Andric PHeader.p_memsz = YamlPhdr.MemSize ? uint64_t(*YamlPhdr.MemSize) 7548bcb0991SDimitry Andric : MemOffset - PHeader.p_offset; 7558bcb0991SDimitry Andric 7568bcb0991SDimitry Andric if (YamlPhdr.Align) { 7578bcb0991SDimitry Andric PHeader.p_align = *YamlPhdr.Align; 7588bcb0991SDimitry Andric } else { 7598bcb0991SDimitry Andric // Set the alignment of the segment to be the maximum alignment of the 7608bcb0991SDimitry Andric // sections so that by default the segment has a valid and sensible 7618bcb0991SDimitry Andric // alignment. 7628bcb0991SDimitry Andric PHeader.p_align = 1; 763*480093f4SDimitry Andric for (const Fragment &F : Fragments) 764*480093f4SDimitry Andric PHeader.p_align = std::max((uint64_t)PHeader.p_align, F.AddrAlign); 7658bcb0991SDimitry Andric } 7668bcb0991SDimitry Andric } 7678bcb0991SDimitry Andric } 7688bcb0991SDimitry Andric 7698bcb0991SDimitry Andric template <class ELFT> 7708bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 7718bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::RawContentSection &Section, 7728bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 7738bcb0991SDimitry Andric raw_ostream &OS = 7748bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 7758bcb0991SDimitry Andric SHeader.sh_size = writeContent(OS, Section.Content, Section.Size); 7768bcb0991SDimitry Andric 7778bcb0991SDimitry Andric if (Section.EntSize) 7788bcb0991SDimitry Andric SHeader.sh_entsize = *Section.EntSize; 7798bcb0991SDimitry Andric 7808bcb0991SDimitry Andric if (Section.Info) 7818bcb0991SDimitry Andric SHeader.sh_info = *Section.Info; 7828bcb0991SDimitry Andric } 7838bcb0991SDimitry Andric 7848bcb0991SDimitry Andric static bool isMips64EL(const ELFYAML::Object &Doc) { 7858bcb0991SDimitry Andric return Doc.Header.Machine == ELFYAML::ELF_EM(llvm::ELF::EM_MIPS) && 7868bcb0991SDimitry Andric Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64) && 7878bcb0991SDimitry Andric Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB); 7888bcb0991SDimitry Andric } 7898bcb0991SDimitry Andric 7908bcb0991SDimitry Andric template <class ELFT> 7918bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 7928bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::RelocationSection &Section, 7938bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 7948bcb0991SDimitry Andric assert((Section.Type == llvm::ELF::SHT_REL || 7958bcb0991SDimitry Andric Section.Type == llvm::ELF::SHT_RELA) && 7968bcb0991SDimitry Andric "Section type is not SHT_REL nor SHT_RELA"); 7978bcb0991SDimitry Andric 7988bcb0991SDimitry Andric bool IsRela = Section.Type == llvm::ELF::SHT_RELA; 7998bcb0991SDimitry Andric SHeader.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); 8008bcb0991SDimitry Andric SHeader.sh_size = SHeader.sh_entsize * Section.Relocations.size(); 8018bcb0991SDimitry Andric 8028bcb0991SDimitry Andric // For relocation section set link to .symtab by default. 803*480093f4SDimitry Andric unsigned Link = 0; 804*480093f4SDimitry Andric if (Section.Link.empty() && SN2I.lookup(".symtab", Link)) 805*480093f4SDimitry Andric SHeader.sh_link = Link; 8068bcb0991SDimitry Andric 8078bcb0991SDimitry Andric if (!Section.RelocatableSec.empty()) 8088bcb0991SDimitry Andric SHeader.sh_info = toSectionIndex(Section.RelocatableSec, Section.Name); 8098bcb0991SDimitry Andric 8108bcb0991SDimitry Andric auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 8118bcb0991SDimitry Andric for (const auto &Rel : Section.Relocations) { 8128bcb0991SDimitry Andric unsigned SymIdx = Rel.Symbol ? toSymbolIndex(*Rel.Symbol, Section.Name, 8138bcb0991SDimitry Andric Section.Link == ".dynsym") 8148bcb0991SDimitry Andric : 0; 8158bcb0991SDimitry Andric if (IsRela) { 8168bcb0991SDimitry Andric Elf_Rela REntry; 8178bcb0991SDimitry Andric zero(REntry); 8188bcb0991SDimitry Andric REntry.r_offset = Rel.Offset; 8198bcb0991SDimitry Andric REntry.r_addend = Rel.Addend; 8208bcb0991SDimitry Andric REntry.setSymbolAndType(SymIdx, Rel.Type, isMips64EL(Doc)); 8218bcb0991SDimitry Andric OS.write((const char *)&REntry, sizeof(REntry)); 8228bcb0991SDimitry Andric } else { 8238bcb0991SDimitry Andric Elf_Rel REntry; 8248bcb0991SDimitry Andric zero(REntry); 8258bcb0991SDimitry Andric REntry.r_offset = Rel.Offset; 8268bcb0991SDimitry Andric REntry.setSymbolAndType(SymIdx, Rel.Type, isMips64EL(Doc)); 8278bcb0991SDimitry Andric OS.write((const char *)&REntry, sizeof(REntry)); 8288bcb0991SDimitry Andric } 8298bcb0991SDimitry Andric } 8308bcb0991SDimitry Andric } 8318bcb0991SDimitry Andric 8328bcb0991SDimitry Andric template <class ELFT> 833*480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 834*480093f4SDimitry Andric const ELFYAML::RelrSection &Section, 835*480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 836*480093f4SDimitry Andric raw_ostream &OS = 837*480093f4SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 838*480093f4SDimitry Andric SHeader.sh_entsize = 839*480093f4SDimitry Andric Section.EntSize ? uint64_t(*Section.EntSize) : sizeof(Elf_Relr); 840*480093f4SDimitry Andric 841*480093f4SDimitry Andric if (Section.Content) { 842*480093f4SDimitry Andric SHeader.sh_size = writeContent(OS, Section.Content, None); 843*480093f4SDimitry Andric return; 844*480093f4SDimitry Andric } 845*480093f4SDimitry Andric 846*480093f4SDimitry Andric if (!Section.Entries) 847*480093f4SDimitry Andric return; 848*480093f4SDimitry Andric 849*480093f4SDimitry Andric for (llvm::yaml::Hex64 E : *Section.Entries) { 850*480093f4SDimitry Andric if (!ELFT::Is64Bits && E > UINT32_MAX) 851*480093f4SDimitry Andric reportError(Section.Name + ": the value is too large for 32-bits: 0x" + 852*480093f4SDimitry Andric Twine::utohexstr(E)); 853*480093f4SDimitry Andric support::endian::write<uintX_t>(OS, E, ELFT::TargetEndianness); 854*480093f4SDimitry Andric } 855*480093f4SDimitry Andric 856*480093f4SDimitry Andric SHeader.sh_size = sizeof(uintX_t) * Section.Entries->size(); 857*480093f4SDimitry Andric } 858*480093f4SDimitry Andric 859*480093f4SDimitry Andric template <class ELFT> 8608bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 8618bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::SymtabShndxSection &Shndx, 8628bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 8638bcb0991SDimitry Andric raw_ostream &OS = 8648bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 8658bcb0991SDimitry Andric 8668bcb0991SDimitry Andric for (uint32_t E : Shndx.Entries) 8678bcb0991SDimitry Andric support::endian::write<uint32_t>(OS, E, ELFT::TargetEndianness); 8688bcb0991SDimitry Andric 8698bcb0991SDimitry Andric SHeader.sh_entsize = Shndx.EntSize ? (uint64_t)*Shndx.EntSize : 4; 8708bcb0991SDimitry Andric SHeader.sh_size = Shndx.Entries.size() * SHeader.sh_entsize; 8718bcb0991SDimitry Andric } 8728bcb0991SDimitry Andric 8738bcb0991SDimitry Andric template <class ELFT> 8748bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 8758bcb0991SDimitry Andric const ELFYAML::Group &Section, 8768bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 8778bcb0991SDimitry Andric assert(Section.Type == llvm::ELF::SHT_GROUP && 8788bcb0991SDimitry Andric "Section type is not SHT_GROUP"); 8798bcb0991SDimitry Andric 880*480093f4SDimitry Andric unsigned Link = 0; 881*480093f4SDimitry Andric if (Section.Link.empty() && SN2I.lookup(".symtab", Link)) 882*480093f4SDimitry Andric SHeader.sh_link = Link; 883*480093f4SDimitry Andric 8848bcb0991SDimitry Andric SHeader.sh_entsize = 4; 8858bcb0991SDimitry Andric SHeader.sh_size = SHeader.sh_entsize * Section.Members.size(); 886*480093f4SDimitry Andric 887*480093f4SDimitry Andric if (Section.Signature) 8888bcb0991SDimitry Andric SHeader.sh_info = 889*480093f4SDimitry Andric toSymbolIndex(*Section.Signature, Section.Name, /*IsDynamic=*/false); 8908bcb0991SDimitry Andric 8918bcb0991SDimitry Andric raw_ostream &OS = 8928bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 8938bcb0991SDimitry Andric 8948bcb0991SDimitry Andric for (const ELFYAML::SectionOrType &Member : Section.Members) { 8958bcb0991SDimitry Andric unsigned int SectionIndex = 0; 8968bcb0991SDimitry Andric if (Member.sectionNameOrType == "GRP_COMDAT") 8978bcb0991SDimitry Andric SectionIndex = llvm::ELF::GRP_COMDAT; 8988bcb0991SDimitry Andric else 8998bcb0991SDimitry Andric SectionIndex = toSectionIndex(Member.sectionNameOrType, Section.Name); 9008bcb0991SDimitry Andric support::endian::write<uint32_t>(OS, SectionIndex, ELFT::TargetEndianness); 9018bcb0991SDimitry Andric } 9028bcb0991SDimitry Andric } 9038bcb0991SDimitry Andric 9048bcb0991SDimitry Andric template <class ELFT> 9058bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 9068bcb0991SDimitry Andric const ELFYAML::SymverSection &Section, 9078bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 9088bcb0991SDimitry Andric raw_ostream &OS = 9098bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 9108bcb0991SDimitry Andric for (uint16_t Version : Section.Entries) 9118bcb0991SDimitry Andric support::endian::write<uint16_t>(OS, Version, ELFT::TargetEndianness); 9128bcb0991SDimitry Andric 9138bcb0991SDimitry Andric SHeader.sh_entsize = Section.EntSize ? (uint64_t)*Section.EntSize : 2; 9148bcb0991SDimitry Andric SHeader.sh_size = Section.Entries.size() * SHeader.sh_entsize; 9158bcb0991SDimitry Andric } 9168bcb0991SDimitry Andric 9178bcb0991SDimitry Andric template <class ELFT> 9188bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 9198bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::StackSizesSection &Section, 9208bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 9218bcb0991SDimitry Andric raw_ostream &OS = 9228bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 9238bcb0991SDimitry Andric 9248bcb0991SDimitry Andric if (Section.Content || Section.Size) { 9258bcb0991SDimitry Andric SHeader.sh_size = writeContent(OS, Section.Content, Section.Size); 9268bcb0991SDimitry Andric return; 9278bcb0991SDimitry Andric } 9288bcb0991SDimitry Andric 9298bcb0991SDimitry Andric for (const ELFYAML::StackSizeEntry &E : *Section.Entries) { 9308bcb0991SDimitry Andric support::endian::write<uintX_t>(OS, E.Address, ELFT::TargetEndianness); 9318bcb0991SDimitry Andric SHeader.sh_size += sizeof(uintX_t) + encodeULEB128(E.Size, OS); 9328bcb0991SDimitry Andric } 9338bcb0991SDimitry Andric } 9348bcb0991SDimitry Andric 9358bcb0991SDimitry Andric template <class ELFT> 936*480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent( 937*480093f4SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::LinkerOptionsSection &Section, 938*480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 939*480093f4SDimitry Andric raw_ostream &OS = 940*480093f4SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 941*480093f4SDimitry Andric 942*480093f4SDimitry Andric if (Section.Content) { 943*480093f4SDimitry Andric SHeader.sh_size = writeContent(OS, Section.Content, None); 944*480093f4SDimitry Andric return; 945*480093f4SDimitry Andric } 946*480093f4SDimitry Andric 947*480093f4SDimitry Andric if (!Section.Options) 948*480093f4SDimitry Andric return; 949*480093f4SDimitry Andric 950*480093f4SDimitry Andric for (const ELFYAML::LinkerOption &LO : *Section.Options) { 951*480093f4SDimitry Andric OS.write(LO.Key.data(), LO.Key.size()); 952*480093f4SDimitry Andric OS.write('\0'); 953*480093f4SDimitry Andric OS.write(LO.Value.data(), LO.Value.size()); 954*480093f4SDimitry Andric OS.write('\0'); 955*480093f4SDimitry Andric SHeader.sh_size += (LO.Key.size() + LO.Value.size() + 2); 956*480093f4SDimitry Andric } 957*480093f4SDimitry Andric } 958*480093f4SDimitry Andric 959*480093f4SDimitry Andric template <class ELFT> 960*480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent( 961*480093f4SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::DependentLibrariesSection &Section, 962*480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 963*480093f4SDimitry Andric raw_ostream &OS = 964*480093f4SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 965*480093f4SDimitry Andric 966*480093f4SDimitry Andric if (Section.Content) { 967*480093f4SDimitry Andric SHeader.sh_size = writeContent(OS, Section.Content, None); 968*480093f4SDimitry Andric return; 969*480093f4SDimitry Andric } 970*480093f4SDimitry Andric 971*480093f4SDimitry Andric if (!Section.Libs) 972*480093f4SDimitry Andric return; 973*480093f4SDimitry Andric 974*480093f4SDimitry Andric for (StringRef Lib : *Section.Libs) { 975*480093f4SDimitry Andric OS.write(Lib.data(), Lib.size()); 976*480093f4SDimitry Andric OS.write('\0'); 977*480093f4SDimitry Andric SHeader.sh_size += Lib.size() + 1; 978*480093f4SDimitry Andric } 979*480093f4SDimitry Andric } 980*480093f4SDimitry Andric 981*480093f4SDimitry Andric template <class ELFT> 9828bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 9838bcb0991SDimitry Andric const ELFYAML::HashSection &Section, 9848bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 9858bcb0991SDimitry Andric raw_ostream &OS = 9868bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 9878bcb0991SDimitry Andric 9888bcb0991SDimitry Andric unsigned Link = 0; 9898bcb0991SDimitry Andric if (Section.Link.empty() && SN2I.lookup(".dynsym", Link)) 9908bcb0991SDimitry Andric SHeader.sh_link = Link; 9918bcb0991SDimitry Andric 9928bcb0991SDimitry Andric if (Section.Content || Section.Size) { 9938bcb0991SDimitry Andric SHeader.sh_size = writeContent(OS, Section.Content, Section.Size); 9948bcb0991SDimitry Andric return; 9958bcb0991SDimitry Andric } 9968bcb0991SDimitry Andric 9978bcb0991SDimitry Andric support::endian::write<uint32_t>(OS, Section.Bucket->size(), 9988bcb0991SDimitry Andric ELFT::TargetEndianness); 9998bcb0991SDimitry Andric support::endian::write<uint32_t>(OS, Section.Chain->size(), 10008bcb0991SDimitry Andric ELFT::TargetEndianness); 10018bcb0991SDimitry Andric for (uint32_t Val : *Section.Bucket) 10028bcb0991SDimitry Andric support::endian::write<uint32_t>(OS, Val, ELFT::TargetEndianness); 10038bcb0991SDimitry Andric for (uint32_t Val : *Section.Chain) 10048bcb0991SDimitry Andric support::endian::write<uint32_t>(OS, Val, ELFT::TargetEndianness); 10058bcb0991SDimitry Andric 10068bcb0991SDimitry Andric SHeader.sh_size = (2 + Section.Bucket->size() + Section.Chain->size()) * 4; 10078bcb0991SDimitry Andric } 10088bcb0991SDimitry Andric 10098bcb0991SDimitry Andric template <class ELFT> 10108bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 10118bcb0991SDimitry Andric const ELFYAML::VerdefSection &Section, 10128bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 10138bcb0991SDimitry Andric typedef typename ELFT::Verdef Elf_Verdef; 10148bcb0991SDimitry Andric typedef typename ELFT::Verdaux Elf_Verdaux; 10158bcb0991SDimitry Andric raw_ostream &OS = 10168bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 10178bcb0991SDimitry Andric 1018*480093f4SDimitry Andric SHeader.sh_info = Section.Info; 1019*480093f4SDimitry Andric 1020*480093f4SDimitry Andric if (Section.Content) { 1021*480093f4SDimitry Andric SHeader.sh_size = writeContent(OS, Section.Content, None); 1022*480093f4SDimitry Andric return; 1023*480093f4SDimitry Andric } 1024*480093f4SDimitry Andric 1025*480093f4SDimitry Andric if (!Section.Entries) 1026*480093f4SDimitry Andric return; 1027*480093f4SDimitry Andric 10288bcb0991SDimitry Andric uint64_t AuxCnt = 0; 1029*480093f4SDimitry Andric for (size_t I = 0; I < Section.Entries->size(); ++I) { 1030*480093f4SDimitry Andric const ELFYAML::VerdefEntry &E = (*Section.Entries)[I]; 10318bcb0991SDimitry Andric 10328bcb0991SDimitry Andric Elf_Verdef VerDef; 10338bcb0991SDimitry Andric VerDef.vd_version = E.Version; 10348bcb0991SDimitry Andric VerDef.vd_flags = E.Flags; 10358bcb0991SDimitry Andric VerDef.vd_ndx = E.VersionNdx; 10368bcb0991SDimitry Andric VerDef.vd_hash = E.Hash; 10378bcb0991SDimitry Andric VerDef.vd_aux = sizeof(Elf_Verdef); 10388bcb0991SDimitry Andric VerDef.vd_cnt = E.VerNames.size(); 1039*480093f4SDimitry Andric if (I == Section.Entries->size() - 1) 10408bcb0991SDimitry Andric VerDef.vd_next = 0; 10418bcb0991SDimitry Andric else 10428bcb0991SDimitry Andric VerDef.vd_next = 10438bcb0991SDimitry Andric sizeof(Elf_Verdef) + E.VerNames.size() * sizeof(Elf_Verdaux); 10448bcb0991SDimitry Andric OS.write((const char *)&VerDef, sizeof(Elf_Verdef)); 10458bcb0991SDimitry Andric 10468bcb0991SDimitry Andric for (size_t J = 0; J < E.VerNames.size(); ++J, ++AuxCnt) { 10478bcb0991SDimitry Andric Elf_Verdaux VernAux; 10488bcb0991SDimitry Andric VernAux.vda_name = DotDynstr.getOffset(E.VerNames[J]); 10498bcb0991SDimitry Andric if (J == E.VerNames.size() - 1) 10508bcb0991SDimitry Andric VernAux.vda_next = 0; 10518bcb0991SDimitry Andric else 10528bcb0991SDimitry Andric VernAux.vda_next = sizeof(Elf_Verdaux); 10538bcb0991SDimitry Andric OS.write((const char *)&VernAux, sizeof(Elf_Verdaux)); 10548bcb0991SDimitry Andric } 10558bcb0991SDimitry Andric } 10568bcb0991SDimitry Andric 1057*480093f4SDimitry Andric SHeader.sh_size = Section.Entries->size() * sizeof(Elf_Verdef) + 10588bcb0991SDimitry Andric AuxCnt * sizeof(Elf_Verdaux); 10598bcb0991SDimitry Andric } 10608bcb0991SDimitry Andric 10618bcb0991SDimitry Andric template <class ELFT> 10628bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 10638bcb0991SDimitry Andric const ELFYAML::VerneedSection &Section, 10648bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 10658bcb0991SDimitry Andric typedef typename ELFT::Verneed Elf_Verneed; 10668bcb0991SDimitry Andric typedef typename ELFT::Vernaux Elf_Vernaux; 10678bcb0991SDimitry Andric 10688bcb0991SDimitry Andric auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 1069*480093f4SDimitry Andric SHeader.sh_info = Section.Info; 1070*480093f4SDimitry Andric 1071*480093f4SDimitry Andric if (Section.Content) { 1072*480093f4SDimitry Andric SHeader.sh_size = writeContent(OS, Section.Content, None); 1073*480093f4SDimitry Andric return; 1074*480093f4SDimitry Andric } 1075*480093f4SDimitry Andric 1076*480093f4SDimitry Andric if (!Section.VerneedV) 1077*480093f4SDimitry Andric return; 10788bcb0991SDimitry Andric 10798bcb0991SDimitry Andric uint64_t AuxCnt = 0; 1080*480093f4SDimitry Andric for (size_t I = 0; I < Section.VerneedV->size(); ++I) { 1081*480093f4SDimitry Andric const ELFYAML::VerneedEntry &VE = (*Section.VerneedV)[I]; 10828bcb0991SDimitry Andric 10838bcb0991SDimitry Andric Elf_Verneed VerNeed; 10848bcb0991SDimitry Andric VerNeed.vn_version = VE.Version; 10858bcb0991SDimitry Andric VerNeed.vn_file = DotDynstr.getOffset(VE.File); 1086*480093f4SDimitry Andric if (I == Section.VerneedV->size() - 1) 10878bcb0991SDimitry Andric VerNeed.vn_next = 0; 10888bcb0991SDimitry Andric else 10898bcb0991SDimitry Andric VerNeed.vn_next = 10908bcb0991SDimitry Andric sizeof(Elf_Verneed) + VE.AuxV.size() * sizeof(Elf_Vernaux); 10918bcb0991SDimitry Andric VerNeed.vn_cnt = VE.AuxV.size(); 10928bcb0991SDimitry Andric VerNeed.vn_aux = sizeof(Elf_Verneed); 10938bcb0991SDimitry Andric OS.write((const char *)&VerNeed, sizeof(Elf_Verneed)); 10948bcb0991SDimitry Andric 10958bcb0991SDimitry Andric for (size_t J = 0; J < VE.AuxV.size(); ++J, ++AuxCnt) { 10968bcb0991SDimitry Andric const ELFYAML::VernauxEntry &VAuxE = VE.AuxV[J]; 10978bcb0991SDimitry Andric 10988bcb0991SDimitry Andric Elf_Vernaux VernAux; 10998bcb0991SDimitry Andric VernAux.vna_hash = VAuxE.Hash; 11008bcb0991SDimitry Andric VernAux.vna_flags = VAuxE.Flags; 11018bcb0991SDimitry Andric VernAux.vna_other = VAuxE.Other; 11028bcb0991SDimitry Andric VernAux.vna_name = DotDynstr.getOffset(VAuxE.Name); 11038bcb0991SDimitry Andric if (J == VE.AuxV.size() - 1) 11048bcb0991SDimitry Andric VernAux.vna_next = 0; 11058bcb0991SDimitry Andric else 11068bcb0991SDimitry Andric VernAux.vna_next = sizeof(Elf_Vernaux); 11078bcb0991SDimitry Andric OS.write((const char *)&VernAux, sizeof(Elf_Vernaux)); 11088bcb0991SDimitry Andric } 11098bcb0991SDimitry Andric } 11108bcb0991SDimitry Andric 1111*480093f4SDimitry Andric SHeader.sh_size = Section.VerneedV->size() * sizeof(Elf_Verneed) + 11128bcb0991SDimitry Andric AuxCnt * sizeof(Elf_Vernaux); 11138bcb0991SDimitry Andric } 11148bcb0991SDimitry Andric 11158bcb0991SDimitry Andric template <class ELFT> 11168bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 11178bcb0991SDimitry Andric const ELFYAML::MipsABIFlags &Section, 11188bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 11198bcb0991SDimitry Andric assert(Section.Type == llvm::ELF::SHT_MIPS_ABIFLAGS && 11208bcb0991SDimitry Andric "Section type is not SHT_MIPS_ABIFLAGS"); 11218bcb0991SDimitry Andric 11228bcb0991SDimitry Andric object::Elf_Mips_ABIFlags<ELFT> Flags; 11238bcb0991SDimitry Andric zero(Flags); 11248bcb0991SDimitry Andric SHeader.sh_entsize = sizeof(Flags); 11258bcb0991SDimitry Andric SHeader.sh_size = SHeader.sh_entsize; 11268bcb0991SDimitry Andric 11278bcb0991SDimitry Andric auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 11288bcb0991SDimitry Andric Flags.version = Section.Version; 11298bcb0991SDimitry Andric Flags.isa_level = Section.ISALevel; 11308bcb0991SDimitry Andric Flags.isa_rev = Section.ISARevision; 11318bcb0991SDimitry Andric Flags.gpr_size = Section.GPRSize; 11328bcb0991SDimitry Andric Flags.cpr1_size = Section.CPR1Size; 11338bcb0991SDimitry Andric Flags.cpr2_size = Section.CPR2Size; 11348bcb0991SDimitry Andric Flags.fp_abi = Section.FpABI; 11358bcb0991SDimitry Andric Flags.isa_ext = Section.ISAExtension; 11368bcb0991SDimitry Andric Flags.ases = Section.ASEs; 11378bcb0991SDimitry Andric Flags.flags1 = Section.Flags1; 11388bcb0991SDimitry Andric Flags.flags2 = Section.Flags2; 11398bcb0991SDimitry Andric OS.write((const char *)&Flags, sizeof(Flags)); 11408bcb0991SDimitry Andric } 11418bcb0991SDimitry Andric 11428bcb0991SDimitry Andric template <class ELFT> 11438bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 11448bcb0991SDimitry Andric const ELFYAML::DynamicSection &Section, 11458bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 11468bcb0991SDimitry Andric assert(Section.Type == llvm::ELF::SHT_DYNAMIC && 11478bcb0991SDimitry Andric "Section type is not SHT_DYNAMIC"); 11488bcb0991SDimitry Andric 11498bcb0991SDimitry Andric if (!Section.Entries.empty() && Section.Content) 11508bcb0991SDimitry Andric reportError("cannot specify both raw content and explicit entries " 11518bcb0991SDimitry Andric "for dynamic section '" + 11528bcb0991SDimitry Andric Section.Name + "'"); 11538bcb0991SDimitry Andric 11548bcb0991SDimitry Andric if (Section.Content) 11558bcb0991SDimitry Andric SHeader.sh_size = Section.Content->binary_size(); 11568bcb0991SDimitry Andric else 11578bcb0991SDimitry Andric SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries.size(); 11588bcb0991SDimitry Andric if (Section.EntSize) 11598bcb0991SDimitry Andric SHeader.sh_entsize = *Section.EntSize; 11608bcb0991SDimitry Andric else 11618bcb0991SDimitry Andric SHeader.sh_entsize = sizeof(Elf_Dyn); 11628bcb0991SDimitry Andric 11638bcb0991SDimitry Andric raw_ostream &OS = 11648bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 11658bcb0991SDimitry Andric for (const ELFYAML::DynamicEntry &DE : Section.Entries) { 11668bcb0991SDimitry Andric support::endian::write<uintX_t>(OS, DE.Tag, ELFT::TargetEndianness); 11678bcb0991SDimitry Andric support::endian::write<uintX_t>(OS, DE.Val, ELFT::TargetEndianness); 11688bcb0991SDimitry Andric } 11698bcb0991SDimitry Andric if (Section.Content) 11708bcb0991SDimitry Andric Section.Content->writeAsBinary(OS); 11718bcb0991SDimitry Andric } 11728bcb0991SDimitry Andric 11738bcb0991SDimitry Andric template <class ELFT> 11748bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 11758bcb0991SDimitry Andric const ELFYAML::AddrsigSection &Section, 11768bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 11778bcb0991SDimitry Andric raw_ostream &OS = 11788bcb0991SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 11798bcb0991SDimitry Andric 11808bcb0991SDimitry Andric unsigned Link = 0; 11818bcb0991SDimitry Andric if (Section.Link.empty() && SN2I.lookup(".symtab", Link)) 11828bcb0991SDimitry Andric SHeader.sh_link = Link; 11838bcb0991SDimitry Andric 11848bcb0991SDimitry Andric if (Section.Content || Section.Size) { 11858bcb0991SDimitry Andric SHeader.sh_size = writeContent(OS, Section.Content, Section.Size); 11868bcb0991SDimitry Andric return; 11878bcb0991SDimitry Andric } 11888bcb0991SDimitry Andric 11898bcb0991SDimitry Andric for (const ELFYAML::AddrsigSymbol &Sym : *Section.Symbols) { 11908bcb0991SDimitry Andric uint64_t Val = 11918bcb0991SDimitry Andric Sym.Name ? toSymbolIndex(*Sym.Name, Section.Name, /*IsDynamic=*/false) 11928bcb0991SDimitry Andric : (uint32_t)*Sym.Index; 11938bcb0991SDimitry Andric SHeader.sh_size += encodeULEB128(Val, OS); 11948bcb0991SDimitry Andric } 11958bcb0991SDimitry Andric } 11968bcb0991SDimitry Andric 1197*480093f4SDimitry Andric template <class ELFT> 1198*480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 1199*480093f4SDimitry Andric const ELFYAML::NoteSection &Section, 1200*480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1201*480093f4SDimitry Andric raw_ostream &OS = 1202*480093f4SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 1203*480093f4SDimitry Andric uint64_t Offset = OS.tell(); 1204*480093f4SDimitry Andric 1205*480093f4SDimitry Andric if (Section.Content || Section.Size) { 1206*480093f4SDimitry Andric SHeader.sh_size = writeContent(OS, Section.Content, Section.Size); 1207*480093f4SDimitry Andric return; 1208*480093f4SDimitry Andric } 1209*480093f4SDimitry Andric 1210*480093f4SDimitry Andric for (const ELFYAML::NoteEntry &NE : *Section.Notes) { 1211*480093f4SDimitry Andric // Write name size. 1212*480093f4SDimitry Andric if (NE.Name.empty()) 1213*480093f4SDimitry Andric support::endian::write<uint32_t>(OS, 0, ELFT::TargetEndianness); 1214*480093f4SDimitry Andric else 1215*480093f4SDimitry Andric support::endian::write<uint32_t>(OS, NE.Name.size() + 1, 1216*480093f4SDimitry Andric ELFT::TargetEndianness); 1217*480093f4SDimitry Andric 1218*480093f4SDimitry Andric // Write description size. 1219*480093f4SDimitry Andric if (NE.Desc.binary_size() == 0) 1220*480093f4SDimitry Andric support::endian::write<uint32_t>(OS, 0, ELFT::TargetEndianness); 1221*480093f4SDimitry Andric else 1222*480093f4SDimitry Andric support::endian::write<uint32_t>(OS, NE.Desc.binary_size(), 1223*480093f4SDimitry Andric ELFT::TargetEndianness); 1224*480093f4SDimitry Andric 1225*480093f4SDimitry Andric // Write type. 1226*480093f4SDimitry Andric support::endian::write<uint32_t>(OS, NE.Type, ELFT::TargetEndianness); 1227*480093f4SDimitry Andric 1228*480093f4SDimitry Andric // Write name, null terminator and padding. 1229*480093f4SDimitry Andric if (!NE.Name.empty()) { 1230*480093f4SDimitry Andric support::endian::write<uint8_t>(OS, arrayRefFromStringRef(NE.Name), 1231*480093f4SDimitry Andric ELFT::TargetEndianness); 1232*480093f4SDimitry Andric support::endian::write<uint8_t>(OS, 0, ELFT::TargetEndianness); 1233*480093f4SDimitry Andric CBA.padToAlignment(4); 1234*480093f4SDimitry Andric } 1235*480093f4SDimitry Andric 1236*480093f4SDimitry Andric // Write description and padding. 1237*480093f4SDimitry Andric if (NE.Desc.binary_size() != 0) { 1238*480093f4SDimitry Andric NE.Desc.writeAsBinary(OS); 1239*480093f4SDimitry Andric CBA.padToAlignment(4); 1240*480093f4SDimitry Andric } 1241*480093f4SDimitry Andric } 1242*480093f4SDimitry Andric 1243*480093f4SDimitry Andric SHeader.sh_size = OS.tell() - Offset; 1244*480093f4SDimitry Andric } 1245*480093f4SDimitry Andric 1246*480093f4SDimitry Andric template <class ELFT> 1247*480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 1248*480093f4SDimitry Andric const ELFYAML::GnuHashSection &Section, 1249*480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1250*480093f4SDimitry Andric raw_ostream &OS = 1251*480093f4SDimitry Andric CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); 1252*480093f4SDimitry Andric 1253*480093f4SDimitry Andric unsigned Link = 0; 1254*480093f4SDimitry Andric if (Section.Link.empty() && SN2I.lookup(".dynsym", Link)) 1255*480093f4SDimitry Andric SHeader.sh_link = Link; 1256*480093f4SDimitry Andric 1257*480093f4SDimitry Andric if (Section.Content) { 1258*480093f4SDimitry Andric SHeader.sh_size = writeContent(OS, Section.Content, None); 1259*480093f4SDimitry Andric return; 1260*480093f4SDimitry Andric } 1261*480093f4SDimitry Andric 1262*480093f4SDimitry Andric // We write the header first, starting with the hash buckets count. Normally 1263*480093f4SDimitry Andric // it is the number of entries in HashBuckets, but the "NBuckets" property can 1264*480093f4SDimitry Andric // be used to override this field, which is useful for producing broken 1265*480093f4SDimitry Andric // objects. 1266*480093f4SDimitry Andric if (Section.Header->NBuckets) 1267*480093f4SDimitry Andric support::endian::write<uint32_t>(OS, *Section.Header->NBuckets, 1268*480093f4SDimitry Andric ELFT::TargetEndianness); 1269*480093f4SDimitry Andric else 1270*480093f4SDimitry Andric support::endian::write<uint32_t>(OS, Section.HashBuckets->size(), 1271*480093f4SDimitry Andric ELFT::TargetEndianness); 1272*480093f4SDimitry Andric 1273*480093f4SDimitry Andric // Write the index of the first symbol in the dynamic symbol table accessible 1274*480093f4SDimitry Andric // via the hash table. 1275*480093f4SDimitry Andric support::endian::write<uint32_t>(OS, Section.Header->SymNdx, 1276*480093f4SDimitry Andric ELFT::TargetEndianness); 1277*480093f4SDimitry Andric 1278*480093f4SDimitry Andric // Write the number of words in the Bloom filter. As above, the "MaskWords" 1279*480093f4SDimitry Andric // property can be used to set this field to any value. 1280*480093f4SDimitry Andric if (Section.Header->MaskWords) 1281*480093f4SDimitry Andric support::endian::write<uint32_t>(OS, *Section.Header->MaskWords, 1282*480093f4SDimitry Andric ELFT::TargetEndianness); 1283*480093f4SDimitry Andric else 1284*480093f4SDimitry Andric support::endian::write<uint32_t>(OS, Section.BloomFilter->size(), 1285*480093f4SDimitry Andric ELFT::TargetEndianness); 1286*480093f4SDimitry Andric 1287*480093f4SDimitry Andric // Write the shift constant used by the Bloom filter. 1288*480093f4SDimitry Andric support::endian::write<uint32_t>(OS, Section.Header->Shift2, 1289*480093f4SDimitry Andric ELFT::TargetEndianness); 1290*480093f4SDimitry Andric 1291*480093f4SDimitry Andric // We've finished writing the header. Now write the Bloom filter. 1292*480093f4SDimitry Andric for (llvm::yaml::Hex64 Val : *Section.BloomFilter) 1293*480093f4SDimitry Andric support::endian::write<typename ELFT::uint>(OS, Val, 1294*480093f4SDimitry Andric ELFT::TargetEndianness); 1295*480093f4SDimitry Andric 1296*480093f4SDimitry Andric // Write an array of hash buckets. 1297*480093f4SDimitry Andric for (llvm::yaml::Hex32 Val : *Section.HashBuckets) 1298*480093f4SDimitry Andric support::endian::write<uint32_t>(OS, Val, ELFT::TargetEndianness); 1299*480093f4SDimitry Andric 1300*480093f4SDimitry Andric // Write an array of hash values. 1301*480093f4SDimitry Andric for (llvm::yaml::Hex32 Val : *Section.HashValues) 1302*480093f4SDimitry Andric support::endian::write<uint32_t>(OS, Val, ELFT::TargetEndianness); 1303*480093f4SDimitry Andric 1304*480093f4SDimitry Andric SHeader.sh_size = 16 /*Header size*/ + 1305*480093f4SDimitry Andric Section.BloomFilter->size() * sizeof(typename ELFT::uint) + 1306*480093f4SDimitry Andric Section.HashBuckets->size() * 4 + 1307*480093f4SDimitry Andric Section.HashValues->size() * 4; 1308*480093f4SDimitry Andric } 1309*480093f4SDimitry Andric 1310*480093f4SDimitry Andric template <class ELFT> 1311*480093f4SDimitry Andric void ELFState<ELFT>::writeFill(ELFYAML::Fill &Fill, 1312*480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1313*480093f4SDimitry Andric raw_ostream &OS = CBA.getOSAndAlignedOffset(Fill.ShOffset, /*Align=*/1); 1314*480093f4SDimitry Andric 1315*480093f4SDimitry Andric size_t PatternSize = Fill.Pattern ? Fill.Pattern->binary_size() : 0; 1316*480093f4SDimitry Andric if (!PatternSize) { 1317*480093f4SDimitry Andric OS.write_zeros(Fill.Size); 1318*480093f4SDimitry Andric return; 1319*480093f4SDimitry Andric } 1320*480093f4SDimitry Andric 1321*480093f4SDimitry Andric // Fill the content with the specified pattern. 1322*480093f4SDimitry Andric uint64_t Written = 0; 1323*480093f4SDimitry Andric for (; Written + PatternSize <= Fill.Size; Written += PatternSize) 1324*480093f4SDimitry Andric Fill.Pattern->writeAsBinary(OS); 1325*480093f4SDimitry Andric Fill.Pattern->writeAsBinary(OS, Fill.Size - Written); 1326*480093f4SDimitry Andric } 1327*480093f4SDimitry Andric 13288bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::buildSectionIndex() { 1329*480093f4SDimitry Andric size_t SecNdx = -1; 1330*480093f4SDimitry Andric StringSet<> Seen; 1331*480093f4SDimitry Andric for (size_t I = 0; I < Doc.Chunks.size(); ++I) { 1332*480093f4SDimitry Andric const std::unique_ptr<ELFYAML::Chunk> &C = Doc.Chunks[I]; 1333*480093f4SDimitry Andric bool IsSection = isa<ELFYAML::Section>(C.get()); 1334*480093f4SDimitry Andric if (IsSection) 1335*480093f4SDimitry Andric ++SecNdx; 1336*480093f4SDimitry Andric 1337*480093f4SDimitry Andric if (C->Name.empty()) 13388bcb0991SDimitry Andric continue; 13398bcb0991SDimitry Andric 1340*480093f4SDimitry Andric if (!Seen.insert(C->Name).second) 1341*480093f4SDimitry Andric reportError("repeated section/fill name: '" + C->Name + 1342*480093f4SDimitry Andric "' at YAML section/fill number " + Twine(I)); 1343*480093f4SDimitry Andric if (!IsSection || HasError) 1344*480093f4SDimitry Andric continue; 1345*480093f4SDimitry Andric 1346*480093f4SDimitry Andric if (!SN2I.addName(C->Name, SecNdx)) 1347*480093f4SDimitry Andric llvm_unreachable("buildSectionIndex() failed"); 1348*480093f4SDimitry Andric DotShStrtab.add(ELFYAML::dropUniqueSuffix(C->Name)); 13498bcb0991SDimitry Andric } 13508bcb0991SDimitry Andric 13518bcb0991SDimitry Andric DotShStrtab.finalize(); 13528bcb0991SDimitry Andric } 13538bcb0991SDimitry Andric 13548bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::buildSymbolIndexes() { 13558bcb0991SDimitry Andric auto Build = [this](ArrayRef<ELFYAML::Symbol> V, NameToIdxMap &Map) { 13568bcb0991SDimitry Andric for (size_t I = 0, S = V.size(); I < S; ++I) { 13578bcb0991SDimitry Andric const ELFYAML::Symbol &Sym = V[I]; 13588bcb0991SDimitry Andric if (!Sym.Name.empty() && !Map.addName(Sym.Name, I + 1)) 13598bcb0991SDimitry Andric reportError("repeated symbol name: '" + Sym.Name + "'"); 13608bcb0991SDimitry Andric } 13618bcb0991SDimitry Andric }; 13628bcb0991SDimitry Andric 13638bcb0991SDimitry Andric if (Doc.Symbols) 13648bcb0991SDimitry Andric Build(*Doc.Symbols, SymN2I); 1365*480093f4SDimitry Andric if (Doc.DynamicSymbols) 1366*480093f4SDimitry Andric Build(*Doc.DynamicSymbols, DynSymN2I); 13678bcb0991SDimitry Andric } 13688bcb0991SDimitry Andric 13698bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::finalizeStrings() { 13708bcb0991SDimitry Andric // Add the regular symbol names to .strtab section. 13718bcb0991SDimitry Andric if (Doc.Symbols) 13728bcb0991SDimitry Andric for (const ELFYAML::Symbol &Sym : *Doc.Symbols) 13738bcb0991SDimitry Andric DotStrtab.add(ELFYAML::dropUniqueSuffix(Sym.Name)); 13748bcb0991SDimitry Andric DotStrtab.finalize(); 13758bcb0991SDimitry Andric 13768bcb0991SDimitry Andric // Add the dynamic symbol names to .dynstr section. 1377*480093f4SDimitry Andric if (Doc.DynamicSymbols) 1378*480093f4SDimitry Andric for (const ELFYAML::Symbol &Sym : *Doc.DynamicSymbols) 13798bcb0991SDimitry Andric DotDynstr.add(ELFYAML::dropUniqueSuffix(Sym.Name)); 13808bcb0991SDimitry Andric 13818bcb0991SDimitry Andric // SHT_GNU_verdef and SHT_GNU_verneed sections might also 13828bcb0991SDimitry Andric // add strings to .dynstr section. 1383*480093f4SDimitry Andric for (const ELFYAML::Chunk *Sec : Doc.getSections()) { 1384*480093f4SDimitry Andric if (auto VerNeed = dyn_cast<ELFYAML::VerneedSection>(Sec)) { 1385*480093f4SDimitry Andric if (VerNeed->VerneedV) { 1386*480093f4SDimitry Andric for (const ELFYAML::VerneedEntry &VE : *VerNeed->VerneedV) { 13878bcb0991SDimitry Andric DotDynstr.add(VE.File); 13888bcb0991SDimitry Andric for (const ELFYAML::VernauxEntry &Aux : VE.AuxV) 13898bcb0991SDimitry Andric DotDynstr.add(Aux.Name); 13908bcb0991SDimitry Andric } 1391*480093f4SDimitry Andric } 1392*480093f4SDimitry Andric } else if (auto VerDef = dyn_cast<ELFYAML::VerdefSection>(Sec)) { 1393*480093f4SDimitry Andric if (VerDef->Entries) 1394*480093f4SDimitry Andric for (const ELFYAML::VerdefEntry &E : *VerDef->Entries) 13958bcb0991SDimitry Andric for (StringRef Name : E.VerNames) 13968bcb0991SDimitry Andric DotDynstr.add(Name); 13978bcb0991SDimitry Andric } 13988bcb0991SDimitry Andric } 13998bcb0991SDimitry Andric 14008bcb0991SDimitry Andric DotDynstr.finalize(); 14018bcb0991SDimitry Andric } 14028bcb0991SDimitry Andric 14038bcb0991SDimitry Andric template <class ELFT> 14048bcb0991SDimitry Andric bool ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc, 14058bcb0991SDimitry Andric yaml::ErrorHandler EH) { 14068bcb0991SDimitry Andric ELFState<ELFT> State(Doc, EH); 14078bcb0991SDimitry Andric 14088bcb0991SDimitry Andric // Finalize .strtab and .dynstr sections. We do that early because want to 14098bcb0991SDimitry Andric // finalize the string table builders before writing the content of the 14108bcb0991SDimitry Andric // sections that might want to use them. 14118bcb0991SDimitry Andric State.finalizeStrings(); 14128bcb0991SDimitry Andric 14138bcb0991SDimitry Andric State.buildSectionIndex(); 1414*480093f4SDimitry Andric if (State.HasError) 1415*480093f4SDimitry Andric return false; 1416*480093f4SDimitry Andric 14178bcb0991SDimitry Andric State.buildSymbolIndexes(); 14188bcb0991SDimitry Andric 14198bcb0991SDimitry Andric std::vector<Elf_Phdr> PHeaders; 14208bcb0991SDimitry Andric State.initProgramHeaders(PHeaders); 14218bcb0991SDimitry Andric 14228bcb0991SDimitry Andric // XXX: This offset is tightly coupled with the order that we write 14238bcb0991SDimitry Andric // things to `OS`. 14248bcb0991SDimitry Andric const size_t SectionContentBeginOffset = 14258bcb0991SDimitry Andric sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * Doc.ProgramHeaders.size(); 14268bcb0991SDimitry Andric ContiguousBlobAccumulator CBA(SectionContentBeginOffset); 14278bcb0991SDimitry Andric 14288bcb0991SDimitry Andric std::vector<Elf_Shdr> SHeaders; 14298bcb0991SDimitry Andric State.initSectionHeaders(SHeaders, CBA); 14308bcb0991SDimitry Andric 1431*480093f4SDimitry Andric // Now we can decide segment offsets. 14328bcb0991SDimitry Andric State.setProgramHeaderLayout(PHeaders, SHeaders); 14338bcb0991SDimitry Andric 14348bcb0991SDimitry Andric if (State.HasError) 14358bcb0991SDimitry Andric return false; 14368bcb0991SDimitry Andric 14378bcb0991SDimitry Andric State.writeELFHeader(CBA, OS); 14388bcb0991SDimitry Andric writeArrayData(OS, makeArrayRef(PHeaders)); 14398bcb0991SDimitry Andric CBA.writeBlobToStream(OS); 14408bcb0991SDimitry Andric writeArrayData(OS, makeArrayRef(SHeaders)); 14418bcb0991SDimitry Andric return true; 14428bcb0991SDimitry Andric } 14438bcb0991SDimitry Andric 14448bcb0991SDimitry Andric namespace llvm { 14458bcb0991SDimitry Andric namespace yaml { 14468bcb0991SDimitry Andric 14478bcb0991SDimitry Andric bool yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH) { 14488bcb0991SDimitry Andric bool IsLE = Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB); 14498bcb0991SDimitry Andric bool Is64Bit = Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64); 14508bcb0991SDimitry Andric if (Is64Bit) { 14518bcb0991SDimitry Andric if (IsLE) 14528bcb0991SDimitry Andric return ELFState<object::ELF64LE>::writeELF(Out, Doc, EH); 14538bcb0991SDimitry Andric return ELFState<object::ELF64BE>::writeELF(Out, Doc, EH); 14548bcb0991SDimitry Andric } 14558bcb0991SDimitry Andric if (IsLE) 14568bcb0991SDimitry Andric return ELFState<object::ELF32LE>::writeELF(Out, Doc, EH); 14578bcb0991SDimitry Andric return ELFState<object::ELF32BE>::writeELF(Out, Doc, EH); 14588bcb0991SDimitry Andric } 14598bcb0991SDimitry Andric 14608bcb0991SDimitry Andric } // namespace yaml 14618bcb0991SDimitry Andric } // namespace llvm 1462