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<BBAddrMapYAML::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 uint64_t CurrentOffset = CBA.getOffset();
1466 for (const auto &[Idx, E] : llvm::enumerate(First: *Section.Entries)) {
1467 // Write version and feature values.
1468 if (E.Version > 5)
1469 WithColor::warning() << "unsupported BB address map version: "
1470 << static_cast<int>(E.Version)
1471 << "; encoding using the most recent version";
1472 CBA.write(C: E.Version);
1473 if (E.Version < 5)
1474 CBA.write(C: static_cast<uint8_t>(E.Feature));
1475 else
1476 CBA.write<uint16_t>(E.Feature, ELFT::Endianness);
1477 auto FeatureOrErr = llvm::object::BBAddrMap::Features::decode(Val: E.Feature);
1478 if (!FeatureOrErr) {
1479 // Invalid feature: warn and skip the entry.
1480 WithColor::warning() << toString(E: FeatureOrErr.takeError());
1481 continue;
1482 }
1483 bool MultiBBRangeFeatureEnabled = FeatureOrErr->MultiBBRange;
1484 bool MultiBBRange =
1485 MultiBBRangeFeatureEnabled ||
1486 (E.NumBBRanges.has_value() && E.NumBBRanges.value() != 1) ||
1487 (E.BBRanges && E.BBRanges->size() != 1);
1488 if (MultiBBRange && !MultiBBRangeFeatureEnabled)
1489 WithColor::warning() << "feature value(" << E.Feature
1490 << ") does not support multiple BB ranges.";
1491 if (MultiBBRange) {
1492 // Write the number of basic block ranges, which is overridden by the
1493 // 'NumBBRanges' field when specified.
1494 uint64_t NumBBRanges =
1495 E.NumBBRanges.value_or(u: E.BBRanges ? E.BBRanges->size() : 0);
1496 CBA.writeULEB128(Val: NumBBRanges);
1497 }
1498 if (!E.BBRanges)
1499 continue;
1500 uint64_t TotalNumBlocks = 0;
1501 bool EmitCallsiteEndOffsets =
1502 FeatureOrErr->CallsiteEndOffsets || E.hasAnyCallsiteEndOffsets();
1503 for (const BBAddrMapYAML::BBAddrMapEntry::BBRangeEntry &BBR : *E.BBRanges) {
1504 // Write the base address of the range.
1505 CBA.write<uintX_t>(BBR.BaseAddress, ELFT::Endianness);
1506 // Write number of BBEntries (number of basic blocks in this basic block
1507 // range). This is overridden by the 'NumBlocks' YAML field when
1508 // specified.
1509 uint64_t NumBlocks =
1510 BBR.NumBlocks.value_or(u: BBR.BBEntries ? BBR.BBEntries->size() : 0);
1511 CBA.writeULEB128(Val: NumBlocks);
1512 // Write all BBEntries in this BBRange.
1513 if (!BBR.BBEntries || FeatureOrErr->OmitBBEntries)
1514 continue;
1515 for (const BBAddrMapYAML::BBAddrMapEntry::BBEntry &BBE : *BBR.BBEntries) {
1516 ++TotalNumBlocks;
1517 if (E.Version > 1)
1518 CBA.writeULEB128(Val: BBE.ID);
1519 CBA.writeULEB128(Val: BBE.AddressOffset);
1520 if (EmitCallsiteEndOffsets) {
1521 size_t NumCallsiteEndOffsets =
1522 BBE.CallsiteEndOffsets ? BBE.CallsiteEndOffsets->size() : 0;
1523 CBA.writeULEB128(Val: NumCallsiteEndOffsets);
1524 if (BBE.CallsiteEndOffsets) {
1525 for (uint32_t Offset : *BBE.CallsiteEndOffsets)
1526 CBA.writeULEB128(Val: Offset);
1527 }
1528 }
1529 CBA.writeULEB128(Val: BBE.Size);
1530 CBA.writeULEB128(Val: BBE.Metadata);
1531 if (FeatureOrErr->BBHash || BBE.Hash.has_value()) {
1532 uint64_t Hash =
1533 BBE.Hash.has_value() ? BBE.Hash.value() : llvm::yaml::Hex64(0);
1534 CBA.write<uint64_t>(Hash, ELFT::Endianness);
1535 }
1536 }
1537 }
1538 if (!PGOAnalyses)
1539 continue;
1540 const BBAddrMapYAML::PGOAnalysisMapEntry &PGOEntry = PGOAnalyses->at(n: Idx);
1541
1542 if (PGOEntry.FuncEntryCount)
1543 CBA.writeULEB128(Val: *PGOEntry.FuncEntryCount);
1544
1545 if (!PGOEntry.PGOBBEntries)
1546 continue;
1547
1548 const auto &PGOBBEntries = PGOEntry.PGOBBEntries.value();
1549 if (TotalNumBlocks != PGOBBEntries.size()) {
1550 WithColor::warning() << "PGOBBEntries must be the same length as "
1551 "BBEntries in the BB address map.\n"
1552 << "Mismatch on function with address: "
1553 << E.getFunctionAddress();
1554 continue;
1555 }
1556
1557 for (const auto &PGOBBE : PGOBBEntries) {
1558 if (PGOBBE.BBFreq)
1559 CBA.writeULEB128(Val: *PGOBBE.BBFreq);
1560 if (FeatureOrErr->PostLinkCfg || PGOBBE.PostLinkBBFreq.has_value())
1561 CBA.writeULEB128(Val: PGOBBE.PostLinkBBFreq.value_or(u: 0));
1562 if (PGOBBE.Successors) {
1563 CBA.writeULEB128(Val: PGOBBE.Successors->size());
1564 for (const auto &[ID, BrProb, PostLinkBrFreq] : *PGOBBE.Successors) {
1565 CBA.writeULEB128(Val: ID);
1566 CBA.writeULEB128(Val: BrProb);
1567 if (FeatureOrErr->PostLinkCfg || PostLinkBrFreq.has_value())
1568 CBA.writeULEB128(Val: PostLinkBrFreq.value_or(u: 0));
1569 }
1570 }
1571 }
1572 }
1573 SHeader.sh_size += CBA.getOffset() - CurrentOffset;
1574}
1575
1576template <class ELFT>
1577void ELFState<ELFT>::writeSectionContent(
1578 Elf_Shdr &SHeader, const ELFYAML::LinkerOptionsSection &Section,
1579 ContiguousBlobAccumulator &CBA) {
1580 if (!Section.Options)
1581 return;
1582
1583 for (const ELFYAML::LinkerOption &LO : *Section.Options) {
1584 CBA.write(Ptr: LO.Key.data(), Size: LO.Key.size());
1585 CBA.write(C: '\0');
1586 CBA.write(Ptr: LO.Value.data(), Size: LO.Value.size());
1587 CBA.write(C: '\0');
1588 SHeader.sh_size += (LO.Key.size() + LO.Value.size() + 2);
1589 }
1590}
1591
1592template <class ELFT>
1593void ELFState<ELFT>::writeSectionContent(
1594 Elf_Shdr &SHeader, const ELFYAML::DependentLibrariesSection &Section,
1595 ContiguousBlobAccumulator &CBA) {
1596 if (!Section.Libs)
1597 return;
1598
1599 for (StringRef Lib : *Section.Libs) {
1600 CBA.write(Ptr: Lib.data(), Size: Lib.size());
1601 CBA.write(C: '\0');
1602 SHeader.sh_size += Lib.size() + 1;
1603 }
1604}
1605
1606template <class ELFT>
1607uint64_t
1608ELFState<ELFT>::alignToOffset(ContiguousBlobAccumulator &CBA, uint64_t Align,
1609 std::optional<llvm::yaml::Hex64> Offset) {
1610 uint64_t CurrentOffset = CBA.getOffset();
1611 uint64_t AlignedOffset;
1612
1613 if (Offset) {
1614 if ((uint64_t)*Offset < CurrentOffset) {
1615 reportError("the 'Offset' value (0x" +
1616 Twine::utohexstr(Val: (uint64_t)*Offset) + ") goes backward");
1617 return CurrentOffset;
1618 }
1619
1620 // We ignore an alignment when an explicit offset has been requested.
1621 AlignedOffset = *Offset;
1622 } else {
1623 AlignedOffset = alignTo(Value: CurrentOffset, Align: std::max(a: Align, b: (uint64_t)1));
1624 }
1625
1626 CBA.writeZeros(Num: AlignedOffset - CurrentOffset);
1627 return AlignedOffset;
1628}
1629
1630template <class ELFT>
1631void ELFState<ELFT>::writeSectionContent(
1632 Elf_Shdr &SHeader, const ELFYAML::CallGraphProfileSection &Section,
1633 ContiguousBlobAccumulator &CBA) {
1634 if (!Section.Entries)
1635 return;
1636
1637 for (const ELFYAML::CallGraphEntryWeight &E : *Section.Entries) {
1638 CBA.write<uint64_t>(E.Weight, ELFT::Endianness);
1639 SHeader.sh_size += sizeof(object::Elf_CGProfile_Impl<ELFT>);
1640 }
1641}
1642
1643template <class ELFT>
1644void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1645 const ELFYAML::HashSection &Section,
1646 ContiguousBlobAccumulator &CBA) {
1647 if (!Section.Bucket)
1648 return;
1649
1650 CBA.write<uint32_t>(
1651 Section.NBucket.value_or(u: llvm::yaml::Hex64(Section.Bucket->size())),
1652 ELFT::Endianness);
1653 CBA.write<uint32_t>(
1654 Section.NChain.value_or(u: llvm::yaml::Hex64(Section.Chain->size())),
1655 ELFT::Endianness);
1656
1657 for (uint32_t Val : *Section.Bucket)
1658 CBA.write<uint32_t>(Val, ELFT::Endianness);
1659 for (uint32_t Val : *Section.Chain)
1660 CBA.write<uint32_t>(Val, ELFT::Endianness);
1661
1662 SHeader.sh_size = (2 + Section.Bucket->size() + Section.Chain->size()) * 4;
1663}
1664
1665template <class ELFT>
1666void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1667 const ELFYAML::VerdefSection &Section,
1668 ContiguousBlobAccumulator &CBA) {
1669
1670 if (Section.Info)
1671 SHeader.sh_info = *Section.Info;
1672 else if (Section.Entries)
1673 SHeader.sh_info = Section.Entries->size();
1674
1675 if (!Section.Entries)
1676 return;
1677
1678 uint64_t AuxCnt = 0;
1679 for (size_t I = 0; I < Section.Entries->size(); ++I) {
1680 const ELFYAML::VerdefEntry &E = (*Section.Entries)[I];
1681
1682 Elf_Verdef VerDef;
1683 VerDef.vd_version = E.Version.value_or(u: 1);
1684 VerDef.vd_flags = E.Flags.value_or(u: 0);
1685 VerDef.vd_ndx = E.VersionNdx.value_or(u: 0);
1686 VerDef.vd_hash = E.Hash.value_or(u: 0);
1687 VerDef.vd_aux = E.VDAux.value_or(u: sizeof(Elf_Verdef));
1688 VerDef.vd_cnt = E.VerNames.size();
1689 if (I == Section.Entries->size() - 1)
1690 VerDef.vd_next = 0;
1691 else
1692 VerDef.vd_next =
1693 sizeof(Elf_Verdef) + E.VerNames.size() * sizeof(Elf_Verdaux);
1694 CBA.write(Ptr: (const char *)&VerDef, Size: sizeof(Elf_Verdef));
1695
1696 for (size_t J = 0; J < E.VerNames.size(); ++J, ++AuxCnt) {
1697 Elf_Verdaux VerdAux;
1698 VerdAux.vda_name = DotDynstr.getOffset(S: E.VerNames[J]);
1699 if (J == E.VerNames.size() - 1)
1700 VerdAux.vda_next = 0;
1701 else
1702 VerdAux.vda_next = sizeof(Elf_Verdaux);
1703 CBA.write(Ptr: (const char *)&VerdAux, Size: sizeof(Elf_Verdaux));
1704 }
1705 }
1706
1707 SHeader.sh_size = Section.Entries->size() * sizeof(Elf_Verdef) +
1708 AuxCnt * sizeof(Elf_Verdaux);
1709}
1710
1711template <class ELFT>
1712void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1713 const ELFYAML::VerneedSection &Section,
1714 ContiguousBlobAccumulator &CBA) {
1715 if (Section.Info)
1716 SHeader.sh_info = *Section.Info;
1717 else if (Section.VerneedV)
1718 SHeader.sh_info = Section.VerneedV->size();
1719
1720 if (!Section.VerneedV)
1721 return;
1722
1723 uint64_t AuxCnt = 0;
1724 for (size_t I = 0; I < Section.VerneedV->size(); ++I) {
1725 const ELFYAML::VerneedEntry &VE = (*Section.VerneedV)[I];
1726
1727 Elf_Verneed VerNeed;
1728 VerNeed.vn_version = VE.Version;
1729 VerNeed.vn_file = DotDynstr.getOffset(S: VE.File);
1730 if (I == Section.VerneedV->size() - 1)
1731 VerNeed.vn_next = 0;
1732 else
1733 VerNeed.vn_next =
1734 sizeof(Elf_Verneed) + VE.AuxV.size() * sizeof(Elf_Vernaux);
1735 VerNeed.vn_cnt = VE.AuxV.size();
1736 VerNeed.vn_aux = sizeof(Elf_Verneed);
1737 CBA.write(Ptr: (const char *)&VerNeed, Size: sizeof(Elf_Verneed));
1738
1739 for (size_t J = 0; J < VE.AuxV.size(); ++J, ++AuxCnt) {
1740 const ELFYAML::VernauxEntry &VAuxE = VE.AuxV[J];
1741
1742 Elf_Vernaux VernAux;
1743 VernAux.vna_hash = VAuxE.Hash;
1744 VernAux.vna_flags = VAuxE.Flags;
1745 VernAux.vna_other = VAuxE.Other;
1746 VernAux.vna_name = DotDynstr.getOffset(S: VAuxE.Name);
1747 if (J == VE.AuxV.size() - 1)
1748 VernAux.vna_next = 0;
1749 else
1750 VernAux.vna_next = sizeof(Elf_Vernaux);
1751 CBA.write(Ptr: (const char *)&VernAux, Size: sizeof(Elf_Vernaux));
1752 }
1753 }
1754
1755 SHeader.sh_size = Section.VerneedV->size() * sizeof(Elf_Verneed) +
1756 AuxCnt * sizeof(Elf_Vernaux);
1757}
1758
1759template <class ELFT>
1760void ELFState<ELFT>::writeSectionContent(
1761 Elf_Shdr &SHeader, const ELFYAML::ARMIndexTableSection &Section,
1762 ContiguousBlobAccumulator &CBA) {
1763 if (!Section.Entries)
1764 return;
1765
1766 for (const ELFYAML::ARMIndexTableEntry &E : *Section.Entries) {
1767 CBA.write<uint32_t>(E.Offset, ELFT::Endianness);
1768 CBA.write<uint32_t>(E.Value, ELFT::Endianness);
1769 }
1770 SHeader.sh_size = Section.Entries->size() * 8;
1771}
1772
1773template <class ELFT>
1774void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1775 const ELFYAML::MipsABIFlags &Section,
1776 ContiguousBlobAccumulator &CBA) {
1777 assert(Section.Type == llvm::ELF::SHT_MIPS_ABIFLAGS &&
1778 "Section type is not SHT_MIPS_ABIFLAGS");
1779
1780 object::Elf_Mips_ABIFlags<ELFT> Flags;
1781 zero(Flags);
1782 SHeader.sh_size = SHeader.sh_entsize;
1783
1784 Flags.version = Section.Version;
1785 Flags.isa_level = Section.ISALevel;
1786 Flags.isa_rev = Section.ISARevision;
1787 Flags.gpr_size = Section.GPRSize;
1788 Flags.cpr1_size = Section.CPR1Size;
1789 Flags.cpr2_size = Section.CPR2Size;
1790 Flags.fp_abi = Section.FpABI;
1791 Flags.isa_ext = Section.ISAExtension;
1792 Flags.ases = Section.ASEs;
1793 Flags.flags1 = Section.Flags1;
1794 Flags.flags2 = Section.Flags2;
1795 CBA.write(Ptr: (const char *)&Flags, Size: sizeof(Flags));
1796}
1797
1798template <class ELFT>
1799void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1800 const ELFYAML::DynamicSection &Section,
1801 ContiguousBlobAccumulator &CBA) {
1802 assert(Section.Type == llvm::ELF::SHT_DYNAMIC &&
1803 "Section type is not SHT_DYNAMIC");
1804
1805 if (!Section.Entries)
1806 return;
1807
1808 for (const ELFYAML::DynamicEntry &DE : *Section.Entries) {
1809 CBA.write<uintX_t>(DE.Tag, ELFT::Endianness);
1810 CBA.write<uintX_t>(DE.Val, ELFT::Endianness);
1811 }
1812 SHeader.sh_size = 2 * sizeof(uintX_t) * Section.Entries->size();
1813}
1814
1815template <class ELFT>
1816void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1817 const ELFYAML::AddrsigSection &Section,
1818 ContiguousBlobAccumulator &CBA) {
1819 if (!Section.Symbols)
1820 return;
1821
1822 for (StringRef Sym : *Section.Symbols)
1823 SHeader.sh_size +=
1824 CBA.writeULEB128(Val: toSymbolIndex(S: Sym, LocSec: Section.Name, /*IsDynamic=*/false));
1825}
1826
1827template <class ELFT>
1828void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1829 const ELFYAML::NoteSection &Section,
1830 ContiguousBlobAccumulator &CBA) {
1831 if (!Section.Notes || Section.Notes->empty())
1832 return;
1833
1834 unsigned Align;
1835 switch (Section.AddressAlign) {
1836 case 0:
1837 case 4:
1838 Align = 4;
1839 break;
1840 case 8:
1841 Align = 8;
1842 break;
1843 default:
1844 reportError(Section.Name + ": invalid alignment for a note section: 0x" +
1845 Twine::utohexstr(Val: Section.AddressAlign));
1846 return;
1847 }
1848
1849 if (CBA.getOffset() != alignTo(Value: CBA.getOffset(), Align)) {
1850 reportError(Section.Name + ": invalid offset of a note section: 0x" +
1851 Twine::utohexstr(Val: CBA.getOffset()) + ", should be aligned to " +
1852 Twine(Align));
1853 return;
1854 }
1855
1856 uint64_t Offset = CBA.tell();
1857 for (const ELFYAML::NoteEntry &NE : *Section.Notes) {
1858 // Write name size.
1859 if (NE.Name.empty())
1860 CBA.write<uint32_t>(0, ELFT::Endianness);
1861 else
1862 CBA.write<uint32_t>(NE.Name.size() + 1, ELFT::Endianness);
1863
1864 // Write description size.
1865 if (NE.Desc.binary_size() == 0)
1866 CBA.write<uint32_t>(0, ELFT::Endianness);
1867 else
1868 CBA.write<uint32_t>(NE.Desc.binary_size(), ELFT::Endianness);
1869
1870 // Write type.
1871 CBA.write<uint32_t>(NE.Type, ELFT::Endianness);
1872
1873 // Write name, null terminator and padding.
1874 if (!NE.Name.empty()) {
1875 CBA.write(Ptr: NE.Name.data(), Size: NE.Name.size());
1876 CBA.write(C: '\0');
1877 }
1878
1879 // Write description and padding.
1880 if (NE.Desc.binary_size() != 0) {
1881 CBA.padToAlignment(Align);
1882 CBA.writeAsBinary(Bin: NE.Desc);
1883 }
1884
1885 CBA.padToAlignment(Align);
1886 }
1887
1888 SHeader.sh_size = CBA.tell() - Offset;
1889}
1890
1891template <class ELFT>
1892void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1893 const ELFYAML::GnuHashSection &Section,
1894 ContiguousBlobAccumulator &CBA) {
1895 if (!Section.HashBuckets)
1896 return;
1897
1898 if (!Section.Header)
1899 return;
1900
1901 // We write the header first, starting with the hash buckets count. Normally
1902 // it is the number of entries in HashBuckets, but the "NBuckets" property can
1903 // be used to override this field, which is useful for producing broken
1904 // objects.
1905 if (Section.Header->NBuckets)
1906 CBA.write<uint32_t>(*Section.Header->NBuckets, ELFT::Endianness);
1907 else
1908 CBA.write<uint32_t>(Section.HashBuckets->size(), ELFT::Endianness);
1909
1910 // Write the index of the first symbol in the dynamic symbol table accessible
1911 // via the hash table.
1912 CBA.write<uint32_t>(Section.Header->SymNdx, ELFT::Endianness);
1913
1914 // Write the number of words in the Bloom filter. As above, the "MaskWords"
1915 // property can be used to set this field to any value.
1916 if (Section.Header->MaskWords)
1917 CBA.write<uint32_t>(*Section.Header->MaskWords, ELFT::Endianness);
1918 else
1919 CBA.write<uint32_t>(Section.BloomFilter->size(), ELFT::Endianness);
1920
1921 // Write the shift constant used by the Bloom filter.
1922 CBA.write<uint32_t>(Section.Header->Shift2, ELFT::Endianness);
1923
1924 // We've finished writing the header. Now write the Bloom filter.
1925 for (llvm::yaml::Hex64 Val : *Section.BloomFilter)
1926 CBA.write<uintX_t>(Val, ELFT::Endianness);
1927
1928 // Write an array of hash buckets.
1929 for (llvm::yaml::Hex32 Val : *Section.HashBuckets)
1930 CBA.write<uint32_t>(Val, ELFT::Endianness);
1931
1932 // Write an array of hash values.
1933 for (llvm::yaml::Hex32 Val : *Section.HashValues)
1934 CBA.write<uint32_t>(Val, ELFT::Endianness);
1935
1936 SHeader.sh_size = 16 /*Header size*/ +
1937 Section.BloomFilter->size() * sizeof(typename ELFT::uint) +
1938 Section.HashBuckets->size() * 4 +
1939 Section.HashValues->size() * 4;
1940}
1941
1942template <class ELFT>
1943void ELFState<ELFT>::writeFill(ELFYAML::Fill &Fill,
1944 ContiguousBlobAccumulator &CBA) {
1945 size_t PatternSize = Fill.Pattern ? Fill.Pattern->binary_size() : 0;
1946 if (!PatternSize) {
1947 CBA.writeZeros(Num: Fill.Size);
1948 return;
1949 }
1950
1951 // Fill the content with the specified pattern.
1952 uint64_t Written = 0;
1953 for (; Written + PatternSize <= Fill.Size; Written += PatternSize)
1954 CBA.writeAsBinary(Bin: *Fill.Pattern);
1955 CBA.writeAsBinary(Bin: *Fill.Pattern, N: Fill.Size - Written);
1956}
1957
1958template <class ELFT>
1959DenseMap<StringRef, size_t> ELFState<ELFT>::buildSectionHeaderReorderMap() {
1960 const ELFYAML::SectionHeaderTable &SectionHeaders =
1961 Doc.getSectionHeaderTable();
1962 if (SectionHeaders.IsImplicit || SectionHeaders.NoHeaders ||
1963 SectionHeaders.isDefault())
1964 return DenseMap<StringRef, size_t>();
1965
1966 DenseMap<StringRef, size_t> Ret;
1967 size_t SecNdx = 0;
1968 StringSet<> Seen;
1969
1970 auto AddSection = [&](const ELFYAML::SectionHeader &Hdr) {
1971 if (!Ret.try_emplace(Key: Hdr.Name, Args&: ++SecNdx).second)
1972 reportError("repeated section name: '" + Hdr.Name +
1973 "' in the section header description");
1974 Seen.insert(key: Hdr.Name);
1975 };
1976
1977 if (SectionHeaders.Sections)
1978 for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Sections)
1979 AddSection(Hdr);
1980
1981 if (SectionHeaders.Excluded)
1982 for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Excluded)
1983 AddSection(Hdr);
1984
1985 for (const ELFYAML::Section *S : Doc.getSections()) {
1986 // Ignore special first SHT_NULL section.
1987 if (S == Doc.getSections().front())
1988 continue;
1989 if (!Seen.count(Key: S->Name))
1990 reportError("section '" + S->Name +
1991 "' should be present in the 'Sections' or 'Excluded' lists");
1992 Seen.erase(Key: S->Name);
1993 }
1994
1995 for (const auto &It : Seen)
1996 reportError("section header contains undefined section '" + It.getKey() +
1997 "'");
1998 return Ret;
1999}
2000
2001template <class ELFT> void ELFState<ELFT>::buildSectionIndex() {
2002 // A YAML description can have an explicit section header declaration that
2003 // allows to change the order of section headers.
2004 DenseMap<StringRef, size_t> ReorderMap = buildSectionHeaderReorderMap();
2005
2006 if (HasError)
2007 return;
2008
2009 // Build excluded section headers map.
2010 std::vector<ELFYAML::Section *> Sections = Doc.getSections();
2011 const ELFYAML::SectionHeaderTable &SectionHeaders =
2012 Doc.getSectionHeaderTable();
2013 if (SectionHeaders.Excluded)
2014 for (const ELFYAML::SectionHeader &Hdr : *SectionHeaders.Excluded)
2015 if (!ExcludedSectionHeaders.insert(key: Hdr.Name).second)
2016 llvm_unreachable("buildSectionIndex() failed");
2017
2018 if (SectionHeaders.NoHeaders.value_or(u: false))
2019 for (const ELFYAML::Section *S : Sections)
2020 if (!ExcludedSectionHeaders.insert(key: S->Name).second)
2021 llvm_unreachable("buildSectionIndex() failed");
2022
2023 size_t SecNdx = -1;
2024 for (const ELFYAML::Section *S : Sections) {
2025 ++SecNdx;
2026
2027 size_t Index = ReorderMap.empty() ? SecNdx : ReorderMap.lookup(Val: S->Name);
2028 if (!SN2I.addName(Name: S->Name, Ndx: Index))
2029 llvm_unreachable("buildSectionIndex() failed");
2030
2031 if (!ExcludedSectionHeaders.count(Key: S->Name))
2032 ShStrtabStrings->add(S: ELFYAML::dropUniqueSuffix(S: S->Name));
2033 }
2034}
2035
2036template <class ELFT> void ELFState<ELFT>::buildSymbolIndexes() {
2037 auto Build = [this](ArrayRef<ELFYAML::Symbol> V, NameToIdxMap &Map) {
2038 for (size_t I = 0, S = V.size(); I < S; ++I) {
2039 const ELFYAML::Symbol &Sym = V[I];
2040 if (!Sym.Name.empty() && !Map.addName(Name: Sym.Name, Ndx: I + 1))
2041 reportError("repeated symbol name: '" + Sym.Name + "'");
2042 }
2043 };
2044
2045 if (Doc.Symbols)
2046 Build(*Doc.Symbols, SymN2I);
2047 if (Doc.DynamicSymbols)
2048 Build(*Doc.DynamicSymbols, DynSymN2I);
2049}
2050
2051template <class ELFT> void ELFState<ELFT>::finalizeStrings() {
2052 // Add the regular symbol names to .strtab section.
2053 if (Doc.Symbols)
2054 for (const ELFYAML::Symbol &Sym : *Doc.Symbols)
2055 DotStrtab.add(S: ELFYAML::dropUniqueSuffix(S: Sym.Name));
2056 DotStrtab.finalize();
2057
2058 // Add the dynamic symbol names to .dynstr section.
2059 if (Doc.DynamicSymbols)
2060 for (const ELFYAML::Symbol &Sym : *Doc.DynamicSymbols)
2061 DotDynstr.add(S: ELFYAML::dropUniqueSuffix(S: Sym.Name));
2062
2063 // SHT_GNU_verdef and SHT_GNU_verneed sections might also
2064 // add strings to .dynstr section.
2065 for (const ELFYAML::Chunk *Sec : Doc.getSections()) {
2066 if (auto VerNeed = dyn_cast<ELFYAML::VerneedSection>(Val: Sec)) {
2067 if (VerNeed->VerneedV) {
2068 for (const ELFYAML::VerneedEntry &VE : *VerNeed->VerneedV) {
2069 DotDynstr.add(S: VE.File);
2070 for (const ELFYAML::VernauxEntry &Aux : VE.AuxV)
2071 DotDynstr.add(S: Aux.Name);
2072 }
2073 }
2074 } else if (auto VerDef = dyn_cast<ELFYAML::VerdefSection>(Val: Sec)) {
2075 if (VerDef->Entries)
2076 for (const ELFYAML::VerdefEntry &E : *VerDef->Entries)
2077 for (StringRef Name : E.VerNames)
2078 DotDynstr.add(S: Name);
2079 }
2080 }
2081
2082 DotDynstr.finalize();
2083
2084 // Don't finalize the section header string table a second time if it has
2085 // already been finalized due to being one of the symbol string tables.
2086 if (ShStrtabStrings != &DotStrtab && ShStrtabStrings != &DotDynstr)
2087 ShStrtabStrings->finalize();
2088}
2089
2090template <class ELFT>
2091bool ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc,
2092 yaml::ErrorHandler EH, uint64_t MaxSize) {
2093 ELFState<ELFT> State(Doc, EH);
2094 if (State.HasError)
2095 return false;
2096
2097 // Build the section index, which adds sections to the section header string
2098 // table first, so that we can finalize the section header string table.
2099 State.buildSectionIndex();
2100 State.buildSymbolIndexes();
2101
2102 // Finalize section header string table and the .strtab and .dynstr sections.
2103 // We do this early because we want to finalize the string table builders
2104 // before writing the content of the sections that might want to use them.
2105 State.finalizeStrings();
2106
2107 if (State.HasError)
2108 return false;
2109
2110 std::vector<Elf_Phdr> PHeaders;
2111 State.initProgramHeaders(PHeaders);
2112
2113 // XXX: This offset is tightly coupled with the order that we write
2114 // things to `OS`.
2115 const size_t SectionContentBeginOffset =
2116 sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * Doc.ProgramHeaders.size();
2117 // It is quite easy to accidentally create output with yaml2obj that is larger
2118 // than intended, for example, due to an issue in the YAML description.
2119 // We limit the maximum allowed output size, but also provide a command line
2120 // option to change this limitation.
2121 ContiguousBlobAccumulator CBA(SectionContentBeginOffset, MaxSize);
2122
2123 std::vector<Elf_Shdr> SHeaders;
2124 State.initSectionHeaders(SHeaders, CBA);
2125
2126 // Now we can decide segment offsets.
2127 State.setProgramHeaderLayout(PHeaders, SHeaders);
2128
2129 // Override section fields, if requested. This needs to happen after program
2130 // header layout happens, because otherwise the layout will use the new
2131 // values.
2132 State.overrideSectionHeaders(SHeaders);
2133
2134 bool ReachedLimit = CBA.getOffset() > MaxSize;
2135 if (Error E = CBA.takeLimitError()) {
2136 // We report a custom error message instead below.
2137 consumeError(Err: std::move(E));
2138 ReachedLimit = true;
2139 }
2140
2141 if (ReachedLimit)
2142 State.reportError(
2143 "the desired output size is greater than permitted. Use the "
2144 "--max-size option to change the limit");
2145
2146 if (State.HasError)
2147 return false;
2148
2149 State.writeELFHeader(OS);
2150 writeArrayData(OS, ArrayRef(PHeaders));
2151
2152 const ELFYAML::SectionHeaderTable &SHT = Doc.getSectionHeaderTable();
2153 if (!SHT.NoHeaders.value_or(u: false))
2154 CBA.updateDataAt(Pos: *SHT.Offset, Data: SHeaders.data(),
2155 Size: SHT.getNumHeaders(SectionsNum: SHeaders.size()) * sizeof(Elf_Shdr));
2156
2157 CBA.writeBlobToStream(Out&: OS);
2158 return true;
2159}
2160
2161namespace llvm {
2162namespace yaml {
2163
2164bool yaml2elf(llvm::ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH,
2165 uint64_t MaxSize) {
2166 bool IsLE = Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB);
2167 bool Is64Bit = Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64);
2168 if (Is64Bit) {
2169 if (IsLE)
2170 return ELFState<object::ELF64LE>::writeELF(OS&: Out, Doc, EH, MaxSize);
2171 return ELFState<object::ELF64BE>::writeELF(OS&: Out, Doc, EH, MaxSize);
2172 }
2173 if (IsLE)
2174 return ELFState<object::ELF32LE>::writeELF(OS&: Out, Doc, EH, MaxSize);
2175 return ELFState<object::ELF32BE>::writeELF(OS&: Out, Doc, EH, MaxSize);
2176}
2177
2178} // namespace yaml
2179} // namespace llvm
2180