26#include <unordered_set>
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()) {
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);
383 return Addr & 0xF0000U;
387 assert(Addr <= 0xFFFFFFFFU);
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));
553 std::copy(Sec.CompressedData.
begin(), Sec.CompressedData.
end(), Buf);
560 :
SectionBase(Sec), CompressionType(CompressionType),
569 Size = ChdrSize + CompressedData.size();
577 DecompressedSize(DecompressedSize), DecompressedAlign(DecompressedAlign) {
582 return Visitor.
visit(*
this);
586 return Visitor.
visit(*
this);
592 return StrTabBuilder.getOffset(
Name);
596 StrTabBuilder.finalize();
597 Size = StrTabBuilder.getSize();
601 Sec.StrTabBuilder.
write(
reinterpret_cast<uint8_t *
>(
Out.getBufferStart()) +
607 return Visitor.
visit(*
this);
611 return Visitor.
visit(*
this);
617 llvm::copy(Sec.Indexes,
reinterpret_cast<Elf_Word *
>(Buf));
629 " is not a symbol table");
634 Symbols->setShndxTable(
this);
641 return Visitor.
visit(*
this);
645 return Visitor.
visit(*
this);
705void SymbolTableSection::assignIndices() {
708 if (Sym->Index != Index)
710 Sym->Index = Index++;
723 if (DefinedIn !=
nullptr)
725 if (DefinedIn ==
nullptr) {
733 Sym.
Size = SymbolSize;
735 Symbols.emplace_back(std::make_unique<Symbol>(Sym));
744 if (!AllowBrokenLinks)
747 "string table '%s' cannot be removed because it is "
748 "referenced by the symbol table '%s'",
759 std::stable_partition(
771 auto PrevSize =
Size;
781 for (std::unique_ptr<Symbol> &Sym :
Symbols)
791 "Symbol table has link index of " +
Twine(
Link) +
792 " which is not a valid index",
793 "Symbol table has link index of " +
Twine(
Link) +
794 " which is not a string table");
804 for (std::unique_ptr<Symbol> &Sym :
Symbols) {
808 MaxLocalIndex = std::max(MaxLocalIndex, Sym->Index);
812 Info = MaxLocalIndex + 1;
827 for (std::unique_ptr<Symbol> &Sym :
Symbols)
836 for (
const std::unique_ptr<Symbol> &Sym :
Symbols) {
837 if (Sym->DefinedIn !=
nullptr && Sym->DefinedIn->Index >=
SHN_LORESERVE)
858 return const_cast<Symbol *
>(*Sym);
863 Elf_Sym *Sym =
reinterpret_cast<Elf_Sym *
>(
Out.getBufferStart() + Sec.
Offset);
879 return Visitor.
visit(*
this);
883 return Visitor.
visit(*
this);
902 if (!AllowBrokenLinks)
905 "symbol table '%s' cannot be removed because it is "
906 "referenced by the relocation section '%s'",
907 Symbols->Name.data(), this->Name.data());
912 if (!R.RelocSymbol || !R.RelocSymbol->DefinedIn ||
913 !
ToRemove(R.RelocSymbol->DefinedIn))
916 "section '%s' cannot be removed: (%s+0x%" PRIx64
917 ") has relocation against symbol '%s'",
918 R.RelocSymbol->DefinedIn->Name.data(),
920 R.RelocSymbol->Name.c_str());
926template <
class SymTabType>
935 " is not a symbol table");
945 " in section " +
Name +
" is invalid");
956template <
class SymTabType>
969 Rela.r_addend = Addend;
972template <
class RelRange,
class T>
973static void writeRel(
const RelRange &Relocations,
T *Buf,
bool IsMips64EL) {
974 for (
const auto &
Reloc : Relocations) {
975 Buf->r_offset =
Reloc.Offset;
977 Buf->setSymbolAndType(
Reloc.RelocSymbol ?
Reloc.RelocSymbol->Index : 0,
978 Reloc.Type, IsMips64EL);
988 memcpy(Buf, Content.data(), Content.size());
990 writeRel(Sec.Relocations,
reinterpret_cast<Elf_Rel *
>(Buf),
993 writeRel(Sec.Relocations,
reinterpret_cast<Elf_Rela *
>(Buf),
1000 return Visitor.
visit(*
this);
1004 return Visitor.
visit(*
this);
1013 "not stripping symbol '%s' because it is named in a relocation",
1014 Reloc.RelocSymbol->Name.data());
1020 if (
Reloc.RelocSymbol)
1021 Reloc.RelocSymbol->Referenced =
true;
1037 return Visitor.
visit(*
this);
1041 return Visitor.
visit(*
this);
1047 if (!AllowBrokenLinks)
1050 "symbol table '%s' cannot be removed because it is "
1051 "referenced by the relocation section '%s'",
1052 Symbols->Name.data(), this->Name.data());
1065 bool AllowBrokenDependency,
1068 if (!AllowBrokenDependency)
1070 "section '%s' cannot be removed because it is "
1071 "referenced by the section '%s'",
1072 LinkSection->Name.data(), this->Name.data());
1073 LinkSection =
nullptr;
1079 this->
Info = Sym ? Sym->Index : 0;
1080 this->
Link = SymTab ? SymTab->Index : 0;
1092 if (!AllowBrokenLinks)
1095 "section '.symtab' cannot be removed because it is "
1096 "referenced by the group section '%s'",
1108 "symbol '%s' cannot be removed because it is "
1109 "referenced by the section '%s[%d]'",
1110 Sym->Name.data(), this->Name.data(), this->Index);
1116 Sym->Referenced =
true;
1139 " in section " +
Name +
" is invalid");
1146 HasSymTabLink =
true;
1147 LinkSection =
nullptr;
1165 Name =
".gnu_debuglink";
1174 : FileName(
File), CRC32(PrecomputedCRC) {
1178template <
class ELFT>
1180 unsigned char *Buf =
1183 reinterpret_cast<Elf_Word *
>(Buf + Sec.
Size -
sizeof(Elf_Word));
1190 return Visitor.
visit(*
this);
1194 return Visitor.
visit(*
this);
1197template <
class ELFT>
1208 return Visitor.
visit(*
this);
1212 return Visitor.
visit(*
this);
1233 if (SectionIsTLS != SegmentIsTLS)
1256 if (
A->OriginalOffset <
B->OriginalOffset)
1258 if (
A->OriginalOffset >
B->OriginalOffset)
1264 if (
A->Align !=
B->Align)
1265 return A->Align >
B->Align;
1266 return A->Index <
B->Index;
1273 Obj->ABIVersion = 0;
1283 StrTab.
Name =
".strtab";
1285 Obj->SectionNames = &StrTab;
1292 SymTab.
Name =
".symtab";
1293 SymTab.Link = StrTab->
Index;
1296 SymTab.addSymbol(
"", 0, 0,
nullptr, 0, 0, 0, 0);
1298 Obj->SymbolTable = &SymTab;
1318 DataSection.
Name =
".data";
1320 DataSection.Size =
Data.size();
1325 std::begin(SanitizedFilename), std::end(SanitizedFilename),
1326 [](
char C) {
return !
isAlnum(
C); },
'_');
1327 Twine Prefix =
Twine(
"_binary_") + SanitizedFilename;
1330 0, NewSymbolVisibility, 0, 0);
1332 DataSection.Size, NewSymbolVisibility, 0, 0);
1334 DataSection.Size, NewSymbolVisibility,
SHN_ABS,
1344 return std::move(Err);
1347 return std::move(
Obj);
1352void IHexELFBuilder::addDataSections() {
1354 uint64_t SegmentAddr = 0, BaseAddr = 0;
1362 if (R.HexData.empty())
1364 RecAddr = R.Addr + SegmentAddr + BaseAddr;
1371 ".sec" + std::to_string(SecNo), RecAddr,
1375 Section->appendHexData(R.HexData);
1404 return std::move(Err);
1407 return std::move(
Obj);
1410template <
class ELFT>
1412 std::optional<StringRef> ExtractPartition)
1413 : ElfFile(ElfObj.getELFFile()), Obj(Obj),
1414 ExtractPartition(ExtractPartition) {
1415 Obj.IsMips64EL = ElfFile.isMips64EL();
1418template <
class ELFT>
void ELFBuilder<ELFT>::setParentSegment(
Segment &Child) {
1419 for (
Segment &Parent : Obj.segments()) {
1434template <
class ELFT>
Error ELFBuilder<ELFT>::findEhdrOffset() {
1435 if (!ExtractPartition)
1445 "could not find partition named '" +
1446 *ExtractPartition +
"'");
1449template <
class ELFT>
1453 Expected<typename ELFFile<ELFT>::Elf_Phdr_Range> Headers =
1459 if (Phdr.p_offset + Phdr.p_filesz > HeadersFile.
getBufSize())
1464 " goes past the end of the file");
1466 ArrayRef<uint8_t>
Data{HeadersFile.
base() + Phdr.p_offset,
1467 (size_t)Phdr.p_filesz};
1469 Seg.
Type = Phdr.p_type;
1470 Seg.
Flags = Phdr.p_flags;
1472 Seg.
Offset = Phdr.p_offset + EhdrOffset;
1473 Seg.
VAddr = Phdr.p_vaddr;
1474 Seg.
PAddr = Phdr.p_paddr;
1477 Seg.
Align = Phdr.p_align;
1487 auto &ElfHdr = Obj.ElfHdrSegment;
1488 ElfHdr.Index =
Index++;
1489 ElfHdr.OriginalOffset = ElfHdr.Offset = EhdrOffset;
1491 const typename ELFT::Ehdr &Ehdr = HeadersFile.
getHeader();
1492 auto &PrHdr = Obj.ProgramHdrSegment;
1499 PrHdr.OriginalOffset = PrHdr.Offset = PrHdr.VAddr = EhdrOffset + Ehdr.e_phoff;
1501 PrHdr.FileSize = PrHdr.MemSize = Ehdr.e_phentsize * Ehdr.e_phnum;
1503 PrHdr.Align =
sizeof(Elf_Addr);
1504 PrHdr.Index =
Index++;
1508 for (
Segment &Child : Obj.segments())
1509 setParentSegment(Child);
1510 setParentSegment(ElfHdr);
1511 setParentSegment(PrHdr);
1516template <
class ELFT>
1520 "invalid alignment " + Twine(GroupSec->
Align) +
1521 " of group section '" + GroupSec->
Name +
"'");
1524 auto SymTab = SecTable.template getSectionOfType<SymbolTableSection>(
1526 "link field value '" + Twine(GroupSec->
Link) +
"' in section '" +
1527 GroupSec->
Name +
"' is invalid",
1528 "link field value '" + Twine(GroupSec->
Link) +
"' in section '" +
1529 GroupSec->
Name +
"' is not a symbol table");
1531 return SymTab.takeError();
1536 "info field value '" + Twine(GroupSec->
Info) +
1537 "' in section '" + GroupSec->
Name +
1538 "' is not a valid symbol index");
1545 "the content of the section " + GroupSec->
Name +
1554 Expected<SectionBase *> Sec = SecTable.
getSection(
1555 Index,
"group member index " + Twine(Index) +
" in section '" +
1556 GroupSec->
Name +
"' is invalid");
1566template <
class ELFT>
1568 Expected<const Elf_Shdr *> Shdr = ElfFile.getSection(SymTab->
Index);
1572 Expected<StringRef> StrTabData = ElfFile.getStringTableForSymtab(**Shdr);
1578 Expected<typename ELFFile<ELFT>::Elf_Sym_Range>
Symbols =
1579 ElfFile.symbols(*Shdr);
1586 Expected<StringRef>
Name = Sym.getName(*StrTabData);
1588 return Name.takeError();
1593 "symbol '" + *Name +
1594 "' has index SHN_XINDEX but no "
1595 "SHT_SYMTAB_SHNDX section exists");
1596 if (ShndxData.
data() ==
nullptr) {
1597 Expected<const Elf_Shdr *> ShndxSec =
1602 Expected<ArrayRef<Elf_Word>>
Data =
1603 ElfFile.template getSectionContentsAsArray<Elf_Word>(**ShndxSec);
1605 return Data.takeError();
1611 "symbol section index table does not have the same number of "
1612 "entries as the symbol table");
1615 Expected<SectionBase *> Sec = Obj.sections().getSection(
1617 "symbol '" + *Name +
"' has invalid section index " + Twine(Index));
1626 "symbol '" + *Name +
1627 "' has unsupported value greater than or equal "
1628 "to SHN_LORESERVE: " +
1629 Twine(Sym.st_shndx));
1632 Expected<SectionBase *> Sec = Obj.sections().getSection(
1633 Sym.st_shndx,
"symbol '" + *Name +
1634 "' is defined has invalid section index " +
1635 Twine(Sym.st_shndx));
1642 SymTab->
addSymbol(*Name, Sym.getBinding(), Sym.getType(), DefSection,
1643 Sym.getValue(), Sym.st_other, Sym.st_shndx, Sym.st_size);
1649template <
class ELFT>
1652template <
class ELFT>
1654 ToSet = Rela.r_addend;
1659 for (
const auto &Rel : RelRange) {
1661 ToAdd.
Offset = Rel.r_offset;
1669 "'" + Relocs->
Name +
"': relocation references symbol with index " +
1670 Twine(Sym) +
", but there is no symbol table");
1687 if (Index ==
SHN_UNDEF || Index > Sections.size())
1689 return Sections[Index - 1].get();
1706template <
class ELFT>
1708 switch (Shdr.sh_type) {
1716 return Data.takeError();
1725 return Obj.addSection<
Section>(*Data);
1727 return Data.takeError();
1735 return Obj.addSection<
Section>(*Data);
1737 return Data.takeError();
1742 return Data.takeError();
1747 return Data.takeError();
1752 return Data.takeError();
1755 if (Obj.SymbolTable !=
nullptr)
1757 "found multiple SHT_SYMTAB sections");
1759 Obj.SymbolTable = &SymTab;
1764 Obj.SectionIndexTable = &ShndxSection;
1765 return ShndxSection;
1768 return Obj.addSection<
Section>(ArrayRef<uint8_t>());
1770 Expected<ArrayRef<uint8_t>>
Data = ElfFile.getSectionContents(Shdr);
1772 return Data.takeError();
1774 Expected<StringRef>
Name = ElfFile.getSectionName(Shdr);
1776 return Name.takeError();
1779 return Obj.addSection<
Section>(*Data);
1780 auto *Chdr =
reinterpret_cast<const Elf_Chdr_Impl<ELFT> *
>(
Data->data());
1782 *
Data, Chdr->ch_type, Chdr->ch_size, Chdr->ch_addralign));
1787template <
class ELFT>
Error ELFBuilder<ELFT>::readSectionHeaders() {
1789 Expected<typename ELFFile<ELFT>::Elf_Shdr_Range> Sections =
1799 Expected<SectionBase &> Sec = makeSection(Shdr);
1803 Expected<StringRef> SecName = ElfFile.getSectionName(Shdr);
1806 Sec->Name = SecName->str();
1807 Sec->Type = Sec->OriginalType = Shdr.sh_type;
1808 Sec->Flags = Sec->OriginalFlags = Shdr.sh_flags;
1809 Sec->Addr = Shdr.sh_addr;
1810 Sec->Offset = Shdr.sh_offset;
1811 Sec->OriginalOffset = Shdr.sh_offset;
1812 Sec->Size = Shdr.sh_size;
1813 Sec->Link = Shdr.sh_link;
1814 Sec->Info = Shdr.sh_info;
1815 Sec->Align = Shdr.sh_addralign;
1816 Sec->EntrySize = Shdr.sh_entsize;
1817 Sec->Index =
Index++;
1818 Sec->OriginalIndex = Sec->Index;
1819 Sec->OriginalData = ArrayRef<uint8_t>(
1820 ElfFile.base() + Shdr.sh_offset,
1821 (Shdr.sh_type ==
SHT_NOBITS) ? (
size_t)0 : Shdr.sh_size);
1827template <
class ELFT>
Error ELFBuilder<ELFT>::readSections(
bool EnsureSymtab) {
1828 uint32_t ShstrIndex = ElfFile.getHeader().e_shstrndx;
1830 Expected<const Elf_Shdr *> Sec = ElfFile.getSection(0);
1834 ShstrIndex = (*Sec)->sh_link;
1838 Obj.HadShdrs =
false;
1840 Expected<StringTableSection *> Sec =
1841 Obj.sections().template getSectionOfType<StringTableSection>(
1843 "e_shstrndx field value " + Twine(ShstrIndex) +
" in elf header " +
1845 "e_shstrndx field value " + Twine(ShstrIndex) +
" in elf header " +
1846 " does not reference a string table");
1850 Obj.SectionNames = *Sec;
1856 if (Obj.SectionIndexTable)
1857 if (
Error Err = Obj.SectionIndexTable->initialize(Obj.sections()))
1863 if (Obj.SymbolTable) {
1864 if (
Error Err = Obj.SymbolTable->initialize(Obj.sections()))
1866 if (
Error Err = initSymbolTable(Obj.SymbolTable))
1868 }
else if (EnsureSymtab) {
1869 if (
Error Err = Obj.addNewSymbolTable())
1877 if (&Sec == Obj.SymbolTable)
1879 if (
Error Err = Sec.initialize(Obj.sections()))
1882 Expected<typename ELFFile<ELFT>::Elf_Shdr_Range> Sections =
1888 Sections->begin() + RelSec->Index;
1890 auto RelsOrRelas = ElfFile.crels(*Shdr);
1892 return RelsOrRelas.takeError();
1897 }
else if (RelSec->Type ==
SHT_REL) {
1898 Expected<typename ELFFile<ELFT>::Elf_Rel_Range> Rels =
1899 ElfFile.rels(*Shdr);
1906 Expected<typename ELFFile<ELFT>::Elf_Rela_Range> Relas =
1907 ElfFile.relas(*Shdr);
1915 if (
Error Err = initGroupSection(GroupSec))
1924 if (
Error E = readSectionHeaders())
1926 if (
Error E = findEhdrOffset())
1933 {ElfFile.base() + EhdrOffset, ElfFile.getBufSize() - EhdrOffset}));
1939 Obj.OSABI = Ehdr.e_ident[
EI_OSABI];
1941 Obj.Type = Ehdr.e_type;
1942 Obj.Machine = Ehdr.e_machine;
1943 Obj.Version = Ehdr.e_version;
1944 Obj.Entry = Ehdr.e_entry;
1945 Obj.Flags = Ehdr.e_flags;
1947 if (
Error E = readSections(EnsureSymtab))
1949 return readProgramHeaders(*HeadersFile);
1963 std::vector<IHexRecord> Records;
1964 bool HasSections =
false;
1967 Records.
reserve(Lines.size());
1968 for (
size_t LineNo = 1; LineNo <= Lines.size(); ++LineNo) {
1969 StringRef Line = Lines[LineNo - 1].trim();
1975 return parseError(LineNo, R.takeError());
1982 return parseError(-1U,
"no sections");
1984 return std::move(Records);
1991 return Records.takeError();
1997 auto Obj = std::make_unique<Object>();
2000 if (
Error Err = Builder.build(EnsureSymtab))
2001 return std::move(Err);
2002 return std::move(Obj);
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);
2022template <
class ELFT>
void ELFWriter<ELFT>::writeEhdr() {
2023 Elf_Ehdr &Ehdr = *
reinterpret_cast<Elf_Ehdr *
>(Buf->getBufferStart());
2024 std::fill(Ehdr.e_ident, Ehdr.e_ident + 16, 0);
2033 Ehdr.e_ident[
EI_OSABI] = Obj.OSABI;
2036 Ehdr.e_type = Obj.Type;
2037 Ehdr.e_machine = Obj.Machine;
2038 Ehdr.e_version = Obj.Version;
2039 Ehdr.e_entry = Obj.Entry;
2043 Ehdr.e_phoff = (Ehdr.e_phnum != 0) ? Obj.ProgramHdrSegment.Offset : 0;
2044 Ehdr.e_phentsize = (Ehdr.e_phnum != 0) ?
sizeof(Elf_Phdr) : 0;
2045 Ehdr.e_flags = Obj.Flags;
2046 Ehdr.e_ehsize =
sizeof(Elf_Ehdr);
2047 if (WriteSectionHeaders && Obj.sections().size() != 0) {
2048 Ehdr.e_shentsize =
sizeof(Elf_Shdr);
2049 Ehdr.e_shoff = Obj.SHOff;
2056 auto Shnum = Obj.sections().size() + 1;
2060 Ehdr.e_shnum = Shnum;
2070 Ehdr.e_shstrndx = Obj.SectionNames->Index;
2072 Ehdr.e_shentsize = 0;
2075 Ehdr.e_shstrndx = 0;
2079template <
class ELFT>
void ELFWriter<ELFT>::writePhdrs() {
2080 for (
auto &Seg : Obj.segments())
2084template <
class ELFT>
void ELFWriter<ELFT>::writeShdrs() {
2088 *
reinterpret_cast<Elf_Shdr *
>(Buf->getBufferStart() + Obj.SHOff);
2095 uint64_t Shnum = Obj.
sections().size() + 1;
2097 Shdr.sh_size = Shnum;
2101 if (Obj.SectionNames !=
nullptr && Obj.SectionNames->Index >=
SHN_LORESERVE)
2102 Shdr.sh_link = Obj.SectionNames->Index;
2106 Shdr.sh_addralign = 0;
2107 Shdr.sh_entsize = 0;
2113template <
class ELFT>
Error ELFWriter<ELFT>::writeSectionData() {
2118 if (Sec.ParentSegment ==
nullptr)
2119 if (
Error Err = Sec.accept(*SecWriter))
2125template <
class ELFT>
void ELFWriter<ELFT>::writeSegmentData() {
2126 for (
Segment &Seg : Obj.segments()) {
2132 for (
const auto &it : Obj.getUpdatedSections()) {
2134 ArrayRef<uint8_t>
Data = it.second;
2137 assert(Parent &&
"This section should've been part of a segment.");
2144 for (
auto &Sec : Obj.removedSections()) {
2145 Segment *Parent = Sec.ParentSegment;
2146 if (Parent ==
nullptr || Sec.Type ==
SHT_NOBITS || Sec.Size == 0)
2150 std::memset(Buf->getBufferStart() +
Offset, 0, Sec.Size);
2154template <
class ELFT>
2161 if (!Sec->hasContents())
2164 "section '%s' cannot be updated because it does not have contents",
2167 if (
Data.size() > Sec->Size && Sec->ParentSegment)
2169 "cannot fit data of size %zu into section '%s' "
2170 "with size %" PRIu64
" that is part of a segment",
2171 Data.size(), Sec->Name.c_str(), Sec->Size);
2173 if (!Sec->ParentSegment) {
2174 Sec = std::make_unique<OwnedDataSection>(*Sec,
Data);
2177 Sec->Size =
Data.size();
2178 UpdatedSections[Sec.get()] =
Data;
2186 [&](
const SecPtr &Sec) {
return Sec->Name == Name; });
2187 if (It == Sections.end())
2189 Name.str().c_str());
2190 return updateSectionData(*It,
Data);
2195 [&](
const SecPtr &Sec) {
return Sec.get() == &S; });
2196 assert(It != Sections.end() &&
"The section should belong to the object");
2197 return updateSectionData(*It,
Data);
2203 auto Iter = std::stable_partition(
2204 std::begin(Sections), std::end(Sections), [=](
const SecPtr &Sec) {
2212 if (
auto ToRelSec = RelSec->getSection())
2231 std::unordered_set<const SectionBase *> RemoveSections;
2232 RemoveSections.reserve(std::distance(Iter, std::end(Sections)));
2233 for (
auto &RemoveSec :
make_range(Iter, std::end(Sections))) {
2234 for (
auto &
Segment : Segments)
2236 RemoveSec->onRemove();
2237 RemoveSections.insert(RemoveSec.get());
2245 for (
auto &KeepSec :
make_range(std::begin(Sections), Iter)) {
2246 if (
Error E = KeepSec->removeSectionReferences(
2247 AllowBrokenLinks, [&RemoveSections](
const SectionBase *Sec) {
2248 return RemoveSections.find(Sec) != RemoveSections.end();
2255 std::move(Iter, Sections.end(), std::back_inserter(RemovedSections));
2257 Sections.erase(Iter, std::end(Sections));
2263 auto SectionIndexLess = [](
const SecPtr &Lhs,
const SecPtr &Rhs) {
2264 return Lhs->Index < Rhs->Index;
2267 "Sections are expected to be sorted by Index");
2270 for (
auto &
I : FromTo)
2271 I.second->Index =
I.first->Index;
2274 for (
auto &Sec : Sections)
2275 Sec->replaceSectionReferences(FromTo);
2287 for (
const SecPtr &Sec : Sections)
2312 SymTab.
Name =
".symtab";
2316 SymTab.
addSymbol(
"", 0, 0,
nullptr, 0, 0, 0, 0);
2339 for (
Segment *Seg : Segments) {
2363template <
class Range>
2373 std::vector<SectionBase *> OutOfSegmentSections;
2375 for (
auto &Sec : Sections) {
2376 Sec.Index = Index++;
2377 if (Sec.ParentSegment !=
nullptr) {
2382 OutOfSegmentSections.push_back(&Sec);
2389 for (
auto *Sec : OutOfSegmentSections) {
2403 std::vector<SectionBase *> Sections;
2407 Sec.Index = Index++;
2408 Sections.push_back(&Sec);
2415 for (
auto *Sec : Sections) {
2416 auto *FirstSec = Sec->ParentSegment && Sec->ParentSegment->Type ==
PT_LOAD
2417 ? Sec->ParentSegment->firstSection()
2422 if (FirstSec && FirstSec == Sec)
2423 Off =
alignTo(Off, Sec->ParentSegment->Align, Sec->Addr);
2436 Off = Sec->Align ?
alignTo(Off, Sec->Align) : Off;
2437 }
else if (FirstSec != Sec) {
2440 Off = Sec->OriginalOffset - FirstSec->OriginalOffset + FirstSec->Offset;
2453 for (
Segment *Seg : Segments) {
2465 FirstSec ? FirstSec->
Offset
2479 FileSize = std::max(FileSize, HdrEnd -
Offset);
2484 MaxOffset = std::max(MaxOffset,
Offset + FileSize);
2489template <
class ELFT>
void ELFWriter<ELFT>::initEhdrSegment() {
2490 Segment &ElfHdr = Obj.ElfHdrSegment;
2499template <
class ELFT>
void ELFWriter<ELFT>::assignOffsets() {
2503 std::vector<Segment *> OrderedSegments;
2505 OrderedSegments.push_back(&
Segment);
2506 OrderedSegments.push_back(&Obj.ElfHdrSegment);
2507 OrderedSegments.push_back(&Obj.ProgramHdrSegment);
2511 if (OnlyKeepDebug) {
2516 sizeof(Elf_Ehdr) +
llvm::size(Obj.segments()) *
sizeof(Elf_Phdr);
2529 if (WriteSectionHeaders)
2534template <
class ELFT>
size_t ELFWriter<ELFT>::totalSize()
const {
2537 if (!WriteSectionHeaders)
2539 size_t ShdrCount = Obj.sections().size() + 1;
2540 return Obj.SHOff + ShdrCount *
sizeof(Elf_Shdr);
2549 if (
Error E = writeSectionData())
2556 Out.write(
Buf->getBufferStart(),
Buf->getBufferSize());
2585 "cannot write section header table because "
2586 "section header string table was removed");
2593 if (
Obj.SymbolTable && !
Obj.SymbolTable->indicesChanged())
2595 Sec.restoreSymTabLink(*
Obj.SymbolTable);
2600 bool NeedsLargeIndexes =
false;
2612 if (NeedsLargeIndexes) {
2615 if (
Obj.SymbolTable !=
nullptr &&
Obj.SectionIndexTable ==
nullptr) {
2619 Obj.SymbolTable->setShndxTable(&Shndx);
2620 Shndx.setSymTab(
Obj.SymbolTable);
2625 if (
Obj.SectionIndexTable !=
nullptr) {
2627 if (
Error E =
Obj.removeSections(
false ,
2629 return &Sec == Obj.SectionIndexTable;
2637 if (
Obj.SectionNames !=
nullptr)
2639 Obj.SectionNames->addString(Sec.Name);
2647 auto SecSizer = std::make_unique<ELFSectionSizer<ELFT>>();
2649 Sec.Index = Index++;
2650 if (
Error Err = Sec.accept(*SecSizer))
2657 if (
Obj.SymbolTable !=
nullptr)
2658 Obj.SymbolTable->prepareForLayout();
2664 StrTab->prepareForLayout();
2670 if (
Obj.SymbolTable !=
nullptr)
2671 Obj.SymbolTable->fillShndxTable();
2677 Sec.HeaderOffset =
Offset;
2678 Offset +=
sizeof(Elf_Shdr);
2680 Sec.NameIndex =
Obj.SectionNames->findIndex(Sec.Name);
2684 size_t TotalSize = totalSize();
2688 "failed to allocate memory buffer of " +
2691 SecWriter = std::make_unique<ELFSectionWriter<ELFT>>(*Buf);
2702 if (SectionsToWrite.
empty())
2707 return LHS->Offset < RHS->Offset;
2712 for (
size_t i = 0; i != SectionsToWrite.
size(); ++i) {
2719 ? SectionsToWrite[i + 1]->Offset
2720 :
Buf->getBufferSize();
2721 assert(PadOffset <= Buf->getBufferSize());
2724 Buf->getBufferStart() + PadOffset, GapFill);
2729 Out.write(
Buf->getBufferStart(),
Buf->getBufferSize());
2740 if (Sec.ParentSegment !=
nullptr)
2742 Sec.Offset - Sec.ParentSegment->Offset + Sec.ParentSegment->PAddr;
2744 MinAddr = std::min(MinAddr, Sec.Addr);
2751 TotalSize = PadTo > MinAddr ? PadTo - MinAddr : 0;
2753 if (Sec.Type !=
SHT_NOBITS && Sec.Size > 0) {
2754 Sec.Offset = Sec.Addr - MinAddr;
2755 TotalSize = std::max(TotalSize, Sec.Offset + Sec.Size);
2761 "failed to allocate memory buffer of " +
2763 SecWriter = std::make_unique<BinarySectionWriter>(*
Buf);
2772 "section '%s' address range [0x%llx, 0x%llx] is not 32 bit",
2781 "entry point address 0x%llx overflows 32 bits",
2796 std::unique_ptr<WritableMemoryBuffer> EmptyBuffer =
2800 "failed to allocate memory buffer of 0 bytes");
2810 "failed to allocate memory buffer of 0x" +
2833 return HexData.
size();
2836uint64_t IHexWriter::writeEndOfFileRecord(uint8_t *Buf) {
2839 return HexData.
size();
2843IHexWriter::getTotalSize(WritableMemoryBuffer &EmptyBuffer)
const {
2844 IHexSectionWriterBase LengthCalc(EmptyBuffer);
2845 for (
const SectionBase *Sec :
Sections)
2846 if (
Error Err = Sec->accept(LengthCalc))
2847 return std::move(Err);
2851 return LengthCalc.getBufferOffset() +
2853 IHexRecord::getLineLength(0);
2865 Offset += writeEntryPointRecord(
2868 Offset += writeEndOfFileRecord(
2874 Out.write(
Buf->getBufferStart(),
Buf->getBufferSize());
2881 "Expected section size to have been finalized");
2904 memcpy(
Out.getBufferStart() + Off,
Data.data(),
Data.size());
2926 while (!
Data.empty()) {
2937 "Section size does not match the section's string table builder size");
2938 std::vector<uint8_t>
Data(Sec.
Size);
2946 auto *Iter = Line.begin();
2948 *Iter++ =
'0' +
Type;
2960 assert(Iter == Line.end());
2966 Sum += (
Address >> 24) & 0xFF;
2967 Sum += (
Address >> 16) & 0xFF;
2972 return 0xFF - (Sum & 0xFF);
3015 reinterpret_cast<const uint8_t *
>(HeaderContents.
data()),
3016 HeaderContents.
size());
3020size_t SRECWriter::writeHeader(
uint8_t *Buf) {
3028 "Invalid record type for terminator");
3036SRECWriter::getTotalSize(WritableMemoryBuffer &EmptyBuffer)
const {
3037 SRECSizeCalculator SizeCalc(EmptyBuffer, 0);
3038 for (
const SectionBase *Sec :
Sections)
3039 if (
Error Err = Sec->accept(SizeCalc))
3040 return std::move(Err);
3042 SizeCalc.writeRecords(
Obj.Entry);
3045 uint8_t TerminatorType = 10 - SizeCalc.getType();
3046 SRecord
Terminator = {TerminatorType,
static_cast<uint32_t
>(
Obj.Entry), {}};
3047 return Header.getSize() + SizeCalc.getBufferOffset() +
Terminator.getSize();
3052 writeHeader(
reinterpret_cast<uint8_t *
>(
Buf->getBufferStart()));
3063 Offset += writeTerminator(
3067 Out.write(
Buf->getBufferStart(),
Buf->getBufferSize());
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
ReachingDefAnalysis InstSet & ToRemove
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
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - 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.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
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 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.
StringRef - 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
str - 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
empty - 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
size - Get the string size.
constexpr const char * data() const
data - 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(const 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
bool isRelocatable() const
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
const SectionBase * getStrTab() const
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.
@ C
The default llvm calling convention, compatible with C.
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.
FunctionAddr VTableAddr uintptr_t uintptr_t DataSize
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).
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...
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...
FunctionAddr VTableAddr uintptr_t uintptr_t Data
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
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