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> 355f757f3fSDimitry 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*0fca6ea1SDimitry Andric unsigned writeSLEB128(int64_t Val) { 127*0fca6ea1SDimitry Andric if (!checkLimit(10)) 128*0fca6ea1SDimitry Andric return 0; 129*0fca6ea1SDimitry Andric return encodeSLEB128(Val, OS); 130*0fca6ea1SDimitry Andric } 131*0fca6ea1SDimitry Andric 1325f757f3fSDimitry Andric template <typename T> void write(T Val, llvm::endianness E) { 1335ffd83dbSDimitry Andric if (checkLimit(sizeof(T))) 1345ffd83dbSDimitry Andric support::endian::write<T>(OS, Val, E); 1355ffd83dbSDimitry Andric } 136e8d8bef9SDimitry Andric 137e8d8bef9SDimitry Andric void updateDataAt(uint64_t Pos, void *Data, size_t Size) { 138e8d8bef9SDimitry Andric assert(Pos >= InitialOffset && Pos + Size <= getOffset()); 139e8d8bef9SDimitry Andric memcpy(&Buf[Pos - InitialOffset], Data, Size); 140e8d8bef9SDimitry Andric } 1418bcb0991SDimitry Andric }; 1428bcb0991SDimitry Andric 1438bcb0991SDimitry Andric // Used to keep track of section and symbol names, so that in the YAML file 1448bcb0991SDimitry Andric // sections and symbols can be referenced by name instead of by index. 1458bcb0991SDimitry Andric class NameToIdxMap { 1468bcb0991SDimitry Andric StringMap<unsigned> Map; 1478bcb0991SDimitry Andric 1488bcb0991SDimitry Andric public: 1498bcb0991SDimitry Andric /// \Returns false if name is already present in the map. 1508bcb0991SDimitry Andric bool addName(StringRef Name, unsigned Ndx) { 1518bcb0991SDimitry Andric return Map.insert({Name, Ndx}).second; 1528bcb0991SDimitry Andric } 1538bcb0991SDimitry Andric /// \Returns false if name is not present in the map. 1548bcb0991SDimitry Andric bool lookup(StringRef Name, unsigned &Idx) const { 1558bcb0991SDimitry Andric auto I = Map.find(Name); 1568bcb0991SDimitry Andric if (I == Map.end()) 1578bcb0991SDimitry Andric return false; 1588bcb0991SDimitry Andric Idx = I->getValue(); 1598bcb0991SDimitry Andric return true; 1608bcb0991SDimitry Andric } 1618bcb0991SDimitry Andric /// Asserts if name is not present in the map. 1628bcb0991SDimitry Andric unsigned get(StringRef Name) const { 1638bcb0991SDimitry Andric unsigned Idx; 1648bcb0991SDimitry Andric if (lookup(Name, Idx)) 1658bcb0991SDimitry Andric return Idx; 1668bcb0991SDimitry Andric assert(false && "Expected section not found in index"); 1678bcb0991SDimitry Andric return 0; 1688bcb0991SDimitry Andric } 1698bcb0991SDimitry Andric unsigned size() const { return Map.size(); } 1708bcb0991SDimitry Andric }; 1718bcb0991SDimitry Andric 172480093f4SDimitry Andric namespace { 173480093f4SDimitry Andric struct Fragment { 174480093f4SDimitry Andric uint64_t Offset; 175480093f4SDimitry Andric uint64_t Size; 176480093f4SDimitry Andric uint32_t Type; 177480093f4SDimitry Andric uint64_t AddrAlign; 178480093f4SDimitry Andric }; 179480093f4SDimitry Andric } // namespace 180480093f4SDimitry Andric 1818bcb0991SDimitry Andric /// "Single point of truth" for the ELF file construction. 1828bcb0991SDimitry Andric /// TODO: This class still has a ways to go before it is truly a "single 1838bcb0991SDimitry Andric /// point of truth". 1848bcb0991SDimitry Andric template <class ELFT> class ELFState { 185e8d8bef9SDimitry Andric LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 1868bcb0991SDimitry Andric 1878bcb0991SDimitry Andric enum class SymtabType { Static, Dynamic }; 1888bcb0991SDimitry Andric 189fe6060f1SDimitry Andric /// The future symbol table string section. 1908bcb0991SDimitry Andric StringTableBuilder DotStrtab{StringTableBuilder::ELF}; 1918bcb0991SDimitry Andric 192fe6060f1SDimitry Andric /// The future section header string table section, if a unique string table 193fe6060f1SDimitry Andric /// is needed. Don't reference this variable direectly: use the 194fe6060f1SDimitry Andric /// ShStrtabStrings member instead. 1958bcb0991SDimitry Andric StringTableBuilder DotShStrtab{StringTableBuilder::ELF}; 1968bcb0991SDimitry Andric 197fe6060f1SDimitry Andric /// The future dynamic symbol string section. 1988bcb0991SDimitry Andric StringTableBuilder DotDynstr{StringTableBuilder::ELF}; 1998bcb0991SDimitry Andric 200fe6060f1SDimitry Andric /// The name of the section header string table section. If it is .strtab or 201fe6060f1SDimitry Andric /// .dynstr, the section header strings will be written to the same string 202fe6060f1SDimitry Andric /// table as the static/dynamic symbols respectively. Otherwise a dedicated 203fe6060f1SDimitry Andric /// section will be created with that name. 204fe6060f1SDimitry Andric StringRef SectionHeaderStringTableName = ".shstrtab"; 205fe6060f1SDimitry Andric StringTableBuilder *ShStrtabStrings = &DotShStrtab; 206fe6060f1SDimitry Andric 2078bcb0991SDimitry Andric NameToIdxMap SN2I; 2088bcb0991SDimitry Andric NameToIdxMap SymN2I; 2098bcb0991SDimitry Andric NameToIdxMap DynSymN2I; 2108bcb0991SDimitry Andric ELFYAML::Object &Doc; 2118bcb0991SDimitry Andric 2125ffd83dbSDimitry Andric StringSet<> ExcludedSectionHeaders; 2135ffd83dbSDimitry Andric 2145ffd83dbSDimitry Andric uint64_t LocationCounter = 0; 2158bcb0991SDimitry Andric bool HasError = false; 2168bcb0991SDimitry Andric yaml::ErrorHandler ErrHandler; 2178bcb0991SDimitry Andric void reportError(const Twine &Msg); 2185ffd83dbSDimitry Andric void reportError(Error Err); 2198bcb0991SDimitry Andric 2208bcb0991SDimitry Andric std::vector<Elf_Sym> toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols, 2218bcb0991SDimitry Andric const StringTableBuilder &Strtab); 2228bcb0991SDimitry Andric unsigned toSectionIndex(StringRef S, StringRef LocSec, StringRef LocSym = ""); 2238bcb0991SDimitry Andric unsigned toSymbolIndex(StringRef S, StringRef LocSec, bool IsDynamic); 2248bcb0991SDimitry Andric 2258bcb0991SDimitry Andric void buildSectionIndex(); 2268bcb0991SDimitry Andric void buildSymbolIndexes(); 2278bcb0991SDimitry Andric void initProgramHeaders(std::vector<Elf_Phdr> &PHeaders); 2288bcb0991SDimitry Andric bool initImplicitHeader(ContiguousBlobAccumulator &CBA, Elf_Shdr &Header, 2298bcb0991SDimitry Andric StringRef SecName, ELFYAML::Section *YAMLSec); 2308bcb0991SDimitry Andric void initSectionHeaders(std::vector<Elf_Shdr> &SHeaders, 2318bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2328bcb0991SDimitry Andric void initSymtabSectionHeader(Elf_Shdr &SHeader, SymtabType STType, 2338bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 2348bcb0991SDimitry Andric ELFYAML::Section *YAMLSec); 2358bcb0991SDimitry Andric void initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name, 2368bcb0991SDimitry Andric StringTableBuilder &STB, 2378bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 2388bcb0991SDimitry Andric ELFYAML::Section *YAMLSec); 2395ffd83dbSDimitry Andric void initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name, 2405ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA, 2415ffd83dbSDimitry Andric ELFYAML::Section *YAMLSec); 2428bcb0991SDimitry Andric void setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders, 2438bcb0991SDimitry Andric std::vector<Elf_Shdr> &SHeaders); 244480093f4SDimitry Andric 245480093f4SDimitry Andric std::vector<Fragment> 246480093f4SDimitry Andric getPhdrFragments(const ELFYAML::ProgramHeader &Phdr, 247480093f4SDimitry Andric ArrayRef<typename ELFT::Shdr> SHeaders); 248480093f4SDimitry Andric 2498bcb0991SDimitry Andric void finalizeStrings(); 250e8d8bef9SDimitry Andric void writeELFHeader(raw_ostream &OS); 2515ffd83dbSDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2525ffd83dbSDimitry Andric const ELFYAML::NoBitsSection &Section, 2535ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA); 2548bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2558bcb0991SDimitry Andric const ELFYAML::RawContentSection &Section, 2568bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2578bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2588bcb0991SDimitry Andric const ELFYAML::RelocationSection &Section, 2598bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 260480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 261480093f4SDimitry Andric const ELFYAML::RelrSection &Section, 262480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 263e8d8bef9SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 264e8d8bef9SDimitry Andric const ELFYAML::GroupSection &Group, 2658bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2668bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2678bcb0991SDimitry Andric const ELFYAML::SymtabShndxSection &Shndx, 2688bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2698bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2708bcb0991SDimitry Andric const ELFYAML::SymverSection &Section, 2718bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2728bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2738bcb0991SDimitry Andric const ELFYAML::VerneedSection &Section, 2748bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2758bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2768bcb0991SDimitry Andric const ELFYAML::VerdefSection &Section, 2778bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2788bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 279e8d8bef9SDimitry Andric const ELFYAML::ARMIndexTableSection &Section, 280e8d8bef9SDimitry Andric ContiguousBlobAccumulator &CBA); 281e8d8bef9SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2828bcb0991SDimitry Andric const ELFYAML::MipsABIFlags &Section, 2838bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2848bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2858bcb0991SDimitry Andric const ELFYAML::DynamicSection &Section, 2868bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2878bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2888bcb0991SDimitry Andric const ELFYAML::StackSizesSection &Section, 2898bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2908bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 291e8d8bef9SDimitry Andric const ELFYAML::BBAddrMapSection &Section, 292e8d8bef9SDimitry Andric ContiguousBlobAccumulator &CBA); 293e8d8bef9SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2948bcb0991SDimitry Andric const ELFYAML::HashSection &Section, 2958bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 2968bcb0991SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 2978bcb0991SDimitry Andric const ELFYAML::AddrsigSection &Section, 2988bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA); 299480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 300480093f4SDimitry Andric const ELFYAML::NoteSection &Section, 301480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 302480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 303480093f4SDimitry Andric const ELFYAML::GnuHashSection &Section, 304480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 305480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 306480093f4SDimitry Andric const ELFYAML::LinkerOptionsSection &Section, 307480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 308480093f4SDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 309480093f4SDimitry Andric const ELFYAML::DependentLibrariesSection &Section, 310480093f4SDimitry Andric ContiguousBlobAccumulator &CBA); 3115ffd83dbSDimitry Andric void writeSectionContent(Elf_Shdr &SHeader, 3125ffd83dbSDimitry Andric const ELFYAML::CallGraphProfileSection &Section, 3135ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA); 314480093f4SDimitry Andric 315480093f4SDimitry Andric void writeFill(ELFYAML::Fill &Fill, ContiguousBlobAccumulator &CBA); 3168bcb0991SDimitry Andric 3178bcb0991SDimitry Andric ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH); 3188bcb0991SDimitry Andric 3195ffd83dbSDimitry Andric void assignSectionAddress(Elf_Shdr &SHeader, ELFYAML::Section *YAMLSec); 3205ffd83dbSDimitry Andric 3215ffd83dbSDimitry Andric DenseMap<StringRef, size_t> buildSectionHeaderReorderMap(); 3225ffd83dbSDimitry Andric 3235ffd83dbSDimitry Andric BumpPtrAllocator StringAlloc; 3245ffd83dbSDimitry Andric uint64_t alignToOffset(ContiguousBlobAccumulator &CBA, uint64_t Align, 325bdd1243dSDimitry Andric std::optional<llvm::yaml::Hex64> Offset); 3265ffd83dbSDimitry Andric 3275ffd83dbSDimitry Andric uint64_t getSectionNameOffset(StringRef Name); 3285ffd83dbSDimitry Andric 3298bcb0991SDimitry Andric public: 3308bcb0991SDimitry Andric static bool writeELF(raw_ostream &OS, ELFYAML::Object &Doc, 3315ffd83dbSDimitry Andric yaml::ErrorHandler EH, uint64_t MaxSize); 3328bcb0991SDimitry Andric }; 3338bcb0991SDimitry Andric } // end anonymous namespace 3348bcb0991SDimitry Andric 3358bcb0991SDimitry Andric template <class T> static size_t arrayDataSize(ArrayRef<T> A) { 3368bcb0991SDimitry Andric return A.size() * sizeof(T); 3378bcb0991SDimitry Andric } 3388bcb0991SDimitry Andric 3398bcb0991SDimitry Andric template <class T> static void writeArrayData(raw_ostream &OS, ArrayRef<T> A) { 3408bcb0991SDimitry Andric OS.write((const char *)A.data(), arrayDataSize(A)); 3418bcb0991SDimitry Andric } 3428bcb0991SDimitry Andric 3438bcb0991SDimitry Andric template <class T> static void zero(T &Obj) { memset(&Obj, 0, sizeof(Obj)); } 3448bcb0991SDimitry Andric 3458bcb0991SDimitry Andric template <class ELFT> 3468bcb0991SDimitry Andric ELFState<ELFT>::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH) 3478bcb0991SDimitry Andric : Doc(D), ErrHandler(EH) { 348fe6060f1SDimitry Andric // The input may explicitly request to store the section header table strings 349fe6060f1SDimitry Andric // in the same string table as dynamic or static symbol names. Set the 350fe6060f1SDimitry Andric // ShStrtabStrings member accordingly. 351fe6060f1SDimitry Andric if (Doc.Header.SectionHeaderStringTable) { 352fe6060f1SDimitry Andric SectionHeaderStringTableName = *Doc.Header.SectionHeaderStringTable; 353fe6060f1SDimitry Andric if (*Doc.Header.SectionHeaderStringTable == ".strtab") 354fe6060f1SDimitry Andric ShStrtabStrings = &DotStrtab; 355fe6060f1SDimitry Andric else if (*Doc.Header.SectionHeaderStringTable == ".dynstr") 356fe6060f1SDimitry Andric ShStrtabStrings = &DotDynstr; 357fe6060f1SDimitry Andric // Otherwise, the unique table will be used. 358fe6060f1SDimitry Andric } 359fe6060f1SDimitry Andric 360480093f4SDimitry Andric std::vector<ELFYAML::Section *> Sections = Doc.getSections(); 3618bcb0991SDimitry Andric // Insert SHT_NULL section implicitly when it is not defined in YAML. 362480093f4SDimitry Andric if (Sections.empty() || Sections.front()->Type != ELF::SHT_NULL) 363480093f4SDimitry Andric Doc.Chunks.insert( 364480093f4SDimitry Andric Doc.Chunks.begin(), 3658bcb0991SDimitry Andric std::make_unique<ELFYAML::Section>( 366480093f4SDimitry Andric ELFYAML::Chunk::ChunkKind::RawContent, /*IsImplicit=*/true)); 3678bcb0991SDimitry Andric 3685ffd83dbSDimitry Andric StringSet<> DocSections; 369e8d8bef9SDimitry Andric ELFYAML::SectionHeaderTable *SecHdrTable = nullptr; 3705ffd83dbSDimitry Andric for (size_t I = 0; I < Doc.Chunks.size(); ++I) { 3715ffd83dbSDimitry Andric const std::unique_ptr<ELFYAML::Chunk> &C = Doc.Chunks[I]; 372e8d8bef9SDimitry Andric 373e8d8bef9SDimitry Andric // We might have an explicit section header table declaration. 374e8d8bef9SDimitry Andric if (auto S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get())) { 375e8d8bef9SDimitry Andric if (SecHdrTable) 376e8d8bef9SDimitry Andric reportError("multiple section header tables are not allowed"); 377e8d8bef9SDimitry Andric SecHdrTable = S; 378e8d8bef9SDimitry Andric continue; 379e8d8bef9SDimitry Andric } 380e8d8bef9SDimitry Andric 381e8d8bef9SDimitry Andric // We add a technical suffix for each unnamed section/fill. It does not 382e8d8bef9SDimitry Andric // affect the output, but allows us to map them by name in the code and 383e8d8bef9SDimitry Andric // report better error messages. 3845ffd83dbSDimitry Andric if (C->Name.empty()) { 3855ffd83dbSDimitry Andric std::string NewName = ELFYAML::appendUniqueSuffix( 3865ffd83dbSDimitry Andric /*Name=*/"", "index " + Twine(I)); 3875ffd83dbSDimitry Andric C->Name = StringRef(NewName).copy(StringAlloc); 3885ffd83dbSDimitry Andric assert(ELFYAML::dropUniqueSuffix(C->Name).empty()); 3895ffd83dbSDimitry Andric } 3908bcb0991SDimitry Andric 3915ffd83dbSDimitry Andric if (!DocSections.insert(C->Name).second) 3925ffd83dbSDimitry Andric reportError("repeated section/fill name: '" + C->Name + 3935ffd83dbSDimitry Andric "' at YAML section/fill number " + Twine(I)); 3945ffd83dbSDimitry Andric } 3955ffd83dbSDimitry Andric 396fe6060f1SDimitry Andric SmallSetVector<StringRef, 8> ImplicitSections; 397fe6060f1SDimitry Andric if (Doc.DynamicSymbols) { 398fe6060f1SDimitry Andric if (SectionHeaderStringTableName == ".dynsym") 399fe6060f1SDimitry Andric reportError("cannot use '.dynsym' as the section header name table when " 400fe6060f1SDimitry Andric "there are dynamic symbols"); 401fe6060f1SDimitry Andric ImplicitSections.insert(".dynsym"); 402fe6060f1SDimitry Andric ImplicitSections.insert(".dynstr"); 403fe6060f1SDimitry Andric } 404fe6060f1SDimitry Andric if (Doc.Symbols) { 405fe6060f1SDimitry Andric if (SectionHeaderStringTableName == ".symtab") 406fe6060f1SDimitry Andric reportError("cannot use '.symtab' as the section header name table when " 407fe6060f1SDimitry Andric "there are symbols"); 408fe6060f1SDimitry Andric ImplicitSections.insert(".symtab"); 409fe6060f1SDimitry Andric } 4105ffd83dbSDimitry Andric if (Doc.DWARF) 411e8d8bef9SDimitry Andric for (StringRef DebugSecName : Doc.DWARF->getNonEmptySectionNames()) { 4125ffd83dbSDimitry Andric std::string SecName = ("." + DebugSecName).str(); 413fe6060f1SDimitry Andric // TODO: For .debug_str it should be possible to share the string table, 414fe6060f1SDimitry Andric // in the same manner as the symbol string tables. 415fe6060f1SDimitry Andric if (SectionHeaderStringTableName == SecName) 416fe6060f1SDimitry Andric reportError("cannot use '" + SecName + 417fe6060f1SDimitry Andric "' as the section header name table when it is needed for " 418fe6060f1SDimitry Andric "DWARF output"); 419fe6060f1SDimitry Andric ImplicitSections.insert(StringRef(SecName).copy(StringAlloc)); 4205ffd83dbSDimitry Andric } 421fe6060f1SDimitry Andric // TODO: Only create the .strtab here if any symbols have been requested. 422fe6060f1SDimitry Andric ImplicitSections.insert(".strtab"); 42381ad6265SDimitry Andric if (!SecHdrTable || !SecHdrTable->NoHeaders.value_or(false)) 424fe6060f1SDimitry Andric ImplicitSections.insert(SectionHeaderStringTableName); 4258bcb0991SDimitry Andric 4268bcb0991SDimitry Andric // Insert placeholders for implicit sections that are not 4278bcb0991SDimitry Andric // defined explicitly in YAML. 4288bcb0991SDimitry Andric for (StringRef SecName : ImplicitSections) { 4298bcb0991SDimitry Andric if (DocSections.count(SecName)) 4308bcb0991SDimitry Andric continue; 4318bcb0991SDimitry Andric 432e8d8bef9SDimitry Andric std::unique_ptr<ELFYAML::Section> Sec = std::make_unique<ELFYAML::Section>( 433480093f4SDimitry Andric ELFYAML::Chunk::ChunkKind::RawContent, true /*IsImplicit*/); 4348bcb0991SDimitry Andric Sec->Name = SecName; 435e8d8bef9SDimitry Andric 436fe6060f1SDimitry Andric if (SecName == SectionHeaderStringTableName) 437fe6060f1SDimitry Andric Sec->Type = ELF::SHT_STRTAB; 438fe6060f1SDimitry Andric else if (SecName == ".dynsym") 439e8d8bef9SDimitry Andric Sec->Type = ELF::SHT_DYNSYM; 440e8d8bef9SDimitry Andric else if (SecName == ".symtab") 441e8d8bef9SDimitry Andric Sec->Type = ELF::SHT_SYMTAB; 442e8d8bef9SDimitry Andric else 443e8d8bef9SDimitry Andric Sec->Type = ELF::SHT_STRTAB; 444e8d8bef9SDimitry Andric 445e8d8bef9SDimitry Andric // When the section header table is explicitly defined at the end of the 446e8d8bef9SDimitry Andric // sections list, it is reasonable to assume that the user wants to reorder 447e8d8bef9SDimitry Andric // section headers, but still wants to place the section header table after 448e8d8bef9SDimitry Andric // all sections, like it normally happens. In this case we want to insert 449e8d8bef9SDimitry Andric // other implicit sections right before the section header table. 450e8d8bef9SDimitry Andric if (Doc.Chunks.back().get() == SecHdrTable) 451e8d8bef9SDimitry Andric Doc.Chunks.insert(Doc.Chunks.end() - 1, std::move(Sec)); 452e8d8bef9SDimitry Andric else 453480093f4SDimitry Andric Doc.Chunks.push_back(std::move(Sec)); 4548bcb0991SDimitry Andric } 455e8d8bef9SDimitry Andric 456e8d8bef9SDimitry Andric // Insert the section header table implicitly at the end, when it is not 457e8d8bef9SDimitry Andric // explicitly defined. 458e8d8bef9SDimitry Andric if (!SecHdrTable) 459e8d8bef9SDimitry Andric Doc.Chunks.push_back( 460e8d8bef9SDimitry Andric std::make_unique<ELFYAML::SectionHeaderTable>(/*IsImplicit=*/true)); 4618bcb0991SDimitry Andric } 4628bcb0991SDimitry Andric 4638bcb0991SDimitry Andric template <class ELFT> 464e8d8bef9SDimitry Andric void ELFState<ELFT>::writeELFHeader(raw_ostream &OS) { 4658bcb0991SDimitry Andric using namespace llvm::ELF; 4668bcb0991SDimitry Andric 4678bcb0991SDimitry Andric Elf_Ehdr Header; 4688bcb0991SDimitry Andric zero(Header); 4698bcb0991SDimitry Andric Header.e_ident[EI_MAG0] = 0x7f; 4708bcb0991SDimitry Andric Header.e_ident[EI_MAG1] = 'E'; 4718bcb0991SDimitry Andric Header.e_ident[EI_MAG2] = 'L'; 4728bcb0991SDimitry Andric Header.e_ident[EI_MAG3] = 'F'; 4738bcb0991SDimitry Andric Header.e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32; 4748bcb0991SDimitry Andric Header.e_ident[EI_DATA] = Doc.Header.Data; 4758bcb0991SDimitry Andric Header.e_ident[EI_VERSION] = EV_CURRENT; 4768bcb0991SDimitry Andric Header.e_ident[EI_OSABI] = Doc.Header.OSABI; 4778bcb0991SDimitry Andric Header.e_ident[EI_ABIVERSION] = Doc.Header.ABIVersion; 4788bcb0991SDimitry Andric Header.e_type = Doc.Header.Type; 479e8d8bef9SDimitry Andric 480e8d8bef9SDimitry Andric if (Doc.Header.Machine) 481e8d8bef9SDimitry Andric Header.e_machine = *Doc.Header.Machine; 482e8d8bef9SDimitry Andric else 483e8d8bef9SDimitry Andric Header.e_machine = EM_NONE; 484e8d8bef9SDimitry Andric 4858bcb0991SDimitry Andric Header.e_version = EV_CURRENT; 4868bcb0991SDimitry Andric Header.e_entry = Doc.Header.Entry; 4878bcb0991SDimitry Andric Header.e_flags = Doc.Header.Flags; 4888bcb0991SDimitry Andric Header.e_ehsize = sizeof(Elf_Ehdr); 4898bcb0991SDimitry Andric 4905ffd83dbSDimitry Andric if (Doc.Header.EPhOff) 4915ffd83dbSDimitry Andric Header.e_phoff = *Doc.Header.EPhOff; 4925ffd83dbSDimitry Andric else if (!Doc.ProgramHeaders.empty()) 4935ffd83dbSDimitry Andric Header.e_phoff = sizeof(Header); 4945ffd83dbSDimitry Andric else 4955ffd83dbSDimitry Andric Header.e_phoff = 0; 4965ffd83dbSDimitry Andric 4975ffd83dbSDimitry Andric if (Doc.Header.EPhEntSize) 4985ffd83dbSDimitry Andric Header.e_phentsize = *Doc.Header.EPhEntSize; 4995ffd83dbSDimitry Andric else if (!Doc.ProgramHeaders.empty()) 5005ffd83dbSDimitry Andric Header.e_phentsize = sizeof(Elf_Phdr); 5015ffd83dbSDimitry Andric else 5025ffd83dbSDimitry Andric Header.e_phentsize = 0; 5035ffd83dbSDimitry Andric 5045ffd83dbSDimitry Andric if (Doc.Header.EPhNum) 5055ffd83dbSDimitry Andric Header.e_phnum = *Doc.Header.EPhNum; 5065ffd83dbSDimitry Andric else if (!Doc.ProgramHeaders.empty()) 5075ffd83dbSDimitry Andric Header.e_phnum = Doc.ProgramHeaders.size(); 5085ffd83dbSDimitry Andric else 5095ffd83dbSDimitry Andric Header.e_phnum = 0; 5105ffd83dbSDimitry Andric 5115ffd83dbSDimitry Andric Header.e_shentsize = Doc.Header.EShEntSize ? (uint16_t)*Doc.Header.EShEntSize 5125ffd83dbSDimitry Andric : sizeof(Elf_Shdr); 5135ffd83dbSDimitry Andric 514e8d8bef9SDimitry Andric const ELFYAML::SectionHeaderTable &SectionHeaders = 515e8d8bef9SDimitry Andric Doc.getSectionHeaderTable(); 5165ffd83dbSDimitry Andric 5175ffd83dbSDimitry Andric if (Doc.Header.EShOff) 5185ffd83dbSDimitry Andric Header.e_shoff = *Doc.Header.EShOff; 519e8d8bef9SDimitry Andric else if (SectionHeaders.Offset) 520e8d8bef9SDimitry Andric Header.e_shoff = *SectionHeaders.Offset; 5215ffd83dbSDimitry Andric else 522e8d8bef9SDimitry Andric Header.e_shoff = 0; 5235ffd83dbSDimitry Andric 5245ffd83dbSDimitry Andric if (Doc.Header.EShNum) 5255ffd83dbSDimitry Andric Header.e_shnum = *Doc.Header.EShNum; 5265ffd83dbSDimitry Andric else 527e8d8bef9SDimitry Andric Header.e_shnum = SectionHeaders.getNumHeaders(Doc.getSections().size()); 5285ffd83dbSDimitry Andric 5295ffd83dbSDimitry Andric if (Doc.Header.EShStrNdx) 5305ffd83dbSDimitry Andric Header.e_shstrndx = *Doc.Header.EShStrNdx; 531fe6060f1SDimitry Andric else if (SectionHeaders.Offset && 532fe6060f1SDimitry Andric !ExcludedSectionHeaders.count(SectionHeaderStringTableName)) 533fe6060f1SDimitry Andric Header.e_shstrndx = SN2I.get(SectionHeaderStringTableName); 534e8d8bef9SDimitry Andric else 535e8d8bef9SDimitry Andric Header.e_shstrndx = 0; 5368bcb0991SDimitry Andric 5378bcb0991SDimitry Andric OS.write((const char *)&Header, sizeof(Header)); 5388bcb0991SDimitry Andric } 5398bcb0991SDimitry Andric 5408bcb0991SDimitry Andric template <class ELFT> 5418bcb0991SDimitry Andric void ELFState<ELFT>::initProgramHeaders(std::vector<Elf_Phdr> &PHeaders) { 5425ffd83dbSDimitry Andric DenseMap<StringRef, ELFYAML::Fill *> NameToFill; 543e8d8bef9SDimitry Andric DenseMap<StringRef, size_t> NameToIndex; 544e8d8bef9SDimitry Andric for (size_t I = 0, E = Doc.Chunks.size(); I != E; ++I) { 545e8d8bef9SDimitry Andric if (auto S = dyn_cast<ELFYAML::Fill>(Doc.Chunks[I].get())) 5465ffd83dbSDimitry Andric NameToFill[S->Name] = S; 547e8d8bef9SDimitry Andric NameToIndex[Doc.Chunks[I]->Name] = I + 1; 548e8d8bef9SDimitry Andric } 5495ffd83dbSDimitry Andric 5505ffd83dbSDimitry Andric std::vector<ELFYAML::Section *> Sections = Doc.getSections(); 551e8d8bef9SDimitry Andric for (size_t I = 0, E = Doc.ProgramHeaders.size(); I != E; ++I) { 552e8d8bef9SDimitry Andric ELFYAML::ProgramHeader &YamlPhdr = Doc.ProgramHeaders[I]; 5538bcb0991SDimitry Andric Elf_Phdr Phdr; 5545ffd83dbSDimitry Andric zero(Phdr); 5558bcb0991SDimitry Andric Phdr.p_type = YamlPhdr.Type; 5568bcb0991SDimitry Andric Phdr.p_flags = YamlPhdr.Flags; 5578bcb0991SDimitry Andric Phdr.p_vaddr = YamlPhdr.VAddr; 5588bcb0991SDimitry Andric Phdr.p_paddr = YamlPhdr.PAddr; 5598bcb0991SDimitry Andric PHeaders.push_back(Phdr); 5605ffd83dbSDimitry Andric 561e8d8bef9SDimitry Andric if (!YamlPhdr.FirstSec && !YamlPhdr.LastSec) 5625ffd83dbSDimitry Andric continue; 5635ffd83dbSDimitry Andric 564e8d8bef9SDimitry Andric // Get the index of the section, or 0 in the case when the section doesn't exist. 565e8d8bef9SDimitry Andric size_t First = NameToIndex[*YamlPhdr.FirstSec]; 566e8d8bef9SDimitry Andric if (!First) 567e8d8bef9SDimitry Andric reportError("unknown section or fill referenced: '" + *YamlPhdr.FirstSec + 568e8d8bef9SDimitry Andric "' by the 'FirstSec' key of the program header with index " + 569e8d8bef9SDimitry Andric Twine(I)); 570e8d8bef9SDimitry Andric size_t Last = NameToIndex[*YamlPhdr.LastSec]; 571e8d8bef9SDimitry Andric if (!Last) 572e8d8bef9SDimitry Andric reportError("unknown section or fill referenced: '" + *YamlPhdr.LastSec + 573e8d8bef9SDimitry Andric "' by the 'LastSec' key of the program header with index " + 574e8d8bef9SDimitry Andric Twine(I)); 575e8d8bef9SDimitry Andric if (!First || !Last) 5765ffd83dbSDimitry Andric continue; 5775ffd83dbSDimitry Andric 578e8d8bef9SDimitry Andric if (First > Last) 579e8d8bef9SDimitry Andric reportError("program header with index " + Twine(I) + 580e8d8bef9SDimitry Andric ": the section index of " + *YamlPhdr.FirstSec + 581e8d8bef9SDimitry Andric " is greater than the index of " + *YamlPhdr.LastSec); 582e8d8bef9SDimitry Andric 583e8d8bef9SDimitry Andric for (size_t I = First; I <= Last; ++I) 584e8d8bef9SDimitry Andric YamlPhdr.Chunks.push_back(Doc.Chunks[I - 1].get()); 5858bcb0991SDimitry Andric } 5868bcb0991SDimitry Andric } 5878bcb0991SDimitry Andric 5888bcb0991SDimitry Andric template <class ELFT> 5898bcb0991SDimitry Andric unsigned ELFState<ELFT>::toSectionIndex(StringRef S, StringRef LocSec, 5908bcb0991SDimitry Andric StringRef LocSym) { 5918bcb0991SDimitry Andric assert(LocSec.empty() || LocSym.empty()); 5925ffd83dbSDimitry Andric 5935ffd83dbSDimitry Andric unsigned Index; 5945ffd83dbSDimitry Andric if (!SN2I.lookup(S, Index) && !to_integer(S, Index)) { 5958bcb0991SDimitry Andric if (!LocSym.empty()) 5968bcb0991SDimitry Andric reportError("unknown section referenced: '" + S + "' by YAML symbol '" + 5978bcb0991SDimitry Andric LocSym + "'"); 5988bcb0991SDimitry Andric else 5998bcb0991SDimitry Andric reportError("unknown section referenced: '" + S + "' by YAML section '" + 6008bcb0991SDimitry Andric LocSec + "'"); 6018bcb0991SDimitry Andric return 0; 6028bcb0991SDimitry Andric } 6038bcb0991SDimitry Andric 604e8d8bef9SDimitry Andric const ELFYAML::SectionHeaderTable &SectionHeaders = 605e8d8bef9SDimitry Andric Doc.getSectionHeaderTable(); 606e8d8bef9SDimitry Andric if (SectionHeaders.IsImplicit || 60781ad6265SDimitry Andric (SectionHeaders.NoHeaders && !*SectionHeaders.NoHeaders) || 608fe6060f1SDimitry Andric SectionHeaders.isDefault()) 6095ffd83dbSDimitry Andric return Index; 6105ffd83dbSDimitry Andric 61181ad6265SDimitry Andric assert(!SectionHeaders.NoHeaders.value_or(false) || !SectionHeaders.Sections); 6125ffd83dbSDimitry Andric size_t FirstExcluded = 613e8d8bef9SDimitry Andric SectionHeaders.Sections ? SectionHeaders.Sections->size() : 0; 614fe6060f1SDimitry Andric if (Index > FirstExcluded) { 6155ffd83dbSDimitry Andric if (LocSym.empty()) 6165ffd83dbSDimitry Andric reportError("unable to link '" + LocSec + "' to excluded section '" + S + 6175ffd83dbSDimitry Andric "'"); 6185ffd83dbSDimitry Andric else 6195ffd83dbSDimitry Andric reportError("excluded section referenced: '" + S + "' by symbol '" + 6205ffd83dbSDimitry Andric LocSym + "'"); 6215ffd83dbSDimitry Andric } 6225ffd83dbSDimitry Andric return Index; 6235ffd83dbSDimitry Andric } 6245ffd83dbSDimitry Andric 6258bcb0991SDimitry Andric template <class ELFT> 6268bcb0991SDimitry Andric unsigned ELFState<ELFT>::toSymbolIndex(StringRef S, StringRef LocSec, 6278bcb0991SDimitry Andric bool IsDynamic) { 6288bcb0991SDimitry Andric const NameToIdxMap &SymMap = IsDynamic ? DynSymN2I : SymN2I; 6298bcb0991SDimitry Andric unsigned Index; 6308bcb0991SDimitry Andric // Here we try to look up S in the symbol table. If it is not there, 6318bcb0991SDimitry Andric // treat its value as a symbol index. 6328bcb0991SDimitry Andric if (!SymMap.lookup(S, Index) && !to_integer(S, Index)) { 6338bcb0991SDimitry Andric reportError("unknown symbol referenced: '" + S + "' by YAML section '" + 6348bcb0991SDimitry Andric LocSec + "'"); 6358bcb0991SDimitry Andric return 0; 6368bcb0991SDimitry Andric } 6378bcb0991SDimitry Andric return Index; 6388bcb0991SDimitry Andric } 6398bcb0991SDimitry Andric 6408bcb0991SDimitry Andric template <class ELFT> 641480093f4SDimitry Andric static void overrideFields(ELFYAML::Section *From, typename ELFT::Shdr &To) { 642480093f4SDimitry Andric if (!From) 643480093f4SDimitry Andric return; 644e8d8bef9SDimitry Andric if (From->ShAddrAlign) 645e8d8bef9SDimitry Andric To.sh_addralign = *From->ShAddrAlign; 646480093f4SDimitry Andric if (From->ShFlags) 647480093f4SDimitry Andric To.sh_flags = *From->ShFlags; 648480093f4SDimitry Andric if (From->ShName) 649480093f4SDimitry Andric To.sh_name = *From->ShName; 650480093f4SDimitry Andric if (From->ShOffset) 651480093f4SDimitry Andric To.sh_offset = *From->ShOffset; 652480093f4SDimitry Andric if (From->ShSize) 653480093f4SDimitry Andric To.sh_size = *From->ShSize; 654e8d8bef9SDimitry Andric if (From->ShType) 655e8d8bef9SDimitry Andric To.sh_type = *From->ShType; 656480093f4SDimitry Andric } 657480093f4SDimitry Andric 658480093f4SDimitry Andric template <class ELFT> 6598bcb0991SDimitry Andric bool ELFState<ELFT>::initImplicitHeader(ContiguousBlobAccumulator &CBA, 6608bcb0991SDimitry Andric Elf_Shdr &Header, StringRef SecName, 6618bcb0991SDimitry Andric ELFYAML::Section *YAMLSec) { 6628bcb0991SDimitry Andric // Check if the header was already initialized. 6638bcb0991SDimitry Andric if (Header.sh_offset) 6648bcb0991SDimitry Andric return false; 6658bcb0991SDimitry Andric 666fe6060f1SDimitry Andric if (SecName == ".strtab") 6678bcb0991SDimitry Andric initStrtabSectionHeader(Header, SecName, DotStrtab, CBA, YAMLSec); 6688bcb0991SDimitry Andric else if (SecName == ".dynstr") 6698bcb0991SDimitry Andric initStrtabSectionHeader(Header, SecName, DotDynstr, CBA, YAMLSec); 670fe6060f1SDimitry Andric else if (SecName == SectionHeaderStringTableName) 671fe6060f1SDimitry Andric initStrtabSectionHeader(Header, SecName, *ShStrtabStrings, CBA, YAMLSec); 672fe6060f1SDimitry Andric else if (SecName == ".symtab") 673fe6060f1SDimitry Andric initSymtabSectionHeader(Header, SymtabType::Static, CBA, YAMLSec); 674fe6060f1SDimitry Andric else if (SecName == ".dynsym") 675fe6060f1SDimitry Andric initSymtabSectionHeader(Header, SymtabType::Dynamic, CBA, YAMLSec); 6765f757f3fSDimitry Andric else if (SecName.starts_with(".debug_")) { 6775ffd83dbSDimitry Andric // If a ".debug_*" section's type is a preserved one, e.g., SHT_DYNAMIC, we 6785ffd83dbSDimitry Andric // will not treat it as a debug section. 6795ffd83dbSDimitry Andric if (YAMLSec && !isa<ELFYAML::RawContentSection>(YAMLSec)) 6808bcb0991SDimitry Andric return false; 6815ffd83dbSDimitry Andric initDWARFSectionHeader(Header, SecName, CBA, YAMLSec); 6825ffd83dbSDimitry Andric } else 6835ffd83dbSDimitry Andric return false; 6845ffd83dbSDimitry Andric 6855ffd83dbSDimitry Andric LocationCounter += Header.sh_size; 6868bcb0991SDimitry Andric 687480093f4SDimitry Andric // Override section fields if requested. 688480093f4SDimitry Andric overrideFields<ELFT>(YAMLSec, Header); 6898bcb0991SDimitry Andric return true; 6908bcb0991SDimitry Andric } 6918bcb0991SDimitry Andric 6925ffd83dbSDimitry Andric constexpr char SuffixStart = '('; 6935ffd83dbSDimitry Andric constexpr char SuffixEnd = ')'; 6945ffd83dbSDimitry Andric 6955ffd83dbSDimitry Andric std::string llvm::ELFYAML::appendUniqueSuffix(StringRef Name, 6965ffd83dbSDimitry Andric const Twine &Msg) { 6975ffd83dbSDimitry Andric // Do not add a space when a Name is empty. 6985ffd83dbSDimitry Andric std::string Ret = Name.empty() ? "" : Name.str() + ' '; 6995ffd83dbSDimitry Andric return Ret + (Twine(SuffixStart) + Msg + Twine(SuffixEnd)).str(); 7005ffd83dbSDimitry Andric } 7015ffd83dbSDimitry Andric 7028bcb0991SDimitry Andric StringRef llvm::ELFYAML::dropUniqueSuffix(StringRef S) { 7035ffd83dbSDimitry Andric if (S.empty() || S.back() != SuffixEnd) 7048bcb0991SDimitry Andric return S; 7055ffd83dbSDimitry Andric 7065ffd83dbSDimitry Andric // A special case for empty names. See appendUniqueSuffix() above. 7075ffd83dbSDimitry Andric size_t SuffixPos = S.rfind(SuffixStart); 7085ffd83dbSDimitry Andric if (SuffixPos == 0) 7095ffd83dbSDimitry Andric return ""; 7105ffd83dbSDimitry Andric 7115ffd83dbSDimitry Andric if (SuffixPos == StringRef::npos || S[SuffixPos - 1] != ' ') 7125ffd83dbSDimitry Andric return S; 7135ffd83dbSDimitry Andric return S.substr(0, SuffixPos - 1); 7145ffd83dbSDimitry Andric } 7155ffd83dbSDimitry Andric 7165ffd83dbSDimitry Andric template <class ELFT> 7175ffd83dbSDimitry Andric uint64_t ELFState<ELFT>::getSectionNameOffset(StringRef Name) { 7185ffd83dbSDimitry Andric // If a section is excluded from section headers, we do not save its name in 7195ffd83dbSDimitry Andric // the string table. 7205ffd83dbSDimitry Andric if (ExcludedSectionHeaders.count(Name)) 7215ffd83dbSDimitry Andric return 0; 722fe6060f1SDimitry Andric return ShStrtabStrings->getOffset(Name); 7238bcb0991SDimitry Andric } 7248bcb0991SDimitry Andric 725e8d8bef9SDimitry Andric static uint64_t writeContent(ContiguousBlobAccumulator &CBA, 726bdd1243dSDimitry Andric const std::optional<yaml::BinaryRef> &Content, 727bdd1243dSDimitry Andric const std::optional<llvm::yaml::Hex64> &Size) { 728e8d8bef9SDimitry Andric size_t ContentSize = 0; 729e8d8bef9SDimitry Andric if (Content) { 730e8d8bef9SDimitry Andric CBA.writeAsBinary(*Content); 731e8d8bef9SDimitry Andric ContentSize = Content->binary_size(); 732e8d8bef9SDimitry Andric } 733e8d8bef9SDimitry Andric 734e8d8bef9SDimitry Andric if (!Size) 735e8d8bef9SDimitry Andric return ContentSize; 736e8d8bef9SDimitry Andric 737e8d8bef9SDimitry Andric CBA.writeZeros(*Size - ContentSize); 738e8d8bef9SDimitry Andric return *Size; 739e8d8bef9SDimitry Andric } 740e8d8bef9SDimitry Andric 741e8d8bef9SDimitry Andric static StringRef getDefaultLinkSec(unsigned SecType) { 742e8d8bef9SDimitry Andric switch (SecType) { 743e8d8bef9SDimitry Andric case ELF::SHT_REL: 744e8d8bef9SDimitry Andric case ELF::SHT_RELA: 745e8d8bef9SDimitry Andric case ELF::SHT_GROUP: 746e8d8bef9SDimitry Andric case ELF::SHT_LLVM_CALL_GRAPH_PROFILE: 747e8d8bef9SDimitry Andric case ELF::SHT_LLVM_ADDRSIG: 748e8d8bef9SDimitry Andric return ".symtab"; 749e8d8bef9SDimitry Andric case ELF::SHT_GNU_versym: 750e8d8bef9SDimitry Andric case ELF::SHT_HASH: 751e8d8bef9SDimitry Andric case ELF::SHT_GNU_HASH: 752e8d8bef9SDimitry Andric return ".dynsym"; 753e8d8bef9SDimitry Andric case ELF::SHT_DYNSYM: 754e8d8bef9SDimitry Andric case ELF::SHT_GNU_verdef: 755e8d8bef9SDimitry Andric case ELF::SHT_GNU_verneed: 756e8d8bef9SDimitry Andric return ".dynstr"; 757e8d8bef9SDimitry Andric case ELF::SHT_SYMTAB: 758e8d8bef9SDimitry Andric return ".strtab"; 759e8d8bef9SDimitry Andric default: 760e8d8bef9SDimitry Andric return ""; 761e8d8bef9SDimitry Andric } 762e8d8bef9SDimitry Andric } 763e8d8bef9SDimitry Andric 7648bcb0991SDimitry Andric template <class ELFT> 7658bcb0991SDimitry Andric void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders, 7668bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 7678bcb0991SDimitry Andric // Ensure SHN_UNDEF entry is present. An all-zero section header is a 7688bcb0991SDimitry Andric // valid SHN_UNDEF entry since SHT_NULL == 0. 769480093f4SDimitry Andric SHeaders.resize(Doc.getSections().size()); 7708bcb0991SDimitry Andric 771480093f4SDimitry Andric for (const std::unique_ptr<ELFYAML::Chunk> &D : Doc.Chunks) { 7725ffd83dbSDimitry Andric if (ELFYAML::Fill *S = dyn_cast<ELFYAML::Fill>(D.get())) { 7735ffd83dbSDimitry Andric S->Offset = alignToOffset(CBA, /*Align=*/1, S->Offset); 774480093f4SDimitry Andric writeFill(*S, CBA); 7755ffd83dbSDimitry Andric LocationCounter += S->Size; 776480093f4SDimitry Andric continue; 777480093f4SDimitry Andric } 778480093f4SDimitry Andric 779e8d8bef9SDimitry Andric if (ELFYAML::SectionHeaderTable *S = 780e8d8bef9SDimitry Andric dyn_cast<ELFYAML::SectionHeaderTable>(D.get())) { 78181ad6265SDimitry Andric if (S->NoHeaders.value_or(false)) 782e8d8bef9SDimitry Andric continue; 783e8d8bef9SDimitry Andric 784e8d8bef9SDimitry Andric if (!S->Offset) 785e8d8bef9SDimitry Andric S->Offset = alignToOffset(CBA, sizeof(typename ELFT::uint), 786bdd1243dSDimitry Andric /*Offset=*/std::nullopt); 787e8d8bef9SDimitry Andric else 788e8d8bef9SDimitry Andric S->Offset = alignToOffset(CBA, /*Align=*/1, S->Offset); 789e8d8bef9SDimitry Andric 790e8d8bef9SDimitry Andric uint64_t Size = S->getNumHeaders(SHeaders.size()) * sizeof(Elf_Shdr); 791e8d8bef9SDimitry Andric // The full section header information might be not available here, so 792e8d8bef9SDimitry Andric // fill the space with zeroes as a placeholder. 793e8d8bef9SDimitry Andric CBA.writeZeros(Size); 794e8d8bef9SDimitry Andric LocationCounter += Size; 795e8d8bef9SDimitry Andric continue; 796e8d8bef9SDimitry Andric } 797e8d8bef9SDimitry Andric 798480093f4SDimitry Andric ELFYAML::Section *Sec = cast<ELFYAML::Section>(D.get()); 799e8d8bef9SDimitry Andric bool IsFirstUndefSection = Sec == Doc.getSections().front(); 8005ffd83dbSDimitry Andric if (IsFirstUndefSection && Sec->IsImplicit) 8018bcb0991SDimitry Andric continue; 8028bcb0991SDimitry Andric 803e8d8bef9SDimitry Andric Elf_Shdr &SHeader = SHeaders[SN2I.get(Sec->Name)]; 804e8d8bef9SDimitry Andric if (Sec->Link) { 805e8d8bef9SDimitry Andric SHeader.sh_link = toSectionIndex(*Sec->Link, Sec->Name); 806e8d8bef9SDimitry Andric } else { 807e8d8bef9SDimitry Andric StringRef LinkSec = getDefaultLinkSec(Sec->Type); 808e8d8bef9SDimitry Andric unsigned Link = 0; 809e8d8bef9SDimitry Andric if (!LinkSec.empty() && !ExcludedSectionHeaders.count(LinkSec) && 810e8d8bef9SDimitry Andric SN2I.lookup(LinkSec, Link)) 811e8d8bef9SDimitry Andric SHeader.sh_link = Link; 812e8d8bef9SDimitry Andric } 813e8d8bef9SDimitry Andric 814e8d8bef9SDimitry Andric if (Sec->EntSize) 815e8d8bef9SDimitry Andric SHeader.sh_entsize = *Sec->EntSize; 816e8d8bef9SDimitry Andric else 817e8d8bef9SDimitry Andric SHeader.sh_entsize = ELFYAML::getDefaultShEntSize<ELFT>( 81881ad6265SDimitry Andric Doc.Header.Machine.value_or(ELF::EM_NONE), Sec->Type, Sec->Name); 819e8d8bef9SDimitry Andric 8208bcb0991SDimitry Andric // We have a few sections like string or symbol tables that are usually 8218bcb0991SDimitry Andric // added implicitly to the end. However, if they are explicitly specified 8228bcb0991SDimitry Andric // in the YAML, we need to write them here. This ensures the file offset 8238bcb0991SDimitry Andric // remains correct. 8248bcb0991SDimitry Andric if (initImplicitHeader(CBA, SHeader, Sec->Name, 8258bcb0991SDimitry Andric Sec->IsImplicit ? nullptr : Sec)) 8268bcb0991SDimitry Andric continue; 8278bcb0991SDimitry Andric 8288bcb0991SDimitry Andric assert(Sec && "It can't be null unless it is an implicit section. But all " 8298bcb0991SDimitry Andric "implicit sections should already have been handled above."); 8308bcb0991SDimitry Andric 8318bcb0991SDimitry Andric SHeader.sh_name = 8325ffd83dbSDimitry Andric getSectionNameOffset(ELFYAML::dropUniqueSuffix(Sec->Name)); 8338bcb0991SDimitry Andric SHeader.sh_type = Sec->Type; 8348bcb0991SDimitry Andric if (Sec->Flags) 8358bcb0991SDimitry Andric SHeader.sh_flags = *Sec->Flags; 8368bcb0991SDimitry Andric SHeader.sh_addralign = Sec->AddressAlign; 8378bcb0991SDimitry Andric 8385ffd83dbSDimitry Andric // Set the offset for all sections, except the SHN_UNDEF section with index 8395ffd83dbSDimitry Andric // 0 when not explicitly requested. 8405ffd83dbSDimitry Andric if (!IsFirstUndefSection || Sec->Offset) 8415ffd83dbSDimitry Andric SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign, Sec->Offset); 8425ffd83dbSDimitry Andric 8435ffd83dbSDimitry Andric assignSectionAddress(SHeader, Sec); 8445ffd83dbSDimitry Andric 8455ffd83dbSDimitry Andric if (IsFirstUndefSection) { 8468bcb0991SDimitry Andric if (auto RawSec = dyn_cast<ELFYAML::RawContentSection>(Sec)) { 8478bcb0991SDimitry Andric // We do not write any content for special SHN_UNDEF section. 8488bcb0991SDimitry Andric if (RawSec->Size) 8498bcb0991SDimitry Andric SHeader.sh_size = *RawSec->Size; 8508bcb0991SDimitry Andric if (RawSec->Info) 8518bcb0991SDimitry Andric SHeader.sh_info = *RawSec->Info; 8528bcb0991SDimitry Andric } 853e8d8bef9SDimitry Andric 854e8d8bef9SDimitry Andric LocationCounter += SHeader.sh_size; 855e8d8bef9SDimitry Andric overrideFields<ELFT>(Sec, SHeader); 856e8d8bef9SDimitry Andric continue; 857e8d8bef9SDimitry Andric } 858e8d8bef9SDimitry Andric 859e8d8bef9SDimitry Andric if (!isa<ELFYAML::NoBitsSection>(Sec) && (Sec->Content || Sec->Size)) 860e8d8bef9SDimitry Andric SHeader.sh_size = writeContent(CBA, Sec->Content, Sec->Size); 861e8d8bef9SDimitry Andric 862e8d8bef9SDimitry Andric if (auto S = dyn_cast<ELFYAML::RawContentSection>(Sec)) { 8638bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8648bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::SymtabShndxSection>(Sec)) { 8658bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8668bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::RelocationSection>(Sec)) { 8678bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 868480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::RelrSection>(Sec)) { 869480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 870e8d8bef9SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::GroupSection>(Sec)) { 871e8d8bef9SDimitry Andric writeSectionContent(SHeader, *S, CBA); 872e8d8bef9SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::ARMIndexTableSection>(Sec)) { 8738bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8748bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::MipsABIFlags>(Sec)) { 8758bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8768bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::NoBitsSection>(Sec)) { 8775ffd83dbSDimitry Andric writeSectionContent(SHeader, *S, CBA); 8788bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::DynamicSection>(Sec)) { 8798bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8808bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::SymverSection>(Sec)) { 8818bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8828bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::VerneedSection>(Sec)) { 8838bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8848bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::VerdefSection>(Sec)) { 8858bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8868bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::StackSizesSection>(Sec)) { 8878bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8888bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::HashSection>(Sec)) { 8898bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 8908bcb0991SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::AddrsigSection>(Sec)) { 8918bcb0991SDimitry Andric writeSectionContent(SHeader, *S, CBA); 892480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::LinkerOptionsSection>(Sec)) { 893480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 894480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::NoteSection>(Sec)) { 895480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 896480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::GnuHashSection>(Sec)) { 897480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 898480093f4SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::DependentLibrariesSection>(Sec)) { 899480093f4SDimitry Andric writeSectionContent(SHeader, *S, CBA); 9005ffd83dbSDimitry Andric } else if (auto S = dyn_cast<ELFYAML::CallGraphProfileSection>(Sec)) { 9015ffd83dbSDimitry Andric writeSectionContent(SHeader, *S, CBA); 902e8d8bef9SDimitry Andric } else if (auto S = dyn_cast<ELFYAML::BBAddrMapSection>(Sec)) { 903e8d8bef9SDimitry Andric writeSectionContent(SHeader, *S, CBA); 9048bcb0991SDimitry Andric } else { 9058bcb0991SDimitry Andric llvm_unreachable("Unknown section type"); 9068bcb0991SDimitry Andric } 9078bcb0991SDimitry Andric 9085ffd83dbSDimitry Andric LocationCounter += SHeader.sh_size; 9095ffd83dbSDimitry Andric 910480093f4SDimitry Andric // Override section fields if requested. 911480093f4SDimitry Andric overrideFields<ELFT>(Sec, SHeader); 9128bcb0991SDimitry Andric } 9138bcb0991SDimitry Andric } 9148bcb0991SDimitry Andric 9155ffd83dbSDimitry Andric template <class ELFT> 9165ffd83dbSDimitry Andric void ELFState<ELFT>::assignSectionAddress(Elf_Shdr &SHeader, 9175ffd83dbSDimitry Andric ELFYAML::Section *YAMLSec) { 9185ffd83dbSDimitry Andric if (YAMLSec && YAMLSec->Address) { 9195ffd83dbSDimitry Andric SHeader.sh_addr = *YAMLSec->Address; 9205ffd83dbSDimitry Andric LocationCounter = *YAMLSec->Address; 9215ffd83dbSDimitry Andric return; 9225ffd83dbSDimitry Andric } 9235ffd83dbSDimitry Andric 9245ffd83dbSDimitry Andric // sh_addr represents the address in the memory image of a process. Sections 9255ffd83dbSDimitry Andric // in a relocatable object file or non-allocatable sections do not need 9265ffd83dbSDimitry Andric // sh_addr assignment. 9275ffd83dbSDimitry Andric if (Doc.Header.Type.value == ELF::ET_REL || 9285ffd83dbSDimitry Andric !(SHeader.sh_flags & ELF::SHF_ALLOC)) 9295ffd83dbSDimitry Andric return; 9305ffd83dbSDimitry Andric 9315ffd83dbSDimitry Andric LocationCounter = 9325ffd83dbSDimitry Andric alignTo(LocationCounter, SHeader.sh_addralign ? SHeader.sh_addralign : 1); 9335ffd83dbSDimitry Andric SHeader.sh_addr = LocationCounter; 9345ffd83dbSDimitry Andric } 9355ffd83dbSDimitry Andric 9368bcb0991SDimitry Andric static size_t findFirstNonGlobal(ArrayRef<ELFYAML::Symbol> Symbols) { 9378bcb0991SDimitry Andric for (size_t I = 0; I < Symbols.size(); ++I) 9388bcb0991SDimitry Andric if (Symbols[I].Binding.value != ELF::STB_LOCAL) 9398bcb0991SDimitry Andric return I; 9408bcb0991SDimitry Andric return Symbols.size(); 9418bcb0991SDimitry Andric } 9428bcb0991SDimitry Andric 9438bcb0991SDimitry Andric template <class ELFT> 9448bcb0991SDimitry Andric std::vector<typename ELFT::Sym> 9458bcb0991SDimitry Andric ELFState<ELFT>::toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols, 9468bcb0991SDimitry Andric const StringTableBuilder &Strtab) { 9478bcb0991SDimitry Andric std::vector<Elf_Sym> Ret; 9488bcb0991SDimitry Andric Ret.resize(Symbols.size() + 1); 9498bcb0991SDimitry Andric 9508bcb0991SDimitry Andric size_t I = 0; 951480093f4SDimitry Andric for (const ELFYAML::Symbol &Sym : Symbols) { 9528bcb0991SDimitry Andric Elf_Sym &Symbol = Ret[++I]; 9538bcb0991SDimitry Andric 9548bcb0991SDimitry Andric // If NameIndex, which contains the name offset, is explicitly specified, we 9558bcb0991SDimitry Andric // use it. This is useful for preparing broken objects. Otherwise, we add 9568bcb0991SDimitry Andric // the specified Name to the string table builder to get its offset. 9575ffd83dbSDimitry Andric if (Sym.StName) 9585ffd83dbSDimitry Andric Symbol.st_name = *Sym.StName; 9598bcb0991SDimitry Andric else if (!Sym.Name.empty()) 9608bcb0991SDimitry Andric Symbol.st_name = Strtab.getOffset(ELFYAML::dropUniqueSuffix(Sym.Name)); 9618bcb0991SDimitry Andric 9628bcb0991SDimitry Andric Symbol.setBindingAndType(Sym.Binding, Sym.Type); 963e8d8bef9SDimitry Andric if (Sym.Section) 964e8d8bef9SDimitry Andric Symbol.st_shndx = toSectionIndex(*Sym.Section, "", Sym.Name); 9658bcb0991SDimitry Andric else if (Sym.Index) 9668bcb0991SDimitry Andric Symbol.st_shndx = *Sym.Index; 9678bcb0991SDimitry Andric 96881ad6265SDimitry Andric Symbol.st_value = Sym.Value.value_or(yaml::Hex64(0)); 9698bcb0991SDimitry Andric Symbol.st_other = Sym.Other ? *Sym.Other : 0; 97081ad6265SDimitry Andric Symbol.st_size = Sym.Size.value_or(yaml::Hex64(0)); 9718bcb0991SDimitry Andric } 9728bcb0991SDimitry Andric 9738bcb0991SDimitry Andric return Ret; 9748bcb0991SDimitry Andric } 9758bcb0991SDimitry Andric 9768bcb0991SDimitry Andric template <class ELFT> 9778bcb0991SDimitry Andric void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader, 9788bcb0991SDimitry Andric SymtabType STType, 9798bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 9808bcb0991SDimitry Andric ELFYAML::Section *YAMLSec) { 9818bcb0991SDimitry Andric 9828bcb0991SDimitry Andric bool IsStatic = STType == SymtabType::Static; 9838bcb0991SDimitry Andric ArrayRef<ELFYAML::Symbol> Symbols; 9848bcb0991SDimitry Andric if (IsStatic && Doc.Symbols) 9858bcb0991SDimitry Andric Symbols = *Doc.Symbols; 986480093f4SDimitry Andric else if (!IsStatic && Doc.DynamicSymbols) 987480093f4SDimitry Andric Symbols = *Doc.DynamicSymbols; 9888bcb0991SDimitry Andric 9898bcb0991SDimitry Andric ELFYAML::RawContentSection *RawSec = 9908bcb0991SDimitry Andric dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec); 991480093f4SDimitry Andric if (RawSec && (RawSec->Content || RawSec->Size)) { 992480093f4SDimitry Andric bool HasSymbolsDescription = 993480093f4SDimitry Andric (IsStatic && Doc.Symbols) || (!IsStatic && Doc.DynamicSymbols); 994480093f4SDimitry Andric if (HasSymbolsDescription) { 995480093f4SDimitry Andric StringRef Property = (IsStatic ? "`Symbols`" : "`DynamicSymbols`"); 9968bcb0991SDimitry Andric if (RawSec->Content) 997480093f4SDimitry Andric reportError("cannot specify both `Content` and " + Property + 9988bcb0991SDimitry Andric " for symbol table section '" + RawSec->Name + "'"); 9998bcb0991SDimitry Andric if (RawSec->Size) 1000480093f4SDimitry Andric reportError("cannot specify both `Size` and " + Property + 10018bcb0991SDimitry Andric " for symbol table section '" + RawSec->Name + "'"); 10028bcb0991SDimitry Andric return; 10038bcb0991SDimitry Andric } 1004480093f4SDimitry Andric } 10058bcb0991SDimitry Andric 10065ffd83dbSDimitry Andric SHeader.sh_name = getSectionNameOffset(IsStatic ? ".symtab" : ".dynsym"); 10078bcb0991SDimitry Andric 10088bcb0991SDimitry Andric if (YAMLSec) 10098bcb0991SDimitry Andric SHeader.sh_type = YAMLSec->Type; 10108bcb0991SDimitry Andric else 10118bcb0991SDimitry Andric SHeader.sh_type = IsStatic ? ELF::SHT_SYMTAB : ELF::SHT_DYNSYM; 10128bcb0991SDimitry Andric 10138bcb0991SDimitry Andric if (YAMLSec && YAMLSec->Flags) 10148bcb0991SDimitry Andric SHeader.sh_flags = *YAMLSec->Flags; 10158bcb0991SDimitry Andric else if (!IsStatic) 10168bcb0991SDimitry Andric SHeader.sh_flags = ELF::SHF_ALLOC; 10178bcb0991SDimitry Andric 10188bcb0991SDimitry Andric // If the symbol table section is explicitly described in the YAML 10198bcb0991SDimitry Andric // then we should set the fields requested. 10208bcb0991SDimitry Andric SHeader.sh_info = (RawSec && RawSec->Info) ? (unsigned)(*RawSec->Info) 10218bcb0991SDimitry Andric : findFirstNonGlobal(Symbols) + 1; 10228bcb0991SDimitry Andric SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 8; 10238bcb0991SDimitry Andric 10245ffd83dbSDimitry Andric assignSectionAddress(SHeader, YAMLSec); 10255ffd83dbSDimitry Andric 1026bdd1243dSDimitry Andric SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign, 1027bdd1243dSDimitry Andric RawSec ? RawSec->Offset : std::nullopt); 10285ffd83dbSDimitry Andric 10298bcb0991SDimitry Andric if (RawSec && (RawSec->Content || RawSec->Size)) { 10308bcb0991SDimitry Andric assert(Symbols.empty()); 10315ffd83dbSDimitry Andric SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size); 10328bcb0991SDimitry Andric return; 10338bcb0991SDimitry Andric } 10348bcb0991SDimitry Andric 10358bcb0991SDimitry Andric std::vector<Elf_Sym> Syms = 10368bcb0991SDimitry Andric toELFSymbols(Symbols, IsStatic ? DotStrtab : DotDynstr); 10375ffd83dbSDimitry Andric SHeader.sh_size = Syms.size() * sizeof(Elf_Sym); 10385ffd83dbSDimitry Andric CBA.write((const char *)Syms.data(), SHeader.sh_size); 10398bcb0991SDimitry Andric } 10408bcb0991SDimitry Andric 10418bcb0991SDimitry Andric template <class ELFT> 10428bcb0991SDimitry Andric void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name, 10438bcb0991SDimitry Andric StringTableBuilder &STB, 10448bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA, 10458bcb0991SDimitry Andric ELFYAML::Section *YAMLSec) { 1046fe6060f1SDimitry Andric SHeader.sh_name = getSectionNameOffset(ELFYAML::dropUniqueSuffix(Name)); 10478bcb0991SDimitry Andric SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_STRTAB; 10488bcb0991SDimitry Andric SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1; 10498bcb0991SDimitry Andric 10508bcb0991SDimitry Andric ELFYAML::RawContentSection *RawSec = 10518bcb0991SDimitry Andric dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec); 10528bcb0991SDimitry Andric 1053e8d8bef9SDimitry Andric SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign, 1054bdd1243dSDimitry Andric YAMLSec ? YAMLSec->Offset : std::nullopt); 10555ffd83dbSDimitry Andric 10568bcb0991SDimitry Andric if (RawSec && (RawSec->Content || RawSec->Size)) { 10575ffd83dbSDimitry Andric SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size); 10588bcb0991SDimitry Andric } else { 10595ffd83dbSDimitry Andric if (raw_ostream *OS = CBA.getRawOS(STB.getSize())) 10605ffd83dbSDimitry Andric STB.write(*OS); 10618bcb0991SDimitry Andric SHeader.sh_size = STB.getSize(); 10628bcb0991SDimitry Andric } 10638bcb0991SDimitry Andric 10648bcb0991SDimitry Andric if (RawSec && RawSec->Info) 10658bcb0991SDimitry Andric SHeader.sh_info = *RawSec->Info; 10668bcb0991SDimitry Andric 10678bcb0991SDimitry Andric if (YAMLSec && YAMLSec->Flags) 10688bcb0991SDimitry Andric SHeader.sh_flags = *YAMLSec->Flags; 10698bcb0991SDimitry Andric else if (Name == ".dynstr") 10708bcb0991SDimitry Andric SHeader.sh_flags = ELF::SHF_ALLOC; 10718bcb0991SDimitry Andric 10725ffd83dbSDimitry Andric assignSectionAddress(SHeader, YAMLSec); 10735ffd83dbSDimitry Andric } 10745ffd83dbSDimitry Andric 10755ffd83dbSDimitry Andric static bool shouldEmitDWARF(DWARFYAML::Data &DWARF, StringRef Name) { 1076e8d8bef9SDimitry Andric SetVector<StringRef> DebugSecNames = DWARF.getNonEmptySectionNames(); 10775ffd83dbSDimitry Andric return Name.consume_front(".") && DebugSecNames.count(Name); 10785ffd83dbSDimitry Andric } 10795ffd83dbSDimitry Andric 10805ffd83dbSDimitry Andric template <class ELFT> 10815ffd83dbSDimitry Andric Expected<uint64_t> emitDWARF(typename ELFT::Shdr &SHeader, StringRef Name, 10825ffd83dbSDimitry Andric const DWARFYAML::Data &DWARF, 10835ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA) { 10845ffd83dbSDimitry Andric // We are unable to predict the size of debug data, so we request to write 0 10855ffd83dbSDimitry Andric // bytes. This should always return us an output stream unless CBA is already 10865ffd83dbSDimitry Andric // in an error state. 10875ffd83dbSDimitry Andric raw_ostream *OS = CBA.getRawOS(0); 10885ffd83dbSDimitry Andric if (!OS) 10895ffd83dbSDimitry Andric return 0; 10905ffd83dbSDimitry Andric 10915ffd83dbSDimitry Andric uint64_t BeginOffset = CBA.tell(); 10925ffd83dbSDimitry Andric 1093e8d8bef9SDimitry Andric auto EmitFunc = DWARFYAML::getDWARFEmitterByName(Name.substr(1)); 1094e8d8bef9SDimitry Andric if (Error Err = EmitFunc(*OS, DWARF)) 10955ffd83dbSDimitry Andric return std::move(Err); 10965ffd83dbSDimitry Andric 10975ffd83dbSDimitry Andric return CBA.tell() - BeginOffset; 10985ffd83dbSDimitry Andric } 10995ffd83dbSDimitry Andric 11005ffd83dbSDimitry Andric template <class ELFT> 11015ffd83dbSDimitry Andric void ELFState<ELFT>::initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name, 11025ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA, 11035ffd83dbSDimitry Andric ELFYAML::Section *YAMLSec) { 11045ffd83dbSDimitry Andric SHeader.sh_name = getSectionNameOffset(ELFYAML::dropUniqueSuffix(Name)); 11055ffd83dbSDimitry Andric SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_PROGBITS; 11065ffd83dbSDimitry Andric SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1; 11075ffd83dbSDimitry Andric SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign, 1108bdd1243dSDimitry Andric YAMLSec ? YAMLSec->Offset : std::nullopt); 11095ffd83dbSDimitry Andric 11105ffd83dbSDimitry Andric ELFYAML::RawContentSection *RawSec = 11115ffd83dbSDimitry Andric dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec); 11125ffd83dbSDimitry Andric if (Doc.DWARF && shouldEmitDWARF(*Doc.DWARF, Name)) { 11135ffd83dbSDimitry Andric if (RawSec && (RawSec->Content || RawSec->Size)) 11145ffd83dbSDimitry Andric reportError("cannot specify section '" + Name + 11155ffd83dbSDimitry Andric "' contents in the 'DWARF' entry and the 'Content' " 11165ffd83dbSDimitry Andric "or 'Size' in the 'Sections' entry at the same time"); 11175ffd83dbSDimitry Andric else { 11185ffd83dbSDimitry Andric if (Expected<uint64_t> ShSizeOrErr = 11195ffd83dbSDimitry Andric emitDWARF<ELFT>(SHeader, Name, *Doc.DWARF, CBA)) 11205ffd83dbSDimitry Andric SHeader.sh_size = *ShSizeOrErr; 11215ffd83dbSDimitry Andric else 11225ffd83dbSDimitry Andric reportError(ShSizeOrErr.takeError()); 11235ffd83dbSDimitry Andric } 11245ffd83dbSDimitry Andric } else if (RawSec) 11255ffd83dbSDimitry Andric SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size); 11265ffd83dbSDimitry Andric else 11275ffd83dbSDimitry Andric llvm_unreachable("debug sections can only be initialized via the 'DWARF' " 11285ffd83dbSDimitry Andric "entry or a RawContentSection"); 11295ffd83dbSDimitry Andric 11305ffd83dbSDimitry Andric if (RawSec && RawSec->Info) 11315ffd83dbSDimitry Andric SHeader.sh_info = *RawSec->Info; 11325ffd83dbSDimitry Andric 11335ffd83dbSDimitry Andric if (YAMLSec && YAMLSec->Flags) 11345ffd83dbSDimitry Andric SHeader.sh_flags = *YAMLSec->Flags; 11355ffd83dbSDimitry Andric else if (Name == ".debug_str") 11365ffd83dbSDimitry Andric SHeader.sh_flags = ELF::SHF_MERGE | ELF::SHF_STRINGS; 11375ffd83dbSDimitry Andric 11385ffd83dbSDimitry Andric assignSectionAddress(SHeader, YAMLSec); 11398bcb0991SDimitry Andric } 11408bcb0991SDimitry Andric 11418bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::reportError(const Twine &Msg) { 11428bcb0991SDimitry Andric ErrHandler(Msg); 11438bcb0991SDimitry Andric HasError = true; 11448bcb0991SDimitry Andric } 11458bcb0991SDimitry Andric 11465ffd83dbSDimitry Andric template <class ELFT> void ELFState<ELFT>::reportError(Error Err) { 11475ffd83dbSDimitry Andric handleAllErrors(std::move(Err), [&](const ErrorInfoBase &Err) { 11485ffd83dbSDimitry Andric reportError(Err.message()); 11495ffd83dbSDimitry Andric }); 11505ffd83dbSDimitry Andric } 11515ffd83dbSDimitry Andric 11528bcb0991SDimitry Andric template <class ELFT> 1153480093f4SDimitry Andric std::vector<Fragment> 1154480093f4SDimitry Andric ELFState<ELFT>::getPhdrFragments(const ELFYAML::ProgramHeader &Phdr, 11555ffd83dbSDimitry Andric ArrayRef<Elf_Shdr> SHeaders) { 1156480093f4SDimitry Andric std::vector<Fragment> Ret; 11575ffd83dbSDimitry Andric for (const ELFYAML::Chunk *C : Phdr.Chunks) { 11585ffd83dbSDimitry Andric if (const ELFYAML::Fill *F = dyn_cast<ELFYAML::Fill>(C)) { 11595ffd83dbSDimitry Andric Ret.push_back({*F->Offset, F->Size, llvm::ELF::SHT_PROGBITS, 1160480093f4SDimitry Andric /*ShAddrAlign=*/1}); 1161480093f4SDimitry Andric continue; 1162480093f4SDimitry Andric } 1163480093f4SDimitry Andric 11645ffd83dbSDimitry Andric const ELFYAML::Section *S = cast<ELFYAML::Section>(C); 11655ffd83dbSDimitry Andric const Elf_Shdr &H = SHeaders[SN2I.get(S->Name)]; 11665ffd83dbSDimitry Andric Ret.push_back({H.sh_offset, H.sh_size, H.sh_type, H.sh_addralign}); 1167480093f4SDimitry Andric } 1168480093f4SDimitry Andric return Ret; 1169480093f4SDimitry Andric } 1170480093f4SDimitry Andric 1171480093f4SDimitry Andric template <class ELFT> 11728bcb0991SDimitry Andric void ELFState<ELFT>::setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders, 11738bcb0991SDimitry Andric std::vector<Elf_Shdr> &SHeaders) { 11748bcb0991SDimitry Andric uint32_t PhdrIdx = 0; 11758bcb0991SDimitry Andric for (auto &YamlPhdr : Doc.ProgramHeaders) { 11768bcb0991SDimitry Andric Elf_Phdr &PHeader = PHeaders[PhdrIdx++]; 1177480093f4SDimitry Andric std::vector<Fragment> Fragments = getPhdrFragments(YamlPhdr, SHeaders); 11785ffd83dbSDimitry Andric if (!llvm::is_sorted(Fragments, [](const Fragment &A, const Fragment &B) { 11795ffd83dbSDimitry Andric return A.Offset < B.Offset; 11805ffd83dbSDimitry Andric })) 11815ffd83dbSDimitry Andric reportError("sections in the program header with index " + 11825ffd83dbSDimitry Andric Twine(PhdrIdx) + " are not sorted by their file offset"); 11838bcb0991SDimitry Andric 11848bcb0991SDimitry Andric if (YamlPhdr.Offset) { 11855ffd83dbSDimitry Andric if (!Fragments.empty() && *YamlPhdr.Offset > Fragments.front().Offset) 11865ffd83dbSDimitry Andric reportError("'Offset' for segment with index " + Twine(PhdrIdx) + 11875ffd83dbSDimitry Andric " must be less than or equal to the minimum file offset of " 11885ffd83dbSDimitry Andric "all included sections (0x" + 11895ffd83dbSDimitry Andric Twine::utohexstr(Fragments.front().Offset) + ")"); 11908bcb0991SDimitry Andric PHeader.p_offset = *YamlPhdr.Offset; 11915ffd83dbSDimitry Andric } else if (!Fragments.empty()) { 11925ffd83dbSDimitry Andric PHeader.p_offset = Fragments.front().Offset; 11935ffd83dbSDimitry Andric } 11948bcb0991SDimitry Andric 11955ffd83dbSDimitry Andric // Set the file size if not set explicitly. 11965ffd83dbSDimitry Andric if (YamlPhdr.FileSize) { 11975ffd83dbSDimitry Andric PHeader.p_filesz = *YamlPhdr.FileSize; 11985ffd83dbSDimitry Andric } else if (!Fragments.empty()) { 11995ffd83dbSDimitry Andric uint64_t FileSize = Fragments.back().Offset - PHeader.p_offset; 12005ffd83dbSDimitry Andric // SHT_NOBITS sections occupy no physical space in a file, we should not 12015ffd83dbSDimitry Andric // take their sizes into account when calculating the file size of a 12025ffd83dbSDimitry Andric // segment. 12035ffd83dbSDimitry Andric if (Fragments.back().Type != llvm::ELF::SHT_NOBITS) 12045ffd83dbSDimitry Andric FileSize += Fragments.back().Size; 12055ffd83dbSDimitry Andric PHeader.p_filesz = FileSize; 12065ffd83dbSDimitry Andric } 12075ffd83dbSDimitry Andric 12085ffd83dbSDimitry Andric // Find the maximum offset of the end of a section in order to set p_memsz. 12095ffd83dbSDimitry Andric uint64_t MemOffset = PHeader.p_offset; 1210480093f4SDimitry Andric for (const Fragment &F : Fragments) 12115ffd83dbSDimitry Andric MemOffset = std::max(MemOffset, F.Offset + F.Size); 12125ffd83dbSDimitry Andric // Set the memory size if not set explicitly. 12138bcb0991SDimitry Andric PHeader.p_memsz = YamlPhdr.MemSize ? uint64_t(*YamlPhdr.MemSize) 12148bcb0991SDimitry Andric : MemOffset - PHeader.p_offset; 12158bcb0991SDimitry Andric 12168bcb0991SDimitry Andric if (YamlPhdr.Align) { 12178bcb0991SDimitry Andric PHeader.p_align = *YamlPhdr.Align; 12188bcb0991SDimitry Andric } else { 12198bcb0991SDimitry Andric // Set the alignment of the segment to be the maximum alignment of the 12208bcb0991SDimitry Andric // sections so that by default the segment has a valid and sensible 12218bcb0991SDimitry Andric // alignment. 12228bcb0991SDimitry Andric PHeader.p_align = 1; 1223480093f4SDimitry Andric for (const Fragment &F : Fragments) 1224480093f4SDimitry Andric PHeader.p_align = std::max((uint64_t)PHeader.p_align, F.AddrAlign); 12258bcb0991SDimitry Andric } 12268bcb0991SDimitry Andric } 12278bcb0991SDimitry Andric } 12288bcb0991SDimitry Andric 1229e8d8bef9SDimitry Andric bool llvm::ELFYAML::shouldAllocateFileSpace( 1230e8d8bef9SDimitry Andric ArrayRef<ELFYAML::ProgramHeader> Phdrs, const ELFYAML::NoBitsSection &S) { 12315ffd83dbSDimitry Andric for (const ELFYAML::ProgramHeader &PH : Phdrs) { 12325ffd83dbSDimitry Andric auto It = llvm::find_if( 12335ffd83dbSDimitry Andric PH.Chunks, [&](ELFYAML::Chunk *C) { return C->Name == S.Name; }); 12345ffd83dbSDimitry Andric if (std::any_of(It, PH.Chunks.end(), [](ELFYAML::Chunk *C) { 12355ffd83dbSDimitry Andric return (isa<ELFYAML::Fill>(C) || 12365ffd83dbSDimitry Andric cast<ELFYAML::Section>(C)->Type != ELF::SHT_NOBITS); 12375ffd83dbSDimitry Andric })) 12385ffd83dbSDimitry Andric return true; 12395ffd83dbSDimitry Andric } 12405ffd83dbSDimitry Andric return false; 12415ffd83dbSDimitry Andric } 12425ffd83dbSDimitry Andric 12435ffd83dbSDimitry Andric template <class ELFT> 12445ffd83dbSDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 12455ffd83dbSDimitry Andric const ELFYAML::NoBitsSection &S, 12465ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA) { 1247e8d8bef9SDimitry Andric if (!S.Size) 1248e8d8bef9SDimitry Andric return; 1249e8d8bef9SDimitry Andric 1250e8d8bef9SDimitry Andric SHeader.sh_size = *S.Size; 12515ffd83dbSDimitry Andric 12525ffd83dbSDimitry Andric // When a nobits section is followed by a non-nobits section or fill 12535ffd83dbSDimitry Andric // in the same segment, we allocate the file space for it. This behavior 12545ffd83dbSDimitry Andric // matches linkers. 12555ffd83dbSDimitry Andric if (shouldAllocateFileSpace(Doc.ProgramHeaders, S)) 1256e8d8bef9SDimitry Andric CBA.writeZeros(*S.Size); 12575ffd83dbSDimitry Andric } 12585ffd83dbSDimitry Andric 12598bcb0991SDimitry Andric template <class ELFT> 12608bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 12618bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::RawContentSection &Section, 12628bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 12638bcb0991SDimitry Andric if (Section.Info) 12648bcb0991SDimitry Andric SHeader.sh_info = *Section.Info; 12658bcb0991SDimitry Andric } 12668bcb0991SDimitry Andric 1267e8d8bef9SDimitry Andric static bool isMips64EL(const ELFYAML::Object &Obj) { 1268e8d8bef9SDimitry Andric return Obj.getMachine() == llvm::ELF::EM_MIPS && 1269e8d8bef9SDimitry Andric Obj.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64) && 1270e8d8bef9SDimitry Andric Obj.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB); 12718bcb0991SDimitry Andric } 12728bcb0991SDimitry Andric 12738bcb0991SDimitry Andric template <class ELFT> 12748bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 12758bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::RelocationSection &Section, 12768bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 12778bcb0991SDimitry Andric assert((Section.Type == llvm::ELF::SHT_REL || 1278*0fca6ea1SDimitry Andric Section.Type == llvm::ELF::SHT_RELA || 1279*0fca6ea1SDimitry Andric Section.Type == llvm::ELF::SHT_CREL) && 12808bcb0991SDimitry Andric "Section type is not SHT_REL nor SHT_RELA"); 12818bcb0991SDimitry Andric 12828bcb0991SDimitry Andric if (!Section.RelocatableSec.empty()) 12838bcb0991SDimitry Andric SHeader.sh_info = toSectionIndex(Section.RelocatableSec, Section.Name); 12848bcb0991SDimitry Andric 1285e8d8bef9SDimitry Andric if (!Section.Relocations) 1286e8d8bef9SDimitry Andric return; 1287e8d8bef9SDimitry Andric 1288*0fca6ea1SDimitry Andric const bool IsCrel = Section.Type == llvm::ELF::SHT_CREL; 1289e8d8bef9SDimitry Andric const bool IsRela = Section.Type == llvm::ELF::SHT_RELA; 1290*0fca6ea1SDimitry Andric typename ELFT::uint OffsetMask = 8, Offset = 0, Addend = 0; 1291*0fca6ea1SDimitry Andric uint32_t SymIdx = 0, Type = 0; 1292*0fca6ea1SDimitry Andric uint64_t CurrentOffset = CBA.getOffset(); 1293*0fca6ea1SDimitry Andric if (IsCrel) 1294*0fca6ea1SDimitry Andric for (const ELFYAML::Relocation &Rel : *Section.Relocations) 1295*0fca6ea1SDimitry Andric OffsetMask |= Rel.Offset; 1296*0fca6ea1SDimitry Andric const int Shift = llvm::countr_zero(OffsetMask); 1297*0fca6ea1SDimitry Andric if (IsCrel) 1298*0fca6ea1SDimitry Andric CBA.writeULEB128(Section.Relocations->size() * 8 + ELF::CREL_HDR_ADDEND + 1299*0fca6ea1SDimitry Andric Shift); 1300e8d8bef9SDimitry Andric for (const ELFYAML::Relocation &Rel : *Section.Relocations) { 1301e8d8bef9SDimitry Andric const bool IsDynamic = Section.Link && (*Section.Link == ".dynsym"); 1302*0fca6ea1SDimitry Andric uint32_t CurSymIdx = 1303e8d8bef9SDimitry Andric Rel.Symbol ? toSymbolIndex(*Rel.Symbol, Section.Name, IsDynamic) : 0; 1304*0fca6ea1SDimitry Andric if (IsCrel) { 1305*0fca6ea1SDimitry Andric // The delta offset and flags member may be larger than uint64_t. Special 1306*0fca6ea1SDimitry Andric // case the first byte (3 flag bits and 4 offset bits). Other ULEB128 1307*0fca6ea1SDimitry Andric // bytes encode the remaining delta offset bits. 1308*0fca6ea1SDimitry Andric auto DeltaOffset = 1309*0fca6ea1SDimitry Andric (static_cast<typename ELFT::uint>(Rel.Offset) - Offset) >> Shift; 1310*0fca6ea1SDimitry Andric Offset = Rel.Offset; 1311*0fca6ea1SDimitry Andric uint8_t B = 1312*0fca6ea1SDimitry Andric DeltaOffset * 8 + (SymIdx != CurSymIdx) + (Type != Rel.Type ? 2 : 0) + 1313*0fca6ea1SDimitry Andric (Addend != static_cast<typename ELFT::uint>(Rel.Addend) ? 4 : 0); 1314*0fca6ea1SDimitry Andric if (DeltaOffset < 0x10) { 1315*0fca6ea1SDimitry Andric CBA.write(B); 1316*0fca6ea1SDimitry Andric } else { 1317*0fca6ea1SDimitry Andric CBA.write(B | 0x80); 1318*0fca6ea1SDimitry Andric CBA.writeULEB128(DeltaOffset >> 4); 1319*0fca6ea1SDimitry Andric } 1320*0fca6ea1SDimitry Andric // Delta symidx/type/addend members (SLEB128). 1321*0fca6ea1SDimitry Andric if (B & 1) { 1322*0fca6ea1SDimitry Andric CBA.writeSLEB128( 1323*0fca6ea1SDimitry Andric std::make_signed_t<typename ELFT::uint>(CurSymIdx - SymIdx)); 1324*0fca6ea1SDimitry Andric SymIdx = CurSymIdx; 1325*0fca6ea1SDimitry Andric } 1326*0fca6ea1SDimitry Andric if (B & 2) { 1327*0fca6ea1SDimitry Andric CBA.writeSLEB128(static_cast<int32_t>(Rel.Type - Type)); 1328*0fca6ea1SDimitry Andric Type = Rel.Type; 1329*0fca6ea1SDimitry Andric } 1330*0fca6ea1SDimitry Andric if (B & 4) { 1331*0fca6ea1SDimitry Andric CBA.writeSLEB128( 1332*0fca6ea1SDimitry Andric std::make_signed_t<typename ELFT::uint>(Rel.Addend - Addend)); 1333*0fca6ea1SDimitry Andric Addend = Rel.Addend; 1334*0fca6ea1SDimitry Andric } 1335*0fca6ea1SDimitry Andric } else if (IsRela) { 13368bcb0991SDimitry Andric Elf_Rela REntry; 13378bcb0991SDimitry Andric zero(REntry); 13388bcb0991SDimitry Andric REntry.r_offset = Rel.Offset; 13398bcb0991SDimitry Andric REntry.r_addend = Rel.Addend; 1340*0fca6ea1SDimitry Andric REntry.setSymbolAndType(CurSymIdx, Rel.Type, isMips64EL(Doc)); 13415ffd83dbSDimitry Andric CBA.write((const char *)&REntry, sizeof(REntry)); 13428bcb0991SDimitry Andric } else { 13438bcb0991SDimitry Andric Elf_Rel REntry; 13448bcb0991SDimitry Andric zero(REntry); 13458bcb0991SDimitry Andric REntry.r_offset = Rel.Offset; 1346*0fca6ea1SDimitry Andric REntry.setSymbolAndType(CurSymIdx, Rel.Type, isMips64EL(Doc)); 13475ffd83dbSDimitry Andric CBA.write((const char *)&REntry, sizeof(REntry)); 13488bcb0991SDimitry Andric } 13498bcb0991SDimitry Andric } 1350e8d8bef9SDimitry Andric 1351*0fca6ea1SDimitry Andric SHeader.sh_size = CBA.getOffset() - CurrentOffset; 13528bcb0991SDimitry Andric } 13538bcb0991SDimitry Andric 13548bcb0991SDimitry Andric template <class ELFT> 1355480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 1356480093f4SDimitry Andric const ELFYAML::RelrSection &Section, 1357480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1358480093f4SDimitry Andric if (!Section.Entries) 1359480093f4SDimitry Andric return; 1360480093f4SDimitry Andric 1361480093f4SDimitry Andric for (llvm::yaml::Hex64 E : *Section.Entries) { 1362480093f4SDimitry Andric if (!ELFT::Is64Bits && E > UINT32_MAX) 1363480093f4SDimitry Andric reportError(Section.Name + ": the value is too large for 32-bits: 0x" + 1364480093f4SDimitry Andric Twine::utohexstr(E)); 1365*0fca6ea1SDimitry Andric CBA.write<uintX_t>(E, ELFT::Endianness); 1366480093f4SDimitry Andric } 1367480093f4SDimitry Andric 1368480093f4SDimitry Andric SHeader.sh_size = sizeof(uintX_t) * Section.Entries->size(); 1369480093f4SDimitry Andric } 1370480093f4SDimitry Andric 1371480093f4SDimitry Andric template <class ELFT> 13728bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 13738bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::SymtabShndxSection &Shndx, 13748bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 1375e8d8bef9SDimitry Andric if (Shndx.Content || Shndx.Size) { 1376e8d8bef9SDimitry Andric SHeader.sh_size = writeContent(CBA, Shndx.Content, Shndx.Size); 1377e8d8bef9SDimitry Andric return; 1378e8d8bef9SDimitry Andric } 13798bcb0991SDimitry Andric 1380e8d8bef9SDimitry Andric if (!Shndx.Entries) 1381e8d8bef9SDimitry Andric return; 1382e8d8bef9SDimitry Andric 1383e8d8bef9SDimitry Andric for (uint32_t E : *Shndx.Entries) 1384*0fca6ea1SDimitry Andric CBA.write<uint32_t>(E, ELFT::Endianness); 1385e8d8bef9SDimitry Andric SHeader.sh_size = Shndx.Entries->size() * SHeader.sh_entsize; 13868bcb0991SDimitry Andric } 13878bcb0991SDimitry Andric 13888bcb0991SDimitry Andric template <class ELFT> 13898bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 1390e8d8bef9SDimitry Andric const ELFYAML::GroupSection &Section, 13918bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 13928bcb0991SDimitry Andric assert(Section.Type == llvm::ELF::SHT_GROUP && 13938bcb0991SDimitry Andric "Section type is not SHT_GROUP"); 13948bcb0991SDimitry Andric 1395480093f4SDimitry Andric if (Section.Signature) 13968bcb0991SDimitry Andric SHeader.sh_info = 1397480093f4SDimitry Andric toSymbolIndex(*Section.Signature, Section.Name, /*IsDynamic=*/false); 13988bcb0991SDimitry Andric 1399e8d8bef9SDimitry Andric if (!Section.Members) 1400e8d8bef9SDimitry Andric return; 1401e8d8bef9SDimitry Andric 1402e8d8bef9SDimitry Andric for (const ELFYAML::SectionOrType &Member : *Section.Members) { 14038bcb0991SDimitry Andric unsigned int SectionIndex = 0; 14048bcb0991SDimitry Andric if (Member.sectionNameOrType == "GRP_COMDAT") 14058bcb0991SDimitry Andric SectionIndex = llvm::ELF::GRP_COMDAT; 14068bcb0991SDimitry Andric else 14078bcb0991SDimitry Andric SectionIndex = toSectionIndex(Member.sectionNameOrType, Section.Name); 1408*0fca6ea1SDimitry Andric CBA.write<uint32_t>(SectionIndex, ELFT::Endianness); 14098bcb0991SDimitry Andric } 1410e8d8bef9SDimitry Andric SHeader.sh_size = SHeader.sh_entsize * Section.Members->size(); 14118bcb0991SDimitry Andric } 14128bcb0991SDimitry Andric 14138bcb0991SDimitry Andric template <class ELFT> 14148bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 14158bcb0991SDimitry Andric const ELFYAML::SymverSection &Section, 14168bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 1417e8d8bef9SDimitry Andric if (!Section.Entries) 1418e8d8bef9SDimitry Andric return; 14198bcb0991SDimitry Andric 1420e8d8bef9SDimitry Andric for (uint16_t Version : *Section.Entries) 1421*0fca6ea1SDimitry Andric CBA.write<uint16_t>(Version, ELFT::Endianness); 1422e8d8bef9SDimitry Andric SHeader.sh_size = Section.Entries->size() * SHeader.sh_entsize; 14238bcb0991SDimitry Andric } 14248bcb0991SDimitry Andric 14258bcb0991SDimitry Andric template <class ELFT> 14268bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent( 14278bcb0991SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::StackSizesSection &Section, 14288bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 1429e8d8bef9SDimitry Andric if (!Section.Entries) 14308bcb0991SDimitry Andric return; 1431e8d8bef9SDimitry Andric 14328bcb0991SDimitry Andric for (const ELFYAML::StackSizeEntry &E : *Section.Entries) { 1433*0fca6ea1SDimitry Andric CBA.write<uintX_t>(E.Address, ELFT::Endianness); 14345ffd83dbSDimitry Andric SHeader.sh_size += sizeof(uintX_t) + CBA.writeULEB128(E.Size); 14358bcb0991SDimitry Andric } 14368bcb0991SDimitry Andric } 14378bcb0991SDimitry Andric 14388bcb0991SDimitry Andric template <class ELFT> 1439480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent( 1440e8d8bef9SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::BBAddrMapSection &Section, 1441480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 14425f757f3fSDimitry Andric if (!Section.Entries) { 14435f757f3fSDimitry Andric if (Section.PGOAnalyses) 14445f757f3fSDimitry Andric WithColor::warning() 14455f757f3fSDimitry Andric << "PGOAnalyses should not exist in SHT_LLVM_BB_ADDR_MAP when " 14465f757f3fSDimitry Andric "Entries does not exist"; 1447480093f4SDimitry Andric return; 14485f757f3fSDimitry Andric } 1449e8d8bef9SDimitry Andric 14505f757f3fSDimitry Andric const std::vector<ELFYAML::PGOAnalysisMapEntry> *PGOAnalyses = nullptr; 14515f757f3fSDimitry Andric if (Section.PGOAnalyses) { 14525f757f3fSDimitry Andric if (Section.Entries->size() != Section.PGOAnalyses->size()) 14535f757f3fSDimitry Andric WithColor::warning() << "PGOAnalyses must be the same length as Entries " 14545f757f3fSDimitry Andric "in SHT_LLVM_BB_ADDR_MAP"; 14555f757f3fSDimitry Andric else 14565f757f3fSDimitry Andric PGOAnalyses = &Section.PGOAnalyses.value(); 14575f757f3fSDimitry Andric } 14585f757f3fSDimitry Andric 14595f757f3fSDimitry Andric for (const auto &[Idx, E] : llvm::enumerate(*Section.Entries)) { 146081ad6265SDimitry Andric // Write version and feature values. 146181ad6265SDimitry Andric if (Section.Type == llvm::ELF::SHT_LLVM_BB_ADDR_MAP) { 1462bdd1243dSDimitry Andric if (E.Version > 2) 146381ad6265SDimitry Andric WithColor::warning() << "unsupported SHT_LLVM_BB_ADDR_MAP version: " 146481ad6265SDimitry Andric << static_cast<int>(E.Version) 146581ad6265SDimitry Andric << "; encoding using the most recent version"; 146681ad6265SDimitry Andric CBA.write(E.Version); 146781ad6265SDimitry Andric CBA.write(E.Feature); 146881ad6265SDimitry Andric SHeader.sh_size += 2; 146981ad6265SDimitry Andric } 1470*0fca6ea1SDimitry Andric auto FeatureOrErr = llvm::object::BBAddrMap::Features::decode(E.Feature); 1471*0fca6ea1SDimitry Andric bool MultiBBRangeFeatureEnabled = false; 1472*0fca6ea1SDimitry Andric if (!FeatureOrErr) 1473*0fca6ea1SDimitry Andric WithColor::warning() << toString(FeatureOrErr.takeError()); 1474*0fca6ea1SDimitry Andric else 1475*0fca6ea1SDimitry Andric MultiBBRangeFeatureEnabled = FeatureOrErr->MultiBBRange; 1476*0fca6ea1SDimitry Andric bool MultiBBRange = 1477*0fca6ea1SDimitry Andric MultiBBRangeFeatureEnabled || 1478*0fca6ea1SDimitry Andric (E.NumBBRanges.has_value() && E.NumBBRanges.value() != 1) || 1479*0fca6ea1SDimitry Andric (E.BBRanges && E.BBRanges->size() != 1); 1480*0fca6ea1SDimitry Andric if (MultiBBRange && !MultiBBRangeFeatureEnabled) 1481*0fca6ea1SDimitry Andric WithColor::warning() << "feature value(" << E.Feature 1482*0fca6ea1SDimitry Andric << ") does not support multiple BB ranges."; 1483*0fca6ea1SDimitry Andric if (MultiBBRange) { 1484*0fca6ea1SDimitry Andric // Write the number of basic block ranges, which is overridden by the 1485*0fca6ea1SDimitry Andric // 'NumBBRanges' field when specified. 1486*0fca6ea1SDimitry Andric uint64_t NumBBRanges = 1487*0fca6ea1SDimitry Andric E.NumBBRanges.value_or(E.BBRanges ? E.BBRanges->size() : 0); 1488*0fca6ea1SDimitry Andric SHeader.sh_size += CBA.writeULEB128(NumBBRanges); 14895f757f3fSDimitry Andric } 1490*0fca6ea1SDimitry Andric if (!E.BBRanges) 1491*0fca6ea1SDimitry Andric continue; 1492*0fca6ea1SDimitry Andric uint64_t TotalNumBlocks = 0; 1493*0fca6ea1SDimitry Andric for (const ELFYAML::BBAddrMapEntry::BBRangeEntry &BBR : *E.BBRanges) { 1494*0fca6ea1SDimitry Andric // Write the base address of the range. 1495*0fca6ea1SDimitry Andric CBA.write<uintX_t>(BBR.BaseAddress, ELFT::Endianness); 1496*0fca6ea1SDimitry Andric // Write number of BBEntries (number of basic blocks in this basic block 1497*0fca6ea1SDimitry Andric // range). This is overridden by the 'NumBlocks' YAML field when 1498*0fca6ea1SDimitry Andric // specified. 1499fe6060f1SDimitry Andric uint64_t NumBlocks = 1500*0fca6ea1SDimitry Andric BBR.NumBlocks.value_or(BBR.BBEntries ? BBR.BBEntries->size() : 0); 1501e8d8bef9SDimitry Andric SHeader.sh_size += sizeof(uintX_t) + CBA.writeULEB128(NumBlocks); 1502*0fca6ea1SDimitry Andric // Write all BBEntries in this BBRange. 1503*0fca6ea1SDimitry Andric if (!BBR.BBEntries) 1504*0fca6ea1SDimitry Andric continue; 1505*0fca6ea1SDimitry Andric for (const ELFYAML::BBAddrMapEntry::BBEntry &BBE : *BBR.BBEntries) { 1506*0fca6ea1SDimitry Andric ++TotalNumBlocks; 1507bdd1243dSDimitry Andric if (Section.Type == llvm::ELF::SHT_LLVM_BB_ADDR_MAP && E.Version > 1) 1508bdd1243dSDimitry Andric SHeader.sh_size += CBA.writeULEB128(BBE.ID); 1509*0fca6ea1SDimitry Andric SHeader.sh_size += CBA.writeULEB128(BBE.AddressOffset); 1510*0fca6ea1SDimitry Andric SHeader.sh_size += CBA.writeULEB128(BBE.Size); 1511*0fca6ea1SDimitry Andric SHeader.sh_size += CBA.writeULEB128(BBE.Metadata); 1512e8d8bef9SDimitry Andric } 1513480093f4SDimitry Andric } 15145f757f3fSDimitry Andric if (!PGOAnalyses) 15155f757f3fSDimitry Andric continue; 15165f757f3fSDimitry Andric const ELFYAML::PGOAnalysisMapEntry &PGOEntry = PGOAnalyses->at(Idx); 15175f757f3fSDimitry Andric 15185f757f3fSDimitry Andric if (PGOEntry.FuncEntryCount) 15195f757f3fSDimitry Andric SHeader.sh_size += CBA.writeULEB128(*PGOEntry.FuncEntryCount); 15205f757f3fSDimitry Andric 15215f757f3fSDimitry Andric if (!PGOEntry.PGOBBEntries) 15225f757f3fSDimitry Andric continue; 15235f757f3fSDimitry Andric 15245f757f3fSDimitry Andric const auto &PGOBBEntries = PGOEntry.PGOBBEntries.value(); 1525*0fca6ea1SDimitry Andric if (TotalNumBlocks != PGOBBEntries.size()) { 15265f757f3fSDimitry Andric WithColor::warning() << "PBOBBEntries must be the same length as " 15275f757f3fSDimitry Andric "BBEntries in SHT_LLVM_BB_ADDR_MAP.\n" 15285f757f3fSDimitry Andric << "Mismatch on function with address: " 1529*0fca6ea1SDimitry Andric << E.getFunctionAddress(); 15305f757f3fSDimitry Andric continue; 15315f757f3fSDimitry Andric } 15325f757f3fSDimitry Andric 15335f757f3fSDimitry Andric for (const auto &PGOBBE : PGOBBEntries) { 15345f757f3fSDimitry Andric if (PGOBBE.BBFreq) 15355f757f3fSDimitry Andric SHeader.sh_size += CBA.writeULEB128(*PGOBBE.BBFreq); 15365f757f3fSDimitry Andric if (PGOBBE.Successors) { 15375f757f3fSDimitry Andric SHeader.sh_size += CBA.writeULEB128(PGOBBE.Successors->size()); 1538*0fca6ea1SDimitry Andric for (const auto &[ID, BrProb] : *PGOBBE.Successors) { 1539*0fca6ea1SDimitry Andric SHeader.sh_size += CBA.writeULEB128(ID); 1540*0fca6ea1SDimitry Andric SHeader.sh_size += CBA.writeULEB128(BrProb); 1541*0fca6ea1SDimitry Andric } 15425f757f3fSDimitry Andric } 15435f757f3fSDimitry Andric } 15445f757f3fSDimitry Andric } 1545bdd1243dSDimitry Andric } 1546480093f4SDimitry Andric 1547e8d8bef9SDimitry Andric template <class ELFT> 1548e8d8bef9SDimitry Andric void ELFState<ELFT>::writeSectionContent( 1549e8d8bef9SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::LinkerOptionsSection &Section, 1550e8d8bef9SDimitry Andric ContiguousBlobAccumulator &CBA) { 1551480093f4SDimitry Andric if (!Section.Options) 1552480093f4SDimitry Andric return; 1553480093f4SDimitry Andric 1554480093f4SDimitry Andric for (const ELFYAML::LinkerOption &LO : *Section.Options) { 15555ffd83dbSDimitry Andric CBA.write(LO.Key.data(), LO.Key.size()); 15565ffd83dbSDimitry Andric CBA.write('\0'); 15575ffd83dbSDimitry Andric CBA.write(LO.Value.data(), LO.Value.size()); 15585ffd83dbSDimitry Andric CBA.write('\0'); 1559480093f4SDimitry Andric SHeader.sh_size += (LO.Key.size() + LO.Value.size() + 2); 1560480093f4SDimitry Andric } 1561480093f4SDimitry Andric } 1562480093f4SDimitry Andric 1563480093f4SDimitry Andric template <class ELFT> 1564480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent( 1565480093f4SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::DependentLibrariesSection &Section, 1566480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1567480093f4SDimitry Andric if (!Section.Libs) 1568480093f4SDimitry Andric return; 1569480093f4SDimitry Andric 1570480093f4SDimitry Andric for (StringRef Lib : *Section.Libs) { 15715ffd83dbSDimitry Andric CBA.write(Lib.data(), Lib.size()); 15725ffd83dbSDimitry Andric CBA.write('\0'); 1573480093f4SDimitry Andric SHeader.sh_size += Lib.size() + 1; 1574480093f4SDimitry Andric } 1575480093f4SDimitry Andric } 1576480093f4SDimitry Andric 1577480093f4SDimitry Andric template <class ELFT> 15785ffd83dbSDimitry Andric uint64_t 15795ffd83dbSDimitry Andric ELFState<ELFT>::alignToOffset(ContiguousBlobAccumulator &CBA, uint64_t Align, 1580bdd1243dSDimitry Andric std::optional<llvm::yaml::Hex64> Offset) { 15815ffd83dbSDimitry Andric uint64_t CurrentOffset = CBA.getOffset(); 15825ffd83dbSDimitry Andric uint64_t AlignedOffset; 15835ffd83dbSDimitry Andric 15845ffd83dbSDimitry Andric if (Offset) { 15855ffd83dbSDimitry Andric if ((uint64_t)*Offset < CurrentOffset) { 15865ffd83dbSDimitry Andric reportError("the 'Offset' value (0x" + 15875ffd83dbSDimitry Andric Twine::utohexstr((uint64_t)*Offset) + ") goes backward"); 15885ffd83dbSDimitry Andric return CurrentOffset; 15895ffd83dbSDimitry Andric } 15905ffd83dbSDimitry Andric 15915ffd83dbSDimitry Andric // We ignore an alignment when an explicit offset has been requested. 15925ffd83dbSDimitry Andric AlignedOffset = *Offset; 15935ffd83dbSDimitry Andric } else { 15945ffd83dbSDimitry Andric AlignedOffset = alignTo(CurrentOffset, std::max(Align, (uint64_t)1)); 15955ffd83dbSDimitry Andric } 15965ffd83dbSDimitry Andric 15975ffd83dbSDimitry Andric CBA.writeZeros(AlignedOffset - CurrentOffset); 15985ffd83dbSDimitry Andric return AlignedOffset; 15995ffd83dbSDimitry Andric } 16005ffd83dbSDimitry Andric 16015ffd83dbSDimitry Andric template <class ELFT> 16025ffd83dbSDimitry Andric void ELFState<ELFT>::writeSectionContent( 16035ffd83dbSDimitry Andric Elf_Shdr &SHeader, const ELFYAML::CallGraphProfileSection &Section, 16045ffd83dbSDimitry Andric ContiguousBlobAccumulator &CBA) { 16055ffd83dbSDimitry Andric if (!Section.Entries) 16065ffd83dbSDimitry Andric return; 16075ffd83dbSDimitry Andric 1608fe6060f1SDimitry Andric for (const ELFYAML::CallGraphEntryWeight &E : *Section.Entries) { 1609*0fca6ea1SDimitry Andric CBA.write<uint64_t>(E.Weight, ELFT::Endianness); 1610fe6060f1SDimitry Andric SHeader.sh_size += sizeof(object::Elf_CGProfile_Impl<ELFT>); 16115ffd83dbSDimitry Andric } 16125ffd83dbSDimitry Andric } 16135ffd83dbSDimitry Andric 16145ffd83dbSDimitry Andric template <class ELFT> 16158bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 16168bcb0991SDimitry Andric const ELFYAML::HashSection &Section, 16178bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 1618e8d8bef9SDimitry Andric if (!Section.Bucket) 16198bcb0991SDimitry Andric return; 1620e8d8bef9SDimitry Andric 16215ffd83dbSDimitry Andric CBA.write<uint32_t>( 162281ad6265SDimitry Andric Section.NBucket.value_or(llvm::yaml::Hex64(Section.Bucket->size())), 1623*0fca6ea1SDimitry Andric ELFT::Endianness); 16245ffd83dbSDimitry Andric CBA.write<uint32_t>( 162581ad6265SDimitry Andric Section.NChain.value_or(llvm::yaml::Hex64(Section.Chain->size())), 1626*0fca6ea1SDimitry Andric ELFT::Endianness); 16275ffd83dbSDimitry Andric 16288bcb0991SDimitry Andric for (uint32_t Val : *Section.Bucket) 1629*0fca6ea1SDimitry Andric CBA.write<uint32_t>(Val, ELFT::Endianness); 16308bcb0991SDimitry Andric for (uint32_t Val : *Section.Chain) 1631*0fca6ea1SDimitry Andric CBA.write<uint32_t>(Val, ELFT::Endianness); 16328bcb0991SDimitry Andric 16338bcb0991SDimitry Andric SHeader.sh_size = (2 + Section.Bucket->size() + Section.Chain->size()) * 4; 16348bcb0991SDimitry Andric } 16358bcb0991SDimitry Andric 16368bcb0991SDimitry Andric template <class ELFT> 16378bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 16388bcb0991SDimitry Andric const ELFYAML::VerdefSection &Section, 16398bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 16408bcb0991SDimitry Andric 1641e8d8bef9SDimitry Andric if (Section.Info) 1642e8d8bef9SDimitry Andric SHeader.sh_info = *Section.Info; 1643e8d8bef9SDimitry Andric else if (Section.Entries) 1644e8d8bef9SDimitry Andric SHeader.sh_info = Section.Entries->size(); 1645480093f4SDimitry Andric 1646480093f4SDimitry Andric if (!Section.Entries) 1647480093f4SDimitry Andric return; 1648480093f4SDimitry Andric 16498bcb0991SDimitry Andric uint64_t AuxCnt = 0; 1650480093f4SDimitry Andric for (size_t I = 0; I < Section.Entries->size(); ++I) { 1651480093f4SDimitry Andric const ELFYAML::VerdefEntry &E = (*Section.Entries)[I]; 16528bcb0991SDimitry Andric 16538bcb0991SDimitry Andric Elf_Verdef VerDef; 165481ad6265SDimitry Andric VerDef.vd_version = E.Version.value_or(1); 165581ad6265SDimitry Andric VerDef.vd_flags = E.Flags.value_or(0); 165681ad6265SDimitry Andric VerDef.vd_ndx = E.VersionNdx.value_or(0); 165781ad6265SDimitry Andric VerDef.vd_hash = E.Hash.value_or(0); 16588bcb0991SDimitry Andric VerDef.vd_aux = sizeof(Elf_Verdef); 16598bcb0991SDimitry Andric VerDef.vd_cnt = E.VerNames.size(); 1660480093f4SDimitry Andric if (I == Section.Entries->size() - 1) 16618bcb0991SDimitry Andric VerDef.vd_next = 0; 16628bcb0991SDimitry Andric else 16638bcb0991SDimitry Andric VerDef.vd_next = 16648bcb0991SDimitry Andric sizeof(Elf_Verdef) + E.VerNames.size() * sizeof(Elf_Verdaux); 16655ffd83dbSDimitry Andric CBA.write((const char *)&VerDef, sizeof(Elf_Verdef)); 16668bcb0991SDimitry Andric 16678bcb0991SDimitry Andric for (size_t J = 0; J < E.VerNames.size(); ++J, ++AuxCnt) { 16688bcb0991SDimitry Andric Elf_Verdaux VernAux; 16698bcb0991SDimitry Andric VernAux.vda_name = DotDynstr.getOffset(E.VerNames[J]); 16708bcb0991SDimitry Andric if (J == E.VerNames.size() - 1) 16718bcb0991SDimitry Andric VernAux.vda_next = 0; 16728bcb0991SDimitry Andric else 16738bcb0991SDimitry Andric VernAux.vda_next = sizeof(Elf_Verdaux); 16745ffd83dbSDimitry Andric CBA.write((const char *)&VernAux, sizeof(Elf_Verdaux)); 16758bcb0991SDimitry Andric } 16768bcb0991SDimitry Andric } 16778bcb0991SDimitry Andric 1678480093f4SDimitry Andric SHeader.sh_size = Section.Entries->size() * sizeof(Elf_Verdef) + 16798bcb0991SDimitry Andric AuxCnt * sizeof(Elf_Verdaux); 16808bcb0991SDimitry Andric } 16818bcb0991SDimitry Andric 16828bcb0991SDimitry Andric template <class ELFT> 16838bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 16848bcb0991SDimitry Andric const ELFYAML::VerneedSection &Section, 16858bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 1686e8d8bef9SDimitry Andric if (Section.Info) 1687e8d8bef9SDimitry Andric SHeader.sh_info = *Section.Info; 1688e8d8bef9SDimitry Andric else if (Section.VerneedV) 1689e8d8bef9SDimitry Andric SHeader.sh_info = Section.VerneedV->size(); 1690480093f4SDimitry Andric 1691480093f4SDimitry Andric if (!Section.VerneedV) 1692480093f4SDimitry Andric return; 16938bcb0991SDimitry Andric 16948bcb0991SDimitry Andric uint64_t AuxCnt = 0; 1695480093f4SDimitry Andric for (size_t I = 0; I < Section.VerneedV->size(); ++I) { 1696480093f4SDimitry Andric const ELFYAML::VerneedEntry &VE = (*Section.VerneedV)[I]; 16978bcb0991SDimitry Andric 16988bcb0991SDimitry Andric Elf_Verneed VerNeed; 16998bcb0991SDimitry Andric VerNeed.vn_version = VE.Version; 17008bcb0991SDimitry Andric VerNeed.vn_file = DotDynstr.getOffset(VE.File); 1701480093f4SDimitry Andric if (I == Section.VerneedV->size() - 1) 17028bcb0991SDimitry Andric VerNeed.vn_next = 0; 17038bcb0991SDimitry Andric else 17048bcb0991SDimitry Andric VerNeed.vn_next = 17058bcb0991SDimitry Andric sizeof(Elf_Verneed) + VE.AuxV.size() * sizeof(Elf_Vernaux); 17068bcb0991SDimitry Andric VerNeed.vn_cnt = VE.AuxV.size(); 17078bcb0991SDimitry Andric VerNeed.vn_aux = sizeof(Elf_Verneed); 17085ffd83dbSDimitry Andric CBA.write((const char *)&VerNeed, sizeof(Elf_Verneed)); 17098bcb0991SDimitry Andric 17108bcb0991SDimitry Andric for (size_t J = 0; J < VE.AuxV.size(); ++J, ++AuxCnt) { 17118bcb0991SDimitry Andric const ELFYAML::VernauxEntry &VAuxE = VE.AuxV[J]; 17128bcb0991SDimitry Andric 17138bcb0991SDimitry Andric Elf_Vernaux VernAux; 17148bcb0991SDimitry Andric VernAux.vna_hash = VAuxE.Hash; 17158bcb0991SDimitry Andric VernAux.vna_flags = VAuxE.Flags; 17168bcb0991SDimitry Andric VernAux.vna_other = VAuxE.Other; 17178bcb0991SDimitry Andric VernAux.vna_name = DotDynstr.getOffset(VAuxE.Name); 17188bcb0991SDimitry Andric if (J == VE.AuxV.size() - 1) 17198bcb0991SDimitry Andric VernAux.vna_next = 0; 17208bcb0991SDimitry Andric else 17218bcb0991SDimitry Andric VernAux.vna_next = sizeof(Elf_Vernaux); 17225ffd83dbSDimitry Andric CBA.write((const char *)&VernAux, sizeof(Elf_Vernaux)); 17238bcb0991SDimitry Andric } 17248bcb0991SDimitry Andric } 17258bcb0991SDimitry Andric 1726480093f4SDimitry Andric SHeader.sh_size = Section.VerneedV->size() * sizeof(Elf_Verneed) + 17278bcb0991SDimitry Andric AuxCnt * sizeof(Elf_Vernaux); 17288bcb0991SDimitry Andric } 17298bcb0991SDimitry Andric 17308bcb0991SDimitry Andric template <class ELFT> 1731e8d8bef9SDimitry Andric void ELFState<ELFT>::writeSectionContent( 1732e8d8bef9SDimitry Andric Elf_Shdr &SHeader, const ELFYAML::ARMIndexTableSection &Section, 1733e8d8bef9SDimitry Andric ContiguousBlobAccumulator &CBA) { 1734e8d8bef9SDimitry Andric if (!Section.Entries) 1735e8d8bef9SDimitry Andric return; 1736e8d8bef9SDimitry Andric 1737e8d8bef9SDimitry Andric for (const ELFYAML::ARMIndexTableEntry &E : *Section.Entries) { 1738*0fca6ea1SDimitry Andric CBA.write<uint32_t>(E.Offset, ELFT::Endianness); 1739*0fca6ea1SDimitry Andric CBA.write<uint32_t>(E.Value, ELFT::Endianness); 1740e8d8bef9SDimitry Andric } 1741e8d8bef9SDimitry Andric SHeader.sh_size = Section.Entries->size() * 8; 1742e8d8bef9SDimitry Andric } 1743e8d8bef9SDimitry Andric 1744e8d8bef9SDimitry Andric template <class ELFT> 17458bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 17468bcb0991SDimitry Andric const ELFYAML::MipsABIFlags &Section, 17478bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 17488bcb0991SDimitry Andric assert(Section.Type == llvm::ELF::SHT_MIPS_ABIFLAGS && 17498bcb0991SDimitry Andric "Section type is not SHT_MIPS_ABIFLAGS"); 17508bcb0991SDimitry Andric 17518bcb0991SDimitry Andric object::Elf_Mips_ABIFlags<ELFT> Flags; 17528bcb0991SDimitry Andric zero(Flags); 17538bcb0991SDimitry Andric SHeader.sh_size = SHeader.sh_entsize; 17548bcb0991SDimitry Andric 17558bcb0991SDimitry Andric Flags.version = Section.Version; 17568bcb0991SDimitry Andric Flags.isa_level = Section.ISALevel; 17578bcb0991SDimitry Andric Flags.isa_rev = Section.ISARevision; 17588bcb0991SDimitry Andric Flags.gpr_size = Section.GPRSize; 17598bcb0991SDimitry Andric Flags.cpr1_size = Section.CPR1Size; 17608bcb0991SDimitry Andric Flags.cpr2_size = Section.CPR2Size; 17618bcb0991SDimitry Andric Flags.fp_abi = Section.FpABI; 17628bcb0991SDimitry Andric Flags.isa_ext = Section.ISAExtension; 17638bcb0991SDimitry Andric Flags.ases = Section.ASEs; 17648bcb0991SDimitry Andric Flags.flags1 = Section.Flags1; 17658bcb0991SDimitry Andric Flags.flags2 = Section.Flags2; 17665ffd83dbSDimitry Andric CBA.write((const char *)&Flags, sizeof(Flags)); 17678bcb0991SDimitry Andric } 17688bcb0991SDimitry Andric 17698bcb0991SDimitry Andric template <class ELFT> 17708bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 17718bcb0991SDimitry Andric const ELFYAML::DynamicSection &Section, 17728bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 17738bcb0991SDimitry Andric assert(Section.Type == llvm::ELF::SHT_DYNAMIC && 17748bcb0991SDimitry Andric "Section type is not SHT_DYNAMIC"); 17758bcb0991SDimitry Andric 1776e8d8bef9SDimitry Andric if (!Section.Entries) 1777e8d8bef9SDimitry Andric return; 17788bcb0991SDimitry Andric 1779e8d8bef9SDimitry Andric for (const ELFYAML::DynamicEntry &DE : *Section.Entries) { 1780*0fca6ea1SDimitry Andric CBA.write<uintX_t>(DE.Tag, ELFT::Endianness); 1781*0fca6ea1SDimitry Andric CBA.write<uintX_t>(DE.Val, ELFT::Endianness); 17828bcb0991SDimitry Andric } 1783e8d8bef9SDimitry Andric SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries->size(); 17848bcb0991SDimitry Andric } 17858bcb0991SDimitry Andric 17868bcb0991SDimitry Andric template <class ELFT> 17878bcb0991SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 17888bcb0991SDimitry Andric const ELFYAML::AddrsigSection &Section, 17898bcb0991SDimitry Andric ContiguousBlobAccumulator &CBA) { 1790e8d8bef9SDimitry Andric if (!Section.Symbols) 17918bcb0991SDimitry Andric return; 1792e8d8bef9SDimitry Andric 17935ffd83dbSDimitry Andric for (StringRef Sym : *Section.Symbols) 17945ffd83dbSDimitry Andric SHeader.sh_size += 17955ffd83dbSDimitry Andric CBA.writeULEB128(toSymbolIndex(Sym, Section.Name, /*IsDynamic=*/false)); 17968bcb0991SDimitry Andric } 17978bcb0991SDimitry Andric 1798480093f4SDimitry Andric template <class ELFT> 1799480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 1800480093f4SDimitry Andric const ELFYAML::NoteSection &Section, 1801480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1802e8d8bef9SDimitry Andric if (!Section.Notes) 1803480093f4SDimitry Andric return; 1804480093f4SDimitry Andric 1805e8d8bef9SDimitry Andric uint64_t Offset = CBA.tell(); 1806480093f4SDimitry Andric for (const ELFYAML::NoteEntry &NE : *Section.Notes) { 1807480093f4SDimitry Andric // Write name size. 1808480093f4SDimitry Andric if (NE.Name.empty()) 1809*0fca6ea1SDimitry Andric CBA.write<uint32_t>(0, ELFT::Endianness); 1810480093f4SDimitry Andric else 1811*0fca6ea1SDimitry Andric CBA.write<uint32_t>(NE.Name.size() + 1, ELFT::Endianness); 1812480093f4SDimitry Andric 1813480093f4SDimitry Andric // Write description size. 1814480093f4SDimitry Andric if (NE.Desc.binary_size() == 0) 1815*0fca6ea1SDimitry Andric CBA.write<uint32_t>(0, ELFT::Endianness); 1816480093f4SDimitry Andric else 1817*0fca6ea1SDimitry Andric CBA.write<uint32_t>(NE.Desc.binary_size(), ELFT::Endianness); 1818480093f4SDimitry Andric 1819480093f4SDimitry Andric // Write type. 1820*0fca6ea1SDimitry Andric CBA.write<uint32_t>(NE.Type, ELFT::Endianness); 1821480093f4SDimitry Andric 1822480093f4SDimitry Andric // Write name, null terminator and padding. 1823480093f4SDimitry Andric if (!NE.Name.empty()) { 18245ffd83dbSDimitry Andric CBA.write(NE.Name.data(), NE.Name.size()); 18255ffd83dbSDimitry Andric CBA.write('\0'); 1826480093f4SDimitry Andric CBA.padToAlignment(4); 1827480093f4SDimitry Andric } 1828480093f4SDimitry Andric 1829480093f4SDimitry Andric // Write description and padding. 1830480093f4SDimitry Andric if (NE.Desc.binary_size() != 0) { 18315ffd83dbSDimitry Andric CBA.writeAsBinary(NE.Desc); 1832480093f4SDimitry Andric CBA.padToAlignment(4); 1833480093f4SDimitry Andric } 1834480093f4SDimitry Andric } 1835480093f4SDimitry Andric 18365ffd83dbSDimitry Andric SHeader.sh_size = CBA.tell() - Offset; 1837480093f4SDimitry Andric } 1838480093f4SDimitry Andric 1839480093f4SDimitry Andric template <class ELFT> 1840480093f4SDimitry Andric void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, 1841480093f4SDimitry Andric const ELFYAML::GnuHashSection &Section, 1842480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1843e8d8bef9SDimitry Andric if (!Section.HashBuckets) 1844480093f4SDimitry Andric return; 1845e8d8bef9SDimitry Andric 1846e8d8bef9SDimitry Andric if (!Section.Header) 1847e8d8bef9SDimitry Andric return; 1848480093f4SDimitry Andric 1849480093f4SDimitry Andric // We write the header first, starting with the hash buckets count. Normally 1850480093f4SDimitry Andric // it is the number of entries in HashBuckets, but the "NBuckets" property can 1851480093f4SDimitry Andric // be used to override this field, which is useful for producing broken 1852480093f4SDimitry Andric // objects. 1853480093f4SDimitry Andric if (Section.Header->NBuckets) 1854*0fca6ea1SDimitry Andric CBA.write<uint32_t>(*Section.Header->NBuckets, ELFT::Endianness); 1855480093f4SDimitry Andric else 1856*0fca6ea1SDimitry Andric CBA.write<uint32_t>(Section.HashBuckets->size(), ELFT::Endianness); 1857480093f4SDimitry Andric 1858480093f4SDimitry Andric // Write the index of the first symbol in the dynamic symbol table accessible 1859480093f4SDimitry Andric // via the hash table. 1860*0fca6ea1SDimitry Andric CBA.write<uint32_t>(Section.Header->SymNdx, ELFT::Endianness); 1861480093f4SDimitry Andric 1862480093f4SDimitry Andric // Write the number of words in the Bloom filter. As above, the "MaskWords" 1863480093f4SDimitry Andric // property can be used to set this field to any value. 1864480093f4SDimitry Andric if (Section.Header->MaskWords) 1865*0fca6ea1SDimitry Andric CBA.write<uint32_t>(*Section.Header->MaskWords, ELFT::Endianness); 1866480093f4SDimitry Andric else 1867*0fca6ea1SDimitry Andric CBA.write<uint32_t>(Section.BloomFilter->size(), ELFT::Endianness); 1868480093f4SDimitry Andric 1869480093f4SDimitry Andric // Write the shift constant used by the Bloom filter. 1870*0fca6ea1SDimitry Andric CBA.write<uint32_t>(Section.Header->Shift2, ELFT::Endianness); 1871480093f4SDimitry Andric 1872480093f4SDimitry Andric // We've finished writing the header. Now write the Bloom filter. 1873480093f4SDimitry Andric for (llvm::yaml::Hex64 Val : *Section.BloomFilter) 1874*0fca6ea1SDimitry Andric CBA.write<uintX_t>(Val, ELFT::Endianness); 1875480093f4SDimitry Andric 1876480093f4SDimitry Andric // Write an array of hash buckets. 1877480093f4SDimitry Andric for (llvm::yaml::Hex32 Val : *Section.HashBuckets) 1878*0fca6ea1SDimitry Andric CBA.write<uint32_t>(Val, ELFT::Endianness); 1879480093f4SDimitry Andric 1880480093f4SDimitry Andric // Write an array of hash values. 1881480093f4SDimitry Andric for (llvm::yaml::Hex32 Val : *Section.HashValues) 1882*0fca6ea1SDimitry Andric CBA.write<uint32_t>(Val, ELFT::Endianness); 1883480093f4SDimitry Andric 1884480093f4SDimitry Andric SHeader.sh_size = 16 /*Header size*/ + 1885480093f4SDimitry Andric Section.BloomFilter->size() * sizeof(typename ELFT::uint) + 1886480093f4SDimitry Andric Section.HashBuckets->size() * 4 + 1887480093f4SDimitry Andric Section.HashValues->size() * 4; 1888480093f4SDimitry Andric } 1889480093f4SDimitry Andric 1890480093f4SDimitry Andric template <class ELFT> 1891480093f4SDimitry Andric void ELFState<ELFT>::writeFill(ELFYAML::Fill &Fill, 1892480093f4SDimitry Andric ContiguousBlobAccumulator &CBA) { 1893480093f4SDimitry Andric size_t PatternSize = Fill.Pattern ? Fill.Pattern->binary_size() : 0; 1894480093f4SDimitry Andric if (!PatternSize) { 18955ffd83dbSDimitry Andric CBA.writeZeros(Fill.Size); 1896480093f4SDimitry Andric return; 1897480093f4SDimitry Andric } 1898480093f4SDimitry Andric 1899480093f4SDimitry Andric // Fill the content with the specified pattern. 1900480093f4SDimitry Andric uint64_t Written = 0; 1901480093f4SDimitry Andric for (; Written + PatternSize <= Fill.Size; Written += PatternSize) 19025ffd83dbSDimitry Andric CBA.writeAsBinary(*Fill.Pattern); 19035ffd83dbSDimitry Andric CBA.writeAsBinary(*Fill.Pattern, Fill.Size - Written); 19045ffd83dbSDimitry Andric } 19055ffd83dbSDimitry Andric 19065ffd83dbSDimitry Andric template <class ELFT> 19075ffd83dbSDimitry Andric DenseMap<StringRef, size_t> ELFState<ELFT>::buildSectionHeaderReorderMap() { 1908e8d8bef9SDimitry Andric const ELFYAML::SectionHeaderTable &SectionHeaders = 1909e8d8bef9SDimitry Andric Doc.getSectionHeaderTable(); 1910fe6060f1SDimitry Andric if (SectionHeaders.IsImplicit || SectionHeaders.NoHeaders || 1911fe6060f1SDimitry Andric SectionHeaders.isDefault()) 19125ffd83dbSDimitry Andric return DenseMap<StringRef, size_t>(); 19135ffd83dbSDimitry Andric 19145ffd83dbSDimitry Andric DenseMap<StringRef, size_t> Ret; 19155ffd83dbSDimitry Andric size_t SecNdx = 0; 19165ffd83dbSDimitry Andric StringSet<> Seen; 19175ffd83dbSDimitry Andric 19185ffd83dbSDimitry Andric auto AddSection = [&](const ELFYAML::SectionHeader &Hdr) { 19195ffd83dbSDimitry Andric if (!Ret.try_emplace(Hdr.Name, ++SecNdx).second) 19205ffd83dbSDimitry Andric reportError("repeated section name: '" + Hdr.Name + 19215ffd83dbSDimitry Andric "' in the section header description"); 19225ffd83dbSDimitry Andric Seen.insert(Hdr.Name); 19235ffd83dbSDimitry Andric }; 19245ffd83dbSDimitry Andric 1925e8d8bef9SDimitry Andric if (SectionHeaders.Sections) 1926e8d8bef9SDimitry Andric for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Sections) 19275ffd83dbSDimitry Andric AddSection(Hdr); 19285ffd83dbSDimitry Andric 1929e8d8bef9SDimitry Andric if (SectionHeaders.Excluded) 1930e8d8bef9SDimitry Andric for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Excluded) 19315ffd83dbSDimitry Andric AddSection(Hdr); 19325ffd83dbSDimitry Andric 19335ffd83dbSDimitry Andric for (const ELFYAML::Section *S : Doc.getSections()) { 19345ffd83dbSDimitry Andric // Ignore special first SHT_NULL section. 19355ffd83dbSDimitry Andric if (S == Doc.getSections().front()) 19365ffd83dbSDimitry Andric continue; 19375ffd83dbSDimitry Andric if (!Seen.count(S->Name)) 19385ffd83dbSDimitry Andric reportError("section '" + S->Name + 19395ffd83dbSDimitry Andric "' should be present in the 'Sections' or 'Excluded' lists"); 19405ffd83dbSDimitry Andric Seen.erase(S->Name); 19415ffd83dbSDimitry Andric } 19425ffd83dbSDimitry Andric 19435ffd83dbSDimitry Andric for (const auto &It : Seen) 19445ffd83dbSDimitry Andric reportError("section header contains undefined section '" + It.getKey() + 19455ffd83dbSDimitry Andric "'"); 19465ffd83dbSDimitry Andric return Ret; 1947480093f4SDimitry Andric } 1948480093f4SDimitry Andric 19498bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::buildSectionIndex() { 19505ffd83dbSDimitry Andric // A YAML description can have an explicit section header declaration that 19515ffd83dbSDimitry Andric // allows to change the order of section headers. 19525ffd83dbSDimitry Andric DenseMap<StringRef, size_t> ReorderMap = buildSectionHeaderReorderMap(); 19535ffd83dbSDimitry Andric 19545ffd83dbSDimitry Andric if (HasError) 19555ffd83dbSDimitry Andric return; 19565ffd83dbSDimitry Andric 19575ffd83dbSDimitry Andric // Build excluded section headers map. 19585ffd83dbSDimitry Andric std::vector<ELFYAML::Section *> Sections = Doc.getSections(); 1959e8d8bef9SDimitry Andric const ELFYAML::SectionHeaderTable &SectionHeaders = 1960e8d8bef9SDimitry Andric Doc.getSectionHeaderTable(); 1961e8d8bef9SDimitry Andric if (SectionHeaders.Excluded) 1962e8d8bef9SDimitry Andric for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Excluded) 19635ffd83dbSDimitry Andric if (!ExcludedSectionHeaders.insert(Hdr.Name).second) 19645ffd83dbSDimitry Andric llvm_unreachable("buildSectionIndex() failed"); 19655ffd83dbSDimitry Andric 196681ad6265SDimitry Andric if (SectionHeaders.NoHeaders.value_or(false)) 19675ffd83dbSDimitry Andric for (const ELFYAML::Section *S : Sections) 19685ffd83dbSDimitry Andric if (!ExcludedSectionHeaders.insert(S->Name).second) 19695ffd83dbSDimitry Andric llvm_unreachable("buildSectionIndex() failed"); 19705ffd83dbSDimitry Andric 1971480093f4SDimitry Andric size_t SecNdx = -1; 19725ffd83dbSDimitry Andric for (const ELFYAML::Section *S : Sections) { 1973480093f4SDimitry Andric ++SecNdx; 1974480093f4SDimitry Andric 19755ffd83dbSDimitry Andric size_t Index = ReorderMap.empty() ? SecNdx : ReorderMap.lookup(S->Name); 19765ffd83dbSDimitry Andric if (!SN2I.addName(S->Name, Index)) 1977480093f4SDimitry Andric llvm_unreachable("buildSectionIndex() failed"); 19785ffd83dbSDimitry Andric 19795ffd83dbSDimitry Andric if (!ExcludedSectionHeaders.count(S->Name)) 1980fe6060f1SDimitry Andric ShStrtabStrings->add(ELFYAML::dropUniqueSuffix(S->Name)); 19818bcb0991SDimitry Andric } 19828bcb0991SDimitry Andric } 19838bcb0991SDimitry Andric 19848bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::buildSymbolIndexes() { 19858bcb0991SDimitry Andric auto Build = [this](ArrayRef<ELFYAML::Symbol> V, NameToIdxMap &Map) { 19868bcb0991SDimitry Andric for (size_t I = 0, S = V.size(); I < S; ++I) { 19878bcb0991SDimitry Andric const ELFYAML::Symbol &Sym = V[I]; 19888bcb0991SDimitry Andric if (!Sym.Name.empty() && !Map.addName(Sym.Name, I + 1)) 19898bcb0991SDimitry Andric reportError("repeated symbol name: '" + Sym.Name + "'"); 19908bcb0991SDimitry Andric } 19918bcb0991SDimitry Andric }; 19928bcb0991SDimitry Andric 19938bcb0991SDimitry Andric if (Doc.Symbols) 19948bcb0991SDimitry Andric Build(*Doc.Symbols, SymN2I); 1995480093f4SDimitry Andric if (Doc.DynamicSymbols) 1996480093f4SDimitry Andric Build(*Doc.DynamicSymbols, DynSymN2I); 19978bcb0991SDimitry Andric } 19988bcb0991SDimitry Andric 19998bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::finalizeStrings() { 20008bcb0991SDimitry Andric // Add the regular symbol names to .strtab section. 20018bcb0991SDimitry Andric if (Doc.Symbols) 20028bcb0991SDimitry Andric for (const ELFYAML::Symbol &Sym : *Doc.Symbols) 20038bcb0991SDimitry Andric DotStrtab.add(ELFYAML::dropUniqueSuffix(Sym.Name)); 20048bcb0991SDimitry Andric DotStrtab.finalize(); 20058bcb0991SDimitry Andric 20068bcb0991SDimitry Andric // Add the dynamic symbol names to .dynstr section. 2007480093f4SDimitry Andric if (Doc.DynamicSymbols) 2008480093f4SDimitry Andric for (const ELFYAML::Symbol &Sym : *Doc.DynamicSymbols) 20098bcb0991SDimitry Andric DotDynstr.add(ELFYAML::dropUniqueSuffix(Sym.Name)); 20108bcb0991SDimitry Andric 20118bcb0991SDimitry Andric // SHT_GNU_verdef and SHT_GNU_verneed sections might also 20128bcb0991SDimitry Andric // add strings to .dynstr section. 2013480093f4SDimitry Andric for (const ELFYAML::Chunk *Sec : Doc.getSections()) { 2014480093f4SDimitry Andric if (auto VerNeed = dyn_cast<ELFYAML::VerneedSection>(Sec)) { 2015480093f4SDimitry Andric if (VerNeed->VerneedV) { 2016480093f4SDimitry Andric for (const ELFYAML::VerneedEntry &VE : *VerNeed->VerneedV) { 20178bcb0991SDimitry Andric DotDynstr.add(VE.File); 20188bcb0991SDimitry Andric for (const ELFYAML::VernauxEntry &Aux : VE.AuxV) 20198bcb0991SDimitry Andric DotDynstr.add(Aux.Name); 20208bcb0991SDimitry Andric } 2021480093f4SDimitry Andric } 2022480093f4SDimitry Andric } else if (auto VerDef = dyn_cast<ELFYAML::VerdefSection>(Sec)) { 2023480093f4SDimitry Andric if (VerDef->Entries) 2024480093f4SDimitry Andric for (const ELFYAML::VerdefEntry &E : *VerDef->Entries) 20258bcb0991SDimitry Andric for (StringRef Name : E.VerNames) 20268bcb0991SDimitry Andric DotDynstr.add(Name); 20278bcb0991SDimitry Andric } 20288bcb0991SDimitry Andric } 20298bcb0991SDimitry Andric 20308bcb0991SDimitry Andric DotDynstr.finalize(); 2031fe6060f1SDimitry Andric 2032fe6060f1SDimitry Andric // Don't finalize the section header string table a second time if it has 2033fe6060f1SDimitry Andric // already been finalized due to being one of the symbol string tables. 2034fe6060f1SDimitry Andric if (ShStrtabStrings != &DotStrtab && ShStrtabStrings != &DotDynstr) 2035fe6060f1SDimitry Andric ShStrtabStrings->finalize(); 20368bcb0991SDimitry Andric } 20378bcb0991SDimitry Andric 20388bcb0991SDimitry Andric template <class ELFT> 20398bcb0991SDimitry Andric bool ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc, 20405ffd83dbSDimitry Andric yaml::ErrorHandler EH, uint64_t MaxSize) { 20418bcb0991SDimitry Andric ELFState<ELFT> State(Doc, EH); 20425ffd83dbSDimitry Andric if (State.HasError) 20435ffd83dbSDimitry Andric return false; 20448bcb0991SDimitry Andric 2045fe6060f1SDimitry Andric // Build the section index, which adds sections to the section header string 2046fe6060f1SDimitry Andric // table first, so that we can finalize the section header string table. 20478bcb0991SDimitry Andric State.buildSectionIndex(); 20485ffd83dbSDimitry Andric State.buildSymbolIndexes(); 20495ffd83dbSDimitry Andric 2050fe6060f1SDimitry Andric // Finalize section header string table and the .strtab and .dynstr sections. 2051fe6060f1SDimitry Andric // We do this early because we want to finalize the string table builders 2052fe6060f1SDimitry Andric // before writing the content of the sections that might want to use them. 2053fe6060f1SDimitry Andric State.finalizeStrings(); 2054fe6060f1SDimitry Andric 2055480093f4SDimitry Andric if (State.HasError) 2056480093f4SDimitry Andric return false; 2057480093f4SDimitry Andric 20588bcb0991SDimitry Andric std::vector<Elf_Phdr> PHeaders; 20598bcb0991SDimitry Andric State.initProgramHeaders(PHeaders); 20608bcb0991SDimitry Andric 20618bcb0991SDimitry Andric // XXX: This offset is tightly coupled with the order that we write 20628bcb0991SDimitry Andric // things to `OS`. 20638bcb0991SDimitry Andric const size_t SectionContentBeginOffset = 20648bcb0991SDimitry Andric sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * Doc.ProgramHeaders.size(); 20655ffd83dbSDimitry Andric // It is quite easy to accidentally create output with yaml2obj that is larger 20665ffd83dbSDimitry Andric // than intended, for example, due to an issue in the YAML description. 20675ffd83dbSDimitry Andric // We limit the maximum allowed output size, but also provide a command line 20685ffd83dbSDimitry Andric // option to change this limitation. 20695ffd83dbSDimitry Andric ContiguousBlobAccumulator CBA(SectionContentBeginOffset, MaxSize); 20708bcb0991SDimitry Andric 20718bcb0991SDimitry Andric std::vector<Elf_Shdr> SHeaders; 20728bcb0991SDimitry Andric State.initSectionHeaders(SHeaders, CBA); 20738bcb0991SDimitry Andric 2074480093f4SDimitry Andric // Now we can decide segment offsets. 20758bcb0991SDimitry Andric State.setProgramHeaderLayout(PHeaders, SHeaders); 20768bcb0991SDimitry Andric 2077e8d8bef9SDimitry Andric bool ReachedLimit = CBA.getOffset() > MaxSize; 20785ffd83dbSDimitry Andric if (Error E = CBA.takeLimitError()) { 20795ffd83dbSDimitry Andric // We report a custom error message instead below. 20805ffd83dbSDimitry Andric consumeError(std::move(E)); 20815ffd83dbSDimitry Andric ReachedLimit = true; 20825ffd83dbSDimitry Andric } 20835ffd83dbSDimitry Andric 20845ffd83dbSDimitry Andric if (ReachedLimit) 20855ffd83dbSDimitry Andric State.reportError( 20865ffd83dbSDimitry Andric "the desired output size is greater than permitted. Use the " 20875ffd83dbSDimitry Andric "--max-size option to change the limit"); 20885ffd83dbSDimitry Andric 20898bcb0991SDimitry Andric if (State.HasError) 20908bcb0991SDimitry Andric return false; 20918bcb0991SDimitry Andric 2092e8d8bef9SDimitry Andric State.writeELFHeader(OS); 2093bdd1243dSDimitry Andric writeArrayData(OS, ArrayRef(PHeaders)); 2094e8d8bef9SDimitry Andric 2095e8d8bef9SDimitry Andric const ELFYAML::SectionHeaderTable &SHT = Doc.getSectionHeaderTable(); 209681ad6265SDimitry Andric if (!SHT.NoHeaders.value_or(false)) 2097e8d8bef9SDimitry Andric CBA.updateDataAt(*SHT.Offset, SHeaders.data(), 2098e8d8bef9SDimitry Andric SHT.getNumHeaders(SHeaders.size()) * sizeof(Elf_Shdr)); 2099e8d8bef9SDimitry Andric 21008bcb0991SDimitry Andric CBA.writeBlobToStream(OS); 21018bcb0991SDimitry Andric return true; 21028bcb0991SDimitry Andric } 21038bcb0991SDimitry Andric 21048bcb0991SDimitry Andric namespace llvm { 21058bcb0991SDimitry Andric namespace yaml { 21068bcb0991SDimitry Andric 21075ffd83dbSDimitry Andric bool yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH, 21085ffd83dbSDimitry Andric uint64_t MaxSize) { 21098bcb0991SDimitry Andric bool IsLE = Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB); 21108bcb0991SDimitry Andric bool Is64Bit = Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64); 21118bcb0991SDimitry Andric if (Is64Bit) { 21128bcb0991SDimitry Andric if (IsLE) 21135ffd83dbSDimitry Andric return ELFState<object::ELF64LE>::writeELF(Out, Doc, EH, MaxSize); 21145ffd83dbSDimitry Andric return ELFState<object::ELF64BE>::writeELF(Out, Doc, EH, MaxSize); 21158bcb0991SDimitry Andric } 21168bcb0991SDimitry Andric if (IsLE) 21175ffd83dbSDimitry Andric return ELFState<object::ELF32LE>::writeELF(Out, Doc, EH, MaxSize); 21185ffd83dbSDimitry Andric return ELFState<object::ELF32BE>::writeELF(Out, Doc, EH, MaxSize); 21198bcb0991SDimitry Andric } 21208bcb0991SDimitry Andric 21218bcb0991SDimitry Andric } // namespace yaml 21228bcb0991SDimitry Andric } // namespace llvm 2123