44class ContiguousBlobAccumulator {
45 const uint64_t InitialOffset;
46 const uint64_t MaxSize;
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) {
107 void write(
const char *Ptr,
size_t Size) {
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;
954 Ret.resize(
Symbols.size() + 1);
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<BBAddrMapYAML::PGOAnalysisMapEntry> *PGOAnalyses =
nullptr;
1460 "in SHT_LLVM_BB_ADDR_MAP";
1462 PGOAnalyses = &
Section.PGOAnalyses.value();
1469 <<
static_cast<int>(
E.Version)
1470 <<
"; encoding using the most recent version";
1471 CBA.write(
E.Version);
1472 SHeader.sh_size += 1;
1473 if (
E.Version < 5) {
1474 CBA.write(
static_cast<uint8_t>(
E.Feature));
1475 SHeader.sh_size += 1;
1477 CBA.write<
uint16_t>(
E.Feature, ELFT::Endianness);
1478 SHeader.sh_size += 2;
1481 if (!FeatureOrErr) {
1486 bool MultiBBRangeFeatureEnabled = FeatureOrErr->MultiBBRange;
1488 MultiBBRangeFeatureEnabled ||
1489 (
E.NumBBRanges.has_value() &&
E.NumBBRanges.value() != 1) ||
1490 (
E.BBRanges &&
E.BBRanges->size() != 1);
1491 if (MultiBBRange && !MultiBBRangeFeatureEnabled)
1493 <<
") does not support multiple BB ranges.";
1498 E.NumBBRanges.value_or(
E.BBRanges ?
E.BBRanges->size() : 0);
1499 SHeader.sh_size += CBA.writeULEB128(NumBBRanges);
1504 bool EmitCallsiteEndOffsets =
1505 FeatureOrErr->CallsiteEndOffsets ||
E.hasAnyCallsiteEndOffsets();
1508 CBA.write<uintX_t>(BBR.
BaseAddress, ELFT::Endianness);
1514 SHeader.sh_size +=
sizeof(uintX_t) + CBA.writeULEB128(NumBlocks);
1516 if (!BBR.
BBEntries || FeatureOrErr->OmitBBEntries)
1521 SHeader.sh_size += CBA.writeULEB128(BBE.
ID);
1523 if (EmitCallsiteEndOffsets) {
1524 size_t NumCallsiteEndOffsets =
1526 SHeader.sh_size += CBA.writeULEB128(NumCallsiteEndOffsets);
1529 SHeader.sh_size += CBA.writeULEB128(
Offset);
1532 SHeader.sh_size += CBA.writeULEB128(BBE.
Size);
1533 SHeader.sh_size += CBA.writeULEB128(BBE.
Metadata);
1534 if (FeatureOrErr->BBHash || BBE.
Hash.has_value()) {
1536 BBE.
Hash.has_value() ? BBE.
Hash.value() : llvm::yaml::Hex64(0);
1537 CBA.write<
uint64_t>(Hash, ELFT::Endianness);
1538 SHeader.sh_size += 8;
1552 const auto &PGOBBEntries = PGOEntry.
PGOBBEntries.value();
1553 if (TotalNumBlocks != PGOBBEntries.size()) {
1555 "BBEntries in the BB address map.\n"
1556 <<
"Mismatch on function with address: "
1557 <<
E.getFunctionAddress();
1561 for (
const auto &PGOBBE : PGOBBEntries) {
1563 SHeader.sh_size += CBA.writeULEB128(*PGOBBE.BBFreq);
1564 if (FeatureOrErr->PostLinkCfg || PGOBBE.PostLinkBBFreq.has_value())
1565 SHeader.sh_size += CBA.writeULEB128(PGOBBE.PostLinkBBFreq.value_or(0));
1566 if (PGOBBE.Successors) {
1567 SHeader.sh_size += CBA.writeULEB128(PGOBBE.Successors->size());
1568 for (
const auto &[
ID,
BrProb, PostLinkBrFreq] : *PGOBBE.Successors) {
1569 SHeader.sh_size += CBA.writeULEB128(
ID);
1570 SHeader.sh_size += CBA.writeULEB128(
BrProb);
1571 if (FeatureOrErr->PostLinkCfg || PostLinkBrFreq.has_value())
1572 SHeader.sh_size += CBA.writeULEB128(PostLinkBrFreq.value_or(0));
1579template <
class ELFT>
1580void ELFState<ELFT>::writeSectionContent(
1582 ContiguousBlobAccumulator &CBA) {
1587 CBA.write(
LO.Key.data(),
LO.Key.size());
1589 CBA.write(
LO.Value.data(),
LO.Value.size());
1591 SHeader.sh_size += (
LO.Key.size() +
LO.Value.size() + 2);
1595template <
class ELFT>
1596void ELFState<ELFT>::writeSectionContent(
1598 ContiguousBlobAccumulator &CBA) {
1603 CBA.write(
Lib.data(),
Lib.size());
1605 SHeader.sh_size +=
Lib.size() + 1;
1609template <
class ELFT>
1611ELFState<ELFT>::alignToOffset(ContiguousBlobAccumulator &CBA,
uint64_t Align,
1612 std::optional<llvm::yaml::Hex64>
Offset) {
1613 uint64_t CurrentOffset = CBA.getOffset();
1620 return CurrentOffset;
1629 CBA.writeZeros(AlignedOffset - CurrentOffset);
1630 return AlignedOffset;
1633template <
class ELFT>
1634void ELFState<ELFT>::writeSectionContent(
1636 ContiguousBlobAccumulator &CBA) {
1641 CBA.write<
uint64_t>(
E.Weight, ELFT::Endianness);
1646template <
class ELFT>
1647void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1649 ContiguousBlobAccumulator &CBA) {
1654 Section.NBucket.value_or(llvm::yaml::Hex64(
Section.Bucket->size())),
1657 Section.NChain.value_or(llvm::yaml::Hex64(
Section.Chain->size())),
1661 CBA.write<
uint32_t>(Val, ELFT::Endianness);
1663 CBA.write<
uint32_t>(Val, ELFT::Endianness);
1665 SHeader.sh_size = (2 +
Section.Bucket->size() +
Section.Chain->size()) * 4;
1668template <
class ELFT>
1669void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1671 ContiguousBlobAccumulator &CBA) {
1674 SHeader.sh_info = *
Section.Info;
1676 SHeader.sh_info =
Section.Entries->size();
1682 for (
size_t I = 0;
I <
Section.Entries->size(); ++
I) {
1686 VerDef.vd_version =
E.Version.value_or(1);
1687 VerDef.vd_flags =
E.Flags.value_or(0);
1688 VerDef.vd_ndx =
E.VersionNdx.value_or(0);
1689 VerDef.vd_hash =
E.Hash.value_or(0);
1690 VerDef.vd_aux =
E.VDAux.value_or(
sizeof(Elf_Verdef));
1691 VerDef.vd_cnt =
E.VerNames.size();
1692 if (
I ==
Section.Entries->size() - 1)
1696 sizeof(Elf_Verdef) +
E.VerNames.size() *
sizeof(Elf_Verdaux);
1697 CBA.write((
const char *)&VerDef,
sizeof(Elf_Verdef));
1699 for (
size_t J = 0; J <
E.VerNames.size(); ++J, ++AuxCnt) {
1700 Elf_Verdaux VerdAux;
1701 VerdAux.vda_name = DotDynstr.getOffset(
E.VerNames[J]);
1702 if (J ==
E.VerNames.size() - 1)
1703 VerdAux.vda_next = 0;
1705 VerdAux.vda_next =
sizeof(Elf_Verdaux);
1706 CBA.write((
const char *)&VerdAux,
sizeof(Elf_Verdaux));
1710 SHeader.sh_size =
Section.Entries->size() *
sizeof(Elf_Verdef) +
1711 AuxCnt *
sizeof(Elf_Verdaux);
1714template <
class ELFT>
1715void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1717 ContiguousBlobAccumulator &CBA) {
1719 SHeader.sh_info = *
Section.Info;
1721 SHeader.sh_info =
Section.VerneedV->size();
1727 for (
size_t I = 0;
I <
Section.VerneedV->size(); ++
I) {
1730 Elf_Verneed VerNeed;
1731 VerNeed.vn_version =
VE.Version;
1732 VerNeed.vn_file = DotDynstr.getOffset(
VE.File);
1733 if (
I ==
Section.VerneedV->size() - 1)
1734 VerNeed.vn_next = 0;
1737 sizeof(Elf_Verneed) +
VE.AuxV.size() *
sizeof(Elf_Vernaux);
1738 VerNeed.vn_cnt =
VE.AuxV.size();
1739 VerNeed.vn_aux =
sizeof(Elf_Verneed);
1740 CBA.write((
const char *)&VerNeed,
sizeof(Elf_Verneed));
1742 for (
size_t J = 0; J <
VE.AuxV.size(); ++J, ++AuxCnt) {
1745 Elf_Vernaux VernAux;
1746 VernAux.vna_hash = VAuxE.
Hash;
1747 VernAux.vna_flags = VAuxE.
Flags;
1748 VernAux.vna_other = VAuxE.
Other;
1749 VernAux.vna_name = DotDynstr.getOffset(VAuxE.
Name);
1750 if (J ==
VE.AuxV.size() - 1)
1751 VernAux.vna_next = 0;
1753 VernAux.vna_next =
sizeof(Elf_Vernaux);
1754 CBA.write((
const char *)&VernAux,
sizeof(Elf_Vernaux));
1758 SHeader.sh_size =
Section.VerneedV->size() *
sizeof(Elf_Verneed) +
1759 AuxCnt *
sizeof(Elf_Vernaux);
1762template <
class ELFT>
1763void ELFState<ELFT>::writeSectionContent(
1765 ContiguousBlobAccumulator &CBA) {
1770 CBA.write<
uint32_t>(
E.Offset, ELFT::Endianness);
1771 CBA.write<
uint32_t>(
E.Value, ELFT::Endianness);
1773 SHeader.sh_size =
Section.Entries->size() * 8;
1776template <
class ELFT>
1777void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1779 ContiguousBlobAccumulator &CBA) {
1781 "Section type is not SHT_MIPS_ABIFLAGS");
1785 SHeader.sh_size = SHeader.sh_entsize;
1787 Flags.version =
Section.Version;
1788 Flags.isa_level =
Section.ISALevel;
1789 Flags.isa_rev =
Section.ISARevision;
1790 Flags.gpr_size =
Section.GPRSize;
1791 Flags.cpr1_size =
Section.CPR1Size;
1792 Flags.cpr2_size =
Section.CPR2Size;
1794 Flags.isa_ext =
Section.ISAExtension;
1796 Flags.flags1 =
Section.Flags1;
1797 Flags.flags2 =
Section.Flags2;
1798 CBA.write((
const char *)&Flags,
sizeof(Flags));
1801template <
class ELFT>
1802void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1804 ContiguousBlobAccumulator &CBA) {
1806 "Section type is not SHT_DYNAMIC");
1812 CBA.write<uintX_t>(DE.
Tag, ELFT::Endianness);
1813 CBA.write<uintX_t>(DE.
Val, ELFT::Endianness);
1815 SHeader.sh_size = 2 *
sizeof(uintX_t) *
Section.Entries->size();
1818template <
class ELFT>
1819void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1821 ContiguousBlobAccumulator &CBA) {
1827 CBA.writeULEB128(toSymbolIndex(Sym,
Section.Name,
false));
1830template <
class ELFT>
1831void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1833 ContiguousBlobAccumulator &CBA) {
1838 switch (
Section.AddressAlign) {
1852 if (CBA.getOffset() !=
alignTo(CBA.getOffset(),
Align)) {
1862 if (
NE.Name.empty())
1863 CBA.write<
uint32_t>(0, ELFT::Endianness);
1865 CBA.write<
uint32_t>(
NE.Name.size() + 1, ELFT::Endianness);
1868 if (
NE.Desc.binary_size() == 0)
1869 CBA.write<
uint32_t>(0, ELFT::Endianness);
1871 CBA.write<
uint32_t>(
NE.Desc.binary_size(), ELFT::Endianness);
1874 CBA.write<
uint32_t>(
NE.Type, ELFT::Endianness);
1877 if (!
NE.Name.empty()) {
1878 CBA.write(
NE.Name.data(),
NE.Name.size());
1883 if (
NE.Desc.binary_size() != 0) {
1884 CBA.padToAlignment(
Align);
1885 CBA.writeAsBinary(
NE.Desc);
1888 CBA.padToAlignment(
Align);
1891 SHeader.sh_size = CBA.tell() -
Offset;
1894template <
class ELFT>
1895void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
1897 ContiguousBlobAccumulator &CBA) {
1919 if (
Section.Header->MaskWords)
1928 for (llvm::yaml::Hex64 Val : *
Section.BloomFilter)
1929 CBA.write<uintX_t>(Val, ELFT::Endianness);
1932 for (llvm::yaml::Hex32 Val : *
Section.HashBuckets)
1933 CBA.write<
uint32_t>(Val, ELFT::Endianness);
1936 for (llvm::yaml::Hex32 Val : *
Section.HashValues)
1937 CBA.write<
uint32_t>(Val, ELFT::Endianness);
1939 SHeader.sh_size = 16 +
1940 Section.BloomFilter->size() *
sizeof(
typename ELFT::uint) +
1941 Section.HashBuckets->size() * 4 +
1942 Section.HashValues->size() * 4;
1945template <
class ELFT>
1947 ContiguousBlobAccumulator &CBA) {
1948 size_t PatternSize = Fill.
Pattern ? Fill.
Pattern->binary_size() : 0;
1950 CBA.writeZeros(Fill.
Size);
1956 for (; Written + PatternSize <= Fill.
Size; Written += PatternSize)
1957 CBA.writeAsBinary(*Fill.
Pattern);
1958 CBA.writeAsBinary(*Fill.
Pattern, Fill.
Size - Written);
1961template <
class ELFT>
1964 Doc.getSectionHeaderTable();
1975 reportError(
"repeated section name: '" + Hdr.Name +
1976 "' in the section header description");
1990 if (S == Doc.getSections().front())
1994 "' should be present in the 'Sections' or 'Excluded' lists");
1998 for (
const auto &It : Seen)
1999 reportError(
"section header contains undefined section '" + It.getKey() +
2004template <
class ELFT>
void ELFState<ELFT>::buildSectionIndex() {
2013 std::vector<ELFYAML::Section *> Sections = Doc.getSections();
2015 Doc.getSectionHeaderTable();
2018 if (!ExcludedSectionHeaders.insert(Hdr.
Name).second)
2021 if (SectionHeaders.
NoHeaders.value_or(
false))
2023 if (!ExcludedSectionHeaders.insert(S->
Name).second)
2030 size_t Index = ReorderMap.
empty() ? SecNdx : ReorderMap.
lookup(S->
Name);
2031 if (!SN2I.addName(S->
Name, Index))
2034 if (!ExcludedSectionHeaders.count(S->
Name))
2039template <
class ELFT>
void ELFState<ELFT>::buildSymbolIndexes() {
2041 for (
size_t I = 0, S = V.size();
I < S; ++
I) {
2049 Build(*Doc.Symbols, SymN2I);
2050 if (Doc.DynamicSymbols)
2051 Build(*Doc.DynamicSymbols, DynSymN2I);
2054template <
class ELFT>
void ELFState<ELFT>::finalizeStrings() {
2059 DotStrtab.finalize();
2062 if (Doc.DynamicSymbols)
2070 if (VerNeed->VerneedV) {
2072 DotDynstr.add(
VE.File);
2074 DotDynstr.add(Aux.
Name);
2078 if (VerDef->Entries)
2081 DotDynstr.add(Name);
2085 DotDynstr.finalize();
2089 if (ShStrtabStrings != &DotStrtab && ShStrtabStrings != &DotDynstr)
2090 ShStrtabStrings->finalize();
2093template <
class ELFT>
2096 ELFState<ELFT> State(Doc, EH);
2102 State.buildSectionIndex();
2103 State.buildSymbolIndexes();
2108 State.finalizeStrings();
2113 std::vector<Elf_Phdr> PHeaders;
2114 State.initProgramHeaders(PHeaders);
2118 const size_t SectionContentBeginOffset =
2124 ContiguousBlobAccumulator CBA(SectionContentBeginOffset, MaxSize);
2126 std::vector<Elf_Shdr> SHeaders;
2127 State.initSectionHeaders(SHeaders, CBA);
2130 State.setProgramHeaderLayout(PHeaders, SHeaders);
2135 State.overrideSectionHeaders(SHeaders);
2137 bool ReachedLimit = CBA.getOffset() > MaxSize;
2138 if (
Error E = CBA.takeLimitError()) {
2141 ReachedLimit =
true;
2146 "the desired output size is greater than permitted. Use the "
2147 "--max-size option to change the limit");
2152 State.writeELFHeader(OS);
2157 CBA.updateDataAt(*SHT.
Offset, SHeaders.data(),
2160 CBA.writeBlobToStream(OS);
2173 return ELFState<object::ELF64LE>::writeELF(Out, Doc, EH, MaxSize);
2174 return ELFState<object::ELF64BE>::writeELF(Out, Doc, EH, MaxSize);
2177 return ELFState<object::ELF32LE>::writeELF(Out, Doc, EH, MaxSize);
2178 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, GsymDataExtractor &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.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
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_arg_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.
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
Check if the string is empty.
char back() const
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)
LLVM_ABI std::string appendUniqueSuffix(StringRef Name, const Twine &Msg)
unsigned getDefaultShEntSize(unsigned EMachine, ELF_SHT SecType, StringRef SecName)
LLVM_ABI StringRef dropUniqueSuffix(StringRef S)
LLVM_ABI 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)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
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...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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
@ 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,...
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
void consumeError(Error Err)
Consume a Error without doing anything.
LLVM_ABI Error write(DWPWriter &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue, Dwarf64StrOffsetsPromotion StrOffsetsOptValue, raw_pwrite_stream *OS=nullptr)
This struct is a compact representation of a valid (non-zero power of two) alignment.
llvm::yaml::Hex64 Metadata
std::optional< std::vector< llvm::yaml::Hex64 > > CallsiteEndOffsets
std::optional< llvm::yaml::Hex64 > Hash
llvm::yaml::Hex64 AddressOffset
std::optional< std::vector< BBEntry > > BBEntries
std::optional< uint64_t > NumBlocks
llvm::yaml::Hex64 BaseAddress
std::optional< uint64_t > FuncEntryCount
std::optional< std::vector< PGOBBEntry > > PGOBBEntries
LLVM_ABI SetVector< StringRef > getNonEmptySectionNames() const
std::optional< llvm::yaml::Hex64 > Offset
std::optional< yaml::BinaryRef > Pattern
const SectionHeaderTable & getSectionHeaderTable() const
std::vector< ProgramHeader > ProgramHeaders
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.