44class ContiguousBlobAccumulator {
45 const uint64_t InitialOffset;
46 const uint64_t MaxSize;
48 SmallVector<char, 128> Buf;
49 raw_svector_ostream OS;
52 bool checkLimit(uint64_t
Size) {
57 "reached the output size limit");
62 ContiguousBlobAccumulator(uint64_t BaseOffset, uint64_t
SizeLimit)
63 : InitialOffset(BaseOffset), MaxSize(
SizeLimit), OS(Buf) {}
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(); }
69 Error takeLimitError() {
72 return std::move(ReachedLimitErr);
76 uint64_t padToAlignment(
unsigned Align) {
81 uint64_t AlignedOffset =
alignTo(CurrentOffset, Align == 0 ? 1 : Align);
82 uint64_t PaddingSize = AlignedOffset - CurrentOffset;
83 if (!checkLimit(PaddingSize))
86 writeZeros(PaddingSize);
90 raw_ostream *getRawOS(uint64_t
Size) {
96 void writeAsBinary(
const yaml::BinaryRef &
Bin, uint64_t
N =
UINT64_MAX) {
97 if (!checkLimit(
Bin.binary_size()))
99 Bin.writeAsBinary(OS,
N);
102 void writeZeros(uint64_t Num) {
108 if (checkLimit(
Size))
112 void write(
unsigned char C) {
117 unsigned writeULEB128(uint64_t Val) {
118 if (!checkLimit(
sizeof(uint64_t)))
123 unsigned writeSLEB128(int64_t Val) {
130 if (checkLimit(
sizeof(
T)))
134 void updateDataAt(uint64_t Pos,
void *
Data,
size_t Size) {
136 memcpy(&Buf[Pos - InitialOffset],
Data,
Size);
143 StringMap<unsigned> Map;
147 bool addName(StringRef Name,
unsigned Ndx) {
148 return Map.insert({
Name, Ndx}).second;
151 bool lookup(StringRef Name,
unsigned &Idx)
const {
152 auto I = Map.find(Name);
159 unsigned get(StringRef Name)
const {
163 assert(
false &&
"Expected section not found in index");
166 unsigned size()
const {
return Map.size(); }
181template <
class ELFT>
class ELFState {
201 StringRef SectionHeaderStringTableName =
".shstrtab";
202 StringTableBuilder *ShStrtabStrings = &DotShStrtab;
206 NameToIdxMap DynSymN2I;
207 ELFYAML::Object &Doc;
209 std::vector<std::pair<Elf_Shdr *, ELFYAML::Section>>
210 SectionHeadersOverrideHelper;
212 StringSet<> ExcludedSectionHeaders;
214 uint64_t LocationCounter = 0;
215 bool HasError =
false;
221 const StringTableBuilder &Strtab);
222 unsigned toSectionIndex(StringRef S, StringRef LocSec, StringRef LocSym =
"");
223 unsigned toSymbolIndex(StringRef S, StringRef LocSec,
bool IsDynamic);
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);
246 std::vector<Fragment>
247 getPhdrFragments(
const ELFYAML::ProgramHeader &Phdr,
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);
316 void writeFill(ELFYAML::Fill &Fill, ContiguousBlobAccumulator &CBA);
320 void assignSectionAddress(Elf_Shdr &SHeader, ELFYAML::Section *YAMLSec);
322 DenseMap<StringRef, size_t> buildSectionHeaderReorderMap();
325 uint64_t alignToOffset(ContiguousBlobAccumulator &CBA, uint64_t Align,
326 std::optional<llvm::yaml::Hex64>
Offset);
328 uint64_t getSectionNameOffset(StringRef Name);
331 static bool writeELF(raw_ostream &OS, ELFYAML::Object &Doc,
337 return A.size() *
sizeof(
T);
344template <
class T>
static void zero(
T &Obj) { memset(&Obj, 0,
sizeof(Obj)); }
348 : Doc(
D), ErrHandler(EH) {
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;
361 std::vector<ELFYAML::Section *> Sections = Doc.getSections();
366 std::make_unique<ELFYAML::Section>(
371 for (
size_t I = 0;
I < Doc.Chunks.size(); ++
I) {
372 const std::unique_ptr<ELFYAML::Chunk> &
C = Doc.Chunks[
I];
377 reportError(
"multiple section header tables are not allowed");
385 if (
C->Name.empty()) {
392 if (!DocSections.insert(
C->Name).second)
394 "' at YAML section/fill number " +
Twine(
I));
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(
".dynsym");
403 ImplicitSections.insert(
".dynstr");
406 if (SectionHeaderStringTableName ==
".symtab")
407 reportError(
"cannot use '.symtab' as the section header name table when "
408 "there are symbols");
409 ImplicitSections.insert(
".symtab");
412 for (
StringRef DebugSecName : Doc.DWARF->getNonEmptySectionNames()) {
413 std::string SecName = (
"." + DebugSecName).str();
416 if (SectionHeaderStringTableName == SecName)
417 reportError(
"cannot use '" + SecName +
418 "' as the section header name table when it is needed for "
420 ImplicitSections.insert(StringRef(SecName).copy(StringAlloc));
423 ImplicitSections.
insert(
".strtab");
424 if (!SecHdrTable || !SecHdrTable->NoHeaders.value_or(
false))
425 ImplicitSections.
insert(SectionHeaderStringTableName);
430 if (DocSections.count(SecName))
433 std::unique_ptr<ELFYAML::Section> Sec = std::make_unique<ELFYAML::Section>(
437 if (SecName == SectionHeaderStringTableName)
439 else if (SecName ==
".dynsym")
441 else if (SecName ==
".symtab")
451 if (Doc.Chunks.back().get() == SecHdrTable)
452 Doc.Chunks.insert(Doc.Chunks.end() - 1, std::move(Sec));
454 Doc.Chunks.push_back(std::move(Sec));
460 Doc.Chunks.push_back(
461 std::make_unique<ELFYAML::SectionHeaderTable>(
true));
465void ELFState<ELFT>::writeELFHeader(
raw_ostream &OS) {
470 Header.e_ident[
EI_MAG0] = 0x7f;
475 Header.e_ident[
EI_DATA] = Doc.Header.Data;
477 Header.e_ident[
EI_OSABI] = Doc.Header.OSABI;
479 Header.e_type = Doc.Header.Type;
481 if (Doc.Header.Machine)
482 Header.e_machine = *Doc.Header.Machine;
487 Header.e_entry = Doc.Header.Entry;
488 if (Doc.Header.Flags)
489 Header.e_flags = *Doc.Header.Flags;
493 Header.e_ehsize =
sizeof(Elf_Ehdr);
495 if (Doc.Header.EPhOff)
496 Header.e_phoff = *Doc.Header.EPhOff;
497 else if (!Doc.ProgramHeaders.empty())
498 Header.e_phoff =
sizeof(Header);
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);
507 Header.e_phentsize = 0;
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();
516 Header.e_shentsize = Doc.Header.EShEntSize ? (
uint16_t)*Doc.Header.EShEntSize
520 Doc.getSectionHeaderTable();
522 if (Doc.Header.EShOff)
523 Header.e_shoff = *Doc.Header.EShOff;
525 Header.e_shoff = *SectionHeaders.
Offset;
529 if (Doc.Header.EShNum)
530 Header.e_shnum = *Doc.Header.EShNum;
532 Header.e_shnum = SectionHeaders.
getNumHeaders(Doc.getSections().size());
534 if (Doc.Header.EShStrNdx)
535 Header.e_shstrndx = *Doc.Header.EShStrNdx;
537 !ExcludedSectionHeaders.count(SectionHeaderStringTableName))
538 Header.e_shstrndx = SN2I.get(SectionHeaderStringTableName);
540 Header.e_shstrndx = 0;
542 OS.
write((
const char *)&Header,
sizeof(Header));
546void ELFState<ELFT>::initProgramHeaders(std::vector<Elf_Phdr> &PHeaders) {
548 for (
size_t I = 0,
E = Doc.Chunks.size();
I !=
E; ++
I) {
549 NameToIndex[Doc.Chunks[
I]->Name] =
I + 1;
552 for (
size_t I = 0,
E = Doc.ProgramHeaders.size();
I !=
E; ++
I) {
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);
569 "' by the 'FirstSec' key of the program header with index " +
574 "' by the 'LastSec' key of the program header with index " +
581 ": the section index of " + *YamlPhdr.
FirstSec +
582 " is greater than the index of " + *YamlPhdr.
LastSec);
585 YamlPhdr.
Chunks.push_back(Doc.Chunks[
I - 1].get());
595 if (!SN2I.lookup(S, Index) && !
to_integer(S, Index)) {
597 reportError(
"unknown section referenced: '" + S +
"' by YAML symbol '" +
600 reportError(
"unknown section referenced: '" + S +
"' by YAML section '" +
606 Doc.getSectionHeaderTable();
613 size_t FirstExcluded =
615 if (Index > FirstExcluded) {
617 reportError(
"unable to link '" + LocSec +
"' to excluded section '" + S +
620 reportError(
"excluded section referenced: '" + S +
"' by symbol '" +
629 const NameToIdxMap &
SymMap = IsDynamic ? DynSymN2I : SymN2I;
634 reportError(
"unknown symbol referenced: '" + S +
"' by YAML section '" +
650 To.sh_name = *From->
ShName;
654 To.sh_size = *From->
ShSize;
656 To.sh_type = *From->
ShType;
660bool ELFState<ELFT>::initImplicitHeader(ContiguousBlobAccumulator &CBA,
664 if (Header.sh_offset)
667 if (SecName ==
".strtab")
668 initStrtabSectionHeader(Header, SecName, DotStrtab, CBA, YAMLSec);
669 else if (SecName ==
".dynstr")
670 initStrtabSectionHeader(Header, SecName, DotDynstr, CBA, YAMLSec);
671 else if (SecName == SectionHeaderStringTableName)
672 initStrtabSectionHeader(Header, SecName, *ShStrtabStrings, CBA, YAMLSec);
673 else if (SecName ==
".symtab")
674 initSymtabSectionHeader(Header, SymtabType::Static, CBA, YAMLSec);
675 else if (SecName ==
".dynsym")
676 initSymtabSectionHeader(Header, SymtabType::Dynamic, CBA, YAMLSec);
682 initDWARFSectionHeader(Header, SecName, CBA, YAMLSec);
686 LocationCounter += Header.sh_size;
699 std::string Ret = Name.empty() ?
"" : Name.str() +
' ';
714 return S.
substr(0, SuffixPos - 1);
721 if (ExcludedSectionHeaders.count(Name))
723 return ShStrtabStrings->getOffset(Name);
727 const std::optional<yaml::BinaryRef> &Content,
728 const std::optional<llvm::yaml::Hex64> &
Size) {
729 size_t ContentSize = 0;
731 CBA.writeAsBinary(*Content);
732 ContentSize = Content->binary_size();
738 CBA.writeZeros(*
Size - ContentSize);
766void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
767 ContiguousBlobAccumulator &CBA) {
770 SHeaders.resize(Doc.getSections().size());
772 for (
const std::unique_ptr<ELFYAML::Chunk> &
D : Doc.Chunks) {
774 S->Offset = alignToOffset(CBA, 1, S->Offset);
776 LocationCounter += S->Size;
782 if (S->NoHeaders.value_or(
false))
786 S->Offset = alignToOffset(CBA,
sizeof(
typename ELFT::uint),
789 S->Offset = alignToOffset(CBA, 1, S->Offset);
791 uint64_t Size = S->getNumHeaders(SHeaders.size()) *
sizeof(Elf_Shdr);
794 CBA.writeZeros(
Size);
795 LocationCounter +=
Size;
800 bool IsFirstUndefSection = Sec == Doc.getSections().front();
804 Elf_Shdr &SHeader = SHeaders[SN2I.get(Sec->
Name)];
806 SHeader.sh_link = toSectionIndex(*Sec->
Link, Sec->
Name);
810 if (!LinkSec.
empty() && !ExcludedSectionHeaders.count(LinkSec) &&
811 SN2I.lookup(LinkSec, Link))
812 SHeader.sh_link = Link;
816 SHeader.sh_entsize = *Sec->
EntSize;
825 if (initImplicitHeader(CBA, SHeader, Sec->
Name,
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.");
834 SHeader.sh_type = Sec->
Type;
836 SHeader.sh_flags = *Sec->
Flags;
841 if (!IsFirstUndefSection || Sec->
Offset)
842 SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign, Sec->
Offset);
844 assignSectionAddress(SHeader, Sec);
846 if (IsFirstUndefSection) {
850 SHeader.sh_size = *RawSec->Size;
852 SHeader.sh_info = *RawSec->Info;
855 LocationCounter += SHeader.sh_size;
856 SectionHeadersOverrideHelper.push_back({&SHeader, *Sec});
864 writeSectionContent(SHeader, *S, CBA);
866 writeSectionContent(SHeader, *S, CBA);
868 writeSectionContent(SHeader, *S, CBA);
870 writeSectionContent(SHeader, *S, CBA);
872 writeSectionContent(SHeader, *S, CBA);
874 writeSectionContent(SHeader, *S, CBA);
876 writeSectionContent(SHeader, *S, CBA);
878 writeSectionContent(SHeader, *S, CBA);
880 writeSectionContent(SHeader, *S, CBA);
882 writeSectionContent(SHeader, *S, CBA);
884 writeSectionContent(SHeader, *S, CBA);
886 writeSectionContent(SHeader, *S, CBA);
888 writeSectionContent(SHeader, *S, CBA);
890 writeSectionContent(SHeader, *S, CBA);
892 writeSectionContent(SHeader, *S, CBA);
894 writeSectionContent(SHeader, *S, CBA);
896 writeSectionContent(SHeader, *S, CBA);
898 writeSectionContent(SHeader, *S, CBA);
900 writeSectionContent(SHeader, *S, CBA);
902 writeSectionContent(SHeader, *S, CBA);
904 writeSectionContent(SHeader, *S, CBA);
909 LocationCounter += SHeader.sh_size;
910 SectionHeadersOverrideHelper.push_back({&SHeader, *Sec});
915void ELFState<ELFT>::overrideSectionHeaders(std::vector<Elf_Shdr> &SHeaders) {
916 for (std::pair<Elf_Shdr *, ELFYAML::Section> &HeaderAndSec :
917 SectionHeadersOverrideHelper)
922void ELFState<ELFT>::assignSectionAddress(Elf_Shdr &SHeader,
924 if (YAMLSec && YAMLSec->
Address) {
925 SHeader.sh_addr = *YAMLSec->
Address;
926 LocationCounter = *YAMLSec->
Address;
938 alignTo(LocationCounter, SHeader.sh_addralign ? SHeader.sh_addralign : 1);
939 SHeader.sh_addr = LocationCounter;
943 for (
size_t I = 0;
I < Symbols.size(); ++
I)
946 return Symbols.size();
950std::vector<typename ELFT::Sym>
953 std::vector<Elf_Sym>
Ret;
958 Elf_Sym &Symbol =
Ret[++
I];
964 Symbol.st_name = *Sym.StName;
965 else if (!Sym.Name.empty())
968 Symbol.setBindingAndType(Sym.Binding, Sym.Type);
970 Symbol.st_shndx = toSectionIndex(*Sym.Section,
"", Sym.Name);
972 Symbol.st_shndx = *Sym.Index;
974 Symbol.st_value = Sym.Value.value_or(yaml::Hex64(0));
975 Symbol.st_other = Sym.Other.value_or(0);
976 Symbol.st_size = Sym.Size.value_or(yaml::Hex64(0));
983void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader,
985 ContiguousBlobAccumulator &CBA,
988 bool IsStatic = STType == SymtabType::Static;
990 if (IsStatic && Doc.Symbols)
992 else if (!IsStatic && Doc.DynamicSymbols)
998 bool HasSymbolsDescription =
999 (IsStatic && Doc.Symbols) || (!IsStatic && Doc.DynamicSymbols);
1000 if (HasSymbolsDescription) {
1003 reportError(
"cannot specify both `Content` and " + Property +
1004 " for symbol table section '" + RawSec->
Name +
"'");
1006 reportError(
"cannot specify both `Size` and " + Property +
1007 " for symbol table section '" + RawSec->
Name +
"'");
1012 SHeader.sh_name = getSectionNameOffset(IsStatic ?
".symtab" :
".dynsym");
1015 SHeader.sh_type = YAMLSec->
Type;
1019 if (YAMLSec && YAMLSec->
Flags)
1020 SHeader.sh_flags = *YAMLSec->
Flags;
1026 SHeader.sh_info = (RawSec && RawSec->
Info) ? (
unsigned)(*RawSec->
Info)
1030 assignSectionAddress(SHeader, YAMLSec);
1032 SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign,
1033 RawSec ? RawSec->
Offset : std::nullopt);
1035 if (RawSec && (RawSec->
Content || RawSec->
Size)) {
1041 std::vector<Elf_Sym> Syms =
1042 toELFSymbols(Symbols, IsStatic ? DotStrtab : DotDynstr);
1043 SHeader.sh_size = Syms.size() *
sizeof(Elf_Sym);
1044 CBA.write((
const char *)Syms.data(), SHeader.sh_size);
1047template <
class ELFT>
1048void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader,
StringRef Name,
1050 ContiguousBlobAccumulator &CBA,
1059 SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign,
1060 YAMLSec ? YAMLSec->
Offset : std::nullopt);
1062 if (RawSec && (RawSec->
Content || RawSec->
Size)) {
1067 SHeader.sh_size = STB.
getSize();
1070 if (RawSec && RawSec->
Info)
1071 SHeader.sh_info = *RawSec->
Info;
1073 if (YAMLSec && YAMLSec->
Flags)
1074 SHeader.sh_flags = *YAMLSec->
Flags;
1075 else if (Name ==
".dynstr")
1078 assignSectionAddress(SHeader, YAMLSec);
1083 return Name.consume_front(
".") && DebugSecNames.
count(Name);
1086template <
class ELFT>
1089 ContiguousBlobAccumulator &CBA) {
1100 if (
Error Err = EmitFunc(*OS, DWARF))
1101 return std::move(Err);
1103 return CBA.tell() - BeginOffset;
1106template <
class ELFT>
1107void ELFState<ELFT>::initDWARFSectionHeader(Elf_Shdr &SHeader,
StringRef Name,
1108 ContiguousBlobAccumulator &CBA,
1113 SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign,
1114 YAMLSec ? YAMLSec->
Offset : std::nullopt);
1121 "' contents in the 'DWARF' entry and the 'Content' "
1122 "or 'Size' in the 'Sections' entry at the same time");
1126 SHeader.sh_size = *ShSizeOrErr;
1134 "entry or a RawContentSection");
1136 if (RawSec && RawSec->
Info)
1137 SHeader.sh_info = *RawSec->
Info;
1139 if (YAMLSec && YAMLSec->
Flags)
1140 SHeader.sh_flags = *YAMLSec->
Flags;
1141 else if (Name ==
".debug_str")
1144 assignSectionAddress(SHeader, YAMLSec);
1147template <
class ELFT>
void ELFState<ELFT>::reportError(
const Twine &Msg) {
1152template <
class ELFT>
void ELFState<ELFT>::reportError(
Error Err) {
1158template <
class ELFT>
1159std::vector<Fragment>
1162 std::vector<Fragment>
Ret;
1171 const Elf_Shdr &
H = SHeaders[SN2I.get(S->
Name)];
1172 Ret.push_back({
H.sh_offset,
H.sh_size,
H.sh_type,
H.sh_addralign});
1177template <
class ELFT>
1178void ELFState<ELFT>::setProgramHeaderLayout(std::vector<Elf_Phdr> &PHeaders,
1179 std::vector<Elf_Shdr> &SHeaders) {
1181 for (
auto &YamlPhdr : Doc.ProgramHeaders) {
1182 Elf_Phdr &PHeader = PHeaders[PhdrIdx++];
1183 std::vector<Fragment> Fragments = getPhdrFragments(YamlPhdr, SHeaders);
1185 return A.Offset <
B.Offset;
1187 reportError(
"sections in the program header with index " +
1188 Twine(PhdrIdx) +
" are not sorted by their file offset");
1191 if (!Fragments.empty() && *YamlPhdr.
Offset > Fragments.front().Offset)
1193 " must be less than or equal to the minimum file offset of "
1194 "all included sections (0x" +
1196 PHeader.p_offset = *YamlPhdr.
Offset;
1197 }
else if (!Fragments.empty()) {
1198 PHeader.p_offset = Fragments.front().Offset;
1203 PHeader.p_filesz = *YamlPhdr.
FileSize;
1204 }
else if (!Fragments.empty()) {
1205 uint64_t FileSize = Fragments.back().Offset - PHeader.p_offset;
1210 FileSize += Fragments.back().Size;
1211 PHeader.p_filesz = FileSize;
1215 uint64_t MemOffset = PHeader.p_offset;
1216 for (
const Fragment &
F : Fragments)
1217 MemOffset = std::max(MemOffset,
F.Offset +
F.Size);
1220 : MemOffset - PHeader.p_offset;
1222 if (YamlPhdr.
Align) {
1223 PHeader.p_align = *YamlPhdr.
Align;
1228 PHeader.p_align = 1;
1229 for (
const Fragment &
F : Fragments)
1230 PHeader.p_align = std::max((
uint64_t)PHeader.p_align,
F.AddrAlign);
1241 return (isa<ELFYAML::Fill>(C) ||
1242 cast<ELFYAML::Section>(C)->Type != ELF::SHT_NOBITS);
1249template <
class ELFT>
1250void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1252 ContiguousBlobAccumulator &CBA) {
1256 SHeader.sh_size = *S.
Size;
1261 if (shouldAllocateFileSpace(Doc.ProgramHeaders, S))
1262 CBA.writeZeros(*S.
Size);
1265template <
class ELFT>
1266void ELFState<ELFT>::writeSectionContent(
1268 ContiguousBlobAccumulator &CBA) {
1270 SHeader.sh_info = *Section.Info;
1279template <
class ELFT>
1280void ELFState<ELFT>::writeSectionContent(
1282 ContiguousBlobAccumulator &CBA) {
1286 "Section type is not SHT_REL nor SHT_RELA");
1288 if (!
Section.RelocatableSec.empty())
1289 SHeader.sh_info = toSectionIndex(
Section.RelocatableSec,
Section.Name);
1296 typename ELFT::uint OffsetMask = 8,
Offset = 0, Addend = 0;
1298 uint64_t CurrentOffset = CBA.getOffset();
1301 OffsetMask |= Rel.
Offset;
1307 const bool IsDynamic =
Section.Link && (*
Section.Link ==
".dynsym");
1315 (
static_cast<typename ELFT::uint
>(Rel.
Offset) -
Offset) >> Shift;
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) {
1323 CBA.write(
B | 0x80);
1324 CBA.writeULEB128(DeltaOffset >> 4);
1329 std::make_signed_t<typename ELFT::uint>(CurSymIdx - SymIdx));
1333 CBA.writeSLEB128(
static_cast<int32_t
>(Rel.
Type -
Type));
1338 std::make_signed_t<typename ELFT::uint>(Rel.
Addend - Addend));
1341 }
else if (IsRela) {
1344 REntry.r_offset = Rel.
Offset;
1345 REntry.r_addend = Rel.
Addend;
1347 CBA.write((
const char *)&REntry,
sizeof(REntry));
1351 REntry.r_offset = Rel.
Offset;
1353 CBA.write((
const char *)&REntry,
sizeof(REntry));
1357 SHeader.sh_size = CBA.getOffset() - CurrentOffset;
1360template <
class ELFT>
1361void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1363 ContiguousBlobAccumulator &CBA) {
1367 for (llvm::yaml::Hex64
E : *
Section.Entries) {
1368 if (!ELFT::Is64Bits &&
E > UINT32_MAX)
1371 CBA.write<uintX_t>(
E, ELFT::Endianness);
1374 SHeader.sh_size =
sizeof(uintX_t) *
Section.Entries->size();
1377template <
class ELFT>
1378void ELFState<ELFT>::writeSectionContent(
1380 ContiguousBlobAccumulator &CBA) {
1390 CBA.write<
uint32_t>(
E, ELFT::Endianness);
1391 SHeader.sh_size = Shndx.
Entries->size() * SHeader.sh_entsize;
1394template <
class ELFT>
1395void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1397 ContiguousBlobAccumulator &CBA) {
1399 "Section type is not SHT_GROUP");
1409 unsigned int SectionIndex = 0;
1410 if (
Member.sectionNameOrType ==
"GRP_COMDAT")
1413 SectionIndex = toSectionIndex(
Member.sectionNameOrType,
Section.Name);
1414 CBA.write<
uint32_t>(SectionIndex, ELFT::Endianness);
1416 SHeader.sh_size = SHeader.sh_entsize *
Section.Members->size();
1419template <
class ELFT>
1420void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1422 ContiguousBlobAccumulator &CBA) {
1427 CBA.write<
uint16_t>(Version, ELFT::Endianness);
1428 SHeader.sh_size =
Section.Entries->size() * SHeader.sh_entsize;
1431template <
class ELFT>
1432void ELFState<ELFT>::writeSectionContent(
1434 ContiguousBlobAccumulator &CBA) {
1439 CBA.write<uintX_t>(
E.Address, ELFT::Endianness);
1440 SHeader.sh_size +=
sizeof(uintX_t) + CBA.writeULEB128(
E.Size);
1444template <
class ELFT>
1445void ELFState<ELFT>::writeSectionContent(
1447 ContiguousBlobAccumulator &CBA) {
1451 <<
"PGOAnalyses should not exist in SHT_LLVM_BB_ADDR_MAP when "
1452 "Entries does not exist";
1456 const std::vector<ELFYAML::PGOAnalysisMapEntry> *PGOAnalyses =
nullptr;
1460 "in SHT_LLVM_BB_ADDR_MAP";
1462 PGOAnalyses = &
Section.PGOAnalyses.value();
1470 <<
static_cast<int>(
E.Version)
1471 <<
"; encoding using the most recent version";
1472 CBA.write(
E.Version);
1473 SHeader.sh_size += 1;
1474 if (
E.Version < 5) {
1475 CBA.write(
static_cast<uint8_t>(
E.Feature));
1476 SHeader.sh_size += 1;
1478 CBA.write<
uint16_t>(
E.Feature, ELFT::Endianness);
1479 SHeader.sh_size += 2;
1483 bool MultiBBRangeFeatureEnabled =
false;
1487 MultiBBRangeFeatureEnabled = FeatureOrErr->MultiBBRange;
1489 MultiBBRangeFeatureEnabled ||
1490 (
E.NumBBRanges.has_value() &&
E.NumBBRanges.value() != 1) ||
1491 (
E.BBRanges &&
E.BBRanges->size() != 1);
1492 if (MultiBBRange && !MultiBBRangeFeatureEnabled)
1494 <<
") does not support multiple BB ranges.";
1499 E.NumBBRanges.value_or(
E.BBRanges ?
E.BBRanges->size() : 0);
1500 SHeader.sh_size += CBA.writeULEB128(NumBBRanges);
1505 bool EmitCallsiteEndOffsets =
1506 FeatureOrErr->CallsiteEndOffsets ||
E.hasAnyCallsiteEndOffsets();
1509 CBA.write<uintX_t>(BBR.
BaseAddress, ELFT::Endianness);
1515 SHeader.sh_size +=
sizeof(uintX_t) + CBA.writeULEB128(NumBlocks);
1517 if (!BBR.
BBEntries || FeatureOrErr->OmitBBEntries)
1522 SHeader.sh_size += CBA.writeULEB128(BBE.
ID);
1524 if (EmitCallsiteEndOffsets) {
1525 size_t NumCallsiteEndOffsets =
1527 SHeader.sh_size += CBA.writeULEB128(NumCallsiteEndOffsets);
1530 SHeader.sh_size += CBA.writeULEB128(
Offset);
1533 SHeader.sh_size += CBA.writeULEB128(BBE.
Size);
1534 SHeader.sh_size += CBA.writeULEB128(BBE.
Metadata);
1535 if (FeatureOrErr->BBHash || BBE.
Hash.has_value()) {
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;
1553 const auto &PGOBBEntries = PGOEntry.
PGOBBEntries.value();
1554 if (TotalNumBlocks != PGOBBEntries.size()) {
1556 "BBEntries in SHT_LLVM_BB_ADDR_MAP.\n"
1557 <<
"Mismatch on function with address: "
1558 <<
E.getFunctionAddress();
1562 for (
const auto &PGOBBE : PGOBBEntries) {
1564 SHeader.sh_size += CBA.writeULEB128(*PGOBBE.BBFreq);
1565 if (FeatureOrErr->PostLinkCfg || PGOBBE.PostLinkBBFreq.has_value())
1566 SHeader.sh_size += CBA.writeULEB128(PGOBBE.PostLinkBBFreq.value_or(0));
1567 if (PGOBBE.Successors) {
1568 SHeader.sh_size += CBA.writeULEB128(PGOBBE.Successors->size());
1569 for (
const auto &[
ID,
BrProb, PostLinkBrFreq] : *PGOBBE.Successors) {
1570 SHeader.sh_size += CBA.writeULEB128(
ID);
1571 SHeader.sh_size += CBA.writeULEB128(
BrProb);
1572 if (FeatureOrErr->PostLinkCfg || PostLinkBrFreq.has_value())
1573 SHeader.sh_size += CBA.writeULEB128(PostLinkBrFreq.value_or(0));
1580template <
class ELFT>
1581void ELFState<ELFT>::writeSectionContent(
1583 ContiguousBlobAccumulator &CBA) {
1588 CBA.write(
LO.Key.data(),
LO.Key.size());
1590 CBA.write(
LO.Value.data(),
LO.Value.size());
1592 SHeader.sh_size += (
LO.Key.size() +
LO.Value.size() + 2);
1596template <
class ELFT>
1597void ELFState<ELFT>::writeSectionContent(
1599 ContiguousBlobAccumulator &CBA) {
1604 CBA.write(
Lib.data(),
Lib.size());
1606 SHeader.sh_size +=
Lib.size() + 1;
1610template <
class ELFT>
1612ELFState<ELFT>::alignToOffset(ContiguousBlobAccumulator &CBA,
uint64_t Align,
1613 std::optional<llvm::yaml::Hex64>
Offset) {
1614 uint64_t CurrentOffset = CBA.getOffset();
1621 return CurrentOffset;
1630 CBA.writeZeros(AlignedOffset - CurrentOffset);
1631 return AlignedOffset;
1634template <
class ELFT>
1635void ELFState<ELFT>::writeSectionContent(
1637 ContiguousBlobAccumulator &CBA) {
1642 CBA.write<
uint64_t>(
E.Weight, ELFT::Endianness);
1647template <
class ELFT>
1648void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1650 ContiguousBlobAccumulator &CBA) {
1655 Section.NBucket.value_or(llvm::yaml::Hex64(
Section.Bucket->size())),
1658 Section.NChain.value_or(llvm::yaml::Hex64(
Section.Chain->size())),
1662 CBA.write<
uint32_t>(Val, ELFT::Endianness);
1664 CBA.write<
uint32_t>(Val, ELFT::Endianness);
1666 SHeader.sh_size = (2 +
Section.Bucket->size() +
Section.Chain->size()) * 4;
1669template <
class ELFT>
1670void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1672 ContiguousBlobAccumulator &CBA) {
1675 SHeader.sh_info = *
Section.Info;
1677 SHeader.sh_info =
Section.Entries->size();
1683 for (
size_t I = 0;
I <
Section.Entries->size(); ++
I) {
1687 VerDef.vd_version =
E.Version.value_or(1);
1688 VerDef.vd_flags =
E.Flags.value_or(0);
1689 VerDef.vd_ndx =
E.VersionNdx.value_or(0);
1690 VerDef.vd_hash =
E.Hash.value_or(0);
1691 VerDef.vd_aux =
E.VDAux.value_or(
sizeof(Elf_Verdef));
1692 VerDef.vd_cnt =
E.VerNames.size();
1693 if (
I ==
Section.Entries->size() - 1)
1697 sizeof(Elf_Verdef) +
E.VerNames.size() *
sizeof(Elf_Verdaux);
1698 CBA.write((
const char *)&VerDef,
sizeof(Elf_Verdef));
1700 for (
size_t J = 0; J <
E.VerNames.size(); ++J, ++AuxCnt) {
1701 Elf_Verdaux VerdAux;
1702 VerdAux.vda_name = DotDynstr.getOffset(
E.VerNames[J]);
1703 if (J ==
E.VerNames.size() - 1)
1704 VerdAux.vda_next = 0;
1706 VerdAux.vda_next =
sizeof(Elf_Verdaux);
1707 CBA.write((
const char *)&VerdAux,
sizeof(Elf_Verdaux));
1711 SHeader.sh_size =
Section.Entries->size() *
sizeof(Elf_Verdef) +
1712 AuxCnt *
sizeof(Elf_Verdaux);
1715template <
class ELFT>
1716void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1718 ContiguousBlobAccumulator &CBA) {
1720 SHeader.sh_info = *
Section.Info;
1722 SHeader.sh_info =
Section.VerneedV->size();
1728 for (
size_t I = 0;
I <
Section.VerneedV->size(); ++
I) {
1731 Elf_Verneed VerNeed;
1732 VerNeed.vn_version =
VE.Version;
1733 VerNeed.vn_file = DotDynstr.getOffset(
VE.File);
1734 if (
I ==
Section.VerneedV->size() - 1)
1735 VerNeed.vn_next = 0;
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((
const char *)&VerNeed,
sizeof(Elf_Verneed));
1743 for (
size_t J = 0; J <
VE.AuxV.size(); ++J, ++AuxCnt) {
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(VAuxE.
Name);
1751 if (J ==
VE.AuxV.size() - 1)
1752 VernAux.vna_next = 0;
1754 VernAux.vna_next =
sizeof(Elf_Vernaux);
1755 CBA.write((
const char *)&VernAux,
sizeof(Elf_Vernaux));
1759 SHeader.sh_size =
Section.VerneedV->size() *
sizeof(Elf_Verneed) +
1760 AuxCnt *
sizeof(Elf_Vernaux);
1763template <
class ELFT>
1764void ELFState<ELFT>::writeSectionContent(
1766 ContiguousBlobAccumulator &CBA) {
1771 CBA.write<
uint32_t>(
E.Offset, ELFT::Endianness);
1772 CBA.write<
uint32_t>(
E.Value, ELFT::Endianness);
1774 SHeader.sh_size =
Section.Entries->size() * 8;
1777template <
class ELFT>
1778void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1780 ContiguousBlobAccumulator &CBA) {
1782 "Section type is not SHT_MIPS_ABIFLAGS");
1786 SHeader.sh_size = SHeader.sh_entsize;
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;
1795 Flags.isa_ext =
Section.ISAExtension;
1797 Flags.flags1 =
Section.Flags1;
1798 Flags.flags2 =
Section.Flags2;
1799 CBA.write((
const char *)&Flags,
sizeof(Flags));
1802template <
class ELFT>
1803void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1805 ContiguousBlobAccumulator &CBA) {
1807 "Section type is not SHT_DYNAMIC");
1813 CBA.write<uintX_t>(DE.
Tag, ELFT::Endianness);
1814 CBA.write<uintX_t>(DE.
Val, ELFT::Endianness);
1816 SHeader.sh_size = 2 *
sizeof(uintX_t) *
Section.Entries->size();
1819template <
class ELFT>
1820void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1822 ContiguousBlobAccumulator &CBA) {
1828 CBA.writeULEB128(toSymbolIndex(Sym,
Section.Name,
false));
1831template <
class ELFT>
1832void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1834 ContiguousBlobAccumulator &CBA) {
1839 switch (
Section.AddressAlign) {
1853 if (CBA.getOffset() !=
alignTo(CBA.getOffset(),
Align)) {
1863 if (
NE.Name.empty())
1864 CBA.write<
uint32_t>(0, ELFT::Endianness);
1866 CBA.write<
uint32_t>(
NE.Name.size() + 1, ELFT::Endianness);
1869 if (
NE.Desc.binary_size() == 0)
1870 CBA.write<
uint32_t>(0, ELFT::Endianness);
1872 CBA.write<
uint32_t>(
NE.Desc.binary_size(), ELFT::Endianness);
1875 CBA.write<
uint32_t>(
NE.Type, ELFT::Endianness);
1878 if (!
NE.Name.empty()) {
1879 CBA.write(
NE.Name.data(),
NE.Name.size());
1884 if (
NE.Desc.binary_size() != 0) {
1885 CBA.padToAlignment(
Align);
1886 CBA.writeAsBinary(
NE.Desc);
1889 CBA.padToAlignment(
Align);
1892 SHeader.sh_size = CBA.tell() -
Offset;
1895template <
class ELFT>
1896void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1898 ContiguousBlobAccumulator &CBA) {
1920 if (
Section.Header->MaskWords)
1929 for (llvm::yaml::Hex64 Val : *
Section.BloomFilter)
1930 CBA.write<uintX_t>(Val, ELFT::Endianness);
1933 for (llvm::yaml::Hex32 Val : *
Section.HashBuckets)
1934 CBA.write<
uint32_t>(Val, ELFT::Endianness);
1937 for (llvm::yaml::Hex32 Val : *
Section.HashValues)
1938 CBA.write<
uint32_t>(Val, ELFT::Endianness);
1940 SHeader.sh_size = 16 +
1941 Section.BloomFilter->size() *
sizeof(
typename ELFT::uint) +
1942 Section.HashBuckets->size() * 4 +
1943 Section.HashValues->size() * 4;
1946template <
class ELFT>
1948 ContiguousBlobAccumulator &CBA) {
1949 size_t PatternSize = Fill.
Pattern ? Fill.
Pattern->binary_size() : 0;
1951 CBA.writeZeros(Fill.
Size);
1957 for (; Written + PatternSize <= Fill.
Size; Written += PatternSize)
1958 CBA.writeAsBinary(*Fill.
Pattern);
1959 CBA.writeAsBinary(*Fill.
Pattern, Fill.
Size - Written);
1962template <
class ELFT>
1965 Doc.getSectionHeaderTable();
1975 if (!
Ret.try_emplace(Hdr.Name, ++SecNdx).second)
1976 reportError(
"repeated section name: '" + Hdr.Name +
1977 "' in the section header description");
1991 if (S == Doc.getSections().front())
1995 "' should be present in the 'Sections' or 'Excluded' lists");
1999 for (
const auto &It : Seen)
2000 reportError(
"section header contains undefined section '" + It.getKey() +
2005template <
class ELFT>
void ELFState<ELFT>::buildSectionIndex() {
2014 std::vector<ELFYAML::Section *> Sections = Doc.getSections();
2016 Doc.getSectionHeaderTable();
2019 if (!ExcludedSectionHeaders.insert(Hdr.
Name).second)
2022 if (SectionHeaders.
NoHeaders.value_or(
false))
2024 if (!ExcludedSectionHeaders.insert(S->
Name).second)
2031 size_t Index = ReorderMap.
empty() ? SecNdx : ReorderMap.
lookup(S->
Name);
2032 if (!SN2I.addName(S->
Name, Index))
2035 if (!ExcludedSectionHeaders.count(S->
Name))
2040template <
class ELFT>
void ELFState<ELFT>::buildSymbolIndexes() {
2042 for (
size_t I = 0, S = V.size();
I < S; ++
I) {
2050 Build(*Doc.Symbols, SymN2I);
2051 if (Doc.DynamicSymbols)
2052 Build(*Doc.DynamicSymbols, DynSymN2I);
2055template <
class ELFT>
void ELFState<ELFT>::finalizeStrings() {
2060 DotStrtab.finalize();
2063 if (Doc.DynamicSymbols)
2071 if (VerNeed->VerneedV) {
2073 DotDynstr.add(
VE.File);
2075 DotDynstr.add(Aux.
Name);
2079 if (VerDef->Entries)
2082 DotDynstr.add(Name);
2086 DotDynstr.finalize();
2090 if (ShStrtabStrings != &DotStrtab && ShStrtabStrings != &DotDynstr)
2091 ShStrtabStrings->finalize();
2094template <
class ELFT>
2097 ELFState<ELFT> State(Doc, EH);
2103 State.buildSectionIndex();
2104 State.buildSymbolIndexes();
2109 State.finalizeStrings();
2114 std::vector<Elf_Phdr> PHeaders;
2115 State.initProgramHeaders(PHeaders);
2119 const size_t SectionContentBeginOffset =
2125 ContiguousBlobAccumulator CBA(SectionContentBeginOffset, MaxSize);
2127 std::vector<Elf_Shdr> SHeaders;
2128 State.initSectionHeaders(SHeaders, CBA);
2131 State.setProgramHeaderLayout(PHeaders, SHeaders);
2136 State.overrideSectionHeaders(SHeaders);
2138 bool ReachedLimit = CBA.getOffset() > MaxSize;
2139 if (
Error E = CBA.takeLimitError()) {
2142 ReachedLimit =
true;
2147 "the desired output size is greater than permitted. Use the "
2148 "--max-size option to change the limit");
2153 State.writeELFHeader(OS);
2158 CBA.updateDataAt(*SHT.
Offset, SHeaders.data(),
2161 CBA.writeBlobToStream(OS);
2174 return ELFState<object::ELF64LE>::writeELF(Out, Doc, EH, MaxSize);
2175 return ELFState<object::ELF64BE>::writeELF(Out, Doc, EH, MaxSize);
2178 return ELFState<object::ELF32LE>::writeELF(Out, Doc, EH, MaxSize);
2179 return ELFState<object::ELF32BE>::writeELF(Out, Doc, EH, MaxSize);
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static Error reportError(StringRef Message)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Common declarations for yaml2obj.
This file declares classes for handling the YAML representation of DWARF Debug Info.
DXIL Resource Implicit Binding
This file defines the DenseMap class.
static StringRef getDefaultLinkSec(unsigned SecType)
static void overrideFields(ELFYAML::Section *From, typename ELFT::Shdr &To)
static void writeArrayData(raw_ostream &OS, ArrayRef< T > A)
static bool isMips64EL(const ELFYAML::Object &Obj)
static size_t arrayDataSize(ArrayRef< T > A)
constexpr char SuffixStart
static bool shouldEmitDWARF(DWARFYAML::Data &DWARF, StringRef Name)
static uint64_t writeContent(ContiguousBlobAccumulator &CBA, const std::optional< yaml::BinaryRef > &Content, const std::optional< llvm::yaml::Hex64 > &Size)
Expected< uint64_t > emitDWARF(typename ELFT::Shdr &SHeader, StringRef Name, const DWARFYAML::Data &DWARF, ContiguousBlobAccumulator &CBA)
static size_t findFirstNonGlobal(ArrayRef< ELFYAML::Symbol > Symbols)
#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
This file declares classes for handling the YAML representation of ELF.
static cl::opt< unsigned > SizeLimit("eif-limit", cl::init(6), cl::Hidden, cl::desc("Size limit in Hexagon early if-conversion"))
static bool lookup(const GsymReader &GR, DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs, llvm::Error &Err)
A Lookup helper functions.
This file implements a set that has insertion order iteration characteristics.
StringSet - A set-like wrapper for the StringMap.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Base class for error info classes.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
A vector that has set insertion semantics.
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
A SetVector that performs no allocations if smaller than a certain size.
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
StringRef - Represent a constant reference to a string, i.e.
static constexpr size_t npos
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
char back() const
back - Get the last character in the string.
size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
StringRef copy(Allocator &A) const
StringSet - A wrapper for StringMap that provides set-like functionality.
std::pair< typename Base::iterator, bool > insert(StringRef key)
Utility for building string tables with deduplicated suffixes.
LLVM_ABI size_t getOffset(CachedHashStringRef S) const
Get the offest of a string in the string table.
LLVM_ABI void write(raw_ostream &OS) const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static Twine utohexstr(uint64_t Val)
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI raw_ostream & warning()
Convenience method for printing "warning: " to stderr.
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & write(unsigned char C)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI std::function< Error(raw_ostream &, const Data &)> getDWARFEmitterByName(StringRef SecName)
std::string appendUniqueSuffix(StringRef Name, const Twine &Msg)
unsigned getDefaultShEntSize(unsigned EMachine, ELF_SHT SecType, StringRef SecName)
StringRef dropUniqueSuffix(StringRef S)
bool shouldAllocateFileSpace(ArrayRef< ProgramHeader > Phdrs, const NoBitsSection &S)
@ SHT_LLVM_CALL_GRAPH_PROFILE
constexpr unsigned CREL_HDR_ADDEND
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
LLVM_ABI bool yaml2elf(ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH, uint64_t MaxSize)
llvm::function_ref< void(const Twine &Msg)> ErrorHandler
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
auto dyn_cast_or_null(const Y &Val)
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue)
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
@ Dynamic
Denotes mode unknown at compile time.
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
bool to_integer(StringRef S, N &Num, unsigned Base=0)
Convert the string S to an integer of the specified type using the radix Base. If Base is 0,...
void consumeError(Error Err)
Consume a Error without doing anything.
This struct is a compact representation of a valid (non-zero power of two) alignment.
LLVM_ABI SetVector< StringRef > getNonEmptySectionNames() const
std::optional< llvm::yaml::Hex64 > Hash
llvm::yaml::Hex64 Metadata
std::optional< std::vector< llvm::yaml::Hex64 > > CallsiteEndOffsets
llvm::yaml::Hex64 AddressOffset
std::optional< uint64_t > NumBlocks
llvm::yaml::Hex64 BaseAddress
std::optional< std::vector< BBEntry > > BBEntries
std::optional< llvm::yaml::Hex64 > Offset
std::optional< yaml::BinaryRef > Pattern
unsigned getMachine() const
const SectionHeaderTable & getSectionHeaderTable() const
std::vector< ProgramHeader > ProgramHeaders
std::optional< std::vector< PGOBBEntry > > PGOBBEntries
std::optional< uint64_t > FuncEntryCount
std::optional< llvm::yaml::Hex64 > Info
std::optional< StringRef > Symbol
std::optional< llvm::yaml::Hex64 > Address
std::optional< StringRef > Link
std::optional< llvm::yaml::Hex64 > Size
std::optional< llvm::yaml::Hex64 > ShAddrAlign
llvm::yaml::Hex64 AddressAlign
std::optional< ELF_SHF > Flags
std::optional< ELF_SHT > ShType
std::optional< llvm::yaml::Hex64 > ShOffset
std::optional< llvm::yaml::Hex64 > ShFlags
std::optional< llvm::yaml::Hex64 > ShName
std::optional< yaml::BinaryRef > Content
std::optional< llvm::yaml::Hex64 > EntSize
std::optional< llvm::yaml::Hex64 > ShSize
std::optional< std::vector< uint32_t > > Entries
static Expected< Features > decode(uint16_t Val)
Common declarations for yaml2obj.