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