1c22d9666SAlex Brachet //===- yaml2elf - Convert YAML to a ELF object file -----------------------===//
2c22d9666SAlex Brachet //
3c22d9666SAlex Brachet // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c22d9666SAlex Brachet // See https://llvm.org/LICENSE.txt for license information.
5c22d9666SAlex Brachet // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c22d9666SAlex Brachet //
7c22d9666SAlex Brachet //===----------------------------------------------------------------------===//
8c22d9666SAlex Brachet ///
9c22d9666SAlex Brachet /// \file
10c22d9666SAlex Brachet /// The ELF component of yaml2obj.
11c22d9666SAlex Brachet ///
12c22d9666SAlex Brachet //===----------------------------------------------------------------------===//
13c22d9666SAlex Brachet
14c22d9666SAlex Brachet #include "llvm/ADT/ArrayRef.h"
1506456daaSGeorgii Rymar #include "llvm/ADT/DenseMap.h"
16373e98a3SXing GUO #include "llvm/ADT/SetVector.h"
17c22d9666SAlex Brachet #include "llvm/ADT/StringSet.h"
18c22d9666SAlex Brachet #include "llvm/BinaryFormat/ELF.h"
19c22d9666SAlex Brachet #include "llvm/MC/StringTableBuilder.h"
20c22d9666SAlex Brachet #include "llvm/Object/ELFObjectFile.h"
21a224c519SAlexander Yermolovich #include "llvm/Object/ELFTypes.h"
22373e98a3SXing GUO #include "llvm/ObjectYAML/DWARFEmitter.h"
23373e98a3SXing GUO #include "llvm/ObjectYAML/DWARFYAML.h"
24c22d9666SAlex Brachet #include "llvm/ObjectYAML/ELFYAML.h"
25c22d9666SAlex Brachet #include "llvm/ObjectYAML/yaml2obj.h"
26c22d9666SAlex Brachet #include "llvm/Support/EndianStream.h"
273c123acfSGeorgii Rymar #include "llvm/Support/Errc.h"
289939f231SXing GUO #include "llvm/Support/Error.h"
291a219aa8SGeorge Rimar #include "llvm/Support/LEB128.h"
30c22d9666SAlex Brachet #include "llvm/Support/MemoryBuffer.h"
31c22d9666SAlex Brachet #include "llvm/Support/WithColor.h"
32c22d9666SAlex Brachet #include "llvm/Support/YAMLTraits.h"
33c22d9666SAlex Brachet #include "llvm/Support/raw_ostream.h"
34c22d9666SAlex Brachet
35c22d9666SAlex Brachet using namespace llvm;
36c22d9666SAlex Brachet
37c22d9666SAlex Brachet // This class is used to build up a contiguous binary blob while keeping
38c22d9666SAlex Brachet // track of an offset in the output (which notionally begins at
39c22d9666SAlex Brachet // `InitialOffset`).
403c123acfSGeorgii Rymar // The blob might be limited to an arbitrary size. All attempts to write data
413c123acfSGeorgii Rymar // are ignored and the error condition is remembered once the limit is reached.
423c123acfSGeorgii Rymar // Such an approach allows us to simplify the code by delaying error reporting
433c123acfSGeorgii Rymar // and doing it at a convenient time.
44c22d9666SAlex Brachet namespace {
45c22d9666SAlex Brachet class ContiguousBlobAccumulator {
46c22d9666SAlex Brachet const uint64_t InitialOffset;
473c123acfSGeorgii Rymar const uint64_t MaxSize;
483c123acfSGeorgii Rymar
49c22d9666SAlex Brachet SmallVector<char, 128> Buf;
50c22d9666SAlex Brachet raw_svector_ostream OS;
513c123acfSGeorgii Rymar Error ReachedLimitErr = Error::success();
523c123acfSGeorgii Rymar
checkLimit(uint64_t Size)533c123acfSGeorgii Rymar bool checkLimit(uint64_t Size) {
543c123acfSGeorgii Rymar if (!ReachedLimitErr && getOffset() + Size <= MaxSize)
553c123acfSGeorgii Rymar return true;
563c123acfSGeorgii Rymar if (!ReachedLimitErr)
573c123acfSGeorgii Rymar ReachedLimitErr = createStringError(errc::invalid_argument,
583c123acfSGeorgii Rymar "reached the output size limit");
593c123acfSGeorgii Rymar return false;
603c123acfSGeorgii Rymar }
61c22d9666SAlex Brachet
62de3cef1dSgeorgerim public:
ContiguousBlobAccumulator(uint64_t BaseOffset,uint64_t SizeLimit)633c123acfSGeorgii Rymar ContiguousBlobAccumulator(uint64_t BaseOffset, uint64_t SizeLimit)
643c123acfSGeorgii Rymar : InitialOffset(BaseOffset), MaxSize(SizeLimit), OS(Buf) {}
65de3cef1dSgeorgerim
tell() const663c123acfSGeorgii Rymar uint64_t tell() const { return OS.tell(); }
getOffset() const677ccae2ceSGeorgii Rymar uint64_t getOffset() const { return InitialOffset + OS.tell(); }
writeBlobToStream(raw_ostream & Out) const683c123acfSGeorgii Rymar void writeBlobToStream(raw_ostream &Out) const { Out << OS.str(); }
693c123acfSGeorgii Rymar
takeLimitError()703c123acfSGeorgii Rymar Error takeLimitError() {
713c123acfSGeorgii Rymar // Request to write 0 bytes to check we did not reach the limit.
723c123acfSGeorgii Rymar checkLimit(0);
733c123acfSGeorgii Rymar return std::move(ReachedLimitErr);
743c123acfSGeorgii Rymar }
75de3cef1dSgeorgerim
76c22d9666SAlex Brachet /// \returns The new offset.
padToAlignment(unsigned Align)77c22d9666SAlex Brachet uint64_t padToAlignment(unsigned Align) {
787ccae2ceSGeorgii Rymar uint64_t CurrentOffset = getOffset();
793c123acfSGeorgii Rymar if (ReachedLimitErr)
803c123acfSGeorgii Rymar return CurrentOffset;
813c123acfSGeorgii Rymar
823c123acfSGeorgii Rymar uint64_t AlignedOffset = alignTo(CurrentOffset, Align == 0 ? 1 : Align);
833c123acfSGeorgii Rymar uint64_t PaddingSize = AlignedOffset - CurrentOffset;
843c123acfSGeorgii Rymar if (!checkLimit(PaddingSize))
853c123acfSGeorgii Rymar return CurrentOffset;
863c123acfSGeorgii Rymar
873c123acfSGeorgii Rymar writeZeros(PaddingSize);
883c123acfSGeorgii Rymar return AlignedOffset;
89c22d9666SAlex Brachet }
90c22d9666SAlex Brachet
getRawOS(uint64_t Size)913c123acfSGeorgii Rymar raw_ostream *getRawOS(uint64_t Size) {
923c123acfSGeorgii Rymar if (checkLimit(Size))
933c123acfSGeorgii Rymar return &OS;
943c123acfSGeorgii Rymar return nullptr;
953c123acfSGeorgii Rymar }
963c123acfSGeorgii Rymar
writeAsBinary(const yaml::BinaryRef & Bin,uint64_t N=UINT64_MAX)973c123acfSGeorgii Rymar void writeAsBinary(const yaml::BinaryRef &Bin, uint64_t N = UINT64_MAX) {
983c123acfSGeorgii Rymar if (!checkLimit(Bin.binary_size()))
993c123acfSGeorgii Rymar return;
1003c123acfSGeorgii Rymar Bin.writeAsBinary(OS, N);
1013c123acfSGeorgii Rymar }
1023c123acfSGeorgii Rymar
writeZeros(uint64_t Num)1033c123acfSGeorgii Rymar void writeZeros(uint64_t Num) {
1043c123acfSGeorgii Rymar if (checkLimit(Num))
1053c123acfSGeorgii Rymar OS.write_zeros(Num);
1063c123acfSGeorgii Rymar }
1073c123acfSGeorgii Rymar
write(const char * Ptr,size_t Size)1083c123acfSGeorgii Rymar void write(const char *Ptr, size_t Size) {
1093c123acfSGeorgii Rymar if (checkLimit(Size))
1103c123acfSGeorgii Rymar OS.write(Ptr, Size);
1113c123acfSGeorgii Rymar }
1123c123acfSGeorgii Rymar
write(unsigned char C)1133c123acfSGeorgii Rymar void write(unsigned char C) {
1143c123acfSGeorgii Rymar if (checkLimit(1))
1153c123acfSGeorgii Rymar OS.write(C);
1163c123acfSGeorgii Rymar }
1173c123acfSGeorgii Rymar
writeULEB128(uint64_t Val)1183c123acfSGeorgii Rymar unsigned writeULEB128(uint64_t Val) {
1193c123acfSGeorgii Rymar if (!checkLimit(sizeof(uint64_t)))
1203c123acfSGeorgii Rymar return 0;
1213c123acfSGeorgii Rymar return encodeULEB128(Val, OS);
1223c123acfSGeorgii Rymar }
1233c123acfSGeorgii Rymar
write(T Val,support::endianness E)1243c123acfSGeorgii Rymar template <typename T> void write(T Val, support::endianness E) {
1253c123acfSGeorgii Rymar if (checkLimit(sizeof(T)))
1263c123acfSGeorgii Rymar support::endian::write<T>(OS, Val, E);
1273c123acfSGeorgii Rymar }
1289c89dcf8SGeorgii Rymar
updateDataAt(uint64_t Pos,void * Data,size_t Size)1299c89dcf8SGeorgii Rymar void updateDataAt(uint64_t Pos, void *Data, size_t Size) {
1309c89dcf8SGeorgii Rymar assert(Pos >= InitialOffset && Pos + Size <= getOffset());
1319c89dcf8SGeorgii Rymar memcpy(&Buf[Pos - InitialOffset], Data, Size);
1329c89dcf8SGeorgii Rymar }
133c22d9666SAlex Brachet };
134c22d9666SAlex Brachet
135c22d9666SAlex Brachet // Used to keep track of section and symbol names, so that in the YAML file
136c22d9666SAlex Brachet // sections and symbols can be referenced by name instead of by index.
137c22d9666SAlex Brachet class NameToIdxMap {
138c22d9666SAlex Brachet StringMap<unsigned> Map;
139c22d9666SAlex Brachet
140c22d9666SAlex Brachet public:
141c22d9666SAlex Brachet /// \Returns false if name is already present in the map.
addName(StringRef Name,unsigned Ndx)142c22d9666SAlex Brachet bool addName(StringRef Name, unsigned Ndx) {
143c22d9666SAlex Brachet return Map.insert({Name, Ndx}).second;
144c22d9666SAlex Brachet }
145c22d9666SAlex Brachet /// \Returns false if name is not present in the map.
lookup(StringRef Name,unsigned & Idx) const146c22d9666SAlex Brachet bool lookup(StringRef Name, unsigned &Idx) const {
147c22d9666SAlex Brachet auto I = Map.find(Name);
148c22d9666SAlex Brachet if (I == Map.end())
149c22d9666SAlex Brachet return false;
150c22d9666SAlex Brachet Idx = I->getValue();
151c22d9666SAlex Brachet return true;
152c22d9666SAlex Brachet }
153c22d9666SAlex Brachet /// Asserts if name is not present in the map.
get(StringRef Name) const154c22d9666SAlex Brachet unsigned get(StringRef Name) const {
155c22d9666SAlex Brachet unsigned Idx;
156c22d9666SAlex Brachet if (lookup(Name, Idx))
157c22d9666SAlex Brachet return Idx;
158c22d9666SAlex Brachet assert(false && "Expected section not found in index");
159c22d9666SAlex Brachet return 0;
160c22d9666SAlex Brachet }
size() const161c22d9666SAlex Brachet unsigned size() const { return Map.size(); }
162c22d9666SAlex Brachet };
163c22d9666SAlex Brachet
16406456daaSGeorgii Rymar namespace {
16506456daaSGeorgii Rymar struct Fragment {
16606456daaSGeorgii Rymar uint64_t Offset;
16706456daaSGeorgii Rymar uint64_t Size;
16806456daaSGeorgii Rymar uint32_t Type;
16906456daaSGeorgii Rymar uint64_t AddrAlign;
17006456daaSGeorgii Rymar };
1718383be0fSSimon Pilgrim } // namespace
17206456daaSGeorgii Rymar
173c22d9666SAlex Brachet /// "Single point of truth" for the ELF file construction.
174c22d9666SAlex Brachet /// TODO: This class still has a ways to go before it is truly a "single
175c22d9666SAlex Brachet /// point of truth".
176c22d9666SAlex Brachet template <class ELFT> class ELFState {
177438bc157SGeorgii Rymar LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
178c22d9666SAlex Brachet
179c22d9666SAlex Brachet enum class SymtabType { Static, Dynamic };
180c22d9666SAlex Brachet
1815c1639feSJames Henderson /// The future symbol table string section.
182c22d9666SAlex Brachet StringTableBuilder DotStrtab{StringTableBuilder::ELF};
183c22d9666SAlex Brachet
1845c1639feSJames Henderson /// The future section header string table section, if a unique string table
1855c1639feSJames Henderson /// is needed. Don't reference this variable direectly: use the
1865c1639feSJames Henderson /// ShStrtabStrings member instead.
187c22d9666SAlex Brachet StringTableBuilder DotShStrtab{StringTableBuilder::ELF};
188c22d9666SAlex Brachet
1895c1639feSJames Henderson /// The future dynamic symbol string section.
190c22d9666SAlex Brachet StringTableBuilder DotDynstr{StringTableBuilder::ELF};
191c22d9666SAlex Brachet
1925c1639feSJames Henderson /// The name of the section header string table section. If it is .strtab or
1935c1639feSJames Henderson /// .dynstr, the section header strings will be written to the same string
1945c1639feSJames Henderson /// table as the static/dynamic symbols respectively. Otherwise a dedicated
1955c1639feSJames Henderson /// section will be created with that name.
1965c1639feSJames Henderson StringRef SectionHeaderStringTableName = ".shstrtab";
1975c1639feSJames Henderson StringTableBuilder *ShStrtabStrings = &DotShStrtab;
1985c1639feSJames Henderson
199c22d9666SAlex Brachet NameToIdxMap SN2I;
200c22d9666SAlex Brachet NameToIdxMap SymN2I;
20191208447SGeorge Rimar NameToIdxMap DynSymN2I;
202c22d9666SAlex Brachet ELFYAML::Object &Doc;
203c22d9666SAlex Brachet
204c781e737SGeorgii Rymar StringSet<> ExcludedSectionHeaders;
205c781e737SGeorgii Rymar
20631f2ad9cSGeorgii Rymar uint64_t LocationCounter = 0;
2073212ecfeSGeorge Rimar bool HasError = false;
20885011027SGeorge Rimar yaml::ErrorHandler ErrHandler;
20985011027SGeorge Rimar void reportError(const Twine &Msg);
2109939f231SXing GUO void reportError(Error Err);
2113212ecfeSGeorge Rimar
2123212ecfeSGeorge Rimar std::vector<Elf_Sym> toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols,
2133212ecfeSGeorge Rimar const StringTableBuilder &Strtab);
2143212ecfeSGeorge Rimar unsigned toSectionIndex(StringRef S, StringRef LocSec, StringRef LocSym = "");
2153212ecfeSGeorge Rimar unsigned toSymbolIndex(StringRef S, StringRef LocSec, bool IsDynamic);
2163212ecfeSGeorge Rimar
2173212ecfeSGeorge Rimar void buildSectionIndex();
2183212ecfeSGeorge Rimar void buildSymbolIndexes();
219c22d9666SAlex Brachet void initProgramHeaders(std::vector<Elf_Phdr> &PHeaders);
22033b1a0ebSGeorge Rimar bool initImplicitHeader(ContiguousBlobAccumulator &CBA, Elf_Shdr &Header,
22133b1a0ebSGeorge Rimar StringRef SecName, ELFYAML::Section *YAMLSec);
2223212ecfeSGeorge Rimar void initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
223c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA);
224c22d9666SAlex Brachet void initSymtabSectionHeader(Elf_Shdr &SHeader, SymtabType STType,
225c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA,
226c22d9666SAlex Brachet ELFYAML::Section *YAMLSec);
227c22d9666SAlex Brachet void initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,
228c22d9666SAlex Brachet StringTableBuilder &STB,
229c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA,
230c22d9666SAlex Brachet ELFYAML::Section *YAMLSec);
231373e98a3SXing GUO void initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name,
232373e98a3SXing GUO ContiguousBlobAccumulator &CBA,
233373e98a3SXing GUO ELFYAML::Section *YAMLSec);
234c22d9666SAlex Brachet void setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders,
235c22d9666SAlex Brachet std::vector<Elf_Shdr> &SHeaders);
23606456daaSGeorgii Rymar
23706456daaSGeorgii Rymar std::vector<Fragment>
23806456daaSGeorgii Rymar getPhdrFragments(const ELFYAML::ProgramHeader &Phdr,
23906456daaSGeorgii Rymar ArrayRef<typename ELFT::Shdr> SHeaders);
24006456daaSGeorgii Rymar
24133b1a0ebSGeorge Rimar void finalizeStrings();
2429c89dcf8SGeorgii Rymar void writeELFHeader(raw_ostream &OS);
2433212ecfeSGeorge Rimar void writeSectionContent(Elf_Shdr &SHeader,
244818ab3d6SGeorgii Rymar const ELFYAML::NoBitsSection &Section,
245818ab3d6SGeorgii Rymar ContiguousBlobAccumulator &CBA);
246818ab3d6SGeorgii Rymar void writeSectionContent(Elf_Shdr &SHeader,
247c22d9666SAlex Brachet const ELFYAML::RawContentSection &Section,
248c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA);
2493212ecfeSGeorge Rimar void writeSectionContent(Elf_Shdr &SHeader,
250c22d9666SAlex Brachet const ELFYAML::RelocationSection &Section,
251c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA);
2527570d387SGeorgii Rymar void writeSectionContent(Elf_Shdr &SHeader,
2537570d387SGeorgii Rymar const ELFYAML::RelrSection &Section,
2547570d387SGeorgii Rymar ContiguousBlobAccumulator &CBA);
25582311766SGeorgii Rymar void writeSectionContent(Elf_Shdr &SHeader,
25682311766SGeorgii Rymar const ELFYAML::GroupSection &Group,
257c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA);
2583212ecfeSGeorge Rimar void writeSectionContent(Elf_Shdr &SHeader,
259d3963051SGeorge Rimar const ELFYAML::SymtabShndxSection &Shndx,
260d3963051SGeorge Rimar ContiguousBlobAccumulator &CBA);
2613212ecfeSGeorge Rimar void writeSectionContent(Elf_Shdr &SHeader,
262c22d9666SAlex Brachet const ELFYAML::SymverSection &Section,
263c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA);
2643212ecfeSGeorge Rimar void writeSectionContent(Elf_Shdr &SHeader,
265c22d9666SAlex Brachet const ELFYAML::VerneedSection &Section,
266c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA);
2673212ecfeSGeorge Rimar void writeSectionContent(Elf_Shdr &SHeader,
268c22d9666SAlex Brachet const ELFYAML::VerdefSection &Section,
269c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA);
2703212ecfeSGeorge Rimar void writeSectionContent(Elf_Shdr &SHeader,
271dab99171SGeorgii Rymar const ELFYAML::ARMIndexTableSection &Section,
272dab99171SGeorgii Rymar ContiguousBlobAccumulator &CBA);
273dab99171SGeorgii Rymar void writeSectionContent(Elf_Shdr &SHeader,
274c22d9666SAlex Brachet const ELFYAML::MipsABIFlags &Section,
275c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA);
2763212ecfeSGeorge Rimar void writeSectionContent(Elf_Shdr &SHeader,
277c22d9666SAlex Brachet const ELFYAML::DynamicSection &Section,
278c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA);
2791a219aa8SGeorge Rimar void writeSectionContent(Elf_Shdr &SHeader,
2801a219aa8SGeorge Rimar const ELFYAML::StackSizesSection &Section,
2811a219aa8SGeorge Rimar ContiguousBlobAccumulator &CBA);
282e5163ebfSGeorge Rimar void writeSectionContent(Elf_Shdr &SHeader,
28382e7c4ceSRahman Lavaee const ELFYAML::BBAddrMapSection &Section,
28482e7c4ceSRahman Lavaee ContiguousBlobAccumulator &CBA);
28582e7c4ceSRahman Lavaee void writeSectionContent(Elf_Shdr &SHeader,
286e5163ebfSGeorge Rimar const ELFYAML::HashSection &Section,
287e5163ebfSGeorge Rimar ContiguousBlobAccumulator &CBA);
288fc9104d4SGeorge Rimar void writeSectionContent(Elf_Shdr &SHeader,
289fc9104d4SGeorge Rimar const ELFYAML::AddrsigSection &Section,
290fc9104d4SGeorge Rimar ContiguousBlobAccumulator &CBA);
291de3cef1dSgeorgerim void writeSectionContent(Elf_Shdr &SHeader,
292de3cef1dSgeorgerim const ELFYAML::NoteSection &Section,
293de3cef1dSgeorgerim ContiguousBlobAccumulator &CBA);
294a7aee6c4Sgeorgerim void writeSectionContent(Elf_Shdr &SHeader,
295a7aee6c4Sgeorgerim const ELFYAML::GnuHashSection &Section,
296a7aee6c4Sgeorgerim ContiguousBlobAccumulator &CBA);
297dd101539SGeorgii Rymar void writeSectionContent(Elf_Shdr &SHeader,
298dd101539SGeorgii Rymar const ELFYAML::LinkerOptionsSection &Section,
299dd101539SGeorgii Rymar ContiguousBlobAccumulator &CBA);
3009659464dSGeorgii Rymar void writeSectionContent(Elf_Shdr &SHeader,
3019659464dSGeorgii Rymar const ELFYAML::DependentLibrariesSection &Section,
3029659464dSGeorgii Rymar ContiguousBlobAccumulator &CBA);
303bec54e46SGeorgii Rymar void writeSectionContent(Elf_Shdr &SHeader,
304bec54e46SGeorgii Rymar const ELFYAML::CallGraphProfileSection &Section,
305bec54e46SGeorgii Rymar ContiguousBlobAccumulator &CBA);
306fc9104d4SGeorge Rimar
30706456daaSGeorgii Rymar void writeFill(ELFYAML::Fill &Fill, ContiguousBlobAccumulator &CBA);
30806456daaSGeorgii Rymar
30985011027SGeorge Rimar ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH);
31085011027SGeorge Rimar
31131f2ad9cSGeorgii Rymar void assignSectionAddress(Elf_Shdr &SHeader, ELFYAML::Section *YAMLSec);
31231f2ad9cSGeorgii Rymar
313ad07d5f3SGeorgii Rymar DenseMap<StringRef, size_t> buildSectionHeaderReorderMap();
314ad07d5f3SGeorgii Rymar
31538c5d6f7SGeorgii Rymar BumpPtrAllocator StringAlloc;
3167ccae2ceSGeorgii Rymar uint64_t alignToOffset(ContiguousBlobAccumulator &CBA, uint64_t Align,
3177ccae2ceSGeorgii Rymar llvm::Optional<llvm::yaml::Hex64> Offset);
3187ccae2ceSGeorgii Rymar
319c781e737SGeorgii Rymar uint64_t getSectionNameOffset(StringRef Name);
320c781e737SGeorgii Rymar
321c22d9666SAlex Brachet public:
32285011027SGeorge Rimar static bool writeELF(raw_ostream &OS, ELFYAML::Object &Doc,
3233c123acfSGeorgii Rymar yaml::ErrorHandler EH, uint64_t MaxSize);
324c22d9666SAlex Brachet };
325c22d9666SAlex Brachet } // end anonymous namespace
326c22d9666SAlex Brachet
arrayDataSize(ArrayRef<T> A)327c22d9666SAlex Brachet template <class T> static size_t arrayDataSize(ArrayRef<T> A) {
328c22d9666SAlex Brachet return A.size() * sizeof(T);
329c22d9666SAlex Brachet }
330c22d9666SAlex Brachet
writeArrayData(raw_ostream & OS,ArrayRef<T> A)331c22d9666SAlex Brachet template <class T> static void writeArrayData(raw_ostream &OS, ArrayRef<T> A) {
332c22d9666SAlex Brachet OS.write((const char *)A.data(), arrayDataSize(A));
333c22d9666SAlex Brachet }
334c22d9666SAlex Brachet
zero(T & Obj)335c22d9666SAlex Brachet template <class T> static void zero(T &Obj) { memset(&Obj, 0, sizeof(Obj)); }
336c22d9666SAlex Brachet
33785011027SGeorge Rimar template <class ELFT>
ELFState(ELFYAML::Object & D,yaml::ErrorHandler EH)33885011027SGeorge Rimar ELFState<ELFT>::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH)
33985011027SGeorge Rimar : Doc(D), ErrHandler(EH) {
3405c1639feSJames Henderson // The input may explicitly request to store the section header table strings
3415c1639feSJames Henderson // in the same string table as dynamic or static symbol names. Set the
3425c1639feSJames Henderson // ShStrtabStrings member accordingly.
3435c1639feSJames Henderson if (Doc.Header.SectionHeaderStringTable) {
3445c1639feSJames Henderson SectionHeaderStringTableName = *Doc.Header.SectionHeaderStringTable;
3455c1639feSJames Henderson if (*Doc.Header.SectionHeaderStringTable == ".strtab")
3465c1639feSJames Henderson ShStrtabStrings = &DotStrtab;
3475c1639feSJames Henderson else if (*Doc.Header.SectionHeaderStringTable == ".dynstr")
3485c1639feSJames Henderson ShStrtabStrings = &DotDynstr;
3495c1639feSJames Henderson // Otherwise, the unique table will be used.
3505c1639feSJames Henderson }
3515c1639feSJames Henderson
35206456daaSGeorgii Rymar std::vector<ELFYAML::Section *> Sections = Doc.getSections();
353c22d9666SAlex Brachet // Insert SHT_NULL section implicitly when it is not defined in YAML.
35406456daaSGeorgii Rymar if (Sections.empty() || Sections.front()->Type != ELF::SHT_NULL)
35506456daaSGeorgii Rymar Doc.Chunks.insert(
35606456daaSGeorgii Rymar Doc.Chunks.begin(),
3570eaee545SJonas Devlieghere std::make_unique<ELFYAML::Section>(
35806456daaSGeorgii Rymar ELFYAML::Chunk::ChunkKind::RawContent, /*IsImplicit=*/true));
359c22d9666SAlex Brachet
36038c5d6f7SGeorgii Rymar StringSet<> DocSections;
3619c89dcf8SGeorgii Rymar ELFYAML::SectionHeaderTable *SecHdrTable = nullptr;
36238c5d6f7SGeorgii Rymar for (size_t I = 0; I < Doc.Chunks.size(); ++I) {
36338c5d6f7SGeorgii Rymar const std::unique_ptr<ELFYAML::Chunk> &C = Doc.Chunks[I];
3649c89dcf8SGeorgii Rymar
3659c89dcf8SGeorgii Rymar // We might have an explicit section header table declaration.
3669c89dcf8SGeorgii Rymar if (auto S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get())) {
3679c89dcf8SGeorgii Rymar if (SecHdrTable)
3689c89dcf8SGeorgii Rymar reportError("multiple section header tables are not allowed");
3699c89dcf8SGeorgii Rymar SecHdrTable = S;
3709c89dcf8SGeorgii Rymar continue;
3719c89dcf8SGeorgii Rymar }
3729c89dcf8SGeorgii Rymar
3739c89dcf8SGeorgii Rymar // We add a technical suffix for each unnamed section/fill. It does not
3749c89dcf8SGeorgii Rymar // affect the output, but allows us to map them by name in the code and
3759c89dcf8SGeorgii Rymar // report better error messages.
37638c5d6f7SGeorgii Rymar if (C->Name.empty()) {
37738c5d6f7SGeorgii Rymar std::string NewName = ELFYAML::appendUniqueSuffix(
37838c5d6f7SGeorgii Rymar /*Name=*/"", "index " + Twine(I));
37938c5d6f7SGeorgii Rymar C->Name = StringRef(NewName).copy(StringAlloc);
38038c5d6f7SGeorgii Rymar assert(ELFYAML::dropUniqueSuffix(C->Name).empty());
38138c5d6f7SGeorgii Rymar }
382304b0ed4SGeorgii Rymar
383304b0ed4SGeorgii Rymar if (!DocSections.insert(C->Name).second)
384304b0ed4SGeorgii Rymar reportError("repeated section/fill name: '" + C->Name +
385304b0ed4SGeorgii Rymar "' at YAML section/fill number " + Twine(I));
38638c5d6f7SGeorgii Rymar }
38738c5d6f7SGeorgii Rymar
3885c1639feSJames Henderson SmallSetVector<StringRef, 8> ImplicitSections;
3895c1639feSJames Henderson if (Doc.DynamicSymbols) {
3905c1639feSJames Henderson if (SectionHeaderStringTableName == ".dynsym")
3915c1639feSJames Henderson reportError("cannot use '.dynsym' as the section header name table when "
3925c1639feSJames Henderson "there are dynamic symbols");
3935c1639feSJames Henderson ImplicitSections.insert(".dynsym");
3945c1639feSJames Henderson ImplicitSections.insert(".dynstr");
3955c1639feSJames Henderson }
3965c1639feSJames Henderson if (Doc.Symbols) {
3975c1639feSJames Henderson if (SectionHeaderStringTableName == ".symtab")
3985c1639feSJames Henderson reportError("cannot use '.symtab' as the section header name table when "
3995c1639feSJames Henderson "there are symbols");
4005c1639feSJames Henderson ImplicitSections.insert(".symtab");
4015c1639feSJames Henderson }
402373e98a3SXing GUO if (Doc.DWARF)
403b1731da8SXing GUO for (StringRef DebugSecName : Doc.DWARF->getNonEmptySectionNames()) {
404373e98a3SXing GUO std::string SecName = ("." + DebugSecName).str();
4055c1639feSJames Henderson // TODO: For .debug_str it should be possible to share the string table,
4065c1639feSJames Henderson // in the same manner as the symbol string tables.
4075c1639feSJames Henderson if (SectionHeaderStringTableName == SecName)
4085c1639feSJames Henderson reportError("cannot use '" + SecName +
4095c1639feSJames Henderson "' as the section header name table when it is needed for "
4105c1639feSJames Henderson "DWARF output");
4115c1639feSJames Henderson ImplicitSections.insert(StringRef(SecName).copy(StringAlloc));
412373e98a3SXing GUO }
4135c1639feSJames Henderson // TODO: Only create the .strtab here if any symbols have been requested.
4145c1639feSJames Henderson ImplicitSections.insert(".strtab");
415129b531cSKazu Hirata if (!SecHdrTable || !SecHdrTable->NoHeaders.value_or(false))
4165c1639feSJames Henderson ImplicitSections.insert(SectionHeaderStringTableName);
4172779987dSGeorge Rimar
418c22d9666SAlex Brachet // Insert placeholders for implicit sections that are not
419c22d9666SAlex Brachet // defined explicitly in YAML.
420c22d9666SAlex Brachet for (StringRef SecName : ImplicitSections) {
421c22d9666SAlex Brachet if (DocSections.count(SecName))
422c22d9666SAlex Brachet continue;
423c22d9666SAlex Brachet
424029644eeSGeorgii Rymar std::unique_ptr<ELFYAML::Section> Sec = std::make_unique<ELFYAML::Section>(
42506456daaSGeorgii Rymar ELFYAML::Chunk::ChunkKind::RawContent, true /*IsImplicit*/);
426c22d9666SAlex Brachet Sec->Name = SecName;
4279c89dcf8SGeorgii Rymar
4285c1639feSJames Henderson if (SecName == SectionHeaderStringTableName)
4295c1639feSJames Henderson Sec->Type = ELF::SHT_STRTAB;
4305c1639feSJames Henderson else if (SecName == ".dynsym")
431029644eeSGeorgii Rymar Sec->Type = ELF::SHT_DYNSYM;
432029644eeSGeorgii Rymar else if (SecName == ".symtab")
433029644eeSGeorgii Rymar Sec->Type = ELF::SHT_SYMTAB;
434029644eeSGeorgii Rymar else
435029644eeSGeorgii Rymar Sec->Type = ELF::SHT_STRTAB;
436029644eeSGeorgii Rymar
4379c89dcf8SGeorgii Rymar // When the section header table is explicitly defined at the end of the
4389c89dcf8SGeorgii Rymar // sections list, it is reasonable to assume that the user wants to reorder
4399c89dcf8SGeorgii Rymar // section headers, but still wants to place the section header table after
4409c89dcf8SGeorgii Rymar // all sections, like it normally happens. In this case we want to insert
4419c89dcf8SGeorgii Rymar // other implicit sections right before the section header table.
4429c89dcf8SGeorgii Rymar if (Doc.Chunks.back().get() == SecHdrTable)
4439c89dcf8SGeorgii Rymar Doc.Chunks.insert(Doc.Chunks.end() - 1, std::move(Sec));
4449c89dcf8SGeorgii Rymar else
44506456daaSGeorgii Rymar Doc.Chunks.push_back(std::move(Sec));
446c22d9666SAlex Brachet }
4479c89dcf8SGeorgii Rymar
4489c89dcf8SGeorgii Rymar // Insert the section header table implicitly at the end, when it is not
4499c89dcf8SGeorgii Rymar // explicitly defined.
4509c89dcf8SGeorgii Rymar if (!SecHdrTable)
4519c89dcf8SGeorgii Rymar Doc.Chunks.push_back(
4529c89dcf8SGeorgii Rymar std::make_unique<ELFYAML::SectionHeaderTable>(/*IsImplicit=*/true));
453c22d9666SAlex Brachet }
454c22d9666SAlex Brachet
455c3bc6979SFangrui Song template <class ELFT>
writeELFHeader(raw_ostream & OS)4569c89dcf8SGeorgii Rymar void ELFState<ELFT>::writeELFHeader(raw_ostream &OS) {
457c22d9666SAlex Brachet using namespace llvm::ELF;
458c3bc6979SFangrui Song
459c3bc6979SFangrui Song Elf_Ehdr Header;
460c22d9666SAlex Brachet zero(Header);
461c22d9666SAlex Brachet Header.e_ident[EI_MAG0] = 0x7f;
462c22d9666SAlex Brachet Header.e_ident[EI_MAG1] = 'E';
463c22d9666SAlex Brachet Header.e_ident[EI_MAG2] = 'L';
464c22d9666SAlex Brachet Header.e_ident[EI_MAG3] = 'F';
465c22d9666SAlex Brachet Header.e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32;
466c22d9666SAlex Brachet Header.e_ident[EI_DATA] = Doc.Header.Data;
467c22d9666SAlex Brachet Header.e_ident[EI_VERSION] = EV_CURRENT;
468c22d9666SAlex Brachet Header.e_ident[EI_OSABI] = Doc.Header.OSABI;
469c22d9666SAlex Brachet Header.e_ident[EI_ABIVERSION] = Doc.Header.ABIVersion;
470c22d9666SAlex Brachet Header.e_type = Doc.Header.Type;
471a6436b0bSGeorgii Rymar
472a6436b0bSGeorgii Rymar if (Doc.Header.Machine)
473a6436b0bSGeorgii Rymar Header.e_machine = *Doc.Header.Machine;
474a6436b0bSGeorgii Rymar else
475a6436b0bSGeorgii Rymar Header.e_machine = EM_NONE;
476a6436b0bSGeorgii Rymar
477c22d9666SAlex Brachet Header.e_version = EV_CURRENT;
478c22d9666SAlex Brachet Header.e_entry = Doc.Header.Entry;
479c22d9666SAlex Brachet Header.e_flags = Doc.Header.Flags;
480c22d9666SAlex Brachet Header.e_ehsize = sizeof(Elf_Ehdr);
48130015693SGeorgii Rymar
48230015693SGeorgii Rymar if (Doc.Header.EPhOff)
48330015693SGeorgii Rymar Header.e_phoff = *Doc.Header.EPhOff;
48430015693SGeorgii Rymar else if (!Doc.ProgramHeaders.empty())
48530015693SGeorgii Rymar Header.e_phoff = sizeof(Header);
48630015693SGeorgii Rymar else
48730015693SGeorgii Rymar Header.e_phoff = 0;
48830015693SGeorgii Rymar
48930015693SGeorgii Rymar if (Doc.Header.EPhEntSize)
49030015693SGeorgii Rymar Header.e_phentsize = *Doc.Header.EPhEntSize;
49130015693SGeorgii Rymar else if (!Doc.ProgramHeaders.empty())
49230015693SGeorgii Rymar Header.e_phentsize = sizeof(Elf_Phdr);
49330015693SGeorgii Rymar else
49430015693SGeorgii Rymar Header.e_phentsize = 0;
49530015693SGeorgii Rymar
49630015693SGeorgii Rymar if (Doc.Header.EPhNum)
49730015693SGeorgii Rymar Header.e_phnum = *Doc.Header.EPhNum;
49830015693SGeorgii Rymar else if (!Doc.ProgramHeaders.empty())
499c22d9666SAlex Brachet Header.e_phnum = Doc.ProgramHeaders.size();
50030015693SGeorgii Rymar else
50130015693SGeorgii Rymar Header.e_phnum = 0;
502c22d9666SAlex Brachet
5037a587ca9SGeorgii Rymar Header.e_shentsize = Doc.Header.EShEntSize ? (uint16_t)*Doc.Header.EShEntSize
5047a587ca9SGeorgii Rymar : sizeof(Elf_Shdr);
505ad07d5f3SGeorgii Rymar
5069c89dcf8SGeorgii Rymar const ELFYAML::SectionHeaderTable &SectionHeaders =
5079c89dcf8SGeorgii Rymar Doc.getSectionHeaderTable();
5089c89dcf8SGeorgii Rymar
5097a587ca9SGeorgii Rymar if (Doc.Header.EShOff)
5107a587ca9SGeorgii Rymar Header.e_shoff = *Doc.Header.EShOff;
5119c89dcf8SGeorgii Rymar else if (SectionHeaders.Offset)
5129c89dcf8SGeorgii Rymar Header.e_shoff = *SectionHeaders.Offset;
513ad07d5f3SGeorgii Rymar else
514fcf62879SGeorgii Rymar Header.e_shoff = 0;
515ad07d5f3SGeorgii Rymar
5167a587ca9SGeorgii Rymar if (Doc.Header.EShNum)
5177a587ca9SGeorgii Rymar Header.e_shnum = *Doc.Header.EShNum;
518ad07d5f3SGeorgii Rymar else
5199c89dcf8SGeorgii Rymar Header.e_shnum = SectionHeaders.getNumHeaders(Doc.getSections().size());
520ad07d5f3SGeorgii Rymar
5217a587ca9SGeorgii Rymar if (Doc.Header.EShStrNdx)
5227a587ca9SGeorgii Rymar Header.e_shstrndx = *Doc.Header.EShStrNdx;
5235c1639feSJames Henderson else if (SectionHeaders.Offset &&
5245c1639feSJames Henderson !ExcludedSectionHeaders.count(SectionHeaderStringTableName))
5255c1639feSJames Henderson Header.e_shstrndx = SN2I.get(SectionHeaderStringTableName);
526fcf62879SGeorgii Rymar else
527fcf62879SGeorgii Rymar Header.e_shstrndx = 0;
528c3bc6979SFangrui Song
529c3bc6979SFangrui Song OS.write((const char *)&Header, sizeof(Header));
530c22d9666SAlex Brachet }
531c22d9666SAlex Brachet
532c22d9666SAlex Brachet template <class ELFT>
initProgramHeaders(std::vector<Elf_Phdr> & PHeaders)533c22d9666SAlex Brachet void ELFState<ELFT>::initProgramHeaders(std::vector<Elf_Phdr> &PHeaders) {
5343d4c873aSGeorgii Rymar DenseMap<StringRef, ELFYAML::Fill *> NameToFill;
535a7a447beSGeorgii Rymar DenseMap<StringRef, size_t> NameToIndex;
536a7a447beSGeorgii Rymar for (size_t I = 0, E = Doc.Chunks.size(); I != E; ++I) {
537a7a447beSGeorgii Rymar if (auto S = dyn_cast<ELFYAML::Fill>(Doc.Chunks[I].get()))
5383d4c873aSGeorgii Rymar NameToFill[S->Name] = S;
539a7a447beSGeorgii Rymar NameToIndex[Doc.Chunks[I]->Name] = I + 1;
540a7a447beSGeorgii Rymar }
5413d4c873aSGeorgii Rymar
5423d4c873aSGeorgii Rymar std::vector<ELFYAML::Section *> Sections = Doc.getSections();
543a7a447beSGeorgii Rymar for (size_t I = 0, E = Doc.ProgramHeaders.size(); I != E; ++I) {
544a7a447beSGeorgii Rymar ELFYAML::ProgramHeader &YamlPhdr = Doc.ProgramHeaders[I];
545c22d9666SAlex Brachet Elf_Phdr Phdr;
54634b3d5b6SGeorgii Rymar zero(Phdr);
547c22d9666SAlex Brachet Phdr.p_type = YamlPhdr.Type;
548c22d9666SAlex Brachet Phdr.p_flags = YamlPhdr.Flags;
549c22d9666SAlex Brachet Phdr.p_vaddr = YamlPhdr.VAddr;
550c22d9666SAlex Brachet Phdr.p_paddr = YamlPhdr.PAddr;
551c22d9666SAlex Brachet PHeaders.push_back(Phdr);
5523d4c873aSGeorgii Rymar
553a7a447beSGeorgii Rymar if (!YamlPhdr.FirstSec && !YamlPhdr.LastSec)
5543d4c873aSGeorgii Rymar continue;
5553d4c873aSGeorgii Rymar
556a7a447beSGeorgii Rymar // Get the index of the section, or 0 in the case when the section doesn't exist.
557a7a447beSGeorgii Rymar size_t First = NameToIndex[*YamlPhdr.FirstSec];
558a7a447beSGeorgii Rymar if (!First)
559a7a447beSGeorgii Rymar reportError("unknown section or fill referenced: '" + *YamlPhdr.FirstSec +
560a7a447beSGeorgii Rymar "' by the 'FirstSec' key of the program header with index " +
561a7a447beSGeorgii Rymar Twine(I));
562a7a447beSGeorgii Rymar size_t Last = NameToIndex[*YamlPhdr.LastSec];
563a7a447beSGeorgii Rymar if (!Last)
564a7a447beSGeorgii Rymar reportError("unknown section or fill referenced: '" + *YamlPhdr.LastSec +
565a7a447beSGeorgii Rymar "' by the 'LastSec' key of the program header with index " +
566a7a447beSGeorgii Rymar Twine(I));
567a7a447beSGeorgii Rymar if (!First || !Last)
5683d4c873aSGeorgii Rymar continue;
5693d4c873aSGeorgii Rymar
570a7a447beSGeorgii Rymar if (First > Last)
571a7a447beSGeorgii Rymar reportError("program header with index " + Twine(I) +
572a7a447beSGeorgii Rymar ": the section index of " + *YamlPhdr.FirstSec +
573a7a447beSGeorgii Rymar " is greater than the index of " + *YamlPhdr.LastSec);
574a7a447beSGeorgii Rymar
575a7a447beSGeorgii Rymar for (size_t I = First; I <= Last; ++I)
576a7a447beSGeorgii Rymar YamlPhdr.Chunks.push_back(Doc.Chunks[I - 1].get());
577c22d9666SAlex Brachet }
578c22d9666SAlex Brachet }
579c22d9666SAlex Brachet
5803212ecfeSGeorge Rimar template <class ELFT>
toSectionIndex(StringRef S,StringRef LocSec,StringRef LocSym)5813212ecfeSGeorge Rimar unsigned ELFState<ELFT>::toSectionIndex(StringRef S, StringRef LocSec,
5823212ecfeSGeorge Rimar StringRef LocSym) {
5833212ecfeSGeorge Rimar assert(LocSec.empty() || LocSym.empty());
584c781e737SGeorgii Rymar
585c781e737SGeorgii Rymar unsigned Index;
586c781e737SGeorgii Rymar if (!SN2I.lookup(S, Index) && !to_integer(S, Index)) {
5873212ecfeSGeorge Rimar if (!LocSym.empty())
5883212ecfeSGeorge Rimar reportError("unknown section referenced: '" + S + "' by YAML symbol '" +
5893212ecfeSGeorge Rimar LocSym + "'");
5903212ecfeSGeorge Rimar else
5913212ecfeSGeorge Rimar reportError("unknown section referenced: '" + S + "' by YAML section '" +
5923212ecfeSGeorge Rimar LocSec + "'");
5933212ecfeSGeorge Rimar return 0;
594c22d9666SAlex Brachet }
5953212ecfeSGeorge Rimar
5969c89dcf8SGeorgii Rymar const ELFYAML::SectionHeaderTable &SectionHeaders =
5979c89dcf8SGeorgii Rymar Doc.getSectionHeaderTable();
5989c89dcf8SGeorgii Rymar if (SectionHeaders.IsImplicit ||
5997a47ee51SKazu Hirata (SectionHeaders.NoHeaders && !*SectionHeaders.NoHeaders) ||
60068195b15SGeorgii Rymar SectionHeaders.isDefault())
601c781e737SGeorgii Rymar return Index;
602c781e737SGeorgii Rymar
603129b531cSKazu Hirata assert(!SectionHeaders.NoHeaders.value_or(false) || !SectionHeaders.Sections);
604ec4e68e6SGeorgii Rymar size_t FirstExcluded =
6059c89dcf8SGeorgii Rymar SectionHeaders.Sections ? SectionHeaders.Sections->size() : 0;
606fef3bfb1SJames Henderson if (Index > FirstExcluded) {
607c781e737SGeorgii Rymar if (LocSym.empty())
608c781e737SGeorgii Rymar reportError("unable to link '" + LocSec + "' to excluded section '" + S +
609c781e737SGeorgii Rymar "'");
610c781e737SGeorgii Rymar else
611c781e737SGeorgii Rymar reportError("excluded section referenced: '" + S + "' by symbol '" +
612c781e737SGeorgii Rymar LocSym + "'");
613c781e737SGeorgii Rymar }
614c781e737SGeorgii Rymar return Index;
615c781e737SGeorgii Rymar }
616c781e737SGeorgii Rymar
6173212ecfeSGeorge Rimar template <class ELFT>
toSymbolIndex(StringRef S,StringRef LocSec,bool IsDynamic)6183212ecfeSGeorge Rimar unsigned ELFState<ELFT>::toSymbolIndex(StringRef S, StringRef LocSec,
6193212ecfeSGeorge Rimar bool IsDynamic) {
6203212ecfeSGeorge Rimar const NameToIdxMap &SymMap = IsDynamic ? DynSymN2I : SymN2I;
6213212ecfeSGeorge Rimar unsigned Index;
6223212ecfeSGeorge Rimar // Here we try to look up S in the symbol table. If it is not there,
6233212ecfeSGeorge Rimar // treat its value as a symbol index.
6243212ecfeSGeorge Rimar if (!SymMap.lookup(S, Index) && !to_integer(S, Index)) {
6253212ecfeSGeorge Rimar reportError("unknown symbol referenced: '" + S + "' by YAML section '" +
6263212ecfeSGeorge Rimar LocSec + "'");
6273212ecfeSGeorge Rimar return 0;
6283212ecfeSGeorge Rimar }
6293212ecfeSGeorge Rimar return Index;
630c22d9666SAlex Brachet }
631c22d9666SAlex Brachet
632c22d9666SAlex Brachet template <class ELFT>
overrideFields(ELFYAML::Section * From,typename ELFT::Shdr & To)63386e652f8SGeorgii Rymar static void overrideFields(ELFYAML::Section *From, typename ELFT::Shdr &To) {
63486e652f8SGeorgii Rymar if (!From)
63586e652f8SGeorgii Rymar return;
6362d59ed4eSGeorgii Rymar if (From->ShAddrAlign)
6372d59ed4eSGeorgii Rymar To.sh_addralign = *From->ShAddrAlign;
63886e652f8SGeorgii Rymar if (From->ShFlags)
63986e652f8SGeorgii Rymar To.sh_flags = *From->ShFlags;
64086e652f8SGeorgii Rymar if (From->ShName)
64186e652f8SGeorgii Rymar To.sh_name = *From->ShName;
64286e652f8SGeorgii Rymar if (From->ShOffset)
64386e652f8SGeorgii Rymar To.sh_offset = *From->ShOffset;
64486e652f8SGeorgii Rymar if (From->ShSize)
64586e652f8SGeorgii Rymar To.sh_size = *From->ShSize;
646bd93f5ceSGeorgii Rymar if (From->ShType)
647bd93f5ceSGeorgii Rymar To.sh_type = *From->ShType;
64886e652f8SGeorgii Rymar }
64986e652f8SGeorgii Rymar
65086e652f8SGeorgii Rymar template <class ELFT>
initImplicitHeader(ContiguousBlobAccumulator & CBA,Elf_Shdr & Header,StringRef SecName,ELFYAML::Section * YAMLSec)65133b1a0ebSGeorge Rimar bool ELFState<ELFT>::initImplicitHeader(ContiguousBlobAccumulator &CBA,
652c22d9666SAlex Brachet Elf_Shdr &Header, StringRef SecName,
653c22d9666SAlex Brachet ELFYAML::Section *YAMLSec) {
654c22d9666SAlex Brachet // Check if the header was already initialized.
655c22d9666SAlex Brachet if (Header.sh_offset)
656c22d9666SAlex Brachet return false;
657c22d9666SAlex Brachet
6585c1639feSJames Henderson if (SecName == ".strtab")
65933b1a0ebSGeorge Rimar initStrtabSectionHeader(Header, SecName, DotStrtab, CBA, YAMLSec);
660c22d9666SAlex Brachet else if (SecName == ".dynstr")
66133b1a0ebSGeorge Rimar initStrtabSectionHeader(Header, SecName, DotDynstr, CBA, YAMLSec);
6625c1639feSJames Henderson else if (SecName == SectionHeaderStringTableName)
6635c1639feSJames Henderson initStrtabSectionHeader(Header, SecName, *ShStrtabStrings, CBA, YAMLSec);
6645c1639feSJames Henderson else if (SecName == ".symtab")
6655c1639feSJames Henderson initSymtabSectionHeader(Header, SymtabType::Static, CBA, YAMLSec);
6665c1639feSJames Henderson else if (SecName == ".dynsym")
6675c1639feSJames Henderson initSymtabSectionHeader(Header, SymtabType::Dynamic, CBA, YAMLSec);
668373e98a3SXing GUO else if (SecName.startswith(".debug_")) {
669373e98a3SXing GUO // If a ".debug_*" section's type is a preserved one, e.g., SHT_DYNAMIC, we
670373e98a3SXing GUO // will not treat it as a debug section.
671373e98a3SXing GUO if (YAMLSec && !isa<ELFYAML::RawContentSection>(YAMLSec))
672373e98a3SXing GUO return false;
673373e98a3SXing GUO initDWARFSectionHeader(Header, SecName, CBA, YAMLSec);
674373e98a3SXing GUO } else
675c22d9666SAlex Brachet return false;
676c22d9666SAlex Brachet
67731f2ad9cSGeorgii Rymar LocationCounter += Header.sh_size;
67831f2ad9cSGeorgii Rymar
67986e652f8SGeorgii Rymar // Override section fields if requested.
68086e652f8SGeorgii Rymar overrideFields<ELFT>(YAMLSec, Header);
681c22d9666SAlex Brachet return true;
682c22d9666SAlex Brachet }
683c22d9666SAlex Brachet
68438c5d6f7SGeorgii Rymar constexpr char SuffixStart = '(';
685e2b134b0SGeorgii Rymar constexpr char SuffixEnd = ')';
686e2b134b0SGeorgii Rymar
appendUniqueSuffix(StringRef Name,const Twine & Msg)687e2b134b0SGeorgii Rymar std::string llvm::ELFYAML::appendUniqueSuffix(StringRef Name,
688e2b134b0SGeorgii Rymar const Twine &Msg) {
68938c5d6f7SGeorgii Rymar // Do not add a space when a Name is empty.
69038c5d6f7SGeorgii Rymar std::string Ret = Name.empty() ? "" : Name.str() + ' ';
69138c5d6f7SGeorgii Rymar return Ret + (Twine(SuffixStart) + Msg + Twine(SuffixEnd)).str();
692e2b134b0SGeorgii Rymar }
693e2b134b0SGeorgii Rymar
dropUniqueSuffix(StringRef S)694cfc2bccfSGeorge Rimar StringRef llvm::ELFYAML::dropUniqueSuffix(StringRef S) {
695e2b134b0SGeorgii Rymar if (S.empty() || S.back() != SuffixEnd)
696e2b134b0SGeorgii Rymar return S;
697e2b134b0SGeorgii Rymar
69838c5d6f7SGeorgii Rymar // A special case for empty names. See appendUniqueSuffix() above.
699e2b134b0SGeorgii Rymar size_t SuffixPos = S.rfind(SuffixStart);
70038c5d6f7SGeorgii Rymar if (SuffixPos == 0)
70138c5d6f7SGeorgii Rymar return "";
70238c5d6f7SGeorgii Rymar
70338c5d6f7SGeorgii Rymar if (SuffixPos == StringRef::npos || S[SuffixPos - 1] != ' ')
704c22d9666SAlex Brachet return S;
70538c5d6f7SGeorgii Rymar return S.substr(0, SuffixPos - 1);
706c22d9666SAlex Brachet }
707c22d9666SAlex Brachet
708c22d9666SAlex Brachet template <class ELFT>
getSectionNameOffset(StringRef Name)709c781e737SGeorgii Rymar uint64_t ELFState<ELFT>::getSectionNameOffset(StringRef Name) {
710c781e737SGeorgii Rymar // If a section is excluded from section headers, we do not save its name in
711c781e737SGeorgii Rymar // the string table.
712c781e737SGeorgii Rymar if (ExcludedSectionHeaders.count(Name))
713c781e737SGeorgii Rymar return 0;
7145c1639feSJames Henderson return ShStrtabStrings->getOffset(Name);
715c781e737SGeorgii Rymar }
716c781e737SGeorgii Rymar
writeContent(ContiguousBlobAccumulator & CBA,const Optional<yaml::BinaryRef> & Content,const Optional<llvm::yaml::Hex64> & Size)7173cfd9384SGeorgii Rymar static uint64_t writeContent(ContiguousBlobAccumulator &CBA,
7183cfd9384SGeorgii Rymar const Optional<yaml::BinaryRef> &Content,
7193cfd9384SGeorgii Rymar const Optional<llvm::yaml::Hex64> &Size) {
7203cfd9384SGeorgii Rymar size_t ContentSize = 0;
7213cfd9384SGeorgii Rymar if (Content) {
7223cfd9384SGeorgii Rymar CBA.writeAsBinary(*Content);
7233cfd9384SGeorgii Rymar ContentSize = Content->binary_size();
7243cfd9384SGeorgii Rymar }
7253cfd9384SGeorgii Rymar
7263cfd9384SGeorgii Rymar if (!Size)
7273cfd9384SGeorgii Rymar return ContentSize;
7283cfd9384SGeorgii Rymar
7293cfd9384SGeorgii Rymar CBA.writeZeros(*Size - ContentSize);
7303cfd9384SGeorgii Rymar return *Size;
7313cfd9384SGeorgii Rymar }
7323cfd9384SGeorgii Rymar
getDefaultLinkSec(unsigned SecType)733029644eeSGeorgii Rymar static StringRef getDefaultLinkSec(unsigned SecType) {
734029644eeSGeorgii Rymar switch (SecType) {
735029644eeSGeorgii Rymar case ELF::SHT_REL:
736029644eeSGeorgii Rymar case ELF::SHT_RELA:
737029644eeSGeorgii Rymar case ELF::SHT_GROUP:
738029644eeSGeorgii Rymar case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
739029644eeSGeorgii Rymar case ELF::SHT_LLVM_ADDRSIG:
740029644eeSGeorgii Rymar return ".symtab";
741029644eeSGeorgii Rymar case ELF::SHT_GNU_versym:
742029644eeSGeorgii Rymar case ELF::SHT_HASH:
743029644eeSGeorgii Rymar case ELF::SHT_GNU_HASH:
744029644eeSGeorgii Rymar return ".dynsym";
745029644eeSGeorgii Rymar case ELF::SHT_DYNSYM:
746029644eeSGeorgii Rymar case ELF::SHT_GNU_verdef:
747029644eeSGeorgii Rymar case ELF::SHT_GNU_verneed:
748029644eeSGeorgii Rymar return ".dynstr";
749029644eeSGeorgii Rymar case ELF::SHT_SYMTAB:
750029644eeSGeorgii Rymar return ".strtab";
751029644eeSGeorgii Rymar default:
752029644eeSGeorgii Rymar return "";
753029644eeSGeorgii Rymar }
754029644eeSGeorgii Rymar }
755029644eeSGeorgii Rymar
756c781e737SGeorgii Rymar template <class ELFT>
initSectionHeaders(std::vector<Elf_Shdr> & SHeaders,ContiguousBlobAccumulator & CBA)7573212ecfeSGeorge Rimar void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
758c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA) {
759c22d9666SAlex Brachet // Ensure SHN_UNDEF entry is present. An all-zero section header is a
760c22d9666SAlex Brachet // valid SHN_UNDEF entry since SHT_NULL == 0.
76106456daaSGeorgii Rymar SHeaders.resize(Doc.getSections().size());
762c22d9666SAlex Brachet
76306456daaSGeorgii Rymar for (const std::unique_ptr<ELFYAML::Chunk> &D : Doc.Chunks) {
764baf32259SGeorgii Rymar if (ELFYAML::Fill *S = dyn_cast<ELFYAML::Fill>(D.get())) {
765baf32259SGeorgii Rymar S->Offset = alignToOffset(CBA, /*Align=*/1, S->Offset);
76606456daaSGeorgii Rymar writeFill(*S, CBA);
76731f2ad9cSGeorgii Rymar LocationCounter += S->Size;
76806456daaSGeorgii Rymar continue;
76906456daaSGeorgii Rymar }
77006456daaSGeorgii Rymar
7719c89dcf8SGeorgii Rymar if (ELFYAML::SectionHeaderTable *S =
7729c89dcf8SGeorgii Rymar dyn_cast<ELFYAML::SectionHeaderTable>(D.get())) {
773129b531cSKazu Hirata if (S->NoHeaders.value_or(false))
7749c89dcf8SGeorgii Rymar continue;
7759c89dcf8SGeorgii Rymar
7769c89dcf8SGeorgii Rymar if (!S->Offset)
7779c89dcf8SGeorgii Rymar S->Offset = alignToOffset(CBA, sizeof(typename ELFT::uint),
7789c89dcf8SGeorgii Rymar /*Offset=*/None);
7799c89dcf8SGeorgii Rymar else
7809c89dcf8SGeorgii Rymar S->Offset = alignToOffset(CBA, /*Align=*/1, S->Offset);
7819c89dcf8SGeorgii Rymar
7829c89dcf8SGeorgii Rymar uint64_t Size = S->getNumHeaders(SHeaders.size()) * sizeof(Elf_Shdr);
7839c89dcf8SGeorgii Rymar // The full section header information might be not available here, so
7849c89dcf8SGeorgii Rymar // fill the space with zeroes as a placeholder.
7859c89dcf8SGeorgii Rymar CBA.writeZeros(Size);
7869c89dcf8SGeorgii Rymar LocationCounter += Size;
7879c89dcf8SGeorgii Rymar continue;
7889c89dcf8SGeorgii Rymar }
7899c89dcf8SGeorgii Rymar
79006456daaSGeorgii Rymar ELFYAML::Section *Sec = cast<ELFYAML::Section>(D.get());
7919c89dcf8SGeorgii Rymar bool IsFirstUndefSection = Sec == Doc.getSections().front();
79238c5d6f7SGeorgii Rymar if (IsFirstUndefSection && Sec->IsImplicit)
793c22d9666SAlex Brachet continue;
794c22d9666SAlex Brachet
795029644eeSGeorgii Rymar Elf_Shdr &SHeader = SHeaders[SN2I.get(Sec->Name)];
796029644eeSGeorgii Rymar if (Sec->Link) {
797029644eeSGeorgii Rymar SHeader.sh_link = toSectionIndex(*Sec->Link, Sec->Name);
798029644eeSGeorgii Rymar } else {
799029644eeSGeorgii Rymar StringRef LinkSec = getDefaultLinkSec(Sec->Type);
800029644eeSGeorgii Rymar unsigned Link = 0;
801029644eeSGeorgii Rymar if (!LinkSec.empty() && !ExcludedSectionHeaders.count(LinkSec) &&
802029644eeSGeorgii Rymar SN2I.lookup(LinkSec, Link))
803029644eeSGeorgii Rymar SHeader.sh_link = Link;
804029644eeSGeorgii Rymar }
805029644eeSGeorgii Rymar
806d5e48f13SGeorgii Rymar if (Sec->EntSize)
807d5e48f13SGeorgii Rymar SHeader.sh_entsize = *Sec->EntSize;
808d5e48f13SGeorgii Rymar else
809d5e48f13SGeorgii Rymar SHeader.sh_entsize = ELFYAML::getDefaultShEntSize<ELFT>(
810129b531cSKazu Hirata Doc.Header.Machine.value_or(ELF::EM_NONE), Sec->Type, Sec->Name);
811d5e48f13SGeorgii Rymar
812c22d9666SAlex Brachet // We have a few sections like string or symbol tables that are usually
813c22d9666SAlex Brachet // added implicitly to the end. However, if they are explicitly specified
814c22d9666SAlex Brachet // in the YAML, we need to write them here. This ensures the file offset
815c22d9666SAlex Brachet // remains correct.
81633b1a0ebSGeorge Rimar if (initImplicitHeader(CBA, SHeader, Sec->Name,
817c22d9666SAlex Brachet Sec->IsImplicit ? nullptr : Sec))
818c22d9666SAlex Brachet continue;
819c22d9666SAlex Brachet
820c22d9666SAlex Brachet assert(Sec && "It can't be null unless it is an implicit section. But all "
821c22d9666SAlex Brachet "implicit sections should already have been handled above.");
822c22d9666SAlex Brachet
823cfc2bccfSGeorge Rimar SHeader.sh_name =
824c781e737SGeorgii Rymar getSectionNameOffset(ELFYAML::dropUniqueSuffix(Sec->Name));
825c22d9666SAlex Brachet SHeader.sh_type = Sec->Type;
826c22d9666SAlex Brachet if (Sec->Flags)
827c22d9666SAlex Brachet SHeader.sh_flags = *Sec->Flags;
828c22d9666SAlex Brachet SHeader.sh_addralign = Sec->AddressAlign;
829c22d9666SAlex Brachet
8307ccae2ceSGeorgii Rymar // Set the offset for all sections, except the SHN_UNDEF section with index
8317ccae2ceSGeorgii Rymar // 0 when not explicitly requested.
8327ccae2ceSGeorgii Rymar if (!IsFirstUndefSection || Sec->Offset)
8337ccae2ceSGeorgii Rymar SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign, Sec->Offset);
8347ccae2ceSGeorgii Rymar
83531f2ad9cSGeorgii Rymar assignSectionAddress(SHeader, Sec);
83631f2ad9cSGeorgii Rymar
8377ccae2ceSGeorgii Rymar if (IsFirstUndefSection) {
838c22d9666SAlex Brachet if (auto RawSec = dyn_cast<ELFYAML::RawContentSection>(Sec)) {
839c22d9666SAlex Brachet // We do not write any content for special SHN_UNDEF section.
840c22d9666SAlex Brachet if (RawSec->Size)
841c22d9666SAlex Brachet SHeader.sh_size = *RawSec->Size;
842c22d9666SAlex Brachet if (RawSec->Info)
843c22d9666SAlex Brachet SHeader.sh_info = *RawSec->Info;
844c22d9666SAlex Brachet }
8453cfd9384SGeorgii Rymar
8463cfd9384SGeorgii Rymar LocationCounter += SHeader.sh_size;
8473cfd9384SGeorgii Rymar overrideFields<ELFT>(Sec, SHeader);
8483cfd9384SGeorgii Rymar continue;
8493cfd9384SGeorgii Rymar }
8503cfd9384SGeorgii Rymar
8513cfd9384SGeorgii Rymar if (!isa<ELFYAML::NoBitsSection>(Sec) && (Sec->Content || Sec->Size))
8523cfd9384SGeorgii Rymar SHeader.sh_size = writeContent(CBA, Sec->Content, Sec->Size);
8533cfd9384SGeorgii Rymar
8543cfd9384SGeorgii Rymar if (auto S = dyn_cast<ELFYAML::RawContentSection>(Sec)) {
8553212ecfeSGeorge Rimar writeSectionContent(SHeader, *S, CBA);
856d3963051SGeorge Rimar } else if (auto S = dyn_cast<ELFYAML::SymtabShndxSection>(Sec)) {
8573212ecfeSGeorge Rimar writeSectionContent(SHeader, *S, CBA);
858c22d9666SAlex Brachet } else if (auto S = dyn_cast<ELFYAML::RelocationSection>(Sec)) {
8593212ecfeSGeorge Rimar writeSectionContent(SHeader, *S, CBA);
8607570d387SGeorgii Rymar } else if (auto S = dyn_cast<ELFYAML::RelrSection>(Sec)) {
8617570d387SGeorgii Rymar writeSectionContent(SHeader, *S, CBA);
86282311766SGeorgii Rymar } else if (auto S = dyn_cast<ELFYAML::GroupSection>(Sec)) {
8633212ecfeSGeorge Rimar writeSectionContent(SHeader, *S, CBA);
864dab99171SGeorgii Rymar } else if (auto S = dyn_cast<ELFYAML::ARMIndexTableSection>(Sec)) {
865dab99171SGeorgii Rymar writeSectionContent(SHeader, *S, CBA);
866c22d9666SAlex Brachet } else if (auto S = dyn_cast<ELFYAML::MipsABIFlags>(Sec)) {
8673212ecfeSGeorge Rimar writeSectionContent(SHeader, *S, CBA);
868c22d9666SAlex Brachet } else if (auto S = dyn_cast<ELFYAML::NoBitsSection>(Sec)) {
869818ab3d6SGeorgii Rymar writeSectionContent(SHeader, *S, CBA);
870c22d9666SAlex Brachet } else if (auto S = dyn_cast<ELFYAML::DynamicSection>(Sec)) {
8713212ecfeSGeorge Rimar writeSectionContent(SHeader, *S, CBA);
872c22d9666SAlex Brachet } else if (auto S = dyn_cast<ELFYAML::SymverSection>(Sec)) {
8733212ecfeSGeorge Rimar writeSectionContent(SHeader, *S, CBA);
874c22d9666SAlex Brachet } else if (auto S = dyn_cast<ELFYAML::VerneedSection>(Sec)) {
8753212ecfeSGeorge Rimar writeSectionContent(SHeader, *S, CBA);
876c22d9666SAlex Brachet } else if (auto S = dyn_cast<ELFYAML::VerdefSection>(Sec)) {
8773212ecfeSGeorge Rimar writeSectionContent(SHeader, *S, CBA);
8781a219aa8SGeorge Rimar } else if (auto S = dyn_cast<ELFYAML::StackSizesSection>(Sec)) {
8791a219aa8SGeorge Rimar writeSectionContent(SHeader, *S, CBA);
880e5163ebfSGeorge Rimar } else if (auto S = dyn_cast<ELFYAML::HashSection>(Sec)) {
881e5163ebfSGeorge Rimar writeSectionContent(SHeader, *S, CBA);
882fc9104d4SGeorge Rimar } else if (auto S = dyn_cast<ELFYAML::AddrsigSection>(Sec)) {
883fc9104d4SGeorge Rimar writeSectionContent(SHeader, *S, CBA);
884dd101539SGeorgii Rymar } else if (auto S = dyn_cast<ELFYAML::LinkerOptionsSection>(Sec)) {
885dd101539SGeorgii Rymar writeSectionContent(SHeader, *S, CBA);
886de3cef1dSgeorgerim } else if (auto S = dyn_cast<ELFYAML::NoteSection>(Sec)) {
887de3cef1dSgeorgerim writeSectionContent(SHeader, *S, CBA);
888a7aee6c4Sgeorgerim } else if (auto S = dyn_cast<ELFYAML::GnuHashSection>(Sec)) {
889a7aee6c4Sgeorgerim writeSectionContent(SHeader, *S, CBA);
8909659464dSGeorgii Rymar } else if (auto S = dyn_cast<ELFYAML::DependentLibrariesSection>(Sec)) {
8919659464dSGeorgii Rymar writeSectionContent(SHeader, *S, CBA);
892bec54e46SGeorgii Rymar } else if (auto S = dyn_cast<ELFYAML::CallGraphProfileSection>(Sec)) {
893bec54e46SGeorgii Rymar writeSectionContent(SHeader, *S, CBA);
89482e7c4ceSRahman Lavaee } else if (auto S = dyn_cast<ELFYAML::BBAddrMapSection>(Sec)) {
89582e7c4ceSRahman Lavaee writeSectionContent(SHeader, *S, CBA);
8963212ecfeSGeorge Rimar } else {
897c22d9666SAlex Brachet llvm_unreachable("Unknown section type");
8983212ecfeSGeorge Rimar }
899c22d9666SAlex Brachet
90031f2ad9cSGeorgii Rymar LocationCounter += SHeader.sh_size;
90131f2ad9cSGeorgii Rymar
90286e652f8SGeorgii Rymar // Override section fields if requested.
90386e652f8SGeorgii Rymar overrideFields<ELFT>(Sec, SHeader);
904c22d9666SAlex Brachet }
905c22d9666SAlex Brachet }
906c22d9666SAlex Brachet
90731f2ad9cSGeorgii Rymar template <class ELFT>
assignSectionAddress(Elf_Shdr & SHeader,ELFYAML::Section * YAMLSec)90831f2ad9cSGeorgii Rymar void ELFState<ELFT>::assignSectionAddress(Elf_Shdr &SHeader,
90931f2ad9cSGeorgii Rymar ELFYAML::Section *YAMLSec) {
91031f2ad9cSGeorgii Rymar if (YAMLSec && YAMLSec->Address) {
91131f2ad9cSGeorgii Rymar SHeader.sh_addr = *YAMLSec->Address;
91231f2ad9cSGeorgii Rymar LocationCounter = *YAMLSec->Address;
91331f2ad9cSGeorgii Rymar return;
91431f2ad9cSGeorgii Rymar }
91531f2ad9cSGeorgii Rymar
91631f2ad9cSGeorgii Rymar // sh_addr represents the address in the memory image of a process. Sections
91731f2ad9cSGeorgii Rymar // in a relocatable object file or non-allocatable sections do not need
91831f2ad9cSGeorgii Rymar // sh_addr assignment.
91931f2ad9cSGeorgii Rymar if (Doc.Header.Type.value == ELF::ET_REL ||
92031f2ad9cSGeorgii Rymar !(SHeader.sh_flags & ELF::SHF_ALLOC))
92131f2ad9cSGeorgii Rymar return;
92231f2ad9cSGeorgii Rymar
92331f2ad9cSGeorgii Rymar LocationCounter =
92431f2ad9cSGeorgii Rymar alignTo(LocationCounter, SHeader.sh_addralign ? SHeader.sh_addralign : 1);
92531f2ad9cSGeorgii Rymar SHeader.sh_addr = LocationCounter;
92631f2ad9cSGeorgii Rymar }
92731f2ad9cSGeorgii Rymar
findFirstNonGlobal(ArrayRef<ELFYAML::Symbol> Symbols)928c22d9666SAlex Brachet static size_t findFirstNonGlobal(ArrayRef<ELFYAML::Symbol> Symbols) {
929c22d9666SAlex Brachet for (size_t I = 0; I < Symbols.size(); ++I)
930c22d9666SAlex Brachet if (Symbols[I].Binding.value != ELF::STB_LOCAL)
931c22d9666SAlex Brachet return I;
932c22d9666SAlex Brachet return Symbols.size();
933c22d9666SAlex Brachet }
934c22d9666SAlex Brachet
935c22d9666SAlex Brachet template <class ELFT>
9363212ecfeSGeorge Rimar std::vector<typename ELFT::Sym>
toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols,const StringTableBuilder & Strtab)9373212ecfeSGeorge Rimar ELFState<ELFT>::toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols,
938c22d9666SAlex Brachet const StringTableBuilder &Strtab) {
939c22d9666SAlex Brachet std::vector<Elf_Sym> Ret;
940c22d9666SAlex Brachet Ret.resize(Symbols.size() + 1);
941c22d9666SAlex Brachet
942c22d9666SAlex Brachet size_t I = 0;
943073ab70bSGeorgii Rymar for (const ELFYAML::Symbol &Sym : Symbols) {
944c22d9666SAlex Brachet Elf_Sym &Symbol = Ret[++I];
945c22d9666SAlex Brachet
946c22d9666SAlex Brachet // If NameIndex, which contains the name offset, is explicitly specified, we
947c22d9666SAlex Brachet // use it. This is useful for preparing broken objects. Otherwise, we add
948c22d9666SAlex Brachet // the specified Name to the string table builder to get its offset.
949fd0abcbfSGeorgii Rymar if (Sym.StName)
950fd0abcbfSGeorgii Rymar Symbol.st_name = *Sym.StName;
951c22d9666SAlex Brachet else if (!Sym.Name.empty())
952cfc2bccfSGeorge Rimar Symbol.st_name = Strtab.getOffset(ELFYAML::dropUniqueSuffix(Sym.Name));
953c22d9666SAlex Brachet
954c22d9666SAlex Brachet Symbol.setBindingAndType(Sym.Binding, Sym.Type);
9557ac06444SGeorgii Rymar if (Sym.Section)
9567ac06444SGeorgii Rymar Symbol.st_shndx = toSectionIndex(*Sym.Section, "", Sym.Name);
9573212ecfeSGeorge Rimar else if (Sym.Index)
958c22d9666SAlex Brachet Symbol.st_shndx = *Sym.Index;
9593212ecfeSGeorge Rimar
960129b531cSKazu Hirata Symbol.st_value = Sym.Value.value_or(yaml::Hex64(0));
9614e71702cSGeorge Rimar Symbol.st_other = Sym.Other ? *Sym.Other : 0;
962129b531cSKazu Hirata Symbol.st_size = Sym.Size.value_or(yaml::Hex64(0));
963c22d9666SAlex Brachet }
964c22d9666SAlex Brachet
965c22d9666SAlex Brachet return Ret;
966c22d9666SAlex Brachet }
967c22d9666SAlex Brachet
968c22d9666SAlex Brachet template <class ELFT>
initSymtabSectionHeader(Elf_Shdr & SHeader,SymtabType STType,ContiguousBlobAccumulator & CBA,ELFYAML::Section * YAMLSec)969c22d9666SAlex Brachet void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader,
970c22d9666SAlex Brachet SymtabType STType,
971c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA,
972c22d9666SAlex Brachet ELFYAML::Section *YAMLSec) {
973c22d9666SAlex Brachet
974c22d9666SAlex Brachet bool IsStatic = STType == SymtabType::Static;
9752779987dSGeorge Rimar ArrayRef<ELFYAML::Symbol> Symbols;
9762779987dSGeorge Rimar if (IsStatic && Doc.Symbols)
9772779987dSGeorge Rimar Symbols = *Doc.Symbols;
978daff7b85SGeorgii Rymar else if (!IsStatic && Doc.DynamicSymbols)
979daff7b85SGeorgii Rymar Symbols = *Doc.DynamicSymbols;
980c22d9666SAlex Brachet
981c22d9666SAlex Brachet ELFYAML::RawContentSection *RawSec =
982c22d9666SAlex Brachet dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec);
983daff7b85SGeorgii Rymar if (RawSec && (RawSec->Content || RawSec->Size)) {
984daff7b85SGeorgii Rymar bool HasSymbolsDescription =
985daff7b85SGeorgii Rymar (IsStatic && Doc.Symbols) || (!IsStatic && Doc.DynamicSymbols);
986daff7b85SGeorgii Rymar if (HasSymbolsDescription) {
987daff7b85SGeorgii Rymar StringRef Property = (IsStatic ? "`Symbols`" : "`DynamicSymbols`");
988c22d9666SAlex Brachet if (RawSec->Content)
989daff7b85SGeorgii Rymar reportError("cannot specify both `Content` and " + Property +
9903212ecfeSGeorge Rimar " for symbol table section '" + RawSec->Name + "'");
991c22d9666SAlex Brachet if (RawSec->Size)
992daff7b85SGeorgii Rymar reportError("cannot specify both `Size` and " + Property +
9933212ecfeSGeorge Rimar " for symbol table section '" + RawSec->Name + "'");
9943212ecfeSGeorge Rimar return;
995c22d9666SAlex Brachet }
996daff7b85SGeorgii Rymar }
997c22d9666SAlex Brachet
998c781e737SGeorgii Rymar SHeader.sh_name = getSectionNameOffset(IsStatic ? ".symtab" : ".dynsym");
999c22d9666SAlex Brachet
1000c22d9666SAlex Brachet if (YAMLSec)
1001c22d9666SAlex Brachet SHeader.sh_type = YAMLSec->Type;
1002c22d9666SAlex Brachet else
1003c22d9666SAlex Brachet SHeader.sh_type = IsStatic ? ELF::SHT_SYMTAB : ELF::SHT_DYNSYM;
1004c22d9666SAlex Brachet
1005c22d9666SAlex Brachet if (YAMLSec && YAMLSec->Flags)
1006c22d9666SAlex Brachet SHeader.sh_flags = *YAMLSec->Flags;
1007c22d9666SAlex Brachet else if (!IsStatic)
1008c22d9666SAlex Brachet SHeader.sh_flags = ELF::SHF_ALLOC;
1009c22d9666SAlex Brachet
1010c22d9666SAlex Brachet // If the symbol table section is explicitly described in the YAML
1011c22d9666SAlex Brachet // then we should set the fields requested.
1012c22d9666SAlex Brachet SHeader.sh_info = (RawSec && RawSec->Info) ? (unsigned)(*RawSec->Info)
1013c22d9666SAlex Brachet : findFirstNonGlobal(Symbols) + 1;
1014c22d9666SAlex Brachet SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 8;
101531f2ad9cSGeorgii Rymar
101631f2ad9cSGeorgii Rymar assignSectionAddress(SHeader, YAMLSec);
1017c22d9666SAlex Brachet
1018edfb2f8bSGeorgii Rymar SHeader.sh_offset =
1019edfb2f8bSGeorgii Rymar alignToOffset(CBA, SHeader.sh_addralign, RawSec ? RawSec->Offset : None);
10207ccae2ceSGeorgii Rymar
1021c22d9666SAlex Brachet if (RawSec && (RawSec->Content || RawSec->Size)) {
1022c22d9666SAlex Brachet assert(Symbols.empty());
10233c123acfSGeorgii Rymar SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size);
1024c22d9666SAlex Brachet return;
1025c22d9666SAlex Brachet }
1026c22d9666SAlex Brachet
1027c22d9666SAlex Brachet std::vector<Elf_Sym> Syms =
10283212ecfeSGeorge Rimar toELFSymbols(Symbols, IsStatic ? DotStrtab : DotDynstr);
10293c123acfSGeorgii Rymar SHeader.sh_size = Syms.size() * sizeof(Elf_Sym);
10303c123acfSGeorgii Rymar CBA.write((const char *)Syms.data(), SHeader.sh_size);
1031c22d9666SAlex Brachet }
1032c22d9666SAlex Brachet
1033c22d9666SAlex Brachet template <class ELFT>
initStrtabSectionHeader(Elf_Shdr & SHeader,StringRef Name,StringTableBuilder & STB,ContiguousBlobAccumulator & CBA,ELFYAML::Section * YAMLSec)1034c22d9666SAlex Brachet void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,
1035c22d9666SAlex Brachet StringTableBuilder &STB,
1036c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA,
1037c22d9666SAlex Brachet ELFYAML::Section *YAMLSec) {
10385c1639feSJames Henderson SHeader.sh_name = getSectionNameOffset(ELFYAML::dropUniqueSuffix(Name));
1039c22d9666SAlex Brachet SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_STRTAB;
1040c22d9666SAlex Brachet SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1;
1041c22d9666SAlex Brachet
1042c22d9666SAlex Brachet ELFYAML::RawContentSection *RawSec =
1043c22d9666SAlex Brachet dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec);
1044c22d9666SAlex Brachet
10455ffafa87SGeorgii Rymar SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign,
10465ffafa87SGeorgii Rymar YAMLSec ? YAMLSec->Offset : None);
10477ccae2ceSGeorgii Rymar
1048c22d9666SAlex Brachet if (RawSec && (RawSec->Content || RawSec->Size)) {
10493c123acfSGeorgii Rymar SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size);
1050c22d9666SAlex Brachet } else {
10513c123acfSGeorgii Rymar if (raw_ostream *OS = CBA.getRawOS(STB.getSize()))
10523c123acfSGeorgii Rymar STB.write(*OS);
1053c22d9666SAlex Brachet SHeader.sh_size = STB.getSize();
1054c22d9666SAlex Brachet }
1055c22d9666SAlex Brachet
1056c22d9666SAlex Brachet if (RawSec && RawSec->Info)
1057c22d9666SAlex Brachet SHeader.sh_info = *RawSec->Info;
1058c22d9666SAlex Brachet
1059c22d9666SAlex Brachet if (YAMLSec && YAMLSec->Flags)
1060c22d9666SAlex Brachet SHeader.sh_flags = *YAMLSec->Flags;
1061c22d9666SAlex Brachet else if (Name == ".dynstr")
1062c22d9666SAlex Brachet SHeader.sh_flags = ELF::SHF_ALLOC;
1063c22d9666SAlex Brachet
106431f2ad9cSGeorgii Rymar assignSectionAddress(SHeader, YAMLSec);
1065c22d9666SAlex Brachet }
1066c22d9666SAlex Brachet
shouldEmitDWARF(DWARFYAML::Data & DWARF,StringRef Name)1067373e98a3SXing GUO static bool shouldEmitDWARF(DWARFYAML::Data &DWARF, StringRef Name) {
1068b1731da8SXing GUO SetVector<StringRef> DebugSecNames = DWARF.getNonEmptySectionNames();
1069373e98a3SXing GUO return Name.consume_front(".") && DebugSecNames.count(Name);
1070373e98a3SXing GUO }
1071373e98a3SXing GUO
1072373e98a3SXing GUO template <class ELFT>
emitDWARF(typename ELFT::Shdr & SHeader,StringRef Name,const DWARFYAML::Data & DWARF,ContiguousBlobAccumulator & CBA)10739939f231SXing GUO Expected<uint64_t> emitDWARF(typename ELFT::Shdr &SHeader, StringRef Name,
10746d242a73SXing GUO const DWARFYAML::Data &DWARF,
10753c123acfSGeorgii Rymar ContiguousBlobAccumulator &CBA) {
10763c123acfSGeorgii Rymar // We are unable to predict the size of debug data, so we request to write 0
10773c123acfSGeorgii Rymar // bytes. This should always return us an output stream unless CBA is already
10783c123acfSGeorgii Rymar // in an error state.
10793c123acfSGeorgii Rymar raw_ostream *OS = CBA.getRawOS(0);
10803c123acfSGeorgii Rymar if (!OS)
10813c123acfSGeorgii Rymar return 0;
10823c123acfSGeorgii Rymar
10833c123acfSGeorgii Rymar uint64_t BeginOffset = CBA.tell();
10849939f231SXing GUO
1085760e4f22SXing GUO auto EmitFunc = DWARFYAML::getDWARFEmitterByName(Name.substr(1));
1086760e4f22SXing GUO if (Error Err = EmitFunc(*OS, DWARF))
10879939f231SXing GUO return std::move(Err);
10889939f231SXing GUO
10893c123acfSGeorgii Rymar return CBA.tell() - BeginOffset;
1090373e98a3SXing GUO }
1091373e98a3SXing GUO
1092373e98a3SXing GUO template <class ELFT>
initDWARFSectionHeader(Elf_Shdr & SHeader,StringRef Name,ContiguousBlobAccumulator & CBA,ELFYAML::Section * YAMLSec)1093373e98a3SXing GUO void ELFState<ELFT>::initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name,
1094373e98a3SXing GUO ContiguousBlobAccumulator &CBA,
1095373e98a3SXing GUO ELFYAML::Section *YAMLSec) {
1096c781e737SGeorgii Rymar SHeader.sh_name = getSectionNameOffset(ELFYAML::dropUniqueSuffix(Name));
1097373e98a3SXing GUO SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_PROGBITS;
1098373e98a3SXing GUO SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1;
1099373e98a3SXing GUO SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign,
1100373e98a3SXing GUO YAMLSec ? YAMLSec->Offset : None);
1101373e98a3SXing GUO
1102373e98a3SXing GUO ELFYAML::RawContentSection *RawSec =
1103373e98a3SXing GUO dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec);
1104373e98a3SXing GUO if (Doc.DWARF && shouldEmitDWARF(*Doc.DWARF, Name)) {
1105373e98a3SXing GUO if (RawSec && (RawSec->Content || RawSec->Size))
1106373e98a3SXing GUO reportError("cannot specify section '" + Name +
1107373e98a3SXing GUO "' contents in the 'DWARF' entry and the 'Content' "
1108373e98a3SXing GUO "or 'Size' in the 'Sections' entry at the same time");
11099939f231SXing GUO else {
11109939f231SXing GUO if (Expected<uint64_t> ShSizeOrErr =
11113c123acfSGeorgii Rymar emitDWARF<ELFT>(SHeader, Name, *Doc.DWARF, CBA))
11129939f231SXing GUO SHeader.sh_size = *ShSizeOrErr;
1113373e98a3SXing GUO else
11149939f231SXing GUO reportError(ShSizeOrErr.takeError());
11159939f231SXing GUO }
1116373e98a3SXing GUO } else if (RawSec)
11173c123acfSGeorgii Rymar SHeader.sh_size = writeContent(CBA, RawSec->Content, RawSec->Size);
1118373e98a3SXing GUO else
1119373e98a3SXing GUO llvm_unreachable("debug sections can only be initialized via the 'DWARF' "
1120373e98a3SXing GUO "entry or a RawContentSection");
1121373e98a3SXing GUO
1122373e98a3SXing GUO if (RawSec && RawSec->Info)
1123373e98a3SXing GUO SHeader.sh_info = *RawSec->Info;
1124373e98a3SXing GUO
1125373e98a3SXing GUO if (YAMLSec && YAMLSec->Flags)
1126373e98a3SXing GUO SHeader.sh_flags = *YAMLSec->Flags;
1127373e98a3SXing GUO else if (Name == ".debug_str")
1128373e98a3SXing GUO SHeader.sh_flags = ELF::SHF_MERGE | ELF::SHF_STRINGS;
1129373e98a3SXing GUO
1130373e98a3SXing GUO assignSectionAddress(SHeader, YAMLSec);
1131373e98a3SXing GUO }
1132373e98a3SXing GUO
reportError(const Twine & Msg)11333212ecfeSGeorge Rimar template <class ELFT> void ELFState<ELFT>::reportError(const Twine &Msg) {
113485011027SGeorge Rimar ErrHandler(Msg);
11353212ecfeSGeorge Rimar HasError = true;
11363212ecfeSGeorge Rimar }
11373212ecfeSGeorge Rimar
reportError(Error Err)11389939f231SXing GUO template <class ELFT> void ELFState<ELFT>::reportError(Error Err) {
11399939f231SXing GUO handleAllErrors(std::move(Err), [&](const ErrorInfoBase &Err) {
11409939f231SXing GUO reportError(Err.message());
11419939f231SXing GUO });
11429939f231SXing GUO }
11439939f231SXing GUO
1144c22d9666SAlex Brachet template <class ELFT>
114506456daaSGeorgii Rymar std::vector<Fragment>
getPhdrFragments(const ELFYAML::ProgramHeader & Phdr,ArrayRef<Elf_Shdr> SHeaders)114606456daaSGeorgii Rymar ELFState<ELFT>::getPhdrFragments(const ELFYAML::ProgramHeader &Phdr,
11473d4c873aSGeorgii Rymar ArrayRef<Elf_Shdr> SHeaders) {
114806456daaSGeorgii Rymar std::vector<Fragment> Ret;
11493d4c873aSGeorgii Rymar for (const ELFYAML::Chunk *C : Phdr.Chunks) {
11503d4c873aSGeorgii Rymar if (const ELFYAML::Fill *F = dyn_cast<ELFYAML::Fill>(C)) {
11513d4c873aSGeorgii Rymar Ret.push_back({*F->Offset, F->Size, llvm::ELF::SHT_PROGBITS,
115206456daaSGeorgii Rymar /*ShAddrAlign=*/1});
115306456daaSGeorgii Rymar continue;
115406456daaSGeorgii Rymar }
115506456daaSGeorgii Rymar
11563d4c873aSGeorgii Rymar const ELFYAML::Section *S = cast<ELFYAML::Section>(C);
11573d4c873aSGeorgii Rymar const Elf_Shdr &H = SHeaders[SN2I.get(S->Name)];
11583d4c873aSGeorgii Rymar Ret.push_back({H.sh_offset, H.sh_size, H.sh_type, H.sh_addralign});
115906456daaSGeorgii Rymar }
116006456daaSGeorgii Rymar return Ret;
116106456daaSGeorgii Rymar }
116206456daaSGeorgii Rymar
116306456daaSGeorgii Rymar template <class ELFT>
setProgramHeaderLayout(std::vector<Elf_Phdr> & PHeaders,std::vector<Elf_Shdr> & SHeaders)1164c22d9666SAlex Brachet void ELFState<ELFT>::setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders,
1165c22d9666SAlex Brachet std::vector<Elf_Shdr> &SHeaders) {
1166c22d9666SAlex Brachet uint32_t PhdrIdx = 0;
1167c22d9666SAlex Brachet for (auto &YamlPhdr : Doc.ProgramHeaders) {
1168c22d9666SAlex Brachet Elf_Phdr &PHeader = PHeaders[PhdrIdx++];
116906456daaSGeorgii Rymar std::vector<Fragment> Fragments = getPhdrFragments(YamlPhdr, SHeaders);
11703471ae9dSGeorgii Rymar if (!llvm::is_sorted(Fragments, [](const Fragment &A, const Fragment &B) {
11713471ae9dSGeorgii Rymar return A.Offset < B.Offset;
11723471ae9dSGeorgii Rymar }))
11733471ae9dSGeorgii Rymar reportError("sections in the program header with index " +
11743471ae9dSGeorgii Rymar Twine(PhdrIdx) + " are not sorted by their file offset");
1175c22d9666SAlex Brachet
11762bf56743SGeorgii Rymar if (YamlPhdr.Offset) {
117734b3d5b6SGeorgii Rymar if (!Fragments.empty() && *YamlPhdr.Offset > Fragments.front().Offset)
11782bf56743SGeorgii Rymar reportError("'Offset' for segment with index " + Twine(PhdrIdx) +
11792bf56743SGeorgii Rymar " must be less than or equal to the minimum file offset of "
11802bf56743SGeorgii Rymar "all included sections (0x" +
118134b3d5b6SGeorgii Rymar Twine::utohexstr(Fragments.front().Offset) + ")");
118234b3d5b6SGeorgii Rymar PHeader.p_offset = *YamlPhdr.Offset;
118334b3d5b6SGeorgii Rymar } else if (!Fragments.empty()) {
118434b3d5b6SGeorgii Rymar PHeader.p_offset = Fragments.front().Offset;
11852bf56743SGeorgii Rymar }
1186c22d9666SAlex Brachet
11879f9a08e1SGeorgii Rymar // Set the file size if not set explicitly.
11889f9a08e1SGeorgii Rymar if (YamlPhdr.FileSize) {
11899f9a08e1SGeorgii Rymar PHeader.p_filesz = *YamlPhdr.FileSize;
11909f9a08e1SGeorgii Rymar } else if (!Fragments.empty()) {
11919f9a08e1SGeorgii Rymar uint64_t FileSize = Fragments.back().Offset - PHeader.p_offset;
11929f9a08e1SGeorgii Rymar // SHT_NOBITS sections occupy no physical space in a file, we should not
11939f9a08e1SGeorgii Rymar // take their sizes into account when calculating the file size of a
11949f9a08e1SGeorgii Rymar // segment.
11959f9a08e1SGeorgii Rymar if (Fragments.back().Type != llvm::ELF::SHT_NOBITS)
11969f9a08e1SGeorgii Rymar FileSize += Fragments.back().Size;
11979f9a08e1SGeorgii Rymar PHeader.p_filesz = FileSize;
1198c22d9666SAlex Brachet }
1199c22d9666SAlex Brachet
12009f9a08e1SGeorgii Rymar // Find the maximum offset of the end of a section in order to set p_memsz.
12019f9a08e1SGeorgii Rymar uint64_t MemOffset = PHeader.p_offset;
12029f9a08e1SGeorgii Rymar for (const Fragment &F : Fragments)
12039f9a08e1SGeorgii Rymar MemOffset = std::max(MemOffset, F.Offset + F.Size);
12049f9a08e1SGeorgii Rymar // Set the memory size if not set explicitly.
1205c28f3e6eSFangrui Song PHeader.p_memsz = YamlPhdr.MemSize ? uint64_t(*YamlPhdr.MemSize)
1206c28f3e6eSFangrui Song : MemOffset - PHeader.p_offset;
1207c22d9666SAlex Brachet
1208c22d9666SAlex Brachet if (YamlPhdr.Align) {
1209c22d9666SAlex Brachet PHeader.p_align = *YamlPhdr.Align;
1210c22d9666SAlex Brachet } else {
12111da4f471SFangrui Song // Set the alignment of the segment to be the maximum alignment of the
12121da4f471SFangrui Song // sections so that by default the segment has a valid and sensible
12131da4f471SFangrui Song // alignment.
1214c22d9666SAlex Brachet PHeader.p_align = 1;
121506456daaSGeorgii Rymar for (const Fragment &F : Fragments)
121606456daaSGeorgii Rymar PHeader.p_align = std::max((uint64_t)PHeader.p_align, F.AddrAlign);
1217c22d9666SAlex Brachet }
1218c22d9666SAlex Brachet }
1219c22d9666SAlex Brachet }
1220c22d9666SAlex Brachet
shouldAllocateFileSpace(ArrayRef<ELFYAML::ProgramHeader> Phdrs,const ELFYAML::NoBitsSection & S)12215edb90c9SGeorgii Rymar bool llvm::ELFYAML::shouldAllocateFileSpace(
12225edb90c9SGeorgii Rymar ArrayRef<ELFYAML::ProgramHeader> Phdrs, const ELFYAML::NoBitsSection &S) {
1223818ab3d6SGeorgii Rymar for (const ELFYAML::ProgramHeader &PH : Phdrs) {
1224818ab3d6SGeorgii Rymar auto It = llvm::find_if(
1225818ab3d6SGeorgii Rymar PH.Chunks, [&](ELFYAML::Chunk *C) { return C->Name == S.Name; });
1226818ab3d6SGeorgii Rymar if (std::any_of(It, PH.Chunks.end(), [](ELFYAML::Chunk *C) {
1227818ab3d6SGeorgii Rymar return (isa<ELFYAML::Fill>(C) ||
1228818ab3d6SGeorgii Rymar cast<ELFYAML::Section>(C)->Type != ELF::SHT_NOBITS);
1229818ab3d6SGeorgii Rymar }))
1230818ab3d6SGeorgii Rymar return true;
1231818ab3d6SGeorgii Rymar }
1232818ab3d6SGeorgii Rymar return false;
1233818ab3d6SGeorgii Rymar }
1234818ab3d6SGeorgii Rymar
1235818ab3d6SGeorgii Rymar template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::NoBitsSection & S,ContiguousBlobAccumulator & CBA)1236818ab3d6SGeorgii Rymar void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1237818ab3d6SGeorgii Rymar const ELFYAML::NoBitsSection &S,
1238818ab3d6SGeorgii Rymar ContiguousBlobAccumulator &CBA) {
1239400103f3SGeorgii Rymar if (!S.Size)
1240400103f3SGeorgii Rymar return;
1241400103f3SGeorgii Rymar
1242400103f3SGeorgii Rymar SHeader.sh_size = *S.Size;
1243818ab3d6SGeorgii Rymar
1244818ab3d6SGeorgii Rymar // When a nobits section is followed by a non-nobits section or fill
1245818ab3d6SGeorgii Rymar // in the same segment, we allocate the file space for it. This behavior
1246818ab3d6SGeorgii Rymar // matches linkers.
1247818ab3d6SGeorgii Rymar if (shouldAllocateFileSpace(Doc.ProgramHeaders, S))
1248400103f3SGeorgii Rymar CBA.writeZeros(*S.Size);
1249818ab3d6SGeorgii Rymar }
1250818ab3d6SGeorgii Rymar
1251c22d9666SAlex Brachet template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::RawContentSection & Section,ContiguousBlobAccumulator & CBA)12523212ecfeSGeorge Rimar void ELFState<ELFT>::writeSectionContent(
1253c22d9666SAlex Brachet Elf_Shdr &SHeader, const ELFYAML::RawContentSection &Section,
1254c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA) {
1255c22d9666SAlex Brachet if (Section.Info)
1256c22d9666SAlex Brachet SHeader.sh_info = *Section.Info;
1257c22d9666SAlex Brachet }
1258c22d9666SAlex Brachet
isMips64EL(const ELFYAML::Object & Obj)1259a6436b0bSGeorgii Rymar static bool isMips64EL(const ELFYAML::Object &Obj) {
1260a6436b0bSGeorgii Rymar return Obj.getMachine() == llvm::ELF::EM_MIPS &&
1261a6436b0bSGeorgii Rymar Obj.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64) &&
1262a6436b0bSGeorgii Rymar Obj.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB);
1263c22d9666SAlex Brachet }
1264c22d9666SAlex Brachet
1265c22d9666SAlex Brachet template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::RelocationSection & Section,ContiguousBlobAccumulator & CBA)12663212ecfeSGeorge Rimar void ELFState<ELFT>::writeSectionContent(
1267c22d9666SAlex Brachet Elf_Shdr &SHeader, const ELFYAML::RelocationSection &Section,
1268c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA) {
1269c22d9666SAlex Brachet assert((Section.Type == llvm::ELF::SHT_REL ||
1270c22d9666SAlex Brachet Section.Type == llvm::ELF::SHT_RELA) &&
1271c22d9666SAlex Brachet "Section type is not SHT_REL nor SHT_RELA");
1272c22d9666SAlex Brachet
12733212ecfeSGeorge Rimar if (!Section.RelocatableSec.empty())
12743212ecfeSGeorge Rimar SHeader.sh_info = toSectionIndex(Section.RelocatableSec, Section.Name);
1275c22d9666SAlex Brachet
1276400103f3SGeorgii Rymar if (!Section.Relocations)
1277400103f3SGeorgii Rymar return;
1278400103f3SGeorgii Rymar
12796d3098e7SGeorgii Rymar const bool IsRela = Section.Type == llvm::ELF::SHT_RELA;
1280400103f3SGeorgii Rymar for (const ELFYAML::Relocation &Rel : *Section.Relocations) {
12812bfaf195SGeorgii Rymar const bool IsDynamic = Section.Link && (*Section.Link == ".dynsym");
12822bfaf195SGeorgii Rymar unsigned SymIdx =
12832bfaf195SGeorgii Rymar Rel.Symbol ? toSymbolIndex(*Rel.Symbol, Section.Name, IsDynamic) : 0;
1284c22d9666SAlex Brachet if (IsRela) {
1285c22d9666SAlex Brachet Elf_Rela REntry;
1286c22d9666SAlex Brachet zero(REntry);
1287c22d9666SAlex Brachet REntry.r_offset = Rel.Offset;
1288c22d9666SAlex Brachet REntry.r_addend = Rel.Addend;
1289c22d9666SAlex Brachet REntry.setSymbolAndType(SymIdx, Rel.Type, isMips64EL(Doc));
12903c123acfSGeorgii Rymar CBA.write((const char *)&REntry, sizeof(REntry));
1291c22d9666SAlex Brachet } else {
1292c22d9666SAlex Brachet Elf_Rel REntry;
1293c22d9666SAlex Brachet zero(REntry);
1294c22d9666SAlex Brachet REntry.r_offset = Rel.Offset;
1295c22d9666SAlex Brachet REntry.setSymbolAndType(SymIdx, Rel.Type, isMips64EL(Doc));
12963c123acfSGeorgii Rymar CBA.write((const char *)&REntry, sizeof(REntry));
1297c22d9666SAlex Brachet }
1298c22d9666SAlex Brachet }
1299400103f3SGeorgii Rymar
1300400103f3SGeorgii Rymar SHeader.sh_size = (IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel)) *
1301400103f3SGeorgii Rymar Section.Relocations->size();
1302c22d9666SAlex Brachet }
1303c22d9666SAlex Brachet
1304c22d9666SAlex Brachet template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::RelrSection & Section,ContiguousBlobAccumulator & CBA)13057570d387SGeorgii Rymar void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
13067570d387SGeorgii Rymar const ELFYAML::RelrSection &Section,
13077570d387SGeorgii Rymar ContiguousBlobAccumulator &CBA) {
13087570d387SGeorgii Rymar if (!Section.Entries)
13097570d387SGeorgii Rymar return;
13107570d387SGeorgii Rymar
13117570d387SGeorgii Rymar for (llvm::yaml::Hex64 E : *Section.Entries) {
13127570d387SGeorgii Rymar if (!ELFT::Is64Bits && E > UINT32_MAX)
13137570d387SGeorgii Rymar reportError(Section.Name + ": the value is too large for 32-bits: 0x" +
13147570d387SGeorgii Rymar Twine::utohexstr(E));
13153c123acfSGeorgii Rymar CBA.write<uintX_t>(E, ELFT::TargetEndianness);
13167570d387SGeorgii Rymar }
13177570d387SGeorgii Rymar
13187570d387SGeorgii Rymar SHeader.sh_size = sizeof(uintX_t) * Section.Entries->size();
13197570d387SGeorgii Rymar }
13207570d387SGeorgii Rymar
13217570d387SGeorgii Rymar template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::SymtabShndxSection & Shndx,ContiguousBlobAccumulator & CBA)13223212ecfeSGeorge Rimar void ELFState<ELFT>::writeSectionContent(
1323d3963051SGeorge Rimar Elf_Shdr &SHeader, const ELFYAML::SymtabShndxSection &Shndx,
1324d3963051SGeorge Rimar ContiguousBlobAccumulator &CBA) {
1325400103f3SGeorgii Rymar if (Shndx.Content || Shndx.Size) {
1326400103f3SGeorgii Rymar SHeader.sh_size = writeContent(CBA, Shndx.Content, Shndx.Size);
1327400103f3SGeorgii Rymar return;
1328400103f3SGeorgii Rymar }
1329400103f3SGeorgii Rymar
1330400103f3SGeorgii Rymar if (!Shndx.Entries)
1331400103f3SGeorgii Rymar return;
1332400103f3SGeorgii Rymar
1333400103f3SGeorgii Rymar for (uint32_t E : *Shndx.Entries)
1334400103f3SGeorgii Rymar CBA.write<uint32_t>(E, ELFT::TargetEndianness);
1335400103f3SGeorgii Rymar SHeader.sh_size = Shndx.Entries->size() * SHeader.sh_entsize;
1336d3963051SGeorge Rimar }
1337d3963051SGeorge Rimar
1338d3963051SGeorge Rimar template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::GroupSection & Section,ContiguousBlobAccumulator & CBA)13393212ecfeSGeorge Rimar void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
134082311766SGeorgii Rymar const ELFYAML::GroupSection &Section,
1341c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA) {
1342c22d9666SAlex Brachet assert(Section.Type == llvm::ELF::SHT_GROUP &&
1343c22d9666SAlex Brachet "Section type is not SHT_GROUP");
1344c22d9666SAlex Brachet
13455b118a04SGeorgii Rymar if (Section.Signature)
13463212ecfeSGeorge Rimar SHeader.sh_info =
13475b118a04SGeorgii Rymar toSymbolIndex(*Section.Signature, Section.Name, /*IsDynamic=*/false);
1348c22d9666SAlex Brachet
1349400103f3SGeorgii Rymar if (!Section.Members)
1350400103f3SGeorgii Rymar return;
1351400103f3SGeorgii Rymar
1352400103f3SGeorgii Rymar for (const ELFYAML::SectionOrType &Member : *Section.Members) {
1353c22d9666SAlex Brachet unsigned int SectionIndex = 0;
1354c22d9666SAlex Brachet if (Member.sectionNameOrType == "GRP_COMDAT")
1355c22d9666SAlex Brachet SectionIndex = llvm::ELF::GRP_COMDAT;
13563212ecfeSGeorge Rimar else
13573212ecfeSGeorge Rimar SectionIndex = toSectionIndex(Member.sectionNameOrType, Section.Name);
13583c123acfSGeorgii Rymar CBA.write<uint32_t>(SectionIndex, ELFT::TargetEndianness);
1359c22d9666SAlex Brachet }
1360400103f3SGeorgii Rymar SHeader.sh_size = SHeader.sh_entsize * Section.Members->size();
1361c22d9666SAlex Brachet }
1362c22d9666SAlex Brachet
1363c22d9666SAlex Brachet template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::SymverSection & Section,ContiguousBlobAccumulator & CBA)13643212ecfeSGeorge Rimar void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1365c22d9666SAlex Brachet const ELFYAML::SymverSection &Section,
1366c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA) {
1367400103f3SGeorgii Rymar if (!Section.Entries)
1368400103f3SGeorgii Rymar return;
1369400103f3SGeorgii Rymar
1370400103f3SGeorgii Rymar for (uint16_t Version : *Section.Entries)
1371400103f3SGeorgii Rymar CBA.write<uint16_t>(Version, ELFT::TargetEndianness);
1372400103f3SGeorgii Rymar SHeader.sh_size = Section.Entries->size() * SHeader.sh_entsize;
1373c22d9666SAlex Brachet }
1374c22d9666SAlex Brachet
1375c22d9666SAlex Brachet template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::StackSizesSection & Section,ContiguousBlobAccumulator & CBA)13761a219aa8SGeorge Rimar void ELFState<ELFT>::writeSectionContent(
13771a219aa8SGeorge Rimar Elf_Shdr &SHeader, const ELFYAML::StackSizesSection &Section,
13781a219aa8SGeorge Rimar ContiguousBlobAccumulator &CBA) {
13793cfd9384SGeorgii Rymar if (!Section.Entries)
13801a219aa8SGeorge Rimar return;
13811a219aa8SGeorge Rimar
13821a219aa8SGeorge Rimar for (const ELFYAML::StackSizeEntry &E : *Section.Entries) {
13833c123acfSGeorgii Rymar CBA.write<uintX_t>(E.Address, ELFT::TargetEndianness);
13843c123acfSGeorgii Rymar SHeader.sh_size += sizeof(uintX_t) + CBA.writeULEB128(E.Size);
13851a219aa8SGeorge Rimar }
13861a219aa8SGeorge Rimar }
13871a219aa8SGeorge Rimar
13881a219aa8SGeorge Rimar template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::BBAddrMapSection & Section,ContiguousBlobAccumulator & CBA)1389dd101539SGeorgii Rymar void ELFState<ELFT>::writeSectionContent(
139082e7c4ceSRahman Lavaee Elf_Shdr &SHeader, const ELFYAML::BBAddrMapSection &Section,
139182e7c4ceSRahman Lavaee ContiguousBlobAccumulator &CBA) {
139282e7c4ceSRahman Lavaee if (!Section.Entries)
139382e7c4ceSRahman Lavaee return;
139482e7c4ceSRahman Lavaee
139582e7c4ceSRahman Lavaee for (const ELFYAML::BBAddrMapEntry &E : *Section.Entries) {
1396*0aa6df65SRahman Lavaee // Write version and feature values.
1397*0aa6df65SRahman Lavaee if (Section.Type == llvm::ELF::SHT_LLVM_BB_ADDR_MAP) {
1398*0aa6df65SRahman Lavaee if (E.Version > 1)
1399*0aa6df65SRahman Lavaee WithColor::warning() << "unsupported SHT_LLVM_BB_ADDR_MAP version: "
1400*0aa6df65SRahman Lavaee << static_cast<int>(E.Version)
1401*0aa6df65SRahman Lavaee << "; encoding using the most recent version";
1402*0aa6df65SRahman Lavaee CBA.write(E.Version);
1403*0aa6df65SRahman Lavaee CBA.write(E.Feature);
1404*0aa6df65SRahman Lavaee SHeader.sh_size += 2;
1405*0aa6df65SRahman Lavaee }
140682e7c4ceSRahman Lavaee // Write the address of the function.
140782e7c4ceSRahman Lavaee CBA.write<uintX_t>(E.Address, ELFT::TargetEndianness);
14080252e6eaSRahman Lavaee // Write number of BBEntries (number of basic blocks in the function). This
14099f527086SRahman Lavaee // is overridden by the 'NumBlocks' YAML field when specified.
1410c22d18b7SRahman Lavaee uint64_t NumBlocks =
1411129b531cSKazu Hirata E.NumBlocks.value_or(E.BBEntries ? E.BBEntries->size() : 0);
141282e7c4ceSRahman Lavaee SHeader.sh_size += sizeof(uintX_t) + CBA.writeULEB128(NumBlocks);
141382e7c4ceSRahman Lavaee // Write all BBEntries.
14140252e6eaSRahman Lavaee if (!E.BBEntries)
14150252e6eaSRahman Lavaee continue;
141682e7c4ceSRahman Lavaee for (const ELFYAML::BBAddrMapEntry::BBEntry &BBE : *E.BBEntries)
141782e7c4ceSRahman Lavaee SHeader.sh_size += CBA.writeULEB128(BBE.AddressOffset) +
141882e7c4ceSRahman Lavaee CBA.writeULEB128(BBE.Size) +
141982e7c4ceSRahman Lavaee CBA.writeULEB128(BBE.Metadata);
142082e7c4ceSRahman Lavaee }
142182e7c4ceSRahman Lavaee }
142282e7c4ceSRahman Lavaee
142382e7c4ceSRahman Lavaee template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::LinkerOptionsSection & Section,ContiguousBlobAccumulator & CBA)142482e7c4ceSRahman Lavaee void ELFState<ELFT>::writeSectionContent(
1425dd101539SGeorgii Rymar Elf_Shdr &SHeader, const ELFYAML::LinkerOptionsSection &Section,
1426dd101539SGeorgii Rymar ContiguousBlobAccumulator &CBA) {
1427dd101539SGeorgii Rymar if (!Section.Options)
1428dd101539SGeorgii Rymar return;
1429dd101539SGeorgii Rymar
1430dd101539SGeorgii Rymar for (const ELFYAML::LinkerOption &LO : *Section.Options) {
14313c123acfSGeorgii Rymar CBA.write(LO.Key.data(), LO.Key.size());
14323c123acfSGeorgii Rymar CBA.write('\0');
14333c123acfSGeorgii Rymar CBA.write(LO.Value.data(), LO.Value.size());
14343c123acfSGeorgii Rymar CBA.write('\0');
1435dd101539SGeorgii Rymar SHeader.sh_size += (LO.Key.size() + LO.Value.size() + 2);
1436dd101539SGeorgii Rymar }
1437dd101539SGeorgii Rymar }
1438dd101539SGeorgii Rymar
1439dd101539SGeorgii Rymar template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::DependentLibrariesSection & Section,ContiguousBlobAccumulator & CBA)14409659464dSGeorgii Rymar void ELFState<ELFT>::writeSectionContent(
14419659464dSGeorgii Rymar Elf_Shdr &SHeader, const ELFYAML::DependentLibrariesSection &Section,
14429659464dSGeorgii Rymar ContiguousBlobAccumulator &CBA) {
14439659464dSGeorgii Rymar if (!Section.Libs)
14449659464dSGeorgii Rymar return;
14459659464dSGeorgii Rymar
14469659464dSGeorgii Rymar for (StringRef Lib : *Section.Libs) {
14473c123acfSGeorgii Rymar CBA.write(Lib.data(), Lib.size());
14483c123acfSGeorgii Rymar CBA.write('\0');
14499659464dSGeorgii Rymar SHeader.sh_size += Lib.size() + 1;
14509659464dSGeorgii Rymar }
14519659464dSGeorgii Rymar }
14529659464dSGeorgii Rymar
14539659464dSGeorgii Rymar template <class ELFT>
14547ccae2ceSGeorgii Rymar uint64_t
alignToOffset(ContiguousBlobAccumulator & CBA,uint64_t Align,llvm::Optional<llvm::yaml::Hex64> Offset)14557ccae2ceSGeorgii Rymar ELFState<ELFT>::alignToOffset(ContiguousBlobAccumulator &CBA, uint64_t Align,
14567ccae2ceSGeorgii Rymar llvm::Optional<llvm::yaml::Hex64> Offset) {
14577ccae2ceSGeorgii Rymar uint64_t CurrentOffset = CBA.getOffset();
14587ccae2ceSGeorgii Rymar uint64_t AlignedOffset;
14597ccae2ceSGeorgii Rymar
14607ccae2ceSGeorgii Rymar if (Offset) {
14617ccae2ceSGeorgii Rymar if ((uint64_t)*Offset < CurrentOffset) {
14627ccae2ceSGeorgii Rymar reportError("the 'Offset' value (0x" +
14637ccae2ceSGeorgii Rymar Twine::utohexstr((uint64_t)*Offset) + ") goes backward");
14647ccae2ceSGeorgii Rymar return CurrentOffset;
14657ccae2ceSGeorgii Rymar }
14667ccae2ceSGeorgii Rymar
14677ccae2ceSGeorgii Rymar // We ignore an alignment when an explicit offset has been requested.
14687ccae2ceSGeorgii Rymar AlignedOffset = *Offset;
14697ccae2ceSGeorgii Rymar } else {
14707ccae2ceSGeorgii Rymar AlignedOffset = alignTo(CurrentOffset, std::max(Align, (uint64_t)1));
14717ccae2ceSGeorgii Rymar }
14727ccae2ceSGeorgii Rymar
14733c123acfSGeorgii Rymar CBA.writeZeros(AlignedOffset - CurrentOffset);
14747ccae2ceSGeorgii Rymar return AlignedOffset;
14757ccae2ceSGeorgii Rymar }
14767ccae2ceSGeorgii Rymar
14777ccae2ceSGeorgii Rymar template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::CallGraphProfileSection & Section,ContiguousBlobAccumulator & CBA)1478bec54e46SGeorgii Rymar void ELFState<ELFT>::writeSectionContent(
1479bec54e46SGeorgii Rymar Elf_Shdr &SHeader, const ELFYAML::CallGraphProfileSection &Section,
1480bec54e46SGeorgii Rymar ContiguousBlobAccumulator &CBA) {
1481bec54e46SGeorgii Rymar if (!Section.Entries)
1482bec54e46SGeorgii Rymar return;
1483bec54e46SGeorgii Rymar
1484a224c519SAlexander Yermolovich for (const ELFYAML::CallGraphEntryWeight &E : *Section.Entries) {
14853c123acfSGeorgii Rymar CBA.write<uint64_t>(E.Weight, ELFT::TargetEndianness);
1486a224c519SAlexander Yermolovich SHeader.sh_size += sizeof(object::Elf_CGProfile_Impl<ELFT>);
1487bec54e46SGeorgii Rymar }
1488bec54e46SGeorgii Rymar }
1489bec54e46SGeorgii Rymar
1490bec54e46SGeorgii Rymar template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::HashSection & Section,ContiguousBlobAccumulator & CBA)14913212ecfeSGeorge Rimar void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1492e5163ebfSGeorge Rimar const ELFYAML::HashSection &Section,
1493e5163ebfSGeorge Rimar ContiguousBlobAccumulator &CBA) {
14943cfd9384SGeorgii Rymar if (!Section.Bucket)
1495e5163ebfSGeorge Rimar return;
1496e5163ebfSGeorge Rimar
14973c123acfSGeorgii Rymar CBA.write<uint32_t>(
1498129b531cSKazu Hirata Section.NBucket.value_or(llvm::yaml::Hex64(Section.Bucket->size())),
1499e5163ebfSGeorge Rimar ELFT::TargetEndianness);
15003c123acfSGeorgii Rymar CBA.write<uint32_t>(
1501129b531cSKazu Hirata Section.NChain.value_or(llvm::yaml::Hex64(Section.Chain->size())),
1502e5163ebfSGeorge Rimar ELFT::TargetEndianness);
150393fc0ba1SGeorgii Rymar
1504e5163ebfSGeorge Rimar for (uint32_t Val : *Section.Bucket)
15053c123acfSGeorgii Rymar CBA.write<uint32_t>(Val, ELFT::TargetEndianness);
1506e5163ebfSGeorge Rimar for (uint32_t Val : *Section.Chain)
15073c123acfSGeorgii Rymar CBA.write<uint32_t>(Val, ELFT::TargetEndianness);
1508e5163ebfSGeorge Rimar
1509e5163ebfSGeorge Rimar SHeader.sh_size = (2 + Section.Bucket->size() + Section.Chain->size()) * 4;
1510e5163ebfSGeorge Rimar }
1511e5163ebfSGeorge Rimar
1512e5163ebfSGeorge Rimar template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::VerdefSection & Section,ContiguousBlobAccumulator & CBA)1513e5163ebfSGeorge Rimar void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1514c22d9666SAlex Brachet const ELFYAML::VerdefSection &Section,
1515c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA) {
151651f49580SGeorgii Rymar
151751f49580SGeorgii Rymar if (Section.Info)
151851f49580SGeorgii Rymar SHeader.sh_info = *Section.Info;
151951f49580SGeorgii Rymar else if (Section.Entries)
152051f49580SGeorgii Rymar SHeader.sh_info = Section.Entries->size();
152151f49580SGeorgii Rymar
1522f69ac55dSGeorgii Rymar if (!Section.Entries)
1523f69ac55dSGeorgii Rymar return;
1524f69ac55dSGeorgii Rymar
1525c22d9666SAlex Brachet uint64_t AuxCnt = 0;
1526f69ac55dSGeorgii Rymar for (size_t I = 0; I < Section.Entries->size(); ++I) {
1527f69ac55dSGeorgii Rymar const ELFYAML::VerdefEntry &E = (*Section.Entries)[I];
1528c22d9666SAlex Brachet
1529c22d9666SAlex Brachet Elf_Verdef VerDef;
1530129b531cSKazu Hirata VerDef.vd_version = E.Version.value_or(1);
1531129b531cSKazu Hirata VerDef.vd_flags = E.Flags.value_or(0);
1532129b531cSKazu Hirata VerDef.vd_ndx = E.VersionNdx.value_or(0);
1533129b531cSKazu Hirata VerDef.vd_hash = E.Hash.value_or(0);
1534c22d9666SAlex Brachet VerDef.vd_aux = sizeof(Elf_Verdef);
1535c22d9666SAlex Brachet VerDef.vd_cnt = E.VerNames.size();
1536f69ac55dSGeorgii Rymar if (I == Section.Entries->size() - 1)
1537c22d9666SAlex Brachet VerDef.vd_next = 0;
1538c22d9666SAlex Brachet else
1539c22d9666SAlex Brachet VerDef.vd_next =
1540c22d9666SAlex Brachet sizeof(Elf_Verdef) + E.VerNames.size() * sizeof(Elf_Verdaux);
15413c123acfSGeorgii Rymar CBA.write((const char *)&VerDef, sizeof(Elf_Verdef));
1542c22d9666SAlex Brachet
1543c22d9666SAlex Brachet for (size_t J = 0; J < E.VerNames.size(); ++J, ++AuxCnt) {
1544c22d9666SAlex Brachet Elf_Verdaux VernAux;
1545c22d9666SAlex Brachet VernAux.vda_name = DotDynstr.getOffset(E.VerNames[J]);
1546c22d9666SAlex Brachet if (J == E.VerNames.size() - 1)
1547c22d9666SAlex Brachet VernAux.vda_next = 0;
1548c22d9666SAlex Brachet else
1549c22d9666SAlex Brachet VernAux.vda_next = sizeof(Elf_Verdaux);
15503c123acfSGeorgii Rymar CBA.write((const char *)&VernAux, sizeof(Elf_Verdaux));
1551c22d9666SAlex Brachet }
1552c22d9666SAlex Brachet }
1553c22d9666SAlex Brachet
1554f69ac55dSGeorgii Rymar SHeader.sh_size = Section.Entries->size() * sizeof(Elf_Verdef) +
1555c22d9666SAlex Brachet AuxCnt * sizeof(Elf_Verdaux);
1556c22d9666SAlex Brachet }
1557c22d9666SAlex Brachet
1558c22d9666SAlex Brachet template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::VerneedSection & Section,ContiguousBlobAccumulator & CBA)15593212ecfeSGeorge Rimar void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1560c22d9666SAlex Brachet const ELFYAML::VerneedSection &Section,
1561c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA) {
156251f49580SGeorgii Rymar if (Section.Info)
156351f49580SGeorgii Rymar SHeader.sh_info = *Section.Info;
156451f49580SGeorgii Rymar else if (Section.VerneedV)
156551f49580SGeorgii Rymar SHeader.sh_info = Section.VerneedV->size();
156651f49580SGeorgii Rymar
156713cbcf1cSGeorgii Rymar if (!Section.VerneedV)
156813cbcf1cSGeorgii Rymar return;
1569c22d9666SAlex Brachet
1570c22d9666SAlex Brachet uint64_t AuxCnt = 0;
157113cbcf1cSGeorgii Rymar for (size_t I = 0; I < Section.VerneedV->size(); ++I) {
157213cbcf1cSGeorgii Rymar const ELFYAML::VerneedEntry &VE = (*Section.VerneedV)[I];
1573c22d9666SAlex Brachet
1574c22d9666SAlex Brachet Elf_Verneed VerNeed;
1575c22d9666SAlex Brachet VerNeed.vn_version = VE.Version;
1576c22d9666SAlex Brachet VerNeed.vn_file = DotDynstr.getOffset(VE.File);
157713cbcf1cSGeorgii Rymar if (I == Section.VerneedV->size() - 1)
1578c22d9666SAlex Brachet VerNeed.vn_next = 0;
1579c22d9666SAlex Brachet else
1580c22d9666SAlex Brachet VerNeed.vn_next =
1581c22d9666SAlex Brachet sizeof(Elf_Verneed) + VE.AuxV.size() * sizeof(Elf_Vernaux);
1582c22d9666SAlex Brachet VerNeed.vn_cnt = VE.AuxV.size();
1583c22d9666SAlex Brachet VerNeed.vn_aux = sizeof(Elf_Verneed);
15843c123acfSGeorgii Rymar CBA.write((const char *)&VerNeed, sizeof(Elf_Verneed));
1585c22d9666SAlex Brachet
1586c22d9666SAlex Brachet for (size_t J = 0; J < VE.AuxV.size(); ++J, ++AuxCnt) {
1587c22d9666SAlex Brachet const ELFYAML::VernauxEntry &VAuxE = VE.AuxV[J];
1588c22d9666SAlex Brachet
1589c22d9666SAlex Brachet Elf_Vernaux VernAux;
1590c22d9666SAlex Brachet VernAux.vna_hash = VAuxE.Hash;
1591c22d9666SAlex Brachet VernAux.vna_flags = VAuxE.Flags;
1592c22d9666SAlex Brachet VernAux.vna_other = VAuxE.Other;
1593c22d9666SAlex Brachet VernAux.vna_name = DotDynstr.getOffset(VAuxE.Name);
1594c22d9666SAlex Brachet if (J == VE.AuxV.size() - 1)
1595c22d9666SAlex Brachet VernAux.vna_next = 0;
1596c22d9666SAlex Brachet else
1597c22d9666SAlex Brachet VernAux.vna_next = sizeof(Elf_Vernaux);
15983c123acfSGeorgii Rymar CBA.write((const char *)&VernAux, sizeof(Elf_Vernaux));
1599c22d9666SAlex Brachet }
1600c22d9666SAlex Brachet }
1601c22d9666SAlex Brachet
160213cbcf1cSGeorgii Rymar SHeader.sh_size = Section.VerneedV->size() * sizeof(Elf_Verneed) +
1603c22d9666SAlex Brachet AuxCnt * sizeof(Elf_Vernaux);
1604c22d9666SAlex Brachet }
1605c22d9666SAlex Brachet
1606c22d9666SAlex Brachet template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::ARMIndexTableSection & Section,ContiguousBlobAccumulator & CBA)1607dab99171SGeorgii Rymar void ELFState<ELFT>::writeSectionContent(
1608dab99171SGeorgii Rymar Elf_Shdr &SHeader, const ELFYAML::ARMIndexTableSection &Section,
1609dab99171SGeorgii Rymar ContiguousBlobAccumulator &CBA) {
1610dab99171SGeorgii Rymar if (!Section.Entries)
1611dab99171SGeorgii Rymar return;
1612dab99171SGeorgii Rymar
1613dab99171SGeorgii Rymar for (const ELFYAML::ARMIndexTableEntry &E : *Section.Entries) {
1614dab99171SGeorgii Rymar CBA.write<uint32_t>(E.Offset, ELFT::TargetEndianness);
1615dab99171SGeorgii Rymar CBA.write<uint32_t>(E.Value, ELFT::TargetEndianness);
1616dab99171SGeorgii Rymar }
1617dab99171SGeorgii Rymar SHeader.sh_size = Section.Entries->size() * 8;
1618dab99171SGeorgii Rymar }
1619dab99171SGeorgii Rymar
1620dab99171SGeorgii Rymar template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::MipsABIFlags & Section,ContiguousBlobAccumulator & CBA)16213212ecfeSGeorge Rimar void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1622c22d9666SAlex Brachet const ELFYAML::MipsABIFlags &Section,
1623c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA) {
1624c22d9666SAlex Brachet assert(Section.Type == llvm::ELF::SHT_MIPS_ABIFLAGS &&
1625c22d9666SAlex Brachet "Section type is not SHT_MIPS_ABIFLAGS");
1626c22d9666SAlex Brachet
1627c22d9666SAlex Brachet object::Elf_Mips_ABIFlags<ELFT> Flags;
1628c22d9666SAlex Brachet zero(Flags);
1629c22d9666SAlex Brachet SHeader.sh_size = SHeader.sh_entsize;
1630c22d9666SAlex Brachet
1631c22d9666SAlex Brachet Flags.version = Section.Version;
1632c22d9666SAlex Brachet Flags.isa_level = Section.ISALevel;
1633c22d9666SAlex Brachet Flags.isa_rev = Section.ISARevision;
1634c22d9666SAlex Brachet Flags.gpr_size = Section.GPRSize;
1635c22d9666SAlex Brachet Flags.cpr1_size = Section.CPR1Size;
1636c22d9666SAlex Brachet Flags.cpr2_size = Section.CPR2Size;
1637c22d9666SAlex Brachet Flags.fp_abi = Section.FpABI;
1638c22d9666SAlex Brachet Flags.isa_ext = Section.ISAExtension;
1639c22d9666SAlex Brachet Flags.ases = Section.ASEs;
1640c22d9666SAlex Brachet Flags.flags1 = Section.Flags1;
1641c22d9666SAlex Brachet Flags.flags2 = Section.Flags2;
16423c123acfSGeorgii Rymar CBA.write((const char *)&Flags, sizeof(Flags));
1643c22d9666SAlex Brachet }
1644c22d9666SAlex Brachet
1645c22d9666SAlex Brachet template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::DynamicSection & Section,ContiguousBlobAccumulator & CBA)16463212ecfeSGeorge Rimar void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1647c22d9666SAlex Brachet const ELFYAML::DynamicSection &Section,
1648c22d9666SAlex Brachet ContiguousBlobAccumulator &CBA) {
1649c22d9666SAlex Brachet assert(Section.Type == llvm::ELF::SHT_DYNAMIC &&
1650c22d9666SAlex Brachet "Section type is not SHT_DYNAMIC");
1651c22d9666SAlex Brachet
1652400103f3SGeorgii Rymar if (!Section.Entries)
1653400103f3SGeorgii Rymar return;
1654400103f3SGeorgii Rymar
1655400103f3SGeorgii Rymar for (const ELFYAML::DynamicEntry &DE : *Section.Entries) {
16563c123acfSGeorgii Rymar CBA.write<uintX_t>(DE.Tag, ELFT::TargetEndianness);
16573c123acfSGeorgii Rymar CBA.write<uintX_t>(DE.Val, ELFT::TargetEndianness);
1658c22d9666SAlex Brachet }
1659400103f3SGeorgii Rymar SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries->size();
1660c22d9666SAlex Brachet }
1661c22d9666SAlex Brachet
1662fc9104d4SGeorge Rimar template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::AddrsigSection & Section,ContiguousBlobAccumulator & CBA)1663fc9104d4SGeorge Rimar void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1664fc9104d4SGeorge Rimar const ELFYAML::AddrsigSection &Section,
1665fc9104d4SGeorge Rimar ContiguousBlobAccumulator &CBA) {
16663cfd9384SGeorgii Rymar if (!Section.Symbols)
1667fc9104d4SGeorge Rimar return;
1668fc9104d4SGeorge Rimar
166960f161ebSGeorgii Rymar for (StringRef Sym : *Section.Symbols)
16703c123acfSGeorgii Rymar SHeader.sh_size +=
16713c123acfSGeorgii Rymar CBA.writeULEB128(toSymbolIndex(Sym, Section.Name, /*IsDynamic=*/false));
1672fc9104d4SGeorge Rimar }
1673fc9104d4SGeorge Rimar
1674de3cef1dSgeorgerim template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::NoteSection & Section,ContiguousBlobAccumulator & CBA)1675de3cef1dSgeorgerim void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1676de3cef1dSgeorgerim const ELFYAML::NoteSection &Section,
1677de3cef1dSgeorgerim ContiguousBlobAccumulator &CBA) {
1678d8bb30c5SGeorgii Rymar if (!Section.Notes)
1679d8bb30c5SGeorgii Rymar return;
1680d8bb30c5SGeorgii Rymar
16813cfd9384SGeorgii Rymar uint64_t Offset = CBA.tell();
1682de3cef1dSgeorgerim for (const ELFYAML::NoteEntry &NE : *Section.Notes) {
1683de3cef1dSgeorgerim // Write name size.
1684de3cef1dSgeorgerim if (NE.Name.empty())
16853c123acfSGeorgii Rymar CBA.write<uint32_t>(0, ELFT::TargetEndianness);
1686de3cef1dSgeorgerim else
16873c123acfSGeorgii Rymar CBA.write<uint32_t>(NE.Name.size() + 1, ELFT::TargetEndianness);
1688de3cef1dSgeorgerim
1689de3cef1dSgeorgerim // Write description size.
1690de3cef1dSgeorgerim if (NE.Desc.binary_size() == 0)
16913c123acfSGeorgii Rymar CBA.write<uint32_t>(0, ELFT::TargetEndianness);
1692de3cef1dSgeorgerim else
16933c123acfSGeorgii Rymar CBA.write<uint32_t>(NE.Desc.binary_size(), ELFT::TargetEndianness);
1694de3cef1dSgeorgerim
1695de3cef1dSgeorgerim // Write type.
16963c123acfSGeorgii Rymar CBA.write<uint32_t>(NE.Type, ELFT::TargetEndianness);
1697de3cef1dSgeorgerim
1698de3cef1dSgeorgerim // Write name, null terminator and padding.
1699de3cef1dSgeorgerim if (!NE.Name.empty()) {
17003c123acfSGeorgii Rymar CBA.write(NE.Name.data(), NE.Name.size());
17013c123acfSGeorgii Rymar CBA.write('\0');
1702de3cef1dSgeorgerim CBA.padToAlignment(4);
1703de3cef1dSgeorgerim }
1704de3cef1dSgeorgerim
1705de3cef1dSgeorgerim // Write description and padding.
1706de3cef1dSgeorgerim if (NE.Desc.binary_size() != 0) {
17073c123acfSGeorgii Rymar CBA.writeAsBinary(NE.Desc);
1708de3cef1dSgeorgerim CBA.padToAlignment(4);
1709de3cef1dSgeorgerim }
1710de3cef1dSgeorgerim }
1711de3cef1dSgeorgerim
17123c123acfSGeorgii Rymar SHeader.sh_size = CBA.tell() - Offset;
1713de3cef1dSgeorgerim }
1714de3cef1dSgeorgerim
1715a7aee6c4Sgeorgerim template <class ELFT>
writeSectionContent(Elf_Shdr & SHeader,const ELFYAML::GnuHashSection & Section,ContiguousBlobAccumulator & CBA)1716a7aee6c4Sgeorgerim void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1717a7aee6c4Sgeorgerim const ELFYAML::GnuHashSection &Section,
1718a7aee6c4Sgeorgerim ContiguousBlobAccumulator &CBA) {
17193cfd9384SGeorgii Rymar if (!Section.HashBuckets)
1720a7aee6c4Sgeorgerim return;
1721a7aee6c4Sgeorgerim
1722d8bb30c5SGeorgii Rymar if (!Section.Header)
1723d8bb30c5SGeorgii Rymar return;
1724d8bb30c5SGeorgii Rymar
1725a7aee6c4Sgeorgerim // We write the header first, starting with the hash buckets count. Normally
1726a7aee6c4Sgeorgerim // it is the number of entries in HashBuckets, but the "NBuckets" property can
1727a7aee6c4Sgeorgerim // be used to override this field, which is useful for producing broken
1728a7aee6c4Sgeorgerim // objects.
1729a7aee6c4Sgeorgerim if (Section.Header->NBuckets)
17303c123acfSGeorgii Rymar CBA.write<uint32_t>(*Section.Header->NBuckets, ELFT::TargetEndianness);
1731a7aee6c4Sgeorgerim else
17323c123acfSGeorgii Rymar CBA.write<uint32_t>(Section.HashBuckets->size(), ELFT::TargetEndianness);
1733a7aee6c4Sgeorgerim
1734a7aee6c4Sgeorgerim // Write the index of the first symbol in the dynamic symbol table accessible
1735a7aee6c4Sgeorgerim // via the hash table.
17363c123acfSGeorgii Rymar CBA.write<uint32_t>(Section.Header->SymNdx, ELFT::TargetEndianness);
1737a7aee6c4Sgeorgerim
1738a7aee6c4Sgeorgerim // Write the number of words in the Bloom filter. As above, the "MaskWords"
1739a7aee6c4Sgeorgerim // property can be used to set this field to any value.
1740a7aee6c4Sgeorgerim if (Section.Header->MaskWords)
17413c123acfSGeorgii Rymar CBA.write<uint32_t>(*Section.Header->MaskWords, ELFT::TargetEndianness);
1742a7aee6c4Sgeorgerim else
17433c123acfSGeorgii Rymar CBA.write<uint32_t>(Section.BloomFilter->size(), ELFT::TargetEndianness);
1744a7aee6c4Sgeorgerim
1745a7aee6c4Sgeorgerim // Write the shift constant used by the Bloom filter.
17463c123acfSGeorgii Rymar CBA.write<uint32_t>(Section.Header->Shift2, ELFT::TargetEndianness);
1747a7aee6c4Sgeorgerim
1748a7aee6c4Sgeorgerim // We've finished writing the header. Now write the Bloom filter.
1749a7aee6c4Sgeorgerim for (llvm::yaml::Hex64 Val : *Section.BloomFilter)
17503c123acfSGeorgii Rymar CBA.write<uintX_t>(Val, ELFT::TargetEndianness);
1751a7aee6c4Sgeorgerim
1752a7aee6c4Sgeorgerim // Write an array of hash buckets.
1753a7aee6c4Sgeorgerim for (llvm::yaml::Hex32 Val : *Section.HashBuckets)
17543c123acfSGeorgii Rymar CBA.write<uint32_t>(Val, ELFT::TargetEndianness);
1755a7aee6c4Sgeorgerim
1756a7aee6c4Sgeorgerim // Write an array of hash values.
1757a7aee6c4Sgeorgerim for (llvm::yaml::Hex32 Val : *Section.HashValues)
17583c123acfSGeorgii Rymar CBA.write<uint32_t>(Val, ELFT::TargetEndianness);
1759a7aee6c4Sgeorgerim
1760a7aee6c4Sgeorgerim SHeader.sh_size = 16 /*Header size*/ +
1761a7aee6c4Sgeorgerim Section.BloomFilter->size() * sizeof(typename ELFT::uint) +
1762a7aee6c4Sgeorgerim Section.HashBuckets->size() * 4 +
1763a7aee6c4Sgeorgerim Section.HashValues->size() * 4;
1764a7aee6c4Sgeorgerim }
1765a7aee6c4Sgeorgerim
176606456daaSGeorgii Rymar template <class ELFT>
writeFill(ELFYAML::Fill & Fill,ContiguousBlobAccumulator & CBA)176706456daaSGeorgii Rymar void ELFState<ELFT>::writeFill(ELFYAML::Fill &Fill,
176806456daaSGeorgii Rymar ContiguousBlobAccumulator &CBA) {
176906456daaSGeorgii Rymar size_t PatternSize = Fill.Pattern ? Fill.Pattern->binary_size() : 0;
177006456daaSGeorgii Rymar if (!PatternSize) {
17713c123acfSGeorgii Rymar CBA.writeZeros(Fill.Size);
177206456daaSGeorgii Rymar return;
177306456daaSGeorgii Rymar }
177406456daaSGeorgii Rymar
177506456daaSGeorgii Rymar // Fill the content with the specified pattern.
177606456daaSGeorgii Rymar uint64_t Written = 0;
177706456daaSGeorgii Rymar for (; Written + PatternSize <= Fill.Size; Written += PatternSize)
17783c123acfSGeorgii Rymar CBA.writeAsBinary(*Fill.Pattern);
17793c123acfSGeorgii Rymar CBA.writeAsBinary(*Fill.Pattern, Fill.Size - Written);
178006456daaSGeorgii Rymar }
178106456daaSGeorgii Rymar
1782ad07d5f3SGeorgii Rymar template <class ELFT>
buildSectionHeaderReorderMap()1783ad07d5f3SGeorgii Rymar DenseMap<StringRef, size_t> ELFState<ELFT>::buildSectionHeaderReorderMap() {
17849c89dcf8SGeorgii Rymar const ELFYAML::SectionHeaderTable &SectionHeaders =
17859c89dcf8SGeorgii Rymar Doc.getSectionHeaderTable();
178668195b15SGeorgii Rymar if (SectionHeaders.IsImplicit || SectionHeaders.NoHeaders ||
178768195b15SGeorgii Rymar SectionHeaders.isDefault())
1788ad07d5f3SGeorgii Rymar return DenseMap<StringRef, size_t>();
1789ad07d5f3SGeorgii Rymar
1790ad07d5f3SGeorgii Rymar DenseMap<StringRef, size_t> Ret;
1791ad07d5f3SGeorgii Rymar size_t SecNdx = 0;
1792ad07d5f3SGeorgii Rymar StringSet<> Seen;
1793c781e737SGeorgii Rymar
1794c781e737SGeorgii Rymar auto AddSection = [&](const ELFYAML::SectionHeader &Hdr) {
1795ad07d5f3SGeorgii Rymar if (!Ret.try_emplace(Hdr.Name, ++SecNdx).second)
1796ad07d5f3SGeorgii Rymar reportError("repeated section name: '" + Hdr.Name +
1797ad07d5f3SGeorgii Rymar "' in the section header description");
1798ad07d5f3SGeorgii Rymar Seen.insert(Hdr.Name);
1799c781e737SGeorgii Rymar };
1800c781e737SGeorgii Rymar
18019c89dcf8SGeorgii Rymar if (SectionHeaders.Sections)
18029c89dcf8SGeorgii Rymar for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Sections)
1803c781e737SGeorgii Rymar AddSection(Hdr);
1804c781e737SGeorgii Rymar
18059c89dcf8SGeorgii Rymar if (SectionHeaders.Excluded)
18069c89dcf8SGeorgii Rymar for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Excluded)
1807c781e737SGeorgii Rymar AddSection(Hdr);
1808ad07d5f3SGeorgii Rymar
1809ad07d5f3SGeorgii Rymar for (const ELFYAML::Section *S : Doc.getSections()) {
1810ad07d5f3SGeorgii Rymar // Ignore special first SHT_NULL section.
1811ad07d5f3SGeorgii Rymar if (S == Doc.getSections().front())
1812ad07d5f3SGeorgii Rymar continue;
1813ad07d5f3SGeorgii Rymar if (!Seen.count(S->Name))
1814ad07d5f3SGeorgii Rymar reportError("section '" + S->Name +
1815c781e737SGeorgii Rymar "' should be present in the 'Sections' or 'Excluded' lists");
1816ad07d5f3SGeorgii Rymar Seen.erase(S->Name);
1817ad07d5f3SGeorgii Rymar }
1818ad07d5f3SGeorgii Rymar
1819ad07d5f3SGeorgii Rymar for (const auto &It : Seen)
1820ad07d5f3SGeorgii Rymar reportError("section header contains undefined section '" + It.getKey() +
1821ad07d5f3SGeorgii Rymar "'");
1822ad07d5f3SGeorgii Rymar return Ret;
1823ad07d5f3SGeorgii Rymar }
1824ad07d5f3SGeorgii Rymar
buildSectionIndex()18253212ecfeSGeorge Rimar template <class ELFT> void ELFState<ELFT>::buildSectionIndex() {
1826c781e737SGeorgii Rymar // A YAML description can have an explicit section header declaration that
1827c781e737SGeorgii Rymar // allows to change the order of section headers.
1828ad07d5f3SGeorgii Rymar DenseMap<StringRef, size_t> ReorderMap = buildSectionHeaderReorderMap();
1829ad07d5f3SGeorgii Rymar
1830c781e737SGeorgii Rymar if (HasError)
1831c781e737SGeorgii Rymar return;
1832c781e737SGeorgii Rymar
1833c781e737SGeorgii Rymar // Build excluded section headers map.
1834ec4e68e6SGeorgii Rymar std::vector<ELFYAML::Section *> Sections = Doc.getSections();
18359c89dcf8SGeorgii Rymar const ELFYAML::SectionHeaderTable &SectionHeaders =
18369c89dcf8SGeorgii Rymar Doc.getSectionHeaderTable();
18379c89dcf8SGeorgii Rymar if (SectionHeaders.Excluded)
18389c89dcf8SGeorgii Rymar for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Excluded)
1839c781e737SGeorgii Rymar if (!ExcludedSectionHeaders.insert(Hdr.Name).second)
1840c781e737SGeorgii Rymar llvm_unreachable("buildSectionIndex() failed");
1841c781e737SGeorgii Rymar
1842129b531cSKazu Hirata if (SectionHeaders.NoHeaders.value_or(false))
1843ec4e68e6SGeorgii Rymar for (const ELFYAML::Section *S : Sections)
1844ec4e68e6SGeorgii Rymar if (!ExcludedSectionHeaders.insert(S->Name).second)
1845ec4e68e6SGeorgii Rymar llvm_unreachable("buildSectionIndex() failed");
1846ec4e68e6SGeorgii Rymar
184706456daaSGeorgii Rymar size_t SecNdx = -1;
1848ec4e68e6SGeorgii Rymar for (const ELFYAML::Section *S : Sections) {
1849304b0ed4SGeorgii Rymar ++SecNdx;
185006456daaSGeorgii Rymar
1851c781e737SGeorgii Rymar size_t Index = ReorderMap.empty() ? SecNdx : ReorderMap.lookup(S->Name);
1852c781e737SGeorgii Rymar if (!SN2I.addName(S->Name, Index))
185306456daaSGeorgii Rymar llvm_unreachable("buildSectionIndex() failed");
1854c781e737SGeorgii Rymar
1855c781e737SGeorgii Rymar if (!ExcludedSectionHeaders.count(S->Name))
18565c1639feSJames Henderson ShStrtabStrings->add(ELFYAML::dropUniqueSuffix(S->Name));
1857c22d9666SAlex Brachet }
1858c22d9666SAlex Brachet }
1859c22d9666SAlex Brachet
buildSymbolIndexes()18603212ecfeSGeorge Rimar template <class ELFT> void ELFState<ELFT>::buildSymbolIndexes() {
18613212ecfeSGeorge Rimar auto Build = [this](ArrayRef<ELFYAML::Symbol> V, NameToIdxMap &Map) {
1862de0bc448SGeorge Rimar for (size_t I = 0, S = V.size(); I < S; ++I) {
1863de0bc448SGeorge Rimar const ELFYAML::Symbol &Sym = V[I];
18643212ecfeSGeorge Rimar if (!Sym.Name.empty() && !Map.addName(Sym.Name, I + 1))
18653212ecfeSGeorge Rimar reportError("repeated symbol name: '" + Sym.Name + "'");
1866c22d9666SAlex Brachet }
18673212ecfeSGeorge Rimar };
1868c22d9666SAlex Brachet
18692779987dSGeorge Rimar if (Doc.Symbols)
18702779987dSGeorge Rimar Build(*Doc.Symbols, SymN2I);
1871daff7b85SGeorgii Rymar if (Doc.DynamicSymbols)
1872daff7b85SGeorgii Rymar Build(*Doc.DynamicSymbols, DynSymN2I);
187391208447SGeorge Rimar }
187491208447SGeorge Rimar
finalizeStrings()1875c22d9666SAlex Brachet template <class ELFT> void ELFState<ELFT>::finalizeStrings() {
1876c22d9666SAlex Brachet // Add the regular symbol names to .strtab section.
18772779987dSGeorge Rimar if (Doc.Symbols)
18782779987dSGeorge Rimar for (const ELFYAML::Symbol &Sym : *Doc.Symbols)
1879cfc2bccfSGeorge Rimar DotStrtab.add(ELFYAML::dropUniqueSuffix(Sym.Name));
1880c22d9666SAlex Brachet DotStrtab.finalize();
1881c22d9666SAlex Brachet
1882c22d9666SAlex Brachet // Add the dynamic symbol names to .dynstr section.
1883daff7b85SGeorgii Rymar if (Doc.DynamicSymbols)
1884daff7b85SGeorgii Rymar for (const ELFYAML::Symbol &Sym : *Doc.DynamicSymbols)
1885cfc2bccfSGeorge Rimar DotDynstr.add(ELFYAML::dropUniqueSuffix(Sym.Name));
1886c22d9666SAlex Brachet
1887c22d9666SAlex Brachet // SHT_GNU_verdef and SHT_GNU_verneed sections might also
1888c22d9666SAlex Brachet // add strings to .dynstr section.
188906456daaSGeorgii Rymar for (const ELFYAML::Chunk *Sec : Doc.getSections()) {
189006456daaSGeorgii Rymar if (auto VerNeed = dyn_cast<ELFYAML::VerneedSection>(Sec)) {
189113cbcf1cSGeorgii Rymar if (VerNeed->VerneedV) {
189213cbcf1cSGeorgii Rymar for (const ELFYAML::VerneedEntry &VE : *VerNeed->VerneedV) {
1893c22d9666SAlex Brachet DotDynstr.add(VE.File);
1894c22d9666SAlex Brachet for (const ELFYAML::VernauxEntry &Aux : VE.AuxV)
1895c22d9666SAlex Brachet DotDynstr.add(Aux.Name);
1896c22d9666SAlex Brachet }
189713cbcf1cSGeorgii Rymar }
189806456daaSGeorgii Rymar } else if (auto VerDef = dyn_cast<ELFYAML::VerdefSection>(Sec)) {
1899f69ac55dSGeorgii Rymar if (VerDef->Entries)
1900f69ac55dSGeorgii Rymar for (const ELFYAML::VerdefEntry &E : *VerDef->Entries)
1901c22d9666SAlex Brachet for (StringRef Name : E.VerNames)
1902c22d9666SAlex Brachet DotDynstr.add(Name);
1903c22d9666SAlex Brachet }
1904c22d9666SAlex Brachet }
1905c22d9666SAlex Brachet
1906c22d9666SAlex Brachet DotDynstr.finalize();
19075c1639feSJames Henderson
19085c1639feSJames Henderson // Don't finalize the section header string table a second time if it has
19095c1639feSJames Henderson // already been finalized due to being one of the symbol string tables.
19105c1639feSJames Henderson if (ShStrtabStrings != &DotStrtab && ShStrtabStrings != &DotDynstr)
19115c1639feSJames Henderson ShStrtabStrings->finalize();
1912c22d9666SAlex Brachet }
1913c22d9666SAlex Brachet
1914c22d9666SAlex Brachet template <class ELFT>
writeELF(raw_ostream & OS,ELFYAML::Object & Doc,yaml::ErrorHandler EH,uint64_t MaxSize)191585011027SGeorge Rimar bool ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc,
19163c123acfSGeorgii Rymar yaml::ErrorHandler EH, uint64_t MaxSize) {
191785011027SGeorge Rimar ELFState<ELFT> State(Doc, EH);
1918304b0ed4SGeorgii Rymar if (State.HasError)
1919304b0ed4SGeorgii Rymar return false;
1920c22d9666SAlex Brachet
19215c1639feSJames Henderson // Build the section index, which adds sections to the section header string
1922b9ce8ea4SJames Henderson // table first, so that we can finalize the section header string table.
19233212ecfeSGeorge Rimar State.buildSectionIndex();
19243212ecfeSGeorge Rimar State.buildSymbolIndexes();
1925c22d9666SAlex Brachet
19265c1639feSJames Henderson // Finalize section header string table and the .strtab and .dynstr sections.
19275c1639feSJames Henderson // We do this early because we want to finalize the string table builders
19285c1639feSJames Henderson // before writing the content of the sections that might want to use them.
19295c1639feSJames Henderson State.finalizeStrings();
19305c1639feSJames Henderson
1931c781e737SGeorgii Rymar if (State.HasError)
1932c781e737SGeorgii Rymar return false;
1933c781e737SGeorgii Rymar
1934c22d9666SAlex Brachet std::vector<Elf_Phdr> PHeaders;
1935c22d9666SAlex Brachet State.initProgramHeaders(PHeaders);
1936c22d9666SAlex Brachet
1937c22d9666SAlex Brachet // XXX: This offset is tightly coupled with the order that we write
1938c22d9666SAlex Brachet // things to `OS`.
1939c3bc6979SFangrui Song const size_t SectionContentBeginOffset =
1940c3bc6979SFangrui Song sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * Doc.ProgramHeaders.size();
19413c123acfSGeorgii Rymar // It is quite easy to accidentally create output with yaml2obj that is larger
19423c123acfSGeorgii Rymar // than intended, for example, due to an issue in the YAML description.
19433c123acfSGeorgii Rymar // We limit the maximum allowed output size, but also provide a command line
19443c123acfSGeorgii Rymar // option to change this limitation.
19453c123acfSGeorgii Rymar ContiguousBlobAccumulator CBA(SectionContentBeginOffset, MaxSize);
1946c22d9666SAlex Brachet
1947c22d9666SAlex Brachet std::vector<Elf_Shdr> SHeaders;
19483212ecfeSGeorge Rimar State.initSectionHeaders(SHeaders, CBA);
1949c22d9666SAlex Brachet
195064df7084Sgeorgerim // Now we can decide segment offsets.
1951c22d9666SAlex Brachet State.setProgramHeaderLayout(PHeaders, SHeaders);
1952c22d9666SAlex Brachet
19539c89dcf8SGeorgii Rymar bool ReachedLimit = CBA.getOffset() > MaxSize;
19543c123acfSGeorgii Rymar if (Error E = CBA.takeLimitError()) {
19553c123acfSGeorgii Rymar // We report a custom error message instead below.
19563c123acfSGeorgii Rymar consumeError(std::move(E));
19573c123acfSGeorgii Rymar ReachedLimit = true;
19583c123acfSGeorgii Rymar }
19593c123acfSGeorgii Rymar
19603c123acfSGeorgii Rymar if (ReachedLimit)
19613c123acfSGeorgii Rymar State.reportError(
19623c123acfSGeorgii Rymar "the desired output size is greater than permitted. Use the "
19633c123acfSGeorgii Rymar "--max-size option to change the limit");
19643c123acfSGeorgii Rymar
19653212ecfeSGeorge Rimar if (State.HasError)
19667da559f2SGeorge Rimar return false;
19673212ecfeSGeorge Rimar
19689c89dcf8SGeorgii Rymar State.writeELFHeader(OS);
1969c22d9666SAlex Brachet writeArrayData(OS, makeArrayRef(PHeaders));
19709c89dcf8SGeorgii Rymar
19719c89dcf8SGeorgii Rymar const ELFYAML::SectionHeaderTable &SHT = Doc.getSectionHeaderTable();
1972129b531cSKazu Hirata if (!SHT.NoHeaders.value_or(false))
19739c89dcf8SGeorgii Rymar CBA.updateDataAt(*SHT.Offset, SHeaders.data(),
19749c89dcf8SGeorgii Rymar SHT.getNumHeaders(SHeaders.size()) * sizeof(Elf_Shdr));
19759c89dcf8SGeorgii Rymar
1976c22d9666SAlex Brachet CBA.writeBlobToStream(OS);
19777da559f2SGeorge Rimar return true;
1978c22d9666SAlex Brachet }
1979c22d9666SAlex Brachet
1980c22d9666SAlex Brachet namespace llvm {
1981c22d9666SAlex Brachet namespace yaml {
1982c22d9666SAlex Brachet
yaml2elf(llvm::ELFYAML::Object & Doc,raw_ostream & Out,ErrorHandler EH,uint64_t MaxSize)19833c123acfSGeorgii Rymar bool yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH,
19843c123acfSGeorgii Rymar uint64_t MaxSize) {
1985c22d9666SAlex Brachet bool IsLE = Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB);
1986c22d9666SAlex Brachet bool Is64Bit = Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64);
1987c22d9666SAlex Brachet if (Is64Bit) {
1988c22d9666SAlex Brachet if (IsLE)
19893c123acfSGeorgii Rymar return ELFState<object::ELF64LE>::writeELF(Out, Doc, EH, MaxSize);
19903c123acfSGeorgii Rymar return ELFState<object::ELF64BE>::writeELF(Out, Doc, EH, MaxSize);
1991c22d9666SAlex Brachet }
1992c22d9666SAlex Brachet if (IsLE)
19933c123acfSGeorgii Rymar return ELFState<object::ELF32LE>::writeELF(Out, Doc, EH, MaxSize);
19943c123acfSGeorgii Rymar return ELFState<object::ELF32BE>::writeELF(Out, Doc, EH, MaxSize);
1995c22d9666SAlex Brachet }
1996c22d9666SAlex Brachet
1997c22d9666SAlex Brachet } // namespace yaml
1998c22d9666SAlex Brachet } // namespace llvm
1999