36template <
class ELFT>
void ELFWriter<ELFT>::writePhdr(
const Segment &Seg) {
38 Obj.ProgramHdrSegment.Offset + Seg.
Index *
sizeof(Elf_Phdr);
39 Elf_Phdr &Phdr = *
reinterpret_cast<Elf_Phdr *
>(
B);
40 Phdr.p_type = Seg.
Type;
41 Phdr.p_flags = Seg.
Flags;
42 Phdr.p_offset = Seg.
Offset;
43 Phdr.p_vaddr = Seg.
VAddr;
44 Phdr.p_paddr = Seg.
PAddr;
47 Phdr.p_align = Seg.
Align;
66template <
class ELFT>
void ELFWriter<ELFT>::writeShdr(
const SectionBase &Sec) {
69 Elf_Shdr &Shdr = *
reinterpret_cast<Elf_Shdr *
>(
B);
71 Shdr.sh_type = Sec.
Type;
72 Shdr.sh_flags = Sec.
Flags;
73 Shdr.sh_addr = Sec.
Addr;
74 Shdr.sh_offset = Sec.
Offset;
75 Shdr.sh_size = Sec.
Size;
76 Shdr.sh_link = Sec.
Link;
77 Shdr.sh_info = Sec.
Info;
78 Shdr.sh_addralign = Sec.
Align;
104 Sec.
Align = ELFT::Is64Bits ?
sizeof(Elf_Xword) :
sizeof(Elf_Word);
110 using uint = std::conditional_t<Is64, uint64_t, uint32_t>;
114 uint32_t CurSymIdx = R.RelocSymbol ? R.RelocSymbol->Index : 0;
116 std::make_signed_t<uint>(R.Addend)};
129 Sec.
Align = ELFT::Is64Bits ?
sizeof(Elf_Xword) :
sizeof(Elf_Word);
140 Sec.
Size =
sizeof(Elf_Word) + Sec.GroupMembers.size() *
sizeof(Elf_Word);
160 "cannot write symbol section index table '" +
166 "cannot write symbol table '" + Sec.
Name +
172 "cannot write relocation section '" + Sec.
Name +
178 "cannot write '" + Sec.
Name +
"' out to binary");
183 "cannot write '" + Sec.
Name +
"' out to binary");
195 return Addr > UINT32_MAX && Addr + 0x80000000 > UINT32_MAX;
208template <
class T,
class Iterator>
211 std::fill(It, It + Len,
'0');
213 for (
long I = Len - 1;
I >= 0; --
I) {
214 unsigned char Mod =
static_cast<unsigned char>(
X) & 15;
236 auto Iter = Line.begin();
243 StringRef S(Line.data() + 1, std::distance(Line.begin() + 1, Iter));
247 assert(Iter == Line.end());
254 if (R.HexData.size() == 0)
257 "zero data length is not allowed for data records");
264 if (R.HexData.size() != 4)
267 "segment address data should be 2 bytes in size");
271 if (R.HexData.size() != 8)
273 "start address data should be 4 bytes in size");
279 R.HexData.take_front(3) !=
"000")
281 "start address exceeds 20 bit for 80x86");
285 if (R.HexData.size() != 4)
288 "extended address data should be 2 bytes in size");
293 static_cast<unsigned>(R.Type));
305 "missing ':' in the beginning of line.");
307 for (
size_t Pos = 1; Pos < Line.size(); ++Pos)
310 "invalid character at position %zu.", Pos + 1);
318 if (Line.size() < 11)
320 "line is too short: %zu chars.", Line.size());
329 "invalid line length %zu (should be %zu)",
356 while (!
Data.empty()) {
357 uint64_t DataSize = std::min<uint64_t>(
Data.size(), ChunkSize);
358 if (Addr > SegmentAddr + BaseAddr + 0xFFFFU) {
359 if (Addr > 0xFFFFFU) {
362 if (SegmentAddr != 0)
363 SegmentAddr = writeSegmentAddr(0U);
364 BaseAddr = writeBaseAddr(Addr);
367 SegmentAddr = writeSegmentAddr(Addr);
370 uint64_t SegOffset = Addr - BaseAddr - SegmentAddr;
371 assert(SegOffset <= 0xFFFFU);
372 DataSize = std::min(DataSize, 0x10000U - SegOffset);
379uint64_t IHexSectionWriterBase::writeSegmentAddr(uint64_t Addr) {
383 return Addr & 0xF0000U;
386uint64_t IHexSectionWriterBase::writeBaseAddr(uint64_t Addr) {
387 assert(Addr <= 0xFFFFFFFFU);
388 uint64_t
Base = Addr & 0xFFFF0000U;
434 std::vector<uint8_t>
Data(Sec.
Size);
441 return Visitor.
visit(*
this);
445 return Visitor.
visit(*
this);
450 assert(LinkSection ==
nullptr);
451 LinkSection = &SymTab;
475 "--decompress-debug-sections: ch_type (" +
477 Sec.
Name +
"' is unsupported");
482 "failed to decompress section '" + Sec.
Name +
485 static_cast<size_t>(Sec.
Size)))
487 "failed to decompress section '" + Sec.
Name +
498 "cannot write compressed section '" + Sec.
Name +
503 return Visitor.
visit(*
this);
507 return Visitor.
visit(*
this);
511 return Visitor.
visit(*
this);
515 return Visitor.
visit(*
this);
520 while (!HexData.
empty()) {
529 "cannot write compressed section '" + Sec.
Name +
537 switch (Sec.CompressionType) {
548 Chdr.ch_size = Sec.DecompressedSize;
549 Chdr.ch_addralign = Sec.DecompressedAlign;
550 memcpy(Buf, &Chdr,
sizeof(Chdr));
560 :
SectionBase(Sec), CompressionType(CompressionType),
570 Size = ChdrSize + CompressedData.size();
575 uint32_t ChType, uint64_t DecompressedSize,
576 uint64_t DecompressedAlign)
578 DecompressedSize(DecompressedSize), DecompressedAlign(DecompressedAlign) {
583 return Visitor.
visit(*
this);
587 return Visitor.
visit(*
this);
593 return StrTabBuilder.getOffset(
Name);
597 StrTabBuilder.finalize();
598 Size = StrTabBuilder.getSize();
602 Sec.StrTabBuilder.
write(
reinterpret_cast<uint8_t *
>(
Out.getBufferStart()) +
608 return Visitor.
visit(*
this);
612 return Visitor.
visit(*
this);
618 llvm::copy(Sec.Indexes,
reinterpret_cast<Elf_Word *
>(Buf));
630 " is not a symbol table");
635 Symbols->setShndxTable(
this);
642 return Visitor.
visit(*
this);
646 return Visitor.
visit(*
this);
706void SymbolTableSection::assignIndices() {
709 if (Sym->Index != Index)
711 Sym->Index = Index++;
717 uint8_t Visibility, uint16_t Shndx,
718 uint64_t SymbolSize) {
724 if (DefinedIn !=
nullptr)
726 if (DefinedIn ==
nullptr) {
734 Sym.
Size = SymbolSize;
736 Symbols.emplace_back(std::make_unique<Symbol>(Sym));
745 if (!AllowBrokenLinks)
748 "string table '%s' cannot be removed because it is "
749 "referenced by the symbol table '%s'",
760 std::stable_partition(
772 auto PrevSize =
Size;
782 for (std::unique_ptr<Symbol> &Sym :
Symbols)
792 "Symbol table has link index of " +
Twine(
Link) +
793 " which is not a valid index",
794 "Symbol table has link index of " +
Twine(
Link) +
795 " which is not a string table");
805 for (std::unique_ptr<Symbol> &Sym :
Symbols) {
809 MaxLocalIndex = std::max(MaxLocalIndex, Sym->Index);
813 Info = MaxLocalIndex + 1;
828 for (std::unique_ptr<Symbol> &Sym :
Symbols)
837 for (
const std::unique_ptr<Symbol> &Sym :
Symbols) {
838 if (Sym->DefinedIn !=
nullptr && Sym->DefinedIn->Index >=
SHN_LORESERVE)
859 return const_cast<Symbol *
>(*Sym);
864 Elf_Sym *Sym =
reinterpret_cast<Elf_Sym *
>(
Out.getBufferStart() + Sec.
Offset);
880 return Visitor.
visit(*
this);
884 return Visitor.
visit(*
this);
903 if (!AllowBrokenLinks)
906 "symbol table '%s' cannot be removed because it is "
907 "referenced by the relocation section '%s'",
908 Symbols->Name.data(), this->Name.data());
913 if (!R.RelocSymbol || !R.RelocSymbol->DefinedIn ||
917 "section '%s' cannot be removed: (%s+0x%" PRIx64
918 ") has relocation against symbol '%s'",
919 R.RelocSymbol->DefinedIn->Name.data(),
921 R.RelocSymbol->Name.c_str());
927template <
class SymTabType>
936 " is not a symbol table");
946 " in section " +
Name +
" is invalid");
957template <
class SymTabType>
970 Rela.r_addend = Addend;
973template <
class RelRange,
class T>
974static void writeRel(
const RelRange &Relocations,
T *Buf,
bool IsMips64EL) {
975 for (
const auto &
Reloc : Relocations) {
976 Buf->r_offset =
Reloc.Offset;
978 Buf->setSymbolAndType(
Reloc.RelocSymbol ?
Reloc.RelocSymbol->Index : 0,
979 Reloc.Type, IsMips64EL);
989 memcpy(Buf, Content.data(), Content.size());
991 writeRel(Sec.Relocations,
reinterpret_cast<Elf_Rel *
>(Buf),
994 writeRel(Sec.Relocations,
reinterpret_cast<Elf_Rela *
>(Buf),
1001 return Visitor.
visit(*
this);
1005 return Visitor.
visit(*
this);
1014 "not stripping symbol '%s' because it is named in a relocation",
1015 Reloc.RelocSymbol->Name.data());
1021 if (
Reloc.RelocSymbol)
1022 Reloc.RelocSymbol->Referenced =
true;
1038 return Visitor.
visit(*
this);
1042 return Visitor.
visit(*
this);
1048 if (!AllowBrokenLinks)
1051 "symbol table '%s' cannot be removed because it is "
1052 "referenced by the relocation section '%s'",
1053 Symbols->Name.data(), this->Name.data());
1066 bool AllowBrokenDependency,
1069 if (!AllowBrokenDependency)
1071 "section '%s' cannot be removed because it is "
1072 "referenced by the section '%s'",
1073 LinkSection->Name.data(), this->Name.data());
1074 LinkSection =
nullptr;
1080 this->
Info = Sym ? Sym->Index : 0;
1081 this->
Link = SymTab ? SymTab->Index : 0;
1093 if (!AllowBrokenLinks)
1096 "section '.symtab' cannot be removed because it is "
1097 "referenced by the group section '%s'",
1109 "symbol '%s' cannot be removed because it is "
1110 "referenced by the section '%s[%d]'",
1111 Sym->Name.data(), this->Name.data(), this->Index);
1117 Sym->Referenced =
true;
1140 " in section " +
Name +
" is invalid");
1147 HasSymTabLink =
true;
1148 LinkSection =
nullptr;
1166 Name =
".gnu_debuglink";
1175 : FileName(
File), CRC32(PrecomputedCRC) {
1179template <
class ELFT>
1181 unsigned char *Buf =
1184 reinterpret_cast<Elf_Word *
>(Buf + Sec.
Size -
sizeof(Elf_Word));
1191 return Visitor.
visit(*
this);
1195 return Visitor.
visit(*
this);
1198template <
class ELFT>
1209 return Visitor.
visit(*
this);
1213 return Visitor.
visit(*
this);
1234 if (SectionIsTLS != SegmentIsTLS)
1257 if (
A->OriginalOffset <
B->OriginalOffset)
1259 if (
A->OriginalOffset >
B->OriginalOffset)
1265 if (
A->Align !=
B->Align)
1266 return A->Align >
B->Align;
1267 return A->Index <
B->Index;
1274 Obj->ABIVersion = 0;
1284 StrTab.
Name =
".strtab";
1286 Obj->SectionNames = &StrTab;
1293 SymTab.
Name =
".symtab";
1294 SymTab.Link = StrTab->
Index;
1297 SymTab.addSymbol(
"", 0, 0,
nullptr, 0, 0, 0, 0);
1299 Obj->SymbolTable = &SymTab;
1319 DataSection.
Name =
".data";
1321 DataSection.Size =
Data.size();
1326 std::begin(SanitizedFilename), std::end(SanitizedFilename),
1327 [](
char C) {
return !
isAlnum(
C); },
'_');
1328 Twine Prefix =
Twine(
"_binary_") + SanitizedFilename;
1331 0, NewSymbolVisibility, 0, 0);
1333 DataSection.Size, NewSymbolVisibility, 0, 0);
1335 DataSection.Size, NewSymbolVisibility,
SHN_ABS,
1345 return std::move(Err);
1348 return std::move(
Obj);
1353void IHexELFBuilder::addDataSections() {
1355 uint64_t SegmentAddr = 0, BaseAddr = 0;
1363 if (R.HexData.empty())
1365 RecAddr = R.Addr + SegmentAddr + BaseAddr;
1372 ".sec" + std::to_string(SecNo), RecAddr,
1376 Section->appendHexData(R.HexData);
1405 return std::move(Err);
1408 return std::move(
Obj);
1411template <
class ELFT>
1413 std::optional<StringRef> ExtractPartition)
1414 : ElfFile(ElfObj.getELFFile()), Obj(Obj),
1415 ExtractPartition(ExtractPartition) {
1416 Obj.IsMips64EL = ElfFile.isMips64EL();
1419template <
class ELFT>
void ELFBuilder<ELFT>::setParentSegment(
Segment &Child) {
1420 for (
Segment &Parent : Obj.segments()) {
1435template <
class ELFT>
Error ELFBuilder<ELFT>::findEhdrOffset() {
1436 if (!ExtractPartition)
1446 "could not find partition named '" +
1447 *ExtractPartition +
"'");
1450template <
class ELFT>
1454 Expected<typename ELFFile<ELFT>::Elf_Phdr_Range> Headers =
1460 if (Phdr.p_offset + Phdr.p_filesz > HeadersFile.
getBufSize())
1465 " goes past the end of the file");
1467 ArrayRef<uint8_t>
Data{HeadersFile.
base() + Phdr.p_offset,
1468 (size_t)Phdr.p_filesz};
1470 Seg.
Type = Phdr.p_type;
1471 Seg.
Flags = Phdr.p_flags;
1473 Seg.
Offset = Phdr.p_offset + EhdrOffset;
1474 Seg.
VAddr = Phdr.p_vaddr;
1475 Seg.
PAddr = Phdr.p_paddr;
1478 Seg.
Align = Phdr.p_align;
1488 auto &ElfHdr =
Obj.ElfHdrSegment;
1489 ElfHdr.Index =
Index++;
1490 ElfHdr.OriginalOffset = ElfHdr.Offset = EhdrOffset;
1492 const typename ELFT::Ehdr &Ehdr = HeadersFile.
getHeader();
1493 auto &PrHdr =
Obj.ProgramHdrSegment;
1500 PrHdr.OriginalOffset = PrHdr.Offset = PrHdr.VAddr = EhdrOffset + Ehdr.e_phoff;
1502 PrHdr.FileSize = PrHdr.MemSize = Ehdr.e_phentsize * Ehdr.e_phnum;
1504 PrHdr.Align =
sizeof(Elf_Addr);
1505 PrHdr.Index =
Index++;
1510 setParentSegment(Child);
1511 setParentSegment(ElfHdr);
1512 setParentSegment(PrHdr);
1517template <
class ELFT>
1521 "invalid alignment " + Twine(GroupSec->
Align) +
1522 " of group section '" + GroupSec->
Name +
"'");
1525 auto SymTab = SecTable.template getSectionOfType<SymbolTableSection>(
1527 "link field value '" + Twine(GroupSec->
Link) +
"' in section '" +
1528 GroupSec->
Name +
"' is invalid",
1529 "link field value '" + Twine(GroupSec->
Link) +
"' in section '" +
1530 GroupSec->
Name +
"' is not a symbol table");
1532 return SymTab.takeError();
1537 "info field value '" + Twine(GroupSec->
Info) +
1538 "' in section '" + GroupSec->
Name +
1539 "' is not a valid symbol index");
1546 "the content of the section " + GroupSec->
Name +
1555 Expected<SectionBase *> Sec = SecTable.
getSection(
1556 Index,
"group member index " + Twine(Index) +
" in section '" +
1557 GroupSec->
Name +
"' is invalid");
1567template <
class ELFT>
1569 Expected<const Elf_Shdr *> Shdr = ElfFile.getSection(SymTab->
Index);
1573 Expected<StringRef> StrTabData = ElfFile.getStringTableForSymtab(**Shdr);
1579 Expected<typename ELFFile<ELFT>::Elf_Sym_Range>
Symbols =
1580 ElfFile.symbols(*Shdr);
1587 Expected<StringRef>
Name = Sym.getName(*StrTabData);
1589 return Name.takeError();
1594 "symbol '" + *Name +
1595 "' has index SHN_XINDEX but no "
1596 "SHT_SYMTAB_SHNDX section exists");
1597 if (ShndxData.
data() ==
nullptr) {
1598 Expected<const Elf_Shdr *> ShndxSec =
1603 Expected<ArrayRef<Elf_Word>>
Data =
1604 ElfFile.template getSectionContentsAsArray<Elf_Word>(**ShndxSec);
1606 return Data.takeError();
1612 "symbol section index table does not have the same number of "
1613 "entries as the symbol table");
1616 Expected<SectionBase *> Sec =
Obj.sections().getSection(
1618 "symbol '" + *Name +
"' has invalid section index " + Twine(Index));
1627 "symbol '" + *Name +
1628 "' has unsupported value greater than or equal "
1629 "to SHN_LORESERVE: " +
1630 Twine(Sym.st_shndx));
1633 Expected<SectionBase *> Sec =
Obj.sections().getSection(
1634 Sym.st_shndx,
"symbol '" + *Name +
1635 "' is defined has invalid section index " +
1636 Twine(Sym.st_shndx));
1643 SymTab->
addSymbol(*Name, Sym.getBinding(), Sym.getType(), DefSection,
1644 Sym.getValue(), Sym.st_other, Sym.st_shndx, Sym.st_size);
1650template <
class ELFT>
1653template <
class ELFT>
1655 ToSet = Rela.r_addend;
1660 for (
const auto &Rel : RelRange) {
1662 ToAdd.
Offset = Rel.r_offset;
1670 "'" + Relocs->
Name +
"': relocation references symbol with index " +
1671 Twine(Sym) +
", but there is no symbol table");
1688 if (Index ==
SHN_UNDEF || Index > Sections.size())
1690 return Sections[Index - 1].get();
1707template <
class ELFT>
1709 switch (Shdr.sh_type) {
1717 if ((Shdr.sh_flags &
SHF_ALLOC) && ElfFile.getHeader().e_type !=
ET_REL) {
1721 return Data.takeError();
1730 return Obj.addSection<
Section>(*Data);
1732 return Data.takeError();
1740 return Obj.addSection<
Section>(*Data);
1742 return Data.takeError();
1747 return Data.takeError();
1752 return Data.takeError();
1757 return Data.takeError();
1760 if (Obj.SymbolTable !=
nullptr)
1762 "found multiple SHT_SYMTAB sections");
1764 Obj.SymbolTable = &SymTab;
1769 Obj.SectionIndexTable = &ShndxSection;
1770 return ShndxSection;
1773 return Obj.addSection<
Section>(ArrayRef<uint8_t>());
1775 Expected<ArrayRef<uint8_t>>
Data = ElfFile.getSectionContents(Shdr);
1777 return Data.takeError();
1779 Expected<StringRef>
Name = ElfFile.getSectionName(Shdr);
1781 return Name.takeError();
1785 auto *Chdr =
reinterpret_cast<const Elf_Chdr_Impl<ELFT> *
>(
Data->data());
1787 *
Data, Chdr->ch_type, Chdr->ch_size, Chdr->ch_addralign));
1792template <
class ELFT>
Error ELFBuilder<ELFT>::readSectionHeaders() {
1794 Expected<typename ELFFile<ELFT>::Elf_Shdr_Range> Sections =
1804 Expected<SectionBase &> Sec = makeSection(Shdr);
1808 Expected<StringRef> SecName = ElfFile.getSectionName(Shdr);
1811 Sec->Name = SecName->str();
1812 Sec->Type = Sec->OriginalType = Shdr.sh_type;
1813 Sec->Flags = Sec->OriginalFlags = Shdr.sh_flags;
1814 Sec->Addr = Shdr.sh_addr;
1815 Sec->Offset = Shdr.sh_offset;
1816 Sec->OriginalOffset = Shdr.sh_offset;
1817 Sec->Size = Shdr.sh_size;
1818 Sec->Link = Shdr.sh_link;
1819 Sec->Info = Shdr.sh_info;
1820 Sec->Align = Shdr.sh_addralign;
1821 Sec->EntrySize = Shdr.sh_entsize;
1822 Sec->Index =
Index++;
1823 Sec->OriginalIndex = Sec->Index;
1824 Sec->OriginalData = ArrayRef<uint8_t>(
1825 ElfFile.base() + Shdr.sh_offset,
1826 (Shdr.sh_type ==
SHT_NOBITS) ? (
size_t)0 : Shdr.sh_size);
1832template <
class ELFT>
Error ELFBuilder<ELFT>::readSections(
bool EnsureSymtab) {
1833 uint32_t ShstrIndex = ElfFile.getHeader().e_shstrndx;
1835 Expected<const Elf_Shdr *> Sec = ElfFile.getSection(0);
1839 ShstrIndex = (*Sec)->sh_link;
1843 Obj.HadShdrs =
false;
1845 Expected<StringTableSection *> Sec =
1846 Obj.sections().template getSectionOfType<StringTableSection>(
1848 "e_shstrndx field value " + Twine(ShstrIndex) +
" in elf header " +
1850 "e_shstrndx field value " + Twine(ShstrIndex) +
" in elf header " +
1851 " does not reference a string table");
1855 Obj.SectionNames = *Sec;
1861 if (
Obj.SectionIndexTable)
1862 if (
Error Err =
Obj.SectionIndexTable->initialize(
Obj.sections()))
1868 if (
Obj.SymbolTable) {
1869 if (
Error Err =
Obj.SymbolTable->initialize(
Obj.sections()))
1871 if (
Error Err = initSymbolTable(
Obj.SymbolTable))
1873 }
else if (EnsureSymtab) {
1874 if (
Error Err =
Obj.addNewSymbolTable())
1882 if (&Sec ==
Obj.SymbolTable)
1884 if (
Error Err = Sec.initialize(
Obj.sections()))
1887 Expected<typename ELFFile<ELFT>::Elf_Shdr_Range> Sections =
1893 Sections->begin() + RelSec->Index;
1895 auto RelsOrRelas = ElfFile.crels(*Shdr);
1897 return RelsOrRelas.takeError();
1902 }
else if (RelSec->Type ==
SHT_REL) {
1903 Expected<typename ELFFile<ELFT>::Elf_Rel_Range> Rels =
1904 ElfFile.rels(*Shdr);
1911 Expected<typename ELFFile<ELFT>::Elf_Rela_Range> Relas =
1912 ElfFile.relas(*Shdr);
1920 if (
Error Err = initGroupSection(GroupSec))
1929 if (
Error E = readSectionHeaders())
1931 if (
Error E = findEhdrOffset())
1938 {ElfFile.base() + EhdrOffset, ElfFile.getBufSize() - EhdrOffset}));
1944 Obj.OSABI = Ehdr.e_ident[
EI_OSABI];
1946 Obj.Type = Ehdr.e_type;
1947 Obj.Machine = Ehdr.e_machine;
1948 Obj.Version = Ehdr.e_version;
1949 Obj.Entry = Ehdr.e_entry;
1950 Obj.Flags = Ehdr.e_flags;
1952 if (
Error E = readSections(EnsureSymtab))
1954 return readProgramHeaders(*HeadersFile);
1968 std::vector<IHexRecord> Records;
1969 bool HasSections =
false;
1972 Records.
reserve(Lines.size());
1973 for (
size_t LineNo = 1; LineNo <= Lines.size(); ++LineNo) {
1974 StringRef Line = Lines[LineNo - 1].trim();
1980 return parseError(LineNo, R.takeError());
1987 return parseError(-1U,
"no sections");
1989 return std::move(Records);
1996 return Records.takeError();
2002 auto Obj = std::make_unique<Object>();
2005 if (
Error Err = Builder.build(EnsureSymtab))
2006 return std::move(Err);
2007 return std::move(Obj);
2010 if (
Error Err = Builder.build(EnsureSymtab))
2011 return std::move(Err);
2012 return std::move(Obj);
2015 if (
Error Err = Builder.build(EnsureSymtab))
2016 return std::move(Err);
2017 return std::move(Obj);
2020 if (
Error Err = Builder.build(EnsureSymtab))
2021 return std::move(Err);
2022 return std::move(Obj);
2027template <
class ELFT>
void ELFWriter<ELFT>::writeEhdr() {
2028 Elf_Ehdr &Ehdr = *
reinterpret_cast<Elf_Ehdr *
>(Buf->getBufferStart());
2029 std::fill(Ehdr.e_ident, Ehdr.e_ident + 16, 0);
2038 Ehdr.e_ident[
EI_OSABI] = Obj.OSABI;
2041 Ehdr.e_type = Obj.Type;
2042 Ehdr.e_machine = Obj.Machine;
2043 Ehdr.e_version = Obj.Version;
2044 Ehdr.e_entry = Obj.Entry;
2048 Ehdr.e_phoff = (Ehdr.e_phnum != 0) ? Obj.ProgramHdrSegment.Offset : 0;
2049 Ehdr.e_phentsize = (Ehdr.e_phnum != 0) ?
sizeof(Elf_Phdr) : 0;
2050 Ehdr.e_flags = Obj.Flags;
2051 Ehdr.e_ehsize =
sizeof(Elf_Ehdr);
2052 if (WriteSectionHeaders && Obj.sections().size() != 0) {
2053 Ehdr.e_shentsize =
sizeof(Elf_Shdr);
2054 Ehdr.e_shoff = Obj.SHOff;
2061 auto Shnum = Obj.sections().size() + 1;
2065 Ehdr.e_shnum = Shnum;
2075 Ehdr.e_shstrndx = Obj.SectionNames->Index;
2077 Ehdr.e_shentsize = 0;
2080 Ehdr.e_shstrndx = 0;
2084template <
class ELFT>
void ELFWriter<ELFT>::writePhdrs() {
2085 for (
auto &Seg : Obj.segments())
2089template <
class ELFT>
void ELFWriter<ELFT>::writeShdrs() {
2093 *
reinterpret_cast<Elf_Shdr *
>(Buf->getBufferStart() +
Obj.SHOff);
2102 Shdr.sh_size = Shnum;
2107 Shdr.sh_link =
Obj.SectionNames->Index;
2111 Shdr.sh_addralign = 0;
2112 Shdr.sh_entsize = 0;
2118template <
class ELFT>
Error ELFWriter<ELFT>::writeSectionData() {
2123 if (Sec.ParentSegment ==
nullptr)
2124 if (
Error Err = Sec.accept(*SecWriter))
2130template <
class ELFT>
void ELFWriter<ELFT>::writeSegmentData() {
2137 for (
const auto &it :
Obj.getUpdatedSections()) {
2139 ArrayRef<uint8_t>
Data = it.second;
2142 assert(Parent &&
"This section should've been part of a segment.");
2149 for (
auto &Sec :
Obj.removedSections()) {
2150 Segment *Parent = Sec.ParentSegment;
2151 if (Parent ==
nullptr || Sec.Type ==
SHT_NOBITS || Sec.Size == 0)
2155 std::memset(Buf->getBufferStart() +
Offset, 0, Sec.Size);
2159template <
class ELFT>
2166 if (!Sec->hasContents())
2169 "section '%s' cannot be updated because it does not have contents",
2172 if (
Data.size() > Sec->Size && Sec->ParentSegment)
2174 "cannot fit data of size %zu into section '%s' "
2175 "with size %" PRIu64
" that is part of a segment",
2176 Data.size(), Sec->Name.c_str(), Sec->Size);
2178 if (!Sec->ParentSegment) {
2190 Sec->Size =
Data.size();
2191 UpdatedSections[Sec.get()] =
Data;
2198 [&](
const SecPtr &Sec) {
return Sec->Name == Name; });
2199 if (It == Sections.end())
2201 Name.str().c_str());
2202 return updateSectionData(*It,
Data);
2207 [&](
const SecPtr &Sec) {
return Sec.get() == &S; });
2208 assert(It != Sections.end() &&
"The section should belong to the object");
2209 return updateSectionData(*It,
Data);
2215 auto Iter = std::stable_partition(
2216 std::begin(Sections), std::end(Sections), [=](
const SecPtr &Sec) {
2220 if (
auto ToRelSec = RelSec->getSection())
2240 RemoveSections.
reserve(std::distance(Iter, std::end(Sections)));
2241 for (
auto &RemoveSec :
make_range(Iter, std::end(Sections))) {
2242 for (
auto &
Segment : Segments)
2244 RemoveSec->onRemove();
2245 RemoveSections.
insert(RemoveSec.get());
2253 for (
auto &KeepSec :
make_range(std::begin(Sections), Iter)) {
2254 if (
Error E = KeepSec->removeSectionReferences(
2255 AllowBrokenLinks, [&RemoveSections](
const SectionBase *Sec) {
2256 return RemoveSections.find(Sec) != RemoveSections.end();
2263 std::move(Iter, Sections.end(), std::back_inserter(RemovedSections));
2265 Sections.erase(Iter, std::end(Sections));
2271 auto SectionIndexLess = [](
const SecPtr &Lhs,
const SecPtr &Rhs) {
2272 return Lhs->Index < Rhs->Index;
2275 "Sections are expected to be sorted by Index");
2278 for (
auto &
I : FromTo)
2279 I.second->Index =
I.first->Index;
2282 for (
auto &Sec : Sections)
2283 Sec->replaceSectionReferences(FromTo);
2295 for (
const SecPtr &Sec : Sections)
2320 SymTab.
Name =
".symtab";
2324 SymTab.
addSymbol(
"", 0, 0,
nullptr, 0, 0, 0, 0);
2347 for (
Segment *Seg : Segments) {
2371template <
class Range>
2381 std::vector<SectionBase *> OutOfSegmentSections;
2383 for (
auto &Sec : Sections) {
2384 Sec.Index = Index++;
2385 if (Sec.ParentSegment !=
nullptr) {
2390 OutOfSegmentSections.push_back(&Sec);
2397 for (
auto *Sec : OutOfSegmentSections) {
2411 std::vector<SectionBase *> Sections;
2412 Sections.reserve(Obj.sections().size());
2414 for (
auto &Sec : Obj.sections()) {
2415 Sec.Index = Index++;
2416 Sections.push_back(&Sec);
2423 for (
auto *Sec : Sections) {
2424 auto *FirstSec = Sec->ParentSegment && Sec->ParentSegment->Type ==
PT_LOAD
2425 ? Sec->ParentSegment->firstSection()
2430 if (FirstSec && FirstSec == Sec)
2445 }
else if (FirstSec != Sec) {
2448 Off = Sec->OriginalOffset - FirstSec->OriginalOffset + FirstSec->Offset;
2461 for (
Segment *Seg : Segments) {
2473 FirstSec ? FirstSec->
Offset
2487 FileSize = std::max(FileSize, HdrEnd -
Offset);
2492 MaxOffset = std::max(MaxOffset,
Offset + FileSize);
2497template <
class ELFT>
void ELFWriter<ELFT>::initEhdrSegment() {
2507template <
class ELFT>
void ELFWriter<ELFT>::assignOffsets() {
2511 std::vector<Segment *> OrderedSegments;
2513 OrderedSegments.push_back(&
Segment);
2514 OrderedSegments.push_back(&
Obj.ElfHdrSegment);
2515 OrderedSegments.push_back(&
Obj.ProgramHdrSegment);
2519 if (OnlyKeepDebug) {
2524 sizeof(Elf_Ehdr) +
llvm::size(
Obj.segments()) *
sizeof(Elf_Phdr);
2537 if (WriteSectionHeaders)
2542template <
class ELFT>
size_t ELFWriter<ELFT>::totalSize()
const {
2545 if (!WriteSectionHeaders)
2547 size_t ShdrCount =
Obj.sections().size() + 1;
2548 return Obj.SHOff + ShdrCount *
sizeof(Elf_Shdr);
2557 if (
Error E = writeSectionData())
2564 Out.write(
Buf->getBufferStart(),
Buf->getBufferSize());
2573 if (Obj.isRelocatable() || Obj.SymbolTable ==
nullptr ||
2574 !Obj.SymbolTable->empty())
2579 auto *StrTab = Obj.SymbolTable->getStrTab() == Obj.SectionNames
2581 : Obj.SymbolTable->getStrTab();
2582 return Obj.removeSections(
false, [&](
const SectionBase &Sec) {
2583 return &Sec == Obj.SymbolTable || &Sec == StrTab;
2593 "cannot write section header table because "
2594 "section header string table was removed");
2601 if (
Obj.SymbolTable && !
Obj.SymbolTable->indicesChanged())
2603 Sec.restoreSymTabLink(*
Obj.SymbolTable);
2608 bool NeedsLargeIndexes =
false;
2620 if (NeedsLargeIndexes) {
2623 if (
Obj.SymbolTable !=
nullptr &&
Obj.SectionIndexTable ==
nullptr) {
2627 Obj.SymbolTable->setShndxTable(&Shndx);
2628 Shndx.setSymTab(
Obj.SymbolTable);
2633 if (
Obj.SectionIndexTable !=
nullptr) {
2635 if (
Error E =
Obj.removeSections(
false ,
2637 return &Sec == Obj.SectionIndexTable;
2645 if (
Obj.SectionNames !=
nullptr)
2647 Obj.SectionNames->addString(Sec.Name);
2655 auto SecSizer = std::make_unique<ELFSectionSizer<ELFT>>();
2657 Sec.Index = Index++;
2658 if (
Error Err = Sec.accept(*SecSizer))
2665 if (
Obj.SymbolTable !=
nullptr)
2666 Obj.SymbolTable->prepareForLayout();
2672 StrTab->prepareForLayout();
2678 if (
Obj.SymbolTable !=
nullptr)
2679 Obj.SymbolTable->fillShndxTable();
2683 uint64_t
Offset =
Obj.SHOff +
sizeof(Elf_Shdr);
2685 Sec.HeaderOffset =
Offset;
2686 Offset +=
sizeof(Elf_Shdr);
2688 Sec.NameIndex =
Obj.SectionNames->findIndex(Sec.Name);
2692 size_t TotalSize = totalSize();
2696 "failed to allocate memory buffer of " +
2699 SecWriter = std::make_unique<ELFSectionWriter<ELFT>>(*Buf);
2710 if (SectionsToWrite.
empty())
2715 return LHS->Offset < RHS->Offset;
2720 for (
size_t i = 0; i != SectionsToWrite.
size(); ++i) {
2726 uint64_t PadOffset = (i < SectionsToWrite.
size() - 1)
2727 ? SectionsToWrite[i + 1]->Offset
2728 :
Buf->getBufferSize();
2729 assert(PadOffset <= Buf->getBufferSize());
2732 Buf->getBufferStart() + PadOffset, GapFill);
2737 Out.write(
Buf->getBufferStart(),
Buf->getBufferSize());
2748 if (Sec.ParentSegment !=
nullptr)
2750 Sec.Offset - Sec.ParentSegment->Offset + Sec.ParentSegment->PAddr;
2752 MinAddr = std::min(MinAddr, Sec.Addr);
2759 TotalSize = PadTo > MinAddr ? PadTo - MinAddr : 0;
2761 if (Sec.Type !=
SHT_NOBITS && Sec.Size > 0) {
2762 Sec.Offset = Sec.Addr - MinAddr;
2763 TotalSize = std::max(TotalSize, Sec.Offset + Sec.Size);
2769 "failed to allocate memory buffer of " +
2771 SecWriter = std::make_unique<BinarySectionWriter>(*
Buf);
2780 "section '%s' address range [0x%llx, 0x%llx] is not 32 bit",
2789 "entry point address 0x%llx overflows 32 bits",
2804 std::unique_ptr<WritableMemoryBuffer> EmptyBuffer =
2808 "failed to allocate memory buffer of 0 bytes");
2818 "failed to allocate memory buffer of 0x" +
2823uint64_t IHexWriter::writeEntryPointRecord(
uint8_t *Buf) {
2841 return HexData.
size();
2844uint64_t IHexWriter::writeEndOfFileRecord(uint8_t *Buf) {
2847 return HexData.
size();
2851IHexWriter::getTotalSize(WritableMemoryBuffer &EmptyBuffer)
const {
2852 IHexSectionWriterBase LengthCalc(EmptyBuffer);
2853 for (
const SectionBase *Sec :
Sections)
2854 if (
Error Err = Sec->accept(LengthCalc))
2855 return std::move(Err);
2859 return LengthCalc.getBufferOffset() +
2861 IHexRecord::getLineLength(0);
2873 Offset += writeEntryPointRecord(
2876 Offset += writeEndOfFileRecord(
2882 Out.write(
Buf->getBufferStart(),
Buf->getBufferSize());
2889 "Expected section size to have been finalized");
2934 while (!
Data.empty()) {
2935 uint64_t DataSize = std::min<uint64_t>(
Data.size(), ChunkSize);
2945 "Section size does not match the section's string table builder size");
2946 std::vector<uint8_t>
Data(Sec.
Size);
2954 auto *Iter = Line.begin();
2956 *Iter++ =
'0' +
Type;
2968 assert(Iter == Line.end());
2974 Sum += (
Address >> 24) & 0xFF;
2975 Sum += (
Address >> 16) & 0xFF;
2980 return 0xFF - (Sum & 0xFF);
3023 reinterpret_cast<const uint8_t *
>(HeaderContents.
data()),
3024 HeaderContents.
size());
3028size_t SRECWriter::writeHeader(
uint8_t *Buf) {
3036 "Invalid record type for terminator");
3044SRECWriter::getTotalSize(WritableMemoryBuffer &EmptyBuffer)
const {
3045 SRECSizeCalculator SizeCalc(EmptyBuffer, 0);
3046 for (
const SectionBase *Sec :
Sections)
3047 if (
Error Err = Sec->accept(SizeCalc))
3048 return std::move(Err);
3050 SizeCalc.writeRecords(
Obj.Entry);
3053 uint8_t TerminatorType = 10 - SizeCalc.getType();
3054 SRecord
Terminator = {TerminatorType,
static_cast<uint32_t
>(
Obj.Entry), {}};
3055 return Header.getSize() + SizeCalc.getBufferOffset() +
Terminator.getSize();
3060 writeHeader(
reinterpret_cast<uint8_t *
>(
Buf->getBufferStart()));
3071 Offset += writeTerminator(
3075 Out.write(
Buf->getBufferStart(),
Buf->getBufferSize());
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
ReachingDefInfo InstSet & ToRemove
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool segmentOverlapsSegment(const Segment &Child, const Segment &Parent)
static void setAddend(Elf_Rel_Impl< ELFT, false > &, uint64_t)
static Error checkChars(StringRef Line)
static void orderSegments(std::vector< Segment * > &Segments)
static uint64_t layoutSegments(std::vector< Segment * > &Segments, uint64_t Offset)
static bool compareSegmentsByOffset(const Segment *A, const Segment *B)
static uint64_t layoutSections(Range Sections, uint64_t Offset)
static uint64_t layoutSectionsForOnlyKeepDebug(Object &Obj, uint64_t Off)
static bool isValidReservedSectionIndex(uint16_t Index, uint16_t Machine)
static uint64_t layoutSegmentsForOnlyKeepDebug(std::vector< Segment * > &Segments, uint64_t HdrEnd)
static void getAddend(uint64_t &, const Elf_Rel_Impl< ELFT, false > &)
static void writeRel(const RelRange &Relocations, T *Buf, bool IsMips64EL)
static bool addressOverflows32bit(uint64_t Addr)
static T checkedGetHex(StringRef S)
static uint64_t sectionPhysicalAddr(const SectionBase *Sec)
static Iterator toHexStr(T X, Iterator It, size_t Len)
static Error checkRecord(const IHexRecord &R)
static Error initRelocations(RelocationSection *Relocs, T RelRange)
static Error removeUnneededSections(Object &Obj)
static bool sectionWithinSegment(const SectionBase &Sec, const Segment &Seg)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
Function const char TargetMachine * Machine
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
This file defines the SmallPtrSet class.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
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.
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.
Error takeError()
Take ownership of the stored error.
virtual StringRef getBufferIdentifier() const
Return an identifier for this buffer, typically the filename it was read from.
size_t getBufferSize() const
StringRef getBuffer() const
const char * getBufferStart() const
void reserve(size_type NewNumEntries)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void reserve(size_type N)
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
std::string str() const
Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr bool empty() const
Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
Get the string size.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
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.
LLVM Value Representation.
static LLVM_ABI std::unique_ptr< WritableMemoryBuffer > getNewMemBuffer(size_t Size, const Twine &BufferName="")
Allocate a new zero-initialized MemoryBuffer of the specified size.
An efficient, type-erasing, non-owning reference to a callable.
Error checkSection(const SectionBase &S) const
Error finalize() override
std::vector< const SectionBase * > Sections
virtual Expected< size_t > getTotalSize(WritableMemoryBuffer &EmptyBuffer) const =0
StringTableSection * addStrTab()
SymbolTableSection * addSymTab(StringTableSection *StrTab)
std::unique_ptr< Object > Obj
Expected< std::unique_ptr< Object > > build()
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
Error visit(const SymbolTableSection &Sec) override
Error finalize() override
Error accept(SectionVisitor &Visitor) const override
CompressedSection(const SectionBase &Sec, DebugCompressionType CompressionType, bool Is64Bits)
Error accept(SectionVisitor &Visitor) const override
Error accept(SectionVisitor &) const override
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
ELFBuilder(const ELFObjectFile< ELFT > &ElfObj, Object &Obj, std::optional< StringRef > ExtractPartition)
Error build(bool EnsureSymtab)
static Expected< ELFFile > create(StringRef Object)
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
Error visit(Section &Sec) override
Error visit(const SymbolTableSection &Sec) override
Error finalize() override
ELFWriter(Object &Obj, raw_ostream &Out, bool WSH, bool OnlyKeepDebug)
Error accept(SectionVisitor &Visitor) const override
GnuDebugLinkSection(StringRef File, uint32_t PrecomputedCRC)
ConstRange< SectionBase > members() const
void setSymTab(const SymbolTableSection *SymTabSec)
void setSymbol(Symbol *S)
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
Error accept(SectionVisitor &) const override
void markSymbols() override
ArrayRef< uint8_t > Contents
void addMember(SectionBase *Sec)
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
void setFlagWord(ELF::Elf32_Word W)
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
Expected< std::unique_ptr< Object > > build()
Expected< std::unique_ptr< Object > > create(bool EnsureSymtab) const override
void writeSection(const SectionBase *Sec, ArrayRef< uint8_t > Data)
Error visit(const Section &Sec) final
virtual void writeData(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data)
void writeData(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data) override
Error visit(const StringTableSection &Sec) override
virtual Error visit(Section &Sec)=0
SectionTableRef sections() const
StringTableSection * SectionNames
Error updateSection(StringRef Name, ArrayRef< uint8_t > Data)
SectionIndexSection * SectionIndexTable
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove)
T & addSection(Ts &&...Args)
Error removeSections(bool AllowBrokenLinks, std::function< bool(const SectionBase &)> ToRemove)
SymbolTableSection * SymbolTable
Error addNewSymbolTable()
Error replaceSections(const DenseMap< SectionBase *, SectionBase * > &FromTo)
void appendHexData(StringRef HexData)
Error accept(SectionVisitor &Sec) const override
Error initialize(SectionTableRef SecTable) override
SymbolTableSection * Symbols
SectionBase * SecToApplyRel
StringRef getNamePrefix() const
void setSection(SectionBase *Sec)
void markSymbols() override
const Object & getObject() const
void addRelocation(const Relocation &Rel)
Error accept(SectionVisitor &Visitor) const override
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
std::vector< SRecord > Records
virtual void writeRecord(SRecord &Record, uint64_t Off)=0
void writeSection(const SectionBase &S, ArrayRef< uint8_t > Data)
Error visit(const Section &S) override
void writeRecords(uint32_t Entry)
Error visit(const StringTableSection &Sec) override
void writeRecord(SRecord &Record, uint64_t Off) override
virtual void markSymbols()
ArrayRef< uint8_t > OriginalData
virtual Error initialize(SectionTableRef SecTable)
virtual Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove)
virtual void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &)
virtual Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove)
virtual Error accept(SectionVisitor &Visitor) const =0
void setSymTab(SymbolTableSection *SymTab)
Error accept(SectionVisitor &Visitor) const override
Error initialize(SectionTableRef SecTable) override
Expected< T * > getSectionOfType(uint32_t Index, Twine IndexErrMsg, Twine TypeErrMsg)
Expected< SectionBase * > getSection(uint32_t Index, Twine ErrMsg)
virtual Error visit(const Section &Sec)=0
Error visit(const Section &Sec) override
WritableMemoryBuffer & Out
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
Error initialize(SectionTableRef SecTable) override
void restoreSymTabLink(SymbolTableSection &SymTab) override
Error accept(SectionVisitor &Visitor) const override
void addSection(const SectionBase *Sec)
void removeSection(const SectionBase *Sec)
const SectionBase * firstSection() const
ArrayRef< uint8_t > getContents() const
std::set< const SectionBase *, SectionCompare > Sections
void addString(StringRef Name)
uint32_t findIndex(StringRef Name) const
Error accept(SectionVisitor &Visitor) const override
Error removeSectionReferences(bool AllowBrokenLinks, function_ref< bool(const SectionBase *)> ToRemove) override
const SectionIndexSection * getShndxTable() const
std::vector< std::unique_ptr< Symbol > > Symbols
SectionIndexSection * SectionIndexTable
Error accept(SectionVisitor &Visitor) const override
void addSymbol(Twine Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn, uint64_t Value, uint8_t Visibility, uint16_t Shndx, uint64_t SymbolSize)
void updateSymbols(function_ref< void(Symbol &)> Callable)
Expected< const Symbol * > getSymbolByIndex(uint32_t Index) const
Error removeSymbols(function_ref< bool(const Symbol &)> ToRemove) override
Error initialize(SectionTableRef SecTable) override
void replaceSectionReferences(const DenseMap< SectionBase *, SectionBase * > &FromTo) override
std::unique_ptr< Symbol > SymPtr
StringTableSection * SymbolNames
std::unique_ptr< WritableMemoryBuffer > Buf
Writer(Object &O, raw_ostream &Out)
const Elf_Ehdr & getHeader() const
Expected< Elf_Phdr_Range > program_headers() const
Iterate over program header table.
size_t getBufSize() const
Expected< Elf_Shdr_Range > sections() const
const uint8_t * base() const
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an SmallVector or SmallString.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void encodeCrel(raw_ostream &OS, RelocsTy Relocs, F ToCrel)
LLVM_ABI const char * getReasonIfUnsupported(Format F)
LLVM_ABI Error decompress(DebugCompressionType T, ArrayRef< uint8_t > Input, uint8_t *Output, size_t UncompressedSize)
Format formatFor(DebugCompressionType Type)
LLVM_ABI void compress(Params P, ArrayRef< uint8_t > Input, SmallVectorImpl< uint8_t > &Output)
support::ulittle32_t Word
SmallVector< char, 64 > IHexLineData
SmallVector< char, 64 > SRecLineData
uint32_t read32(const void *P, endianness E)
void write32(void *P, uint32_t V, endianness E)
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void stable_sort(R &&Range)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
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.
unsigned hexDigitValue(char C)
Interpret the given character C as a hexadecimal digit and return its value.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
@ operation_not_permitted
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
void sort(IteratorTy Start, IteratorTy End)
char hexdigit(unsigned X, bool LowerCase=false)
hexdigit - Return the hexadecimal character for the given number X (which should be less than 16).
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...
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
bool isAlnum(char C)
Checks whether character C is either a decimal digit or an uppercase or lowercase letter as classifie...
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)
OutputIt copy(R &&Range, OutputIt Out)
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.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
Implement std::hash so that hash_code can be used in STL containers.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static IHexLineData getLine(uint8_t Type, uint16_t Addr, ArrayRef< uint8_t > Data)
static uint8_t getChecksum(StringRef S)
static Expected< IHexRecord > parse(StringRef Line)
static size_t getLength(size_t DataSize)
static size_t getLineLength(size_t DataSize)
uint8_t getAddressSize() const
static SRecord getHeader(StringRef FileName)
uint8_t getChecksum() const
SRecLineData toString() const
static uint8_t getType(uint32_t Address)
uint16_t getShndx() const
SymbolShndxType ShndxType