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