xref: /freebsd/contrib/llvm-project/llvm/lib/ObjectYAML/ELFEmitter.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
checkLimit(uint64_t Size)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:
ContiguousBlobAccumulator(uint64_t BaseOffset,uint64_t SizeLimit)655ffd83dbSDimitry Andric   ContiguousBlobAccumulator(uint64_t BaseOffset, uint64_t SizeLimit)
665ffd83dbSDimitry Andric       : InitialOffset(BaseOffset), MaxSize(SizeLimit), OS(Buf) {}
67480093f4SDimitry Andric 
tell() const685ffd83dbSDimitry Andric   uint64_t tell() const { return OS.tell(); }
getOffset() const695ffd83dbSDimitry Andric   uint64_t getOffset() const { return InitialOffset + OS.tell(); }
writeBlobToStream(raw_ostream & Out) const705ffd83dbSDimitry Andric   void writeBlobToStream(raw_ostream &Out) const { Out << OS.str(); }
715ffd83dbSDimitry Andric 
takeLimitError()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.
padToAlignment(unsigned Align)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 
getRawOS(uint64_t Size)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 
writeAsBinary(const yaml::BinaryRef & Bin,uint64_t N=UINT64_MAX)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 
writeZeros(uint64_t Num)1055ffd83dbSDimitry Andric   void writeZeros(uint64_t Num) {
1065ffd83dbSDimitry Andric     if (checkLimit(Num))
1075ffd83dbSDimitry Andric       OS.write_zeros(Num);
1085ffd83dbSDimitry Andric   }
1095ffd83dbSDimitry Andric 
write(const char * Ptr,size_t Size)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 
write(unsigned char C)1155ffd83dbSDimitry Andric   void write(unsigned char C) {
1165ffd83dbSDimitry Andric     if (checkLimit(1))
1175ffd83dbSDimitry Andric       OS.write(C);
1185ffd83dbSDimitry Andric   }
1195ffd83dbSDimitry Andric 
writeULEB128(uint64_t Val)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 
writeSLEB128(int64_t Val)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 
write(T Val,llvm::endianness E)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 
updateDataAt(uint64_t Pos,void * Data,size_t Size)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.
addName(StringRef Name,unsigned Ndx)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.
lookup(StringRef Name,unsigned & Idx) const1548bcb0991SDimitry 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.
get(StringRef Name) const1628bcb0991SDimitry 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   }
size() const1698bcb0991SDimitry 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 
arrayDataSize(ArrayRef<T> A)3358bcb0991SDimitry Andric template <class T> static size_t arrayDataSize(ArrayRef<T> A) {
3368bcb0991SDimitry Andric   return A.size() * sizeof(T);
3378bcb0991SDimitry Andric }
3388bcb0991SDimitry Andric 
writeArrayData(raw_ostream & OS,ArrayRef<T> A)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 
zero(T & Obj)3438bcb0991SDimitry Andric template <class T> static void zero(T &Obj) { memset(&Obj, 0, sizeof(Obj)); }
3448bcb0991SDimitry Andric 
3458bcb0991SDimitry Andric template <class ELFT>
ELFState(ELFYAML::Object & D,yaml::ErrorHandler EH)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>
writeELFHeader(raw_ostream & OS)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>
initProgramHeaders(std::vector<Elf_Phdr> & PHeaders)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>
toSectionIndex(StringRef S,StringRef LocSec,StringRef LocSym)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>
toSymbolIndex(StringRef S,StringRef LocSec,bool IsDynamic)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>
overrideFields(ELFYAML::Section * From,typename ELFT::Shdr & To)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>
initImplicitHeader(ContiguousBlobAccumulator & CBA,Elf_Shdr & Header,StringRef SecName,ELFYAML::Section * YAMLSec)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 
appendUniqueSuffix(StringRef Name,const Twine & Msg)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 
dropUniqueSuffix(StringRef S)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>
getSectionNameOffset(StringRef Name)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 
writeContent(ContiguousBlobAccumulator & CBA,const std::optional<yaml::BinaryRef> & Content,const std::optional<llvm::yaml::Hex64> & Size)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 
getDefaultLinkSec(unsigned SecType)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>
initSectionHeaders(std::vector<Elf_Shdr> & SHeaders,ContiguousBlobAccumulator & CBA)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>
assignSectionAddress(Elf_Shdr & SHeader,ELFYAML::Section * YAMLSec)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 
findFirstNonGlobal(ArrayRef<ELFYAML::Symbol> Symbols)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>
toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols,const StringTableBuilder & Strtab)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>
initSymtabSectionHeader(Elf_Shdr & SHeader,SymtabType STType,ContiguousBlobAccumulator & CBA,ELFYAML::Section * YAMLSec)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>
initStrtabSectionHeader(Elf_Shdr & SHeader,StringRef Name,StringTableBuilder & STB,ContiguousBlobAccumulator & CBA,ELFYAML::Section * YAMLSec)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 
shouldEmitDWARF(DWARFYAML::Data & DWARF,StringRef Name)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>
emitDWARF(typename ELFT::Shdr & SHeader,StringRef Name,const DWARFYAML::Data & DWARF,ContiguousBlobAccumulator & CBA)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>
initDWARFSectionHeader(Elf_Shdr & SHeader,StringRef Name,ContiguousBlobAccumulator & CBA,ELFYAML::Section * YAMLSec)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 
reportError(const Twine & Msg)11418bcb0991SDimitry Andric template <class ELFT> void ELFState<ELFT>::reportError(const Twine &Msg) {
11428bcb0991SDimitry Andric   ErrHandler(Msg);
11438bcb0991SDimitry Andric   HasError = true;
11448bcb0991SDimitry Andric }
11458bcb0991SDimitry Andric 
reportError(Error Err)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>
getPhdrFragments(const ELFYAML::ProgramHeader & Phdr,ArrayRef<Elf_Shdr> SHeaders)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>
setProgramHeaderLayout(std::vector<Elf_Phdr> & PHeaders,std::vector<Elf_Shdr> & SHeaders)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 
shouldAllocateFileSpace(ArrayRef<ELFYAML::ProgramHeader> Phdrs,const ELFYAML::NoBitsSection & S)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::NoBitsSection & S,ContiguousBlobAccumulator & CBA)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::RawContentSection & Section,ContiguousBlobAccumulator & CBA)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 
isMips64EL(const ELFYAML::Object & Obj)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::RelocationSection & Section,ContiguousBlobAccumulator & CBA)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::RelrSection & Section,ContiguousBlobAccumulator & CBA)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::SymtabShndxSection & Shndx,ContiguousBlobAccumulator & CBA)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::GroupSection & Section,ContiguousBlobAccumulator & CBA)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::SymverSection & Section,ContiguousBlobAccumulator & CBA)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::StackSizesSection & Section,ContiguousBlobAccumulator & CBA)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::BBAddrMapSection & Section,ContiguousBlobAccumulator & CBA)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::LinkerOptionsSection & Section,ContiguousBlobAccumulator & CBA)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::DependentLibrariesSection & Section,ContiguousBlobAccumulator & CBA)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
alignToOffset(ContiguousBlobAccumulator & CBA,uint64_t Align,std::optional<llvm::yaml::Hex64> Offset)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::CallGraphProfileSection & Section,ContiguousBlobAccumulator & CBA)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::HashSection & Section,ContiguousBlobAccumulator & CBA)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::VerdefSection & Section,ContiguousBlobAccumulator & CBA)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::VerneedSection & Section,ContiguousBlobAccumulator & CBA)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::ARMIndexTableSection & Section,ContiguousBlobAccumulator & CBA)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::MipsABIFlags & Section,ContiguousBlobAccumulator & CBA)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::DynamicSection & Section,ContiguousBlobAccumulator & CBA)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::AddrsigSection & Section,ContiguousBlobAccumulator & CBA)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::NoteSection & Section,ContiguousBlobAccumulator & CBA)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>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::GnuHashSection & Section,ContiguousBlobAccumulator & CBA)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>
writeFill(ELFYAML::Fill & Fill,ContiguousBlobAccumulator & CBA)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>
buildSectionHeaderReorderMap()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 
buildSectionIndex()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 
buildSymbolIndexes()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 
finalizeStrings()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>
writeELF(raw_ostream & OS,ELFYAML::Object & Doc,yaml::ErrorHandler EH,uint64_t MaxSize)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 
yaml2elf(llvm::ELFYAML::Object & Doc,raw_ostream & Out,ErrorHandler EH,uint64_t MaxSize)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