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" 34bdd1243dSDimitry Andric #include <optional> 35*5f757f3fSDimitry Andric #include <variant> 368bcb0991SDimitry Andric 378bcb0991SDimitry Andric using namespace llvm; 388bcb0991SDimitry Andric 398bcb0991SDimitry Andric // This class is used to build up a contiguous binary blob while keeping 408bcb0991SDimitry Andric // track of an offset in the output (which notionally begins at 418bcb0991SDimitry Andric // `InitialOffset`). 425ffd83dbSDimitry Andric // The blob might be limited to an arbitrary size. All attempts to write data 435ffd83dbSDimitry Andric // are ignored and the error condition is remembered once the limit is reached. 445ffd83dbSDimitry Andric // Such an approach allows us to simplify the code by delaying error reporting 455ffd83dbSDimitry Andric // and doing it at a convenient time. 468bcb0991SDimitry Andric namespace { 478bcb0991SDimitry Andric class ContiguousBlobAccumulator { 488bcb0991SDimitry Andric const uint64_t InitialOffset; 495ffd83dbSDimitry Andric const uint64_t MaxSize; 505ffd83dbSDimitry Andric 518bcb0991SDimitry Andric SmallVector<char, 128> Buf; 528bcb0991SDimitry Andric raw_svector_ostream OS; 535ffd83dbSDimitry Andric Error ReachedLimitErr = Error::success(); 545ffd83dbSDimitry Andric 555ffd83dbSDimitry Andric bool checkLimit(uint64_t Size) { 565ffd83dbSDimitry Andric if (!ReachedLimitErr && getOffset() + Size <= MaxSize) 575ffd83dbSDimitry Andric return true; 585ffd83dbSDimitry Andric if (!ReachedLimitErr) 595ffd83dbSDimitry Andric ReachedLimitErr = createStringError(errc::invalid_argument, 605ffd83dbSDimitry Andric "reached the output size limit"); 615ffd83dbSDimitry Andric return false; 625ffd83dbSDimitry Andric } 638bcb0991SDimitry Andric 64480093f4SDimitry Andric public: 655ffd83dbSDimitry Andric ContiguousBlobAccumulator(uint64_t BaseOffset, uint64_t SizeLimit) 665ffd83dbSDimitry Andric : InitialOffset(BaseOffset), MaxSize(SizeLimit), OS(Buf) {} 67480093f4SDimitry Andric 685ffd83dbSDimitry Andric uint64_t tell() const { return OS.tell(); } 695ffd83dbSDimitry Andric uint64_t getOffset() const { return InitialOffset + OS.tell(); } 705ffd83dbSDimitry Andric void writeBlobToStream(raw_ostream &Out) const { Out << OS.str(); } 715ffd83dbSDimitry Andric 725ffd83dbSDimitry Andric Error takeLimitError() { 735ffd83dbSDimitry Andric // Request to write 0 bytes to check we did not reach the limit. 745ffd83dbSDimitry Andric checkLimit(0); 755ffd83dbSDimitry Andric return std::move(ReachedLimitErr); 76480093f4SDimitry Andric } 77480093f4SDimitry Andric 788bcb0991SDimitry Andric /// \returns The new offset. 798bcb0991SDimitry Andric uint64_t padToAlignment(unsigned Align) { 805ffd83dbSDimitry Andric uint64_t CurrentOffset = getOffset(); 815ffd83dbSDimitry Andric if (ReachedLimitErr) 825ffd83dbSDimitry Andric return CurrentOffset; 835ffd83dbSDimitry Andric 845ffd83dbSDimitry Andric uint64_t AlignedOffset = alignTo(CurrentOffset, Align == 0 ? 1 : Align); 855ffd83dbSDimitry Andric uint64_t PaddingSize = AlignedOffset - CurrentOffset; 865ffd83dbSDimitry Andric if (!checkLimit(PaddingSize)) 875ffd83dbSDimitry Andric return CurrentOffset; 885ffd83dbSDimitry Andric 895ffd83dbSDimitry Andric writeZeros(PaddingSize); 905ffd83dbSDimitry Andric return AlignedOffset; 918bcb0991SDimitry Andric } 928bcb0991SDimitry Andric 935ffd83dbSDimitry Andric raw_ostream *getRawOS(uint64_t Size) { 945ffd83dbSDimitry Andric if (checkLimit(Size)) 955ffd83dbSDimitry Andric return &OS; 965ffd83dbSDimitry Andric return nullptr; 975ffd83dbSDimitry Andric } 985ffd83dbSDimitry Andric 995ffd83dbSDimitry Andric void writeAsBinary(const yaml::BinaryRef &Bin, uint64_t N = UINT64_MAX) { 1005ffd83dbSDimitry Andric if (!checkLimit(Bin.binary_size())) 1015ffd83dbSDimitry Andric return; 1025ffd83dbSDimitry Andric Bin.writeAsBinary(OS, N); 1035ffd83dbSDimitry Andric } 1045ffd83dbSDimitry Andric 1055ffd83dbSDimitry Andric void writeZeros(uint64_t Num) { 1065ffd83dbSDimitry Andric if (checkLimit(Num)) 1075ffd83dbSDimitry Andric OS.write_zeros(Num); 1085ffd83dbSDimitry Andric } 1095ffd83dbSDimitry Andric 1105ffd83dbSDimitry Andric void write(const char *Ptr, size_t Size) { 1115ffd83dbSDimitry Andric if (checkLimit(Size)) 1125ffd83dbSDimitry Andric OS.write(Ptr, Size); 1135ffd83dbSDimitry Andric } 1145ffd83dbSDimitry Andric 1155ffd83dbSDimitry Andric void write(unsigned char C) { 1165ffd83dbSDimitry Andric if (checkLimit(1)) 1175ffd83dbSDimitry Andric OS.write(C); 1185ffd83dbSDimitry Andric } 1195ffd83dbSDimitry Andric 1205ffd83dbSDimitry Andric unsigned writeULEB128(uint64_t Val) { 1215ffd83dbSDimitry Andric if (!checkLimit(sizeof(uint64_t))) 1225ffd83dbSDimitry Andric return 0; 1235ffd83dbSDimitry Andric return encodeULEB128(Val, OS); 1245ffd83dbSDimitry Andric } 1255ffd83dbSDimitry Andric 126*5f757f3fSDimitry Andric template <typename T> void write(T Val, llvm::endianness E) { 1275ffd83dbSDimitry Andric if (checkLimit(sizeof(T))) 1285ffd83dbSDimitry Andric support::endian::write<T>(OS, Val, E); 1295ffd83dbSDimitry Andric } 130e8d8bef9SDimitry Andric 131e8d8bef9SDimitry Andric void updateDataAt(uint64_t Pos, void *Data, size_t Size) { 132e8d8bef9SDimitry Andric assert(Pos >= InitialOffset && Pos + Size <= getOffset()); 133e8d8bef9SDimitry Andric memcpy(&Buf[Pos - InitialOffset], Data, Size); 134e8d8bef9SDimitry Andric } 1358bcb0991SDimitry Andric }; 1368bcb0991SDimitry Andric 1378bcb0991SDimitry Andric // Used to keep track of section and symbol names, so that in the YAML file 1388bcb0991SDimitry Andric // sections and symbols can be referenced by name instead of by index. 1398bcb0991SDimitry Andric class NameToIdxMap { 1408bcb0991SDimitry Andric StringMap<unsigned> Map; 1418bcb0991SDimitry Andric 1428bcb0991SDimitry Andric public: 1438bcb0991SDimitry Andric /// \Returns false if name is already present in the map. 1448bcb0991SDimitry Andric bool addName(StringRef Name, unsigned Ndx) { 1458bcb0991SDimitry Andric return Map.insert({Name, Ndx}).second; 1468bcb0991SDimitry Andric } 1478bcb0991SDimitry Andric /// \Returns false if name is not present in the map. 1488bcb0991SDimitry Andric bool lookup(StringRef Name, unsigned &Idx) const { 1498bcb0991SDimitry Andric auto I = Map.find(Name); 1508bcb0991SDimitry Andric if (I == Map.end()) 1518bcb0991SDimitry Andric return false; 1528bcb0991SDimitry Andric Idx = I->getValue(); 1538bcb0991SDimitry Andric return true; 1548bcb0991SDimitry Andric } 1558bcb0991SDimitry Andric /// Asserts if name is not present in the map. 1568bcb0991SDimitry Andric unsigned get(StringRef Name) const { 1578bcb0991SDimitry Andric unsigned Idx; 1588bcb0991SDimitry Andric if (lookup(Name, Idx)) 1598bcb0991SDimitry Andric return Idx; 1608bcb0991SDimitry Andric assert(false && "Expected section not found in index"); 1618bcb0991SDimitry Andric return 0; 1628bcb0991SDimitry Andric } 1638bcb0991SDimitry Andric unsigned size() const { return Map.size(); } 1648bcb0991SDimitry Andric }; 1658bcb0991SDimitry Andric 166480093f4SDimitry Andric namespace { 167480093f4SDimitry Andric struct Fragment { 168480093f4SDimitry Andric uint64_t Offset; 169480093f4SDimitry Andric uint64_t Size; 170480093f4SDimitry Andric uint32_t Type; 171480093f4SDimitry Andric uint64_t AddrAlign; 172480093f4SDimitry Andric }; 173480093f4SDimitry Andric } // namespace 174480093f4SDimitry Andric 1758bcb0991SDimitry Andric /// "Single point of truth" for the ELF file construction. 1768bcb0991SDimitry Andric /// TODO: This class still has a ways to go before it is truly a "single 1778bcb0991SDimitry Andric /// point of truth". 1788bcb0991SDimitry Andric template <class ELFT> class ELFState { 179e8d8bef9SDimitry Andric LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 1808bcb0991SDimitry Andric 1818bcb0991SDimitry Andric enum class SymtabType { Static, Dynamic }; 1828bcb0991SDimitry Andric 183fe6060f1SDimitry Andric /// The future symbol table string section. 1848bcb0991SDimitry Andric StringTableBuilder DotStrtab{StringTableBuilder::ELF}; 1858bcb0991SDimitry Andric 186fe6060f1SDimitry Andric /// The future section header string table section, if a unique string table 187fe6060f1SDimitry Andric /// is needed. Don't reference this variable direectly: use the 188fe6060f1SDimitry Andric /// ShStrtabStrings member instead. 1898bcb0991SDimitry Andric StringTableBuilder DotShStrtab{StringTableBuilder::ELF}; 1908bcb0991SDimitry Andric 191fe6060f1SDimitry Andric /// The future dynamic symbol string section. 1928bcb0991SDimitry Andric StringTableBuilder DotDynstr{StringTableBuilder::ELF}; 1938bcb0991SDimitry Andric 194fe6060f1SDimitry Andric /// The name of the section header string table section. If it is .strtab or 195fe6060f1SDimitry Andric /// .dynstr, the section header strings will be written to the same string 196fe6060f1SDimitry Andric /// table as the static/dynamic symbols respectively. Otherwise a dedicated 197fe6060f1SDimitry Andric /// section will be created with that name. 198fe6060f1SDimitry Andric StringRef SectionHeaderStringTableName = ".shstrtab"; 199fe6060f1SDimitry Andric StringTableBuilder *ShStrtabStrings = &DotShStrtab; 200fe6060f1SDimitry Andric 2018bcb0991SDimitry Andric NameToIdxMap SN2I; 2028bcb0991SDimitry Andric NameToIdxMap SymN2I; 2038bcb0991SDimitry Andric NameToIdxMap DynSymN2I; 2048bcb0991SDimitry Andric ELFYAML::Object &Doc; 2058bcb0991SDimitry Andric 2065ffd83dbSDimitry Andric StringSet<> ExcludedSectionHeaders; 2075ffd83dbSDimitry Andric 2085ffd83dbSDimitry Andric uint64_t LocationCounter = 0; 2098bcb0991SDimitry Andric bool HasError = false; 2108bcb0991SDimitry Andric yaml::ErrorHandler ErrHandler; 2118bcb0991SDimitry Andric void reportError(const Twine &Msg); 2125ffd83dbSDimitry Andric void reportError(Error Err); 2138bcb0991SDimitry Andric 2148bcb0991SDimitry Andric std::vector<Elf_Sym> toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols, 2158bcb0991SDimitry Andric const StringTableBuilder &Strtab); 2168bcb0991SDimitry Andric unsigned toSectionIndex(StringRef S, StringRef LocSec, StringRef LocSym = ""); 2178bcb0991SDimitry Andric unsigned toSymbolIndex(StringRef S, StringRef LocSec, bool IsDynamic); 2188bcb0991SDimitry Andric 2198bcb0991SDimitry Andric void buildSectionIndex(); 2208bcb0991SDimitry Andric void buildSymbolIndexes(); 2218bcb0991SDimitry Andric void initProgramHeaders(std::vector<Elf_Phdr> &PHeaders); 2228bcb0991SDimitry Andric bool initImplicitHeader(ContiguousBlobAccumulator &CBA, Elf_Shdr &Header, 2238bcb0991SDimitry Andric StringRef SecName, ELFYAML::Section *YAMLSec); 2248bcb0991SDimitry Andric void initSectionHeaders(std::vector<Elf_Shdr> &SHeaders, 2258bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2268bcb0991SDimitry Andric void initSymtabSectionHeader(Elf_Shdr &SHeader, SymtabType STType, 2278bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 2288bcb0991SDimitry Andric ELFYAML::Section *YAMLSec); 2298bcb0991SDimitry Andric void initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name, 2308bcb0991SDimitry Andric StringTableBuilder &STB, 2318bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 2328bcb0991SDimitry Andric ELFYAML::Section *YAMLSec); 2335ffd83dbSDimitry Andric void initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name, 2345ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA, 2355ffd83dbSDimitry Andric ELFYAML::Section *YAMLSec); 2368bcb0991SDimitry Andric void setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders, 2378bcb0991SDimitry Andric std::vector<Elf_Shdr> &SHeaders); 238480093f4SDimitry Andric 239480093f4SDimitry Andric std::vector<Fragment> 240480093f4SDimitry Andric getPhdrFragments(const ELFYAML::ProgramHeader &Phdr, 241480093f4SDimitry Andric ArrayRef<typename ELFT::Shdr> SHeaders); 242480093f4SDimitry Andric 2438bcb0991SDimitry Andric void finalizeStrings(); 244e8d8bef9SDimitry Andric void writeELFHeader(raw_ostream &OS); 2455ffd83dbSDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2465ffd83dbSDimitry Andric const ELFYAML::NoBitsSection &Section, 2475ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA); 2488bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2498bcb0991SDimitry Andric const ELFYAML::RawContentSection &Section, 2508bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2518bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2528bcb0991SDimitry Andric const ELFYAML::RelocationSection &Section, 2538bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 254480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 255480093f4SDimitry Andric const ELFYAML::RelrSection &Section, 256480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 257e8d8bef9SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 258e8d8bef9SDimitry Andric const ELFYAML::GroupSection &Group, 2598bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2608bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2618bcb0991SDimitry Andric const ELFYAML::SymtabShndxSection &Shndx, 2628bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2638bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2648bcb0991SDimitry Andric const ELFYAML::SymverSection &Section, 2658bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2668bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2678bcb0991SDimitry Andric const ELFYAML::VerneedSection &Section, 2688bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2698bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2708bcb0991SDimitry Andric const ELFYAML::VerdefSection &Section, 2718bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2728bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 273e8d8bef9SDimitry Andric const ELFYAML::ARMIndexTableSection &Section, 274e8d8bef9SDimitry Andric ContiguousBlobAccumulator &CBA); 275e8d8bef9SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2768bcb0991SDimitry Andric const ELFYAML::MipsABIFlags &Section, 2778bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2788bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2798bcb0991SDimitry Andric const ELFYAML::DynamicSection &Section, 2808bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2818bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2828bcb0991SDimitry Andric const ELFYAML::StackSizesSection &Section, 2838bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2848bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 285e8d8bef9SDimitry Andric const ELFYAML::BBAddrMapSection &Section, 286e8d8bef9SDimitry Andric ContiguousBlobAccumulator &CBA); 287e8d8bef9SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2888bcb0991SDimitry Andric const ELFYAML::HashSection &Section, 2898bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2908bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2918bcb0991SDimitry Andric const ELFYAML::AddrsigSection &Section, 2928bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 293480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 294480093f4SDimitry Andric const ELFYAML::NoteSection &Section, 295480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 296480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 297480093f4SDimitry Andric const ELFYAML::GnuHashSection &Section, 298480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 299480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 300480093f4SDimitry Andric const ELFYAML::LinkerOptionsSection &Section, 301480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 302480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 303480093f4SDimitry Andric const ELFYAML::DependentLibrariesSection &Section, 304480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 3055ffd83dbSDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 3065ffd83dbSDimitry Andric const ELFYAML::CallGraphProfileSection &Section, 3075ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA); 308480093f4SDimitry Andric 309480093f4SDimitry Andric void writeFill(ELFYAML::Fill &Fill, ContiguousBlobAccumulator &CBA); 3108bcb0991SDimitry Andric 3118bcb0991SDimitry Andric ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH); 3128bcb0991SDimitry Andric 3135ffd83dbSDimitry Andric void assignSectionAddress(Elf_Shdr &SHeader, ELFYAML::Section *YAMLSec); 3145ffd83dbSDimitry Andric 3155ffd83dbSDimitry Andric DenseMap<StringRef, size_t> buildSectionHeaderReorderMap(); 3165ffd83dbSDimitry Andric 3175ffd83dbSDimitry Andric BumpPtrAllocator StringAlloc; 3185ffd83dbSDimitry Andric uint64_t alignToOffset(ContiguousBlobAccumulator &CBA, uint64_t Align, 319bdd1243dSDimitry Andric std::optional<llvm::yaml::Hex64> Offset); 3205ffd83dbSDimitry Andric 3215ffd83dbSDimitry Andric uint64_t getSectionNameOffset(StringRef Name); 3225ffd83dbSDimitry Andric 3238bcb0991SDimitry Andric public: 3248bcb0991SDimitry Andric static bool writeELF(raw_ostream &OS, ELFYAML::Object &Doc, 3255ffd83dbSDimitry Andric yaml::ErrorHandler EH, uint64_t MaxSize); 3268bcb0991SDimitry Andric }; 3278bcb0991SDimitry Andric } // end anonymous namespace 3288bcb0991SDimitry Andric 3298bcb0991SDimitry Andric template <class T> static size_t arrayDataSize(ArrayRef<T> A) { 3308bcb0991SDimitry Andric return A.size() * sizeof(T); 3318bcb0991SDimitry Andric } 3328bcb0991SDimitry Andric 3338bcb0991SDimitry Andric template <class T> static void writeArrayData(raw_ostream &OS, ArrayRef<T> A) { 3348bcb0991SDimitry Andric OS.write((const char *)A.data(), arrayDataSize(A)); 3358bcb0991SDimitry Andric } 3368bcb0991SDimitry Andric 3378bcb0991SDimitry Andric template <class T> static void zero(T &Obj) { memset(&Obj, 0, sizeof(Obj)); } 3388bcb0991SDimitry Andric 3398bcb0991SDimitry Andric template <class ELFT> 3408bcb0991SDimitry Andric ELFState<ELFT>::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH) 3418bcb0991SDimitry Andric : Doc(D), ErrHandler(EH) { 342fe6060f1SDimitry Andric // The input may explicitly request to store the section header table strings 343fe6060f1SDimitry Andric // in the same string table as dynamic or static symbol names. Set the 344fe6060f1SDimitry Andric // ShStrtabStrings member accordingly. 345fe6060f1SDimitry Andric if (Doc.Header.SectionHeaderStringTable) { 346fe6060f1SDimitry Andric SectionHeaderStringTableName = *Doc.Header.SectionHeaderStringTable; 347fe6060f1SDimitry Andric if (*Doc.Header.SectionHeaderStringTable == ".strtab") 348fe6060f1SDimitry Andric ShStrtabStrings = &DotStrtab; 349fe6060f1SDimitry Andric else if (*Doc.Header.SectionHeaderStringTable == ".dynstr") 350fe6060f1SDimitry Andric ShStrtabStrings = &DotDynstr; 351fe6060f1SDimitry Andric // Otherwise, the unique table will be used. 352fe6060f1SDimitry Andric } 353fe6060f1SDimitry Andric 354480093f4SDimitry Andric std::vector<ELFYAML::Section *> Sections = Doc.getSections(); 3558bcb0991SDimitry Andric // Insert SHT_NULL section implicitly when it is not defined in YAML. 356480093f4SDimitry Andric if (Sections.empty() || Sections.front()->Type != ELF::SHT_NULL) 357480093f4SDimitry Andric Doc.Chunks.insert( 358480093f4SDimitry Andric Doc.Chunks.begin(), 3598bcb0991SDimitry Andric std::make_unique<ELFYAML::Section>( 360480093f4SDimitry Andric ELFYAML::Chunk::ChunkKind::RawContent, /*IsImplicit=*/true)); 3618bcb0991SDimitry Andric 3625ffd83dbSDimitry Andric StringSet<> DocSections; 363e8d8bef9SDimitry Andric ELFYAML::SectionHeaderTable *SecHdrTable = nullptr; 3645ffd83dbSDimitry Andric for (size_t I = 0; I < Doc.Chunks.size(); ++I) { 3655ffd83dbSDimitry Andric const std::unique_ptr<ELFYAML::Chunk> &C = Doc.Chunks[I]; 366e8d8bef9SDimitry Andric 367e8d8bef9SDimitry Andric // We might have an explicit section header table declaration. 368e8d8bef9SDimitry Andric if (auto S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get())) { 369e8d8bef9SDimitry Andric if (SecHdrTable) 370e8d8bef9SDimitry Andric reportError("multiple section header tables are not allowed"); 371e8d8bef9SDimitry Andric SecHdrTable = S; 372e8d8bef9SDimitry Andric continue; 373e8d8bef9SDimitry Andric } 374e8d8bef9SDimitry Andric 375e8d8bef9SDimitry Andric // We add a technical suffix for each unnamed section/fill. It does not 376e8d8bef9SDimitry Andric // affect the output, but allows us to map them by name in the code and 377e8d8bef9SDimitry Andric // report better error messages. 3785ffd83dbSDimitry Andric if (C->Name.empty()) { 3795ffd83dbSDimitry Andric std::string NewName = ELFYAML::appendUniqueSuffix( 3805ffd83dbSDimitry Andric /*Name=*/"", "index " + Twine(I)); 3815ffd83dbSDimitry Andric C->Name = StringRef(NewName).copy(StringAlloc); 3825ffd83dbSDimitry Andric assert(ELFYAML::dropUniqueSuffix(C->Name).empty()); 3835ffd83dbSDimitry Andric } 3848bcb0991SDimitry Andric 3855ffd83dbSDimitry Andric if (!DocSections.insert(C->Name).second) 3865ffd83dbSDimitry Andric reportError("repeated section/fill name: '" + C->Name + 3875ffd83dbSDimitry Andric "' at YAML section/fill number " + Twine(I)); 3885ffd83dbSDimitry Andric } 3895ffd83dbSDimitry Andric 390fe6060f1SDimitry Andric SmallSetVector<StringRef, 8> ImplicitSections; 391fe6060f1SDimitry Andric if (Doc.DynamicSymbols) { 392fe6060f1SDimitry Andric if (SectionHeaderStringTableName == ".dynsym") 393fe6060f1SDimitry Andric reportError("cannot use '.dynsym' as the section header name table when " 394fe6060f1SDimitry Andric "there are dynamic symbols"); 395fe6060f1SDimitry Andric ImplicitSections.insert(".dynsym"); 396fe6060f1SDimitry Andric ImplicitSections.insert(".dynstr"); 397fe6060f1SDimitry Andric } 398fe6060f1SDimitry Andric if (Doc.Symbols) { 399fe6060f1SDimitry Andric if (SectionHeaderStringTableName == ".symtab") 400fe6060f1SDimitry Andric reportError("cannot use '.symtab' as the section header name table when " 401fe6060f1SDimitry Andric "there are symbols"); 402fe6060f1SDimitry Andric ImplicitSections.insert(".symtab"); 403fe6060f1SDimitry Andric } 4045ffd83dbSDimitry Andric if (Doc.DWARF) 405e8d8bef9SDimitry Andric for (StringRef DebugSecName : Doc.DWARF->getNonEmptySectionNames()) { 4065ffd83dbSDimitry Andric std::string SecName = ("." + DebugSecName).str(); 407fe6060f1SDimitry Andric // TODO: For .debug_str it should be possible to share the string table, 408fe6060f1SDimitry Andric // in the same manner as the symbol string tables. 409fe6060f1SDimitry Andric if (SectionHeaderStringTableName == SecName) 410fe6060f1SDimitry Andric reportError("cannot use '" + SecName + 411fe6060f1SDimitry Andric "' as the section header name table when it is needed for " 412fe6060f1SDimitry Andric "DWARF output"); 413fe6060f1SDimitry Andric ImplicitSections.insert(StringRef(SecName).copy(StringAlloc)); 4145ffd83dbSDimitry Andric } 415fe6060f1SDimitry Andric // TODO: Only create the .strtab here if any symbols have been requested. 416fe6060f1SDimitry Andric ImplicitSections.insert(".strtab"); 41781ad6265SDimitry Andric if (!SecHdrTable || !SecHdrTable->NoHeaders.value_or(false)) 418fe6060f1SDimitry Andric ImplicitSections.insert(SectionHeaderStringTableName); 4198bcb0991SDimitry Andric 4208bcb0991SDimitry Andric // Insert placeholders for implicit sections that are not 4218bcb0991SDimitry Andric // defined explicitly in YAML. 4228bcb0991SDimitry Andric for (StringRef SecName : ImplicitSections) { 4238bcb0991SDimitry Andric if (DocSections.count(SecName)) 4248bcb0991SDimitry Andric continue; 4258bcb0991SDimitry Andric 426e8d8bef9SDimitry Andric std::unique_ptr<ELFYAML::Section> Sec = std::make_unique<ELFYAML::Section>( 427480093f4SDimitry Andric ELFYAML::Chunk::ChunkKind::RawContent, true /*IsImplicit*/); 4288bcb0991SDimitry Andric Sec->Name = SecName; 429e8d8bef9SDimitry Andric 430fe6060f1SDimitry Andric if (SecName == SectionHeaderStringTableName) 431fe6060f1SDimitry Andric Sec->Type = ELF::SHT_STRTAB; 432fe6060f1SDimitry Andric else if (SecName == ".dynsym") 433e8d8bef9SDimitry Andric Sec->Type = ELF::SHT_DYNSYM; 434e8d8bef9SDimitry Andric else if (SecName == ".symtab") 435e8d8bef9SDimitry Andric Sec->Type = ELF::SHT_SYMTAB; 436e8d8bef9SDimitry Andric else 437e8d8bef9SDimitry Andric Sec->Type = ELF::SHT_STRTAB; 438e8d8bef9SDimitry Andric 439e8d8bef9SDimitry Andric // When the section header table is explicitly defined at the end of the 440e8d8bef9SDimitry Andric // sections list, it is reasonable to assume that the user wants to reorder 441e8d8bef9SDimitry Andric // section headers, but still wants to place the section header table after 442e8d8bef9SDimitry Andric // all sections, like it normally happens. In this case we want to insert 443e8d8bef9SDimitry Andric // other implicit sections right before the section header table. 444e8d8bef9SDimitry Andric if (Doc.Chunks.back().get() == SecHdrTable) 445e8d8bef9SDimitry Andric Doc.Chunks.insert(Doc.Chunks.end() - 1, std::move(Sec)); 446e8d8bef9SDimitry Andric else 447480093f4SDimitry Andric Doc.Chunks.push_back(std::move(Sec)); 4488bcb0991SDimitry Andric } 449e8d8bef9SDimitry Andric 450e8d8bef9SDimitry Andric // Insert the section header table implicitly at the end, when it is not 451e8d8bef9SDimitry Andric // explicitly defined. 452e8d8bef9SDimitry Andric if (!SecHdrTable) 453e8d8bef9SDimitry Andric Doc.Chunks.push_back( 454e8d8bef9SDimitry Andric std::make_unique<ELFYAML::SectionHeaderTable>(/*IsImplicit=*/true)); 4558bcb0991SDimitry Andric } 4568bcb0991SDimitry Andric 4578bcb0991SDimitry Andric template <class ELFT> 458e8d8bef9SDimitry Andric void ELFState<ELFT>::writeELFHeader(raw_ostream &OS) { 4598bcb0991SDimitry Andric using namespace llvm::ELF; 4608bcb0991SDimitry Andric 4618bcb0991SDimitry Andric Elf_Ehdr Header; 4628bcb0991SDimitry Andric zero(Header); 4638bcb0991SDimitry Andric Header.e_ident[EI_MAG0] = 0x7f; 4648bcb0991SDimitry Andric Header.e_ident[EI_MAG1] = 'E'; 4658bcb0991SDimitry Andric Header.e_ident[EI_MAG2] = 'L'; 4668bcb0991SDimitry Andric Header.e_ident[EI_MAG3] = 'F'; 4678bcb0991SDimitry Andric Header.e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32; 4688bcb0991SDimitry Andric Header.e_ident[EI_DATA] = Doc.Header.Data; 4698bcb0991SDimitry Andric Header.e_ident[EI_VERSION] = EV_CURRENT; 4708bcb0991SDimitry Andric Header.e_ident[EI_OSABI] = Doc.Header.OSABI; 4718bcb0991SDimitry Andric Header.e_ident[EI_ABIVERSION] = Doc.Header.ABIVersion; 4728bcb0991SDimitry Andric Header.e_type = Doc.Header.Type; 473e8d8bef9SDimitry Andric 474e8d8bef9SDimitry Andric if (Doc.Header.Machine) 475e8d8bef9SDimitry Andric Header.e_machine = *Doc.Header.Machine; 476e8d8bef9SDimitry Andric else 477e8d8bef9SDimitry Andric Header.e_machine = EM_NONE; 478e8d8bef9SDimitry Andric 4798bcb0991SDimitry Andric Header.e_version = EV_CURRENT; 4808bcb0991SDimitry Andric Header.e_entry = Doc.Header.Entry; 4818bcb0991SDimitry Andric Header.e_flags = Doc.Header.Flags; 4828bcb0991SDimitry Andric Header.e_ehsize = sizeof(Elf_Ehdr); 4838bcb0991SDimitry Andric 4845ffd83dbSDimitry Andric if (Doc.Header.EPhOff) 4855ffd83dbSDimitry Andric Header.e_phoff = *Doc.Header.EPhOff; 4865ffd83dbSDimitry Andric else if (!Doc.ProgramHeaders.empty()) 4875ffd83dbSDimitry Andric Header.e_phoff = sizeof(Header); 4885ffd83dbSDimitry Andric else 4895ffd83dbSDimitry Andric Header.e_phoff = 0; 4905ffd83dbSDimitry Andric 4915ffd83dbSDimitry Andric if (Doc.Header.EPhEntSize) 4925ffd83dbSDimitry Andric Header.e_phentsize = *Doc.Header.EPhEntSize; 4935ffd83dbSDimitry Andric else if (!Doc.ProgramHeaders.empty()) 4945ffd83dbSDimitry Andric Header.e_phentsize = sizeof(Elf_Phdr); 4955ffd83dbSDimitry Andric else 4965ffd83dbSDimitry Andric Header.e_phentsize = 0; 4975ffd83dbSDimitry Andric 4985ffd83dbSDimitry Andric if (Doc.Header.EPhNum) 4995ffd83dbSDimitry Andric Header.e_phnum = *Doc.Header.EPhNum; 5005ffd83dbSDimitry Andric else if (!Doc.ProgramHeaders.empty()) 5015ffd83dbSDimitry Andric Header.e_phnum = Doc.ProgramHeaders.size(); 5025ffd83dbSDimitry Andric else 5035ffd83dbSDimitry Andric Header.e_phnum = 0; 5045ffd83dbSDimitry Andric 5055ffd83dbSDimitry Andric Header.e_shentsize = Doc.Header.EShEntSize ? (uint16_t)*Doc.Header.EShEntSize 5065ffd83dbSDimitry Andric : sizeof(Elf_Shdr); 5075ffd83dbSDimitry Andric 508e8d8bef9SDimitry Andric const ELFYAML::SectionHeaderTable &SectionHeaders = 509e8d8bef9SDimitry Andric Doc.getSectionHeaderTable(); 5105ffd83dbSDimitry Andric 5115ffd83dbSDimitry Andric if (Doc.Header.EShOff) 5125ffd83dbSDimitry Andric Header.e_shoff = *Doc.Header.EShOff; 513e8d8bef9SDimitry Andric else if (SectionHeaders.Offset) 514e8d8bef9SDimitry Andric Header.e_shoff = *SectionHeaders.Offset; 5155ffd83dbSDimitry Andric else 516e8d8bef9SDimitry Andric Header.e_shoff = 0; 5175ffd83dbSDimitry Andric 5185ffd83dbSDimitry Andric if (Doc.Header.EShNum) 5195ffd83dbSDimitry Andric Header.e_shnum = *Doc.Header.EShNum; 5205ffd83dbSDimitry Andric else 521e8d8bef9SDimitry Andric Header.e_shnum = SectionHeaders.getNumHeaders(Doc.getSections().size()); 5225ffd83dbSDimitry Andric 5235ffd83dbSDimitry Andric if (Doc.Header.EShStrNdx) 5245ffd83dbSDimitry Andric Header.e_shstrndx = *Doc.Header.EShStrNdx; 525fe6060f1SDimitry Andric else if (SectionHeaders.Offset && 526fe6060f1SDimitry Andric !ExcludedSectionHeaders.count(SectionHeaderStringTableName)) 527fe6060f1SDimitry Andric Header.e_shstrndx = SN2I.get(SectionHeaderStringTableName); 528e8d8bef9SDimitry Andric else 529e8d8bef9SDimitry Andric Header.e_shstrndx = 0; 5308bcb0991SDimitry Andric 5318bcb0991SDimitry Andric OS.write((const char *)&Header, sizeof(Header)); 5328bcb0991SDimitry Andric } 5338bcb0991SDimitry Andric 5348bcb0991SDimitry Andric template <class ELFT> 5358bcb0991SDimitry Andric void ELFState<ELFT>::initProgramHeaders(std::vector<Elf_Phdr> &PHeaders) { 5365ffd83dbSDimitry Andric DenseMap<StringRef, ELFYAML::Fill *> NameToFill; 537e8d8bef9SDimitry Andric DenseMap<StringRef, size_t> NameToIndex; 538e8d8bef9SDimitry Andric for (size_t I = 0, E = Doc.Chunks.size(); I != E; ++I) { 539e8d8bef9SDimitry Andric if (auto S = dyn_cast<ELFYAML::Fill>(Doc.Chunks[I].get())) 5405ffd83dbSDimitry Andric NameToFill[S->Name] = S; 541e8d8bef9SDimitry Andric NameToIndex[Doc.Chunks[I]->Name] = I + 1; 542e8d8bef9SDimitry Andric } 5435ffd83dbSDimitry Andric 5445ffd83dbSDimitry Andric std::vector<ELFYAML::Section *> Sections = Doc.getSections(); 545e8d8bef9SDimitry Andric for (size_t I = 0, E = Doc.ProgramHeaders.size(); I != E; ++I) { 546e8d8bef9SDimitry Andric ELFYAML::ProgramHeader &YamlPhdr = Doc.ProgramHeaders[I]; 5478bcb0991SDimitry Andric Elf_Phdr Phdr; 5485ffd83dbSDimitry Andric zero(Phdr); 5498bcb0991SDimitry Andric Phdr.p_type = YamlPhdr.Type; 5508bcb0991SDimitry Andric Phdr.p_flags = YamlPhdr.Flags; 5518bcb0991SDimitry Andric Phdr.p_vaddr = YamlPhdr.VAddr; 5528bcb0991SDimitry Andric Phdr.p_paddr = YamlPhdr.PAddr; 5538bcb0991SDimitry Andric PHeaders.push_back(Phdr); 5545ffd83dbSDimitry Andric 555e8d8bef9SDimitry Andric if (!YamlPhdr.FirstSec && !YamlPhdr.LastSec) 5565ffd83dbSDimitry Andric continue; 5575ffd83dbSDimitry Andric 558e8d8bef9SDimitry Andric // Get the index of the section, or 0 in the case when the section doesn't exist. 559e8d8bef9SDimitry Andric size_t First = NameToIndex[*YamlPhdr.FirstSec]; 560e8d8bef9SDimitry Andric if (!First) 561e8d8bef9SDimitry Andric reportError("unknown section or fill referenced: '" + *YamlPhdr.FirstSec + 562e8d8bef9SDimitry Andric "' by the 'FirstSec' key of the program header with index " + 563e8d8bef9SDimitry Andric Twine(I)); 564e8d8bef9SDimitry Andric size_t Last = NameToIndex[*YamlPhdr.LastSec]; 565e8d8bef9SDimitry Andric if (!Last) 566e8d8bef9SDimitry Andric reportError("unknown section or fill referenced: '" + *YamlPhdr.LastSec + 567e8d8bef9SDimitry Andric "' by the 'LastSec' key of the program header with index " + 568e8d8bef9SDimitry Andric Twine(I)); 569e8d8bef9SDimitry Andric if (!First || !Last) 5705ffd83dbSDimitry Andric continue; 5715ffd83dbSDimitry Andric 572e8d8bef9SDimitry Andric if (First > Last) 573e8d8bef9SDimitry Andric reportError("program header with index " + Twine(I) + 574e8d8bef9SDimitry Andric ": the section index of " + *YamlPhdr.FirstSec + 575e8d8bef9SDimitry Andric " is greater than the index of " + *YamlPhdr.LastSec); 576e8d8bef9SDimitry Andric 577e8d8bef9SDimitry Andric for (size_t I = First; I <= Last; ++I) 578e8d8bef9SDimitry Andric YamlPhdr.Chunks.push_back(Doc.Chunks[I - 1].get()); 5798bcb0991SDimitry Andric } 5808bcb0991SDimitry Andric } 5818bcb0991SDimitry Andric 5828bcb0991SDimitry Andric template <class ELFT> 5838bcb0991SDimitry Andric unsigned ELFState<ELFT>::toSectionIndex(StringRef S, StringRef LocSec, 5848bcb0991SDimitry Andric StringRef LocSym) { 5858bcb0991SDimitry Andric assert(LocSec.empty() || LocSym.empty()); 5865ffd83dbSDimitry Andric 5875ffd83dbSDimitry Andric unsigned Index; 5885ffd83dbSDimitry Andric if (!SN2I.lookup(S, Index) && !to_integer(S, Index)) { 5898bcb0991SDimitry Andric if (!LocSym.empty()) 5908bcb0991SDimitry Andric reportError("unknown section referenced: '" + S + "' by YAML symbol '" + 5918bcb0991SDimitry Andric LocSym + "'"); 5928bcb0991SDimitry Andric else 5938bcb0991SDimitry Andric reportError("unknown section referenced: '" + S + "' by YAML section '" + 5948bcb0991SDimitry Andric LocSec + "'"); 5958bcb0991SDimitry Andric return 0; 5968bcb0991SDimitry Andric } 5978bcb0991SDimitry Andric 598e8d8bef9SDimitry Andric const ELFYAML::SectionHeaderTable &SectionHeaders = 599e8d8bef9SDimitry Andric Doc.getSectionHeaderTable(); 600e8d8bef9SDimitry Andric if (SectionHeaders.IsImplicit || 60181ad6265SDimitry Andric (SectionHeaders.NoHeaders && !*SectionHeaders.NoHeaders) || 602fe6060f1SDimitry Andric SectionHeaders.isDefault()) 6035ffd83dbSDimitry Andric return Index; 6045ffd83dbSDimitry Andric 60581ad6265SDimitry Andric assert(!SectionHeaders.NoHeaders.value_or(false) || !SectionHeaders.Sections); 6065ffd83dbSDimitry Andric size_t FirstExcluded = 607e8d8bef9SDimitry Andric SectionHeaders.Sections ? SectionHeaders.Sections->size() : 0; 608fe6060f1SDimitry Andric if (Index > FirstExcluded) { 6095ffd83dbSDimitry Andric if (LocSym.empty()) 6105ffd83dbSDimitry Andric reportError("unable to link '" + LocSec + "' to excluded section '" + S + 6115ffd83dbSDimitry Andric "'"); 6125ffd83dbSDimitry Andric else 6135ffd83dbSDimitry Andric reportError("excluded section referenced: '" + S + "' by symbol '" + 6145ffd83dbSDimitry Andric LocSym + "'"); 6155ffd83dbSDimitry Andric } 6165ffd83dbSDimitry Andric return Index; 6175ffd83dbSDimitry Andric } 6185ffd83dbSDimitry Andric 6198bcb0991SDimitry Andric template <class ELFT> 6208bcb0991SDimitry Andric unsigned ELFState<ELFT>::toSymbolIndex(StringRef S, StringRef LocSec, 6218bcb0991SDimitry Andric bool IsDynamic) { 6228bcb0991SDimitry Andric const NameToIdxMap &SymMap = IsDynamic ? DynSymN2I : SymN2I; 6238bcb0991SDimitry Andric unsigned Index; 6248bcb0991SDimitry Andric // Here we try to look up S in the symbol table. If it is not there, 6258bcb0991SDimitry Andric // treat its value as a symbol index. 6268bcb0991SDimitry Andric if (!SymMap.lookup(S, Index) && !to_integer(S, Index)) { 6278bcb0991SDimitry Andric reportError("unknown symbol referenced: '" + S + "' by YAML section '" + 6288bcb0991SDimitry Andric LocSec + "'"); 6298bcb0991SDimitry Andric return 0; 6308bcb0991SDimitry Andric } 6318bcb0991SDimitry Andric return Index; 6328bcb0991SDimitry Andric } 6338bcb0991SDimitry Andric 6348bcb0991SDimitry Andric template <class ELFT> 635480093f4SDimitry Andric static void overrideFields(ELFYAML::Section *From, typename ELFT::Shdr &To) { 636480093f4SDimitry Andric if (!From) 637480093f4SDimitry Andric return; 638e8d8bef9SDimitry Andric if (From->ShAddrAlign) 639e8d8bef9SDimitry Andric To.sh_addralign = *From->ShAddrAlign; 640480093f4SDimitry Andric if (From->ShFlags) 641480093f4SDimitry Andric To.sh_flags = *From->ShFlags; 642480093f4SDimitry Andric if (From->ShName) 643480093f4SDimitry Andric To.sh_name = *From->ShName; 644480093f4SDimitry Andric if (From->ShOffset) 645480093f4SDimitry Andric To.sh_offset = *From->ShOffset; 646480093f4SDimitry Andric if (From->ShSize) 647480093f4SDimitry Andric To.sh_size = *From->ShSize; 648e8d8bef9SDimitry Andric if (From->ShType) 649e8d8bef9SDimitry Andric To.sh_type = *From->ShType; 650480093f4SDimitry Andric } 651480093f4SDimitry Andric 652480093f4SDimitry Andric template <class ELFT> 6538bcb0991SDimitry Andric bool ELFState<ELFT>::initImplicitHeader(ContiguousBlobAccumulator &CBA, 6548bcb0991SDimitry Andric Elf_Shdr &Header, StringRef SecName, 6558bcb0991SDimitry Andric ELFYAML::Section *YAMLSec) { 6568bcb0991SDimitry Andric // Check if the header was already initialized. 6578bcb0991SDimitry Andric if (Header.sh_offset) 6588bcb0991SDimitry Andric return false; 6598bcb0991SDimitry Andric 660fe6060f1SDimitry Andric if (SecName == ".strtab") 6618bcb0991SDimitry Andric initStrtabSectionHeader(Header, SecName, DotStrtab, CBA, YAMLSec); 6628bcb0991SDimitry Andric else if (SecName == ".dynstr") 6638bcb0991SDimitry Andric initStrtabSectionHeader(Header, SecName, DotDynstr, CBA, YAMLSec); 664fe6060f1SDimitry Andric else if (SecName == SectionHeaderStringTableName) 665fe6060f1SDimitry Andric initStrtabSectionHeader(Header, SecName, *ShStrtabStrings, CBA, YAMLSec); 666fe6060f1SDimitry Andric else if (SecName == ".symtab") 667fe6060f1SDimitry Andric initSymtabSectionHeader(Header, SymtabType::Static, CBA, YAMLSec); 668fe6060f1SDimitry Andric else if (SecName == ".dynsym") 669fe6060f1SDimitry Andric initSymtabSectionHeader(Header, SymtabType::Dynamic, CBA, YAMLSec); 670*5f757f3fSDimitry Andric else if (SecName.starts_with(".debug_")) { 6715ffd83dbSDimitry Andric // If a ".debug_*" section's type is a preserved one, e.g., SHT_DYNAMIC, we 6725ffd83dbSDimitry Andric // will not treat it as a debug section. 6735ffd83dbSDimitry Andric if (YAMLSec && !isa<ELFYAML::RawContentSection>(YAMLSec)) 6748bcb0991SDimitry Andric return false; 6755ffd83dbSDimitry Andric initDWARFSectionHeader(Header, SecName, CBA, YAMLSec); 6765ffd83dbSDimitry Andric } else 6775ffd83dbSDimitry Andric return false; 6785ffd83dbSDimitry Andric 6795ffd83dbSDimitry Andric LocationCounter += Header.sh_size; 6808bcb0991SDimitry Andric 681480093f4SDimitry Andric // Override section fields if requested. 682480093f4SDimitry Andric overrideFields<ELFT>(YAMLSec, Header); 6838bcb0991SDimitry Andric return true; 6848bcb0991SDimitry Andric } 6858bcb0991SDimitry Andric 6865ffd83dbSDimitry Andric constexpr char SuffixStart = '('; 6875ffd83dbSDimitry Andric constexpr char SuffixEnd = ')'; 6885ffd83dbSDimitry Andric 6895ffd83dbSDimitry Andric std::string llvm::ELFYAML::appendUniqueSuffix(StringRef Name, 6905ffd83dbSDimitry Andric const Twine &Msg) { 6915ffd83dbSDimitry Andric // Do not add a space when a Name is empty. 6925ffd83dbSDimitry Andric std::string Ret = Name.empty() ? "" : Name.str() + ' '; 6935ffd83dbSDimitry Andric return Ret + (Twine(SuffixStart) + Msg + Twine(SuffixEnd)).str(); 6945ffd83dbSDimitry Andric } 6955ffd83dbSDimitry Andric 6968bcb0991SDimitry Andric StringRef llvm::ELFYAML::dropUniqueSuffix(StringRef S) { 6975ffd83dbSDimitry Andric if (S.empty() || S.back() != SuffixEnd) 6988bcb0991SDimitry Andric return S; 6995ffd83dbSDimitry Andric 7005ffd83dbSDimitry Andric // A special case for empty names. See appendUniqueSuffix() above. 7015ffd83dbSDimitry Andric size_t SuffixPos = S.rfind(SuffixStart); 7025ffd83dbSDimitry Andric if (SuffixPos == 0) 7035ffd83dbSDimitry Andric return ""; 7045ffd83dbSDimitry Andric 7055ffd83dbSDimitry Andric if (SuffixPos == StringRef::npos || S[SuffixPos - 1] != ' ') 7065ffd83dbSDimitry Andric return S; 7075ffd83dbSDimitry Andric return S.substr(0, SuffixPos - 1); 7085ffd83dbSDimitry Andric } 7095ffd83dbSDimitry Andric 7105ffd83dbSDimitry Andric template <class ELFT> 7115ffd83dbSDimitry Andric uint64_t ELFState<ELFT>::getSectionNameOffset(StringRef Name) { 7125ffd83dbSDimitry Andric // If a section is excluded from section headers, we do not save its name in 7135ffd83dbSDimitry Andric // the string table. 7145ffd83dbSDimitry Andric if (ExcludedSectionHeaders.count(Name)) 7155ffd83dbSDimitry Andric return 0; 716fe6060f1SDimitry Andric return ShStrtabStrings->getOffset(Name); 7178bcb0991SDimitry Andric } 7188bcb0991SDimitry Andric 719e8d8bef9SDimitry Andric static uint64_t writeContent(ContiguousBlobAccumulator &CBA, 720bdd1243dSDimitry Andric const std::optional<yaml::BinaryRef> &Content, 721bdd1243dSDimitry Andric const std::optional<llvm::yaml::Hex64> &Size) { 722e8d8bef9SDimitry Andric size_t ContentSize = 0; 723e8d8bef9SDimitry Andric if (Content) { 724e8d8bef9SDimitry Andric CBA.writeAsBinary(*Content); 725e8d8bef9SDimitry Andric ContentSize = Content->binary_size(); 726e8d8bef9SDimitry Andric } 727e8d8bef9SDimitry Andric 728e8d8bef9SDimitry Andric if (!Size) 729e8d8bef9SDimitry Andric return ContentSize; 730e8d8bef9SDimitry Andric 731e8d8bef9SDimitry Andric CBA.writeZeros(*Size - ContentSize); 732e8d8bef9SDimitry Andric return *Size; 733e8d8bef9SDimitry Andric } 734e8d8bef9SDimitry Andric 735e8d8bef9SDimitry Andric static StringRef getDefaultLinkSec(unsigned SecType) { 736e8d8bef9SDimitry Andric switch (SecType) { 737e8d8bef9SDimitry Andric case ELF::SHT_REL: 738e8d8bef9SDimitry Andric case ELF::SHT_RELA: 739e8d8bef9SDimitry Andric case ELF::SHT_GROUP: 740e8d8bef9SDimitry Andric case ELF::SHT_LLVM_CALL_GRAPH_PROFILE: 741e8d8bef9SDimitry Andric case ELF::SHT_LLVM_ADDRSIG: 742e8d8bef9SDimitry Andric return ".symtab"; 743e8d8bef9SDimitry Andric case ELF::SHT_GNU_versym: 744e8d8bef9SDimitry Andric case ELF::SHT_HASH: 745e8d8bef9SDimitry Andric case ELF::SHT_GNU_HASH: 746e8d8bef9SDimitry Andric return ".dynsym"; 747e8d8bef9SDimitry Andric case ELF::SHT_DYNSYM: 748e8d8bef9SDimitry Andric case ELF::SHT_GNU_verdef: 749e8d8bef9SDimitry Andric case ELF::SHT_GNU_verneed: 750e8d8bef9SDimitry Andric return ".dynstr"; 751e8d8bef9SDimitry Andric case ELF::SHT_SYMTAB: 752e8d8bef9SDimitry Andric return ".strtab"; 753e8d8bef9SDimitry Andric default: 754e8d8bef9SDimitry Andric return ""; 755e8d8bef9SDimitry Andric } 756e8d8bef9SDimitry Andric } 757e8d8bef9SDimitry Andric 7588bcb0991SDimitry Andric template <class ELFT> 7598bcb0991SDimitry Andric void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders, 7608bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 7618bcb0991SDimitry Andric // Ensure SHN_UNDEF entry is present. An all-zero section header is a 7628bcb0991SDimitry Andric // valid SHN_UNDEF entry since SHT_NULL == 0. 763480093f4SDimitry Andric SHeaders.resize(Doc.getSections().size()); 7648bcb0991SDimitry Andric 765480093f4SDimitry Andric for (const std::unique_ptr<ELFYAML::Chunk> &D : Doc.Chunks) { 7665ffd83dbSDimitry Andric if (ELFYAML::Fill *S = dyn_cast<ELFYAML::Fill>(D.get())) { 7675ffd83dbSDimitry Andric S->Offset = alignToOffset(CBA, /*Align=*/1, S->Offset); 768480093f4SDimitry Andric writeFill(*S, CBA); 7695ffd83dbSDimitry Andric LocationCounter += S->Size; 770480093f4SDimitry Andric continue; 771480093f4SDimitry Andric } 772480093f4SDimitry Andric 773e8d8bef9SDimitry Andric if (ELFYAML::SectionHeaderTable *S = 774e8d8bef9SDimitry Andric dyn_cast<ELFYAML::SectionHeaderTable>(D.get())) { 77581ad6265SDimitry Andric if (S->NoHeaders.value_or(false)) 776e8d8bef9SDimitry Andric continue; 777e8d8bef9SDimitry Andric 778e8d8bef9SDimitry Andric if (!S->Offset) 779e8d8bef9SDimitry Andric S->Offset = alignToOffset(CBA, sizeof(typename ELFT::uint), 780bdd1243dSDimitry Andric /*Offset=*/std::nullopt); 781e8d8bef9SDimitry Andric else 782e8d8bef9SDimitry Andric S->Offset = alignToOffset(CBA, /*Align=*/1, S->Offset); 783e8d8bef9SDimitry Andric 784e8d8bef9SDimitry Andric uint64_t Size = S->getNumHeaders(SHeaders.size()) * sizeof(Elf_Shdr); 785e8d8bef9SDimitry Andric // The full section header information might be not available here, so 786e8d8bef9SDimitry Andric // fill the space with zeroes as a placeholder. 787e8d8bef9SDimitry Andric CBA.writeZeros(Size); 788e8d8bef9SDimitry Andric LocationCounter += Size; 789e8d8bef9SDimitry Andric continue; 790e8d8bef9SDimitry Andric } 791e8d8bef9SDimitry Andric 792480093f4SDimitry Andric ELFYAML::Section *Sec = cast<ELFYAML::Section>(D.get()); 793e8d8bef9SDimitry Andric bool IsFirstUndefSection = Sec == Doc.getSections().front(); 7945ffd83dbSDimitry Andric if (IsFirstUndefSection && Sec->IsImplicit) 7958bcb0991SDimitry Andric continue; 7968bcb0991SDimitry Andric 797e8d8bef9SDimitry Andric Elf_Shdr &SHeader = SHeaders[SN2I.get(Sec->Name)]; 798e8d8bef9SDimitry Andric if (Sec->Link) { 799e8d8bef9SDimitry Andric SHeader.sh_link = toSectionIndex(*Sec->Link, Sec->Name); 800e8d8bef9SDimitry Andric } else { 801e8d8bef9SDimitry Andric StringRef LinkSec = getDefaultLinkSec(Sec->Type); 802e8d8bef9SDimitry Andric unsigned Link = 0; 803e8d8bef9SDimitry Andric if (!LinkSec.empty() && !ExcludedSectionHeaders.count(LinkSec) && 804e8d8bef9SDimitry Andric SN2I.lookup(LinkSec, Link)) 805e8d8bef9SDimitry Andric SHeader.sh_link = Link; 806e8d8bef9SDimitry Andric } 807e8d8bef9SDimitry Andric 808e8d8bef9SDimitry Andric if (Sec->EntSize) 809e8d8bef9SDimitry Andric SHeader.sh_entsize = *Sec->EntSize; 810e8d8bef9SDimitry Andric else 811e8d8bef9SDimitry Andric SHeader.sh_entsize = ELFYAML::getDefaultShEntSize<ELFT>( 81281ad6265SDimitry Andric Doc.Header.Machine.value_or(ELF::EM_NONE), Sec->Type, Sec->Name); 813e8d8bef9SDimitry Andric 8148bcb0991SDimitry Andric // We have a few sections like string or symbol tables that are usually 8158bcb0991SDimitry Andric // added implicitly to the end. However, if they are explicitly specified 8168bcb0991SDimitry Andric // in the YAML, we need to write them here. This ensures the file offset 8178bcb0991SDimitry Andric // remains correct. 8188bcb0991SDimitry Andric if (initImplicitHeader(CBA, SHeader, Sec->Name, 8198bcb0991SDimitry Andric Sec->IsImplicit ? nullptr : Sec)) 8208bcb0991SDimitry Andric continue; 8218bcb0991SDimitry Andric 8228bcb0991SDimitry Andric assert(Sec && "It can't be null unless it is an implicit section. But all " 8238bcb0991SDimitry Andric "implicit sections should already have been handled above."); 8248bcb0991SDimitry Andric 8258bcb0991SDimitry Andric SHeader.sh_name = 8265ffd83dbSDimitry Andric getSectionNameOffset(ELFYAML::dropUniqueSuffix(Sec->Name)); 8278bcb0991SDimitry Andric SHeader.sh_type = Sec->Type; 8288bcb0991SDimitry Andric if (Sec->Flags) 8298bcb0991SDimitry Andric SHeader.sh_flags = *Sec->Flags; 8308bcb0991SDimitry Andric SHeader.sh_addralign = Sec->AddressAlign; 8318bcb0991SDimitry Andric 8325ffd83dbSDimitry Andric // Set the offset for all sections, except the SHN_UNDEF section with index 8335ffd83dbSDimitry Andric // 0 when not explicitly requested. 8345ffd83dbSDimitry Andric if (!IsFirstUndefSection || Sec->Offset) 8355ffd83dbSDimitry Andric SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign, Sec->Offset); 8365ffd83dbSDimitry Andric 8375ffd83dbSDimitry Andric assignSectionAddress(SHeader, Sec); 8385ffd83dbSDimitry Andric 8395ffd83dbSDimitry Andric if (IsFirstUndefSection) { 8408bcb0991SDimitry Andric if (auto RawSec = dyn_cast<ELFYAML::RawContentSection>(Sec)) { 8418bcb0991SDimitry Andric // We do not write any content for special SHN_UNDEF section. 8428bcb0991SDimitry Andric if (RawSec->Size) 8438bcb0991SDimitry Andric SHeader.sh_size = *RawSec->Size; 8448bcb0991SDimitry Andric if (RawSec->Info) 8458bcb0991SDimitry Andric SHeader.sh_info = *RawSec->Info; 8468bcb0991SDimitry Andric } 847e8d8bef9SDimitry Andric 848e8d8bef9SDimitry Andric LocationCounter += SHeader.sh_size; 849e8d8bef9SDimitry Andric overrideFields<ELFT>(Sec, SHeader); 850e8d8bef9SDimitry Andric continue; 851e8d8bef9SDimitry Andric } 852e8d8bef9SDimitry Andric 853e8d8bef9SDimitry Andric if (!isa<ELFYAML::NoBitsSection>(Sec) && (Sec->Content || Sec->Size)) 854e8d8bef9SDimitry Andric SHeader.sh_size = writeContent(CBA, Sec->Content, Sec->Size); 855e8d8bef9SDimitry Andric 856e8d8bef9SDimitry Andric if (auto S = dyn_cast<ELFYAML::RawContentSection>(Sec)) { 8578bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8588bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::SymtabShndxSection>(Sec)) { 8598bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8608bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::RelocationSection>(Sec)) { 8618bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 862480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::RelrSection>(Sec)) { 863480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 864e8d8bef9SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::GroupSection>(Sec)) { 865e8d8bef9SDimitry Andric writeSectionContent(SHeader, *S, CBA); 866e8d8bef9SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::ARMIndexTableSection>(Sec)) { 8678bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8688bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::MipsABIFlags>(Sec)) { 8698bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8708bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::NoBitsSection>(Sec)) { 8715ffd83dbSDimitry Andric writeSectionContent(SHeader, *S, CBA); 8728bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::DynamicSection>(Sec)) { 8738bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8748bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::SymverSection>(Sec)) { 8758bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8768bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::VerneedSection>(Sec)) { 8778bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8788bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::VerdefSection>(Sec)) { 8798bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8808bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::StackSizesSection>(Sec)) { 8818bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8828bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::HashSection>(Sec)) { 8838bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8848bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::AddrsigSection>(Sec)) { 8858bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 886480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::LinkerOptionsSection>(Sec)) { 887480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 888480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::NoteSection>(Sec)) { 889480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 890480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::GnuHashSection>(Sec)) { 891480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 892480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::DependentLibrariesSection>(Sec)) { 893480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8945ffd83dbSDimitry Andric } else if (auto S = dyn_cast<ELFYAML::CallGraphProfileSection>(Sec)) { 8955ffd83dbSDimitry Andric writeSectionContent(SHeader, *S, CBA); 896e8d8bef9SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::BBAddrMapSection>(Sec)) { 897e8d8bef9SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8988bcb0991SDimitry Andric } else { 8998bcb0991SDimitry Andric llvm_unreachable("Unknown section type"); 9008bcb0991SDimitry Andric } 9018bcb0991SDimitry Andric 9025ffd83dbSDimitry Andric LocationCounter += SHeader.sh_size; 9035ffd83dbSDimitry Andric 904480093f4SDimitry Andric // Override section fields if requested. 905480093f4SDimitry Andric overrideFields<ELFT>(Sec, SHeader); 9068bcb0991SDimitry Andric } 9078bcb0991SDimitry Andric } 9088bcb0991SDimitry Andric 9095ffd83dbSDimitry Andric template <class ELFT> 9105ffd83dbSDimitry Andric void ELFState<ELFT>::assignSectionAddress(Elf_Shdr &SHeader, 9115ffd83dbSDimitry Andric ELFYAML::Section *YAMLSec) { 9125ffd83dbSDimitry Andric if (YAMLSec && YAMLSec->Address) { 9135ffd83dbSDimitry Andric SHeader.sh_addr = *YAMLSec->Address; 9145ffd83dbSDimitry Andric LocationCounter = *YAMLSec->Address; 9155ffd83dbSDimitry Andric return; 9165ffd83dbSDimitry Andric } 9175ffd83dbSDimitry Andric 9185ffd83dbSDimitry Andric // sh_addr represents the address in the memory image of a process. Sections 9195ffd83dbSDimitry Andric // in a relocatable object file or non-allocatable sections do not need 9205ffd83dbSDimitry Andric // sh_addr assignment. 9215ffd83dbSDimitry Andric if (Doc.Header.Type.value == ELF::ET_REL || 9225ffd83dbSDimitry Andric !(SHeader.sh_flags & ELF::SHF_ALLOC)) 9235ffd83dbSDimitry Andric return; 9245ffd83dbSDimitry Andric 9255ffd83dbSDimitry Andric LocationCounter = 9265ffd83dbSDimitry Andric alignTo(LocationCounter, SHeader.sh_addralign ? SHeader.sh_addralign : 1); 9275ffd83dbSDimitry Andric SHeader.sh_addr = LocationCounter; 9285ffd83dbSDimitry Andric } 9295ffd83dbSDimitry Andric 9308bcb0991SDimitry Andric static size_t findFirstNonGlobal(ArrayRef<ELFYAML::Symbol> Symbols) { 9318bcb0991SDimitry Andric for (size_t I = 0; I < Symbols.size(); ++I) 9328bcb0991SDimitry Andric if (Symbols[I].Binding.value != ELF::STB_LOCAL) 9338bcb0991SDimitry Andric return I; 9348bcb0991SDimitry Andric return Symbols.size(); 9358bcb0991SDimitry Andric } 9368bcb0991SDimitry Andric 9378bcb0991SDimitry Andric template <class ELFT> 9388bcb0991SDimitry Andric std::vector<typename ELFT::Sym> 9398bcb0991SDimitry Andric ELFState<ELFT>::toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols, 9408bcb0991SDimitry Andric const StringTableBuilder &Strtab) { 9418bcb0991SDimitry Andric std::vector<Elf_Sym> Ret; 9428bcb0991SDimitry Andric Ret.resize(Symbols.size() + 1); 9438bcb0991SDimitry Andric 9448bcb0991SDimitry Andric size_t I = 0; 945480093f4SDimitry Andric for (const ELFYAML::Symbol &Sym : Symbols) { 9468bcb0991SDimitry Andric Elf_Sym &Symbol = Ret[++I]; 9478bcb0991SDimitry Andric 9488bcb0991SDimitry Andric // If NameIndex, which contains the name offset, is explicitly specified, we 9498bcb0991SDimitry Andric // use it. This is useful for preparing broken objects. Otherwise, we add 9508bcb0991SDimitry Andric // the specified Name to the string table builder to get its offset. 9515ffd83dbSDimitry Andric if (Sym.StName) 9525ffd83dbSDimitry Andric Symbol.st_name = *Sym.StName; 9538bcb0991SDimitry Andric else if (!Sym.Name.empty()) 9548bcb0991SDimitry Andric Symbol.st_name = Strtab.getOffset(ELFYAML::dropUniqueSuffix(Sym.Name)); 9558bcb0991SDimitry Andric 9568bcb0991SDimitry Andric Symbol.setBindingAndType(Sym.Binding, Sym.Type); 957e8d8bef9SDimitry Andric if (Sym.Section) 958e8d8bef9SDimitry Andric Symbol.st_shndx = toSectionIndex(*Sym.Section, "", Sym.Name); 9598bcb0991SDimitry Andric else if (Sym.Index) 9608bcb0991SDimitry Andric Symbol.st_shndx = *Sym.Index; 9618bcb0991SDimitry Andric 96281ad6265SDimitry Andric Symbol.st_value = Sym.Value.value_or(yaml::Hex64(0)); 9638bcb0991SDimitry Andric Symbol.st_other = Sym.Other ? *Sym.Other : 0; 96481ad6265SDimitry Andric Symbol.st_size = Sym.Size.value_or(yaml::Hex64(0)); 9658bcb0991SDimitry Andric } 9668bcb0991SDimitry Andric 9678bcb0991SDimitry Andric return Ret; 9688bcb0991SDimitry Andric } 9698bcb0991SDimitry Andric 9708bcb0991SDimitry Andric template <class ELFT> 9718bcb0991SDimitry Andric void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader, 9728bcb0991SDimitry Andric SymtabType STType, 9738bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 9748bcb0991SDimitry Andric ELFYAML::Section *YAMLSec) { 9758bcb0991SDimitry Andric 9768bcb0991SDimitry Andric bool IsStatic = STType == SymtabType::Static; 9778bcb0991SDimitry Andric ArrayRef<ELFYAML::Symbol> Symbols; 9788bcb0991SDimitry Andric if (IsStatic && Doc.Symbols) 9798bcb0991SDimitry Andric Symbols = *Doc.Symbols; 980480093f4SDimitry Andric else if (!IsStatic && Doc.DynamicSymbols) 981480093f4SDimitry Andric Symbols = *Doc.DynamicSymbols; 9828bcb0991SDimitry Andric 9838bcb0991SDimitry Andric ELFYAML::RawContentSection *RawSec = 9848bcb0991SDimitry Andric dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec); 985480093f4SDimitry Andric if (RawSec && (RawSec->Content || RawSec->Size)) { 986480093f4SDimitry Andric bool HasSymbolsDescription = 987480093f4SDimitry Andric (IsStatic && Doc.Symbols) || (!IsStatic && Doc.DynamicSymbols); 988480093f4SDimitry Andric if (HasSymbolsDescription) { 989480093f4SDimitry Andric StringRef Property = (IsStatic ? "`Symbols`" : "`DynamicSymbols`"); 9908bcb0991SDimitry Andric if (RawSec->Content) 991480093f4SDimitry Andric reportError("cannot specify both `Content` and " + Property + 9928bcb0991SDimitry Andric " for symbol table section '" + RawSec->Name + "'"); 9938bcb0991SDimitry Andric if (RawSec->Size) 994480093f4SDimitry Andric reportError("cannot specify both `Size` and " + Property + 9958bcb0991SDimitry Andric " for symbol table section '" + RawSec->Name + "'"); 9968bcb0991SDimitry Andric return; 9978bcb0991SDimitry Andric } 998480093f4SDimitry Andric } 9998bcb0991SDimitry Andric 10005ffd83dbSDimitry Andric SHeader.sh_name = getSectionNameOffset(IsStatic ? ".symtab" : ".dynsym"); 10018bcb0991SDimitry Andric 10028bcb0991SDimitry Andric if (YAMLSec) 10038bcb0991SDimitry Andric SHeader.sh_type = YAMLSec->Type; 10048bcb0991SDimitry Andric else 10058bcb0991SDimitry Andric SHeader.sh_type = IsStatic ? ELF::SHT_SYMTAB : ELF::SHT_DYNSYM; 10068bcb0991SDimitry Andric 10078bcb0991SDimitry Andric if (YAMLSec && YAMLSec->Flags) 10088bcb0991SDimitry Andric SHeader.sh_flags = *YAMLSec->Flags; 10098bcb0991SDimitry Andric else if (!IsStatic) 10108bcb0991SDimitry Andric SHeader.sh_flags = ELF::SHF_ALLOC; 10118bcb0991SDimitry Andric 10128bcb0991SDimitry Andric // If the symbol table section is explicitly described in the YAML 10138bcb0991SDimitry Andric // then we should set the fields requested. 10148bcb0991SDimitry Andric SHeader.sh_info = (RawSec && RawSec->Info) ? (unsigned)(*RawSec->Info) 10158bcb0991SDimitry Andric : findFirstNonGlobal(Symbols) + 1; 10168bcb0991SDimitry Andric SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 8; 10178bcb0991SDimitry Andric 10185ffd83dbSDimitry Andric assignSectionAddress(SHeader, YAMLSec); 10195ffd83dbSDimitry Andric 1020bdd1243dSDimitry Andric SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign, 1021bdd1243dSDimitry Andric RawSec ? RawSec->Offset : std::nullopt); 10225ffd83dbSDimitry Andric 10238bcb0991SDimitry Andric if (RawSec && (RawSec->Content || RawSec->Size)) { 10248bcb0991SDimitry Andric assert(Symbols.empty()); 10255ffd83dbSDimitry Andric SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size); 10268bcb0991SDimitry Andric return; 10278bcb0991SDimitry Andric } 10288bcb0991SDimitry Andric 10298bcb0991SDimitry Andric std::vector<Elf_Sym> Syms = 10308bcb0991SDimitry Andric toELFSymbols(Symbols, IsStatic ? DotStrtab : DotDynstr); 10315ffd83dbSDimitry Andric SHeader.sh_size = Syms.size() * sizeof(Elf_Sym); 10325ffd83dbSDimitry Andric CBA.write((const char *)Syms.data(), SHeader.sh_size); 10338bcb0991SDimitry Andric } 10348bcb0991SDimitry Andric 10358bcb0991SDimitry Andric template <class ELFT> 10368bcb0991SDimitry Andric void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name, 10378bcb0991SDimitry Andric StringTableBuilder &STB, 10388bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 10398bcb0991SDimitry Andric ELFYAML::Section *YAMLSec) { 1040fe6060f1SDimitry Andric SHeader.sh_name = getSectionNameOffset(ELFYAML::dropUniqueSuffix(Name)); 10418bcb0991SDimitry Andric SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_STRTAB; 10428bcb0991SDimitry Andric SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1; 10438bcb0991SDimitry Andric 10448bcb0991SDimitry Andric ELFYAML::RawContentSection *RawSec = 10458bcb0991SDimitry Andric dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec); 10468bcb0991SDimitry Andric 1047e8d8bef9SDimitry Andric SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign, 1048bdd1243dSDimitry Andric YAMLSec ? YAMLSec->Offset : std::nullopt); 10495ffd83dbSDimitry Andric 10508bcb0991SDimitry Andric if (RawSec && (RawSec->Content || RawSec->Size)) { 10515ffd83dbSDimitry Andric SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size); 10528bcb0991SDimitry Andric } else { 10535ffd83dbSDimitry Andric if (raw_ostream *OS = CBA.getRawOS(STB.getSize())) 10545ffd83dbSDimitry Andric STB.write(*OS); 10558bcb0991SDimitry Andric SHeader.sh_size = STB.getSize(); 10568bcb0991SDimitry Andric } 10578bcb0991SDimitry Andric 10588bcb0991SDimitry Andric if (RawSec && RawSec->Info) 10598bcb0991SDimitry Andric SHeader.sh_info = *RawSec->Info; 10608bcb0991SDimitry Andric 10618bcb0991SDimitry Andric if (YAMLSec && YAMLSec->Flags) 10628bcb0991SDimitry Andric SHeader.sh_flags = *YAMLSec->Flags; 10638bcb0991SDimitry Andric else if (Name == ".dynstr") 10648bcb0991SDimitry Andric SHeader.sh_flags = ELF::SHF_ALLOC; 10658bcb0991SDimitry Andric 10665ffd83dbSDimitry Andric assignSectionAddress(SHeader, YAMLSec); 10675ffd83dbSDimitry Andric } 10685ffd83dbSDimitry Andric 10695ffd83dbSDimitry Andric static bool shouldEmitDWARF(DWARFYAML::Data &DWARF, StringRef Name) { 1070e8d8bef9SDimitry Andric SetVector<StringRef> DebugSecNames = DWARF.getNonEmptySectionNames(); 10715ffd83dbSDimitry Andric return Name.consume_front(".") && DebugSecNames.count(Name); 10725ffd83dbSDimitry Andric } 10735ffd83dbSDimitry Andric 10745ffd83dbSDimitry Andric template <class ELFT> 10755ffd83dbSDimitry Andric Expected<uint64_t> emitDWARF(typename ELFT::Shdr &SHeader, StringRef Name, 10765ffd83dbSDimitry Andric const DWARFYAML::Data &DWARF, 10775ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA) { 10785ffd83dbSDimitry Andric // We are unable to predict the size of debug data, so we request to write 0 10795ffd83dbSDimitry Andric // bytes. This should always return us an output stream unless CBA is already 10805ffd83dbSDimitry Andric // in an error state. 10815ffd83dbSDimitry Andric raw_ostream *OS = CBA.getRawOS(0); 10825ffd83dbSDimitry Andric if (!OS) 10835ffd83dbSDimitry Andric return 0; 10845ffd83dbSDimitry Andric 10855ffd83dbSDimitry Andric uint64_t BeginOffset = CBA.tell(); 10865ffd83dbSDimitry Andric 1087e8d8bef9SDimitry Andric auto EmitFunc = DWARFYAML::getDWARFEmitterByName(Name.substr(1)); 1088e8d8bef9SDimitry Andric if (Error Err = EmitFunc(*OS, DWARF)) 10895ffd83dbSDimitry Andric return std::move(Err); 10905ffd83dbSDimitry Andric 10915ffd83dbSDimitry Andric return CBA.tell() - BeginOffset; 10925ffd83dbSDimitry Andric } 10935ffd83dbSDimitry Andric 10945ffd83dbSDimitry Andric template <class ELFT> 10955ffd83dbSDimitry Andric void ELFState<ELFT>::initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name, 10965ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA, 10975ffd83dbSDimitry Andric ELFYAML::Section *YAMLSec) { 10985ffd83dbSDimitry Andric SHeader.sh_name = getSectionNameOffset(ELFYAML::dropUniqueSuffix(Name)); 10995ffd83dbSDimitry Andric SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_PROGBITS; 11005ffd83dbSDimitry Andric SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1; 11015ffd83dbSDimitry Andric SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign, 1102bdd1243dSDimitry Andric YAMLSec ? YAMLSec->Offset : std::nullopt); 11035ffd83dbSDimitry Andric 11045ffd83dbSDimitry Andric ELFYAML::RawContentSection *RawSec = 11055ffd83dbSDimitry Andric dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec); 11065ffd83dbSDimitry Andric if (Doc.DWARF && shouldEmitDWARF(*Doc.DWARF, Name)) { 11075ffd83dbSDimitry Andric if (RawSec && (RawSec->Content || RawSec->Size)) 11085ffd83dbSDimitry Andric reportError("cannot specify section '" + Name + 11095ffd83dbSDimitry Andric "' contents in the 'DWARF' entry and the 'Content' " 11105ffd83dbSDimitry Andric "or 'Size' in the 'Sections' entry at the same time"); 11115ffd83dbSDimitry Andric else { 11125ffd83dbSDimitry Andric if (Expected<uint64_t> ShSizeOrErr = 11135ffd83dbSDimitry Andric emitDWARF<ELFT>(SHeader, Name, *Doc.DWARF, CBA)) 11145ffd83dbSDimitry Andric SHeader.sh_size = *ShSizeOrErr; 11155ffd83dbSDimitry Andric else 11165ffd83dbSDimitry Andric reportError(ShSizeOrErr.takeError()); 11175ffd83dbSDimitry Andric } 11185ffd83dbSDimitry Andric } else if (RawSec) 11195ffd83dbSDimitry Andric SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size); 11205ffd83dbSDimitry Andric else 11215ffd83dbSDimitry Andric llvm_unreachable("debug sections can only be initialized via the 'DWARF' " 11225ffd83dbSDimitry Andric "entry or a RawContentSection"); 11235ffd83dbSDimitry Andric 11245ffd83dbSDimitry Andric if (RawSec && RawSec->Info) 11255ffd83dbSDimitry Andric SHeader.sh_info = *RawSec->Info; 11265ffd83dbSDimitry Andric 11275ffd83dbSDimitry Andric if (YAMLSec && YAMLSec->Flags) 11285ffd83dbSDimitry Andric SHeader.sh_flags = *YAMLSec->Flags; 11295ffd83dbSDimitry Andric else if (Name == ".debug_str") 11305ffd83dbSDimitry Andric SHeader.sh_flags = ELF::SHF_MERGE | ELF::SHF_STRINGS; 11315ffd83dbSDimitry Andric 11325ffd83dbSDimitry Andric assignSectionAddress(SHeader, YAMLSec); 11338bcb0991SDimitry Andric } 11348bcb0991SDimitry Andric 11358bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::reportError(const Twine &Msg) { 11368bcb0991SDimitry Andric ErrHandler(Msg); 11378bcb0991SDimitry Andric HasError = true; 11388bcb0991SDimitry Andric } 11398bcb0991SDimitry Andric 11405ffd83dbSDimitry Andric template <class ELFT> void ELFState<ELFT>::reportError(Error Err) { 11415ffd83dbSDimitry Andric handleAllErrors(std::move(Err), [&](const ErrorInfoBase &Err) { 11425ffd83dbSDimitry Andric reportError(Err.message()); 11435ffd83dbSDimitry Andric }); 11445ffd83dbSDimitry Andric } 11455ffd83dbSDimitry Andric 11468bcb0991SDimitry Andric template <class ELFT> 1147480093f4SDimitry Andric std::vector<Fragment> 1148480093f4SDimitry Andric ELFState<ELFT>::getPhdrFragments(const ELFYAML::ProgramHeader &Phdr, 11495ffd83dbSDimitry Andric ArrayRef<Elf_Shdr> SHeaders) { 1150480093f4SDimitry Andric std::vector<Fragment> Ret; 11515ffd83dbSDimitry Andric for (const ELFYAML::Chunk *C : Phdr.Chunks) { 11525ffd83dbSDimitry Andric if (const ELFYAML::Fill *F = dyn_cast<ELFYAML::Fill>(C)) { 11535ffd83dbSDimitry Andric Ret.push_back({*F->Offset, F->Size, llvm::ELF::SHT_PROGBITS, 1154480093f4SDimitry Andric /*ShAddrAlign=*/1}); 1155480093f4SDimitry Andric continue; 1156480093f4SDimitry Andric } 1157480093f4SDimitry Andric 11585ffd83dbSDimitry Andric const ELFYAML::Section *S = cast<ELFYAML::Section>(C); 11595ffd83dbSDimitry Andric const Elf_Shdr &H = SHeaders[SN2I.get(S->Name)]; 11605ffd83dbSDimitry Andric Ret.push_back({H.sh_offset, H.sh_size, H.sh_type, H.sh_addralign}); 1161480093f4SDimitry Andric } 1162480093f4SDimitry Andric return Ret; 1163480093f4SDimitry Andric } 1164480093f4SDimitry Andric 1165480093f4SDimitry Andric template <class ELFT> 11668bcb0991SDimitry Andric void ELFState<ELFT>::setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders, 11678bcb0991SDimitry Andric std::vector<Elf_Shdr> &SHeaders) { 11688bcb0991SDimitry Andric uint32_t PhdrIdx = 0; 11698bcb0991SDimitry Andric for (auto &YamlPhdr : Doc.ProgramHeaders) { 11708bcb0991SDimitry Andric Elf_Phdr &PHeader = PHeaders[PhdrIdx++]; 1171480093f4SDimitry Andric std::vector<Fragment> Fragments = getPhdrFragments(YamlPhdr, SHeaders); 11725ffd83dbSDimitry Andric if (!llvm::is_sorted(Fragments, [](const Fragment &A, const Fragment &B) { 11735ffd83dbSDimitry Andric return A.Offset < B.Offset; 11745ffd83dbSDimitry Andric })) 11755ffd83dbSDimitry Andric reportError("sections in the program header with index " + 11765ffd83dbSDimitry Andric Twine(PhdrIdx) + " are not sorted by their file offset"); 11778bcb0991SDimitry Andric 11788bcb0991SDimitry Andric if (YamlPhdr.Offset) { 11795ffd83dbSDimitry Andric if (!Fragments.empty() && *YamlPhdr.Offset > Fragments.front().Offset) 11805ffd83dbSDimitry Andric reportError("'Offset' for segment with index " + Twine(PhdrIdx) + 11815ffd83dbSDimitry Andric " must be less than or equal to the minimum file offset of " 11825ffd83dbSDimitry Andric "all included sections (0x" + 11835ffd83dbSDimitry Andric Twine::utohexstr(Fragments.front().Offset) + ")"); 11848bcb0991SDimitry Andric PHeader.p_offset = *YamlPhdr.Offset; 11855ffd83dbSDimitry Andric } else if (!Fragments.empty()) { 11865ffd83dbSDimitry Andric PHeader.p_offset = Fragments.front().Offset; 11875ffd83dbSDimitry Andric } 11888bcb0991SDimitry Andric 11895ffd83dbSDimitry Andric // Set the file size if not set explicitly. 11905ffd83dbSDimitry Andric if (YamlPhdr.FileSize) { 11915ffd83dbSDimitry Andric PHeader.p_filesz = *YamlPhdr.FileSize; 11925ffd83dbSDimitry Andric } else if (!Fragments.empty()) { 11935ffd83dbSDimitry Andric uint64_t FileSize = Fragments.back().Offset - PHeader.p_offset; 11945ffd83dbSDimitry Andric // SHT_NOBITS sections occupy no physical space in a file, we should not 11955ffd83dbSDimitry Andric // take their sizes into account when calculating the file size of a 11965ffd83dbSDimitry Andric // segment. 11975ffd83dbSDimitry Andric if (Fragments.back().Type != llvm::ELF::SHT_NOBITS) 11985ffd83dbSDimitry Andric FileSize += Fragments.back().Size; 11995ffd83dbSDimitry Andric PHeader.p_filesz = FileSize; 12005ffd83dbSDimitry Andric } 12015ffd83dbSDimitry Andric 12025ffd83dbSDimitry Andric // Find the maximum offset of the end of a section in order to set p_memsz. 12035ffd83dbSDimitry Andric uint64_t MemOffset = PHeader.p_offset; 1204480093f4SDimitry Andric for (const Fragment &F : Fragments) 12055ffd83dbSDimitry Andric MemOffset = std::max(MemOffset, F.Offset + F.Size); 12065ffd83dbSDimitry Andric // Set the memory size if not set explicitly. 12078bcb0991SDimitry Andric PHeader.p_memsz = YamlPhdr.MemSize ? uint64_t(*YamlPhdr.MemSize) 12088bcb0991SDimitry Andric : MemOffset - PHeader.p_offset; 12098bcb0991SDimitry Andric 12108bcb0991SDimitry Andric if (YamlPhdr.Align) { 12118bcb0991SDimitry Andric PHeader.p_align = *YamlPhdr.Align; 12128bcb0991SDimitry Andric } else { 12138bcb0991SDimitry Andric // Set the alignment of the segment to be the maximum alignment of the 12148bcb0991SDimitry Andric // sections so that by default the segment has a valid and sensible 12158bcb0991SDimitry Andric // alignment. 12168bcb0991SDimitry Andric PHeader.p_align = 1; 1217480093f4SDimitry Andric for (const Fragment &F : Fragments) 1218480093f4SDimitry Andric PHeader.p_align = std::max((uint64_t)PHeader.p_align, F.AddrAlign); 12198bcb0991SDimitry Andric } 12208bcb0991SDimitry Andric } 12218bcb0991SDimitry Andric } 12228bcb0991SDimitry Andric 1223e8d8bef9SDimitry Andric bool llvm::ELFYAML::shouldAllocateFileSpace( 1224e8d8bef9SDimitry Andric ArrayRef<ELFYAML::ProgramHeader> Phdrs, const ELFYAML::NoBitsSection &S) { 12255ffd83dbSDimitry Andric for (const ELFYAML::ProgramHeader &PH : Phdrs) { 12265ffd83dbSDimitry Andric auto It = llvm::find_if( 12275ffd83dbSDimitry Andric PH.Chunks, [&](ELFYAML::Chunk *C) { return C->Name == S.Name; }); 12285ffd83dbSDimitry Andric if (std::any_of(It, PH.Chunks.end(), [](ELFYAML::Chunk *C) { 12295ffd83dbSDimitry Andric return (isa<ELFYAML::Fill>(C) || 12305ffd83dbSDimitry Andric cast<ELFYAML::Section>(C)->Type != ELF::SHT_NOBITS); 12315ffd83dbSDimitry Andric })) 12325ffd83dbSDimitry Andric return true; 12335ffd83dbSDimitry Andric } 12345ffd83dbSDimitry Andric return false; 12355ffd83dbSDimitry Andric } 12365ffd83dbSDimitry Andric 12375ffd83dbSDimitry Andric template <class ELFT> 12385ffd83dbSDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 12395ffd83dbSDimitry Andric const ELFYAML::NoBitsSection &S, 12405ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA) { 1241e8d8bef9SDimitry Andric if (!S.Size) 1242e8d8bef9SDimitry Andric return; 1243e8d8bef9SDimitry Andric 1244e8d8bef9SDimitry Andric SHeader.sh_size = *S.Size; 12455ffd83dbSDimitry Andric 12465ffd83dbSDimitry Andric // When a nobits section is followed by a non-nobits section or fill 12475ffd83dbSDimitry Andric // in the same segment, we allocate the file space for it. This behavior 12485ffd83dbSDimitry Andric // matches linkers. 12495ffd83dbSDimitry Andric if (shouldAllocateFileSpace(Doc.ProgramHeaders, S)) 1250e8d8bef9SDimitry Andric CBA.writeZeros(*S.Size); 12515ffd83dbSDimitry Andric } 12525ffd83dbSDimitry Andric 12538bcb0991SDimitry Andric template <class ELFT> 12548bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 12558bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::RawContentSection &Section, 12568bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 12578bcb0991SDimitry Andric if (Section.Info) 12588bcb0991SDimitry Andric SHeader.sh_info = *Section.Info; 12598bcb0991SDimitry Andric } 12608bcb0991SDimitry Andric 1261e8d8bef9SDimitry Andric static bool isMips64EL(const ELFYAML::Object &Obj) { 1262e8d8bef9SDimitry Andric return Obj.getMachine() == llvm::ELF::EM_MIPS && 1263e8d8bef9SDimitry Andric Obj.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64) && 1264e8d8bef9SDimitry Andric Obj.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB); 12658bcb0991SDimitry Andric } 12668bcb0991SDimitry Andric 12678bcb0991SDimitry Andric template <class ELFT> 12688bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 12698bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::RelocationSection &Section, 12708bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 12718bcb0991SDimitry Andric assert((Section.Type == llvm::ELF::SHT_REL || 12728bcb0991SDimitry Andric Section.Type == llvm::ELF::SHT_RELA) && 12738bcb0991SDimitry Andric "Section type is not SHT_REL nor SHT_RELA"); 12748bcb0991SDimitry Andric 12758bcb0991SDimitry Andric if (!Section.RelocatableSec.empty()) 12768bcb0991SDimitry Andric SHeader.sh_info = toSectionIndex(Section.RelocatableSec, Section.Name); 12778bcb0991SDimitry Andric 1278e8d8bef9SDimitry Andric if (!Section.Relocations) 1279e8d8bef9SDimitry Andric return; 1280e8d8bef9SDimitry Andric 1281e8d8bef9SDimitry Andric const bool IsRela = Section.Type == llvm::ELF::SHT_RELA; 1282e8d8bef9SDimitry Andric for (const ELFYAML::Relocation &Rel : *Section.Relocations) { 1283e8d8bef9SDimitry Andric const bool IsDynamic = Section.Link && (*Section.Link == ".dynsym"); 1284e8d8bef9SDimitry Andric unsigned SymIdx = 1285e8d8bef9SDimitry Andric Rel.Symbol ? toSymbolIndex(*Rel.Symbol, Section.Name, IsDynamic) : 0; 12868bcb0991SDimitry Andric if (IsRela) { 12878bcb0991SDimitry Andric Elf_Rela REntry; 12888bcb0991SDimitry Andric zero(REntry); 12898bcb0991SDimitry Andric REntry.r_offset = Rel.Offset; 12908bcb0991SDimitry Andric REntry.r_addend = Rel.Addend; 12918bcb0991SDimitry Andric REntry.setSymbolAndType(SymIdx, Rel.Type, isMips64EL(Doc)); 12925ffd83dbSDimitry Andric CBA.write((const char *)&REntry, sizeof(REntry)); 12938bcb0991SDimitry Andric } else { 12948bcb0991SDimitry Andric Elf_Rel REntry; 12958bcb0991SDimitry Andric zero(REntry); 12968bcb0991SDimitry Andric REntry.r_offset = Rel.Offset; 12978bcb0991SDimitry Andric REntry.setSymbolAndType(SymIdx, Rel.Type, isMips64EL(Doc)); 12985ffd83dbSDimitry Andric CBA.write((const char *)&REntry, sizeof(REntry)); 12998bcb0991SDimitry Andric } 13008bcb0991SDimitry Andric } 1301e8d8bef9SDimitry Andric 1302e8d8bef9SDimitry Andric SHeader.sh_size = (IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel)) * 1303e8d8bef9SDimitry Andric Section.Relocations->size(); 13048bcb0991SDimitry Andric } 13058bcb0991SDimitry Andric 13068bcb0991SDimitry Andric template <class ELFT> 1307480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 1308480093f4SDimitry Andric const ELFYAML::RelrSection &Section, 1309480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1310480093f4SDimitry Andric if (!Section.Entries) 1311480093f4SDimitry Andric return; 1312480093f4SDimitry Andric 1313480093f4SDimitry Andric for (llvm::yaml::Hex64 E : *Section.Entries) { 1314480093f4SDimitry Andric if (!ELFT::Is64Bits && E > UINT32_MAX) 1315480093f4SDimitry Andric reportError(Section.Name + ": the value is too large for 32-bits: 0x" + 1316480093f4SDimitry Andric Twine::utohexstr(E)); 13175ffd83dbSDimitry Andric CBA.write<uintX_t>(E, ELFT::TargetEndianness); 1318480093f4SDimitry Andric } 1319480093f4SDimitry Andric 1320480093f4SDimitry Andric SHeader.sh_size = sizeof(uintX_t) * Section.Entries->size(); 1321480093f4SDimitry Andric } 1322480093f4SDimitry Andric 1323480093f4SDimitry Andric template <class ELFT> 13248bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 13258bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::SymtabShndxSection &Shndx, 13268bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 1327e8d8bef9SDimitry Andric if (Shndx.Content || Shndx.Size) { 1328e8d8bef9SDimitry Andric SHeader.sh_size = writeContent(CBA, Shndx.Content, Shndx.Size); 1329e8d8bef9SDimitry Andric return; 1330e8d8bef9SDimitry Andric } 13318bcb0991SDimitry Andric 1332e8d8bef9SDimitry Andric if (!Shndx.Entries) 1333e8d8bef9SDimitry Andric return; 1334e8d8bef9SDimitry Andric 1335e8d8bef9SDimitry Andric for (uint32_t E : *Shndx.Entries) 1336e8d8bef9SDimitry Andric CBA.write<uint32_t>(E, ELFT::TargetEndianness); 1337e8d8bef9SDimitry Andric SHeader.sh_size = Shndx.Entries->size() * SHeader.sh_entsize; 13388bcb0991SDimitry Andric } 13398bcb0991SDimitry Andric 13408bcb0991SDimitry Andric template <class ELFT> 13418bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 1342e8d8bef9SDimitry Andric const ELFYAML::GroupSection &Section, 13438bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 13448bcb0991SDimitry Andric assert(Section.Type == llvm::ELF::SHT_GROUP && 13458bcb0991SDimitry Andric "Section type is not SHT_GROUP"); 13468bcb0991SDimitry Andric 1347480093f4SDimitry Andric if (Section.Signature) 13488bcb0991SDimitry Andric SHeader.sh_info = 1349480093f4SDimitry Andric toSymbolIndex(*Section.Signature, Section.Name, /*IsDynamic=*/false); 13508bcb0991SDimitry Andric 1351e8d8bef9SDimitry Andric if (!Section.Members) 1352e8d8bef9SDimitry Andric return; 1353e8d8bef9SDimitry Andric 1354e8d8bef9SDimitry Andric for (const ELFYAML::SectionOrType &Member : *Section.Members) { 13558bcb0991SDimitry Andric unsigned int SectionIndex = 0; 13568bcb0991SDimitry Andric if (Member.sectionNameOrType == "GRP_COMDAT") 13578bcb0991SDimitry Andric SectionIndex = llvm::ELF::GRP_COMDAT; 13588bcb0991SDimitry Andric else 13598bcb0991SDimitry Andric SectionIndex = toSectionIndex(Member.sectionNameOrType, Section.Name); 13605ffd83dbSDimitry Andric CBA.write<uint32_t>(SectionIndex, ELFT::TargetEndianness); 13618bcb0991SDimitry Andric } 1362e8d8bef9SDimitry Andric SHeader.sh_size = SHeader.sh_entsize * Section.Members->size(); 13638bcb0991SDimitry Andric } 13648bcb0991SDimitry Andric 13658bcb0991SDimitry Andric template <class ELFT> 13668bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 13678bcb0991SDimitry Andric const ELFYAML::SymverSection &Section, 13688bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 1369e8d8bef9SDimitry Andric if (!Section.Entries) 1370e8d8bef9SDimitry Andric return; 13718bcb0991SDimitry Andric 1372e8d8bef9SDimitry Andric for (uint16_t Version : *Section.Entries) 1373e8d8bef9SDimitry Andric CBA.write<uint16_t>(Version, ELFT::TargetEndianness); 1374e8d8bef9SDimitry Andric SHeader.sh_size = Section.Entries->size() * SHeader.sh_entsize; 13758bcb0991SDimitry Andric } 13768bcb0991SDimitry Andric 13778bcb0991SDimitry Andric template <class ELFT> 13788bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 13798bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::StackSizesSection &Section, 13808bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 1381e8d8bef9SDimitry Andric if (!Section.Entries) 13828bcb0991SDimitry Andric return; 1383e8d8bef9SDimitry Andric 13848bcb0991SDimitry Andric for (const ELFYAML::StackSizeEntry &E : *Section.Entries) { 13855ffd83dbSDimitry Andric CBA.write<uintX_t>(E.Address, ELFT::TargetEndianness); 13865ffd83dbSDimitry Andric SHeader.sh_size += sizeof(uintX_t) + CBA.writeULEB128(E.Size); 13878bcb0991SDimitry Andric } 13888bcb0991SDimitry Andric } 13898bcb0991SDimitry Andric 13908bcb0991SDimitry Andric template <class ELFT> 1391480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent( 1392e8d8bef9SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::BBAddrMapSection &Section, 1393480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1394*5f757f3fSDimitry Andric if (!Section.Entries) { 1395*5f757f3fSDimitry Andric if (Section.PGOAnalyses) 1396*5f757f3fSDimitry Andric WithColor::warning() 1397*5f757f3fSDimitry Andric << "PGOAnalyses should not exist in SHT_LLVM_BB_ADDR_MAP when " 1398*5f757f3fSDimitry Andric "Entries does not exist"; 1399480093f4SDimitry Andric return; 1400*5f757f3fSDimitry Andric } 1401e8d8bef9SDimitry Andric 1402*5f757f3fSDimitry Andric const std::vector<ELFYAML::PGOAnalysisMapEntry> *PGOAnalyses = nullptr; 1403*5f757f3fSDimitry Andric if (Section.PGOAnalyses) { 1404*5f757f3fSDimitry Andric if (Section.Entries->size() != Section.PGOAnalyses->size()) 1405*5f757f3fSDimitry Andric WithColor::warning() << "PGOAnalyses must be the same length as Entries " 1406*5f757f3fSDimitry Andric "in SHT_LLVM_BB_ADDR_MAP"; 1407*5f757f3fSDimitry Andric else 1408*5f757f3fSDimitry Andric PGOAnalyses = &Section.PGOAnalyses.value(); 1409*5f757f3fSDimitry Andric } 1410*5f757f3fSDimitry Andric 1411*5f757f3fSDimitry Andric for (const auto &[Idx, E] : llvm::enumerate(*Section.Entries)) { 141281ad6265SDimitry Andric // Write version and feature values. 141381ad6265SDimitry Andric if (Section.Type == llvm::ELF::SHT_LLVM_BB_ADDR_MAP) { 1414bdd1243dSDimitry Andric if (E.Version > 2) 141581ad6265SDimitry Andric WithColor::warning() << "unsupported SHT_LLVM_BB_ADDR_MAP version: " 141681ad6265SDimitry Andric << static_cast<int>(E.Version) 141781ad6265SDimitry Andric << "; encoding using the most recent version"; 141881ad6265SDimitry Andric CBA.write(E.Version); 141981ad6265SDimitry Andric CBA.write(E.Feature); 142081ad6265SDimitry Andric SHeader.sh_size += 2; 142181ad6265SDimitry Andric } 1422*5f757f3fSDimitry Andric 1423*5f757f3fSDimitry Andric if (Section.PGOAnalyses) { 1424*5f757f3fSDimitry Andric if (E.Version < 2) 1425*5f757f3fSDimitry Andric WithColor::warning() 1426*5f757f3fSDimitry Andric << "unsupported SHT_LLVM_BB_ADDR_MAP version when using PGO: " 1427*5f757f3fSDimitry Andric << static_cast<int>(E.Version) << "; must use version >= 2"; 1428*5f757f3fSDimitry Andric } 1429*5f757f3fSDimitry Andric 1430e8d8bef9SDimitry Andric // Write the address of the function. 1431e8d8bef9SDimitry Andric CBA.write<uintX_t>(E.Address, ELFT::TargetEndianness); 1432fe6060f1SDimitry Andric // Write number of BBEntries (number of basic blocks in the function). This 1433fe6060f1SDimitry Andric // is overridden by the 'NumBlocks' YAML field when specified. 1434fe6060f1SDimitry Andric uint64_t NumBlocks = 143581ad6265SDimitry Andric E.NumBlocks.value_or(E.BBEntries ? E.BBEntries->size() : 0); 1436e8d8bef9SDimitry Andric SHeader.sh_size += sizeof(uintX_t) + CBA.writeULEB128(NumBlocks); 1437e8d8bef9SDimitry Andric // Write all BBEntries. 1438*5f757f3fSDimitry Andric if (E.BBEntries) { 1439bdd1243dSDimitry Andric for (const ELFYAML::BBAddrMapEntry::BBEntry &BBE : *E.BBEntries) { 1440bdd1243dSDimitry Andric if (Section.Type == llvm::ELF::SHT_LLVM_BB_ADDR_MAP && E.Version > 1) 1441bdd1243dSDimitry Andric SHeader.sh_size += CBA.writeULEB128(BBE.ID); 1442e8d8bef9SDimitry Andric SHeader.sh_size += CBA.writeULEB128(BBE.AddressOffset) + 1443e8d8bef9SDimitry Andric CBA.writeULEB128(BBE.Size) + 1444e8d8bef9SDimitry Andric CBA.writeULEB128(BBE.Metadata); 1445e8d8bef9SDimitry Andric } 1446480093f4SDimitry Andric } 1447*5f757f3fSDimitry Andric 1448*5f757f3fSDimitry Andric if (!PGOAnalyses) 1449*5f757f3fSDimitry Andric continue; 1450*5f757f3fSDimitry Andric const ELFYAML::PGOAnalysisMapEntry &PGOEntry = PGOAnalyses->at(Idx); 1451*5f757f3fSDimitry Andric 1452*5f757f3fSDimitry Andric if (PGOEntry.FuncEntryCount) 1453*5f757f3fSDimitry Andric SHeader.sh_size += CBA.writeULEB128(*PGOEntry.FuncEntryCount); 1454*5f757f3fSDimitry Andric 1455*5f757f3fSDimitry Andric if (!PGOEntry.PGOBBEntries) 1456*5f757f3fSDimitry Andric continue; 1457*5f757f3fSDimitry Andric 1458*5f757f3fSDimitry Andric const auto &PGOBBEntries = PGOEntry.PGOBBEntries.value(); 1459*5f757f3fSDimitry Andric if (!E.BBEntries || E.BBEntries->size() != PGOBBEntries.size()) { 1460*5f757f3fSDimitry Andric WithColor::warning() << "PBOBBEntries must be the same length as " 1461*5f757f3fSDimitry Andric "BBEntries in SHT_LLVM_BB_ADDR_MAP.\n" 1462*5f757f3fSDimitry Andric << "Mismatch on function with address: " 1463*5f757f3fSDimitry Andric << E.Address; 1464*5f757f3fSDimitry Andric continue; 1465*5f757f3fSDimitry Andric } 1466*5f757f3fSDimitry Andric 1467*5f757f3fSDimitry Andric for (const auto &PGOBBE : PGOBBEntries) { 1468*5f757f3fSDimitry Andric if (PGOBBE.BBFreq) 1469*5f757f3fSDimitry Andric SHeader.sh_size += CBA.writeULEB128(*PGOBBE.BBFreq); 1470*5f757f3fSDimitry Andric if (PGOBBE.Successors) { 1471*5f757f3fSDimitry Andric SHeader.sh_size += CBA.writeULEB128(PGOBBE.Successors->size()); 1472*5f757f3fSDimitry Andric for (const auto &[ID, BrProb] : *PGOBBE.Successors) 1473*5f757f3fSDimitry Andric SHeader.sh_size += CBA.writeULEB128(ID) + CBA.writeULEB128(BrProb); 1474*5f757f3fSDimitry Andric } 1475*5f757f3fSDimitry Andric } 1476*5f757f3fSDimitry Andric } 1477bdd1243dSDimitry Andric } 1478480093f4SDimitry Andric 1479e8d8bef9SDimitry Andric template <class ELFT> 1480e8d8bef9SDimitry Andric void ELFState<ELFT>::writeSectionContent( 1481e8d8bef9SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::LinkerOptionsSection &Section, 1482e8d8bef9SDimitry Andric ContiguousBlobAccumulator &CBA) { 1483480093f4SDimitry Andric if (!Section.Options) 1484480093f4SDimitry Andric return; 1485480093f4SDimitry Andric 1486480093f4SDimitry Andric for (const ELFYAML::LinkerOption &LO : *Section.Options) { 14875ffd83dbSDimitry Andric CBA.write(LO.Key.data(), LO.Key.size()); 14885ffd83dbSDimitry Andric CBA.write('\0'); 14895ffd83dbSDimitry Andric CBA.write(LO.Value.data(), LO.Value.size()); 14905ffd83dbSDimitry Andric CBA.write('\0'); 1491480093f4SDimitry Andric SHeader.sh_size += (LO.Key.size() + LO.Value.size() + 2); 1492480093f4SDimitry Andric } 1493480093f4SDimitry Andric } 1494480093f4SDimitry Andric 1495480093f4SDimitry Andric template <class ELFT> 1496480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent( 1497480093f4SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::DependentLibrariesSection &Section, 1498480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1499480093f4SDimitry Andric if (!Section.Libs) 1500480093f4SDimitry Andric return; 1501480093f4SDimitry Andric 1502480093f4SDimitry Andric for (StringRef Lib : *Section.Libs) { 15035ffd83dbSDimitry Andric CBA.write(Lib.data(), Lib.size()); 15045ffd83dbSDimitry Andric CBA.write('\0'); 1505480093f4SDimitry Andric SHeader.sh_size += Lib.size() + 1; 1506480093f4SDimitry Andric } 1507480093f4SDimitry Andric } 1508480093f4SDimitry Andric 1509480093f4SDimitry Andric template <class ELFT> 15105ffd83dbSDimitry Andric uint64_t 15115ffd83dbSDimitry Andric ELFState<ELFT>::alignToOffset(ContiguousBlobAccumulator &CBA, uint64_t Align, 1512bdd1243dSDimitry Andric std::optional<llvm::yaml::Hex64> Offset) { 15135ffd83dbSDimitry Andric uint64_t CurrentOffset = CBA.getOffset(); 15145ffd83dbSDimitry Andric uint64_t AlignedOffset; 15155ffd83dbSDimitry Andric 15165ffd83dbSDimitry Andric if (Offset) { 15175ffd83dbSDimitry Andric if ((uint64_t)*Offset < CurrentOffset) { 15185ffd83dbSDimitry Andric reportError("the 'Offset' value (0x" + 15195ffd83dbSDimitry Andric Twine::utohexstr((uint64_t)*Offset) + ") goes backward"); 15205ffd83dbSDimitry Andric return CurrentOffset; 15215ffd83dbSDimitry Andric } 15225ffd83dbSDimitry Andric 15235ffd83dbSDimitry Andric // We ignore an alignment when an explicit offset has been requested. 15245ffd83dbSDimitry Andric AlignedOffset = *Offset; 15255ffd83dbSDimitry Andric } else { 15265ffd83dbSDimitry Andric AlignedOffset = alignTo(CurrentOffset, std::max(Align, (uint64_t)1)); 15275ffd83dbSDimitry Andric } 15285ffd83dbSDimitry Andric 15295ffd83dbSDimitry Andric CBA.writeZeros(AlignedOffset - CurrentOffset); 15305ffd83dbSDimitry Andric return AlignedOffset; 15315ffd83dbSDimitry Andric } 15325ffd83dbSDimitry Andric 15335ffd83dbSDimitry Andric template <class ELFT> 15345ffd83dbSDimitry Andric void ELFState<ELFT>::writeSectionContent( 15355ffd83dbSDimitry Andric Elf_Shdr &SHeader, const ELFYAML::CallGraphProfileSection &Section, 15365ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA) { 15375ffd83dbSDimitry Andric if (!Section.Entries) 15385ffd83dbSDimitry Andric return; 15395ffd83dbSDimitry Andric 1540fe6060f1SDimitry Andric for (const ELFYAML::CallGraphEntryWeight &E : *Section.Entries) { 15415ffd83dbSDimitry Andric CBA.write<uint64_t>(E.Weight, ELFT::TargetEndianness); 1542fe6060f1SDimitry Andric SHeader.sh_size += sizeof(object::Elf_CGProfile_Impl<ELFT>); 15435ffd83dbSDimitry Andric } 15445ffd83dbSDimitry Andric } 15455ffd83dbSDimitry Andric 15465ffd83dbSDimitry Andric template <class ELFT> 15478bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 15488bcb0991SDimitry Andric const ELFYAML::HashSection &Section, 15498bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 1550e8d8bef9SDimitry Andric if (!Section.Bucket) 15518bcb0991SDimitry Andric return; 1552e8d8bef9SDimitry Andric 15535ffd83dbSDimitry Andric CBA.write<uint32_t>( 155481ad6265SDimitry Andric Section.NBucket.value_or(llvm::yaml::Hex64(Section.Bucket->size())), 15558bcb0991SDimitry Andric ELFT::TargetEndianness); 15565ffd83dbSDimitry Andric CBA.write<uint32_t>( 155781ad6265SDimitry Andric Section.NChain.value_or(llvm::yaml::Hex64(Section.Chain->size())), 15588bcb0991SDimitry Andric ELFT::TargetEndianness); 15595ffd83dbSDimitry Andric 15608bcb0991SDimitry Andric for (uint32_t Val : *Section.Bucket) 15615ffd83dbSDimitry Andric CBA.write<uint32_t>(Val, ELFT::TargetEndianness); 15628bcb0991SDimitry Andric for (uint32_t Val : *Section.Chain) 15635ffd83dbSDimitry Andric CBA.write<uint32_t>(Val, ELFT::TargetEndianness); 15648bcb0991SDimitry Andric 15658bcb0991SDimitry Andric SHeader.sh_size = (2 + Section.Bucket->size() + Section.Chain->size()) * 4; 15668bcb0991SDimitry Andric } 15678bcb0991SDimitry Andric 15688bcb0991SDimitry Andric template <class ELFT> 15698bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 15708bcb0991SDimitry Andric const ELFYAML::VerdefSection &Section, 15718bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 15728bcb0991SDimitry Andric 1573e8d8bef9SDimitry Andric if (Section.Info) 1574e8d8bef9SDimitry Andric SHeader.sh_info = *Section.Info; 1575e8d8bef9SDimitry Andric else if (Section.Entries) 1576e8d8bef9SDimitry Andric SHeader.sh_info = Section.Entries->size(); 1577480093f4SDimitry Andric 1578480093f4SDimitry Andric if (!Section.Entries) 1579480093f4SDimitry Andric return; 1580480093f4SDimitry Andric 15818bcb0991SDimitry Andric uint64_t AuxCnt = 0; 1582480093f4SDimitry Andric for (size_t I = 0; I < Section.Entries->size(); ++I) { 1583480093f4SDimitry Andric const ELFYAML::VerdefEntry &E = (*Section.Entries)[I]; 15848bcb0991SDimitry Andric 15858bcb0991SDimitry Andric Elf_Verdef VerDef; 158681ad6265SDimitry Andric VerDef.vd_version = E.Version.value_or(1); 158781ad6265SDimitry Andric VerDef.vd_flags = E.Flags.value_or(0); 158881ad6265SDimitry Andric VerDef.vd_ndx = E.VersionNdx.value_or(0); 158981ad6265SDimitry Andric VerDef.vd_hash = E.Hash.value_or(0); 15908bcb0991SDimitry Andric VerDef.vd_aux = sizeof(Elf_Verdef); 15918bcb0991SDimitry Andric VerDef.vd_cnt = E.VerNames.size(); 1592480093f4SDimitry Andric if (I == Section.Entries->size() - 1) 15938bcb0991SDimitry Andric VerDef.vd_next = 0; 15948bcb0991SDimitry Andric else 15958bcb0991SDimitry Andric VerDef.vd_next = 15968bcb0991SDimitry Andric sizeof(Elf_Verdef) + E.VerNames.size() * sizeof(Elf_Verdaux); 15975ffd83dbSDimitry Andric CBA.write((const char *)&VerDef, sizeof(Elf_Verdef)); 15988bcb0991SDimitry Andric 15998bcb0991SDimitry Andric for (size_t J = 0; J < E.VerNames.size(); ++J, ++AuxCnt) { 16008bcb0991SDimitry Andric Elf_Verdaux VernAux; 16018bcb0991SDimitry Andric VernAux.vda_name = DotDynstr.getOffset(E.VerNames[J]); 16028bcb0991SDimitry Andric if (J == E.VerNames.size() - 1) 16038bcb0991SDimitry Andric VernAux.vda_next = 0; 16048bcb0991SDimitry Andric else 16058bcb0991SDimitry Andric VernAux.vda_next = sizeof(Elf_Verdaux); 16065ffd83dbSDimitry Andric CBA.write((const char *)&VernAux, sizeof(Elf_Verdaux)); 16078bcb0991SDimitry Andric } 16088bcb0991SDimitry Andric } 16098bcb0991SDimitry Andric 1610480093f4SDimitry Andric SHeader.sh_size = Section.Entries->size() * sizeof(Elf_Verdef) + 16118bcb0991SDimitry Andric AuxCnt * sizeof(Elf_Verdaux); 16128bcb0991SDimitry Andric } 16138bcb0991SDimitry Andric 16148bcb0991SDimitry Andric template <class ELFT> 16158bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 16168bcb0991SDimitry Andric const ELFYAML::VerneedSection &Section, 16178bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 1618e8d8bef9SDimitry Andric if (Section.Info) 1619e8d8bef9SDimitry Andric SHeader.sh_info = *Section.Info; 1620e8d8bef9SDimitry Andric else if (Section.VerneedV) 1621e8d8bef9SDimitry Andric SHeader.sh_info = Section.VerneedV->size(); 1622480093f4SDimitry Andric 1623480093f4SDimitry Andric if (!Section.VerneedV) 1624480093f4SDimitry Andric return; 16258bcb0991SDimitry Andric 16268bcb0991SDimitry Andric uint64_t AuxCnt = 0; 1627480093f4SDimitry Andric for (size_t I = 0; I < Section.VerneedV->size(); ++I) { 1628480093f4SDimitry Andric const ELFYAML::VerneedEntry &VE = (*Section.VerneedV)[I]; 16298bcb0991SDimitry Andric 16308bcb0991SDimitry Andric Elf_Verneed VerNeed; 16318bcb0991SDimitry Andric VerNeed.vn_version = VE.Version; 16328bcb0991SDimitry Andric VerNeed.vn_file = DotDynstr.getOffset(VE.File); 1633480093f4SDimitry Andric if (I == Section.VerneedV->size() - 1) 16348bcb0991SDimitry Andric VerNeed.vn_next = 0; 16358bcb0991SDimitry Andric else 16368bcb0991SDimitry Andric VerNeed.vn_next = 16378bcb0991SDimitry Andric sizeof(Elf_Verneed) + VE.AuxV.size() * sizeof(Elf_Vernaux); 16388bcb0991SDimitry Andric VerNeed.vn_cnt = VE.AuxV.size(); 16398bcb0991SDimitry Andric VerNeed.vn_aux = sizeof(Elf_Verneed); 16405ffd83dbSDimitry Andric CBA.write((const char *)&VerNeed, sizeof(Elf_Verneed)); 16418bcb0991SDimitry Andric 16428bcb0991SDimitry Andric for (size_t J = 0; J < VE.AuxV.size(); ++J, ++AuxCnt) { 16438bcb0991SDimitry Andric const ELFYAML::VernauxEntry &VAuxE = VE.AuxV[J]; 16448bcb0991SDimitry Andric 16458bcb0991SDimitry Andric Elf_Vernaux VernAux; 16468bcb0991SDimitry Andric VernAux.vna_hash = VAuxE.Hash; 16478bcb0991SDimitry Andric VernAux.vna_flags = VAuxE.Flags; 16488bcb0991SDimitry Andric VernAux.vna_other = VAuxE.Other; 16498bcb0991SDimitry Andric VernAux.vna_name = DotDynstr.getOffset(VAuxE.Name); 16508bcb0991SDimitry Andric if (J == VE.AuxV.size() - 1) 16518bcb0991SDimitry Andric VernAux.vna_next = 0; 16528bcb0991SDimitry Andric else 16538bcb0991SDimitry Andric VernAux.vna_next = sizeof(Elf_Vernaux); 16545ffd83dbSDimitry Andric CBA.write((const char *)&VernAux, sizeof(Elf_Vernaux)); 16558bcb0991SDimitry Andric } 16568bcb0991SDimitry Andric } 16578bcb0991SDimitry Andric 1658480093f4SDimitry Andric SHeader.sh_size = Section.VerneedV->size() * sizeof(Elf_Verneed) + 16598bcb0991SDimitry Andric AuxCnt * sizeof(Elf_Vernaux); 16608bcb0991SDimitry Andric } 16618bcb0991SDimitry Andric 16628bcb0991SDimitry Andric template <class ELFT> 1663e8d8bef9SDimitry Andric void ELFState<ELFT>::writeSectionContent( 1664e8d8bef9SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::ARMIndexTableSection &Section, 1665e8d8bef9SDimitry Andric ContiguousBlobAccumulator &CBA) { 1666e8d8bef9SDimitry Andric if (!Section.Entries) 1667e8d8bef9SDimitry Andric return; 1668e8d8bef9SDimitry Andric 1669e8d8bef9SDimitry Andric for (const ELFYAML::ARMIndexTableEntry &E : *Section.Entries) { 1670e8d8bef9SDimitry Andric CBA.write<uint32_t>(E.Offset, ELFT::TargetEndianness); 1671e8d8bef9SDimitry Andric CBA.write<uint32_t>(E.Value, ELFT::TargetEndianness); 1672e8d8bef9SDimitry Andric } 1673e8d8bef9SDimitry Andric SHeader.sh_size = Section.Entries->size() * 8; 1674e8d8bef9SDimitry Andric } 1675e8d8bef9SDimitry Andric 1676e8d8bef9SDimitry Andric template <class ELFT> 16778bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 16788bcb0991SDimitry Andric const ELFYAML::MipsABIFlags &Section, 16798bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 16808bcb0991SDimitry Andric assert(Section.Type == llvm::ELF::SHT_MIPS_ABIFLAGS && 16818bcb0991SDimitry Andric "Section type is not SHT_MIPS_ABIFLAGS"); 16828bcb0991SDimitry Andric 16838bcb0991SDimitry Andric object::Elf_Mips_ABIFlags<ELFT> Flags; 16848bcb0991SDimitry Andric zero(Flags); 16858bcb0991SDimitry Andric SHeader.sh_size = SHeader.sh_entsize; 16868bcb0991SDimitry Andric 16878bcb0991SDimitry Andric Flags.version = Section.Version; 16888bcb0991SDimitry Andric Flags.isa_level = Section.ISALevel; 16898bcb0991SDimitry Andric Flags.isa_rev = Section.ISARevision; 16908bcb0991SDimitry Andric Flags.gpr_size = Section.GPRSize; 16918bcb0991SDimitry Andric Flags.cpr1_size = Section.CPR1Size; 16928bcb0991SDimitry Andric Flags.cpr2_size = Section.CPR2Size; 16938bcb0991SDimitry Andric Flags.fp_abi = Section.FpABI; 16948bcb0991SDimitry Andric Flags.isa_ext = Section.ISAExtension; 16958bcb0991SDimitry Andric Flags.ases = Section.ASEs; 16968bcb0991SDimitry Andric Flags.flags1 = Section.Flags1; 16978bcb0991SDimitry Andric Flags.flags2 = Section.Flags2; 16985ffd83dbSDimitry Andric CBA.write((const char *)&Flags, sizeof(Flags)); 16998bcb0991SDimitry Andric } 17008bcb0991SDimitry Andric 17018bcb0991SDimitry Andric template <class ELFT> 17028bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 17038bcb0991SDimitry Andric const ELFYAML::DynamicSection &Section, 17048bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 17058bcb0991SDimitry Andric assert(Section.Type == llvm::ELF::SHT_DYNAMIC && 17068bcb0991SDimitry Andric "Section type is not SHT_DYNAMIC"); 17078bcb0991SDimitry Andric 1708e8d8bef9SDimitry Andric if (!Section.Entries) 1709e8d8bef9SDimitry Andric return; 17108bcb0991SDimitry Andric 1711e8d8bef9SDimitry Andric for (const ELFYAML::DynamicEntry &DE : *Section.Entries) { 17125ffd83dbSDimitry Andric CBA.write<uintX_t>(DE.Tag, ELFT::TargetEndianness); 17135ffd83dbSDimitry Andric CBA.write<uintX_t>(DE.Val, ELFT::TargetEndianness); 17148bcb0991SDimitry Andric } 1715e8d8bef9SDimitry Andric SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries->size(); 17168bcb0991SDimitry Andric } 17178bcb0991SDimitry Andric 17188bcb0991SDimitry Andric template <class ELFT> 17198bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 17208bcb0991SDimitry Andric const ELFYAML::AddrsigSection &Section, 17218bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 1722e8d8bef9SDimitry Andric if (!Section.Symbols) 17238bcb0991SDimitry Andric return; 1724e8d8bef9SDimitry Andric 17255ffd83dbSDimitry Andric for (StringRef Sym : *Section.Symbols) 17265ffd83dbSDimitry Andric SHeader.sh_size += 17275ffd83dbSDimitry Andric CBA.writeULEB128(toSymbolIndex(Sym, Section.Name, /*IsDynamic=*/false)); 17288bcb0991SDimitry Andric } 17298bcb0991SDimitry Andric 1730480093f4SDimitry Andric template <class ELFT> 1731480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 1732480093f4SDimitry Andric const ELFYAML::NoteSection &Section, 1733480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1734e8d8bef9SDimitry Andric if (!Section.Notes) 1735480093f4SDimitry Andric return; 1736480093f4SDimitry Andric 1737e8d8bef9SDimitry Andric uint64_t Offset = CBA.tell(); 1738480093f4SDimitry Andric for (const ELFYAML::NoteEntry &NE : *Section.Notes) { 1739480093f4SDimitry Andric // Write name size. 1740480093f4SDimitry Andric if (NE.Name.empty()) 17415ffd83dbSDimitry Andric CBA.write<uint32_t>(0, ELFT::TargetEndianness); 1742480093f4SDimitry Andric else 17435ffd83dbSDimitry Andric CBA.write<uint32_t>(NE.Name.size() + 1, ELFT::TargetEndianness); 1744480093f4SDimitry Andric 1745480093f4SDimitry Andric // Write description size. 1746480093f4SDimitry Andric if (NE.Desc.binary_size() == 0) 17475ffd83dbSDimitry Andric CBA.write<uint32_t>(0, ELFT::TargetEndianness); 1748480093f4SDimitry Andric else 17495ffd83dbSDimitry Andric CBA.write<uint32_t>(NE.Desc.binary_size(), ELFT::TargetEndianness); 1750480093f4SDimitry Andric 1751480093f4SDimitry Andric // Write type. 17525ffd83dbSDimitry Andric CBA.write<uint32_t>(NE.Type, ELFT::TargetEndianness); 1753480093f4SDimitry Andric 1754480093f4SDimitry Andric // Write name, null terminator and padding. 1755480093f4SDimitry Andric if (!NE.Name.empty()) { 17565ffd83dbSDimitry Andric CBA.write(NE.Name.data(), NE.Name.size()); 17575ffd83dbSDimitry Andric CBA.write('\0'); 1758480093f4SDimitry Andric CBA.padToAlignment(4); 1759480093f4SDimitry Andric } 1760480093f4SDimitry Andric 1761480093f4SDimitry Andric // Write description and padding. 1762480093f4SDimitry Andric if (NE.Desc.binary_size() != 0) { 17635ffd83dbSDimitry Andric CBA.writeAsBinary(NE.Desc); 1764480093f4SDimitry Andric CBA.padToAlignment(4); 1765480093f4SDimitry Andric } 1766480093f4SDimitry Andric } 1767480093f4SDimitry Andric 17685ffd83dbSDimitry Andric SHeader.sh_size = CBA.tell() - Offset; 1769480093f4SDimitry Andric } 1770480093f4SDimitry Andric 1771480093f4SDimitry Andric template <class ELFT> 1772480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 1773480093f4SDimitry Andric const ELFYAML::GnuHashSection &Section, 1774480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1775e8d8bef9SDimitry Andric if (!Section.HashBuckets) 1776480093f4SDimitry Andric return; 1777e8d8bef9SDimitry Andric 1778e8d8bef9SDimitry Andric if (!Section.Header) 1779e8d8bef9SDimitry Andric return; 1780480093f4SDimitry Andric 1781480093f4SDimitry Andric // We write the header first, starting with the hash buckets count. Normally 1782480093f4SDimitry Andric // it is the number of entries in HashBuckets, but the "NBuckets" property can 1783480093f4SDimitry Andric // be used to override this field, which is useful for producing broken 1784480093f4SDimitry Andric // objects. 1785480093f4SDimitry Andric if (Section.Header->NBuckets) 17865ffd83dbSDimitry Andric CBA.write<uint32_t>(*Section.Header->NBuckets, ELFT::TargetEndianness); 1787480093f4SDimitry Andric else 17885ffd83dbSDimitry Andric CBA.write<uint32_t>(Section.HashBuckets->size(), ELFT::TargetEndianness); 1789480093f4SDimitry Andric 1790480093f4SDimitry Andric // Write the index of the first symbol in the dynamic symbol table accessible 1791480093f4SDimitry Andric // via the hash table. 17925ffd83dbSDimitry Andric CBA.write<uint32_t>(Section.Header->SymNdx, ELFT::TargetEndianness); 1793480093f4SDimitry Andric 1794480093f4SDimitry Andric // Write the number of words in the Bloom filter. As above, the "MaskWords" 1795480093f4SDimitry Andric // property can be used to set this field to any value. 1796480093f4SDimitry Andric if (Section.Header->MaskWords) 17975ffd83dbSDimitry Andric CBA.write<uint32_t>(*Section.Header->MaskWords, ELFT::TargetEndianness); 1798480093f4SDimitry Andric else 17995ffd83dbSDimitry Andric CBA.write<uint32_t>(Section.BloomFilter->size(), ELFT::TargetEndianness); 1800480093f4SDimitry Andric 1801480093f4SDimitry Andric // Write the shift constant used by the Bloom filter. 18025ffd83dbSDimitry Andric CBA.write<uint32_t>(Section.Header->Shift2, ELFT::TargetEndianness); 1803480093f4SDimitry Andric 1804480093f4SDimitry Andric // We've finished writing the header. Now write the Bloom filter. 1805480093f4SDimitry Andric for (llvm::yaml::Hex64 Val : *Section.BloomFilter) 18065ffd83dbSDimitry Andric CBA.write<uintX_t>(Val, ELFT::TargetEndianness); 1807480093f4SDimitry Andric 1808480093f4SDimitry Andric // Write an array of hash buckets. 1809480093f4SDimitry Andric for (llvm::yaml::Hex32 Val : *Section.HashBuckets) 18105ffd83dbSDimitry Andric CBA.write<uint32_t>(Val, ELFT::TargetEndianness); 1811480093f4SDimitry Andric 1812480093f4SDimitry Andric // Write an array of hash values. 1813480093f4SDimitry Andric for (llvm::yaml::Hex32 Val : *Section.HashValues) 18145ffd83dbSDimitry Andric CBA.write<uint32_t>(Val, ELFT::TargetEndianness); 1815480093f4SDimitry Andric 1816480093f4SDimitry Andric SHeader.sh_size = 16 /*Header size*/ + 1817480093f4SDimitry Andric Section.BloomFilter->size() * sizeof(typename ELFT::uint) + 1818480093f4SDimitry Andric Section.HashBuckets->size() * 4 + 1819480093f4SDimitry Andric Section.HashValues->size() * 4; 1820480093f4SDimitry Andric } 1821480093f4SDimitry Andric 1822480093f4SDimitry Andric template <class ELFT> 1823480093f4SDimitry Andric void ELFState<ELFT>::writeFill(ELFYAML::Fill &Fill, 1824480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1825480093f4SDimitry Andric size_t PatternSize = Fill.Pattern ? Fill.Pattern->binary_size() : 0; 1826480093f4SDimitry Andric if (!PatternSize) { 18275ffd83dbSDimitry Andric CBA.writeZeros(Fill.Size); 1828480093f4SDimitry Andric return; 1829480093f4SDimitry Andric } 1830480093f4SDimitry Andric 1831480093f4SDimitry Andric // Fill the content with the specified pattern. 1832480093f4SDimitry Andric uint64_t Written = 0; 1833480093f4SDimitry Andric for (; Written + PatternSize <= Fill.Size; Written += PatternSize) 18345ffd83dbSDimitry Andric CBA.writeAsBinary(*Fill.Pattern); 18355ffd83dbSDimitry Andric CBA.writeAsBinary(*Fill.Pattern, Fill.Size - Written); 18365ffd83dbSDimitry Andric } 18375ffd83dbSDimitry Andric 18385ffd83dbSDimitry Andric template <class ELFT> 18395ffd83dbSDimitry Andric DenseMap<StringRef, size_t> ELFState<ELFT>::buildSectionHeaderReorderMap() { 1840e8d8bef9SDimitry Andric const ELFYAML::SectionHeaderTable &SectionHeaders = 1841e8d8bef9SDimitry Andric Doc.getSectionHeaderTable(); 1842fe6060f1SDimitry Andric if (SectionHeaders.IsImplicit || SectionHeaders.NoHeaders || 1843fe6060f1SDimitry Andric SectionHeaders.isDefault()) 18445ffd83dbSDimitry Andric return DenseMap<StringRef, size_t>(); 18455ffd83dbSDimitry Andric 18465ffd83dbSDimitry Andric DenseMap<StringRef, size_t> Ret; 18475ffd83dbSDimitry Andric size_t SecNdx = 0; 18485ffd83dbSDimitry Andric StringSet<> Seen; 18495ffd83dbSDimitry Andric 18505ffd83dbSDimitry Andric auto AddSection = [&](const ELFYAML::SectionHeader &Hdr) { 18515ffd83dbSDimitry Andric if (!Ret.try_emplace(Hdr.Name, ++SecNdx).second) 18525ffd83dbSDimitry Andric reportError("repeated section name: '" + Hdr.Name + 18535ffd83dbSDimitry Andric "' in the section header description"); 18545ffd83dbSDimitry Andric Seen.insert(Hdr.Name); 18555ffd83dbSDimitry Andric }; 18565ffd83dbSDimitry Andric 1857e8d8bef9SDimitry Andric if (SectionHeaders.Sections) 1858e8d8bef9SDimitry Andric for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Sections) 18595ffd83dbSDimitry Andric AddSection(Hdr); 18605ffd83dbSDimitry Andric 1861e8d8bef9SDimitry Andric if (SectionHeaders.Excluded) 1862e8d8bef9SDimitry Andric for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Excluded) 18635ffd83dbSDimitry Andric AddSection(Hdr); 18645ffd83dbSDimitry Andric 18655ffd83dbSDimitry Andric for (const ELFYAML::Section *S : Doc.getSections()) { 18665ffd83dbSDimitry Andric // Ignore special first SHT_NULL section. 18675ffd83dbSDimitry Andric if (S == Doc.getSections().front()) 18685ffd83dbSDimitry Andric continue; 18695ffd83dbSDimitry Andric if (!Seen.count(S->Name)) 18705ffd83dbSDimitry Andric reportError("section '" + S->Name + 18715ffd83dbSDimitry Andric "' should be present in the 'Sections' or 'Excluded' lists"); 18725ffd83dbSDimitry Andric Seen.erase(S->Name); 18735ffd83dbSDimitry Andric } 18745ffd83dbSDimitry Andric 18755ffd83dbSDimitry Andric for (const auto &It : Seen) 18765ffd83dbSDimitry Andric reportError("section header contains undefined section '" + It.getKey() + 18775ffd83dbSDimitry Andric "'"); 18785ffd83dbSDimitry Andric return Ret; 1879480093f4SDimitry Andric } 1880480093f4SDimitry Andric 18818bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::buildSectionIndex() { 18825ffd83dbSDimitry Andric // A YAML description can have an explicit section header declaration that 18835ffd83dbSDimitry Andric // allows to change the order of section headers. 18845ffd83dbSDimitry Andric DenseMap<StringRef, size_t> ReorderMap = buildSectionHeaderReorderMap(); 18855ffd83dbSDimitry Andric 18865ffd83dbSDimitry Andric if (HasError) 18875ffd83dbSDimitry Andric return; 18885ffd83dbSDimitry Andric 18895ffd83dbSDimitry Andric // Build excluded section headers map. 18905ffd83dbSDimitry Andric std::vector<ELFYAML::Section *> Sections = Doc.getSections(); 1891e8d8bef9SDimitry Andric const ELFYAML::SectionHeaderTable &SectionHeaders = 1892e8d8bef9SDimitry Andric Doc.getSectionHeaderTable(); 1893e8d8bef9SDimitry Andric if (SectionHeaders.Excluded) 1894e8d8bef9SDimitry Andric for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Excluded) 18955ffd83dbSDimitry Andric if (!ExcludedSectionHeaders.insert(Hdr.Name).second) 18965ffd83dbSDimitry Andric llvm_unreachable("buildSectionIndex() failed"); 18975ffd83dbSDimitry Andric 189881ad6265SDimitry Andric if (SectionHeaders.NoHeaders.value_or(false)) 18995ffd83dbSDimitry Andric for (const ELFYAML::Section *S : Sections) 19005ffd83dbSDimitry Andric if (!ExcludedSectionHeaders.insert(S->Name).second) 19015ffd83dbSDimitry Andric llvm_unreachable("buildSectionIndex() failed"); 19025ffd83dbSDimitry Andric 1903480093f4SDimitry Andric size_t SecNdx = -1; 19045ffd83dbSDimitry Andric for (const ELFYAML::Section *S : Sections) { 1905480093f4SDimitry Andric ++SecNdx; 1906480093f4SDimitry Andric 19075ffd83dbSDimitry Andric size_t Index = ReorderMap.empty() ? SecNdx : ReorderMap.lookup(S->Name); 19085ffd83dbSDimitry Andric if (!SN2I.addName(S->Name, Index)) 1909480093f4SDimitry Andric llvm_unreachable("buildSectionIndex() failed"); 19105ffd83dbSDimitry Andric 19115ffd83dbSDimitry Andric if (!ExcludedSectionHeaders.count(S->Name)) 1912fe6060f1SDimitry Andric ShStrtabStrings->add(ELFYAML::dropUniqueSuffix(S->Name)); 19138bcb0991SDimitry Andric } 19148bcb0991SDimitry Andric } 19158bcb0991SDimitry Andric 19168bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::buildSymbolIndexes() { 19178bcb0991SDimitry Andric auto Build = [this](ArrayRef<ELFYAML::Symbol> V, NameToIdxMap &Map) { 19188bcb0991SDimitry Andric for (size_t I = 0, S = V.size(); I < S; ++I) { 19198bcb0991SDimitry Andric const ELFYAML::Symbol &Sym = V[I]; 19208bcb0991SDimitry Andric if (!Sym.Name.empty() && !Map.addName(Sym.Name, I + 1)) 19218bcb0991SDimitry Andric reportError("repeated symbol name: '" + Sym.Name + "'"); 19228bcb0991SDimitry Andric } 19238bcb0991SDimitry Andric }; 19248bcb0991SDimitry Andric 19258bcb0991SDimitry Andric if (Doc.Symbols) 19268bcb0991SDimitry Andric Build(*Doc.Symbols, SymN2I); 1927480093f4SDimitry Andric if (Doc.DynamicSymbols) 1928480093f4SDimitry Andric Build(*Doc.DynamicSymbols, DynSymN2I); 19298bcb0991SDimitry Andric } 19308bcb0991SDimitry Andric 19318bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::finalizeStrings() { 19328bcb0991SDimitry Andric // Add the regular symbol names to .strtab section. 19338bcb0991SDimitry Andric if (Doc.Symbols) 19348bcb0991SDimitry Andric for (const ELFYAML::Symbol &Sym : *Doc.Symbols) 19358bcb0991SDimitry Andric DotStrtab.add(ELFYAML::dropUniqueSuffix(Sym.Name)); 19368bcb0991SDimitry Andric DotStrtab.finalize(); 19378bcb0991SDimitry Andric 19388bcb0991SDimitry Andric // Add the dynamic symbol names to .dynstr section. 1939480093f4SDimitry Andric if (Doc.DynamicSymbols) 1940480093f4SDimitry Andric for (const ELFYAML::Symbol &Sym : *Doc.DynamicSymbols) 19418bcb0991SDimitry Andric DotDynstr.add(ELFYAML::dropUniqueSuffix(Sym.Name)); 19428bcb0991SDimitry Andric 19438bcb0991SDimitry Andric // SHT_GNU_verdef and SHT_GNU_verneed sections might also 19448bcb0991SDimitry Andric // add strings to .dynstr section. 1945480093f4SDimitry Andric for (const ELFYAML::Chunk *Sec : Doc.getSections()) { 1946480093f4SDimitry Andric if (auto VerNeed = dyn_cast<ELFYAML::VerneedSection>(Sec)) { 1947480093f4SDimitry Andric if (VerNeed->VerneedV) { 1948480093f4SDimitry Andric for (const ELFYAML::VerneedEntry &VE : *VerNeed->VerneedV) { 19498bcb0991SDimitry Andric DotDynstr.add(VE.File); 19508bcb0991SDimitry Andric for (const ELFYAML::VernauxEntry &Aux : VE.AuxV) 19518bcb0991SDimitry Andric DotDynstr.add(Aux.Name); 19528bcb0991SDimitry Andric } 1953480093f4SDimitry Andric } 1954480093f4SDimitry Andric } else if (auto VerDef = dyn_cast<ELFYAML::VerdefSection>(Sec)) { 1955480093f4SDimitry Andric if (VerDef->Entries) 1956480093f4SDimitry Andric for (const ELFYAML::VerdefEntry &E : *VerDef->Entries) 19578bcb0991SDimitry Andric for (StringRef Name : E.VerNames) 19588bcb0991SDimitry Andric DotDynstr.add(Name); 19598bcb0991SDimitry Andric } 19608bcb0991SDimitry Andric } 19618bcb0991SDimitry Andric 19628bcb0991SDimitry Andric DotDynstr.finalize(); 1963fe6060f1SDimitry Andric 1964fe6060f1SDimitry Andric // Don't finalize the section header string table a second time if it has 1965fe6060f1SDimitry Andric // already been finalized due to being one of the symbol string tables. 1966fe6060f1SDimitry Andric if (ShStrtabStrings != &DotStrtab && ShStrtabStrings != &DotDynstr) 1967fe6060f1SDimitry Andric ShStrtabStrings->finalize(); 19688bcb0991SDimitry Andric } 19698bcb0991SDimitry Andric 19708bcb0991SDimitry Andric template <class ELFT> 19718bcb0991SDimitry Andric bool ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc, 19725ffd83dbSDimitry Andric yaml::ErrorHandler EH, uint64_t MaxSize) { 19738bcb0991SDimitry Andric ELFState<ELFT> State(Doc, EH); 19745ffd83dbSDimitry Andric if (State.HasError) 19755ffd83dbSDimitry Andric return false; 19768bcb0991SDimitry Andric 1977fe6060f1SDimitry Andric // Build the section index, which adds sections to the section header string 1978fe6060f1SDimitry Andric // table first, so that we can finalize the section header string table. 19798bcb0991SDimitry Andric State.buildSectionIndex(); 19805ffd83dbSDimitry Andric State.buildSymbolIndexes(); 19815ffd83dbSDimitry Andric 1982fe6060f1SDimitry Andric // Finalize section header string table and the .strtab and .dynstr sections. 1983fe6060f1SDimitry Andric // We do this early because we want to finalize the string table builders 1984fe6060f1SDimitry Andric // before writing the content of the sections that might want to use them. 1985fe6060f1SDimitry Andric State.finalizeStrings(); 1986fe6060f1SDimitry Andric 1987480093f4SDimitry Andric if (State.HasError) 1988480093f4SDimitry Andric return false; 1989480093f4SDimitry Andric 19908bcb0991SDimitry Andric std::vector<Elf_Phdr> PHeaders; 19918bcb0991SDimitry Andric State.initProgramHeaders(PHeaders); 19928bcb0991SDimitry Andric 19938bcb0991SDimitry Andric // XXX: This offset is tightly coupled with the order that we write 19948bcb0991SDimitry Andric // things to `OS`. 19958bcb0991SDimitry Andric const size_t SectionContentBeginOffset = 19968bcb0991SDimitry Andric sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * Doc.ProgramHeaders.size(); 19975ffd83dbSDimitry Andric // It is quite easy to accidentally create output with yaml2obj that is larger 19985ffd83dbSDimitry Andric // than intended, for example, due to an issue in the YAML description. 19995ffd83dbSDimitry Andric // We limit the maximum allowed output size, but also provide a command line 20005ffd83dbSDimitry Andric // option to change this limitation. 20015ffd83dbSDimitry Andric ContiguousBlobAccumulator CBA(SectionContentBeginOffset, MaxSize); 20028bcb0991SDimitry Andric 20038bcb0991SDimitry Andric std::vector<Elf_Shdr> SHeaders; 20048bcb0991SDimitry Andric State.initSectionHeaders(SHeaders, CBA); 20058bcb0991SDimitry Andric 2006480093f4SDimitry Andric // Now we can decide segment offsets. 20078bcb0991SDimitry Andric State.setProgramHeaderLayout(PHeaders, SHeaders); 20088bcb0991SDimitry Andric 2009e8d8bef9SDimitry Andric bool ReachedLimit = CBA.getOffset() > MaxSize; 20105ffd83dbSDimitry Andric if (Error E = CBA.takeLimitError()) { 20115ffd83dbSDimitry Andric // We report a custom error message instead below. 20125ffd83dbSDimitry Andric consumeError(std::move(E)); 20135ffd83dbSDimitry Andric ReachedLimit = true; 20145ffd83dbSDimitry Andric } 20155ffd83dbSDimitry Andric 20165ffd83dbSDimitry Andric if (ReachedLimit) 20175ffd83dbSDimitry Andric State.reportError( 20185ffd83dbSDimitry Andric "the desired output size is greater than permitted. Use the " 20195ffd83dbSDimitry Andric "--max-size option to change the limit"); 20205ffd83dbSDimitry Andric 20218bcb0991SDimitry Andric if (State.HasError) 20228bcb0991SDimitry Andric return false; 20238bcb0991SDimitry Andric 2024e8d8bef9SDimitry Andric State.writeELFHeader(OS); 2025bdd1243dSDimitry Andric writeArrayData(OS, ArrayRef(PHeaders)); 2026e8d8bef9SDimitry Andric 2027e8d8bef9SDimitry Andric const ELFYAML::SectionHeaderTable &SHT = Doc.getSectionHeaderTable(); 202881ad6265SDimitry Andric if (!SHT.NoHeaders.value_or(false)) 2029e8d8bef9SDimitry Andric CBA.updateDataAt(*SHT.Offset, SHeaders.data(), 2030e8d8bef9SDimitry Andric SHT.getNumHeaders(SHeaders.size()) * sizeof(Elf_Shdr)); 2031e8d8bef9SDimitry Andric 20328bcb0991SDimitry Andric CBA.writeBlobToStream(OS); 20338bcb0991SDimitry Andric return true; 20348bcb0991SDimitry Andric } 20358bcb0991SDimitry Andric 20368bcb0991SDimitry Andric namespace llvm { 20378bcb0991SDimitry Andric namespace yaml { 20388bcb0991SDimitry Andric 20395ffd83dbSDimitry Andric bool yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH, 20405ffd83dbSDimitry Andric uint64_t MaxSize) { 20418bcb0991SDimitry Andric bool IsLE = Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB); 20428bcb0991SDimitry Andric bool Is64Bit = Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64); 20438bcb0991SDimitry Andric if (Is64Bit) { 20448bcb0991SDimitry Andric if (IsLE) 20455ffd83dbSDimitry Andric return ELFState<object::ELF64LE>::writeELF(Out, Doc, EH, MaxSize); 20465ffd83dbSDimitry Andric return ELFState<object::ELF64BE>::writeELF(Out, Doc, EH, MaxSize); 20478bcb0991SDimitry Andric } 20488bcb0991SDimitry Andric if (IsLE) 20495ffd83dbSDimitry Andric return ELFState<object::ELF32LE>::writeELF(Out, Doc, EH, MaxSize); 20505ffd83dbSDimitry Andric return ELFState<object::ELF32BE>::writeELF(Out, Doc, EH, MaxSize); 20518bcb0991SDimitry Andric } 20528bcb0991SDimitry Andric 20538bcb0991SDimitry Andric } // namespace yaml 20548bcb0991SDimitry Andric } // namespace llvm 2055