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" 15480093f4SDimitry Andric #include "llvm/ADT/DenseMap.h" 165ffd83dbSDimitry Andric #include "llvm/ADT/SetVector.h" 178bcb0991SDimitry Andric #include "llvm/ADT/StringSet.h" 188bcb0991SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 198bcb0991SDimitry Andric #include "llvm/MC/StringTableBuilder.h" 208bcb0991SDimitry Andric #include "llvm/Object/ELFObjectFile.h" 21fe6060f1SDimitry Andric #include "llvm/Object/ELFTypes.h" 225ffd83dbSDimitry Andric #include "llvm/ObjectYAML/DWARFEmitter.h" 235ffd83dbSDimitry Andric #include "llvm/ObjectYAML/DWARFYAML.h" 248bcb0991SDimitry Andric #include "llvm/ObjectYAML/ELFYAML.h" 258bcb0991SDimitry Andric #include "llvm/ObjectYAML/yaml2obj.h" 268bcb0991SDimitry Andric #include "llvm/Support/EndianStream.h" 275ffd83dbSDimitry Andric #include "llvm/Support/Errc.h" 285ffd83dbSDimitry Andric #include "llvm/Support/Error.h" 298bcb0991SDimitry Andric #include "llvm/Support/LEB128.h" 308bcb0991SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 318bcb0991SDimitry Andric #include "llvm/Support/WithColor.h" 328bcb0991SDimitry Andric #include "llvm/Support/YAMLTraits.h" 338bcb0991SDimitry Andric #include "llvm/Support/raw_ostream.h" 348bcb0991SDimitry Andric 358bcb0991SDimitry Andric using namespace llvm; 368bcb0991SDimitry Andric 378bcb0991SDimitry Andric // This class is used to build up a contiguous binary blob while keeping 388bcb0991SDimitry Andric // track of an offset in the output (which notionally begins at 398bcb0991SDimitry Andric // `InitialOffset`). 405ffd83dbSDimitry Andric // The blob might be limited to an arbitrary size. All attempts to write data 415ffd83dbSDimitry Andric // are ignored and the error condition is remembered once the limit is reached. 425ffd83dbSDimitry Andric // Such an approach allows us to simplify the code by delaying error reporting 435ffd83dbSDimitry Andric // and doing it at a convenient time. 448bcb0991SDimitry Andric namespace { 458bcb0991SDimitry Andric class ContiguousBlobAccumulator { 468bcb0991SDimitry Andric const uint64_t InitialOffset; 475ffd83dbSDimitry Andric const uint64_t MaxSize; 485ffd83dbSDimitry Andric 498bcb0991SDimitry Andric SmallVector<char, 128> Buf; 508bcb0991SDimitry Andric raw_svector_ostream OS; 515ffd83dbSDimitry Andric Error ReachedLimitErr = Error::success(); 525ffd83dbSDimitry Andric 535ffd83dbSDimitry Andric bool checkLimit(uint64_t Size) { 545ffd83dbSDimitry Andric if (!ReachedLimitErr && getOffset() + Size <= MaxSize) 555ffd83dbSDimitry Andric return true; 565ffd83dbSDimitry Andric if (!ReachedLimitErr) 575ffd83dbSDimitry Andric ReachedLimitErr = createStringError(errc::invalid_argument, 585ffd83dbSDimitry Andric "reached the output size limit"); 595ffd83dbSDimitry Andric return false; 605ffd83dbSDimitry Andric } 618bcb0991SDimitry Andric 62480093f4SDimitry Andric public: 635ffd83dbSDimitry Andric ContiguousBlobAccumulator(uint64_t BaseOffset, uint64_t SizeLimit) 645ffd83dbSDimitry Andric : InitialOffset(BaseOffset), MaxSize(SizeLimit), OS(Buf) {} 65480093f4SDimitry Andric 665ffd83dbSDimitry Andric uint64_t tell() const { return OS.tell(); } 675ffd83dbSDimitry Andric uint64_t getOffset() const { return InitialOffset + OS.tell(); } 685ffd83dbSDimitry Andric void writeBlobToStream(raw_ostream &Out) const { Out << OS.str(); } 695ffd83dbSDimitry Andric 705ffd83dbSDimitry Andric Error takeLimitError() { 715ffd83dbSDimitry Andric // Request to write 0 bytes to check we did not reach the limit. 725ffd83dbSDimitry Andric checkLimit(0); 735ffd83dbSDimitry Andric return std::move(ReachedLimitErr); 74480093f4SDimitry Andric } 75480093f4SDimitry Andric 768bcb0991SDimitry Andric /// \returns The new offset. 778bcb0991SDimitry Andric uint64_t padToAlignment(unsigned Align) { 785ffd83dbSDimitry Andric uint64_t CurrentOffset = getOffset(); 795ffd83dbSDimitry Andric if (ReachedLimitErr) 805ffd83dbSDimitry Andric return CurrentOffset; 815ffd83dbSDimitry Andric 825ffd83dbSDimitry Andric uint64_t AlignedOffset = alignTo(CurrentOffset, Align == 0 ? 1 : Align); 835ffd83dbSDimitry Andric uint64_t PaddingSize = AlignedOffset - CurrentOffset; 845ffd83dbSDimitry Andric if (!checkLimit(PaddingSize)) 855ffd83dbSDimitry Andric return CurrentOffset; 865ffd83dbSDimitry Andric 875ffd83dbSDimitry Andric writeZeros(PaddingSize); 885ffd83dbSDimitry Andric return AlignedOffset; 898bcb0991SDimitry Andric } 908bcb0991SDimitry Andric 915ffd83dbSDimitry Andric raw_ostream *getRawOS(uint64_t Size) { 925ffd83dbSDimitry Andric if (checkLimit(Size)) 935ffd83dbSDimitry Andric return &OS; 945ffd83dbSDimitry Andric return nullptr; 955ffd83dbSDimitry Andric } 965ffd83dbSDimitry Andric 975ffd83dbSDimitry Andric void writeAsBinary(const yaml::BinaryRef &Bin, uint64_t N = UINT64_MAX) { 985ffd83dbSDimitry Andric if (!checkLimit(Bin.binary_size())) 995ffd83dbSDimitry Andric return; 1005ffd83dbSDimitry Andric Bin.writeAsBinary(OS, N); 1015ffd83dbSDimitry Andric } 1025ffd83dbSDimitry Andric 1035ffd83dbSDimitry Andric void writeZeros(uint64_t Num) { 1045ffd83dbSDimitry Andric if (checkLimit(Num)) 1055ffd83dbSDimitry Andric OS.write_zeros(Num); 1065ffd83dbSDimitry Andric } 1075ffd83dbSDimitry Andric 1085ffd83dbSDimitry Andric void write(const char *Ptr, size_t Size) { 1095ffd83dbSDimitry Andric if (checkLimit(Size)) 1105ffd83dbSDimitry Andric OS.write(Ptr, Size); 1115ffd83dbSDimitry Andric } 1125ffd83dbSDimitry Andric 1135ffd83dbSDimitry Andric void write(unsigned char C) { 1145ffd83dbSDimitry Andric if (checkLimit(1)) 1155ffd83dbSDimitry Andric OS.write(C); 1165ffd83dbSDimitry Andric } 1175ffd83dbSDimitry Andric 1185ffd83dbSDimitry Andric unsigned writeULEB128(uint64_t Val) { 1195ffd83dbSDimitry Andric if (!checkLimit(sizeof(uint64_t))) 1205ffd83dbSDimitry Andric return 0; 1215ffd83dbSDimitry Andric return encodeULEB128(Val, OS); 1225ffd83dbSDimitry Andric } 1235ffd83dbSDimitry Andric 1245ffd83dbSDimitry Andric template <typename T> void write(T Val, support::endianness E) { 1255ffd83dbSDimitry Andric if (checkLimit(sizeof(T))) 1265ffd83dbSDimitry Andric support::endian::write<T>(OS, Val, E); 1275ffd83dbSDimitry Andric } 128e8d8bef9SDimitry Andric 129e8d8bef9SDimitry Andric void updateDataAt(uint64_t Pos, void *Data, size_t Size) { 130e8d8bef9SDimitry Andric assert(Pos >= InitialOffset && Pos + Size <= getOffset()); 131e8d8bef9SDimitry Andric memcpy(&Buf[Pos - InitialOffset], Data, Size); 132e8d8bef9SDimitry Andric } 1338bcb0991SDimitry Andric }; 1348bcb0991SDimitry Andric 1358bcb0991SDimitry Andric // Used to keep track of section and symbol names, so that in the YAML file 1368bcb0991SDimitry Andric // sections and symbols can be referenced by name instead of by index. 1378bcb0991SDimitry Andric class NameToIdxMap { 1388bcb0991SDimitry Andric StringMap<unsigned> Map; 1398bcb0991SDimitry Andric 1408bcb0991SDimitry Andric public: 1418bcb0991SDimitry Andric /// \Returns false if name is already present in the map. 1428bcb0991SDimitry Andric bool addName(StringRef Name, unsigned Ndx) { 1438bcb0991SDimitry Andric return Map.insert({Name, Ndx}).second; 1448bcb0991SDimitry Andric } 1458bcb0991SDimitry Andric /// \Returns false if name is not present in the map. 1468bcb0991SDimitry Andric bool lookup(StringRef Name, unsigned &Idx) const { 1478bcb0991SDimitry Andric auto I = Map.find(Name); 1488bcb0991SDimitry Andric if (I == Map.end()) 1498bcb0991SDimitry Andric return false; 1508bcb0991SDimitry Andric Idx = I->getValue(); 1518bcb0991SDimitry Andric return true; 1528bcb0991SDimitry Andric } 1538bcb0991SDimitry Andric /// Asserts if name is not present in the map. 1548bcb0991SDimitry Andric unsigned get(StringRef Name) const { 1558bcb0991SDimitry Andric unsigned Idx; 1568bcb0991SDimitry Andric if (lookup(Name, Idx)) 1578bcb0991SDimitry Andric return Idx; 1588bcb0991SDimitry Andric assert(false && "Expected section not found in index"); 1598bcb0991SDimitry Andric return 0; 1608bcb0991SDimitry Andric } 1618bcb0991SDimitry Andric unsigned size() const { return Map.size(); } 1628bcb0991SDimitry Andric }; 1638bcb0991SDimitry Andric 164480093f4SDimitry Andric namespace { 165480093f4SDimitry Andric struct Fragment { 166480093f4SDimitry Andric uint64_t Offset; 167480093f4SDimitry Andric uint64_t Size; 168480093f4SDimitry Andric uint32_t Type; 169480093f4SDimitry Andric uint64_t AddrAlign; 170480093f4SDimitry Andric }; 171480093f4SDimitry Andric } // namespace 172480093f4SDimitry Andric 1738bcb0991SDimitry Andric /// "Single point of truth" for the ELF file construction. 1748bcb0991SDimitry Andric /// TODO: This class still has a ways to go before it is truly a "single 1758bcb0991SDimitry Andric /// point of truth". 1768bcb0991SDimitry Andric template <class ELFT> class ELFState { 177e8d8bef9SDimitry Andric LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 1788bcb0991SDimitry Andric 1798bcb0991SDimitry Andric enum class SymtabType { Static, Dynamic }; 1808bcb0991SDimitry Andric 181fe6060f1SDimitry Andric /// The future symbol table string section. 1828bcb0991SDimitry Andric StringTableBuilder DotStrtab{StringTableBuilder::ELF}; 1838bcb0991SDimitry Andric 184fe6060f1SDimitry Andric /// The future section header string table section, if a unique string table 185fe6060f1SDimitry Andric /// is needed. Don't reference this variable direectly: use the 186fe6060f1SDimitry Andric /// ShStrtabStrings member instead. 1878bcb0991SDimitry Andric StringTableBuilder DotShStrtab{StringTableBuilder::ELF}; 1888bcb0991SDimitry Andric 189fe6060f1SDimitry Andric /// The future dynamic symbol string section. 1908bcb0991SDimitry Andric StringTableBuilder DotDynstr{StringTableBuilder::ELF}; 1918bcb0991SDimitry Andric 192fe6060f1SDimitry Andric /// The name of the section header string table section. If it is .strtab or 193fe6060f1SDimitry Andric /// .dynstr, the section header strings will be written to the same string 194fe6060f1SDimitry Andric /// table as the static/dynamic symbols respectively. Otherwise a dedicated 195fe6060f1SDimitry Andric /// section will be created with that name. 196fe6060f1SDimitry Andric StringRef SectionHeaderStringTableName = ".shstrtab"; 197fe6060f1SDimitry Andric StringTableBuilder *ShStrtabStrings = &DotShStrtab; 198fe6060f1SDimitry Andric 1998bcb0991SDimitry Andric NameToIdxMap SN2I; 2008bcb0991SDimitry Andric NameToIdxMap SymN2I; 2018bcb0991SDimitry Andric NameToIdxMap DynSymN2I; 2028bcb0991SDimitry Andric ELFYAML::Object &Doc; 2038bcb0991SDimitry Andric 2045ffd83dbSDimitry Andric StringSet<> ExcludedSectionHeaders; 2055ffd83dbSDimitry Andric 2065ffd83dbSDimitry Andric uint64_t LocationCounter = 0; 2078bcb0991SDimitry Andric bool HasError = false; 2088bcb0991SDimitry Andric yaml::ErrorHandler ErrHandler; 2098bcb0991SDimitry Andric void reportError(const Twine &Msg); 2105ffd83dbSDimitry Andric void reportError(Error Err); 2118bcb0991SDimitry Andric 2128bcb0991SDimitry Andric std::vector<Elf_Sym> toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols, 2138bcb0991SDimitry Andric const StringTableBuilder &Strtab); 2148bcb0991SDimitry Andric unsigned toSectionIndex(StringRef S, StringRef LocSec, StringRef LocSym = ""); 2158bcb0991SDimitry Andric unsigned toSymbolIndex(StringRef S, StringRef LocSec, bool IsDynamic); 2168bcb0991SDimitry Andric 2178bcb0991SDimitry Andric void buildSectionIndex(); 2188bcb0991SDimitry Andric void buildSymbolIndexes(); 2198bcb0991SDimitry Andric void initProgramHeaders(std::vector<Elf_Phdr> &PHeaders); 2208bcb0991SDimitry Andric bool initImplicitHeader(ContiguousBlobAccumulator &CBA, Elf_Shdr &Header, 2218bcb0991SDimitry Andric StringRef SecName, ELFYAML::Section *YAMLSec); 2228bcb0991SDimitry Andric void initSectionHeaders(std::vector<Elf_Shdr> &SHeaders, 2238bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2248bcb0991SDimitry Andric void initSymtabSectionHeader(Elf_Shdr &SHeader, SymtabType STType, 2258bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 2268bcb0991SDimitry Andric ELFYAML::Section *YAMLSec); 2278bcb0991SDimitry Andric void initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name, 2288bcb0991SDimitry Andric StringTableBuilder &STB, 2298bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 2308bcb0991SDimitry Andric ELFYAML::Section *YAMLSec); 2315ffd83dbSDimitry Andric void initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name, 2325ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA, 2335ffd83dbSDimitry Andric ELFYAML::Section *YAMLSec); 2348bcb0991SDimitry Andric void setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders, 2358bcb0991SDimitry Andric std::vector<Elf_Shdr> &SHeaders); 236480093f4SDimitry Andric 237480093f4SDimitry Andric std::vector<Fragment> 238480093f4SDimitry Andric getPhdrFragments(const ELFYAML::ProgramHeader &Phdr, 239480093f4SDimitry Andric ArrayRef<typename ELFT::Shdr> SHeaders); 240480093f4SDimitry Andric 2418bcb0991SDimitry Andric void finalizeStrings(); 242e8d8bef9SDimitry Andric void writeELFHeader(raw_ostream &OS); 2435ffd83dbSDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2445ffd83dbSDimitry Andric const ELFYAML::NoBitsSection &Section, 2455ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA); 2468bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2478bcb0991SDimitry Andric const ELFYAML::RawContentSection &Section, 2488bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2498bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2508bcb0991SDimitry Andric const ELFYAML::RelocationSection &Section, 2518bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 252480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 253480093f4SDimitry Andric const ELFYAML::RelrSection &Section, 254480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 255e8d8bef9SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 256e8d8bef9SDimitry Andric const ELFYAML::GroupSection &Group, 2578bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2588bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2598bcb0991SDimitry Andric const ELFYAML::SymtabShndxSection &Shndx, 2608bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2618bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2628bcb0991SDimitry Andric const ELFYAML::SymverSection &Section, 2638bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2648bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2658bcb0991SDimitry Andric const ELFYAML::VerneedSection &Section, 2668bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2678bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2688bcb0991SDimitry Andric const ELFYAML::VerdefSection &Section, 2698bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2708bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 271e8d8bef9SDimitry Andric const ELFYAML::ARMIndexTableSection &Section, 272e8d8bef9SDimitry Andric ContiguousBlobAccumulator &CBA); 273e8d8bef9SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2748bcb0991SDimitry Andric const ELFYAML::MipsABIFlags &Section, 2758bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2768bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2778bcb0991SDimitry Andric const ELFYAML::DynamicSection &Section, 2788bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2798bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2808bcb0991SDimitry Andric const ELFYAML::StackSizesSection &Section, 2818bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2828bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 283e8d8bef9SDimitry Andric const ELFYAML::BBAddrMapSection &Section, 284e8d8bef9SDimitry Andric ContiguousBlobAccumulator &CBA); 285e8d8bef9SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2868bcb0991SDimitry Andric const ELFYAML::HashSection &Section, 2878bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2888bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2898bcb0991SDimitry Andric const ELFYAML::AddrsigSection &Section, 2908bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 291480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 292480093f4SDimitry Andric const ELFYAML::NoteSection &Section, 293480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 294480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 295480093f4SDimitry Andric const ELFYAML::GnuHashSection &Section, 296480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 297480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 298480093f4SDimitry Andric const ELFYAML::LinkerOptionsSection &Section, 299480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 300480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 301480093f4SDimitry Andric const ELFYAML::DependentLibrariesSection &Section, 302480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 3035ffd83dbSDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 3045ffd83dbSDimitry Andric const ELFYAML::CallGraphProfileSection &Section, 3055ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA); 306480093f4SDimitry Andric 307480093f4SDimitry Andric void writeFill(ELFYAML::Fill &Fill, ContiguousBlobAccumulator &CBA); 3088bcb0991SDimitry Andric 3098bcb0991SDimitry Andric ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH); 3108bcb0991SDimitry Andric 3115ffd83dbSDimitry Andric void assignSectionAddress(Elf_Shdr &SHeader, ELFYAML::Section *YAMLSec); 3125ffd83dbSDimitry Andric 3135ffd83dbSDimitry Andric DenseMap<StringRef, size_t> buildSectionHeaderReorderMap(); 3145ffd83dbSDimitry Andric 3155ffd83dbSDimitry Andric BumpPtrAllocator StringAlloc; 3165ffd83dbSDimitry Andric uint64_t alignToOffset(ContiguousBlobAccumulator &CBA, uint64_t Align, 3175ffd83dbSDimitry Andric llvm::Optional<llvm::yaml::Hex64> Offset); 3185ffd83dbSDimitry Andric 3195ffd83dbSDimitry Andric uint64_t getSectionNameOffset(StringRef Name); 3205ffd83dbSDimitry Andric 3218bcb0991SDimitry Andric public: 3228bcb0991SDimitry Andric static bool writeELF(raw_ostream &OS, ELFYAML::Object &Doc, 3235ffd83dbSDimitry Andric yaml::ErrorHandler EH, uint64_t MaxSize); 3248bcb0991SDimitry Andric }; 3258bcb0991SDimitry Andric } // end anonymous namespace 3268bcb0991SDimitry Andric 3278bcb0991SDimitry Andric template <class T> static size_t arrayDataSize(ArrayRef<T> A) { 3288bcb0991SDimitry Andric return A.size() * sizeof(T); 3298bcb0991SDimitry Andric } 3308bcb0991SDimitry Andric 3318bcb0991SDimitry Andric template <class T> static void writeArrayData(raw_ostream &OS, ArrayRef<T> A) { 3328bcb0991SDimitry Andric OS.write((const char *)A.data(), arrayDataSize(A)); 3338bcb0991SDimitry Andric } 3348bcb0991SDimitry Andric 3358bcb0991SDimitry Andric template <class T> static void zero(T &Obj) { memset(&Obj, 0, sizeof(Obj)); } 3368bcb0991SDimitry Andric 3378bcb0991SDimitry Andric template <class ELFT> 3388bcb0991SDimitry Andric ELFState<ELFT>::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH) 3398bcb0991SDimitry Andric : Doc(D), ErrHandler(EH) { 340fe6060f1SDimitry Andric // The input may explicitly request to store the section header table strings 341fe6060f1SDimitry Andric // in the same string table as dynamic or static symbol names. Set the 342fe6060f1SDimitry Andric // ShStrtabStrings member accordingly. 343fe6060f1SDimitry Andric if (Doc.Header.SectionHeaderStringTable) { 344fe6060f1SDimitry Andric SectionHeaderStringTableName = *Doc.Header.SectionHeaderStringTable; 345fe6060f1SDimitry Andric if (*Doc.Header.SectionHeaderStringTable == ".strtab") 346fe6060f1SDimitry Andric ShStrtabStrings = &DotStrtab; 347fe6060f1SDimitry Andric else if (*Doc.Header.SectionHeaderStringTable == ".dynstr") 348fe6060f1SDimitry Andric ShStrtabStrings = &DotDynstr; 349fe6060f1SDimitry Andric // Otherwise, the unique table will be used. 350fe6060f1SDimitry Andric } 351fe6060f1SDimitry Andric 352480093f4SDimitry Andric std::vector<ELFYAML::Section *> Sections = Doc.getSections(); 3538bcb0991SDimitry Andric // Insert SHT_NULL section implicitly when it is not defined in YAML. 354480093f4SDimitry Andric if (Sections.empty() || Sections.front()->Type != ELF::SHT_NULL) 355480093f4SDimitry Andric Doc.Chunks.insert( 356480093f4SDimitry Andric Doc.Chunks.begin(), 3578bcb0991SDimitry Andric std::make_unique<ELFYAML::Section>( 358480093f4SDimitry Andric ELFYAML::Chunk::ChunkKind::RawContent, /*IsImplicit=*/true)); 3598bcb0991SDimitry Andric 3605ffd83dbSDimitry Andric StringSet<> DocSections; 361e8d8bef9SDimitry Andric ELFYAML::SectionHeaderTable *SecHdrTable = nullptr; 3625ffd83dbSDimitry Andric for (size_t I = 0; I < Doc.Chunks.size(); ++I) { 3635ffd83dbSDimitry Andric const std::unique_ptr<ELFYAML::Chunk> &C = Doc.Chunks[I]; 364e8d8bef9SDimitry Andric 365e8d8bef9SDimitry Andric // We might have an explicit section header table declaration. 366e8d8bef9SDimitry Andric if (auto S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get())) { 367e8d8bef9SDimitry Andric if (SecHdrTable) 368e8d8bef9SDimitry Andric reportError("multiple section header tables are not allowed"); 369e8d8bef9SDimitry Andric SecHdrTable = S; 370e8d8bef9SDimitry Andric continue; 371e8d8bef9SDimitry Andric } 372e8d8bef9SDimitry Andric 373e8d8bef9SDimitry Andric // We add a technical suffix for each unnamed section/fill. It does not 374e8d8bef9SDimitry Andric // affect the output, but allows us to map them by name in the code and 375e8d8bef9SDimitry Andric // report better error messages. 3765ffd83dbSDimitry Andric if (C->Name.empty()) { 3775ffd83dbSDimitry Andric std::string NewName = ELFYAML::appendUniqueSuffix( 3785ffd83dbSDimitry Andric /*Name=*/"", "index " + Twine(I)); 3795ffd83dbSDimitry Andric C->Name = StringRef(NewName).copy(StringAlloc); 3805ffd83dbSDimitry Andric assert(ELFYAML::dropUniqueSuffix(C->Name).empty()); 3815ffd83dbSDimitry Andric } 3828bcb0991SDimitry Andric 3835ffd83dbSDimitry Andric if (!DocSections.insert(C->Name).second) 3845ffd83dbSDimitry Andric reportError("repeated section/fill name: '" + C->Name + 3855ffd83dbSDimitry Andric "' at YAML section/fill number " + Twine(I)); 3865ffd83dbSDimitry Andric } 3875ffd83dbSDimitry Andric 388fe6060f1SDimitry Andric SmallSetVector<StringRef, 8> ImplicitSections; 389fe6060f1SDimitry Andric if (Doc.DynamicSymbols) { 390fe6060f1SDimitry Andric if (SectionHeaderStringTableName == ".dynsym") 391fe6060f1SDimitry Andric reportError("cannot use '.dynsym' as the section header name table when " 392fe6060f1SDimitry Andric "there are dynamic symbols"); 393fe6060f1SDimitry Andric ImplicitSections.insert(".dynsym"); 394fe6060f1SDimitry Andric ImplicitSections.insert(".dynstr"); 395fe6060f1SDimitry Andric } 396fe6060f1SDimitry Andric if (Doc.Symbols) { 397fe6060f1SDimitry Andric if (SectionHeaderStringTableName == ".symtab") 398fe6060f1SDimitry Andric reportError("cannot use '.symtab' as the section header name table when " 399fe6060f1SDimitry Andric "there are symbols"); 400fe6060f1SDimitry Andric ImplicitSections.insert(".symtab"); 401fe6060f1SDimitry Andric } 4025ffd83dbSDimitry Andric if (Doc.DWARF) 403e8d8bef9SDimitry Andric for (StringRef DebugSecName : Doc.DWARF->getNonEmptySectionNames()) { 4045ffd83dbSDimitry Andric std::string SecName = ("." + DebugSecName).str(); 405fe6060f1SDimitry Andric // TODO: For .debug_str it should be possible to share the string table, 406fe6060f1SDimitry Andric // in the same manner as the symbol string tables. 407fe6060f1SDimitry Andric if (SectionHeaderStringTableName == SecName) 408fe6060f1SDimitry Andric reportError("cannot use '" + SecName + 409fe6060f1SDimitry Andric "' as the section header name table when it is needed for " 410fe6060f1SDimitry Andric "DWARF output"); 411fe6060f1SDimitry Andric ImplicitSections.insert(StringRef(SecName).copy(StringAlloc)); 4125ffd83dbSDimitry Andric } 413fe6060f1SDimitry Andric // TODO: Only create the .strtab here if any symbols have been requested. 414fe6060f1SDimitry Andric ImplicitSections.insert(".strtab"); 415*81ad6265SDimitry Andric if (!SecHdrTable || !SecHdrTable->NoHeaders.value_or(false)) 416fe6060f1SDimitry Andric ImplicitSections.insert(SectionHeaderStringTableName); 4178bcb0991SDimitry Andric 4188bcb0991SDimitry Andric // Insert placeholders for implicit sections that are not 4198bcb0991SDimitry Andric // defined explicitly in YAML. 4208bcb0991SDimitry Andric for (StringRef SecName : ImplicitSections) { 4218bcb0991SDimitry Andric if (DocSections.count(SecName)) 4228bcb0991SDimitry Andric continue; 4238bcb0991SDimitry Andric 424e8d8bef9SDimitry Andric std::unique_ptr<ELFYAML::Section> Sec = std::make_unique<ELFYAML::Section>( 425480093f4SDimitry Andric ELFYAML::Chunk::ChunkKind::RawContent, true /*IsImplicit*/); 4268bcb0991SDimitry Andric Sec->Name = SecName; 427e8d8bef9SDimitry Andric 428fe6060f1SDimitry Andric if (SecName == SectionHeaderStringTableName) 429fe6060f1SDimitry Andric Sec->Type = ELF::SHT_STRTAB; 430fe6060f1SDimitry Andric else if (SecName == ".dynsym") 431e8d8bef9SDimitry Andric Sec->Type = ELF::SHT_DYNSYM; 432e8d8bef9SDimitry Andric else if (SecName == ".symtab") 433e8d8bef9SDimitry Andric Sec->Type = ELF::SHT_SYMTAB; 434e8d8bef9SDimitry Andric else 435e8d8bef9SDimitry Andric Sec->Type = ELF::SHT_STRTAB; 436e8d8bef9SDimitry Andric 437e8d8bef9SDimitry Andric // When the section header table is explicitly defined at the end of the 438e8d8bef9SDimitry Andric // sections list, it is reasonable to assume that the user wants to reorder 439e8d8bef9SDimitry Andric // section headers, but still wants to place the section header table after 440e8d8bef9SDimitry Andric // all sections, like it normally happens. In this case we want to insert 441e8d8bef9SDimitry Andric // other implicit sections right before the section header table. 442e8d8bef9SDimitry Andric if (Doc.Chunks.back().get() == SecHdrTable) 443e8d8bef9SDimitry Andric Doc.Chunks.insert(Doc.Chunks.end() - 1, std::move(Sec)); 444e8d8bef9SDimitry Andric else 445480093f4SDimitry Andric Doc.Chunks.push_back(std::move(Sec)); 4468bcb0991SDimitry Andric } 447e8d8bef9SDimitry Andric 448e8d8bef9SDimitry Andric // Insert the section header table implicitly at the end, when it is not 449e8d8bef9SDimitry Andric // explicitly defined. 450e8d8bef9SDimitry Andric if (!SecHdrTable) 451e8d8bef9SDimitry Andric Doc.Chunks.push_back( 452e8d8bef9SDimitry Andric std::make_unique<ELFYAML::SectionHeaderTable>(/*IsImplicit=*/true)); 4538bcb0991SDimitry Andric } 4548bcb0991SDimitry Andric 4558bcb0991SDimitry Andric template <class ELFT> 456e8d8bef9SDimitry Andric void ELFState<ELFT>::writeELFHeader(raw_ostream &OS) { 4578bcb0991SDimitry Andric using namespace llvm::ELF; 4588bcb0991SDimitry Andric 4598bcb0991SDimitry Andric Elf_Ehdr Header; 4608bcb0991SDimitry Andric zero(Header); 4618bcb0991SDimitry Andric Header.e_ident[EI_MAG0] = 0x7f; 4628bcb0991SDimitry Andric Header.e_ident[EI_MAG1] = 'E'; 4638bcb0991SDimitry Andric Header.e_ident[EI_MAG2] = 'L'; 4648bcb0991SDimitry Andric Header.e_ident[EI_MAG3] = 'F'; 4658bcb0991SDimitry Andric Header.e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32; 4668bcb0991SDimitry Andric Header.e_ident[EI_DATA] = Doc.Header.Data; 4678bcb0991SDimitry Andric Header.e_ident[EI_VERSION] = EV_CURRENT; 4688bcb0991SDimitry Andric Header.e_ident[EI_OSABI] = Doc.Header.OSABI; 4698bcb0991SDimitry Andric Header.e_ident[EI_ABIVERSION] = Doc.Header.ABIVersion; 4708bcb0991SDimitry Andric Header.e_type = Doc.Header.Type; 471e8d8bef9SDimitry Andric 472e8d8bef9SDimitry Andric if (Doc.Header.Machine) 473e8d8bef9SDimitry Andric Header.e_machine = *Doc.Header.Machine; 474e8d8bef9SDimitry Andric else 475e8d8bef9SDimitry Andric Header.e_machine = EM_NONE; 476e8d8bef9SDimitry Andric 4778bcb0991SDimitry Andric Header.e_version = EV_CURRENT; 4788bcb0991SDimitry Andric Header.e_entry = Doc.Header.Entry; 4798bcb0991SDimitry Andric Header.e_flags = Doc.Header.Flags; 4808bcb0991SDimitry Andric Header.e_ehsize = sizeof(Elf_Ehdr); 4818bcb0991SDimitry Andric 4825ffd83dbSDimitry Andric if (Doc.Header.EPhOff) 4835ffd83dbSDimitry Andric Header.e_phoff = *Doc.Header.EPhOff; 4845ffd83dbSDimitry Andric else if (!Doc.ProgramHeaders.empty()) 4855ffd83dbSDimitry Andric Header.e_phoff = sizeof(Header); 4865ffd83dbSDimitry Andric else 4875ffd83dbSDimitry Andric Header.e_phoff = 0; 4885ffd83dbSDimitry Andric 4895ffd83dbSDimitry Andric if (Doc.Header.EPhEntSize) 4905ffd83dbSDimitry Andric Header.e_phentsize = *Doc.Header.EPhEntSize; 4915ffd83dbSDimitry Andric else if (!Doc.ProgramHeaders.empty()) 4925ffd83dbSDimitry Andric Header.e_phentsize = sizeof(Elf_Phdr); 4935ffd83dbSDimitry Andric else 4945ffd83dbSDimitry Andric Header.e_phentsize = 0; 4955ffd83dbSDimitry Andric 4965ffd83dbSDimitry Andric if (Doc.Header.EPhNum) 4975ffd83dbSDimitry Andric Header.e_phnum = *Doc.Header.EPhNum; 4985ffd83dbSDimitry Andric else if (!Doc.ProgramHeaders.empty()) 4995ffd83dbSDimitry Andric Header.e_phnum = Doc.ProgramHeaders.size(); 5005ffd83dbSDimitry Andric else 5015ffd83dbSDimitry Andric Header.e_phnum = 0; 5025ffd83dbSDimitry Andric 5035ffd83dbSDimitry Andric Header.e_shentsize = Doc.Header.EShEntSize ? (uint16_t)*Doc.Header.EShEntSize 5045ffd83dbSDimitry Andric : sizeof(Elf_Shdr); 5055ffd83dbSDimitry Andric 506e8d8bef9SDimitry Andric const ELFYAML::SectionHeaderTable &SectionHeaders = 507e8d8bef9SDimitry Andric Doc.getSectionHeaderTable(); 5085ffd83dbSDimitry Andric 5095ffd83dbSDimitry Andric if (Doc.Header.EShOff) 5105ffd83dbSDimitry Andric Header.e_shoff = *Doc.Header.EShOff; 511e8d8bef9SDimitry Andric else if (SectionHeaders.Offset) 512e8d8bef9SDimitry Andric Header.e_shoff = *SectionHeaders.Offset; 5135ffd83dbSDimitry Andric else 514e8d8bef9SDimitry Andric Header.e_shoff = 0; 5155ffd83dbSDimitry Andric 5165ffd83dbSDimitry Andric if (Doc.Header.EShNum) 5175ffd83dbSDimitry Andric Header.e_shnum = *Doc.Header.EShNum; 5185ffd83dbSDimitry Andric else 519e8d8bef9SDimitry Andric Header.e_shnum = SectionHeaders.getNumHeaders(Doc.getSections().size()); 5205ffd83dbSDimitry Andric 5215ffd83dbSDimitry Andric if (Doc.Header.EShStrNdx) 5225ffd83dbSDimitry Andric Header.e_shstrndx = *Doc.Header.EShStrNdx; 523fe6060f1SDimitry Andric else if (SectionHeaders.Offset && 524fe6060f1SDimitry Andric !ExcludedSectionHeaders.count(SectionHeaderStringTableName)) 525fe6060f1SDimitry Andric Header.e_shstrndx = SN2I.get(SectionHeaderStringTableName); 526e8d8bef9SDimitry Andric else 527e8d8bef9SDimitry Andric Header.e_shstrndx = 0; 5288bcb0991SDimitry Andric 5298bcb0991SDimitry Andric OS.write((const char *)&Header, sizeof(Header)); 5308bcb0991SDimitry Andric } 5318bcb0991SDimitry Andric 5328bcb0991SDimitry Andric template <class ELFT> 5338bcb0991SDimitry Andric void ELFState<ELFT>::initProgramHeaders(std::vector<Elf_Phdr> &PHeaders) { 5345ffd83dbSDimitry Andric DenseMap<StringRef, ELFYAML::Fill *> NameToFill; 535e8d8bef9SDimitry Andric DenseMap<StringRef, size_t> NameToIndex; 536e8d8bef9SDimitry Andric for (size_t I = 0, E = Doc.Chunks.size(); I != E; ++I) { 537e8d8bef9SDimitry Andric if (auto S = dyn_cast<ELFYAML::Fill>(Doc.Chunks[I].get())) 5385ffd83dbSDimitry Andric NameToFill[S->Name] = S; 539e8d8bef9SDimitry Andric NameToIndex[Doc.Chunks[I]->Name] = I + 1; 540e8d8bef9SDimitry Andric } 5415ffd83dbSDimitry Andric 5425ffd83dbSDimitry Andric std::vector<ELFYAML::Section *> Sections = Doc.getSections(); 543e8d8bef9SDimitry Andric for (size_t I = 0, E = Doc.ProgramHeaders.size(); I != E; ++I) { 544e8d8bef9SDimitry Andric ELFYAML::ProgramHeader &YamlPhdr = Doc.ProgramHeaders[I]; 5458bcb0991SDimitry Andric Elf_Phdr Phdr; 5465ffd83dbSDimitry Andric zero(Phdr); 5478bcb0991SDimitry Andric Phdr.p_type = YamlPhdr.Type; 5488bcb0991SDimitry Andric Phdr.p_flags = YamlPhdr.Flags; 5498bcb0991SDimitry Andric Phdr.p_vaddr = YamlPhdr.VAddr; 5508bcb0991SDimitry Andric Phdr.p_paddr = YamlPhdr.PAddr; 5518bcb0991SDimitry Andric PHeaders.push_back(Phdr); 5525ffd83dbSDimitry Andric 553e8d8bef9SDimitry Andric if (!YamlPhdr.FirstSec && !YamlPhdr.LastSec) 5545ffd83dbSDimitry Andric continue; 5555ffd83dbSDimitry Andric 556e8d8bef9SDimitry Andric // Get the index of the section, or 0 in the case when the section doesn't exist. 557e8d8bef9SDimitry Andric size_t First = NameToIndex[*YamlPhdr.FirstSec]; 558e8d8bef9SDimitry Andric if (!First) 559e8d8bef9SDimitry Andric reportError("unknown section or fill referenced: '" + *YamlPhdr.FirstSec + 560e8d8bef9SDimitry Andric "' by the 'FirstSec' key of the program header with index " + 561e8d8bef9SDimitry Andric Twine(I)); 562e8d8bef9SDimitry Andric size_t Last = NameToIndex[*YamlPhdr.LastSec]; 563e8d8bef9SDimitry Andric if (!Last) 564e8d8bef9SDimitry Andric reportError("unknown section or fill referenced: '" + *YamlPhdr.LastSec + 565e8d8bef9SDimitry Andric "' by the 'LastSec' key of the program header with index " + 566e8d8bef9SDimitry Andric Twine(I)); 567e8d8bef9SDimitry Andric if (!First || !Last) 5685ffd83dbSDimitry Andric continue; 5695ffd83dbSDimitry Andric 570e8d8bef9SDimitry Andric if (First > Last) 571e8d8bef9SDimitry Andric reportError("program header with index " + Twine(I) + 572e8d8bef9SDimitry Andric ": the section index of " + *YamlPhdr.FirstSec + 573e8d8bef9SDimitry Andric " is greater than the index of " + *YamlPhdr.LastSec); 574e8d8bef9SDimitry Andric 575e8d8bef9SDimitry Andric for (size_t I = First; I <= Last; ++I) 576e8d8bef9SDimitry Andric YamlPhdr.Chunks.push_back(Doc.Chunks[I - 1].get()); 5778bcb0991SDimitry Andric } 5788bcb0991SDimitry Andric } 5798bcb0991SDimitry Andric 5808bcb0991SDimitry Andric template <class ELFT> 5818bcb0991SDimitry Andric unsigned ELFState<ELFT>::toSectionIndex(StringRef S, StringRef LocSec, 5828bcb0991SDimitry Andric StringRef LocSym) { 5838bcb0991SDimitry Andric assert(LocSec.empty() || LocSym.empty()); 5845ffd83dbSDimitry Andric 5855ffd83dbSDimitry Andric unsigned Index; 5865ffd83dbSDimitry Andric if (!SN2I.lookup(S, Index) && !to_integer(S, Index)) { 5878bcb0991SDimitry Andric if (!LocSym.empty()) 5888bcb0991SDimitry Andric reportError("unknown section referenced: '" + S + "' by YAML symbol '" + 5898bcb0991SDimitry Andric LocSym + "'"); 5908bcb0991SDimitry Andric else 5918bcb0991SDimitry Andric reportError("unknown section referenced: '" + S + "' by YAML section '" + 5928bcb0991SDimitry Andric LocSec + "'"); 5938bcb0991SDimitry Andric return 0; 5948bcb0991SDimitry Andric } 5958bcb0991SDimitry Andric 596e8d8bef9SDimitry Andric const ELFYAML::SectionHeaderTable &SectionHeaders = 597e8d8bef9SDimitry Andric Doc.getSectionHeaderTable(); 598e8d8bef9SDimitry Andric if (SectionHeaders.IsImplicit || 599*81ad6265SDimitry Andric (SectionHeaders.NoHeaders && !*SectionHeaders.NoHeaders) || 600fe6060f1SDimitry Andric SectionHeaders.isDefault()) 6015ffd83dbSDimitry Andric return Index; 6025ffd83dbSDimitry Andric 603*81ad6265SDimitry Andric assert(!SectionHeaders.NoHeaders.value_or(false) || !SectionHeaders.Sections); 6045ffd83dbSDimitry Andric size_t FirstExcluded = 605e8d8bef9SDimitry Andric SectionHeaders.Sections ? SectionHeaders.Sections->size() : 0; 606fe6060f1SDimitry Andric if (Index > FirstExcluded) { 6075ffd83dbSDimitry Andric if (LocSym.empty()) 6085ffd83dbSDimitry Andric reportError("unable to link '" + LocSec + "' to excluded section '" + S + 6095ffd83dbSDimitry Andric "'"); 6105ffd83dbSDimitry Andric else 6115ffd83dbSDimitry Andric reportError("excluded section referenced: '" + S + "' by symbol '" + 6125ffd83dbSDimitry Andric LocSym + "'"); 6135ffd83dbSDimitry Andric } 6145ffd83dbSDimitry Andric return Index; 6155ffd83dbSDimitry Andric } 6165ffd83dbSDimitry Andric 6178bcb0991SDimitry Andric template <class ELFT> 6188bcb0991SDimitry Andric unsigned ELFState<ELFT>::toSymbolIndex(StringRef S, StringRef LocSec, 6198bcb0991SDimitry Andric bool IsDynamic) { 6208bcb0991SDimitry Andric const NameToIdxMap &SymMap = IsDynamic ? DynSymN2I : SymN2I; 6218bcb0991SDimitry Andric unsigned Index; 6228bcb0991SDimitry Andric // Here we try to look up S in the symbol table. If it is not there, 6238bcb0991SDimitry Andric // treat its value as a symbol index. 6248bcb0991SDimitry Andric if (!SymMap.lookup(S, Index) && !to_integer(S, Index)) { 6258bcb0991SDimitry Andric reportError("unknown symbol referenced: '" + S + "' by YAML section '" + 6268bcb0991SDimitry Andric LocSec + "'"); 6278bcb0991SDimitry Andric return 0; 6288bcb0991SDimitry Andric } 6298bcb0991SDimitry Andric return Index; 6308bcb0991SDimitry Andric } 6318bcb0991SDimitry Andric 6328bcb0991SDimitry Andric template <class ELFT> 633480093f4SDimitry Andric static void overrideFields(ELFYAML::Section *From, typename ELFT::Shdr &To) { 634480093f4SDimitry Andric if (!From) 635480093f4SDimitry Andric return; 636e8d8bef9SDimitry Andric if (From->ShAddrAlign) 637e8d8bef9SDimitry Andric To.sh_addralign = *From->ShAddrAlign; 638480093f4SDimitry Andric if (From->ShFlags) 639480093f4SDimitry Andric To.sh_flags = *From->ShFlags; 640480093f4SDimitry Andric if (From->ShName) 641480093f4SDimitry Andric To.sh_name = *From->ShName; 642480093f4SDimitry Andric if (From->ShOffset) 643480093f4SDimitry Andric To.sh_offset = *From->ShOffset; 644480093f4SDimitry Andric if (From->ShSize) 645480093f4SDimitry Andric To.sh_size = *From->ShSize; 646e8d8bef9SDimitry Andric if (From->ShType) 647e8d8bef9SDimitry Andric To.sh_type = *From->ShType; 648480093f4SDimitry Andric } 649480093f4SDimitry Andric 650480093f4SDimitry Andric template <class ELFT> 6518bcb0991SDimitry Andric bool ELFState<ELFT>::initImplicitHeader(ContiguousBlobAccumulator &CBA, 6528bcb0991SDimitry Andric Elf_Shdr &Header, StringRef SecName, 6538bcb0991SDimitry Andric ELFYAML::Section *YAMLSec) { 6548bcb0991SDimitry Andric // Check if the header was already initialized. 6558bcb0991SDimitry Andric if (Header.sh_offset) 6568bcb0991SDimitry Andric return false; 6578bcb0991SDimitry Andric 658fe6060f1SDimitry Andric if (SecName == ".strtab") 6598bcb0991SDimitry Andric initStrtabSectionHeader(Header, SecName, DotStrtab, CBA, YAMLSec); 6608bcb0991SDimitry Andric else if (SecName == ".dynstr") 6618bcb0991SDimitry Andric initStrtabSectionHeader(Header, SecName, DotDynstr, CBA, YAMLSec); 662fe6060f1SDimitry Andric else if (SecName == SectionHeaderStringTableName) 663fe6060f1SDimitry Andric initStrtabSectionHeader(Header, SecName, *ShStrtabStrings, CBA, YAMLSec); 664fe6060f1SDimitry Andric else if (SecName == ".symtab") 665fe6060f1SDimitry Andric initSymtabSectionHeader(Header, SymtabType::Static, CBA, YAMLSec); 666fe6060f1SDimitry Andric else if (SecName == ".dynsym") 667fe6060f1SDimitry Andric initSymtabSectionHeader(Header, SymtabType::Dynamic, CBA, YAMLSec); 6685ffd83dbSDimitry Andric else if (SecName.startswith(".debug_")) { 6695ffd83dbSDimitry Andric // If a ".debug_*" section's type is a preserved one, e.g., SHT_DYNAMIC, we 6705ffd83dbSDimitry Andric // will not treat it as a debug section. 6715ffd83dbSDimitry Andric if (YAMLSec && !isa<ELFYAML::RawContentSection>(YAMLSec)) 6728bcb0991SDimitry Andric return false; 6735ffd83dbSDimitry Andric initDWARFSectionHeader(Header, SecName, CBA, YAMLSec); 6745ffd83dbSDimitry Andric } else 6755ffd83dbSDimitry Andric return false; 6765ffd83dbSDimitry Andric 6775ffd83dbSDimitry Andric LocationCounter += Header.sh_size; 6788bcb0991SDimitry Andric 679480093f4SDimitry Andric // Override section fields if requested. 680480093f4SDimitry Andric overrideFields<ELFT>(YAMLSec, Header); 6818bcb0991SDimitry Andric return true; 6828bcb0991SDimitry Andric } 6838bcb0991SDimitry Andric 6845ffd83dbSDimitry Andric constexpr char SuffixStart = '('; 6855ffd83dbSDimitry Andric constexpr char SuffixEnd = ')'; 6865ffd83dbSDimitry Andric 6875ffd83dbSDimitry Andric std::string llvm::ELFYAML::appendUniqueSuffix(StringRef Name, 6885ffd83dbSDimitry Andric const Twine &Msg) { 6895ffd83dbSDimitry Andric // Do not add a space when a Name is empty. 6905ffd83dbSDimitry Andric std::string Ret = Name.empty() ? "" : Name.str() + ' '; 6915ffd83dbSDimitry Andric return Ret + (Twine(SuffixStart) + Msg + Twine(SuffixEnd)).str(); 6925ffd83dbSDimitry Andric } 6935ffd83dbSDimitry Andric 6948bcb0991SDimitry Andric StringRef llvm::ELFYAML::dropUniqueSuffix(StringRef S) { 6955ffd83dbSDimitry Andric if (S.empty() || S.back() != SuffixEnd) 6968bcb0991SDimitry Andric return S; 6975ffd83dbSDimitry Andric 6985ffd83dbSDimitry Andric // A special case for empty names. See appendUniqueSuffix() above. 6995ffd83dbSDimitry Andric size_t SuffixPos = S.rfind(SuffixStart); 7005ffd83dbSDimitry Andric if (SuffixPos == 0) 7015ffd83dbSDimitry Andric return ""; 7025ffd83dbSDimitry Andric 7035ffd83dbSDimitry Andric if (SuffixPos == StringRef::npos || S[SuffixPos - 1] != ' ') 7045ffd83dbSDimitry Andric return S; 7055ffd83dbSDimitry Andric return S.substr(0, SuffixPos - 1); 7065ffd83dbSDimitry Andric } 7075ffd83dbSDimitry Andric 7085ffd83dbSDimitry Andric template <class ELFT> 7095ffd83dbSDimitry Andric uint64_t ELFState<ELFT>::getSectionNameOffset(StringRef Name) { 7105ffd83dbSDimitry Andric // If a section is excluded from section headers, we do not save its name in 7115ffd83dbSDimitry Andric // the string table. 7125ffd83dbSDimitry Andric if (ExcludedSectionHeaders.count(Name)) 7135ffd83dbSDimitry Andric return 0; 714fe6060f1SDimitry Andric return ShStrtabStrings->getOffset(Name); 7158bcb0991SDimitry Andric } 7168bcb0991SDimitry Andric 717e8d8bef9SDimitry Andric static uint64_t writeContent(ContiguousBlobAccumulator &CBA, 718e8d8bef9SDimitry Andric const Optional<yaml::BinaryRef> &Content, 719e8d8bef9SDimitry Andric const Optional<llvm::yaml::Hex64> &Size) { 720e8d8bef9SDimitry Andric size_t ContentSize = 0; 721e8d8bef9SDimitry Andric if (Content) { 722e8d8bef9SDimitry Andric CBA.writeAsBinary(*Content); 723e8d8bef9SDimitry Andric ContentSize = Content->binary_size(); 724e8d8bef9SDimitry Andric } 725e8d8bef9SDimitry Andric 726e8d8bef9SDimitry Andric if (!Size) 727e8d8bef9SDimitry Andric return ContentSize; 728e8d8bef9SDimitry Andric 729e8d8bef9SDimitry Andric CBA.writeZeros(*Size - ContentSize); 730e8d8bef9SDimitry Andric return *Size; 731e8d8bef9SDimitry Andric } 732e8d8bef9SDimitry Andric 733e8d8bef9SDimitry Andric static StringRef getDefaultLinkSec(unsigned SecType) { 734e8d8bef9SDimitry Andric switch (SecType) { 735e8d8bef9SDimitry Andric case ELF::SHT_REL: 736e8d8bef9SDimitry Andric case ELF::SHT_RELA: 737e8d8bef9SDimitry Andric case ELF::SHT_GROUP: 738e8d8bef9SDimitry Andric case ELF::SHT_LLVM_CALL_GRAPH_PROFILE: 739e8d8bef9SDimitry Andric case ELF::SHT_LLVM_ADDRSIG: 740e8d8bef9SDimitry Andric return ".symtab"; 741e8d8bef9SDimitry Andric case ELF::SHT_GNU_versym: 742e8d8bef9SDimitry Andric case ELF::SHT_HASH: 743e8d8bef9SDimitry Andric case ELF::SHT_GNU_HASH: 744e8d8bef9SDimitry Andric return ".dynsym"; 745e8d8bef9SDimitry Andric case ELF::SHT_DYNSYM: 746e8d8bef9SDimitry Andric case ELF::SHT_GNU_verdef: 747e8d8bef9SDimitry Andric case ELF::SHT_GNU_verneed: 748e8d8bef9SDimitry Andric return ".dynstr"; 749e8d8bef9SDimitry Andric case ELF::SHT_SYMTAB: 750e8d8bef9SDimitry Andric return ".strtab"; 751e8d8bef9SDimitry Andric default: 752e8d8bef9SDimitry Andric return ""; 753e8d8bef9SDimitry Andric } 754e8d8bef9SDimitry Andric } 755e8d8bef9SDimitry Andric 7568bcb0991SDimitry Andric template <class ELFT> 7578bcb0991SDimitry Andric void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders, 7588bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 7598bcb0991SDimitry Andric // Ensure SHN_UNDEF entry is present. An all-zero section header is a 7608bcb0991SDimitry Andric // valid SHN_UNDEF entry since SHT_NULL == 0. 761480093f4SDimitry Andric SHeaders.resize(Doc.getSections().size()); 7628bcb0991SDimitry Andric 763480093f4SDimitry Andric for (const std::unique_ptr<ELFYAML::Chunk> &D : Doc.Chunks) { 7645ffd83dbSDimitry Andric if (ELFYAML::Fill *S = dyn_cast<ELFYAML::Fill>(D.get())) { 7655ffd83dbSDimitry Andric S->Offset = alignToOffset(CBA, /*Align=*/1, S->Offset); 766480093f4SDimitry Andric writeFill(*S, CBA); 7675ffd83dbSDimitry Andric LocationCounter += S->Size; 768480093f4SDimitry Andric continue; 769480093f4SDimitry Andric } 770480093f4SDimitry Andric 771e8d8bef9SDimitry Andric if (ELFYAML::SectionHeaderTable *S = 772e8d8bef9SDimitry Andric dyn_cast<ELFYAML::SectionHeaderTable>(D.get())) { 773*81ad6265SDimitry Andric if (S->NoHeaders.value_or(false)) 774e8d8bef9SDimitry Andric continue; 775e8d8bef9SDimitry Andric 776e8d8bef9SDimitry Andric if (!S->Offset) 777e8d8bef9SDimitry Andric S->Offset = alignToOffset(CBA, sizeof(typename ELFT::uint), 778e8d8bef9SDimitry Andric /*Offset=*/None); 779e8d8bef9SDimitry Andric else 780e8d8bef9SDimitry Andric S->Offset = alignToOffset(CBA, /*Align=*/1, S->Offset); 781e8d8bef9SDimitry Andric 782e8d8bef9SDimitry Andric uint64_t Size = S->getNumHeaders(SHeaders.size()) * sizeof(Elf_Shdr); 783e8d8bef9SDimitry Andric // The full section header information might be not available here, so 784e8d8bef9SDimitry Andric // fill the space with zeroes as a placeholder. 785e8d8bef9SDimitry Andric CBA.writeZeros(Size); 786e8d8bef9SDimitry Andric LocationCounter += Size; 787e8d8bef9SDimitry Andric continue; 788e8d8bef9SDimitry Andric } 789e8d8bef9SDimitry Andric 790480093f4SDimitry Andric ELFYAML::Section *Sec = cast<ELFYAML::Section>(D.get()); 791e8d8bef9SDimitry Andric bool IsFirstUndefSection = Sec == Doc.getSections().front(); 7925ffd83dbSDimitry Andric if (IsFirstUndefSection && Sec->IsImplicit) 7938bcb0991SDimitry Andric continue; 7948bcb0991SDimitry Andric 795e8d8bef9SDimitry Andric Elf_Shdr &SHeader = SHeaders[SN2I.get(Sec->Name)]; 796e8d8bef9SDimitry Andric if (Sec->Link) { 797e8d8bef9SDimitry Andric SHeader.sh_link = toSectionIndex(*Sec->Link, Sec->Name); 798e8d8bef9SDimitry Andric } else { 799e8d8bef9SDimitry Andric StringRef LinkSec = getDefaultLinkSec(Sec->Type); 800e8d8bef9SDimitry Andric unsigned Link = 0; 801e8d8bef9SDimitry Andric if (!LinkSec.empty() && !ExcludedSectionHeaders.count(LinkSec) && 802e8d8bef9SDimitry Andric SN2I.lookup(LinkSec, Link)) 803e8d8bef9SDimitry Andric SHeader.sh_link = Link; 804e8d8bef9SDimitry Andric } 805e8d8bef9SDimitry Andric 806e8d8bef9SDimitry Andric if (Sec->EntSize) 807e8d8bef9SDimitry Andric SHeader.sh_entsize = *Sec->EntSize; 808e8d8bef9SDimitry Andric else 809e8d8bef9SDimitry Andric SHeader.sh_entsize = ELFYAML::getDefaultShEntSize<ELFT>( 810*81ad6265SDimitry Andric Doc.Header.Machine.value_or(ELF::EM_NONE), Sec->Type, Sec->Name); 811e8d8bef9SDimitry Andric 8128bcb0991SDimitry Andric // We have a few sections like string or symbol tables that are usually 8138bcb0991SDimitry Andric // added implicitly to the end. However, if they are explicitly specified 8148bcb0991SDimitry Andric // in the YAML, we need to write them here. This ensures the file offset 8158bcb0991SDimitry Andric // remains correct. 8168bcb0991SDimitry Andric if (initImplicitHeader(CBA, SHeader, Sec->Name, 8178bcb0991SDimitry Andric Sec->IsImplicit ? nullptr : Sec)) 8188bcb0991SDimitry Andric continue; 8198bcb0991SDimitry Andric 8208bcb0991SDimitry Andric assert(Sec && "It can't be null unless it is an implicit section. But all " 8218bcb0991SDimitry Andric "implicit sections should already have been handled above."); 8228bcb0991SDimitry Andric 8238bcb0991SDimitry Andric SHeader.sh_name = 8245ffd83dbSDimitry Andric getSectionNameOffset(ELFYAML::dropUniqueSuffix(Sec->Name)); 8258bcb0991SDimitry Andric SHeader.sh_type = Sec->Type; 8268bcb0991SDimitry Andric if (Sec->Flags) 8278bcb0991SDimitry Andric SHeader.sh_flags = *Sec->Flags; 8288bcb0991SDimitry Andric SHeader.sh_addralign = Sec->AddressAlign; 8298bcb0991SDimitry Andric 8305ffd83dbSDimitry Andric // Set the offset for all sections, except the SHN_UNDEF section with index 8315ffd83dbSDimitry Andric // 0 when not explicitly requested. 8325ffd83dbSDimitry Andric if (!IsFirstUndefSection || Sec->Offset) 8335ffd83dbSDimitry Andric SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign, Sec->Offset); 8345ffd83dbSDimitry Andric 8355ffd83dbSDimitry Andric assignSectionAddress(SHeader, Sec); 8365ffd83dbSDimitry Andric 8375ffd83dbSDimitry Andric if (IsFirstUndefSection) { 8388bcb0991SDimitry Andric if (auto RawSec = dyn_cast<ELFYAML::RawContentSection>(Sec)) { 8398bcb0991SDimitry Andric // We do not write any content for special SHN_UNDEF section. 8408bcb0991SDimitry Andric if (RawSec->Size) 8418bcb0991SDimitry Andric SHeader.sh_size = *RawSec->Size; 8428bcb0991SDimitry Andric if (RawSec->Info) 8438bcb0991SDimitry Andric SHeader.sh_info = *RawSec->Info; 8448bcb0991SDimitry Andric } 845e8d8bef9SDimitry Andric 846e8d8bef9SDimitry Andric LocationCounter += SHeader.sh_size; 847e8d8bef9SDimitry Andric overrideFields<ELFT>(Sec, SHeader); 848e8d8bef9SDimitry Andric continue; 849e8d8bef9SDimitry Andric } 850e8d8bef9SDimitry Andric 851e8d8bef9SDimitry Andric if (!isa<ELFYAML::NoBitsSection>(Sec) && (Sec->Content || Sec->Size)) 852e8d8bef9SDimitry Andric SHeader.sh_size = writeContent(CBA, Sec->Content, Sec->Size); 853e8d8bef9SDimitry Andric 854e8d8bef9SDimitry Andric if (auto S = dyn_cast<ELFYAML::RawContentSection>(Sec)) { 8558bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8568bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::SymtabShndxSection>(Sec)) { 8578bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8588bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::RelocationSection>(Sec)) { 8598bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 860480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::RelrSection>(Sec)) { 861480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 862e8d8bef9SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::GroupSection>(Sec)) { 863e8d8bef9SDimitry Andric writeSectionContent(SHeader, *S, CBA); 864e8d8bef9SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::ARMIndexTableSection>(Sec)) { 8658bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8668bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::MipsABIFlags>(Sec)) { 8678bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8688bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::NoBitsSection>(Sec)) { 8695ffd83dbSDimitry Andric writeSectionContent(SHeader, *S, CBA); 8708bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::DynamicSection>(Sec)) { 8718bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8728bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::SymverSection>(Sec)) { 8738bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8748bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::VerneedSection>(Sec)) { 8758bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8768bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::VerdefSection>(Sec)) { 8778bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8788bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::StackSizesSection>(Sec)) { 8798bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8808bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::HashSection>(Sec)) { 8818bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8828bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::AddrsigSection>(Sec)) { 8838bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 884480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::LinkerOptionsSection>(Sec)) { 885480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 886480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::NoteSection>(Sec)) { 887480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 888480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::GnuHashSection>(Sec)) { 889480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 890480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::DependentLibrariesSection>(Sec)) { 891480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8925ffd83dbSDimitry Andric } else if (auto S = dyn_cast<ELFYAML::CallGraphProfileSection>(Sec)) { 8935ffd83dbSDimitry Andric writeSectionContent(SHeader, *S, CBA); 894e8d8bef9SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::BBAddrMapSection>(Sec)) { 895e8d8bef9SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8968bcb0991SDimitry Andric } else { 8978bcb0991SDimitry Andric llvm_unreachable("Unknown section type"); 8988bcb0991SDimitry Andric } 8998bcb0991SDimitry Andric 9005ffd83dbSDimitry Andric LocationCounter += SHeader.sh_size; 9015ffd83dbSDimitry Andric 902480093f4SDimitry Andric // Override section fields if requested. 903480093f4SDimitry Andric overrideFields<ELFT>(Sec, SHeader); 9048bcb0991SDimitry Andric } 9058bcb0991SDimitry Andric } 9068bcb0991SDimitry Andric 9075ffd83dbSDimitry Andric template <class ELFT> 9085ffd83dbSDimitry Andric void ELFState<ELFT>::assignSectionAddress(Elf_Shdr &SHeader, 9095ffd83dbSDimitry Andric ELFYAML::Section *YAMLSec) { 9105ffd83dbSDimitry Andric if (YAMLSec && YAMLSec->Address) { 9115ffd83dbSDimitry Andric SHeader.sh_addr = *YAMLSec->Address; 9125ffd83dbSDimitry Andric LocationCounter = *YAMLSec->Address; 9135ffd83dbSDimitry Andric return; 9145ffd83dbSDimitry Andric } 9155ffd83dbSDimitry Andric 9165ffd83dbSDimitry Andric // sh_addr represents the address in the memory image of a process. Sections 9175ffd83dbSDimitry Andric // in a relocatable object file or non-allocatable sections do not need 9185ffd83dbSDimitry Andric // sh_addr assignment. 9195ffd83dbSDimitry Andric if (Doc.Header.Type.value == ELF::ET_REL || 9205ffd83dbSDimitry Andric !(SHeader.sh_flags & ELF::SHF_ALLOC)) 9215ffd83dbSDimitry Andric return; 9225ffd83dbSDimitry Andric 9235ffd83dbSDimitry Andric LocationCounter = 9245ffd83dbSDimitry Andric alignTo(LocationCounter, SHeader.sh_addralign ? SHeader.sh_addralign : 1); 9255ffd83dbSDimitry Andric SHeader.sh_addr = LocationCounter; 9265ffd83dbSDimitry Andric } 9275ffd83dbSDimitry Andric 9288bcb0991SDimitry Andric static size_t findFirstNonGlobal(ArrayRef<ELFYAML::Symbol> Symbols) { 9298bcb0991SDimitry Andric for (size_t I = 0; I < Symbols.size(); ++I) 9308bcb0991SDimitry Andric if (Symbols[I].Binding.value != ELF::STB_LOCAL) 9318bcb0991SDimitry Andric return I; 9328bcb0991SDimitry Andric return Symbols.size(); 9338bcb0991SDimitry Andric } 9348bcb0991SDimitry Andric 9358bcb0991SDimitry Andric template <class ELFT> 9368bcb0991SDimitry Andric std::vector<typename ELFT::Sym> 9378bcb0991SDimitry Andric ELFState<ELFT>::toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols, 9388bcb0991SDimitry Andric const StringTableBuilder &Strtab) { 9398bcb0991SDimitry Andric std::vector<Elf_Sym> Ret; 9408bcb0991SDimitry Andric Ret.resize(Symbols.size() + 1); 9418bcb0991SDimitry Andric 9428bcb0991SDimitry Andric size_t I = 0; 943480093f4SDimitry Andric for (const ELFYAML::Symbol &Sym : Symbols) { 9448bcb0991SDimitry Andric Elf_Sym &Symbol = Ret[++I]; 9458bcb0991SDimitry Andric 9468bcb0991SDimitry Andric // If NameIndex, which contains the name offset, is explicitly specified, we 9478bcb0991SDimitry Andric // use it. This is useful for preparing broken objects. Otherwise, we add 9488bcb0991SDimitry Andric // the specified Name to the string table builder to get its offset. 9495ffd83dbSDimitry Andric if (Sym.StName) 9505ffd83dbSDimitry Andric Symbol.st_name = *Sym.StName; 9518bcb0991SDimitry Andric else if (!Sym.Name.empty()) 9528bcb0991SDimitry Andric Symbol.st_name = Strtab.getOffset(ELFYAML::dropUniqueSuffix(Sym.Name)); 9538bcb0991SDimitry Andric 9548bcb0991SDimitry Andric Symbol.setBindingAndType(Sym.Binding, Sym.Type); 955e8d8bef9SDimitry Andric if (Sym.Section) 956e8d8bef9SDimitry Andric Symbol.st_shndx = toSectionIndex(*Sym.Section, "", Sym.Name); 9578bcb0991SDimitry Andric else if (Sym.Index) 9588bcb0991SDimitry Andric Symbol.st_shndx = *Sym.Index; 9598bcb0991SDimitry Andric 960*81ad6265SDimitry Andric Symbol.st_value = Sym.Value.value_or(yaml::Hex64(0)); 9618bcb0991SDimitry Andric Symbol.st_other = Sym.Other ? *Sym.Other : 0; 962*81ad6265SDimitry Andric Symbol.st_size = Sym.Size.value_or(yaml::Hex64(0)); 9638bcb0991SDimitry Andric } 9648bcb0991SDimitry Andric 9658bcb0991SDimitry Andric return Ret; 9668bcb0991SDimitry Andric } 9678bcb0991SDimitry Andric 9688bcb0991SDimitry Andric template <class ELFT> 9698bcb0991SDimitry Andric void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader, 9708bcb0991SDimitry Andric SymtabType STType, 9718bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 9728bcb0991SDimitry Andric ELFYAML::Section *YAMLSec) { 9738bcb0991SDimitry Andric 9748bcb0991SDimitry Andric bool IsStatic = STType == SymtabType::Static; 9758bcb0991SDimitry Andric ArrayRef<ELFYAML::Symbol> Symbols; 9768bcb0991SDimitry Andric if (IsStatic && Doc.Symbols) 9778bcb0991SDimitry Andric Symbols = *Doc.Symbols; 978480093f4SDimitry Andric else if (!IsStatic && Doc.DynamicSymbols) 979480093f4SDimitry Andric Symbols = *Doc.DynamicSymbols; 9808bcb0991SDimitry Andric 9818bcb0991SDimitry Andric ELFYAML::RawContentSection *RawSec = 9828bcb0991SDimitry Andric dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec); 983480093f4SDimitry Andric if (RawSec && (RawSec->Content || RawSec->Size)) { 984480093f4SDimitry Andric bool HasSymbolsDescription = 985480093f4SDimitry Andric (IsStatic && Doc.Symbols) || (!IsStatic && Doc.DynamicSymbols); 986480093f4SDimitry Andric if (HasSymbolsDescription) { 987480093f4SDimitry Andric StringRef Property = (IsStatic ? "`Symbols`" : "`DynamicSymbols`"); 9888bcb0991SDimitry Andric if (RawSec->Content) 989480093f4SDimitry Andric reportError("cannot specify both `Content` and " + Property + 9908bcb0991SDimitry Andric " for symbol table section '" + RawSec->Name + "'"); 9918bcb0991SDimitry Andric if (RawSec->Size) 992480093f4SDimitry Andric reportError("cannot specify both `Size` and " + Property + 9938bcb0991SDimitry Andric " for symbol table section '" + RawSec->Name + "'"); 9948bcb0991SDimitry Andric return; 9958bcb0991SDimitry Andric } 996480093f4SDimitry Andric } 9978bcb0991SDimitry Andric 9985ffd83dbSDimitry Andric SHeader.sh_name = getSectionNameOffset(IsStatic ? ".symtab" : ".dynsym"); 9998bcb0991SDimitry Andric 10008bcb0991SDimitry Andric if (YAMLSec) 10018bcb0991SDimitry Andric SHeader.sh_type = YAMLSec->Type; 10028bcb0991SDimitry Andric else 10038bcb0991SDimitry Andric SHeader.sh_type = IsStatic ? ELF::SHT_SYMTAB : ELF::SHT_DYNSYM; 10048bcb0991SDimitry Andric 10058bcb0991SDimitry Andric if (YAMLSec && YAMLSec->Flags) 10068bcb0991SDimitry Andric SHeader.sh_flags = *YAMLSec->Flags; 10078bcb0991SDimitry Andric else if (!IsStatic) 10088bcb0991SDimitry Andric SHeader.sh_flags = ELF::SHF_ALLOC; 10098bcb0991SDimitry Andric 10108bcb0991SDimitry Andric // If the symbol table section is explicitly described in the YAML 10118bcb0991SDimitry Andric // then we should set the fields requested. 10128bcb0991SDimitry Andric SHeader.sh_info = (RawSec && RawSec->Info) ? (unsigned)(*RawSec->Info) 10138bcb0991SDimitry Andric : findFirstNonGlobal(Symbols) + 1; 10148bcb0991SDimitry Andric SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 8; 10158bcb0991SDimitry Andric 10165ffd83dbSDimitry Andric assignSectionAddress(SHeader, YAMLSec); 10175ffd83dbSDimitry Andric 1018e8d8bef9SDimitry Andric SHeader.sh_offset = 1019e8d8bef9SDimitry Andric alignToOffset(CBA, SHeader.sh_addralign, RawSec ? RawSec->Offset : None); 10205ffd83dbSDimitry Andric 10218bcb0991SDimitry Andric if (RawSec && (RawSec->Content || RawSec->Size)) { 10228bcb0991SDimitry Andric assert(Symbols.empty()); 10235ffd83dbSDimitry Andric SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size); 10248bcb0991SDimitry Andric return; 10258bcb0991SDimitry Andric } 10268bcb0991SDimitry Andric 10278bcb0991SDimitry Andric std::vector<Elf_Sym> Syms = 10288bcb0991SDimitry Andric toELFSymbols(Symbols, IsStatic ? DotStrtab : DotDynstr); 10295ffd83dbSDimitry Andric SHeader.sh_size = Syms.size() * sizeof(Elf_Sym); 10305ffd83dbSDimitry Andric CBA.write((const char *)Syms.data(), SHeader.sh_size); 10318bcb0991SDimitry Andric } 10328bcb0991SDimitry Andric 10338bcb0991SDimitry Andric template <class ELFT> 10348bcb0991SDimitry Andric void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name, 10358bcb0991SDimitry Andric StringTableBuilder &STB, 10368bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 10378bcb0991SDimitry Andric ELFYAML::Section *YAMLSec) { 1038fe6060f1SDimitry Andric SHeader.sh_name = getSectionNameOffset(ELFYAML::dropUniqueSuffix(Name)); 10398bcb0991SDimitry Andric SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_STRTAB; 10408bcb0991SDimitry Andric SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1; 10418bcb0991SDimitry Andric 10428bcb0991SDimitry Andric ELFYAML::RawContentSection *RawSec = 10438bcb0991SDimitry Andric dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec); 10448bcb0991SDimitry Andric 1045e8d8bef9SDimitry Andric SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign, 1046e8d8bef9SDimitry Andric YAMLSec ? YAMLSec->Offset : None); 10475ffd83dbSDimitry Andric 10488bcb0991SDimitry Andric if (RawSec && (RawSec->Content || RawSec->Size)) { 10495ffd83dbSDimitry Andric SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size); 10508bcb0991SDimitry Andric } else { 10515ffd83dbSDimitry Andric if (raw_ostream *OS = CBA.getRawOS(STB.getSize())) 10525ffd83dbSDimitry Andric STB.write(*OS); 10538bcb0991SDimitry Andric SHeader.sh_size = STB.getSize(); 10548bcb0991SDimitry Andric } 10558bcb0991SDimitry Andric 10568bcb0991SDimitry Andric if (RawSec && RawSec->Info) 10578bcb0991SDimitry Andric SHeader.sh_info = *RawSec->Info; 10588bcb0991SDimitry Andric 10598bcb0991SDimitry Andric if (YAMLSec && YAMLSec->Flags) 10608bcb0991SDimitry Andric SHeader.sh_flags = *YAMLSec->Flags; 10618bcb0991SDimitry Andric else if (Name == ".dynstr") 10628bcb0991SDimitry Andric SHeader.sh_flags = ELF::SHF_ALLOC; 10638bcb0991SDimitry Andric 10645ffd83dbSDimitry Andric assignSectionAddress(SHeader, YAMLSec); 10655ffd83dbSDimitry Andric } 10665ffd83dbSDimitry Andric 10675ffd83dbSDimitry Andric static bool shouldEmitDWARF(DWARFYAML::Data &DWARF, StringRef Name) { 1068e8d8bef9SDimitry Andric SetVector<StringRef> DebugSecNames = DWARF.getNonEmptySectionNames(); 10695ffd83dbSDimitry Andric return Name.consume_front(".") && DebugSecNames.count(Name); 10705ffd83dbSDimitry Andric } 10715ffd83dbSDimitry Andric 10725ffd83dbSDimitry Andric template <class ELFT> 10735ffd83dbSDimitry Andric Expected<uint64_t> emitDWARF(typename ELFT::Shdr &SHeader, StringRef Name, 10745ffd83dbSDimitry Andric const DWARFYAML::Data &DWARF, 10755ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA) { 10765ffd83dbSDimitry Andric // We are unable to predict the size of debug data, so we request to write 0 10775ffd83dbSDimitry Andric // bytes. This should always return us an output stream unless CBA is already 10785ffd83dbSDimitry Andric // in an error state. 10795ffd83dbSDimitry Andric raw_ostream *OS = CBA.getRawOS(0); 10805ffd83dbSDimitry Andric if (!OS) 10815ffd83dbSDimitry Andric return 0; 10825ffd83dbSDimitry Andric 10835ffd83dbSDimitry Andric uint64_t BeginOffset = CBA.tell(); 10845ffd83dbSDimitry Andric 1085e8d8bef9SDimitry Andric auto EmitFunc = DWARFYAML::getDWARFEmitterByName(Name.substr(1)); 1086e8d8bef9SDimitry Andric if (Error Err = EmitFunc(*OS, DWARF)) 10875ffd83dbSDimitry Andric return std::move(Err); 10885ffd83dbSDimitry Andric 10895ffd83dbSDimitry Andric return CBA.tell() - BeginOffset; 10905ffd83dbSDimitry Andric } 10915ffd83dbSDimitry Andric 10925ffd83dbSDimitry Andric template <class ELFT> 10935ffd83dbSDimitry Andric void ELFState<ELFT>::initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name, 10945ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA, 10955ffd83dbSDimitry Andric ELFYAML::Section *YAMLSec) { 10965ffd83dbSDimitry Andric SHeader.sh_name = getSectionNameOffset(ELFYAML::dropUniqueSuffix(Name)); 10975ffd83dbSDimitry Andric SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_PROGBITS; 10985ffd83dbSDimitry Andric SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1; 10995ffd83dbSDimitry Andric SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign, 11005ffd83dbSDimitry Andric YAMLSec ? YAMLSec->Offset : None); 11015ffd83dbSDimitry Andric 11025ffd83dbSDimitry Andric ELFYAML::RawContentSection *RawSec = 11035ffd83dbSDimitry Andric dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec); 11045ffd83dbSDimitry Andric if (Doc.DWARF && shouldEmitDWARF(*Doc.DWARF, Name)) { 11055ffd83dbSDimitry Andric if (RawSec && (RawSec->Content || RawSec->Size)) 11065ffd83dbSDimitry Andric reportError("cannot specify section '" + Name + 11075ffd83dbSDimitry Andric "' contents in the 'DWARF' entry and the 'Content' " 11085ffd83dbSDimitry Andric "or 'Size' in the 'Sections' entry at the same time"); 11095ffd83dbSDimitry Andric else { 11105ffd83dbSDimitry Andric if (Expected<uint64_t> ShSizeOrErr = 11115ffd83dbSDimitry Andric emitDWARF<ELFT>(SHeader, Name, *Doc.DWARF, CBA)) 11125ffd83dbSDimitry Andric SHeader.sh_size = *ShSizeOrErr; 11135ffd83dbSDimitry Andric else 11145ffd83dbSDimitry Andric reportError(ShSizeOrErr.takeError()); 11155ffd83dbSDimitry Andric } 11165ffd83dbSDimitry Andric } else if (RawSec) 11175ffd83dbSDimitry Andric SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size); 11185ffd83dbSDimitry Andric else 11195ffd83dbSDimitry Andric llvm_unreachable("debug sections can only be initialized via the 'DWARF' " 11205ffd83dbSDimitry Andric "entry or a RawContentSection"); 11215ffd83dbSDimitry Andric 11225ffd83dbSDimitry Andric if (RawSec && RawSec->Info) 11235ffd83dbSDimitry Andric SHeader.sh_info = *RawSec->Info; 11245ffd83dbSDimitry Andric 11255ffd83dbSDimitry Andric if (YAMLSec && YAMLSec->Flags) 11265ffd83dbSDimitry Andric SHeader.sh_flags = *YAMLSec->Flags; 11275ffd83dbSDimitry Andric else if (Name == ".debug_str") 11285ffd83dbSDimitry Andric SHeader.sh_flags = ELF::SHF_MERGE | ELF::SHF_STRINGS; 11295ffd83dbSDimitry Andric 11305ffd83dbSDimitry Andric assignSectionAddress(SHeader, YAMLSec); 11318bcb0991SDimitry Andric } 11328bcb0991SDimitry Andric 11338bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::reportError(const Twine &Msg) { 11348bcb0991SDimitry Andric ErrHandler(Msg); 11358bcb0991SDimitry Andric HasError = true; 11368bcb0991SDimitry Andric } 11378bcb0991SDimitry Andric 11385ffd83dbSDimitry Andric template <class ELFT> void ELFState<ELFT>::reportError(Error Err) { 11395ffd83dbSDimitry Andric handleAllErrors(std::move(Err), [&](const ErrorInfoBase &Err) { 11405ffd83dbSDimitry Andric reportError(Err.message()); 11415ffd83dbSDimitry Andric }); 11425ffd83dbSDimitry Andric } 11435ffd83dbSDimitry Andric 11448bcb0991SDimitry Andric template <class ELFT> 1145480093f4SDimitry Andric std::vector<Fragment> 1146480093f4SDimitry Andric ELFState<ELFT>::getPhdrFragments(const ELFYAML::ProgramHeader &Phdr, 11475ffd83dbSDimitry Andric ArrayRef<Elf_Shdr> SHeaders) { 1148480093f4SDimitry Andric std::vector<Fragment> Ret; 11495ffd83dbSDimitry Andric for (const ELFYAML::Chunk *C : Phdr.Chunks) { 11505ffd83dbSDimitry Andric if (const ELFYAML::Fill *F = dyn_cast<ELFYAML::Fill>(C)) { 11515ffd83dbSDimitry Andric Ret.push_back({*F->Offset, F->Size, llvm::ELF::SHT_PROGBITS, 1152480093f4SDimitry Andric /*ShAddrAlign=*/1}); 1153480093f4SDimitry Andric continue; 1154480093f4SDimitry Andric } 1155480093f4SDimitry Andric 11565ffd83dbSDimitry Andric const ELFYAML::Section *S = cast<ELFYAML::Section>(C); 11575ffd83dbSDimitry Andric const Elf_Shdr &H = SHeaders[SN2I.get(S->Name)]; 11585ffd83dbSDimitry Andric Ret.push_back({H.sh_offset, H.sh_size, H.sh_type, H.sh_addralign}); 1159480093f4SDimitry Andric } 1160480093f4SDimitry Andric return Ret; 1161480093f4SDimitry Andric } 1162480093f4SDimitry Andric 1163480093f4SDimitry Andric template <class ELFT> 11648bcb0991SDimitry Andric void ELFState<ELFT>::setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders, 11658bcb0991SDimitry Andric std::vector<Elf_Shdr> &SHeaders) { 11668bcb0991SDimitry Andric uint32_t PhdrIdx = 0; 11678bcb0991SDimitry Andric for (auto &YamlPhdr : Doc.ProgramHeaders) { 11688bcb0991SDimitry Andric Elf_Phdr &PHeader = PHeaders[PhdrIdx++]; 1169480093f4SDimitry Andric std::vector<Fragment> Fragments = getPhdrFragments(YamlPhdr, SHeaders); 11705ffd83dbSDimitry Andric if (!llvm::is_sorted(Fragments, [](const Fragment &A, const Fragment &B) { 11715ffd83dbSDimitry Andric return A.Offset < B.Offset; 11725ffd83dbSDimitry Andric })) 11735ffd83dbSDimitry Andric reportError("sections in the program header with index " + 11745ffd83dbSDimitry Andric Twine(PhdrIdx) + " are not sorted by their file offset"); 11758bcb0991SDimitry Andric 11768bcb0991SDimitry Andric if (YamlPhdr.Offset) { 11775ffd83dbSDimitry Andric if (!Fragments.empty() && *YamlPhdr.Offset > Fragments.front().Offset) 11785ffd83dbSDimitry Andric reportError("'Offset' for segment with index " + Twine(PhdrIdx) + 11795ffd83dbSDimitry Andric " must be less than or equal to the minimum file offset of " 11805ffd83dbSDimitry Andric "all included sections (0x" + 11815ffd83dbSDimitry Andric Twine::utohexstr(Fragments.front().Offset) + ")"); 11828bcb0991SDimitry Andric PHeader.p_offset = *YamlPhdr.Offset; 11835ffd83dbSDimitry Andric } else if (!Fragments.empty()) { 11845ffd83dbSDimitry Andric PHeader.p_offset = Fragments.front().Offset; 11855ffd83dbSDimitry Andric } 11868bcb0991SDimitry Andric 11875ffd83dbSDimitry Andric // Set the file size if not set explicitly. 11885ffd83dbSDimitry Andric if (YamlPhdr.FileSize) { 11895ffd83dbSDimitry Andric PHeader.p_filesz = *YamlPhdr.FileSize; 11905ffd83dbSDimitry Andric } else if (!Fragments.empty()) { 11915ffd83dbSDimitry Andric uint64_t FileSize = Fragments.back().Offset - PHeader.p_offset; 11925ffd83dbSDimitry Andric // SHT_NOBITS sections occupy no physical space in a file, we should not 11935ffd83dbSDimitry Andric // take their sizes into account when calculating the file size of a 11945ffd83dbSDimitry Andric // segment. 11955ffd83dbSDimitry Andric if (Fragments.back().Type != llvm::ELF::SHT_NOBITS) 11965ffd83dbSDimitry Andric FileSize += Fragments.back().Size; 11975ffd83dbSDimitry Andric PHeader.p_filesz = FileSize; 11985ffd83dbSDimitry Andric } 11995ffd83dbSDimitry Andric 12005ffd83dbSDimitry Andric // Find the maximum offset of the end of a section in order to set p_memsz. 12015ffd83dbSDimitry Andric uint64_t MemOffset = PHeader.p_offset; 1202480093f4SDimitry Andric for (const Fragment &F : Fragments) 12035ffd83dbSDimitry Andric MemOffset = std::max(MemOffset, F.Offset + F.Size); 12045ffd83dbSDimitry Andric // Set the memory size if not set explicitly. 12058bcb0991SDimitry Andric PHeader.p_memsz = YamlPhdr.MemSize ? uint64_t(*YamlPhdr.MemSize) 12068bcb0991SDimitry Andric : MemOffset - PHeader.p_offset; 12078bcb0991SDimitry Andric 12088bcb0991SDimitry Andric if (YamlPhdr.Align) { 12098bcb0991SDimitry Andric PHeader.p_align = *YamlPhdr.Align; 12108bcb0991SDimitry Andric } else { 12118bcb0991SDimitry Andric // Set the alignment of the segment to be the maximum alignment of the 12128bcb0991SDimitry Andric // sections so that by default the segment has a valid and sensible 12138bcb0991SDimitry Andric // alignment. 12148bcb0991SDimitry Andric PHeader.p_align = 1; 1215480093f4SDimitry Andric for (const Fragment &F : Fragments) 1216480093f4SDimitry Andric PHeader.p_align = std::max((uint64_t)PHeader.p_align, F.AddrAlign); 12178bcb0991SDimitry Andric } 12188bcb0991SDimitry Andric } 12198bcb0991SDimitry Andric } 12208bcb0991SDimitry Andric 1221e8d8bef9SDimitry Andric bool llvm::ELFYAML::shouldAllocateFileSpace( 1222e8d8bef9SDimitry Andric ArrayRef<ELFYAML::ProgramHeader> Phdrs, const ELFYAML::NoBitsSection &S) { 12235ffd83dbSDimitry Andric for (const ELFYAML::ProgramHeader &PH : Phdrs) { 12245ffd83dbSDimitry Andric auto It = llvm::find_if( 12255ffd83dbSDimitry Andric PH.Chunks, [&](ELFYAML::Chunk *C) { return C->Name == S.Name; }); 12265ffd83dbSDimitry Andric if (std::any_of(It, PH.Chunks.end(), [](ELFYAML::Chunk *C) { 12275ffd83dbSDimitry Andric return (isa<ELFYAML::Fill>(C) || 12285ffd83dbSDimitry Andric cast<ELFYAML::Section>(C)->Type != ELF::SHT_NOBITS); 12295ffd83dbSDimitry Andric })) 12305ffd83dbSDimitry Andric return true; 12315ffd83dbSDimitry Andric } 12325ffd83dbSDimitry Andric return false; 12335ffd83dbSDimitry Andric } 12345ffd83dbSDimitry Andric 12355ffd83dbSDimitry Andric template <class ELFT> 12365ffd83dbSDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 12375ffd83dbSDimitry Andric const ELFYAML::NoBitsSection &S, 12385ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA) { 1239e8d8bef9SDimitry Andric if (!S.Size) 1240e8d8bef9SDimitry Andric return; 1241e8d8bef9SDimitry Andric 1242e8d8bef9SDimitry Andric SHeader.sh_size = *S.Size; 12435ffd83dbSDimitry Andric 12445ffd83dbSDimitry Andric // When a nobits section is followed by a non-nobits section or fill 12455ffd83dbSDimitry Andric // in the same segment, we allocate the file space for it. This behavior 12465ffd83dbSDimitry Andric // matches linkers. 12475ffd83dbSDimitry Andric if (shouldAllocateFileSpace(Doc.ProgramHeaders, S)) 1248e8d8bef9SDimitry Andric CBA.writeZeros(*S.Size); 12495ffd83dbSDimitry Andric } 12505ffd83dbSDimitry Andric 12518bcb0991SDimitry Andric template <class ELFT> 12528bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 12538bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::RawContentSection &Section, 12548bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 12558bcb0991SDimitry Andric if (Section.Info) 12568bcb0991SDimitry Andric SHeader.sh_info = *Section.Info; 12578bcb0991SDimitry Andric } 12588bcb0991SDimitry Andric 1259e8d8bef9SDimitry Andric static bool isMips64EL(const ELFYAML::Object &Obj) { 1260e8d8bef9SDimitry Andric return Obj.getMachine() == llvm::ELF::EM_MIPS && 1261e8d8bef9SDimitry Andric Obj.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64) && 1262e8d8bef9SDimitry Andric Obj.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB); 12638bcb0991SDimitry Andric } 12648bcb0991SDimitry Andric 12658bcb0991SDimitry Andric template <class ELFT> 12668bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 12678bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::RelocationSection &Section, 12688bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 12698bcb0991SDimitry Andric assert((Section.Type == llvm::ELF::SHT_REL || 12708bcb0991SDimitry Andric Section.Type == llvm::ELF::SHT_RELA) && 12718bcb0991SDimitry Andric "Section type is not SHT_REL nor SHT_RELA"); 12728bcb0991SDimitry Andric 12738bcb0991SDimitry Andric if (!Section.RelocatableSec.empty()) 12748bcb0991SDimitry Andric SHeader.sh_info = toSectionIndex(Section.RelocatableSec, Section.Name); 12758bcb0991SDimitry Andric 1276e8d8bef9SDimitry Andric if (!Section.Relocations) 1277e8d8bef9SDimitry Andric return; 1278e8d8bef9SDimitry Andric 1279e8d8bef9SDimitry Andric const bool IsRela = Section.Type == llvm::ELF::SHT_RELA; 1280e8d8bef9SDimitry Andric for (const ELFYAML::Relocation &Rel : *Section.Relocations) { 1281e8d8bef9SDimitry Andric const bool IsDynamic = Section.Link && (*Section.Link == ".dynsym"); 1282e8d8bef9SDimitry Andric unsigned SymIdx = 1283e8d8bef9SDimitry Andric Rel.Symbol ? toSymbolIndex(*Rel.Symbol, Section.Name, IsDynamic) : 0; 12848bcb0991SDimitry Andric if (IsRela) { 12858bcb0991SDimitry Andric Elf_Rela REntry; 12868bcb0991SDimitry Andric zero(REntry); 12878bcb0991SDimitry Andric REntry.r_offset = Rel.Offset; 12888bcb0991SDimitry Andric REntry.r_addend = Rel.Addend; 12898bcb0991SDimitry Andric REntry.setSymbolAndType(SymIdx, Rel.Type, isMips64EL(Doc)); 12905ffd83dbSDimitry Andric CBA.write((const char *)&REntry, sizeof(REntry)); 12918bcb0991SDimitry Andric } else { 12928bcb0991SDimitry Andric Elf_Rel REntry; 12938bcb0991SDimitry Andric zero(REntry); 12948bcb0991SDimitry Andric REntry.r_offset = Rel.Offset; 12958bcb0991SDimitry Andric REntry.setSymbolAndType(SymIdx, Rel.Type, isMips64EL(Doc)); 12965ffd83dbSDimitry Andric CBA.write((const char *)&REntry, sizeof(REntry)); 12978bcb0991SDimitry Andric } 12988bcb0991SDimitry Andric } 1299e8d8bef9SDimitry Andric 1300e8d8bef9SDimitry Andric SHeader.sh_size = (IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel)) * 1301e8d8bef9SDimitry Andric Section.Relocations->size(); 13028bcb0991SDimitry Andric } 13038bcb0991SDimitry Andric 13048bcb0991SDimitry Andric template <class ELFT> 1305480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 1306480093f4SDimitry Andric const ELFYAML::RelrSection &Section, 1307480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1308480093f4SDimitry Andric if (!Section.Entries) 1309480093f4SDimitry Andric return; 1310480093f4SDimitry Andric 1311480093f4SDimitry Andric for (llvm::yaml::Hex64 E : *Section.Entries) { 1312480093f4SDimitry Andric if (!ELFT::Is64Bits && E > UINT32_MAX) 1313480093f4SDimitry Andric reportError(Section.Name + ": the value is too large for 32-bits: 0x" + 1314480093f4SDimitry Andric Twine::utohexstr(E)); 13155ffd83dbSDimitry Andric CBA.write<uintX_t>(E, ELFT::TargetEndianness); 1316480093f4SDimitry Andric } 1317480093f4SDimitry Andric 1318480093f4SDimitry Andric SHeader.sh_size = sizeof(uintX_t) * Section.Entries->size(); 1319480093f4SDimitry Andric } 1320480093f4SDimitry Andric 1321480093f4SDimitry Andric template <class ELFT> 13228bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 13238bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::SymtabShndxSection &Shndx, 13248bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 1325e8d8bef9SDimitry Andric if (Shndx.Content || Shndx.Size) { 1326e8d8bef9SDimitry Andric SHeader.sh_size = writeContent(CBA, Shndx.Content, Shndx.Size); 1327e8d8bef9SDimitry Andric return; 1328e8d8bef9SDimitry Andric } 13298bcb0991SDimitry Andric 1330e8d8bef9SDimitry Andric if (!Shndx.Entries) 1331e8d8bef9SDimitry Andric return; 1332e8d8bef9SDimitry Andric 1333e8d8bef9SDimitry Andric for (uint32_t E : *Shndx.Entries) 1334e8d8bef9SDimitry Andric CBA.write<uint32_t>(E, ELFT::TargetEndianness); 1335e8d8bef9SDimitry Andric SHeader.sh_size = Shndx.Entries->size() * SHeader.sh_entsize; 13368bcb0991SDimitry Andric } 13378bcb0991SDimitry Andric 13388bcb0991SDimitry Andric template <class ELFT> 13398bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 1340e8d8bef9SDimitry Andric const ELFYAML::GroupSection &Section, 13418bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 13428bcb0991SDimitry Andric assert(Section.Type == llvm::ELF::SHT_GROUP && 13438bcb0991SDimitry Andric "Section type is not SHT_GROUP"); 13448bcb0991SDimitry Andric 1345480093f4SDimitry Andric if (Section.Signature) 13468bcb0991SDimitry Andric SHeader.sh_info = 1347480093f4SDimitry Andric toSymbolIndex(*Section.Signature, Section.Name, /*IsDynamic=*/false); 13488bcb0991SDimitry Andric 1349e8d8bef9SDimitry Andric if (!Section.Members) 1350e8d8bef9SDimitry Andric return; 1351e8d8bef9SDimitry Andric 1352e8d8bef9SDimitry Andric for (const ELFYAML::SectionOrType &Member : *Section.Members) { 13538bcb0991SDimitry Andric unsigned int SectionIndex = 0; 13548bcb0991SDimitry Andric if (Member.sectionNameOrType == "GRP_COMDAT") 13558bcb0991SDimitry Andric SectionIndex = llvm::ELF::GRP_COMDAT; 13568bcb0991SDimitry Andric else 13578bcb0991SDimitry Andric SectionIndex = toSectionIndex(Member.sectionNameOrType, Section.Name); 13585ffd83dbSDimitry Andric CBA.write<uint32_t>(SectionIndex, ELFT::TargetEndianness); 13598bcb0991SDimitry Andric } 1360e8d8bef9SDimitry Andric SHeader.sh_size = SHeader.sh_entsize * Section.Members->size(); 13618bcb0991SDimitry Andric } 13628bcb0991SDimitry Andric 13638bcb0991SDimitry Andric template <class ELFT> 13648bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 13658bcb0991SDimitry Andric const ELFYAML::SymverSection &Section, 13668bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 1367e8d8bef9SDimitry Andric if (!Section.Entries) 1368e8d8bef9SDimitry Andric return; 13698bcb0991SDimitry Andric 1370e8d8bef9SDimitry Andric for (uint16_t Version : *Section.Entries) 1371e8d8bef9SDimitry Andric CBA.write<uint16_t>(Version, ELFT::TargetEndianness); 1372e8d8bef9SDimitry Andric SHeader.sh_size = Section.Entries->size() * SHeader.sh_entsize; 13738bcb0991SDimitry Andric } 13748bcb0991SDimitry Andric 13758bcb0991SDimitry Andric template <class ELFT> 13768bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 13778bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::StackSizesSection &Section, 13788bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 1379e8d8bef9SDimitry Andric if (!Section.Entries) 13808bcb0991SDimitry Andric return; 1381e8d8bef9SDimitry Andric 13828bcb0991SDimitry Andric for (const ELFYAML::StackSizeEntry &E : *Section.Entries) { 13835ffd83dbSDimitry Andric CBA.write<uintX_t>(E.Address, ELFT::TargetEndianness); 13845ffd83dbSDimitry Andric SHeader.sh_size += sizeof(uintX_t) + CBA.writeULEB128(E.Size); 13858bcb0991SDimitry Andric } 13868bcb0991SDimitry Andric } 13878bcb0991SDimitry Andric 13888bcb0991SDimitry Andric template <class ELFT> 1389480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent( 1390e8d8bef9SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::BBAddrMapSection &Section, 1391480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1392e8d8bef9SDimitry Andric if (!Section.Entries) 1393480093f4SDimitry Andric return; 1394e8d8bef9SDimitry Andric 1395e8d8bef9SDimitry Andric for (const ELFYAML::BBAddrMapEntry &E : *Section.Entries) { 1396*81ad6265SDimitry Andric // Write version and feature values. 1397*81ad6265SDimitry Andric if (Section.Type == llvm::ELF::SHT_LLVM_BB_ADDR_MAP) { 1398*81ad6265SDimitry Andric if (E.Version > 1) 1399*81ad6265SDimitry Andric WithColor::warning() << "unsupported SHT_LLVM_BB_ADDR_MAP version: " 1400*81ad6265SDimitry Andric << static_cast<int>(E.Version) 1401*81ad6265SDimitry Andric << "; encoding using the most recent version"; 1402*81ad6265SDimitry Andric CBA.write(E.Version); 1403*81ad6265SDimitry Andric CBA.write(E.Feature); 1404*81ad6265SDimitry Andric SHeader.sh_size += 2; 1405*81ad6265SDimitry Andric } 1406e8d8bef9SDimitry Andric // Write the address of the function. 1407e8d8bef9SDimitry Andric CBA.write<uintX_t>(E.Address, ELFT::TargetEndianness); 1408fe6060f1SDimitry Andric // Write number of BBEntries (number of basic blocks in the function). This 1409fe6060f1SDimitry Andric // is overridden by the 'NumBlocks' YAML field when specified. 1410fe6060f1SDimitry Andric uint64_t NumBlocks = 1411*81ad6265SDimitry Andric E.NumBlocks.value_or(E.BBEntries ? E.BBEntries->size() : 0); 1412e8d8bef9SDimitry Andric SHeader.sh_size += sizeof(uintX_t) + CBA.writeULEB128(NumBlocks); 1413e8d8bef9SDimitry Andric // Write all BBEntries. 1414fe6060f1SDimitry Andric if (!E.BBEntries) 1415fe6060f1SDimitry Andric continue; 1416e8d8bef9SDimitry Andric for (const ELFYAML::BBAddrMapEntry::BBEntry &BBE : *E.BBEntries) 1417e8d8bef9SDimitry Andric SHeader.sh_size += CBA.writeULEB128(BBE.AddressOffset) + 1418e8d8bef9SDimitry Andric CBA.writeULEB128(BBE.Size) + 1419e8d8bef9SDimitry Andric CBA.writeULEB128(BBE.Metadata); 1420e8d8bef9SDimitry Andric } 1421480093f4SDimitry Andric } 1422480093f4SDimitry Andric 1423e8d8bef9SDimitry Andric template <class ELFT> 1424e8d8bef9SDimitry Andric void ELFState<ELFT>::writeSectionContent( 1425e8d8bef9SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::LinkerOptionsSection &Section, 1426e8d8bef9SDimitry Andric ContiguousBlobAccumulator &CBA) { 1427480093f4SDimitry Andric if (!Section.Options) 1428480093f4SDimitry Andric return; 1429480093f4SDimitry Andric 1430480093f4SDimitry Andric for (const ELFYAML::LinkerOption &LO : *Section.Options) { 14315ffd83dbSDimitry Andric CBA.write(LO.Key.data(), LO.Key.size()); 14325ffd83dbSDimitry Andric CBA.write('\0'); 14335ffd83dbSDimitry Andric CBA.write(LO.Value.data(), LO.Value.size()); 14345ffd83dbSDimitry Andric CBA.write('\0'); 1435480093f4SDimitry Andric SHeader.sh_size += (LO.Key.size() + LO.Value.size() + 2); 1436480093f4SDimitry Andric } 1437480093f4SDimitry Andric } 1438480093f4SDimitry Andric 1439480093f4SDimitry Andric template <class ELFT> 1440480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent( 1441480093f4SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::DependentLibrariesSection &Section, 1442480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1443480093f4SDimitry Andric if (!Section.Libs) 1444480093f4SDimitry Andric return; 1445480093f4SDimitry Andric 1446480093f4SDimitry Andric for (StringRef Lib : *Section.Libs) { 14475ffd83dbSDimitry Andric CBA.write(Lib.data(), Lib.size()); 14485ffd83dbSDimitry Andric CBA.write('\0'); 1449480093f4SDimitry Andric SHeader.sh_size += Lib.size() + 1; 1450480093f4SDimitry Andric } 1451480093f4SDimitry Andric } 1452480093f4SDimitry Andric 1453480093f4SDimitry Andric template <class ELFT> 14545ffd83dbSDimitry Andric uint64_t 14555ffd83dbSDimitry Andric ELFState<ELFT>::alignToOffset(ContiguousBlobAccumulator &CBA, uint64_t Align, 14565ffd83dbSDimitry Andric llvm::Optional<llvm::yaml::Hex64> Offset) { 14575ffd83dbSDimitry Andric uint64_t CurrentOffset = CBA.getOffset(); 14585ffd83dbSDimitry Andric uint64_t AlignedOffset; 14595ffd83dbSDimitry Andric 14605ffd83dbSDimitry Andric if (Offset) { 14615ffd83dbSDimitry Andric if ((uint64_t)*Offset < CurrentOffset) { 14625ffd83dbSDimitry Andric reportError("the 'Offset' value (0x" + 14635ffd83dbSDimitry Andric Twine::utohexstr((uint64_t)*Offset) + ") goes backward"); 14645ffd83dbSDimitry Andric return CurrentOffset; 14655ffd83dbSDimitry Andric } 14665ffd83dbSDimitry Andric 14675ffd83dbSDimitry Andric // We ignore an alignment when an explicit offset has been requested. 14685ffd83dbSDimitry Andric AlignedOffset = *Offset; 14695ffd83dbSDimitry Andric } else { 14705ffd83dbSDimitry Andric AlignedOffset = alignTo(CurrentOffset, std::max(Align, (uint64_t)1)); 14715ffd83dbSDimitry Andric } 14725ffd83dbSDimitry Andric 14735ffd83dbSDimitry Andric CBA.writeZeros(AlignedOffset - CurrentOffset); 14745ffd83dbSDimitry Andric return AlignedOffset; 14755ffd83dbSDimitry Andric } 14765ffd83dbSDimitry Andric 14775ffd83dbSDimitry Andric template <class ELFT> 14785ffd83dbSDimitry Andric void ELFState<ELFT>::writeSectionContent( 14795ffd83dbSDimitry Andric Elf_Shdr &SHeader, const ELFYAML::CallGraphProfileSection &Section, 14805ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA) { 14815ffd83dbSDimitry Andric if (!Section.Entries) 14825ffd83dbSDimitry Andric return; 14835ffd83dbSDimitry Andric 1484fe6060f1SDimitry Andric for (const ELFYAML::CallGraphEntryWeight &E : *Section.Entries) { 14855ffd83dbSDimitry Andric CBA.write<uint64_t>(E.Weight, ELFT::TargetEndianness); 1486fe6060f1SDimitry Andric SHeader.sh_size += sizeof(object::Elf_CGProfile_Impl<ELFT>); 14875ffd83dbSDimitry Andric } 14885ffd83dbSDimitry Andric } 14895ffd83dbSDimitry Andric 14905ffd83dbSDimitry Andric template <class ELFT> 14918bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 14928bcb0991SDimitry Andric const ELFYAML::HashSection &Section, 14938bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 1494e8d8bef9SDimitry Andric if (!Section.Bucket) 14958bcb0991SDimitry Andric return; 1496e8d8bef9SDimitry Andric 14975ffd83dbSDimitry Andric CBA.write<uint32_t>( 1498*81ad6265SDimitry Andric Section.NBucket.value_or(llvm::yaml::Hex64(Section.Bucket->size())), 14998bcb0991SDimitry Andric ELFT::TargetEndianness); 15005ffd83dbSDimitry Andric CBA.write<uint32_t>( 1501*81ad6265SDimitry Andric Section.NChain.value_or(llvm::yaml::Hex64(Section.Chain->size())), 15028bcb0991SDimitry Andric ELFT::TargetEndianness); 15035ffd83dbSDimitry Andric 15048bcb0991SDimitry Andric for (uint32_t Val : *Section.Bucket) 15055ffd83dbSDimitry Andric CBA.write<uint32_t>(Val, ELFT::TargetEndianness); 15068bcb0991SDimitry Andric for (uint32_t Val : *Section.Chain) 15075ffd83dbSDimitry Andric CBA.write<uint32_t>(Val, ELFT::TargetEndianness); 15088bcb0991SDimitry Andric 15098bcb0991SDimitry Andric SHeader.sh_size = (2 + Section.Bucket->size() + Section.Chain->size()) * 4; 15108bcb0991SDimitry Andric } 15118bcb0991SDimitry Andric 15128bcb0991SDimitry Andric template <class ELFT> 15138bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 15148bcb0991SDimitry Andric const ELFYAML::VerdefSection &Section, 15158bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 15168bcb0991SDimitry Andric 1517e8d8bef9SDimitry Andric if (Section.Info) 1518e8d8bef9SDimitry Andric SHeader.sh_info = *Section.Info; 1519e8d8bef9SDimitry Andric else if (Section.Entries) 1520e8d8bef9SDimitry Andric SHeader.sh_info = Section.Entries->size(); 1521480093f4SDimitry Andric 1522480093f4SDimitry Andric if (!Section.Entries) 1523480093f4SDimitry Andric return; 1524480093f4SDimitry Andric 15258bcb0991SDimitry Andric uint64_t AuxCnt = 0; 1526480093f4SDimitry Andric for (size_t I = 0; I < Section.Entries->size(); ++I) { 1527480093f4SDimitry Andric const ELFYAML::VerdefEntry &E = (*Section.Entries)[I]; 15288bcb0991SDimitry Andric 15298bcb0991SDimitry Andric Elf_Verdef VerDef; 1530*81ad6265SDimitry Andric VerDef.vd_version = E.Version.value_or(1); 1531*81ad6265SDimitry Andric VerDef.vd_flags = E.Flags.value_or(0); 1532*81ad6265SDimitry Andric VerDef.vd_ndx = E.VersionNdx.value_or(0); 1533*81ad6265SDimitry Andric VerDef.vd_hash = E.Hash.value_or(0); 15348bcb0991SDimitry Andric VerDef.vd_aux = sizeof(Elf_Verdef); 15358bcb0991SDimitry Andric VerDef.vd_cnt = E.VerNames.size(); 1536480093f4SDimitry Andric if (I == Section.Entries->size() - 1) 15378bcb0991SDimitry Andric VerDef.vd_next = 0; 15388bcb0991SDimitry Andric else 15398bcb0991SDimitry Andric VerDef.vd_next = 15408bcb0991SDimitry Andric sizeof(Elf_Verdef) + E.VerNames.size() * sizeof(Elf_Verdaux); 15415ffd83dbSDimitry Andric CBA.write((const char *)&VerDef, sizeof(Elf_Verdef)); 15428bcb0991SDimitry Andric 15438bcb0991SDimitry Andric for (size_t J = 0; J < E.VerNames.size(); ++J, ++AuxCnt) { 15448bcb0991SDimitry Andric Elf_Verdaux VernAux; 15458bcb0991SDimitry Andric VernAux.vda_name = DotDynstr.getOffset(E.VerNames[J]); 15468bcb0991SDimitry Andric if (J == E.VerNames.size() - 1) 15478bcb0991SDimitry Andric VernAux.vda_next = 0; 15488bcb0991SDimitry Andric else 15498bcb0991SDimitry Andric VernAux.vda_next = sizeof(Elf_Verdaux); 15505ffd83dbSDimitry Andric CBA.write((const char *)&VernAux, sizeof(Elf_Verdaux)); 15518bcb0991SDimitry Andric } 15528bcb0991SDimitry Andric } 15538bcb0991SDimitry Andric 1554480093f4SDimitry Andric SHeader.sh_size = Section.Entries->size() * sizeof(Elf_Verdef) + 15558bcb0991SDimitry Andric AuxCnt * sizeof(Elf_Verdaux); 15568bcb0991SDimitry Andric } 15578bcb0991SDimitry Andric 15588bcb0991SDimitry Andric template <class ELFT> 15598bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 15608bcb0991SDimitry Andric const ELFYAML::VerneedSection &Section, 15618bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 1562e8d8bef9SDimitry Andric if (Section.Info) 1563e8d8bef9SDimitry Andric SHeader.sh_info = *Section.Info; 1564e8d8bef9SDimitry Andric else if (Section.VerneedV) 1565e8d8bef9SDimitry Andric SHeader.sh_info = Section.VerneedV->size(); 1566480093f4SDimitry Andric 1567480093f4SDimitry Andric if (!Section.VerneedV) 1568480093f4SDimitry Andric return; 15698bcb0991SDimitry Andric 15708bcb0991SDimitry Andric uint64_t AuxCnt = 0; 1571480093f4SDimitry Andric for (size_t I = 0; I < Section.VerneedV->size(); ++I) { 1572480093f4SDimitry Andric const ELFYAML::VerneedEntry &VE = (*Section.VerneedV)[I]; 15738bcb0991SDimitry Andric 15748bcb0991SDimitry Andric Elf_Verneed VerNeed; 15758bcb0991SDimitry Andric VerNeed.vn_version = VE.Version; 15768bcb0991SDimitry Andric VerNeed.vn_file = DotDynstr.getOffset(VE.File); 1577480093f4SDimitry Andric if (I == Section.VerneedV->size() - 1) 15788bcb0991SDimitry Andric VerNeed.vn_next = 0; 15798bcb0991SDimitry Andric else 15808bcb0991SDimitry Andric VerNeed.vn_next = 15818bcb0991SDimitry Andric sizeof(Elf_Verneed) + VE.AuxV.size() * sizeof(Elf_Vernaux); 15828bcb0991SDimitry Andric VerNeed.vn_cnt = VE.AuxV.size(); 15838bcb0991SDimitry Andric VerNeed.vn_aux = sizeof(Elf_Verneed); 15845ffd83dbSDimitry Andric CBA.write((const char *)&VerNeed, sizeof(Elf_Verneed)); 15858bcb0991SDimitry Andric 15868bcb0991SDimitry Andric for (size_t J = 0; J < VE.AuxV.size(); ++J, ++AuxCnt) { 15878bcb0991SDimitry Andric const ELFYAML::VernauxEntry &VAuxE = VE.AuxV[J]; 15888bcb0991SDimitry Andric 15898bcb0991SDimitry Andric Elf_Vernaux VernAux; 15908bcb0991SDimitry Andric VernAux.vna_hash = VAuxE.Hash; 15918bcb0991SDimitry Andric VernAux.vna_flags = VAuxE.Flags; 15928bcb0991SDimitry Andric VernAux.vna_other = VAuxE.Other; 15938bcb0991SDimitry Andric VernAux.vna_name = DotDynstr.getOffset(VAuxE.Name); 15948bcb0991SDimitry Andric if (J == VE.AuxV.size() - 1) 15958bcb0991SDimitry Andric VernAux.vna_next = 0; 15968bcb0991SDimitry Andric else 15978bcb0991SDimitry Andric VernAux.vna_next = sizeof(Elf_Vernaux); 15985ffd83dbSDimitry Andric CBA.write((const char *)&VernAux, sizeof(Elf_Vernaux)); 15998bcb0991SDimitry Andric } 16008bcb0991SDimitry Andric } 16018bcb0991SDimitry Andric 1602480093f4SDimitry Andric SHeader.sh_size = Section.VerneedV->size() * sizeof(Elf_Verneed) + 16038bcb0991SDimitry Andric AuxCnt * sizeof(Elf_Vernaux); 16048bcb0991SDimitry Andric } 16058bcb0991SDimitry Andric 16068bcb0991SDimitry Andric template <class ELFT> 1607e8d8bef9SDimitry Andric void ELFState<ELFT>::writeSectionContent( 1608e8d8bef9SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::ARMIndexTableSection &Section, 1609e8d8bef9SDimitry Andric ContiguousBlobAccumulator &CBA) { 1610e8d8bef9SDimitry Andric if (!Section.Entries) 1611e8d8bef9SDimitry Andric return; 1612e8d8bef9SDimitry Andric 1613e8d8bef9SDimitry Andric for (const ELFYAML::ARMIndexTableEntry &E : *Section.Entries) { 1614e8d8bef9SDimitry Andric CBA.write<uint32_t>(E.Offset, ELFT::TargetEndianness); 1615e8d8bef9SDimitry Andric CBA.write<uint32_t>(E.Value, ELFT::TargetEndianness); 1616e8d8bef9SDimitry Andric } 1617e8d8bef9SDimitry Andric SHeader.sh_size = Section.Entries->size() * 8; 1618e8d8bef9SDimitry Andric } 1619e8d8bef9SDimitry Andric 1620e8d8bef9SDimitry Andric template <class ELFT> 16218bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 16228bcb0991SDimitry Andric const ELFYAML::MipsABIFlags &Section, 16238bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 16248bcb0991SDimitry Andric assert(Section.Type == llvm::ELF::SHT_MIPS_ABIFLAGS && 16258bcb0991SDimitry Andric "Section type is not SHT_MIPS_ABIFLAGS"); 16268bcb0991SDimitry Andric 16278bcb0991SDimitry Andric object::Elf_Mips_ABIFlags<ELFT> Flags; 16288bcb0991SDimitry Andric zero(Flags); 16298bcb0991SDimitry Andric SHeader.sh_size = SHeader.sh_entsize; 16308bcb0991SDimitry Andric 16318bcb0991SDimitry Andric Flags.version = Section.Version; 16328bcb0991SDimitry Andric Flags.isa_level = Section.ISALevel; 16338bcb0991SDimitry Andric Flags.isa_rev = Section.ISARevision; 16348bcb0991SDimitry Andric Flags.gpr_size = Section.GPRSize; 16358bcb0991SDimitry Andric Flags.cpr1_size = Section.CPR1Size; 16368bcb0991SDimitry Andric Flags.cpr2_size = Section.CPR2Size; 16378bcb0991SDimitry Andric Flags.fp_abi = Section.FpABI; 16388bcb0991SDimitry Andric Flags.isa_ext = Section.ISAExtension; 16398bcb0991SDimitry Andric Flags.ases = Section.ASEs; 16408bcb0991SDimitry Andric Flags.flags1 = Section.Flags1; 16418bcb0991SDimitry Andric Flags.flags2 = Section.Flags2; 16425ffd83dbSDimitry Andric CBA.write((const char *)&Flags, sizeof(Flags)); 16438bcb0991SDimitry Andric } 16448bcb0991SDimitry Andric 16458bcb0991SDimitry Andric template <class ELFT> 16468bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 16478bcb0991SDimitry Andric const ELFYAML::DynamicSection &Section, 16488bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 16498bcb0991SDimitry Andric assert(Section.Type == llvm::ELF::SHT_DYNAMIC && 16508bcb0991SDimitry Andric "Section type is not SHT_DYNAMIC"); 16518bcb0991SDimitry Andric 1652e8d8bef9SDimitry Andric if (!Section.Entries) 1653e8d8bef9SDimitry Andric return; 16548bcb0991SDimitry Andric 1655e8d8bef9SDimitry Andric for (const ELFYAML::DynamicEntry &DE : *Section.Entries) { 16565ffd83dbSDimitry Andric CBA.write<uintX_t>(DE.Tag, ELFT::TargetEndianness); 16575ffd83dbSDimitry Andric CBA.write<uintX_t>(DE.Val, ELFT::TargetEndianness); 16588bcb0991SDimitry Andric } 1659e8d8bef9SDimitry Andric SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries->size(); 16608bcb0991SDimitry Andric } 16618bcb0991SDimitry Andric 16628bcb0991SDimitry Andric template <class ELFT> 16638bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 16648bcb0991SDimitry Andric const ELFYAML::AddrsigSection &Section, 16658bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 1666e8d8bef9SDimitry Andric if (!Section.Symbols) 16678bcb0991SDimitry Andric return; 1668e8d8bef9SDimitry Andric 16695ffd83dbSDimitry Andric for (StringRef Sym : *Section.Symbols) 16705ffd83dbSDimitry Andric SHeader.sh_size += 16715ffd83dbSDimitry Andric CBA.writeULEB128(toSymbolIndex(Sym, Section.Name, /*IsDynamic=*/false)); 16728bcb0991SDimitry Andric } 16738bcb0991SDimitry Andric 1674480093f4SDimitry Andric template <class ELFT> 1675480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 1676480093f4SDimitry Andric const ELFYAML::NoteSection &Section, 1677480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1678e8d8bef9SDimitry Andric if (!Section.Notes) 1679480093f4SDimitry Andric return; 1680480093f4SDimitry Andric 1681e8d8bef9SDimitry Andric uint64_t Offset = CBA.tell(); 1682480093f4SDimitry Andric for (const ELFYAML::NoteEntry &NE : *Section.Notes) { 1683480093f4SDimitry Andric // Write name size. 1684480093f4SDimitry Andric if (NE.Name.empty()) 16855ffd83dbSDimitry Andric CBA.write<uint32_t>(0, ELFT::TargetEndianness); 1686480093f4SDimitry Andric else 16875ffd83dbSDimitry Andric CBA.write<uint32_t>(NE.Name.size() + 1, ELFT::TargetEndianness); 1688480093f4SDimitry Andric 1689480093f4SDimitry Andric // Write description size. 1690480093f4SDimitry Andric if (NE.Desc.binary_size() == 0) 16915ffd83dbSDimitry Andric CBA.write<uint32_t>(0, ELFT::TargetEndianness); 1692480093f4SDimitry Andric else 16935ffd83dbSDimitry Andric CBA.write<uint32_t>(NE.Desc.binary_size(), ELFT::TargetEndianness); 1694480093f4SDimitry Andric 1695480093f4SDimitry Andric // Write type. 16965ffd83dbSDimitry Andric CBA.write<uint32_t>(NE.Type, ELFT::TargetEndianness); 1697480093f4SDimitry Andric 1698480093f4SDimitry Andric // Write name, null terminator and padding. 1699480093f4SDimitry Andric if (!NE.Name.empty()) { 17005ffd83dbSDimitry Andric CBA.write(NE.Name.data(), NE.Name.size()); 17015ffd83dbSDimitry Andric CBA.write('\0'); 1702480093f4SDimitry Andric CBA.padToAlignment(4); 1703480093f4SDimitry Andric } 1704480093f4SDimitry Andric 1705480093f4SDimitry Andric // Write description and padding. 1706480093f4SDimitry Andric if (NE.Desc.binary_size() != 0) { 17075ffd83dbSDimitry Andric CBA.writeAsBinary(NE.Desc); 1708480093f4SDimitry Andric CBA.padToAlignment(4); 1709480093f4SDimitry Andric } 1710480093f4SDimitry Andric } 1711480093f4SDimitry Andric 17125ffd83dbSDimitry Andric SHeader.sh_size = CBA.tell() - Offset; 1713480093f4SDimitry Andric } 1714480093f4SDimitry Andric 1715480093f4SDimitry Andric template <class ELFT> 1716480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 1717480093f4SDimitry Andric const ELFYAML::GnuHashSection &Section, 1718480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1719e8d8bef9SDimitry Andric if (!Section.HashBuckets) 1720480093f4SDimitry Andric return; 1721e8d8bef9SDimitry Andric 1722e8d8bef9SDimitry Andric if (!Section.Header) 1723e8d8bef9SDimitry Andric return; 1724480093f4SDimitry Andric 1725480093f4SDimitry Andric // We write the header first, starting with the hash buckets count. Normally 1726480093f4SDimitry Andric // it is the number of entries in HashBuckets, but the "NBuckets" property can 1727480093f4SDimitry Andric // be used to override this field, which is useful for producing broken 1728480093f4SDimitry Andric // objects. 1729480093f4SDimitry Andric if (Section.Header->NBuckets) 17305ffd83dbSDimitry Andric CBA.write<uint32_t>(*Section.Header->NBuckets, ELFT::TargetEndianness); 1731480093f4SDimitry Andric else 17325ffd83dbSDimitry Andric CBA.write<uint32_t>(Section.HashBuckets->size(), ELFT::TargetEndianness); 1733480093f4SDimitry Andric 1734480093f4SDimitry Andric // Write the index of the first symbol in the dynamic symbol table accessible 1735480093f4SDimitry Andric // via the hash table. 17365ffd83dbSDimitry Andric CBA.write<uint32_t>(Section.Header->SymNdx, ELFT::TargetEndianness); 1737480093f4SDimitry Andric 1738480093f4SDimitry Andric // Write the number of words in the Bloom filter. As above, the "MaskWords" 1739480093f4SDimitry Andric // property can be used to set this field to any value. 1740480093f4SDimitry Andric if (Section.Header->MaskWords) 17415ffd83dbSDimitry Andric CBA.write<uint32_t>(*Section.Header->MaskWords, ELFT::TargetEndianness); 1742480093f4SDimitry Andric else 17435ffd83dbSDimitry Andric CBA.write<uint32_t>(Section.BloomFilter->size(), ELFT::TargetEndianness); 1744480093f4SDimitry Andric 1745480093f4SDimitry Andric // Write the shift constant used by the Bloom filter. 17465ffd83dbSDimitry Andric CBA.write<uint32_t>(Section.Header->Shift2, ELFT::TargetEndianness); 1747480093f4SDimitry Andric 1748480093f4SDimitry Andric // We've finished writing the header. Now write the Bloom filter. 1749480093f4SDimitry Andric for (llvm::yaml::Hex64 Val : *Section.BloomFilter) 17505ffd83dbSDimitry Andric CBA.write<uintX_t>(Val, ELFT::TargetEndianness); 1751480093f4SDimitry Andric 1752480093f4SDimitry Andric // Write an array of hash buckets. 1753480093f4SDimitry Andric for (llvm::yaml::Hex32 Val : *Section.HashBuckets) 17545ffd83dbSDimitry Andric CBA.write<uint32_t>(Val, ELFT::TargetEndianness); 1755480093f4SDimitry Andric 1756480093f4SDimitry Andric // Write an array of hash values. 1757480093f4SDimitry Andric for (llvm::yaml::Hex32 Val : *Section.HashValues) 17585ffd83dbSDimitry Andric CBA.write<uint32_t>(Val, ELFT::TargetEndianness); 1759480093f4SDimitry Andric 1760480093f4SDimitry Andric SHeader.sh_size = 16 /*Header size*/ + 1761480093f4SDimitry Andric Section.BloomFilter->size() * sizeof(typename ELFT::uint) + 1762480093f4SDimitry Andric Section.HashBuckets->size() * 4 + 1763480093f4SDimitry Andric Section.HashValues->size() * 4; 1764480093f4SDimitry Andric } 1765480093f4SDimitry Andric 1766480093f4SDimitry Andric template <class ELFT> 1767480093f4SDimitry Andric void ELFState<ELFT>::writeFill(ELFYAML::Fill &Fill, 1768480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1769480093f4SDimitry Andric size_t PatternSize = Fill.Pattern ? Fill.Pattern->binary_size() : 0; 1770480093f4SDimitry Andric if (!PatternSize) { 17715ffd83dbSDimitry Andric CBA.writeZeros(Fill.Size); 1772480093f4SDimitry Andric return; 1773480093f4SDimitry Andric } 1774480093f4SDimitry Andric 1775480093f4SDimitry Andric // Fill the content with the specified pattern. 1776480093f4SDimitry Andric uint64_t Written = 0; 1777480093f4SDimitry Andric for (; Written + PatternSize <= Fill.Size; Written += PatternSize) 17785ffd83dbSDimitry Andric CBA.writeAsBinary(*Fill.Pattern); 17795ffd83dbSDimitry Andric CBA.writeAsBinary(*Fill.Pattern, Fill.Size - Written); 17805ffd83dbSDimitry Andric } 17815ffd83dbSDimitry Andric 17825ffd83dbSDimitry Andric template <class ELFT> 17835ffd83dbSDimitry Andric DenseMap<StringRef, size_t> ELFState<ELFT>::buildSectionHeaderReorderMap() { 1784e8d8bef9SDimitry Andric const ELFYAML::SectionHeaderTable &SectionHeaders = 1785e8d8bef9SDimitry Andric Doc.getSectionHeaderTable(); 1786fe6060f1SDimitry Andric if (SectionHeaders.IsImplicit || SectionHeaders.NoHeaders || 1787fe6060f1SDimitry Andric SectionHeaders.isDefault()) 17885ffd83dbSDimitry Andric return DenseMap<StringRef, size_t>(); 17895ffd83dbSDimitry Andric 17905ffd83dbSDimitry Andric DenseMap<StringRef, size_t> Ret; 17915ffd83dbSDimitry Andric size_t SecNdx = 0; 17925ffd83dbSDimitry Andric StringSet<> Seen; 17935ffd83dbSDimitry Andric 17945ffd83dbSDimitry Andric auto AddSection = [&](const ELFYAML::SectionHeader &Hdr) { 17955ffd83dbSDimitry Andric if (!Ret.try_emplace(Hdr.Name, ++SecNdx).second) 17965ffd83dbSDimitry Andric reportError("repeated section name: '" + Hdr.Name + 17975ffd83dbSDimitry Andric "' in the section header description"); 17985ffd83dbSDimitry Andric Seen.insert(Hdr.Name); 17995ffd83dbSDimitry Andric }; 18005ffd83dbSDimitry Andric 1801e8d8bef9SDimitry Andric if (SectionHeaders.Sections) 1802e8d8bef9SDimitry Andric for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Sections) 18035ffd83dbSDimitry Andric AddSection(Hdr); 18045ffd83dbSDimitry Andric 1805e8d8bef9SDimitry Andric if (SectionHeaders.Excluded) 1806e8d8bef9SDimitry Andric for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Excluded) 18075ffd83dbSDimitry Andric AddSection(Hdr); 18085ffd83dbSDimitry Andric 18095ffd83dbSDimitry Andric for (const ELFYAML::Section *S : Doc.getSections()) { 18105ffd83dbSDimitry Andric // Ignore special first SHT_NULL section. 18115ffd83dbSDimitry Andric if (S == Doc.getSections().front()) 18125ffd83dbSDimitry Andric continue; 18135ffd83dbSDimitry Andric if (!Seen.count(S->Name)) 18145ffd83dbSDimitry Andric reportError("section '" + S->Name + 18155ffd83dbSDimitry Andric "' should be present in the 'Sections' or 'Excluded' lists"); 18165ffd83dbSDimitry Andric Seen.erase(S->Name); 18175ffd83dbSDimitry Andric } 18185ffd83dbSDimitry Andric 18195ffd83dbSDimitry Andric for (const auto &It : Seen) 18205ffd83dbSDimitry Andric reportError("section header contains undefined section '" + It.getKey() + 18215ffd83dbSDimitry Andric "'"); 18225ffd83dbSDimitry Andric return Ret; 1823480093f4SDimitry Andric } 1824480093f4SDimitry Andric 18258bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::buildSectionIndex() { 18265ffd83dbSDimitry Andric // A YAML description can have an explicit section header declaration that 18275ffd83dbSDimitry Andric // allows to change the order of section headers. 18285ffd83dbSDimitry Andric DenseMap<StringRef, size_t> ReorderMap = buildSectionHeaderReorderMap(); 18295ffd83dbSDimitry Andric 18305ffd83dbSDimitry Andric if (HasError) 18315ffd83dbSDimitry Andric return; 18325ffd83dbSDimitry Andric 18335ffd83dbSDimitry Andric // Build excluded section headers map. 18345ffd83dbSDimitry Andric std::vector<ELFYAML::Section *> Sections = Doc.getSections(); 1835e8d8bef9SDimitry Andric const ELFYAML::SectionHeaderTable &SectionHeaders = 1836e8d8bef9SDimitry Andric Doc.getSectionHeaderTable(); 1837e8d8bef9SDimitry Andric if (SectionHeaders.Excluded) 1838e8d8bef9SDimitry Andric for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Excluded) 18395ffd83dbSDimitry Andric if (!ExcludedSectionHeaders.insert(Hdr.Name).second) 18405ffd83dbSDimitry Andric llvm_unreachable("buildSectionIndex() failed"); 18415ffd83dbSDimitry Andric 1842*81ad6265SDimitry Andric if (SectionHeaders.NoHeaders.value_or(false)) 18435ffd83dbSDimitry Andric for (const ELFYAML::Section *S : Sections) 18445ffd83dbSDimitry Andric if (!ExcludedSectionHeaders.insert(S->Name).second) 18455ffd83dbSDimitry Andric llvm_unreachable("buildSectionIndex() failed"); 18465ffd83dbSDimitry Andric 1847480093f4SDimitry Andric size_t SecNdx = -1; 18485ffd83dbSDimitry Andric for (const ELFYAML::Section *S : Sections) { 1849480093f4SDimitry Andric ++SecNdx; 1850480093f4SDimitry Andric 18515ffd83dbSDimitry Andric size_t Index = ReorderMap.empty() ? SecNdx : ReorderMap.lookup(S->Name); 18525ffd83dbSDimitry Andric if (!SN2I.addName(S->Name, Index)) 1853480093f4SDimitry Andric llvm_unreachable("buildSectionIndex() failed"); 18545ffd83dbSDimitry Andric 18555ffd83dbSDimitry Andric if (!ExcludedSectionHeaders.count(S->Name)) 1856fe6060f1SDimitry Andric ShStrtabStrings->add(ELFYAML::dropUniqueSuffix(S->Name)); 18578bcb0991SDimitry Andric } 18588bcb0991SDimitry Andric } 18598bcb0991SDimitry Andric 18608bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::buildSymbolIndexes() { 18618bcb0991SDimitry Andric auto Build = [this](ArrayRef<ELFYAML::Symbol> V, NameToIdxMap &Map) { 18628bcb0991SDimitry Andric for (size_t I = 0, S = V.size(); I < S; ++I) { 18638bcb0991SDimitry Andric const ELFYAML::Symbol &Sym = V[I]; 18648bcb0991SDimitry Andric if (!Sym.Name.empty() && !Map.addName(Sym.Name, I + 1)) 18658bcb0991SDimitry Andric reportError("repeated symbol name: '" + Sym.Name + "'"); 18668bcb0991SDimitry Andric } 18678bcb0991SDimitry Andric }; 18688bcb0991SDimitry Andric 18698bcb0991SDimitry Andric if (Doc.Symbols) 18708bcb0991SDimitry Andric Build(*Doc.Symbols, SymN2I); 1871480093f4SDimitry Andric if (Doc.DynamicSymbols) 1872480093f4SDimitry Andric Build(*Doc.DynamicSymbols, DynSymN2I); 18738bcb0991SDimitry Andric } 18748bcb0991SDimitry Andric 18758bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::finalizeStrings() { 18768bcb0991SDimitry Andric // Add the regular symbol names to .strtab section. 18778bcb0991SDimitry Andric if (Doc.Symbols) 18788bcb0991SDimitry Andric for (const ELFYAML::Symbol &Sym : *Doc.Symbols) 18798bcb0991SDimitry Andric DotStrtab.add(ELFYAML::dropUniqueSuffix(Sym.Name)); 18808bcb0991SDimitry Andric DotStrtab.finalize(); 18818bcb0991SDimitry Andric 18828bcb0991SDimitry Andric // Add the dynamic symbol names to .dynstr section. 1883480093f4SDimitry Andric if (Doc.DynamicSymbols) 1884480093f4SDimitry Andric for (const ELFYAML::Symbol &Sym : *Doc.DynamicSymbols) 18858bcb0991SDimitry Andric DotDynstr.add(ELFYAML::dropUniqueSuffix(Sym.Name)); 18868bcb0991SDimitry Andric 18878bcb0991SDimitry Andric // SHT_GNU_verdef and SHT_GNU_verneed sections might also 18888bcb0991SDimitry Andric // add strings to .dynstr section. 1889480093f4SDimitry Andric for (const ELFYAML::Chunk *Sec : Doc.getSections()) { 1890480093f4SDimitry Andric if (auto VerNeed = dyn_cast<ELFYAML::VerneedSection>(Sec)) { 1891480093f4SDimitry Andric if (VerNeed->VerneedV) { 1892480093f4SDimitry Andric for (const ELFYAML::VerneedEntry &VE : *VerNeed->VerneedV) { 18938bcb0991SDimitry Andric DotDynstr.add(VE.File); 18948bcb0991SDimitry Andric for (const ELFYAML::VernauxEntry &Aux : VE.AuxV) 18958bcb0991SDimitry Andric DotDynstr.add(Aux.Name); 18968bcb0991SDimitry Andric } 1897480093f4SDimitry Andric } 1898480093f4SDimitry Andric } else if (auto VerDef = dyn_cast<ELFYAML::VerdefSection>(Sec)) { 1899480093f4SDimitry Andric if (VerDef->Entries) 1900480093f4SDimitry Andric for (const ELFYAML::VerdefEntry &E : *VerDef->Entries) 19018bcb0991SDimitry Andric for (StringRef Name : E.VerNames) 19028bcb0991SDimitry Andric DotDynstr.add(Name); 19038bcb0991SDimitry Andric } 19048bcb0991SDimitry Andric } 19058bcb0991SDimitry Andric 19068bcb0991SDimitry Andric DotDynstr.finalize(); 1907fe6060f1SDimitry Andric 1908fe6060f1SDimitry Andric // Don't finalize the section header string table a second time if it has 1909fe6060f1SDimitry Andric // already been finalized due to being one of the symbol string tables. 1910fe6060f1SDimitry Andric if (ShStrtabStrings != &DotStrtab && ShStrtabStrings != &DotDynstr) 1911fe6060f1SDimitry Andric ShStrtabStrings->finalize(); 19128bcb0991SDimitry Andric } 19138bcb0991SDimitry Andric 19148bcb0991SDimitry Andric template <class ELFT> 19158bcb0991SDimitry Andric bool ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc, 19165ffd83dbSDimitry Andric yaml::ErrorHandler EH, uint64_t MaxSize) { 19178bcb0991SDimitry Andric ELFState<ELFT> State(Doc, EH); 19185ffd83dbSDimitry Andric if (State.HasError) 19195ffd83dbSDimitry Andric return false; 19208bcb0991SDimitry Andric 1921fe6060f1SDimitry Andric // Build the section index, which adds sections to the section header string 1922fe6060f1SDimitry Andric // table first, so that we can finalize the section header string table. 19238bcb0991SDimitry Andric State.buildSectionIndex(); 19245ffd83dbSDimitry Andric State.buildSymbolIndexes(); 19255ffd83dbSDimitry Andric 1926fe6060f1SDimitry Andric // Finalize section header string table and the .strtab and .dynstr sections. 1927fe6060f1SDimitry Andric // We do this early because we want to finalize the string table builders 1928fe6060f1SDimitry Andric // before writing the content of the sections that might want to use them. 1929fe6060f1SDimitry Andric State.finalizeStrings(); 1930fe6060f1SDimitry Andric 1931480093f4SDimitry Andric if (State.HasError) 1932480093f4SDimitry Andric return false; 1933480093f4SDimitry Andric 19348bcb0991SDimitry Andric std::vector<Elf_Phdr> PHeaders; 19358bcb0991SDimitry Andric State.initProgramHeaders(PHeaders); 19368bcb0991SDimitry Andric 19378bcb0991SDimitry Andric // XXX: This offset is tightly coupled with the order that we write 19388bcb0991SDimitry Andric // things to `OS`. 19398bcb0991SDimitry Andric const size_t SectionContentBeginOffset = 19408bcb0991SDimitry Andric sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * Doc.ProgramHeaders.size(); 19415ffd83dbSDimitry Andric // It is quite easy to accidentally create output with yaml2obj that is larger 19425ffd83dbSDimitry Andric // than intended, for example, due to an issue in the YAML description. 19435ffd83dbSDimitry Andric // We limit the maximum allowed output size, but also provide a command line 19445ffd83dbSDimitry Andric // option to change this limitation. 19455ffd83dbSDimitry Andric ContiguousBlobAccumulator CBA(SectionContentBeginOffset, MaxSize); 19468bcb0991SDimitry Andric 19478bcb0991SDimitry Andric std::vector<Elf_Shdr> SHeaders; 19488bcb0991SDimitry Andric State.initSectionHeaders(SHeaders, CBA); 19498bcb0991SDimitry Andric 1950480093f4SDimitry Andric // Now we can decide segment offsets. 19518bcb0991SDimitry Andric State.setProgramHeaderLayout(PHeaders, SHeaders); 19528bcb0991SDimitry Andric 1953e8d8bef9SDimitry Andric bool ReachedLimit = CBA.getOffset() > MaxSize; 19545ffd83dbSDimitry Andric if (Error E = CBA.takeLimitError()) { 19555ffd83dbSDimitry Andric // We report a custom error message instead below. 19565ffd83dbSDimitry Andric consumeError(std::move(E)); 19575ffd83dbSDimitry Andric ReachedLimit = true; 19585ffd83dbSDimitry Andric } 19595ffd83dbSDimitry Andric 19605ffd83dbSDimitry Andric if (ReachedLimit) 19615ffd83dbSDimitry Andric State.reportError( 19625ffd83dbSDimitry Andric "the desired output size is greater than permitted. Use the " 19635ffd83dbSDimitry Andric "--max-size option to change the limit"); 19645ffd83dbSDimitry Andric 19658bcb0991SDimitry Andric if (State.HasError) 19668bcb0991SDimitry Andric return false; 19678bcb0991SDimitry Andric 1968e8d8bef9SDimitry Andric State.writeELFHeader(OS); 19698bcb0991SDimitry Andric writeArrayData(OS, makeArrayRef(PHeaders)); 1970e8d8bef9SDimitry Andric 1971e8d8bef9SDimitry Andric const ELFYAML::SectionHeaderTable &SHT = Doc.getSectionHeaderTable(); 1972*81ad6265SDimitry Andric if (!SHT.NoHeaders.value_or(false)) 1973e8d8bef9SDimitry Andric CBA.updateDataAt(*SHT.Offset, SHeaders.data(), 1974e8d8bef9SDimitry Andric SHT.getNumHeaders(SHeaders.size()) * sizeof(Elf_Shdr)); 1975e8d8bef9SDimitry Andric 19768bcb0991SDimitry Andric CBA.writeBlobToStream(OS); 19778bcb0991SDimitry Andric return true; 19788bcb0991SDimitry Andric } 19798bcb0991SDimitry Andric 19808bcb0991SDimitry Andric namespace llvm { 19818bcb0991SDimitry Andric namespace yaml { 19828bcb0991SDimitry Andric 19835ffd83dbSDimitry Andric bool yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH, 19845ffd83dbSDimitry Andric uint64_t MaxSize) { 19858bcb0991SDimitry Andric bool IsLE = Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB); 19868bcb0991SDimitry Andric bool Is64Bit = Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64); 19878bcb0991SDimitry Andric if (Is64Bit) { 19888bcb0991SDimitry Andric if (IsLE) 19895ffd83dbSDimitry Andric return ELFState<object::ELF64LE>::writeELF(Out, Doc, EH, MaxSize); 19905ffd83dbSDimitry Andric return ELFState<object::ELF64BE>::writeELF(Out, Doc, EH, MaxSize); 19918bcb0991SDimitry Andric } 19928bcb0991SDimitry Andric if (IsLE) 19935ffd83dbSDimitry Andric return ELFState<object::ELF32LE>::writeELF(Out, Doc, EH, MaxSize); 19945ffd83dbSDimitry Andric return ELFState<object::ELF32BE>::writeELF(Out, Doc, EH, MaxSize); 19958bcb0991SDimitry Andric } 19968bcb0991SDimitry Andric 19978bcb0991SDimitry Andric } // namespace yaml 19988bcb0991SDimitry Andric } // namespace llvm 1999