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 CBA.write(
E.Feature);
1474 SHeader.sh_size += 2;
1477 bool MultiBBRangeFeatureEnabled =
false;
1481 MultiBBRangeFeatureEnabled = FeatureOrErr->MultiBBRange;
1483 MultiBBRangeFeatureEnabled ||
1484 (
E.NumBBRanges.has_value() &&
E.NumBBRanges.value() != 1) ||
1485 (
E.BBRanges &&
E.BBRanges->size() != 1);
1486 if (MultiBBRange && !MultiBBRangeFeatureEnabled)
1488 <<
") does not support multiple BB ranges.";
1493 E.NumBBRanges.value_or(
E.BBRanges ?
E.BBRanges->size() : 0);
1494 SHeader.sh_size += CBA.writeULEB128(NumBBRanges);
1499 bool EmitCallsiteEndOffsets =
1500 FeatureOrErr->CallsiteEndOffsets ||
E.hasAnyCallsiteEndOffsets();
1503 CBA.write<uintX_t>(BBR.
BaseAddress, ELFT::Endianness);
1509 SHeader.sh_size +=
sizeof(uintX_t) + CBA.writeULEB128(NumBlocks);
1511 if (!BBR.
BBEntries || FeatureOrErr->OmitBBEntries)
1516 SHeader.sh_size += CBA.writeULEB128(BBE.
ID);
1518 if (EmitCallsiteEndOffsets) {
1519 size_t NumCallsiteEndOffsets =
1521 SHeader.sh_size += CBA.writeULEB128(NumCallsiteEndOffsets);
1524 SHeader.sh_size += CBA.writeULEB128(
Offset);
1527 SHeader.sh_size += CBA.writeULEB128(BBE.
Size);
1528 SHeader.sh_size += CBA.writeULEB128(BBE.
Metadata);
1541 const auto &PGOBBEntries = PGOEntry.
PGOBBEntries.value();
1542 if (TotalNumBlocks != PGOBBEntries.size()) {
1544 "BBEntries in SHT_LLVM_BB_ADDR_MAP.\n"
1545 <<
"Mismatch on function with address: "
1546 <<
E.getFunctionAddress();
1550 for (
const auto &PGOBBE : PGOBBEntries) {
1552 SHeader.sh_size += CBA.writeULEB128(*PGOBBE.BBFreq);
1553 if (PGOBBE.Successors) {
1554 SHeader.sh_size += CBA.writeULEB128(PGOBBE.Successors->size());
1555 for (
const auto &[
ID,
BrProb] : *PGOBBE.Successors) {
1556 SHeader.sh_size += CBA.writeULEB128(
ID);
1557 SHeader.sh_size += CBA.writeULEB128(
BrProb);
1564template <
class ELFT>
1565void ELFState<ELFT>::writeSectionContent(
1567 ContiguousBlobAccumulator &CBA) {
1572 CBA.write(
LO.Key.data(),
LO.Key.size());
1574 CBA.write(
LO.Value.data(),
LO.Value.size());
1576 SHeader.sh_size += (
LO.Key.size() +
LO.Value.size() + 2);
1580template <
class ELFT>
1581void ELFState<ELFT>::writeSectionContent(
1583 ContiguousBlobAccumulator &CBA) {
1588 CBA.write(
Lib.data(),
Lib.size());
1590 SHeader.sh_size +=
Lib.size() + 1;
1594template <
class ELFT>
1596ELFState<ELFT>::alignToOffset(ContiguousBlobAccumulator &CBA,
uint64_t Align,
1597 std::optional<llvm::yaml::Hex64>
Offset) {
1598 uint64_t CurrentOffset = CBA.getOffset();
1605 return CurrentOffset;
1614 CBA.writeZeros(AlignedOffset - CurrentOffset);
1615 return AlignedOffset;
1618template <
class ELFT>
1619void ELFState<ELFT>::writeSectionContent(
1621 ContiguousBlobAccumulator &CBA) {
1626 CBA.write<
uint64_t>(
E.Weight, ELFT::Endianness);
1631template <
class ELFT>
1632void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1634 ContiguousBlobAccumulator &CBA) {
1639 Section.NBucket.value_or(llvm::yaml::Hex64(
Section.Bucket->size())),
1642 Section.NChain.value_or(llvm::yaml::Hex64(
Section.Chain->size())),
1646 CBA.write<
uint32_t>(Val, ELFT::Endianness);
1648 CBA.write<
uint32_t>(Val, ELFT::Endianness);
1650 SHeader.sh_size = (2 +
Section.Bucket->size() +
Section.Chain->size()) * 4;
1653template <
class ELFT>
1654void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1656 ContiguousBlobAccumulator &CBA) {
1659 SHeader.sh_info = *
Section.Info;
1661 SHeader.sh_info =
Section.Entries->size();
1667 for (
size_t I = 0;
I <
Section.Entries->size(); ++
I) {
1671 VerDef.vd_version =
E.Version.value_or(1);
1672 VerDef.vd_flags =
E.Flags.value_or(0);
1673 VerDef.vd_ndx =
E.VersionNdx.value_or(0);
1674 VerDef.vd_hash =
E.Hash.value_or(0);
1675 VerDef.vd_aux =
E.VDAux.value_or(
sizeof(Elf_Verdef));
1676 VerDef.vd_cnt =
E.VerNames.size();
1677 if (
I ==
Section.Entries->size() - 1)
1681 sizeof(Elf_Verdef) +
E.VerNames.size() *
sizeof(Elf_Verdaux);
1682 CBA.write((
const char *)&VerDef,
sizeof(Elf_Verdef));
1684 for (
size_t J = 0; J <
E.VerNames.size(); ++J, ++AuxCnt) {
1685 Elf_Verdaux VerdAux;
1686 VerdAux.vda_name = DotDynstr.getOffset(
E.VerNames[J]);
1687 if (J ==
E.VerNames.size() - 1)
1688 VerdAux.vda_next = 0;
1690 VerdAux.vda_next =
sizeof(Elf_Verdaux);
1691 CBA.write((
const char *)&VerdAux,
sizeof(Elf_Verdaux));
1695 SHeader.sh_size =
Section.Entries->size() *
sizeof(Elf_Verdef) +
1696 AuxCnt *
sizeof(Elf_Verdaux);
1699template <
class ELFT>
1700void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1702 ContiguousBlobAccumulator &CBA) {
1704 SHeader.sh_info = *
Section.Info;
1706 SHeader.sh_info =
Section.VerneedV->size();
1712 for (
size_t I = 0;
I <
Section.VerneedV->size(); ++
I) {
1715 Elf_Verneed VerNeed;
1716 VerNeed.vn_version =
VE.Version;
1717 VerNeed.vn_file = DotDynstr.getOffset(
VE.File);
1718 if (
I ==
Section.VerneedV->size() - 1)
1719 VerNeed.vn_next = 0;
1722 sizeof(Elf_Verneed) +
VE.AuxV.size() *
sizeof(Elf_Vernaux);
1723 VerNeed.vn_cnt =
VE.AuxV.size();
1724 VerNeed.vn_aux =
sizeof(Elf_Verneed);
1725 CBA.write((
const char *)&VerNeed,
sizeof(Elf_Verneed));
1727 for (
size_t J = 0; J <
VE.AuxV.size(); ++J, ++AuxCnt) {
1730 Elf_Vernaux VernAux;
1731 VernAux.vna_hash = VAuxE.
Hash;
1732 VernAux.vna_flags = VAuxE.
Flags;
1733 VernAux.vna_other = VAuxE.
Other;
1734 VernAux.vna_name = DotDynstr.getOffset(VAuxE.
Name);
1735 if (J ==
VE.AuxV.size() - 1)
1736 VernAux.vna_next = 0;
1738 VernAux.vna_next =
sizeof(Elf_Vernaux);
1739 CBA.write((
const char *)&VernAux,
sizeof(Elf_Vernaux));
1743 SHeader.sh_size =
Section.VerneedV->size() *
sizeof(Elf_Verneed) +
1744 AuxCnt *
sizeof(Elf_Vernaux);
1747template <
class ELFT>
1748void ELFState<ELFT>::writeSectionContent(
1750 ContiguousBlobAccumulator &CBA) {
1755 CBA.write<
uint32_t>(
E.Offset, ELFT::Endianness);
1756 CBA.write<
uint32_t>(
E.Value, ELFT::Endianness);
1758 SHeader.sh_size =
Section.Entries->size() * 8;
1761template <
class ELFT>
1762void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1764 ContiguousBlobAccumulator &CBA) {
1766 "Section type is not SHT_MIPS_ABIFLAGS");
1770 SHeader.sh_size = SHeader.sh_entsize;
1772 Flags.version =
Section.Version;
1773 Flags.isa_level =
Section.ISALevel;
1774 Flags.isa_rev =
Section.ISARevision;
1775 Flags.gpr_size =
Section.GPRSize;
1776 Flags.cpr1_size =
Section.CPR1Size;
1777 Flags.cpr2_size =
Section.CPR2Size;
1779 Flags.isa_ext =
Section.ISAExtension;
1781 Flags.flags1 =
Section.Flags1;
1782 Flags.flags2 =
Section.Flags2;
1783 CBA.write((
const char *)&Flags,
sizeof(Flags));
1786template <
class ELFT>
1787void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1789 ContiguousBlobAccumulator &CBA) {
1791 "Section type is not SHT_DYNAMIC");
1797 CBA.write<uintX_t>(DE.
Tag, ELFT::Endianness);
1798 CBA.write<uintX_t>(DE.
Val, ELFT::Endianness);
1800 SHeader.sh_size = 2 *
sizeof(uintX_t) *
Section.Entries->size();
1803template <
class ELFT>
1804void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1806 ContiguousBlobAccumulator &CBA) {
1812 CBA.writeULEB128(toSymbolIndex(Sym,
Section.Name,
false));
1815template <
class ELFT>
1816void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1818 ContiguousBlobAccumulator &CBA) {
1823 switch (
Section.AddressAlign) {
1837 if (CBA.getOffset() !=
alignTo(CBA.getOffset(),
Align)) {
1847 if (
NE.Name.empty())
1848 CBA.write<
uint32_t>(0, ELFT::Endianness);
1850 CBA.write<
uint32_t>(
NE.Name.size() + 1, ELFT::Endianness);
1853 if (
NE.Desc.binary_size() == 0)
1854 CBA.write<
uint32_t>(0, ELFT::Endianness);
1856 CBA.write<
uint32_t>(
NE.Desc.binary_size(), ELFT::Endianness);
1859 CBA.write<
uint32_t>(
NE.Type, ELFT::Endianness);
1862 if (!
NE.Name.empty()) {
1863 CBA.write(
NE.Name.data(),
NE.Name.size());
1868 if (
NE.Desc.binary_size() != 0) {
1869 CBA.padToAlignment(
Align);
1870 CBA.writeAsBinary(
NE.Desc);
1873 CBA.padToAlignment(
Align);
1876 SHeader.sh_size = CBA.tell() -
Offset;
1879template <
class ELFT>
1880void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1882 ContiguousBlobAccumulator &CBA) {
1904 if (
Section.Header->MaskWords)
1913 for (llvm::yaml::Hex64 Val : *
Section.BloomFilter)
1914 CBA.write<uintX_t>(Val, ELFT::Endianness);
1917 for (llvm::yaml::Hex32 Val : *
Section.HashBuckets)
1918 CBA.write<
uint32_t>(Val, ELFT::Endianness);
1921 for (llvm::yaml::Hex32 Val : *
Section.HashValues)
1922 CBA.write<
uint32_t>(Val, ELFT::Endianness);
1924 SHeader.sh_size = 16 +
1925 Section.BloomFilter->size() *
sizeof(
typename ELFT::uint) +
1926 Section.HashBuckets->size() * 4 +
1927 Section.HashValues->size() * 4;
1930template <
class ELFT>
1932 ContiguousBlobAccumulator &CBA) {
1933 size_t PatternSize = Fill.
Pattern ? Fill.
Pattern->binary_size() : 0;
1935 CBA.writeZeros(Fill.
Size);
1941 for (; Written + PatternSize <= Fill.
Size; Written += PatternSize)
1942 CBA.writeAsBinary(*Fill.
Pattern);
1943 CBA.writeAsBinary(*Fill.
Pattern, Fill.
Size - Written);
1946template <
class ELFT>
1949 Doc.getSectionHeaderTable();
1959 if (!
Ret.try_emplace(Hdr.Name, ++SecNdx).second)
1960 reportError(
"repeated section name: '" + Hdr.Name +
1961 "' in the section header description");
1975 if (S == Doc.getSections().front())
1979 "' should be present in the 'Sections' or 'Excluded' lists");
1983 for (
const auto &It : Seen)
1984 reportError(
"section header contains undefined section '" + It.getKey() +
1989template <
class ELFT>
void ELFState<ELFT>::buildSectionIndex() {
1998 std::vector<ELFYAML::Section *> Sections = Doc.getSections();
2000 Doc.getSectionHeaderTable();
2003 if (!ExcludedSectionHeaders.insert(Hdr.
Name).second)
2006 if (SectionHeaders.
NoHeaders.value_or(
false))
2008 if (!ExcludedSectionHeaders.insert(S->
Name).second)
2015 size_t Index = ReorderMap.
empty() ? SecNdx : ReorderMap.
lookup(S->
Name);
2016 if (!SN2I.addName(S->
Name, Index))
2019 if (!ExcludedSectionHeaders.count(S->
Name))
2024template <
class ELFT>
void ELFState<ELFT>::buildSymbolIndexes() {
2026 for (
size_t I = 0, S = V.size();
I < S; ++
I) {
2034 Build(*Doc.Symbols, SymN2I);
2035 if (Doc.DynamicSymbols)
2036 Build(*Doc.DynamicSymbols, DynSymN2I);
2039template <
class ELFT>
void ELFState<ELFT>::finalizeStrings() {
2044 DotStrtab.finalize();
2047 if (Doc.DynamicSymbols)
2055 if (VerNeed->VerneedV) {
2057 DotDynstr.add(
VE.File);
2059 DotDynstr.add(Aux.
Name);
2063 if (VerDef->Entries)
2066 DotDynstr.add(Name);
2070 DotDynstr.finalize();
2074 if (ShStrtabStrings != &DotStrtab && ShStrtabStrings != &DotDynstr)
2075 ShStrtabStrings->finalize();
2078template <
class ELFT>
2081 ELFState<ELFT> State(Doc, EH);
2087 State.buildSectionIndex();
2088 State.buildSymbolIndexes();
2093 State.finalizeStrings();
2098 std::vector<Elf_Phdr> PHeaders;
2099 State.initProgramHeaders(PHeaders);
2103 const size_t SectionContentBeginOffset =
2109 ContiguousBlobAccumulator CBA(SectionContentBeginOffset, MaxSize);
2111 std::vector<Elf_Shdr> SHeaders;
2112 State.initSectionHeaders(SHeaders, CBA);
2115 State.setProgramHeaderLayout(PHeaders, SHeaders);
2120 State.overrideSectionHeaders(SHeaders);
2122 bool ReachedLimit = CBA.getOffset() > MaxSize;
2123 if (
Error E = CBA.takeLimitError()) {
2126 ReachedLimit =
true;
2131 "the desired output size is greater than permitted. Use the "
2132 "--max-size option to change the limit");
2137 State.writeELFHeader(OS);
2142 CBA.updateDataAt(*SHT.
Offset, SHeaders.data(),
2145 CBA.writeBlobToStream(OS);
2158 return ELFState<object::ELF64LE>::writeELF(Out, Doc, EH, MaxSize);
2159 return ELFState<object::ELF64BE>::writeELF(Out, Doc, EH, MaxSize);
2162 return ELFState<object::ELF32LE>::writeELF(Out, Doc, EH, MaxSize);
2163 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.
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
static constexpr size_t npos
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
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(uint8_t Val)
Common declarations for yaml2obj.