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