28 #include <unordered_set>
38 uint8_t *
B =
reinterpret_cast<uint8_t *
>(Buf->getBufferStart()) +
39 Obj.ProgramHdrSegment.Offset + Seg.
Index *
sizeof(Elf_Phdr);
40 Elf_Phdr &Phdr = *
reinterpret_cast<Elf_Phdr *
>(
B);
41 Phdr.p_type = Seg.
Type;
42 Phdr.p_flags = Seg.
Flags;
43 Phdr.p_offset = Seg.
Offset;
44 Phdr.p_vaddr = Seg.
VAddr;
45 Phdr.p_paddr = Seg.
PAddr;
48 Phdr.p_align = Seg.
Align;
51 Error SectionBase::removeSectionReferences(
63 void SectionBase::replaceSectionReferences(
65 void SectionBase::onRemove() {}
69 reinterpret_cast<uint8_t *
>(Buf->getBufferStart()) + Sec.
HeaderOffset;
70 Elf_Shdr &
Shdr = *
reinterpret_cast<Elf_Shdr *
>(
B);
100 template <
class ELFT>
105 Sec.
Align = ELFT::Is64Bits ?
sizeof(Elf_Xword) :
sizeof(Elf_Word);
109 template <
class ELFT>
114 Sec.
Align = ELFT::Is64Bits ?
sizeof(Elf_Xword) :
sizeof(Elf_Word);
118 template <
class ELFT>
124 Sec.
Size =
sizeof(Elf_Word) + Sec.GroupMembers.size() *
sizeof(Elf_Word);
128 template <
class ELFT>
137 template <
class ELFT>
144 "cannot write symbol section index table '" +
150 "cannot write symbol table '" + Sec.
Name +
156 "cannot write relocation section '" + Sec.
Name +
162 "cannot write '" + Sec.
Name +
"' out to binary");
167 "cannot write '" + Sec.
Name +
"' out to binary");
179 return Addr > UINT32_MAX &&
Addr + 0x80000000 > UINT32_MAX;
192 template <
class T,
class Iterator>
195 std::fill(It, It + Len,
'0');
197 for (
long I = Len - 1;
I >= 0; --
I) {
198 unsigned char Mod =
static_cast<unsigned char>(
X) & 15;
199 *(It +
I) = hexdigit(
Mod,
false);
208 uint8_t Checksum = 0;
210 Checksum += checkedGetHex<uint8_t>(
S.take_front(2));
220 auto Iter = Line.begin();
225 for (uint8_t
X :
Data)
227 StringRef S(Line.data() + 1, std::distance(Line.begin() + 1, Iter));
228 Iter =
toHexStr(getChecksum(
S), Iter, 2);
231 assert(Iter == Line.end());
238 if (R.HexData.size() == 0)
241 "zero data length is not allowed for data records");
243 case IHexRecord::EndOfFile:
245 case IHexRecord::SegmentAddr:
248 if (R.HexData.size() != 4)
251 "segment address data should be 2 bytes in size");
253 case IHexRecord::StartAddr80x86:
254 case IHexRecord::StartAddr:
255 if (R.HexData.size() != 8)
257 "start address data should be 4 bytes in size");
262 if (R.Type == IHexRecord::StartAddr80x86 &&
263 R.HexData.take_front(3) !=
"000")
265 "start address exceeds 20 bit for 80x86");
267 case IHexRecord::ExtendedAddr:
269 if (R.HexData.size() != 4)
272 "extended address data should be 2 bytes in size");
277 static_cast<unsigned>(R.Type));
289 "missing ':' in the beginning of line.");
291 for (
size_t Pos = 1; Pos < Line.
size(); ++Pos)
292 if (hexDigitValue(Line[Pos]) == -1U)
294 "invalid character at position %zu.", Pos + 1);
302 if (Line.
size() < 11)
304 "line is too short: %zu chars.", Line.
size());
310 size_t DataLen = checkedGetHex<uint8_t>(Line.
substr(1, 2));
311 if (Line.
size() != getLength(DataLen))
313 "invalid line length %zu (should be %zu)",
314 Line.
size(), getLength(DataLen));
316 Rec.
Addr = checkedGetHex<uint16_t>(Line.
substr(3, 4));
317 Rec.
Type = checkedGetHex<uint8_t>(Line.
substr(7, 2));
340 while (!
Data.empty()) {
341 uint64_t DataSize = std::min<uint64_t>(
Data.size(), ChunkSize);
342 if (
Addr > SegmentAddr + BaseAddr + 0xFFFFU) {
343 if (
Addr > 0xFFFFFU) {
346 if (SegmentAddr != 0)
347 SegmentAddr = writeSegmentAddr(0U);
348 BaseAddr = writeBaseAddr(
Addr);
351 SegmentAddr = writeSegmentAddr(
Addr);
355 assert(SegOffset <= 0xFFFFU);
356 DataSize =
std::min(DataSize, 0x10000U - SegOffset);
365 uint8_t
Data[] = {
static_cast<uint8_t
>((
Addr & 0xF0000U) >> 12), 0};
367 return Addr & 0xF0000U;
373 uint8_t
Data[] = {
static_cast<uint8_t
>(
Base >> 24),
374 static_cast<uint8_t
>((
Base >> 16) & 0xFF)};
381 Offset += IHexRecord::getLineLength(
Data.size());
385 writeSection(&Sec, Sec.Contents);
390 writeSection(&Sec, Sec.Data);
400 writeSection(&Sec, {
nullptr,
static_cast<size_t>(Sec.
Size)});
405 writeSection(&Sec, Sec.Contents);
412 memcpy(Out.getBufferStart() + Offset, HexData.data(), HexData.size());
413 Offset += HexData.size();
418 std::vector<uint8_t>
Data(Sec.
Size);
420 writeSection(&Sec,
Data);
425 return Visitor.
visit(*
this);
429 return Visitor.
visit(*
this);
437 static constexpr std::array<uint8_t, 4>
ZlibGnuMagic = {{
'Z',
'L',
'I',
'B'}};
444 template <
class ELFT>
445 static std::tuple<uint64_t, uint64_t>
457 return std::make_tuple(DecompressedSize, DecompressedAlign);
460 template <
class ELFT>
472 static_cast<size_t>(Sec.
Size)))
476 uint8_t *Buf =
reinterpret_cast<uint8_t *
>(Out.getBufferStart()) + Sec.
Offset;
477 std::copy(DecompressedContent.begin(), DecompressedContent.end(), Buf);
484 "cannot write compressed section '" + Sec.
Name +
489 return Visitor.
visit(*
this);
493 return Visitor.
visit(*
this);
497 return Visitor.
visit(*
this);
501 return Visitor.
visit(*
this);
504 void OwnedDataSection::appendHexData(
StringRef HexData) {
506 while (!HexData.
empty()) {
515 "cannot write compressed section '" + Sec.
Name +
519 template <
class ELFT>
521 uint8_t *Buf =
reinterpret_cast<uint8_t *
>(Out.getBufferStart()) + Sec.
Offset;
528 const char *
Magic =
"ZLIB";
530 Buf += strlen(
Magic);
533 memcpy(Buf, &DecompressedSize,
sizeof(DecompressedSize));
534 Buf +=
sizeof(DecompressedSize);
538 Chdr.ch_size = Sec.DecompressedSize;
539 Chdr.ch_addralign = Sec.DecompressedAlign;
540 memcpy(Buf, &Chdr,
sizeof(Chdr));
544 std::copy(Sec.CompressedData.begin(), Sec.CompressedData.end(), Buf);
550 :
SectionBase(Sec), CompressionType(CompressionType),
551 DecompressedSize(Sec.OriginalData.
size()), DecompressedAlign(Sec.
Align) {
559 ChdrSize =
sizeof(
"ZLIB") - 1 +
sizeof(
uint64_t);
568 Size = ChdrSize + CompressedData.size();
576 DecompressedSize(DecompressedSize), DecompressedAlign(DecompressedAlign) {
581 return Visitor.
visit(*
this);
585 return Visitor.
visit(*
this);
606 return Visitor.
visit(*
this);
610 return Visitor.
visit(*
this);
613 template <
class ELFT>
615 uint8_t *Buf =
reinterpret_cast<uint8_t *
>(Out.getBufferStart()) + Sec.
Offset;
616 llvm::copy(Sec.Indexes,
reinterpret_cast<Elf_Word *
>(Buf));
628 " is not a symbol table");
640 return Visitor.
visit(*
this);
644 return Visitor.
visit(*
this);
704 void SymbolTableSection::assignIndices() {
707 Sym->Index =
Index++;
719 if (DefinedIn !=
nullptr)
721 if (DefinedIn ==
nullptr) {
729 Sym.
Size = SymbolSize;
731 Symbols.emplace_back(std::make_unique<Symbol>(Sym));
740 if (!AllowBrokenLinks)
743 "string table '%s' cannot be removed because it is "
744 "referenced by the symbol table '%s'",
755 std::stable_partition(
774 for (std::unique_ptr<Symbol> &Sym :
Symbols)
784 "Symbol table has link index of " +
Twine(
Link) +
785 " which is not a valid index",
786 "Symbol table has link index of " +
Twine(
Link) +
787 " which is not a string table");
797 for (std::unique_ptr<Symbol> &Sym :
Symbols) {
801 MaxLocalIndex =
std::max(MaxLocalIndex, Sym->Index);
805 Info = MaxLocalIndex + 1;
820 for (std::unique_ptr<Symbol> &Sym :
Symbols)
829 for (
const std::unique_ptr<Symbol> &Sym :
Symbols) {
830 if (Sym->DefinedIn !=
nullptr && Sym->DefinedIn->Index >=
SHN_LORESERVE)
851 return const_cast<Symbol *
>(*Sym);
854 template <
class ELFT>
856 Elf_Sym *Sym =
reinterpret_cast<Elf_Sym *
>(Out.getBufferStart() + Sec.
Offset);
872 return Visitor.
visit(*
this);
876 return Visitor.
visit(*
this);
893 if (!AllowBrokenLinks)
896 "symbol table '%s' cannot be removed because it is "
897 "referenced by the relocation section '%s'",
903 if (!R.RelocSymbol || !R.RelocSymbol->DefinedIn ||
904 !
ToRemove(R.RelocSymbol->DefinedIn))
907 "section '%s' cannot be removed: (%s+0x%" PRIx64
908 ") has relocation against symbol '%s'",
909 R.RelocSymbol->DefinedIn->Name.data(),
911 R.RelocSymbol->Name.c_str());
917 template <
class SymTabType>
926 " is not a symbol table");
936 " in section " +
Name +
" is invalid");
947 template <
class SymTabType>
949 this->
Link = Symbols ? Symbols->Index : 0;
951 if (SecToApplyRel !=
nullptr)
952 this->
Info = SecToApplyRel->Index;
955 template <
class ELFT>
958 template <
class ELFT>
960 Rela.r_addend = Addend;
963 template <
class RelRange,
class T>
964 static void writeRel(
const RelRange &Relocations,
T *Buf,
bool IsMips64EL) {
965 for (
const auto &Reloc : Relocations) {
966 Buf->r_offset = Reloc.Offset;
968 Buf->setSymbolAndType(Reloc.RelocSymbol ? Reloc.RelocSymbol->Index : 0,
969 Reloc.Type, IsMips64EL);
974 template <
class ELFT>
976 uint8_t *Buf =
reinterpret_cast<uint8_t *
>(Out.getBufferStart()) + Sec.
Offset;
978 writeRel(Sec.Relocations,
reinterpret_cast<Elf_Rel *
>(Buf),
981 writeRel(Sec.Relocations,
reinterpret_cast<Elf_Rela *
>(Buf),
987 return Visitor.
visit(*
this);
991 return Visitor.
visit(*
this);
997 if (Reloc.RelocSymbol &&
ToRemove(*Reloc.RelocSymbol))
1000 "not stripping symbol '%s' because it is named in a relocation",
1001 Reloc.RelocSymbol->Name.data());
1007 if (Reloc.RelocSymbol)
1008 Reloc.RelocSymbol->Referenced =
true;
1024 return Visitor.
visit(*
this);
1028 return Visitor.
visit(*
this);
1034 if (!AllowBrokenLinks)
1037 "symbol table '%s' cannot be removed because it is "
1038 "referenced by the relocation section '%s'",
1052 bool AllowBrokenDependency,
1055 if (!AllowBrokenDependency)
1057 "section '%s' cannot be removed because it is "
1058 "referenced by the section '%s'",
1059 LinkSection->
Name.data(),
this->Name.data());
1060 LinkSection =
nullptr;
1067 this->
Link = SymTab ? SymTab->
Index : 0;
1079 if (!AllowBrokenLinks)
1082 "section '.symtab' cannot be removed because it is "
1083 "referenced by the group section '%s'",
1095 "symbol '%s' cannot be removed because it is "
1096 "referenced by the section '%s[%d]'",
1126 " in section " +
Name +
" is invalid");
1133 LinkSection =
nullptr;
1140 void GnuDebugLinkSection::init(
StringRef File) {
1150 Name =
".gnu_debuglink";
1159 : FileName(File), CRC32(PrecomputedCRC) {
1163 template <
class ELFT>
1165 unsigned char *Buf =
1166 reinterpret_cast<uint8_t *
>(Out.getBufferStart()) + Sec.
Offset;
1168 reinterpret_cast<Elf_Word *
>(Buf + Sec.
Size -
sizeof(Elf_Word));
1175 return Visitor.
visit(*
this);
1179 return Visitor.
visit(*
this);
1182 template <
class ELFT>
1186 support::endian::write32<ELFT::TargetEndianness>(Buf++, Sec.FlagWord);
1188 support::endian::write32<ELFT::TargetEndianness>(Buf++,
S->Index);
1193 return Visitor.
visit(*
this);
1197 return Visitor.
visit(*
this);
1218 if (SectionIsTLS != SegmentIsTLS)
1241 if (A->OriginalOffset <
B->OriginalOffset)
1243 if (A->OriginalOffset >
B->OriginalOffset)
1245 return A->Index <
B->Index;
1252 Obj->ABIVersion = 0;
1262 StrTab.
Name =
".strtab";
1264 Obj->SectionNames = &StrTab;
1271 SymTab.
Name =
".symtab";
1272 SymTab.Link = StrTab->
Index;
1275 SymTab.addSymbol(
"", 0, 0,
nullptr, 0, 0, 0, 0);
1277 Obj->SymbolTable = &SymTab;
1294 DataSection.
Name =
".data";
1296 DataSection.Size =
Data.size();
1302 [](
char C) {
return !isAlnum(
C); },
'_');
1306 0, NewSymbolVisibility, 0, 0);
1308 DataSection.Size, NewSymbolVisibility, 0, 0);
1310 DataSection.Size, NewSymbolVisibility,
SHN_ABS,
1328 void IHexELFBuilder::addDataSections() {
1330 uint64_t SegmentAddr = 0, BaseAddr = 0;
1338 if (R.HexData.empty())
1340 RecAddr = R.Addr + SegmentAddr + BaseAddr;
1351 Section->appendHexData(R.HexData);
1357 SegmentAddr = checkedGetHex<uint16_t>(R.HexData) << 4;
1361 Obj->Entry = checkedGetHex<uint32_t>(R.HexData);
1366 BaseAddr = checkedGetHex<uint16_t>(R.HexData) << 16;
1386 template <
class ELFT>
1389 : ElfFile(ElfObj.getELFFile()), Obj(Obj),
1390 ExtractPartition(ExtractPartition) {
1395 for (
Segment &Parent : Obj.segments()) {
1411 if (!ExtractPartition)
1421 "could not find partition named '" +
1422 *ExtractPartition +
"'");
1425 template <
class ELFT>
1435 if (Phdr.p_offset + Phdr.p_filesz > HeadersFile.
getBufSize())
1440 " goes past the end of the file");
1443 (size_t)Phdr.p_filesz};
1444 Segment &Seg = Obj.addSegment(Data);
1445 Seg.
Type = Phdr.p_type;
1446 Seg.
Flags = Phdr.p_flags;
1448 Seg.
Offset = Phdr.p_offset + EhdrOffset;
1449 Seg.
VAddr = Phdr.p_vaddr;
1450 Seg.
PAddr = Phdr.p_paddr;
1453 Seg.
Align = Phdr.p_align;
1463 auto &ElfHdr = Obj.ElfHdrSegment;
1465 ElfHdr.OriginalOffset = ElfHdr.Offset = EhdrOffset;
1467 const typename ELFT::Ehdr &Ehdr = HeadersFile.
getHeader();
1468 auto &PrHdr = Obj.ProgramHdrSegment;
1475 PrHdr.OriginalOffset = PrHdr.Offset = PrHdr.VAddr = EhdrOffset + Ehdr.e_phoff;
1477 PrHdr.FileSize = PrHdr.MemSize = Ehdr.e_phentsize * Ehdr.e_phnum;
1479 PrHdr.Align =
sizeof(Elf_Addr);
1480 PrHdr.Index =
Index++;
1484 for (
Segment &Child : Obj.segments())
1485 setParentSegment(Child);
1486 setParentSegment(ElfHdr);
1487 setParentSegment(PrHdr);
1492 template <
class ELFT>
1496 "invalid alignment " +
Twine(GroupSec->
Align) +
1497 " of group section '" + GroupSec->
Name +
"'");
1500 auto SymTab = SecTable.template getSectionOfType<SymbolTableSection>(
1502 "link field value '" +
Twine(GroupSec->
Link) +
"' in section '" +
1503 GroupSec->
Name +
"' is invalid",
1504 "link field value '" +
Twine(GroupSec->
Link) +
"' in section '" +
1505 GroupSec->
Name +
"' is not a symbol table");
1507 return SymTab.takeError();
1512 "info field value '" +
Twine(GroupSec->
Info) +
1513 "' in section '" + GroupSec->
Name +
1514 "' is not a valid symbol index");
1521 "the content of the section " + GroupSec->
Name +
1528 support::endian::read32<ELFT::TargetEndianness>(
Word++));
1533 GroupSec->
Name +
"' is invalid");
1543 template <
class ELFT>
1547 return Shdr.takeError();
1556 ElfFile.symbols(*
Shdr);
1558 return Symbols.takeError();
1565 return Name.takeError();
1570 "symbol '" + *
Name +
1571 "' has index SHN_XINDEX but no "
1572 "SHT_SYMTAB_SHNDX section exists");
1573 if (ShndxData.
data() ==
nullptr) {
1580 ElfFile.template getSectionContentsAsArray<Elf_Word>(**ShndxSec);
1582 return Data.takeError();
1585 if (ShndxData.
size() != Symbols->size())
1588 "symbol section index table does not have the same number of "
1589 "entries as the symbol table");
1591 Elf_Word
Index = ShndxData[&Sym - Symbols->begin()];
1594 "symbol '" + *
Name +
"' has invalid section index " +
Twine(
Index));
1603 "symbol '" + *
Name +
1604 "' has unsupported value greater than or equal "
1605 "to SHN_LORESERVE: " +
1606 Twine(Sym.st_shndx));
1610 Sym.st_shndx,
"symbol '" + *
Name +
1611 "' is defined has invalid section index " +
1612 Twine(Sym.st_shndx));
1619 SymTab->
addSymbol(*
Name, Sym.getBinding(), Sym.getType(), DefSection,
1620 Sym.getValue(), Sym.st_other, Sym.st_shndx, Sym.st_size);
1626 template <
class ELFT>
1629 template <
class ELFT>
1631 ToSet = Rela.r_addend;
1636 for (
const auto &Rel : RelRange) {
1638 ToAdd.
Offset = Rel.r_offset;
1646 "'" + Relocs->
Name +
"': relocation references symbol with index " +
1647 Twine(Sym) +
", but there is no symbol table");
1666 return Sections[
Index - 1].get();
1677 if (
T *Sec = dyn_cast<T>(*BaseSec))
1683 template <
class ELFT>
1685 switch (
Shdr.sh_type) {
1692 return Data.takeError();
1701 return Obj.addSection<
Section>(*Data);
1703 return Data.takeError();
1711 return Obj.addSection<
Section>(*Data);
1713 return Data.takeError();
1718 return Data.takeError();
1723 return Data.takeError();
1728 return Data.takeError();
1731 Obj.SymbolTable = &SymTab;
1736 Obj.SectionIndexTable = &ShndxSection;
1737 return ShndxSection;
1744 return Data.takeError();
1748 return Name.takeError();
1751 uint64_t DecompressedSize, DecompressedAlign;
1752 std::tie(DecompressedSize, DecompressedAlign) =
1753 getDecompressedSizeAndAlignment<ELFT>(*Data);
1758 return Obj.addSection<
Section>(*Data);
1782 Sec->Name = SecName->str();
1783 Sec->Type = Sec->OriginalType =
Shdr.sh_type;
1784 Sec->Flags = Sec->OriginalFlags =
Shdr.sh_flags;
1785 Sec->Addr =
Shdr.sh_addr;
1786 Sec->Offset =
Shdr.sh_offset;
1787 Sec->OriginalOffset =
Shdr.sh_offset;
1788 Sec->Size =
Shdr.sh_size;
1789 Sec->Link =
Shdr.sh_link;
1790 Sec->Info =
Shdr.sh_info;
1791 Sec->Align =
Shdr.sh_addralign;
1792 Sec->EntrySize =
Shdr.sh_entsize;
1793 Sec->Index =
Index++;
1794 Sec->OriginalIndex = Sec->Index;
1796 ElfFile.base() +
Shdr.sh_offset,
1804 uint32_t ShstrIndex = ElfFile.getHeader().e_shstrndx;
1810 ShstrIndex = (*Sec)->sh_link;
1814 Obj.HadShdrs =
false;
1817 Obj.sections().template getSectionOfType<StringTableSection>(
1819 "e_shstrndx field value " +
Twine(ShstrIndex) +
" in elf header " +
1821 "e_shstrndx field value " +
Twine(ShstrIndex) +
" in elf header " +
1822 " does not reference a string table");
1826 Obj.SectionNames = *Sec;
1832 if (Obj.SectionIndexTable)
1833 if (
Error Err = Obj.SectionIndexTable->initialize(Obj.sections()))
1839 if (Obj.SymbolTable) {
1840 if (
Error Err = Obj.SymbolTable->initialize(Obj.sections()))
1842 if (
Error Err = initSymbolTable(Obj.SymbolTable))
1844 }
else if (EnsureSymtab) {
1845 if (
Error Err = Obj.addNewSymbolTable())
1853 if (&Sec == Obj.SymbolTable)
1855 if (
Error Err = Sec.initialize(Obj.sections()))
1857 if (
auto RelSec = dyn_cast<RelocationSection>(&Sec)) {
1864 Sections->begin() + RelSec->Index;
1865 if (RelSec->Type ==
SHT_REL) {
1867 ElfFile.rels(*
Shdr);
1875 ElfFile.relas(*
Shdr);
1882 }
else if (
auto GroupSec = dyn_cast<GroupSection>(&Sec)) {
1883 if (
Error Err = initGroupSection(GroupSec))
1892 if (
Error E = readSectionHeaders())
1894 if (
Error E = findEhdrOffset())
1901 {ElfFile.base() + EhdrOffset, ElfFile.getBufSize() - EhdrOffset}));
1906 Obj.OSABI = Ehdr.e_ident[
EI_OSABI];
1908 Obj.Type = Ehdr.e_type;
1909 Obj.Machine = Ehdr.e_machine;
1910 Obj.Version = Ehdr.e_version;
1911 Obj.Entry = Ehdr.e_entry;
1912 Obj.Flags = Ehdr.e_flags;
1914 if (
Error E = readSections(EnsureSymtab))
1916 return readProgramHeaders(*HeadersFile);
1930 std::vector<IHexRecord> Records;
1931 bool HasSections =
false;
1934 Records.reserve(Lines.size());
1935 for (
size_t LineNo = 1; LineNo <= Lines.size(); ++LineNo) {
1936 StringRef Line = Lines[LineNo - 1].trim();
1942 return parseError(LineNo, R.takeError());
1946 Records.push_back(*R);
1949 return parseError(-1U,
"no sections");
1964 auto Obj = std::make_unique<Object>();
1990 Elf_Ehdr &Ehdr = *
reinterpret_cast<Elf_Ehdr *
>(Buf->getBufferStart());
1991 std::fill(Ehdr.e_ident, Ehdr.e_ident + 16, 0);
2000 Ehdr.e_ident[
EI_OSABI] = Obj.OSABI;
2003 Ehdr.e_type = Obj.Type;
2004 Ehdr.e_machine = Obj.Machine;
2005 Ehdr.e_version = Obj.Version;
2006 Ehdr.e_entry = Obj.Entry;
2010 Ehdr.e_phoff = (Ehdr.e_phnum != 0) ? Obj.ProgramHdrSegment.Offset : 0;
2011 Ehdr.e_phentsize = (Ehdr.e_phnum != 0) ?
sizeof(Elf_Phdr) : 0;
2012 Ehdr.e_flags = Obj.Flags;
2013 Ehdr.e_ehsize =
sizeof(Elf_Ehdr);
2014 if (WriteSectionHeaders && Obj.sections().size() != 0) {
2015 Ehdr.e_shentsize =
sizeof(Elf_Shdr);
2016 Ehdr.e_shoff = Obj.SHOff;
2023 auto Shnum = Obj.sections().size() + 1;
2027 Ehdr.e_shnum = Shnum;
2037 Ehdr.e_shstrndx = Obj.SectionNames->Index;
2039 Ehdr.e_shentsize = 0;
2042 Ehdr.e_shstrndx = 0;
2047 for (
auto &Seg : Obj.segments())
2055 *
reinterpret_cast<Elf_Shdr *
>(Buf->getBufferStart() + Obj.SHOff);
2062 uint64_t Shnum = Obj.sections().size() + 1;
2064 Shdr.sh_size = Shnum;
2068 if (Obj.SectionNames !=
nullptr && Obj.SectionNames->Index >=
SHN_LORESERVE)
2069 Shdr.sh_link = Obj.SectionNames->Index;
2073 Shdr.sh_addralign = 0;
2074 Shdr.sh_entsize = 0;
2085 if (Sec.ParentSegment ==
nullptr)
2086 if (
Error Err = Sec.accept(*SecWriter))
2093 for (
Segment &Seg : Obj.segments()) {
2099 for (
auto it : Obj.getUpdatedSections()) {
2104 assert(Parent &&
"This section should've been part of a segment.");
2107 llvm::copy(Data, Buf->getBufferStart() + Offset);
2111 for (
auto &Sec : Obj.removedSections()) {
2112 Segment *Parent = Sec.ParentSegment;
2113 if (Parent ==
nullptr || Sec.Type ==
SHT_NOBITS || Sec.Size == 0)
2117 std::memset(Buf->getBufferStart() + Offset, 0, Sec.Size);
2121 template <
class ELFT>
2124 :
Writer(Obj, Buf), WriteSectionHeaders(WSH && Obj.HadShdrs),
2125 OnlyKeepDebug(OnlyKeepDebug) {}
2129 [&](
const SecPtr &Sec) {
return Sec->Name ==
Name; });
2130 if (It == Sections.end())
2132 Name.str().c_str());
2134 auto *OldSec = It->get();
2135 if (!OldSec->hasContents())
2138 "section '%s' cannot be updated because it does not have contents",
2139 Name.str().c_str());
2141 if (
Data.size() > OldSec->Size && OldSec->ParentSegment)
2143 "cannot fit data of size %zu into section '%s' "
2144 "with size %zu that is part of a segment",
2145 Data.size(),
Name.str().c_str(), OldSec->Size);
2147 if (!OldSec->ParentSegment) {
2148 *It = std::make_unique<OwnedDataSection>(*OldSec,
Data);
2151 OldSec->Size =
Data.size();
2152 UpdatedSections[OldSec] =
Data;
2161 auto Iter = std::stable_partition(
2165 if (
auto RelSec = dyn_cast<RelocationSectionBase>(Sec.get())) {
2166 if (auto ToRelSec = RelSec->getSection())
2167 return !ToRemove(*ToRelSec);
2180 std::unordered_set<const SectionBase *> RemoveSections;
2183 for (
auto &
Segment : Segments)
2185 RemoveSec->onRemove();
2186 RemoveSections.insert(RemoveSec.get());
2195 if (
Error E = KeepSec->removeSectionReferences(
2196 AllowBrokenLinks, [&RemoveSections](
const SectionBase *Sec) {
2197 return RemoveSections.find(Sec) != RemoveSections.end();
2204 std::move(Iter, Sections.end(), std::back_inserter(RemovedSections));
2206 Sections.erase(Iter,
std::end(Sections));
2212 auto SectionIndexLess = [](
const SecPtr &Lhs,
const SecPtr &Rhs) {
2213 return Lhs->Index < Rhs->Index;
2216 "Sections are expected to be sorted by Index");
2219 for (
auto &
I : FromTo)
2220 I.second->Index =
I.first->Index;
2223 for (
auto &Sec : Sections)
2224 Sec->replaceSectionReferences(FromTo);
2228 [=](
const SectionBase &Sec) {
return FromTo.count(&Sec) > 0; }))
2236 for (
const SecPtr &Sec : Sections)
2258 StrTab = &addSection<StringTableSection>();
2261 SymTab.
Name =
".symtab";
2265 SymTab.
addSymbol(
"", 0, 0,
nullptr, 0, 0, 0, 0);
2288 for (
Segment *Seg : Segments) {
2312 template <
class Range>
2322 std::vector<SectionBase *> OutOfSegmentSections;
2324 for (
auto &Sec : Sections) {
2325 Sec.Index =
Index++;
2326 if (Sec.ParentSegment !=
nullptr) {
2327 auto Segment = *Sec.ParentSegment;
2331 OutOfSegmentSections.push_back(&Sec);
2338 for (
auto *Sec : OutOfSegmentSections) {
2339 Offset =
alignTo(Offset, Sec->Align == 0 ? 1 : Sec->Align);
2340 Sec->Offset = Offset;
2342 Offset += Sec->Size;
2352 std::vector<SectionBase *> Sections;
2356 Sec.Index =
Index++;
2357 Sections.push_back(&Sec);
2364 for (
auto *Sec : Sections) {
2365 auto *FirstSec = Sec->ParentSegment && Sec->ParentSegment->Type ==
PT_LOAD
2366 ? Sec->ParentSegment->firstSection()
2371 if (FirstSec && FirstSec == Sec)
2372 Off =
alignTo(Off, Sec->ParentSegment->Align, Sec->Addr);
2385 Off = Sec->Align ?
alignTo(Off, Sec->Align) : Off;
2386 }
else if (FirstSec != Sec) {
2389 Off = Sec->OriginalOffset - FirstSec->OriginalOffset + FirstSec->Offset;
2402 for (
Segment *Seg : Segments) {
2414 FirstSec ? FirstSec->
Offset
2419 if (Sec->
Offset + Size > Offset)
2425 if (Seg->
Offset < HdrEnd && HdrEnd <= Seg->Offset + Seg->
FileSize) {
2426 FileSize += Offset - Seg->
Offset;
2428 FileSize =
std::max(FileSize, HdrEnd - Offset);
2433 MaxOffset =
std::max(MaxOffset, Offset + FileSize);
2439 Segment &ElfHdr = Obj.ElfHdrSegment;
2452 std::vector<Segment *> OrderedSegments;
2454 OrderedSegments.push_back(&
Segment);
2455 OrderedSegments.push_back(&Obj.ElfHdrSegment);
2456 OrderedSegments.push_back(&Obj.ProgramHdrSegment);
2460 if (OnlyKeepDebug) {
2465 sizeof(Elf_Ehdr) +
llvm::size(Obj.segments()) *
sizeof(Elf_Phdr);
2478 if (WriteSectionHeaders)
2486 if (!WriteSectionHeaders)
2488 size_t ShdrCount = Obj.sections().size() + 1;
2489 return Obj.SHOff + ShdrCount *
sizeof(Elf_Shdr);
2498 if (
Error E = writeSectionData())
2500 if (WriteSectionHeaders)
2505 Out.write(Buf->getBufferStart(), Buf->getBufferSize());
2532 if (Obj.SectionNames ==
nullptr && WriteSectionHeaders)
2534 "cannot write section header table because "
2535 "section header string table was removed");
2543 bool NeedsLargeIndexes =
false;
2555 if (NeedsLargeIndexes) {
2558 if (Obj.SymbolTable !=
nullptr && Obj.SectionIndexTable ==
nullptr) {
2562 Obj.SymbolTable->setShndxTable(&Shndx);
2568 if (Obj.SectionIndexTable !=
nullptr) {
2570 if (
Error E = Obj.removeSections(
false ,
2572 return &Sec == Obj.SectionIndexTable;
2580 if (Obj.SectionNames !=
nullptr)
2582 Obj.SectionNames->addString(Sec.Name);
2590 auto SecSizer = std::make_unique<ELFSectionSizer<ELFT>>();
2592 Sec.Index =
Index++;
2593 if (
Error Err = Sec.accept(*SecSizer))
2600 if (Obj.SymbolTable !=
nullptr)
2601 Obj.SymbolTable->prepareForLayout();
2606 if (
auto StrTab = dyn_cast<StringTableSection>(&Sec))
2607 StrTab->prepareForLayout();
2613 if (Obj.SymbolTable !=
nullptr)
2614 Obj.SymbolTable->fillShndxTable();
2618 uint64_t Offset = Obj.SHOff +
sizeof(Elf_Shdr);
2620 Sec.HeaderOffset = Offset;
2621 Offset +=
sizeof(Elf_Shdr);
2622 if (WriteSectionHeaders)
2623 Sec.NameIndex = Obj.SectionNames->findIndex(Sec.Name);
2627 size_t TotalSize = totalSize();
2631 "failed to allocate memory buffer of " +
2634 SecWriter = std::make_unique<ELFSectionWriter<ELFT>>(*Buf);
2640 if (
Error Err = Sec.accept(*SecWriter))
2656 if (Sec.ParentSegment !=
nullptr)
2658 Sec.Offset - Sec.ParentSegment->Offset + Sec.ParentSegment->PAddr;
2660 MinAddr =
std::min(MinAddr, Sec.Addr);
2669 if (Sec.Type !=
SHT_NOBITS && Sec.Size > 0) {
2670 Sec.Offset = Sec.Addr - MinAddr;
2671 TotalSize =
std::max(TotalSize, Sec.Offset + Sec.Size);
2677 "failed to allocate memory buffer of " +
2679 SecWriter = std::make_unique<BinarySectionWriter>(*
Buf);
2683 bool IHexWriter::SectionCompare::operator()(
const SectionBase *Lhs,
2689 uint64_t IHexWriter::writeEntryPointRecord(uint8_t *Buf) {
2691 uint8_t
Data[4] = {};
2706 memcpy(
Buf, HexData.data(), HexData.size());
2707 return HexData.size();
2710 uint64_t IHexWriter::writeEndOfFileRecord(uint8_t *Buf) {
2712 memcpy(
Buf, HexData.data(), HexData.size());
2713 return HexData.size();
2725 Offset += writeEntryPointRecord(
2726 reinterpret_cast<uint8_t *
>(
Buf->getBufferStart()) + Offset);
2728 Offset += writeEndOfFileRecord(
2729 reinterpret_cast<uint8_t *
>(
Buf->getBufferStart()) + Offset);
2730 assert(Offset == TotalSize);
2743 "Section '%s' address range [0x%llx, 0x%llx] is not 32 bit",
2752 "Entry point address 0x%llx overflows 32 bits",
2758 if (
Error E = checkSection(Sec))
2760 Sections.insert(&Sec);
2763 std::unique_ptr<WritableMemoryBuffer> EmptyBuffer =
2767 "failed to allocate memory buffer of 0 bytes");
2783 "failed to allocate memory buffer of " +