1//===- yaml2elf - Convert YAML to a ELF object file -----------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// The ELF component of yaml2obj.
11///
12//===----------------------------------------------------------------------===//
13
14#include "llvm/ADT/ArrayRef.h"
15#include "llvm/ADT/DenseMap.h"
16#include "llvm/ADT/SetVector.h"
17#include "llvm/ADT/StringSet.h"
18#include "llvm/BinaryFormat/ELF.h"
19#include "llvm/MC/StringTableBuilder.h"
20#include "llvm/Object/ELFTypes.h"
21#include "llvm/ObjectYAML/ContiguousBlobAccumulator.h"
22#include "llvm/ObjectYAML/DWARFEmitter.h"
23#include "llvm/ObjectYAML/DWARFYAML.h"
24#include "llvm/ObjectYAML/ELFYAML.h"
25#include "llvm/ObjectYAML/yaml2obj.h"
26#include "llvm/Support/Error.h"
27#include "llvm/Support/WithColor.h"
28#include "llvm/Support/YAMLTraits.h"
29#include "llvm/Support/raw_ostream.h"
30#include <optional>
31
32using namespace llvm;
33using llvm::yaml::ContiguousBlobAccumulator;
34
35namespace {
36// Used to keep track of section and symbol names, so that in the YAML file
37// sections and symbols can be referenced by name instead of by index.
38class NameToIdxMap {
39 StringMap<unsigned> Map;
40
41public:
42 /// \Returns false if name is already present in the map.
43 bool addName(StringRef Name, unsigned Ndx) {
44 return Map.insert(KV: {Name, Ndx}).second;
45 }
46 /// \Returns false if name is not present in the map.
47 bool lookup(StringRef Name, unsigned &Idx) const {
48 auto I = Map.find(Key: Name);
49 if (I == Map.end())
50 return false;
51 Idx = I->getValue();
52 return true;
53 }
54 /// Asserts if name is not present in the map.
55 unsigned get(StringRef Name) const {
56 unsigned Idx;
57 if (lookup(Name, Idx))
58 return Idx;
59 assert(false && "Expected section not found in index");
60 return 0;
61 }
62 unsigned size() const { return Map.size(); }
63};
64
65namespace {
66struct Fragment {
67 uint64_t Offset;
68 uint64_t Size;
69 uint32_t Type;
70 uint64_t AddrAlign;
71};
72} // namespace
73
74/// "Single point of truth" for the ELF file construction.
75/// TODO: This class still has a ways to go before it is truly a "single
76/// point of truth".
77template <class ELFT> class ELFState {
78 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
79
80 enum class SymtabType { Static, Dynamic };
81
82 /// The future symbol table string section.
83 StringTableBuilder DotStrtab{StringTableBuilder::ELF};
84
85 /// The future section header string table section, if a unique string table
86 /// is needed. Don't reference this variable direectly: use the
87 /// ShStrtabStrings member instead.
88 StringTableBuilder DotShStrtab{StringTableBuilder::ELF};
89
90 /// The future dynamic symbol string section.
91 StringTableBuilder DotDynstr{StringTableBuilder::ELF};
92
93 /// The name of the section header string table section. If it is .strtab or
94 /// .dynstr, the section header strings will be written to the same string
95 /// table as the static/dynamic symbols respectively. Otherwise a dedicated
96 /// section will be created with that name.
97 StringRef SectionHeaderStringTableName = ".shstrtab";
98 StringTableBuilder *ShStrtabStrings = &DotShStrtab;
99
100 NameToIdxMap SN2I;
101 NameToIdxMap SymN2I;
102 NameToIdxMap DynSymN2I;
103 ELFYAML::Object &Doc;
104
105 std::vector<std::pair<Elf_Shdr *, ELFYAML::Section>>
106 SectionHeadersOverrideHelper;
107
108 StringSet<> ExcludedSectionHeaders;
109
110 uint64_t LocationCounter = 0;
111 bool HasError = false;
112 yaml::ErrorHandler ErrHandler;
113 void reportError(const Twine &Msg);
114 void reportError(Error Err);
115
116 std::vector<Elf_Sym> toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols,
117 const StringTableBuilder &Strtab);
118 unsigned toSectionIndex(StringRef S, StringRef LocSec, StringRef LocSym = "");
119 unsigned toSymbolIndex(StringRef S, StringRef LocSec, bool IsDynamic);
120
121 void buildSectionIndex();
122 void buildSymbolIndexes();
123 void initProgramHeaders(std::vector<Elf_Phdr> &PHeaders);
124 bool initImplicitHeader(ContiguousBlobAccumulator &CBA, Elf_Shdr &Header,
125 StringRef SecName, ELFYAML::Section *YAMLSec);
126 void initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
127 ContiguousBlobAccumulator &CBA);
128 void overrideSectionHeaders(std::vector<Elf_Shdr> &SHeaders);
129 void initSymtabSectionHeader(Elf_Shdr &SHeader, SymtabType STType,
130 ContiguousBlobAccumulator &CBA,
131 ELFYAML::Section *YAMLSec);
132 void initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,
133 StringTableBuilder &STB,
134 ContiguousBlobAccumulator &CBA,
135 ELFYAML::Section *YAMLSec);
136 void initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name,
137 ContiguousBlobAccumulator &CBA,
138 ELFYAML::Section *YAMLSec);
139 void setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders,
140 std::vector<Elf_Shdr> &SHeaders);
141
142 std::vector<Fragment>
143 getPhdrFragments(const ELFYAML::ProgramHeader &Phdr,
144 ArrayRef<typename ELFT::Shdr> SHeaders);
145
146 void finalizeStrings();
147 void writeELFHeader(raw_ostream &OS);
148 void writeSectionContent(Elf_Shdr &SHeader,
149 const ELFYAML::NoBitsSection &Section,
150 ContiguousBlobAccumulator &CBA);
151 void writeSectionContent(Elf_Shdr &SHeader,
152 const ELFYAML::RawContentSection &Section,
153 ContiguousBlobAccumulator &CBA);
154 void writeSectionContent(Elf_Shdr &SHeader,
155 const ELFYAML::RelocationSection &Section,
156 ContiguousBlobAccumulator &CBA);
157 void writeSectionContent(Elf_Shdr &SHeader,
158 const ELFYAML::RelrSection &Section,
159 ContiguousBlobAccumulator &CBA);
160 void writeSectionContent(Elf_Shdr &SHeader,
161 const ELFYAML::GroupSection &Group,
162 ContiguousBlobAccumulator &CBA);
163 void writeSectionContent(Elf_Shdr &SHeader,
164 const ELFYAML::SymtabShndxSection &Shndx,
165 ContiguousBlobAccumulator &CBA);
166 void writeSectionContent(Elf_Shdr &SHeader,
167 const ELFYAML::SymverSection &Section,
168 ContiguousBlobAccumulator &CBA);
169 void writeSectionContent(Elf_Shdr &SHeader,
170 const ELFYAML::VerneedSection &Section,
171 ContiguousBlobAccumulator &CBA);
172 void writeSectionContent(Elf_Shdr &SHeader,
173 const ELFYAML::VerdefSection &Section,
174 ContiguousBlobAccumulator &CBA);
175 void writeSectionContent(Elf_Shdr &SHeader,
176 const ELFYAML::ARMIndexTableSection &Section,
177 ContiguousBlobAccumulator &CBA);
178 void writeSectionContent(Elf_Shdr &SHeader,
179 const ELFYAML::MipsABIFlags &Section,
180 ContiguousBlobAccumulator &CBA);
181 void writeSectionContent(Elf_Shdr &SHeader,
182 const ELFYAML::DynamicSection &Section,
183 ContiguousBlobAccumulator &CBA);
184 void writeSectionContent(Elf_Shdr &SHeader,
185 const ELFYAML::StackSizesSection &Section,
186 ContiguousBlobAccumulator &CBA);
187 void writeSectionContent(Elf_Shdr &SHeader,
188 const ELFYAML::BBAddrMapSection &Section,
189 ContiguousBlobAccumulator &CBA);
190 void writeSectionContent(Elf_Shdr &SHeader,
191 const ELFYAML::HashSection &Section,
192 ContiguousBlobAccumulator &CBA);
193 void writeSectionContent(Elf_Shdr &SHeader,
194 const ELFYAML::AddrsigSection &Section,
195 ContiguousBlobAccumulator &CBA);
196 void writeSectionContent(Elf_Shdr &SHeader,
197 const ELFYAML::NoteSection &Section,
198 ContiguousBlobAccumulator &CBA);
199 void writeSectionContent(Elf_Shdr &SHeader,
200 const ELFYAML::GnuHashSection &Section,
201 ContiguousBlobAccumulator &CBA);
202 void writeSectionContent(Elf_Shdr &SHeader,
203 const ELFYAML::LinkerOptionsSection &Section,
204 ContiguousBlobAccumulator &CBA);
205 void writeSectionContent(Elf_Shdr &SHeader,
206 const ELFYAML::DependentLibrariesSection &Section,
207 ContiguousBlobAccumulator &CBA);
208 void writeSectionContent(Elf_Shdr &SHeader,
209 const ELFYAML::CallGraphProfileSection &Section,
210 ContiguousBlobAccumulator &CBA);
211
212 void writeFill(ELFYAML::Fill &Fill, ContiguousBlobAccumulator &CBA);
213
214 ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH);
215
216 void assignSectionAddress(Elf_Shdr &SHeader, ELFYAML::Section *YAMLSec);
217
218 DenseMap<StringRef, size_t> buildSectionHeaderReorderMap();
219
220 BumpPtrAllocator StringAlloc;
221 uint64_t alignToOffset(ContiguousBlobAccumulator &CBA, uint64_t Align,
222 std::optional<llvm::yaml::Hex64> Offset);
223
224 uint64_t getSectionNameOffset(StringRef Name);
225
226public:
227 static bool writeELF(raw_ostream &OS, ELFYAML::Object &Doc,
228 yaml::ErrorHandler EH, uint64_t MaxSize);
229};
230} // end anonymous namespace
231
232template <class T> static size_t arrayDataSize(ArrayRef<T> A) {
233 return A.size() * sizeof(T);
234}
235
236template <class T> static void writeArrayData(raw_ostream &OS, ArrayRef<T> A) {
237 OS.write((const char *)A.data(), arrayDataSize(A));
238}
239
240template <class T> static void zero(T &Obj) { memset(&Obj, 0, sizeof(Obj)); }
241
242template <class ELFT>
243ELFState<ELFT>::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH)
244 : Doc(D), ErrHandler(EH) {
245 // The input may explicitly request to store the section header table strings
246 // in the same string table as dynamic or static symbol names. Set the
247 // ShStrtabStrings member accordingly.
248 if (Doc.Header.SectionHeaderStringTable) {
249 SectionHeaderStringTableName = *Doc.Header.SectionHeaderStringTable;
250 if (*Doc.Header.SectionHeaderStringTable == ".strtab")
251 ShStrtabStrings = &DotStrtab;
252 else if (*Doc.Header.SectionHeaderStringTable == ".dynstr")
253 ShStrtabStrings = &DotDynstr;
254 // Otherwise, the unique table will be used.
255 }
256
257 std::vector<ELFYAML::Section *> Sections = Doc.getSections();
258 // Insert SHT_NULL section implicitly when it is not defined in YAML.
259 if (Sections.empty() || Sections.front()->Type != ELF::SHT_NULL)
260 Doc.Chunks.insert(
261 position: Doc.Chunks.begin(),
262 x: std::make_unique<ELFYAML::Section>(
263 args: ELFYAML::Chunk::ChunkKind::RawContent, /*IsImplicit=*/args: true));
264
265 StringSet<> DocSections;
266 ELFYAML::SectionHeaderTable *SecHdrTable = nullptr;
267 for (size_t I = 0; I < Doc.Chunks.size(); ++I) {
268 const std::unique_ptr<ELFYAML::Chunk> &C = Doc.Chunks[I];
269
270 // We might have an explicit section header table declaration.
271 if (auto S = dyn_cast<ELFYAML::SectionHeaderTable>(Val: C.get())) {
272 if (SecHdrTable)
273 reportError("multiple section header tables are not allowed");
274 SecHdrTable = S;
275 continue;
276 }
277
278 // We add a technical suffix for each unnamed section/fill. It does not
279 // affect the output, but allows us to map them by name in the code and
280 // report better error messages.
281 if (C->Name.empty()) {
282 std::string NewName = ELFYAML::appendUniqueSuffix(
283 /*Name=*/"", Msg: "index " + Twine(I));
284 C->Name = StringRef(NewName).copy(A&: StringAlloc);
285 assert(ELFYAML::dropUniqueSuffix(C->Name).empty());
286 }
287
288 if (!DocSections.insert(key: C->Name).second)
289 reportError("repeated section/fill name: '" + C->Name +
290 "' at YAML section/fill number " + Twine(I));
291 }
292
293 SmallSetVector<StringRef, 8> ImplicitSections;
294 if (Doc.DynamicSymbols) {
295 if (SectionHeaderStringTableName == ".dynsym")
296 reportError("cannot use '.dynsym' as the section header name table when "
297 "there are dynamic symbols");
298 ImplicitSections.insert(X: ".dynsym");
299 ImplicitSections.insert(X: ".dynstr");
300 }
301 if (Doc.Symbols) {
302 if (SectionHeaderStringTableName == ".symtab")
303 reportError("cannot use '.symtab' as the section header name table when "
304 "there are symbols");
305 ImplicitSections.insert(X: ".symtab");
306 }
307 if (Doc.DWARF)
308 for (StringRef DebugSecName : Doc.DWARF->getNonEmptySectionNames()) {
309 std::string SecName = ("." + DebugSecName).str();
310 // TODO: For .debug_str it should be possible to share the string table,
311 // in the same manner as the symbol string tables.
312 if (SectionHeaderStringTableName == SecName)
313 reportError("cannot use '" + SecName +
314 "' as the section header name table when it is needed for "
315 "DWARF output");
316 ImplicitSections.insert(X: StringRef(SecName).copy(A&: StringAlloc));
317 }
318 // TODO: Only create the .strtab here if any symbols have been requested.
319 ImplicitSections.insert(X: ".strtab");
320 if (!SecHdrTable || !SecHdrTable->NoHeaders.value_or(u: false))
321 ImplicitSections.insert(X: SectionHeaderStringTableName);
322
323 // Insert placeholders for implicit sections that are not
324 // defined explicitly in YAML.
325 for (StringRef SecName : ImplicitSections) {
326 if (DocSections.count(Key: SecName))
327 continue;
328
329 std::unique_ptr<ELFYAML::Section> Sec = std::make_unique<ELFYAML::Section>(
330 args: ELFYAML::Chunk::ChunkKind::RawContent, args: true /*IsImplicit*/);
331 Sec->Name = SecName;
332
333 if (SecName == SectionHeaderStringTableName)
334 Sec->Type = ELF::SHT_STRTAB;
335 else if (SecName == ".dynsym")
336 Sec->Type = ELF::SHT_DYNSYM;
337 else if (SecName == ".symtab")
338 Sec->Type = ELF::SHT_SYMTAB;
339 else
340 Sec->Type = ELF::SHT_STRTAB;
341
342 // When the section header table is explicitly defined at the end of the
343 // sections list, it is reasonable to assume that the user wants to reorder
344 // section headers, but still wants to place the section header table after
345 // all sections, like it normally happens. In this case we want to insert
346 // other implicit sections right before the section header table.
347 if (Doc.Chunks.back().get() == SecHdrTable)
348 Doc.Chunks.insert(position: Doc.Chunks.end() - 1, x: std::move(Sec));
349 else
350 Doc.Chunks.push_back(x: std::move(Sec));
351 }
352
353 // Insert the section header table implicitly at the end, when it is not
354 // explicitly defined.
355 if (!SecHdrTable)
356 Doc.Chunks.push_back(
357 x: std::make_unique<ELFYAML::SectionHeaderTable>(/*IsImplicit=*/args: true));
358}
359
360template <class ELFT>
361void ELFState<ELFT>::writeELFHeader(raw_ostream &OS) {
362 using namespace llvm::ELF;
363
364 Elf_Ehdr Header;
365 zero(Header);
366 Header.e_ident[EI_MAG0] = 0x7f;
367 Header.e_ident[EI_MAG1] = 'E';
368 Header.e_ident[EI_MAG2] = 'L';
369 Header.e_ident[EI_MAG3] = 'F';
370 Header.e_ident[EI_CLASS] = ELFT::Is64Bits ? ELFCLASS64 : ELFCLASS32;
371 Header.e_ident[EI_DATA] = Doc.Header.Data;
372 Header.e_ident[EI_VERSION] = EV_CURRENT;
373 Header.e_ident[EI_OSABI] = Doc.Header.OSABI;
374 Header.e_ident[EI_ABIVERSION] = Doc.Header.ABIVersion;
375 Header.e_type = Doc.Header.Type;
376
377 if (Doc.Header.Machine)
378 Header.e_machine = *Doc.Header.Machine;
379 else
380 Header.e_machine = EM_NONE;
381
382 Header.e_version = EV_CURRENT;
383 Header.e_entry = Doc.Header.Entry;
384 if (Doc.Header.Flags)
385 Header.e_flags = *Doc.Header.Flags;
386 else
387 Header.e_flags = 0;
388
389 Header.e_ehsize = sizeof(Elf_Ehdr);
390
391 if (Doc.Header.EPhOff)
392 Header.e_phoff = *Doc.Header.EPhOff;
393 else if (!Doc.ProgramHeaders.empty())
394 Header.e_phoff = sizeof(Header);
395 else
396 Header.e_phoff = 0;
397
398 if (Doc.Header.EPhEntSize)
399 Header.e_phentsize = *Doc.Header.EPhEntSize;
400 else if (!Doc.ProgramHeaders.empty())
401 Header.e_phentsize = sizeof(Elf_Phdr);
402 else
403 Header.e_phentsize = 0;
404
405 if (Doc.Header.EPhNum)
406 Header.e_phnum = *Doc.Header.EPhNum;
407 else if (!Doc.ProgramHeaders.empty())
408 Header.e_phnum = Doc.ProgramHeaders.size();
409 else
410 Header.e_phnum = 0;
411
412 Header.e_shentsize = Doc.Header.EShEntSize ? (uint16_t)*Doc.Header.EShEntSize
413 : sizeof(Elf_Shdr);
414
415 const ELFYAML::SectionHeaderTable &SectionHeaders =
416 Doc.getSectionHeaderTable();
417
418 if (Doc.Header.EShOff)
419 Header.e_shoff = *Doc.Header.EShOff;
420 else if (SectionHeaders.Offset)
421 Header.e_shoff = *SectionHeaders.Offset;
422 else
423 Header.e_shoff = 0;
424
425 if (Doc.Header.EShNum)
426 Header.e_shnum = *Doc.Header.EShNum;
427 else
428 Header.e_shnum = SectionHeaders.getNumHeaders(SectionsNum: Doc.getSections().size());
429
430 if (Doc.Header.EShStrNdx)
431 Header.e_shstrndx = *Doc.Header.EShStrNdx;
432 else if (SectionHeaders.Offset &&
433 !ExcludedSectionHeaders.count(Key: SectionHeaderStringTableName))
434 Header.e_shstrndx = SN2I.get(Name: SectionHeaderStringTableName);
435 else
436 Header.e_shstrndx = 0;
437
438 OS.write(Ptr: (const char *)&Header, Size: sizeof(Header));
439}
440
441template <class ELFT>
442void ELFState<ELFT>::initProgramHeaders(std::vector<Elf_Phdr> &PHeaders) {
443 DenseMap<StringRef, size_t> NameToIndex;
444 for (size_t I = 0, E = Doc.Chunks.size(); I != E; ++I) {
445 NameToIndex[Doc.Chunks[I]->Name] = I + 1;
446 }
447
448 for (size_t I = 0, E = Doc.ProgramHeaders.size(); I != E; ++I) {
449 ELFYAML::ProgramHeader &YamlPhdr = Doc.ProgramHeaders[I];
450 Elf_Phdr Phdr;
451 zero(Phdr);
452 Phdr.p_type = YamlPhdr.Type;
453 Phdr.p_flags = YamlPhdr.Flags;
454 Phdr.p_vaddr = YamlPhdr.VAddr;
455 Phdr.p_paddr = YamlPhdr.PAddr;
456 PHeaders.push_back(Phdr);
457
458 if (!YamlPhdr.FirstSec && !YamlPhdr.LastSec)
459 continue;
460
461 // Get the index of the section, or 0 in the case when the section doesn't exist.
462 size_t First = NameToIndex[*YamlPhdr.FirstSec];
463 if (!First)
464 reportError("unknown section or fill referenced: '" + *YamlPhdr.FirstSec +
465 "' by the 'FirstSec' key of the program header with index " +
466 Twine(I));
467 size_t Last = NameToIndex[*YamlPhdr.LastSec];
468 if (!Last)
469 reportError("unknown section or fill referenced: '" + *YamlPhdr.LastSec +
470 "' by the 'LastSec' key of the program header with index " +
471 Twine(I));
472 if (!First || !Last)
473 continue;
474
475 if (First > Last)
476 reportError("program header with index " + Twine(I) +
477 ": the section index of " + *YamlPhdr.FirstSec +
478 " is greater than the index of " + *YamlPhdr.LastSec);
479
480 for (size_t I = First; I <= Last; ++I)
481 YamlPhdr.Chunks.push_back(x: Doc.Chunks[I - 1].get());
482 }
483}
484
485template <class ELFT>
486unsigned ELFState<ELFT>::toSectionIndex(StringRef S, StringRef LocSec,
487 StringRef LocSym) {
488 assert(LocSec.empty() || LocSym.empty());
489
490 unsigned Index;
491 if (!SN2I.lookup(Name: S, Idx&: Index) && !to_integer(S, Num&: Index)) {
492 if (!LocSym.empty())
493 reportError("unknown section referenced: '" + S + "' by YAML symbol '" +
494 LocSym + "'");
495 else
496 reportError("unknown section referenced: '" + S + "' by YAML section '" +
497 LocSec + "'");
498 return 0;
499 }
500
501 const ELFYAML::SectionHeaderTable &SectionHeaders =
502 Doc.getSectionHeaderTable();
503 if (SectionHeaders.IsImplicit ||
504 (SectionHeaders.NoHeaders && !*SectionHeaders.NoHeaders) ||
505 SectionHeaders.isDefault())
506 return Index;
507
508 assert(!SectionHeaders.NoHeaders.value_or(false) || !SectionHeaders.Sections);
509 size_t FirstExcluded =
510 SectionHeaders.Sections ? SectionHeaders.Sections->size() : 0;
511 if (Index > FirstExcluded) {
512 if (LocSym.empty())
513 reportError("unable to link '" + LocSec + "' to excluded section '" + S +
514 "'");
515 else
516 reportError("excluded section referenced: '" + S + "' by symbol '" +
517 LocSym + "'");
518 }
519 return Index;
520}
521
522template <class ELFT>
523unsigned ELFState<ELFT>::toSymbolIndex(StringRef S, StringRef LocSec,
524 bool IsDynamic) {
525 const NameToIdxMap &SymMap = IsDynamic ? DynSymN2I : SymN2I;
526 unsigned Index;
527 // Here we try to look up S in the symbol table. If it is not there,
528 // treat its value as a symbol index.
529 if (!SymMap.lookup(Name: S, Idx&: Index) && !to_integer(S, Num&: Index)) {
530 reportError("unknown symbol referenced: '" + S + "' by YAML section '" +
531 LocSec + "'");
532 return 0;
533 }
534 return Index;
535}
536
537template <class ELFT>
538static void overrideFields(ELFYAML::Section *From, typename ELFT::Shdr &To) {
539 if (!From)
540 return;
541 if (From->ShAddrAlign)
542 To.sh_addralign = *From->ShAddrAlign;
543 if (From->ShFlags)
544 To.sh_flags = *From->ShFlags;
545 if (From->ShName)
546 To.sh_name = *From->ShName;
547 if (From->ShOffset)
548 To.sh_offset = *From->ShOffset;
549 if (From->ShSize)
550 To.sh_size = *From->ShSize;
551 if (From->ShType)
552 To.sh_type = *From->ShType;
553}
554
555template <class ELFT>
556bool ELFState<ELFT>::initImplicitHeader(ContiguousBlobAccumulator &CBA,
557 Elf_Shdr &Header, StringRef SecName,
558 ELFYAML::Section *YAMLSec) {
559 // Check if the header was already initialized.
560 if (Header.sh_offset)
561 return false;
562
563 if (SecName == ".strtab")
564 initStrtabSectionHeader(SHeader&: Header, Name: SecName, STB&: DotStrtab, CBA, YAMLSec);
565 else if (SecName == ".dynstr")
566 initStrtabSectionHeader(SHeader&: Header, Name: SecName, STB&: DotDynstr, CBA, YAMLSec);
567 else if (SecName == SectionHeaderStringTableName)
568 initStrtabSectionHeader(SHeader&: Header, Name: SecName, STB&: *ShStrtabStrings, CBA, YAMLSec);
569 else if (SecName == ".symtab")
570 initSymtabSectionHeader(SHeader&: Header, STType: SymtabType::Static, CBA, YAMLSec);
571 else if (SecName == ".dynsym")
572 initSymtabSectionHeader(SHeader&: Header, STType: SymtabType::Dynamic, CBA, YAMLSec);
573 else if (SecName.starts_with(Prefix: ".debug_")) {
574 // If a ".debug_*" section's type is a preserved one, e.g., SHT_DYNAMIC, we
575 // will not treat it as a debug section.
576 if (YAMLSec && !isa<ELFYAML::RawContentSection>(Val: YAMLSec))
577 return false;
578 initDWARFSectionHeader(SHeader&: Header, Name: SecName, CBA, YAMLSec);
579 } else
580 return false;
581
582 LocationCounter += Header.sh_size;
583
584 // Override section fields if requested.
585 overrideFields<ELFT>(YAMLSec, Header);
586 return true;
587}
588
589constexpr char SuffixStart = '(';
590constexpr char SuffixEnd = ')';
591
592std::string llvm::ELFYAML::appendUniqueSuffix(StringRef Name,
593 const Twine &Msg) {
594 // Do not add a space when a Name is empty.
595 std::string Ret = Name.empty() ? "" : Name.str() + ' ';
596 return Ret + (Twine(SuffixStart) + Msg + Twine(SuffixEnd)).str();
597}
598
599StringRef llvm::ELFYAML::dropUniqueSuffix(StringRef S) {
600 if (S.empty() || S.back() != SuffixEnd)
601 return S;
602
603 // A special case for empty names. See appendUniqueSuffix() above.
604 size_t SuffixPos = S.rfind(C: SuffixStart);
605 if (SuffixPos == 0)
606 return "";
607
608 if (SuffixPos == StringRef::npos || S[SuffixPos - 1] != ' ')
609 return S;
610 return S.substr(Start: 0, N: SuffixPos - 1);
611}
612
613template <class ELFT>
614uint64_t ELFState<ELFT>::getSectionNameOffset(StringRef Name) {
615 // If a section is excluded from section headers, we do not save its name in
616 // the string table.
617 if (ExcludedSectionHeaders.count(Key: Name))
618 return 0;
619 return ShStrtabStrings->getOffset(S: Name);
620}
621
622static uint64_t writeContent(ContiguousBlobAccumulator &CBA,
623 const std::optional<yaml::BinaryRef> &Content,
624 const std::optional<llvm::yaml::Hex64> &Size) {
625 size_t ContentSize = 0;
626 if (Content) {
627 CBA.writeAsBinary(Bin: *Content);
628 ContentSize = Content->binary_size();
629 }
630
631 if (!Size)
632 return ContentSize;
633
634 CBA.writeZeros(Num: *Size - ContentSize);
635 return *Size;
636}
637
638static StringRef getDefaultLinkSec(unsigned SecType) {
639 switch (SecType) {
640 case ELF::SHT_REL:
641 case ELF::SHT_RELA:
642 case ELF::SHT_GROUP:
643 case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
644 case ELF::SHT_LLVM_ADDRSIG:
645 return ".symtab";
646 case ELF::SHT_GNU_versym:
647 case ELF::SHT_HASH:
648 case ELF::SHT_GNU_HASH:
649 return ".dynsym";
650 case ELF::SHT_DYNSYM:
651 case ELF::SHT_GNU_verdef:
652 case ELF::SHT_GNU_verneed:
653 return ".dynstr";
654 case ELF::SHT_SYMTAB:
655 return ".strtab";
656 default:
657 return "";
658 }
659}
660
661template <class ELFT>
662void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
663 ContiguousBlobAccumulator &CBA) {
664 // Ensure SHN_UNDEF entry is present. An all-zero section header is a
665 // valid SHN_UNDEF entry since SHT_NULL == 0.
666 SHeaders.resize(Doc.getSections().size());
667
668 for (const std::unique_ptr<ELFYAML::Chunk> &D : Doc.Chunks) {
669 if (ELFYAML::Fill *S = dyn_cast<ELFYAML::Fill>(Val: D.get())) {
670 S->Offset = alignToOffset(CBA, /*Align=*/1, Offset: S->Offset);
671 writeFill(Fill&: *S, CBA);
672 LocationCounter += S->Size;
673 continue;
674 }
675
676 if (ELFYAML::SectionHeaderTable *S =
677 dyn_cast<ELFYAML::SectionHeaderTable>(Val: D.get())) {
678 if (S->NoHeaders.value_or(u: false))
679 continue;
680
681 if (!S->Offset)
682 S->Offset = alignToOffset(CBA, Align: sizeof(typename ELFT::uint),
683 /*Offset=*/std::nullopt);
684 else
685 S->Offset = alignToOffset(CBA, /*Align=*/1, Offset: S->Offset);
686
687 uint64_t Size = S->getNumHeaders(SectionsNum: SHeaders.size()) * sizeof(Elf_Shdr);
688 // The full section header information might be not available here, so
689 // fill the space with zeroes as a placeholder.
690 CBA.writeZeros(Num: Size);
691 LocationCounter += Size;
692 continue;
693 }
694
695 ELFYAML::Section *Sec = cast<ELFYAML::Section>(Val: D.get());
696 bool IsFirstUndefSection = Sec == Doc.getSections().front();
697 if (IsFirstUndefSection && Sec->IsImplicit)
698 continue;
699
700 Elf_Shdr &SHeader = SHeaders[SN2I.get(Name: Sec->Name)];
701 if (Sec->Link) {
702 SHeader.sh_link = toSectionIndex(S: *Sec->Link, LocSec: Sec->Name);
703 } else {
704 StringRef LinkSec = getDefaultLinkSec(SecType: Sec->Type);
705 unsigned Link = 0;
706 if (!LinkSec.empty() && !ExcludedSectionHeaders.count(Key: LinkSec) &&
707 SN2I.lookup(Name: LinkSec, Idx&: Link))
708 SHeader.sh_link = Link;
709 }
710
711 if (Sec->EntSize)
712 SHeader.sh_entsize = *Sec->EntSize;
713 else
714 SHeader.sh_entsize = ELFYAML::getDefaultShEntSize<ELFT>(
715 Doc.Header.Machine.value_or(u: ELF::EM_NONE), Sec->Type, Sec->Name);
716
717 // We have a few sections like string or symbol tables that are usually
718 // added implicitly to the end. However, if they are explicitly specified
719 // in the YAML, we need to write them here. This ensures the file offset
720 // remains correct.
721 if (initImplicitHeader(CBA, Header&: SHeader, SecName: Sec->Name,
722 YAMLSec: Sec->IsImplicit ? nullptr : Sec))
723 continue;
724
725 assert(Sec && "It can't be null unless it is an implicit section. But all "
726 "implicit sections should already have been handled above.");
727
728 SHeader.sh_name =
729 getSectionNameOffset(Name: ELFYAML::dropUniqueSuffix(S: Sec->Name));
730 SHeader.sh_type = Sec->Type;
731 if (Sec->Flags)
732 SHeader.sh_flags = *Sec->Flags;
733 SHeader.sh_addralign = Sec->AddressAlign;
734
735 // Set the offset for all sections, except the SHN_UNDEF section with index
736 // 0 when not explicitly requested.
737 if (!IsFirstUndefSection || Sec->Offset)
738 SHeader.sh_offset = alignToOffset(CBA, Align: SHeader.sh_addralign, Offset: Sec->Offset);
739
740 assignSectionAddress(SHeader, YAMLSec: Sec);
741
742 if (IsFirstUndefSection) {
743 if (auto RawSec = dyn_cast<ELFYAML::RawContentSection>(Val: Sec)) {
744 // We do not write any content for special SHN_UNDEF section.
745 if (RawSec->Size)
746 SHeader.sh_size = *RawSec->Size;
747 if (RawSec->Info)
748 SHeader.sh_info = *RawSec->Info;
749 }
750
751 LocationCounter += SHeader.sh_size;
752 SectionHeadersOverrideHelper.push_back({&SHeader, *Sec});
753 continue;
754 }
755
756 if (!isa<ELFYAML::NoBitsSection>(Val: Sec) && (Sec->Content || Sec->Size))
757 SHeader.sh_size = writeContent(CBA, Content: Sec->Content, Size: Sec->Size);
758
759 if (auto S = dyn_cast<ELFYAML::RawContentSection>(Val: Sec)) {
760 writeSectionContent(SHeader, *S, CBA);
761 } else if (auto S = dyn_cast<ELFYAML::SymtabShndxSection>(Val: Sec)) {
762 writeSectionContent(SHeader, *S, CBA);
763 } else if (auto S = dyn_cast<ELFYAML::RelocationSection>(Val: Sec)) {
764 writeSectionContent(SHeader, *S, CBA);
765 } else if (auto S = dyn_cast<ELFYAML::RelrSection>(Val: Sec)) {
766 writeSectionContent(SHeader, *S, CBA);
767 } else if (auto S = dyn_cast<ELFYAML::GroupSection>(Val: Sec)) {
768 writeSectionContent(SHeader, *S, CBA);
769 } else if (auto S = dyn_cast<ELFYAML::ARMIndexTableSection>(Val: Sec)) {
770 writeSectionContent(SHeader, *S, CBA);
771 } else if (auto S = dyn_cast<ELFYAML::MipsABIFlags>(Val: Sec)) {
772 writeSectionContent(SHeader, *S, CBA);
773 } else if (auto S = dyn_cast<ELFYAML::NoBitsSection>(Val: Sec)) {
774 writeSectionContent(SHeader, *S, CBA);
775 } else if (auto S = dyn_cast<ELFYAML::DynamicSection>(Val: Sec)) {
776 writeSectionContent(SHeader, *S, CBA);
777 } else if (auto S = dyn_cast<ELFYAML::SymverSection>(Val: Sec)) {
778 writeSectionContent(SHeader, *S, CBA);
779 } else if (auto S = dyn_cast<ELFYAML::VerneedSection>(Val: Sec)) {
780 writeSectionContent(SHeader, *S, CBA);
781 } else if (auto S = dyn_cast<ELFYAML::VerdefSection>(Val: Sec)) {
782 writeSectionContent(SHeader, *S, CBA);
783 } else if (auto S = dyn_cast<ELFYAML::StackSizesSection>(Val: Sec)) {
784 writeSectionContent(SHeader, *S, CBA);
785 } else if (auto S = dyn_cast<ELFYAML::HashSection>(Val: Sec)) {
786 writeSectionContent(SHeader, *S, CBA);
787 } else if (auto S = dyn_cast<ELFYAML::AddrsigSection>(Val: Sec)) {
788 writeSectionContent(SHeader, *S, CBA);
789 } else if (auto S = dyn_cast<ELFYAML::LinkerOptionsSection>(Val: Sec)) {
790 writeSectionContent(SHeader, *S, CBA);
791 } else if (auto S = dyn_cast<ELFYAML::NoteSection>(Val: Sec)) {
792 writeSectionContent(SHeader, *S, CBA);
793 } else if (auto S = dyn_cast<ELFYAML::GnuHashSection>(Val: Sec)) {
794 writeSectionContent(SHeader, *S, CBA);
795 } else if (auto S = dyn_cast<ELFYAML::DependentLibrariesSection>(Val: Sec)) {
796 writeSectionContent(SHeader, *S, CBA);
797 } else if (auto S = dyn_cast<ELFYAML::CallGraphProfileSection>(Val: Sec)) {
798 writeSectionContent(SHeader, *S, CBA);
799 } else if (auto S = dyn_cast<ELFYAML::BBAddrMapSection>(Val: Sec)) {
800 writeSectionContent(SHeader, *S, CBA);
801 } else {
802 llvm_unreachable("Unknown section type");
803 }
804
805 LocationCounter += SHeader.sh_size;
806 SectionHeadersOverrideHelper.push_back({&SHeader, *Sec});
807 }
808}
809
810template <class ELFT>
811void ELFState<ELFT>::overrideSectionHeaders(std::vector<Elf_Shdr> &SHeaders) {
812 for (std::pair<Elf_Shdr *, ELFYAML::Section> &HeaderAndSec :
813 SectionHeadersOverrideHelper)
814 overrideFields<ELFT>(&HeaderAndSec.second, *HeaderAndSec.first);
815}
816
817template <class ELFT>
818void ELFState<ELFT>::assignSectionAddress(Elf_Shdr &SHeader,
819 ELFYAML::Section *YAMLSec) {
820 if (YAMLSec && YAMLSec->Address) {
821 SHeader.sh_addr = *YAMLSec->Address;
822 LocationCounter = *YAMLSec->Address;
823 return;
824 }
825
826 // sh_addr represents the address in the memory image of a process. Sections
827 // in a relocatable object file or non-allocatable sections do not need
828 // sh_addr assignment.
829 if (Doc.Header.Type.value == ELF::ET_REL ||
830 !(SHeader.sh_flags & ELF::SHF_ALLOC))
831 return;
832
833 LocationCounter =
834 alignTo(LocationCounter, SHeader.sh_addralign ? SHeader.sh_addralign : 1);
835 SHeader.sh_addr = LocationCounter;
836}
837
838static size_t findFirstNonGlobal(ArrayRef<ELFYAML::Symbol> Symbols) {
839 for (size_t I = 0; I < Symbols.size(); ++I)
840 if (Symbols[I].Binding.value != ELF::STB_LOCAL)
841 return I;
842 return Symbols.size();
843}
844
845template <class ELFT>
846std::vector<typename ELFT::Sym>
847ELFState<ELFT>::toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols,
848 const StringTableBuilder &Strtab) {
849 std::vector<Elf_Sym> Ret;
850 Ret.resize(Symbols.size() + 1);
851
852 size_t I = 0;
853 for (const ELFYAML::Symbol &Sym : Symbols) {
854 Elf_Sym &Symbol = Ret[++I];
855
856 // If NameIndex, which contains the name offset, is explicitly specified, we
857 // use it. This is useful for preparing broken objects. Otherwise, we add
858 // the specified Name to the string table builder to get its offset.
859 if (Sym.StName)
860 Symbol.st_name = *Sym.StName;
861 else if (!Sym.Name.empty())
862 Symbol.st_name = Strtab.getOffset(S: ELFYAML::dropUniqueSuffix(S: Sym.Name));
863
864 Symbol.setBindingAndType(Sym.Binding, Sym.Type);
865 if (Sym.Section)
866 Symbol.st_shndx = toSectionIndex(S: *Sym.Section, LocSec: "", LocSym: Sym.Name);
867 else if (Sym.Index)
868 Symbol.st_shndx = *Sym.Index;
869
870 Symbol.st_value = Sym.Value.value_or(u: yaml::Hex64(0));
871 Symbol.st_other = Sym.Other.value_or(u: 0);
872 Symbol.st_size = Sym.Size.value_or(u: yaml::Hex64(0));
873 }
874
875 return Ret;
876}
877
878template <class ELFT>
879void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader,
880 SymtabType STType,
881 ContiguousBlobAccumulator &CBA,
882 ELFYAML::Section *YAMLSec) {
883
884 bool IsStatic = STType == SymtabType::Static;
885 ArrayRef<ELFYAML::Symbol> Symbols;
886 if (IsStatic && Doc.Symbols)
887 Symbols = *Doc.Symbols;
888 else if (!IsStatic && Doc.DynamicSymbols)
889 Symbols = *Doc.DynamicSymbols;
890
891 ELFYAML::RawContentSection *RawSec =
892 dyn_cast_or_null<ELFYAML::RawContentSection>(Val: YAMLSec);
893 if (RawSec && (RawSec->Content || RawSec->Size)) {
894 bool HasSymbolsDescription =
895 (IsStatic && Doc.Symbols) || (!IsStatic && Doc.DynamicSymbols);
896 if (HasSymbolsDescription) {
897 StringRef Property = (IsStatic ? "`Symbols`" : "`DynamicSymbols`");
898 if (RawSec->Content)
899 reportError("cannot specify both `Content` and " + Property +
900 " for symbol table section '" + RawSec->Name + "'");
901 if (RawSec->Size)
902 reportError("cannot specify both `Size` and " + Property +
903 " for symbol table section '" + RawSec->Name + "'");
904 return;
905 }
906 }
907
908 SHeader.sh_name = getSectionNameOffset(Name: IsStatic ? ".symtab" : ".dynsym");
909
910 if (YAMLSec)
911 SHeader.sh_type = YAMLSec->Type;
912 else
913 SHeader.sh_type = IsStatic ? ELF::SHT_SYMTAB : ELF::SHT_DYNSYM;
914
915 if (YAMLSec && YAMLSec->Flags)
916 SHeader.sh_flags = *YAMLSec->Flags;
917 else if (!IsStatic)
918 SHeader.sh_flags = ELF::SHF_ALLOC;
919
920 // If the symbol table section is explicitly described in the YAML
921 // then we should set the fields requested.
922 SHeader.sh_info = (RawSec && RawSec->Info) ? (unsigned)(*RawSec->Info)
923 : findFirstNonGlobal(Symbols) + 1;
924 SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 8;
925
926 assignSectionAddress(SHeader, YAMLSec);
927
928 SHeader.sh_offset = alignToOffset(CBA, Align: SHeader.sh_addralign,
929 Offset: RawSec ? RawSec->Offset : std::nullopt);
930
931 if (RawSec && (RawSec->Content || RawSec->Size)) {
932 assert(Symbols.empty());
933 SHeader.sh_size = writeContent(CBA, Content: RawSec->Content, Size: RawSec->Size);
934 return;
935 }
936
937 std::vector<Elf_Sym> Syms =
938 toELFSymbols(Symbols, Strtab: IsStatic ? DotStrtab : DotDynstr);
939 SHeader.sh_size = Syms.size() * sizeof(Elf_Sym);
940 CBA.write((const char *)Syms.data(), SHeader.sh_size);
941}
942
943template <class ELFT>
944void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,
945 StringTableBuilder &STB,
946 ContiguousBlobAccumulator &CBA,
947 ELFYAML::Section *YAMLSec) {
948 SHeader.sh_name = getSectionNameOffset(Name: ELFYAML::dropUniqueSuffix(S: Name));
949 SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_STRTAB;
950 SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1;
951
952 ELFYAML::RawContentSection *RawSec =
953 dyn_cast_or_null<ELFYAML::RawContentSection>(Val: YAMLSec);
954
955 SHeader.sh_offset = alignToOffset(CBA, Align: SHeader.sh_addralign,
956 Offset: YAMLSec ? YAMLSec->Offset : std::nullopt);
957
958 if (RawSec && (RawSec->Content || RawSec->Size)) {
959 SHeader.sh_size = writeContent(CBA, Content: RawSec->Content, Size: RawSec->Size);
960 } else {
961 if (raw_ostream *OS = CBA.getRawOS(Size: STB.getSize()))
962 STB.write(OS&: *OS);
963 SHeader.sh_size = STB.getSize();
964 }
965
966 if (RawSec && RawSec->Info)
967 SHeader.sh_info = *RawSec->Info;
968
969 if (YAMLSec && YAMLSec->Flags)
970 SHeader.sh_flags = *YAMLSec->Flags;
971 else if (Name == ".dynstr")
972 SHeader.sh_flags = ELF::SHF_ALLOC;
973
974 assignSectionAddress(SHeader, YAMLSec);
975}
976
977static bool shouldEmitDWARF(DWARFYAML::Data &DWARF, StringRef Name) {
978 SetVector<StringRef> DebugSecNames = DWARF.getNonEmptySectionNames();
979 return Name.consume_front(Prefix: ".") && DebugSecNames.count(key: Name);
980}
981
982template <class ELFT>
983Expected<uint64_t> emitDWARF(typename ELFT::Shdr &SHeader, StringRef Name,
984 const DWARFYAML::Data &DWARF,
985 ContiguousBlobAccumulator &CBA) {
986 // We are unable to predict the size of debug data, so we request to write 0
987 // bytes. This should always return us an output stream unless CBA is already
988 // in an error state.
989 raw_ostream *OS = CBA.getRawOS(Size: 0);
990 if (!OS)
991 return 0;
992
993 uint64_t BeginOffset = CBA.tell();
994
995 auto EmitFunc = DWARFYAML::getDWARFEmitterByName(SecName: Name.substr(Start: 1));
996 if (Error Err = EmitFunc(*OS, DWARF))
997 return std::move(Err);
998
999 return CBA.tell() - BeginOffset;
1000}
1001
1002template <class ELFT>
1003void ELFState<ELFT>::initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name,
1004 ContiguousBlobAccumulator &CBA,
1005 ELFYAML::Section *YAMLSec) {
1006 SHeader.sh_name = getSectionNameOffset(Name: ELFYAML::dropUniqueSuffix(S: Name));
1007 SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_PROGBITS;
1008 SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1;
1009 SHeader.sh_offset = alignToOffset(CBA, Align: SHeader.sh_addralign,
1010 Offset: YAMLSec ? YAMLSec->Offset : std::nullopt);
1011
1012 ELFYAML::RawContentSection *RawSec =
1013 dyn_cast_or_null<ELFYAML::RawContentSection>(Val: YAMLSec);
1014 if (Doc.DWARF && shouldEmitDWARF(DWARF&: *Doc.DWARF, Name)) {
1015 if (RawSec && (RawSec->Content || RawSec->Size))
1016 reportError("cannot specify section '" + Name +
1017 "' contents in the 'DWARF' entry and the 'Content' "
1018 "or 'Size' in the 'Sections' entry at the same time");
1019 else {
1020 if (Expected<uint64_t> ShSizeOrErr =
1021 emitDWARF<ELFT>(SHeader, Name, *Doc.DWARF, CBA))
1022 SHeader.sh_size = *ShSizeOrErr;
1023 else
1024 reportError(ShSizeOrErr.takeError());
1025 }
1026 } else if (RawSec)
1027 SHeader.sh_size = writeContent(CBA, Content: RawSec->Content, Size: RawSec->Size);
1028 else
1029 llvm_unreachable("debug sections can only be initialized via the 'DWARF' "
1030 "entry or a RawContentSection");
1031
1032 if (RawSec && RawSec->Info)
1033 SHeader.sh_info = *RawSec->Info;
1034
1035 if (YAMLSec && YAMLSec->Flags)
1036 SHeader.sh_flags = *YAMLSec->Flags;
1037 else if (Name == ".debug_str")
1038 SHeader.sh_flags = ELF::SHF_MERGE | ELF::SHF_STRINGS;
1039
1040 assignSectionAddress(SHeader, YAMLSec);
1041}
1042
1043template <class ELFT> void ELFState<ELFT>::reportError(const Twine &Msg) {
1044 ErrHandler(Msg);
1045 HasError = true;
1046}
1047
1048template <class ELFT> void ELFState<ELFT>::reportError(Error Err) {
1049 handleAllErrors(std::move(Err), [&](const ErrorInfoBase &Err) {
1050 reportError(Err.message());
1051 });
1052}
1053
1054template <class ELFT>
1055std::vector<Fragment>
1056ELFState<ELFT>::getPhdrFragments(const ELFYAML::ProgramHeader &Phdr,
1057 ArrayRef<Elf_Shdr> SHeaders) {
1058 std::vector<Fragment> Ret;
1059 for (const ELFYAML::Chunk *C : Phdr.Chunks) {
1060 if (const ELFYAML::Fill *F = dyn_cast<ELFYAML::Fill>(Val: C)) {
1061 Ret.push_back(x: {.Offset: *F->Offset, .Size: F->Size, .Type: llvm::ELF::SHT_PROGBITS,
1062 /*ShAddrAlign=*/.AddrAlign: 1});
1063 continue;
1064 }
1065
1066 const ELFYAML::Section *S = cast<ELFYAML::Section>(Val: C);
1067 const Elf_Shdr &H = SHeaders[SN2I.get(Name: S->Name)];
1068 Ret.push_back({H.sh_offset, H.sh_size, H.sh_type, H.sh_addralign});
1069 }
1070 return Ret;
1071}
1072
1073template <class ELFT>
1074void ELFState<ELFT>::setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders,
1075 std::vector<Elf_Shdr> &SHeaders) {
1076 uint32_t PhdrIdx = 0;
1077 for (auto &YamlPhdr : Doc.ProgramHeaders) {
1078 Elf_Phdr &PHeader = PHeaders[PhdrIdx++];
1079 std::vector<Fragment> Fragments = getPhdrFragments(Phdr: YamlPhdr, SHeaders);
1080 if (!llvm::is_sorted(Fragments, [](const Fragment &A, const Fragment &B) {
1081 return A.Offset < B.Offset;
1082 }))
1083 reportError("sections in the program header with index " +
1084 Twine(PhdrIdx) + " are not sorted by their file offset");
1085
1086 if (YamlPhdr.Offset) {
1087 if (!Fragments.empty() && *YamlPhdr.Offset > Fragments.front().Offset)
1088 reportError("'Offset' for segment with index " + Twine(PhdrIdx) +
1089 " must be less than or equal to the minimum file offset of "
1090 "all included sections (0x" +
1091 Twine::utohexstr(Val: Fragments.front().Offset) + ")");
1092 PHeader.p_offset = *YamlPhdr.Offset;
1093 } else if (!Fragments.empty()) {
1094 PHeader.p_offset = Fragments.front().Offset;
1095 }
1096
1097 // Set the file size if not set explicitly.
1098 if (YamlPhdr.FileSize) {
1099 PHeader.p_filesz = *YamlPhdr.FileSize;
1100 } else if (!Fragments.empty()) {
1101 uint64_t FileSize = Fragments.back().Offset - PHeader.p_offset;
1102 // SHT_NOBITS sections occupy no physical space in a file, we should not
1103 // take their sizes into account when calculating the file size of a
1104 // segment.
1105 if (Fragments.back().Type != llvm::ELF::SHT_NOBITS)
1106 FileSize += Fragments.back().Size;
1107 PHeader.p_filesz = FileSize;
1108 }
1109
1110 // Find the maximum offset of the end of a section in order to set p_memsz.
1111 uint64_t MemOffset = PHeader.p_offset;
1112 for (const Fragment &F : Fragments)
1113 MemOffset = std::max(a: MemOffset, b: F.Offset + F.Size);
1114 // Set the memory size if not set explicitly.
1115 PHeader.p_memsz = YamlPhdr.MemSize ? uint64_t(*YamlPhdr.MemSize)
1116 : MemOffset - PHeader.p_offset;
1117
1118 if (YamlPhdr.Align) {
1119 PHeader.p_align = *YamlPhdr.Align;
1120 } else {
1121 // Set the alignment of the segment to be the maximum alignment of the
1122 // sections so that by default the segment has a valid and sensible
1123 // alignment.
1124 PHeader.p_align = 1;
1125 for (const Fragment &F : Fragments)
1126 PHeader.p_align = std::max(a: (uint64_t)PHeader.p_align, b: F.AddrAlign);
1127 }
1128 }
1129}
1130
1131bool llvm::ELFYAML::shouldAllocateFileSpace(
1132 ArrayRef<ELFYAML::ProgramHeader> Phdrs, const ELFYAML::NoBitsSection &S) {
1133 for (const ELFYAML::ProgramHeader &PH : Phdrs) {
1134 auto It = llvm::find_if(
1135 Range: PH.Chunks, P: [&](ELFYAML::Chunk *C) { return C->Name == S.Name; });
1136 if (std::any_of(first: It, last: PH.Chunks.end(), pred: [](ELFYAML::Chunk *C) {
1137 return (isa<ELFYAML::Fill>(Val: C) ||
1138 cast<ELFYAML::Section>(Val: C)->Type != ELF::SHT_NOBITS);
1139 }))
1140 return true;
1141 }
1142 return false;
1143}
1144
1145template <class ELFT>
1146void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1147 const ELFYAML::NoBitsSection &S,
1148 ContiguousBlobAccumulator &CBA) {
1149 if (!S.Size)
1150 return;
1151
1152 SHeader.sh_size = *S.Size;
1153
1154 // When a nobits section is followed by a non-nobits section or fill
1155 // in the same segment, we allocate the file space for it. This behavior
1156 // matches linkers.
1157 if (shouldAllocateFileSpace(Phdrs: Doc.ProgramHeaders, S))
1158 CBA.writeZeros(Num: *S.Size);
1159}
1160
1161template <class ELFT>
1162void ELFState<ELFT>::writeSectionContent(
1163 Elf_Shdr &SHeader, const ELFYAML::RawContentSection &Section,
1164 ContiguousBlobAccumulator &CBA) {
1165 if (Section.Info)
1166 SHeader.sh_info = *Section.Info;
1167}
1168
1169static bool isMips64EL(const ELFYAML::Object &Obj) {
1170 return Obj.getMachine() == llvm::ELF::EM_MIPS &&
1171 Obj.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64) &&
1172 Obj.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB);
1173}
1174
1175template <class ELFT>
1176void ELFState<ELFT>::writeSectionContent(
1177 Elf_Shdr &SHeader, const ELFYAML::RelocationSection &Section,
1178 ContiguousBlobAccumulator &CBA) {
1179 assert((Section.Type == llvm::ELF::SHT_REL ||
1180 Section.Type == llvm::ELF::SHT_RELA ||
1181 Section.Type == llvm::ELF::SHT_CREL) &&
1182 "Section type is not SHT_REL nor SHT_RELA");
1183
1184 if (!Section.RelocatableSec.empty())
1185 SHeader.sh_info = toSectionIndex(S: Section.RelocatableSec, LocSec: Section.Name);
1186
1187 if (!Section.Relocations)
1188 return;
1189
1190 const bool IsCrel = Section.Type == llvm::ELF::SHT_CREL;
1191 const bool IsRela = Section.Type == llvm::ELF::SHT_RELA;
1192 typename ELFT::uint OffsetMask = 8, Offset = 0, Addend = 0;
1193 uint32_t SymIdx = 0, Type = 0;
1194 uint64_t CurrentOffset = CBA.getOffset();
1195 if (IsCrel)
1196 for (const ELFYAML::Relocation &Rel : *Section.Relocations)
1197 OffsetMask |= Rel.Offset;
1198 const int Shift = llvm::countr_zero(OffsetMask);
1199 if (IsCrel)
1200 CBA.writeULEB128(Val: Section.Relocations->size() * 8 + ELF::CREL_HDR_ADDEND +
1201 Shift);
1202 for (const ELFYAML::Relocation &Rel : *Section.Relocations) {
1203 const bool IsDynamic = Section.Link && (*Section.Link == ".dynsym");
1204 uint32_t CurSymIdx =
1205 Rel.Symbol ? toSymbolIndex(S: *Rel.Symbol, LocSec: Section.Name, IsDynamic) : 0;
1206 if (IsCrel) {
1207 // The delta offset and flags member may be larger than uint64_t. Special
1208 // case the first byte (3 flag bits and 4 offset bits). Other ULEB128
1209 // bytes encode the remaining delta offset bits.
1210 auto DeltaOffset =
1211 (static_cast<typename ELFT::uint>(Rel.Offset) - Offset) >> Shift;
1212 Offset = Rel.Offset;
1213 uint8_t B =
1214 DeltaOffset * 8 + (SymIdx != CurSymIdx) + (Type != Rel.Type ? 2 : 0) +
1215 (Addend != static_cast<typename ELFT::uint>(Rel.Addend) ? 4 : 0);
1216 if (DeltaOffset < 0x10) {
1217 CBA.write(C: B);
1218 } else {
1219 CBA.write(C: B | 0x80);
1220 CBA.writeULEB128(Val: DeltaOffset >> 4);
1221 }
1222 // Delta symidx/type/addend members (SLEB128).
1223 if (B & 1) {
1224 CBA.writeSLEB128(
1225 Val: std::make_signed_t<typename ELFT::uint>(CurSymIdx - SymIdx));
1226 SymIdx = CurSymIdx;
1227 }
1228 if (B & 2) {
1229 CBA.writeSLEB128(Val: static_cast<int32_t>(Rel.Type - Type));
1230 Type = Rel.Type;
1231 }
1232 if (B & 4) {
1233 CBA.writeSLEB128(
1234 Val: std::make_signed_t<typename ELFT::uint>(Rel.Addend - Addend));
1235 Addend = Rel.Addend;
1236 }
1237 } else if (IsRela) {
1238 Elf_Rela REntry;
1239 zero(REntry);
1240 REntry.r_offset = Rel.Offset;
1241 REntry.r_addend = Rel.Addend;
1242 REntry.setSymbolAndType(CurSymIdx, Rel.Type, isMips64EL(Obj: Doc));
1243 CBA.write(Ptr: (const char *)&REntry, Size: sizeof(REntry));
1244 } else {
1245 Elf_Rel REntry;
1246 zero(REntry);
1247 REntry.r_offset = Rel.Offset;
1248 REntry.setSymbolAndType(CurSymIdx, Rel.Type, isMips64EL(Obj: Doc));
1249 CBA.write(Ptr: (const char *)&REntry, Size: sizeof(REntry));
1250 }
1251 }
1252
1253 SHeader.sh_size = CBA.getOffset() - CurrentOffset;
1254}
1255
1256template <class ELFT>
1257void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1258 const ELFYAML::RelrSection &Section,
1259 ContiguousBlobAccumulator &CBA) {
1260 if (!Section.Entries)
1261 return;
1262
1263 for (llvm::yaml::Hex64 E : *Section.Entries) {
1264 if (!ELFT::Is64Bits && E > UINT32_MAX)
1265 reportError(Section.Name + ": the value is too large for 32-bits: 0x" +
1266 Twine::utohexstr(Val: E));
1267 CBA.write<uintX_t>(E, ELFT::Endianness);
1268 }
1269
1270 SHeader.sh_size = sizeof(uintX_t) * Section.Entries->size();
1271}
1272
1273template <class ELFT>
1274void ELFState<ELFT>::writeSectionContent(
1275 Elf_Shdr &SHeader, const ELFYAML::SymtabShndxSection &Shndx,
1276 ContiguousBlobAccumulator &CBA) {
1277 if (Shndx.Content || Shndx.Size) {
1278 SHeader.sh_size = writeContent(CBA, Content: Shndx.Content, Size: Shndx.Size);
1279 return;
1280 }
1281
1282 if (!Shndx.Entries)
1283 return;
1284
1285 for (uint32_t E : *Shndx.Entries)
1286 CBA.write<uint32_t>(E, ELFT::Endianness);
1287 SHeader.sh_size = Shndx.Entries->size() * SHeader.sh_entsize;
1288}
1289
1290template <class ELFT>
1291void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1292 const ELFYAML::GroupSection &Section,
1293 ContiguousBlobAccumulator &CBA) {
1294 assert(Section.Type == llvm::ELF::SHT_GROUP &&
1295 "Section type is not SHT_GROUP");
1296
1297 if (Section.Signature)
1298 SHeader.sh_info =
1299 toSymbolIndex(S: *Section.Signature, LocSec: Section.Name, /*IsDynamic=*/false);
1300
1301 if (!Section.Members)
1302 return;
1303
1304 for (const ELFYAML::SectionOrType &Member : *Section.Members) {
1305 unsigned int SectionIndex = 0;
1306 if (Member.sectionNameOrType == "GRP_COMDAT")
1307 SectionIndex = llvm::ELF::GRP_COMDAT;
1308 else
1309 SectionIndex = toSectionIndex(S: Member.sectionNameOrType, LocSec: Section.Name);
1310 CBA.write<uint32_t>(SectionIndex, ELFT::Endianness);
1311 }
1312 SHeader.sh_size = SHeader.sh_entsize * Section.Members->size();
1313}
1314
1315template <class ELFT>
1316void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1317 const ELFYAML::SymverSection &Section,
1318 ContiguousBlobAccumulator &CBA) {
1319 if (!Section.Entries)
1320 return;
1321
1322 for (uint16_t Version : *Section.Entries)
1323 CBA.write<uint16_t>(Version, ELFT::Endianness);
1324 SHeader.sh_size = Section.Entries->size() * SHeader.sh_entsize;
1325}
1326
1327template <class ELFT>
1328void ELFState<ELFT>::writeSectionContent(
1329 Elf_Shdr &SHeader, const ELFYAML::StackSizesSection &Section,
1330 ContiguousBlobAccumulator &CBA) {
1331 if (!Section.Entries)
1332 return;
1333
1334 for (const ELFYAML::StackSizeEntry &E : *Section.Entries) {
1335 CBA.write<uintX_t>(E.Address, ELFT::Endianness);
1336 SHeader.sh_size += sizeof(uintX_t) + CBA.writeULEB128(Val: E.Size);
1337 }
1338}
1339
1340template <class ELFT>
1341void ELFState<ELFT>::writeSectionContent(
1342 Elf_Shdr &SHeader, const ELFYAML::BBAddrMapSection &Section,
1343 ContiguousBlobAccumulator &CBA) {
1344 if (!Section.Entries) {
1345 if (Section.PGOAnalyses)
1346 WithColor::warning()
1347 << "PGOAnalyses should not exist in SHT_LLVM_BB_ADDR_MAP when "
1348 "Entries does not exist";
1349 return;
1350 }
1351
1352 const std::vector<BBAddrMapYAML::PGOAnalysisMapEntry> *PGOAnalyses = nullptr;
1353 if (Section.PGOAnalyses) {
1354 if (Section.Entries->size() != Section.PGOAnalyses->size())
1355 WithColor::warning() << "PGOAnalyses must be the same length as Entries "
1356 "in SHT_LLVM_BB_ADDR_MAP";
1357 else
1358 PGOAnalyses = &Section.PGOAnalyses.value();
1359 }
1360
1361 uint64_t CurrentOffset = CBA.getOffset();
1362 BBAddrMapYAML::encodePayload(Entries: *Section.Entries, PGOAnalyses, CBA,
1363 Endian: ELFT::Endianness, AddressSize: sizeof(uintX_t));
1364 SHeader.sh_size += CBA.getOffset() - CurrentOffset;
1365}
1366
1367template <class ELFT>
1368void ELFState<ELFT>::writeSectionContent(
1369 Elf_Shdr &SHeader, const ELFYAML::LinkerOptionsSection &Section,
1370 ContiguousBlobAccumulator &CBA) {
1371 if (!Section.Options)
1372 return;
1373
1374 for (const ELFYAML::LinkerOption &LO : *Section.Options) {
1375 CBA.write(Ptr: LO.Key.data(), Size: LO.Key.size());
1376 CBA.write(C: '\0');
1377 CBA.write(Ptr: LO.Value.data(), Size: LO.Value.size());
1378 CBA.write(C: '\0');
1379 SHeader.sh_size += (LO.Key.size() + LO.Value.size() + 2);
1380 }
1381}
1382
1383template <class ELFT>
1384void ELFState<ELFT>::writeSectionContent(
1385 Elf_Shdr &SHeader, const ELFYAML::DependentLibrariesSection &Section,
1386 ContiguousBlobAccumulator &CBA) {
1387 if (!Section.Libs)
1388 return;
1389
1390 for (StringRef Lib : *Section.Libs) {
1391 CBA.write(Ptr: Lib.data(), Size: Lib.size());
1392 CBA.write(C: '\0');
1393 SHeader.sh_size += Lib.size() + 1;
1394 }
1395}
1396
1397template <class ELFT>
1398uint64_t
1399ELFState<ELFT>::alignToOffset(ContiguousBlobAccumulator &CBA, uint64_t Align,
1400 std::optional<llvm::yaml::Hex64> Offset) {
1401 uint64_t CurrentOffset = CBA.getOffset();
1402 uint64_t AlignedOffset;
1403
1404 if (Offset) {
1405 if ((uint64_t)*Offset < CurrentOffset) {
1406 reportError("the 'Offset' value (0x" +
1407 Twine::utohexstr(Val: (uint64_t)*Offset) + ") goes backward");
1408 return CurrentOffset;
1409 }
1410
1411 // We ignore an alignment when an explicit offset has been requested.
1412 AlignedOffset = *Offset;
1413 } else {
1414 AlignedOffset = alignTo(Value: CurrentOffset, Align: std::max(a: Align, b: (uint64_t)1));
1415 }
1416
1417 CBA.writeZeros(Num: AlignedOffset - CurrentOffset);
1418 return AlignedOffset;
1419}
1420
1421template <class ELFT>
1422void ELFState<ELFT>::writeSectionContent(
1423 Elf_Shdr &SHeader, const ELFYAML::CallGraphProfileSection &Section,
1424 ContiguousBlobAccumulator &CBA) {
1425 if (!Section.Entries)
1426 return;
1427
1428 for (const ELFYAML::CallGraphEntryWeight &E : *Section.Entries) {
1429 CBA.write<uint64_t>(E.Weight, ELFT::Endianness);
1430 SHeader.sh_size += sizeof(object::Elf_CGProfile_Impl<ELFT>);
1431 }
1432}
1433
1434template <class ELFT>
1435void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1436 const ELFYAML::HashSection &Section,
1437 ContiguousBlobAccumulator &CBA) {
1438 if (!Section.Bucket)
1439 return;
1440
1441 CBA.write<uint32_t>(
1442 Section.NBucket.value_or(u: llvm::yaml::Hex64(Section.Bucket->size())),
1443 ELFT::Endianness);
1444 CBA.write<uint32_t>(
1445 Section.NChain.value_or(u: llvm::yaml::Hex64(Section.Chain->size())),
1446 ELFT::Endianness);
1447
1448 for (uint32_t Val : *Section.Bucket)
1449 CBA.write<uint32_t>(Val, ELFT::Endianness);
1450 for (uint32_t Val : *Section.Chain)
1451 CBA.write<uint32_t>(Val, ELFT::Endianness);
1452
1453 SHeader.sh_size = (2 + Section.Bucket->size() + Section.Chain->size()) * 4;
1454}
1455
1456template <class ELFT>
1457void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1458 const ELFYAML::VerdefSection &Section,
1459 ContiguousBlobAccumulator &CBA) {
1460
1461 if (Section.Info)
1462 SHeader.sh_info = *Section.Info;
1463 else if (Section.Entries)
1464 SHeader.sh_info = Section.Entries->size();
1465
1466 if (!Section.Entries)
1467 return;
1468
1469 uint64_t AuxCnt = 0;
1470 for (size_t I = 0; I < Section.Entries->size(); ++I) {
1471 const ELFYAML::VerdefEntry &E = (*Section.Entries)[I];
1472
1473 Elf_Verdef VerDef;
1474 VerDef.vd_version = E.Version.value_or(u: 1);
1475 VerDef.vd_flags = E.Flags.value_or(u: 0);
1476 VerDef.vd_ndx = E.VersionNdx.value_or(u: 0);
1477 VerDef.vd_hash = E.Hash.value_or(u: 0);
1478 VerDef.vd_aux = E.VDAux.value_or(u: sizeof(Elf_Verdef));
1479 VerDef.vd_cnt = E.VerNames.size();
1480 if (I == Section.Entries->size() - 1)
1481 VerDef.vd_next = 0;
1482 else
1483 VerDef.vd_next =
1484 sizeof(Elf_Verdef) + E.VerNames.size() * sizeof(Elf_Verdaux);
1485 CBA.write(Ptr: (const char *)&VerDef, Size: sizeof(Elf_Verdef));
1486
1487 for (size_t J = 0; J < E.VerNames.size(); ++J, ++AuxCnt) {
1488 Elf_Verdaux VerdAux;
1489 VerdAux.vda_name = DotDynstr.getOffset(S: E.VerNames[J]);
1490 if (J == E.VerNames.size() - 1)
1491 VerdAux.vda_next = 0;
1492 else
1493 VerdAux.vda_next = sizeof(Elf_Verdaux);
1494 CBA.write(Ptr: (const char *)&VerdAux, Size: sizeof(Elf_Verdaux));
1495 }
1496 }
1497
1498 SHeader.sh_size = Section.Entries->size() * sizeof(Elf_Verdef) +
1499 AuxCnt * sizeof(Elf_Verdaux);
1500}
1501
1502template <class ELFT>
1503void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1504 const ELFYAML::VerneedSection &Section,
1505 ContiguousBlobAccumulator &CBA) {
1506 if (Section.Info)
1507 SHeader.sh_info = *Section.Info;
1508 else if (Section.VerneedV)
1509 SHeader.sh_info = Section.VerneedV->size();
1510
1511 if (!Section.VerneedV)
1512 return;
1513
1514 uint64_t AuxCnt = 0;
1515 for (size_t I = 0; I < Section.VerneedV->size(); ++I) {
1516 const ELFYAML::VerneedEntry &VE = (*Section.VerneedV)[I];
1517
1518 Elf_Verneed VerNeed;
1519 VerNeed.vn_version = VE.Version;
1520 VerNeed.vn_file = DotDynstr.getOffset(S: VE.File);
1521 if (I == Section.VerneedV->size() - 1)
1522 VerNeed.vn_next = 0;
1523 else
1524 VerNeed.vn_next =
1525 sizeof(Elf_Verneed) + VE.AuxV.size() * sizeof(Elf_Vernaux);
1526 VerNeed.vn_cnt = VE.AuxV.size();
1527 VerNeed.vn_aux = sizeof(Elf_Verneed);
1528 CBA.write(Ptr: (const char *)&VerNeed, Size: sizeof(Elf_Verneed));
1529
1530 for (size_t J = 0; J < VE.AuxV.size(); ++J, ++AuxCnt) {
1531 const ELFYAML::VernauxEntry &VAuxE = VE.AuxV[J];
1532
1533 Elf_Vernaux VernAux;
1534 VernAux.vna_hash = VAuxE.Hash;
1535 VernAux.vna_flags = VAuxE.Flags;
1536 VernAux.vna_other = VAuxE.Other;
1537 VernAux.vna_name = DotDynstr.getOffset(S: VAuxE.Name);
1538 if (J == VE.AuxV.size() - 1)
1539 VernAux.vna_next = 0;
1540 else
1541 VernAux.vna_next = sizeof(Elf_Vernaux);
1542 CBA.write(Ptr: (const char *)&VernAux, Size: sizeof(Elf_Vernaux));
1543 }
1544 }
1545
1546 SHeader.sh_size = Section.VerneedV->size() * sizeof(Elf_Verneed) +
1547 AuxCnt * sizeof(Elf_Vernaux);
1548}
1549
1550template <class ELFT>
1551void ELFState<ELFT>::writeSectionContent(
1552 Elf_Shdr &SHeader, const ELFYAML::ARMIndexTableSection &Section,
1553 ContiguousBlobAccumulator &CBA) {
1554 if (!Section.Entries)
1555 return;
1556
1557 for (const ELFYAML::ARMIndexTableEntry &E : *Section.Entries) {
1558 CBA.write<uint32_t>(E.Offset, ELFT::Endianness);
1559 CBA.write<uint32_t>(E.Value, ELFT::Endianness);
1560 }
1561 SHeader.sh_size = Section.Entries->size() * 8;
1562}
1563
1564template <class ELFT>
1565void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1566 const ELFYAML::MipsABIFlags &Section,
1567 ContiguousBlobAccumulator &CBA) {
1568 assert(Section.Type == llvm::ELF::SHT_MIPS_ABIFLAGS &&
1569 "Section type is not SHT_MIPS_ABIFLAGS");
1570
1571 object::Elf_Mips_ABIFlags<ELFT> Flags;
1572 zero(Flags);
1573 SHeader.sh_size = SHeader.sh_entsize;
1574
1575 Flags.version = Section.Version;
1576 Flags.isa_level = Section.ISALevel;
1577 Flags.isa_rev = Section.ISARevision;
1578 Flags.gpr_size = Section.GPRSize;
1579 Flags.cpr1_size = Section.CPR1Size;
1580 Flags.cpr2_size = Section.CPR2Size;
1581 Flags.fp_abi = Section.FpABI;
1582 Flags.isa_ext = Section.ISAExtension;
1583 Flags.ases = Section.ASEs;
1584 Flags.flags1 = Section.Flags1;
1585 Flags.flags2 = Section.Flags2;
1586 CBA.write(Ptr: (const char *)&Flags, Size: sizeof(Flags));
1587}
1588
1589template <class ELFT>
1590void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1591 const ELFYAML::DynamicSection &Section,
1592 ContiguousBlobAccumulator &CBA) {
1593 assert(Section.Type == llvm::ELF::SHT_DYNAMIC &&
1594 "Section type is not SHT_DYNAMIC");
1595
1596 if (!Section.Entries)
1597 return;
1598
1599 for (const ELFYAML::DynamicEntry &DE : *Section.Entries) {
1600 CBA.write<uintX_t>(DE.Tag, ELFT::Endianness);
1601 CBA.write<uintX_t>(DE.Val, ELFT::Endianness);
1602 }
1603 SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries->size();
1604}
1605
1606template <class ELFT>
1607void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1608 const ELFYAML::AddrsigSection &Section,
1609 ContiguousBlobAccumulator &CBA) {
1610 if (!Section.Symbols)
1611 return;
1612
1613 for (StringRef Sym : *Section.Symbols)
1614 SHeader.sh_size +=
1615 CBA.writeULEB128(Val: toSymbolIndex(S: Sym, LocSec: Section.Name, /*IsDynamic=*/false));
1616}
1617
1618template <class ELFT>
1619void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1620 const ELFYAML::NoteSection &Section,
1621 ContiguousBlobAccumulator &CBA) {
1622 if (!Section.Notes || Section.Notes->empty())
1623 return;
1624
1625 unsigned Align;
1626 switch (Section.AddressAlign) {
1627 case 0:
1628 case 4:
1629 Align = 4;
1630 break;
1631 case 8:
1632 Align = 8;
1633 break;
1634 default:
1635 reportError(Section.Name + ": invalid alignment for a note section: 0x" +
1636 Twine::utohexstr(Val: Section.AddressAlign));
1637 return;
1638 }
1639
1640 if (CBA.getOffset() != alignTo(Value: CBA.getOffset(), Align)) {
1641 reportError(Section.Name + ": invalid offset of a note section: 0x" +
1642 Twine::utohexstr(Val: CBA.getOffset()) + ", should be aligned to " +
1643 Twine(Align));
1644 return;
1645 }
1646
1647 uint64_t Offset = CBA.tell();
1648 for (const ELFYAML::NoteEntry &NE : *Section.Notes) {
1649 // Write name size.
1650 if (NE.Name.empty())
1651 CBA.write<uint32_t>(0, ELFT::Endianness);
1652 else
1653 CBA.write<uint32_t>(NE.Name.size() + 1, ELFT::Endianness);
1654
1655 // Write description size.
1656 if (NE.Desc.binary_size() == 0)
1657 CBA.write<uint32_t>(0, ELFT::Endianness);
1658 else
1659 CBA.write<uint32_t>(NE.Desc.binary_size(), ELFT::Endianness);
1660
1661 // Write type.
1662 CBA.write<uint32_t>(NE.Type, ELFT::Endianness);
1663
1664 // Write name, null terminator and padding.
1665 if (!NE.Name.empty()) {
1666 CBA.write(Ptr: NE.Name.data(), Size: NE.Name.size());
1667 CBA.write(C: '\0');
1668 }
1669
1670 // Write description and padding.
1671 if (NE.Desc.binary_size() != 0) {
1672 CBA.padToAlignment(Align);
1673 CBA.writeAsBinary(Bin: NE.Desc);
1674 }
1675
1676 CBA.padToAlignment(Align);
1677 }
1678
1679 SHeader.sh_size = CBA.tell() - Offset;
1680}
1681
1682template <class ELFT>
1683void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1684 const ELFYAML::GnuHashSection &Section,
1685 ContiguousBlobAccumulator &CBA) {
1686 if (!Section.HashBuckets)
1687 return;
1688
1689 if (!Section.Header)
1690 return;
1691
1692 // We write the header first, starting with the hash buckets count. Normally
1693 // it is the number of entries in HashBuckets, but the "NBuckets" property can
1694 // be used to override this field, which is useful for producing broken
1695 // objects.
1696 if (Section.Header->NBuckets)
1697 CBA.write<uint32_t>(*Section.Header->NBuckets, ELFT::Endianness);
1698 else
1699 CBA.write<uint32_t>(Section.HashBuckets->size(), ELFT::Endianness);
1700
1701 // Write the index of the first symbol in the dynamic symbol table accessible
1702 // via the hash table.
1703 CBA.write<uint32_t>(Section.Header->SymNdx, ELFT::Endianness);
1704
1705 // Write the number of words in the Bloom filter. As above, the "MaskWords"
1706 // property can be used to set this field to any value.
1707 if (Section.Header->MaskWords)
1708 CBA.write<uint32_t>(*Section.Header->MaskWords, ELFT::Endianness);
1709 else
1710 CBA.write<uint32_t>(Section.BloomFilter->size(), ELFT::Endianness);
1711
1712 // Write the shift constant used by the Bloom filter.
1713 CBA.write<uint32_t>(Section.Header->Shift2, ELFT::Endianness);
1714
1715 // We've finished writing the header. Now write the Bloom filter.
1716 for (llvm::yaml::Hex64 Val : *Section.BloomFilter)
1717 CBA.write<uintX_t>(Val, ELFT::Endianness);
1718
1719 // Write an array of hash buckets.
1720 for (llvm::yaml::Hex32 Val : *Section.HashBuckets)
1721 CBA.write<uint32_t>(Val, ELFT::Endianness);
1722
1723 // Write an array of hash values.
1724 for (llvm::yaml::Hex32 Val : *Section.HashValues)
1725 CBA.write<uint32_t>(Val, ELFT::Endianness);
1726
1727 SHeader.sh_size = 16 /*Header size*/ +
1728 Section.BloomFilter->size() * sizeof(typename ELFT::uint) +
1729 Section.HashBuckets->size() * 4 +
1730 Section.HashValues->size() * 4;
1731}
1732
1733template <class ELFT>
1734void ELFState<ELFT>::writeFill(ELFYAML::Fill &Fill,
1735 ContiguousBlobAccumulator &CBA) {
1736 size_t PatternSize = Fill.Pattern ? Fill.Pattern->binary_size() : 0;
1737 if (!PatternSize) {
1738 CBA.writeZeros(Num: Fill.Size);
1739 return;
1740 }
1741
1742 // Fill the content with the specified pattern.
1743 uint64_t Written = 0;
1744 for (; Written + PatternSize <= Fill.Size; Written += PatternSize)
1745 CBA.writeAsBinary(Bin: *Fill.Pattern);
1746 CBA.writeAsBinary(Bin: *Fill.Pattern, N: Fill.Size - Written);
1747}
1748
1749template <class ELFT>
1750DenseMap<StringRef, size_t> ELFState<ELFT>::buildSectionHeaderReorderMap() {
1751 const ELFYAML::SectionHeaderTable &SectionHeaders =
1752 Doc.getSectionHeaderTable();
1753 if (SectionHeaders.IsImplicit || SectionHeaders.NoHeaders ||
1754 SectionHeaders.isDefault())
1755 return DenseMap<StringRef, size_t>();
1756
1757 DenseMap<StringRef, size_t> Ret;
1758 size_t SecNdx = 0;
1759 StringSet<> Seen;
1760
1761 auto AddSection = [&](const ELFYAML::SectionHeader &Hdr) {
1762 if (!Ret.try_emplace(Key: Hdr.Name, Args&: ++SecNdx).second)
1763 reportError("repeated section name: '" + Hdr.Name +
1764 "' in the section header description");
1765 Seen.insert(key: Hdr.Name);
1766 };
1767
1768 if (SectionHeaders.Sections)
1769 for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Sections)
1770 AddSection(Hdr);
1771
1772 if (SectionHeaders.Excluded)
1773 for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Excluded)
1774 AddSection(Hdr);
1775
1776 for (const ELFYAML::Section *S : Doc.getSections()) {
1777 // Ignore special first SHT_NULL section.
1778 if (S == Doc.getSections().front())
1779 continue;
1780 if (!Seen.count(Key: S->Name))
1781 reportError("section '" + S->Name +
1782 "' should be present in the 'Sections' or 'Excluded' lists");
1783 Seen.erase(Key: S->Name);
1784 }
1785
1786 for (const auto &It : Seen)
1787 reportError("section header contains undefined section '" + It.getKey() +
1788 "'");
1789 return Ret;
1790}
1791
1792template <class ELFT> void ELFState<ELFT>::buildSectionIndex() {
1793 // A YAML description can have an explicit section header declaration that
1794 // allows to change the order of section headers.
1795 DenseMap<StringRef, size_t> ReorderMap = buildSectionHeaderReorderMap();
1796
1797 if (HasError)
1798 return;
1799
1800 // Build excluded section headers map.
1801 std::vector<ELFYAML::Section *> Sections = Doc.getSections();
1802 const ELFYAML::SectionHeaderTable &SectionHeaders =
1803 Doc.getSectionHeaderTable();
1804 if (SectionHeaders.Excluded)
1805 for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Excluded)
1806 if (!ExcludedSectionHeaders.insert(key: Hdr.Name).second)
1807 llvm_unreachable("buildSectionIndex() failed");
1808
1809 if (SectionHeaders.NoHeaders.value_or(u: false))
1810 for (const ELFYAML::Section *S : Sections)
1811 if (!ExcludedSectionHeaders.insert(key: S->Name).second)
1812 llvm_unreachable("buildSectionIndex() failed");
1813
1814 size_t SecNdx = -1;
1815 for (const ELFYAML::Section *S : Sections) {
1816 ++SecNdx;
1817
1818 size_t Index = ReorderMap.empty() ? SecNdx : ReorderMap.lookup(Val: S->Name);
1819 if (!SN2I.addName(Name: S->Name, Ndx: Index))
1820 llvm_unreachable("buildSectionIndex() failed");
1821
1822 if (!ExcludedSectionHeaders.count(Key: S->Name))
1823 ShStrtabStrings->add(S: ELFYAML::dropUniqueSuffix(S: S->Name));
1824 }
1825}
1826
1827template <class ELFT> void ELFState<ELFT>::buildSymbolIndexes() {
1828 auto Build = [this](ArrayRef<ELFYAML::Symbol> V, NameToIdxMap &Map) {
1829 for (size_t I = 0, S = V.size(); I < S; ++I) {
1830 const ELFYAML::Symbol &Sym = V[I];
1831 if (!Sym.Name.empty() && !Map.addName(Name: Sym.Name, Ndx: I + 1))
1832 reportError("repeated symbol name: '" + Sym.Name + "'");
1833 }
1834 };
1835
1836 if (Doc.Symbols)
1837 Build(*Doc.Symbols, SymN2I);
1838 if (Doc.DynamicSymbols)
1839 Build(*Doc.DynamicSymbols, DynSymN2I);
1840}
1841
1842template <class ELFT> void ELFState<ELFT>::finalizeStrings() {
1843 // Add the regular symbol names to .strtab section.
1844 if (Doc.Symbols)
1845 for (const ELFYAML::Symbol &Sym : *Doc.Symbols)
1846 DotStrtab.add(S: ELFYAML::dropUniqueSuffix(S: Sym.Name));
1847 DotStrtab.finalize();
1848
1849 // Add the dynamic symbol names to .dynstr section.
1850 if (Doc.DynamicSymbols)
1851 for (const ELFYAML::Symbol &Sym : *Doc.DynamicSymbols)
1852 DotDynstr.add(S: ELFYAML::dropUniqueSuffix(S: Sym.Name));
1853
1854 // SHT_GNU_verdef and SHT_GNU_verneed sections might also
1855 // add strings to .dynstr section.
1856 for (const ELFYAML::Chunk *Sec : Doc.getSections()) {
1857 if (auto VerNeed = dyn_cast<ELFYAML::VerneedSection>(Val: Sec)) {
1858 if (VerNeed->VerneedV) {
1859 for (const ELFYAML::VerneedEntry &VE : *VerNeed->VerneedV) {
1860 DotDynstr.add(S: VE.File);
1861 for (const ELFYAML::VernauxEntry &Aux : VE.AuxV)
1862 DotDynstr.add(S: Aux.Name);
1863 }
1864 }
1865 } else if (auto VerDef = dyn_cast<ELFYAML::VerdefSection>(Val: Sec)) {
1866 if (VerDef->Entries)
1867 for (const ELFYAML::VerdefEntry &E : *VerDef->Entries)
1868 for (StringRef Name : E.VerNames)
1869 DotDynstr.add(S: Name);
1870 }
1871 }
1872
1873 DotDynstr.finalize();
1874
1875 // Don't finalize the section header string table a second time if it has
1876 // already been finalized due to being one of the symbol string tables.
1877 if (ShStrtabStrings != &DotStrtab && ShStrtabStrings != &DotDynstr)
1878 ShStrtabStrings->finalize();
1879}
1880
1881template <class ELFT>
1882bool ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc,
1883 yaml::ErrorHandler EH, uint64_t MaxSize) {
1884 ELFState<ELFT> State(Doc, EH);
1885 if (State.HasError)
1886 return false;
1887
1888 // Build the section index, which adds sections to the section header string
1889 // table first, so that we can finalize the section header string table.
1890 State.buildSectionIndex();
1891 State.buildSymbolIndexes();
1892
1893 // Finalize section header string table and the .strtab and .dynstr sections.
1894 // We do this early because we want to finalize the string table builders
1895 // before writing the content of the sections that might want to use them.
1896 State.finalizeStrings();
1897
1898 if (State.HasError)
1899 return false;
1900
1901 std::vector<Elf_Phdr> PHeaders;
1902 State.initProgramHeaders(PHeaders);
1903
1904 // XXX: This offset is tightly coupled with the order that we write
1905 // things to `OS`.
1906 const size_t SectionContentBeginOffset =
1907 sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * Doc.ProgramHeaders.size();
1908 // It is quite easy to accidentally create output with yaml2obj that is larger
1909 // than intended, for example, due to an issue in the YAML description.
1910 // We limit the maximum allowed output size, but also provide a command line
1911 // option to change this limitation.
1912 ContiguousBlobAccumulator CBA(SectionContentBeginOffset, MaxSize);
1913
1914 std::vector<Elf_Shdr> SHeaders;
1915 State.initSectionHeaders(SHeaders, CBA);
1916
1917 // Now we can decide segment offsets.
1918 State.setProgramHeaderLayout(PHeaders, SHeaders);
1919
1920 // Override section fields, if requested. This needs to happen after program
1921 // header layout happens, because otherwise the layout will use the new
1922 // values.
1923 State.overrideSectionHeaders(SHeaders);
1924
1925 bool ReachedLimit = CBA.getOffset() > MaxSize;
1926 if (Error E = CBA.takeLimitError()) {
1927 // We report a custom error message instead below.
1928 consumeError(Err: std::move(E));
1929 ReachedLimit = true;
1930 }
1931
1932 if (ReachedLimit)
1933 State.reportError(
1934 "the desired output size is greater than permitted. Use the "
1935 "--max-size option to change the limit");
1936
1937 if (State.HasError)
1938 return false;
1939
1940 State.writeELFHeader(OS);
1941 writeArrayData(OS, ArrayRef(PHeaders));
1942
1943 const ELFYAML::SectionHeaderTable &SHT = Doc.getSectionHeaderTable();
1944 if (!SHT.NoHeaders.value_or(u: false))
1945 CBA.updateDataAt(Pos: *SHT.Offset, Data: SHeaders.data(),
1946 Size: SHT.getNumHeaders(SectionsNum: SHeaders.size()) * sizeof(Elf_Shdr));
1947
1948 CBA.writeBlobToStream(Out&: OS);
1949 return true;
1950}
1951
1952namespace llvm {
1953namespace yaml {
1954
1955bool yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH,
1956 uint64_t MaxSize) {
1957 bool IsLE = Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB);
1958 bool Is64Bit = Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64);
1959 if (Is64Bit) {
1960 if (IsLE)
1961 return ELFState<object::ELF64LE>::writeELF(OS&: Out, Doc, EH, MaxSize);
1962 return ELFState<object::ELF64BE>::writeELF(OS&: Out, Doc, EH, MaxSize);
1963 }
1964 if (IsLE)
1965 return ELFState<object::ELF32LE>::writeELF(OS&: Out, Doc, EH, MaxSize);
1966 return ELFState<object::ELF32BE>::writeELF(OS&: Out, Doc, EH, MaxSize);
1967}
1968
1969} // namespace yaml
1970} // namespace llvm
1971