LLVM: lib/ObjCopy/ELF/ELFObject.cpp Source File (original) (raw)
905 "symbol table '%s' cannot be removed because it is "
906 "referenced by the relocation section '%s'",
907 Symbols->Name.data(), this->Name.data());
909 }
910
911 for (const Relocation &R : Relocations) {
912 if (!R.RelocSymbol || !R.RelocSymbol->DefinedIn ||
913 (R.RelocSymbol->DefinedIn))
914 continue;
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());
921 }
922
924}
925
926template
932 "Link field value " + Twine(Link) + " in section " + Name +
933 " is invalid",
934 "Link field value " + Twine(Link) + " in section " + Name +
935 " is not a symbol table");
936 if (!Sec)
938
939 setSymTab(*Sec);
940 }
941
945 " in section " + Name + " is invalid");
946 if (!Sec)
948
950 } else
952
954}
955
956template
963
964template
966
967template
969 Rela.r_addend = Addend;
970}
971
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);
979 ++Buf;
980 }
981}
982
983template
988 memcpy(Buf, Content.data(), Content.size());
990 writeRel(Sec.Relocations, reinterpret_cast<Elf_Rel *>(Buf),
992 } else {
993 writeRel(Sec.Relocations, reinterpret_cast<Elf_Rela *>(Buf),
995 }
997}
998
1000 return Visitor.visit(*this);
1001}
1002
1004 return Visitor.visit(*this);
1005}
1006
1013 "not stripping symbol '%s' because it is named in a relocation",
1014 Reloc.RelocSymbol->Name.data());
1016}
1017
1020 if (Reloc.RelocSymbol)
1021 Reloc.RelocSymbol->Referenced = true;
1022}
1023
1030
1035
1037 return Visitor.visit(*this);
1038}
1039
1041 return Visitor.visit(*this);
1042}
1043
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());
1054 }
1055
1056
1057
1058
1059
1062}
1063
1065 bool AllowBrokenDependency,
1067 if (ToRemove(LinkSection)) {
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;
1074 }
1076}
1077
1079 this->Info = Sym ? Sym->Index : 0;
1080 this->Link = SymTab ? SymTab->Index : 0;
1081
1082
1083
1084
1087}
1088
1092 if (!AllowBrokenLinks)
1095 "section '.symtab' cannot be removed because it is "
1096 "referenced by the group section '%s'",
1097 this->Name.data());
1098 SymTab = nullptr;
1099 Sym = nullptr;
1100 }
1103}
1104
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);
1112}
1113
1115 if (Sym)
1116 Sym->Referenced = true;
1117}
1118
1125
1132
1136
1139 " in section " + Name + " is invalid");
1140 if (!Sec)
1142
1143 LinkSection = *Sec;
1144
1146 HasSymTabLink = true;
1147 LinkSection = nullptr;
1148 }
1149
1151}
1152
1154
1157
1158
1159
1160
1162
1165 Name = ".gnu_debuglink";
1166
1167
1168
1169 OriginalOffset = std::numeric_limits<uint64_t>::max();
1170}
1171
1174 : FileName(File), CRC32(PrecomputedCRC) {
1176}
1177
1178template
1180 unsigned char *Buf =
1181 reinterpret_cast<uint8_t *>(Out.getBufferStart()) + Sec.Offset;
1182 Elf_Word *CRC =
1183 reinterpret_cast<Elf_Word *>(Buf + Sec.Size - sizeof(Elf_Word));
1184 *CRC = Sec.CRC32;
1187}
1188
1190 return Visitor.visit(*this);
1191}
1192
1194 return Visitor.visit(*this);
1195}
1196
1197template
1206
1208 return Visitor.visit(*this);
1209}
1210
1212 return Visitor.visit(*this);
1213}
1214
1215
1217
1218
1219
1220
1222
1223
1224 if (Sec.OriginalOffset == std::numeric_limits<uint64_t>::max())
1225 return false;
1226
1229 return false;
1230
1232 bool SegmentIsTLS = Seg.Type == PT_TLS;
1233 if (SectionIsTLS != SegmentIsTLS)
1234 return false;
1235
1238 }
1239
1242}
1243
1244
1245
1247 const Segment &Parent) {
1248
1251}
1252
1254
1255
1256 if (A->OriginalOffset < B->OriginalOffset)
1257 return true;
1258 if (A->OriginalOffset > B->OriginalOffset)
1259 return false;
1260
1261
1262
1263
1264 if (A->Align != B->Align)
1265 return A->Align > B->Align;
1266 return A->Index < B->Index;
1267}
1268
1270 Obj->Flags = 0x0;
1273 Obj->ABIVersion = 0;
1274 Obj->Entry = 0x0;
1276 Obj->Version = 1;
1277}
1278
1280
1283 StrTab.Name = ".strtab";
1284
1285 Obj->SectionNames = &StrTab;
1286 return &StrTab;
1287}
1288
1291
1292 SymTab.Name = ".symtab";
1293 SymTab.Link = StrTab->Index;
1294
1295
1296 SymTab.addSymbol("", 0, 0, nullptr, 0, 0, 0, 0);
1297
1298 Obj->SymbolTable = &SymTab;
1299 return &SymTab;
1300}
1301
1305 return Err;
1306
1308}
1309
1312
1318 DataSection.Name = ".data";
1320 DataSection.Size = Data.size();
1322
1324 std::replace_if(
1325 std::begin(SanitizedFilename), std::end(SanitizedFilename),
1326 [](char C) { return (C); }, '_');
1327 Twine Prefix = Twine("_binary_") + SanitizedFilename;
1328
1330 0, NewSymbolVisibility, 0, 0);
1332 DataSection.Size, NewSymbolVisibility, 0, 0);
1334 DataSection.Size, NewSymbolVisibility, SHN_ABS,
1335 0);
1336}
1337
1341
1344 return std::move(Err);
1345 addData(SymTab);
1346
1347 return std::move(Obj);
1348}
1349
1350
1351
1352void IHexELFBuilder::addDataSections() {
1354 uint64_t SegmentAddr = 0, BaseAddr = 0;
1356
1357 for (const IHexRecord &R : Records) {
1359 switch (R.Type) {
1361
1362 if (R.HexData.empty())
1363 continue;
1364 RecAddr = R.Addr + SegmentAddr + BaseAddr;
1366
1367
1368
1369
1371 ".sec" + std::to_string(SecNo), RecAddr,
1373 SecNo++;
1374 }
1375 Section->appendHexData(R.HexData);
1376 break;
1378 break;
1380
1382 break;
1387 break;
1389
1391 break;
1392 default:
1394 }
1395 }
1396}
1397
1404 return std::move(Err);
1405 addDataSections();
1406
1407 return std::move(Obj);
1408}
1409
1410template
1412 std::optional ExtractPartition)
1413 : ElfFile(ElfObj.getELFFile()), Obj(Obj),
1414 ExtractPartition(ExtractPartition) {
1415 Obj.IsMips64EL = ElfFile.isMips64EL();
1416}
1417
1418template void ELFBuilder::setParentSegment(Segment &Child) {
1419 for (Segment &Parent : Obj.segments()) {
1420
1421
1423
1424
1429 }
1430 }
1431 }
1432}
1433
1434template Error ELFBuilder::findEhdrOffset() {
1435 if (!ExtractPartition)
1437
1440 EhdrOffset = Sec.Offset;
1442 }
1443 }
1445 "could not find partition named '" +
1446 *ExtractPartition + "'");
1447}
1448
1449template
1450Error ELFBuilder::readProgramHeaders(const ELFFile &HeadersFile) {
1451 uint32_t Index = 0;
1452
1453 Expected<typename ELFFile::Elf_Phdr_Range> Headers =
1455 if (!Headers)
1457
1459 if (Phdr.p_offset + Phdr.p_filesz > HeadersFile.getBufSize())
1462 "program header with offset 0x" + Twine::utohexstr(Phdr.p_offset) +
1464 " goes past the end of the file");
1465
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;
1475 Seg.FileSize = Phdr.p_filesz;
1476 Seg.MemSize = Phdr.p_memsz;
1477 Seg.Align = Phdr.p_align;
1484 }
1485 }
1486
1487 auto &ElfHdr = Obj.ElfHdrSegment;
1488 ElfHdr.Index = Index++;
1489 ElfHdr.OriginalOffset = ElfHdr.Offset = EhdrOffset;
1490
1491 const typename ELFT::Ehdr &Ehdr = HeadersFile.getHeader();
1492 auto &PrHdr = Obj.ProgramHdrSegment;
1494 PrHdr.Flags = 0;
1495
1496
1497
1498
1499 PrHdr.OriginalOffset = PrHdr.Offset = PrHdr.VAddr = EhdrOffset + Ehdr.e_phoff;
1500 PrHdr.PAddr = 0;
1501 PrHdr.FileSize = PrHdr.MemSize = Ehdr.e_phentsize * Ehdr.e_phnum;
1502
1503 PrHdr.Align = sizeof(Elf_Addr);
1504 PrHdr.Index = Index++;
1505
1506
1507
1508 for (Segment &Child : Obj.segments())
1509 setParentSegment(Child);
1510 setParentSegment(ElfHdr);
1511 setParentSegment(PrHdr);
1512
1514}
1515
1516template
1517Error ELFBuilder::initGroupSection(GroupSection *GroupSec) {
1520 "invalid alignment " + Twine(GroupSec->Align) +
1521 " of group section '" + GroupSec->Name + "'");
1524 auto SymTab = SecTable.template getSectionOfType(
1525 GroupSec->Link,
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");
1530 if (!SymTab)
1531 return SymTab.takeError();
1532
1534 if (!Sym)
1536 "info field value '" + Twine(GroupSec->Info) +
1537 "' in section '" + GroupSec->Name +
1538 "' is not a valid symbol index");
1541 }
1545 "the content of the section " + GroupSec->Name +
1546 " is malformed");
1552 for (; Word != End; ++Word) {
1554 Expected<SectionBase *> Sec = SecTable.getSection(
1555 Index, "group member index " + Twine(Index) + " in section '" +
1556 GroupSec->Name + "' is invalid");
1557 if (!Sec)
1559
1561 }
1562
1564}
1565
1566template
1568 Expected<const Elf_Shdr *> Shdr = ElfFile.getSection(SymTab->Index);
1569 if (!Shdr)
1571
1572 Expected StrTabData = ElfFile.getStringTableForSymtab(**Shdr);
1573 if (!StrTabData)
1575
1577
1578 Expected<typename ELFFile::Elf_Sym_Range> Symbols =
1579 ElfFile.symbols(*Shdr);
1580 if (!Symbols)
1581 return Symbols.takeError();
1582
1585
1586 Expected Name = Sym.getName(*StrTabData);
1587 if (!Name)
1588 return Name.takeError();
1589
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 =
1599 if (!ShndxSec)
1601
1602 Expected<ArrayRef<Elf_Word>> Data =
1603 ElfFile.template getSectionContentsAsArray<Elf_Word>(**ShndxSec);
1605 return Data.takeError();
1606
1607 ShndxData = *Data;
1608 if (ShndxData.size() != Symbols->size())
1611 "symbol section index table does not have the same number of "
1612 "entries as the symbol table");
1613 }
1614 Elf_Word Index = ShndxData[&Sym - Symbols->begin()];
1615 Expected<SectionBase *> Sec = Obj.sections().getSection(
1616 Index,
1617 "symbol '" + *Name + "' has invalid section index " + Twine(Index));
1618 if (!Sec)
1620
1621 DefSection = *Sec;
1626 "symbol '" + *Name +
1627 "' has unsupported value greater than or equal "
1628 "to SHN_LORESERVE: " +
1629 Twine(Sym.st_shndx));
1630 }
1631 } else if (Sym.st_shndx != SHN_UNDEF) {
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));
1636 if (!Sec)
1638
1639 DefSection = *Sec;
1640 }
1641
1642 SymTab->addSymbol(*Name, Sym.getBinding(), Sym.getType(), DefSection,
1643 Sym.getValue(), Sym.st_other, Sym.st_shndx, Sym.st_size);
1644 }
1645
1647}
1648
1649template
1651
1652template
1654 ToSet = Rela.r_addend;
1655}
1656
1657template
1659 for (const auto &Rel : RelRange) {
1661 ToAdd.Offset = Rel.r_offset;
1664
1669 "'" + Relocs->Name + "': relocation references symbol with index " +
1670 Twine(Sym) + ", but there is no symbol table");
1673 if (!SymByIndex)
1675
1677 }
1678
1680 }
1681
1683}
1684
1687 if (Index == SHN_UNDEF || Index > Sections.size())
1689 return Sections[Index - 1].get();
1690}
1691
1692template
1694 Twine IndexErrMsg,
1695 Twine TypeErrMsg) {
1697 if (!BaseSec)
1699
1701 return Sec;
1702
1704}
1705
1706template
1708 switch (Shdr.sh_type) {
1712 if (Shdr.sh_flags & SHF_ALLOC) {
1715 else
1716 return Data.takeError();
1717 }
1720
1721
1722
1723 if (Shdr.sh_flags & SHF_ALLOC) {
1725 return Obj.addSection<Section>(*Data);
1726 else
1727 return Data.takeError();
1728 }
1732
1733
1735 return Obj.addSection<Section>(*Data);
1736 else
1737 return Data.takeError();
1741 else
1742 return Data.takeError();
1746 else
1747 return Data.takeError();
1751 else
1752 return Data.takeError();
1754
1755 if (Obj.SymbolTable != nullptr)
1757 "found multiple SHT_SYMTAB sections");
1759 Obj.SymbolTable = &SymTab;
1760 return SymTab;
1761 }
1764 Obj.SectionIndexTable = &ShndxSection;
1765 return ShndxSection;
1766 }
1768 return Obj.addSection<Section>(ArrayRef<uint8_t>());
1769 default: {
1770 Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr);
1772 return Data.takeError();
1773
1774 Expected Name = ElfFile.getSectionName(Shdr);
1775 if (!Name)
1776 return Name.takeError();
1777
1779 return Obj.addSection<Section>(*Data);
1780 auto *Chdr = reinterpret_cast<const Elf_Chdr_Impl *>(Data->data());
1782 *Data, Chdr->ch_type, Chdr->ch_size, Chdr->ch_addralign));
1783 }
1784 }
1785}
1786
1787template Error ELFBuilder::readSectionHeaders() {
1788 uint32_t Index = 0;
1789 Expected<typename ELFFile::Elf_Shdr_Range> Sections =
1790 ElfFile.sections();
1791 if (!Sections)
1793
1795 if (Index == 0) {
1797 continue;
1798 }
1799 Expected<SectionBase &> Sec = makeSection(Shdr);
1800 if (!Sec)
1802
1803 Expected SecName = ElfFile.getSectionName(Shdr);
1804 if (!SecName)
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);
1822 }
1823
1825}
1826
1827template Error ELFBuilder::readSections(bool EnsureSymtab) {
1828 uint32_t ShstrIndex = ElfFile.getHeader().e_shstrndx;
1830 Expected<const Elf_Shdr *> Sec = ElfFile.getSection(0);
1831 if (!Sec)
1833
1834 ShstrIndex = (*Sec)->sh_link;
1835 }
1836
1838 Obj.HadShdrs = false;
1839 else {
1840 Expected<StringTableSection *> Sec =
1841 Obj.sections().template getSectionOfType(
1842 ShstrIndex,
1843 "e_shstrndx field value " + Twine(ShstrIndex) + " in elf header " +
1844 " is invalid",
1845 "e_shstrndx field value " + Twine(ShstrIndex) + " in elf header " +
1846 " does not reference a string table");
1847 if (!Sec)
1849
1850 Obj.SectionNames = *Sec;
1851 }
1852
1853
1854
1855
1856 if (Obj.SectionIndexTable)
1857 if (Error Err = Obj.SectionIndexTable->initialize(Obj.sections()))
1858 return Err;
1859
1860
1861
1862
1863 if (Obj.SymbolTable) {
1864 if (Error Err = Obj.SymbolTable->initialize(Obj.sections()))
1865 return Err;
1866 if (Error Err = initSymbolTable(Obj.SymbolTable))
1867 return Err;
1868 } else if (EnsureSymtab) {
1869 if (Error Err = Obj.addNewSymbolTable())
1870 return Err;
1871 }
1872
1873
1874
1875
1877 if (&Sec == Obj.SymbolTable)
1878 continue;
1879 if (Error Err = Sec.initialize(Obj.sections()))
1880 return Err;
1882 Expected<typename ELFFile::Elf_Shdr_Range> Sections =
1884 if (!Sections)
1886
1888 Sections->begin() + RelSec->Index;
1889 if (RelSec->Type == SHT_CREL) {
1890 auto RelsOrRelas = ElfFile.crels(*Shdr);
1891 if (!RelsOrRelas)
1892 return RelsOrRelas.takeError();
1894 return Err;
1896 return Err;
1897 } else if (RelSec->Type == SHT_REL) {
1898 Expected<typename ELFFile::Elf_Rel_Range> Rels =
1899 ElfFile.rels(*Shdr);
1900 if (!Rels)
1902
1904 return Err;
1905 } else {
1906 Expected<typename ELFFile::Elf_Rela_Range> Relas =
1907 ElfFile.relas(*Shdr);
1908 if (!Relas)
1910
1912 return Err;
1913 }
1915 if (Error Err = initGroupSection(GroupSec))
1916 return Err;
1917 }
1918 }
1919
1921}
1922
1924 if (Error E = readSectionHeaders())
1925 return E;
1926 if (Error E = findEhdrOffset())
1927 return E;
1928
1929
1930
1931
1933 {ElfFile.base() + EhdrOffset, ElfFile.getBufSize() - EhdrOffset}));
1934 if (!HeadersFile)
1936
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;
1946
1947 if (Error E = readSections(EnsureSymtab))
1948 return E;
1949 return readProgramHeaders(*HeadersFile);
1950}
1951
1953
1955
1960
1963 std::vector Records;
1964 bool HasSections = false;
1965
1967 Records.reserve(Lines.size());
1968 for (size_t LineNo = 1; LineNo <= Lines.size(); ++LineNo) {
1969 StringRef Line = Lines[LineNo - 1].trim();
1970 if (Line.empty())
1971 continue;
1972
1974 if (!R)
1975 return parseError(LineNo, R.takeError());
1977 break;
1980 }
1981 if (!HasSections)
1982 return parseError(-1U, "no sections");
1983
1984 return std::move(Records);
1985}
1986
1990 if (!Records)
1991 return Records.takeError();
1992
1994}
1995
1997 auto Obj = std::make_unique();
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);
2018 }
2020}
2021
2022template void ELFWriter::writeEhdr() {
2023 Elf_Ehdr &Ehdr = *reinterpret_cast<Elf_Ehdr *>(Buf->getBufferStart());
2024 std::fill(Ehdr.e_ident, Ehdr.e_ident + 16, 0);
2025 Ehdr.e_ident[EI_MAG0] = 0x7f;
2026 Ehdr.e_ident[EI_MAG1] = 'E';
2027 Ehdr.e_ident[EI_MAG2] = 'L';
2028 Ehdr.e_ident[EI_MAG3] = 'F';
2033 Ehdr.e_ident[EI_OSABI] = Obj.OSABI;
2035
2036 Ehdr.e_type = Obj.Type;
2037 Ehdr.e_machine = Obj.Machine;
2038 Ehdr.e_version = Obj.Version;
2039 Ehdr.e_entry = Obj.Entry;
2040
2041
2042 Ehdr.e_phnum = llvm::size(Obj.segments());
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;
2050
2051
2052
2053
2054
2055
2056 auto Shnum = Obj.sections().size() + 1;
2058 Ehdr.e_shnum = 0;
2059 else
2060 Ehdr.e_shnum = Shnum;
2061
2062
2063
2064
2065
2066
2069 else
2070 Ehdr.e_shstrndx = Obj.SectionNames->Index;
2071 } else {
2072 Ehdr.e_shentsize = 0;
2073 Ehdr.e_shoff = 0;
2074 Ehdr.e_shnum = 0;
2075 Ehdr.e_shstrndx = 0;
2076 }
2077}
2078
2079template void ELFWriter::writePhdrs() {
2080 for (auto &Seg : Obj.segments())
2081 writePhdr(Seg);
2082}
2083
2084template void ELFWriter::writeShdrs() {
2085
2086
2087 Elf_Shdr &Shdr =
2088 *reinterpret_cast<Elf_Shdr *>(Buf->getBufferStart() + Obj.SHOff);
2089 Shdr.sh_name = 0;
2091 Shdr.sh_flags = 0;
2092 Shdr.sh_addr = 0;
2093 Shdr.sh_offset = 0;
2094
2095 uint64_t Shnum = Obj.sections().size() + 1;
2097 Shdr.sh_size = Shnum;
2098 else
2099 Shdr.sh_size = 0;
2100
2101 if (Obj.SectionNames != nullptr && Obj.SectionNames->Index >= SHN_LORESERVE)
2102 Shdr.sh_link = Obj.SectionNames->Index;
2103 else
2104 Shdr.sh_link = 0;
2105 Shdr.sh_info = 0;
2106 Shdr.sh_addralign = 0;
2107 Shdr.sh_entsize = 0;
2108
2110 writeShdr(Sec);
2111}
2112
2113template Error ELFWriter::writeSectionData() {
2115
2116
2117
2118 if (Sec.ParentSegment == nullptr)
2119 if (Error Err = Sec.accept(*SecWriter))
2120 return Err;
2121
2123}
2124
2125template void ELFWriter::writeSegmentData() {
2126 for (Segment &Seg : Obj.segments()) {
2130 }
2131
2132 for (const auto &it : Obj.getUpdatedSections()) {
2134 ArrayRef<uint8_t> Data = it.second;
2135
2137 assert(Parent && "This section should've been part of a segment.");
2139 Sec->OriginalOffset - Parent->OriginalOffset + Parent->Offset;
2141 }
2142
2143
2144 for (auto &Sec : Obj.removedSections()) {
2145 Segment *Parent = Sec.ParentSegment;
2146 if (Parent == nullptr || Sec.Type == SHT_NOBITS || Sec.Size == 0)
2147 continue;
2150 std::memset(Buf->getBufferStart() + Offset, 0, Sec.Size);
2151 }
2152}
2153
2154template
2159
2161 if (!Sec->hasContents())
2164 "section '%s' cannot be updated because it does not have contents",
2165 Sec->Name.c_str());
2166
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);
2172
2173 if (!Sec->ParentSegment) {
2174 Sec = std::make_unique(*Sec, Data);
2175 } else {
2176
2177 Sec->Size = Data.size();
2178 UpdatedSections[Sec.get()] = Data;
2179 }
2180
2182}
2183
2186 [&](const SecPtr &Sec) { return Sec->Name == Name; });
2187 if (It == Sections.end())
2189 Name.str().c_str());
2190 return updateSectionData(*It, Data);
2191}
2192
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);
2198}
2199
2201 bool AllowBrokenLinks, std::function<bool(const SectionBase &)> ToRemove) {
2202
2203 auto Iter = std::stable_partition(
2204 std::begin(Sections), std::end(Sections), [=](const SecPtr &Sec) {
2206 return false;
2207
2208
2210 return true;
2212 if (auto ToRelSec = RelSec->getSection())
2213 return (*ToRelSec);
2214 }
2215
2219 }
2220 return true;
2221 });
2228
2229
2230
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());
2238 }
2239
2240
2241
2242
2243
2244
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();
2249 }))
2250 return E;
2251 }
2252
2253
2254
2255 std::move(Iter, Sections.end(), std::back_inserter(RemovedSections));
2256
2257 Sections.erase(Iter, std::end(Sections));
2259}
2260
2263 auto SectionIndexLess = [](const SecPtr &Lhs, const SecPtr &Rhs) {
2264 return Lhs->Index < Rhs->Index;
2265 };
2267 "Sections are expected to be sorted by Index");
2268
2269
2270 for (auto &I : FromTo)
2271 I.second->Index = I.first->Index;
2272
2273
2274 for (auto &Sec : Sections)
2275 Sec->replaceSectionReferences(FromTo);
2276
2278 false,
2279 [=](const SectionBase &Sec) { return FromTo.count(&Sec) > 0; }))
2280 return E;
2281 llvm::sort(Sections, SectionIndexLess);
2283}
2284
2287 for (const SecPtr &Sec : Sections)
2289 return E;
2291}
2292
2295
2296
2301
2302
2303
2305 break;
2306 }
2307 }
2308 if (!StrTab)
2310
2312 SymTab.Name = ".symtab";
2315 return Err;
2316 SymTab.addSymbol("", 0, 0, nullptr, 0, 0, 0, 0);
2317
2319
2321}
2322
2323
2327
2328
2329
2330
2334
2335
2336
2337
2338
2339 for (Segment *Seg : Segments) {
2340
2341
2342
2343
2348 } else {
2351 }
2353 }
2355}
2356
2357
2358
2359
2360
2361
2362
2363template
2365
2366
2367
2368
2369
2370
2371
2372
2373 std::vector<SectionBase *> OutOfSegmentSections;
2375 for (auto &Sec : Sections) {
2376 Sec.Index = Index++;
2377 if (Sec.ParentSegment != nullptr) {
2381 } else
2382 OutOfSegmentSections.push_back(&Sec);
2383 }
2384
2388 });
2389 for (auto *Sec : OutOfSegmentSections) {
2391 Sec->Offset = Offset;
2393 Offset += Sec->Size;
2394 }
2396}
2397
2398
2399
2401
2402
2403 std::vector<SectionBase *> Sections;
2404 Sections.reserve(Obj.sections().size());
2406 for (auto &Sec : Obj.sections()) {
2407 Sec.Index = Index++;
2408 Sections.push_back(&Sec);
2409 }
2413 });
2414
2415 for (auto *Sec : Sections) {
2416 auto *FirstSec = Sec->ParentSegment && Sec->ParentSegment->Type == PT_LOAD
2417 ? Sec->ParentSegment->firstSection()
2418 : nullptr;
2419
2420
2421
2422 if (FirstSec && FirstSec == Sec)
2423 Off = alignTo(Off, Sec->ParentSegment->Align, Sec->Addr);
2424
2425
2426
2427
2429 Sec->Offset = Off;
2430 continue;
2431 }
2432
2433 if (!FirstSec) {
2434
2435
2436 Off = Sec->Align ? alignTo(Off, Sec->Align) : Off;
2437 } else if (FirstSec != Sec) {
2438
2439
2440 Off = Sec->OriginalOffset - FirstSec->OriginalOffset + FirstSec->Offset;
2441 }
2442 Sec->Offset = Off;
2443 Off += Sec->Size;
2444 }
2445 return Off;
2446}
2447
2448
2449
2453 for (Segment *Seg : Segments) {
2455 continue;
2456
2457
2458
2459
2460
2461
2462
2465 FirstSec ? FirstSec->Offset
2472 }
2473
2474
2475
2479 FileSize = std::max(FileSize, HdrEnd - Offset);
2480 }
2481
2484 MaxOffset = std::max(MaxOffset, Offset + FileSize);
2485 }
2486 return MaxOffset;
2487}
2488
2489template void ELFWriter::initEhdrSegment() {
2490 Segment &ElfHdr = Obj.ElfHdrSegment;
2492 ElfHdr.Flags = 0;
2493 ElfHdr.VAddr = 0;
2494 ElfHdr.PAddr = 0;
2496 ElfHdr.Align = 0;
2497}
2498
2499template void ELFWriter::assignOffsets() {
2500
2501
2502
2503 std::vector<Segment *> OrderedSegments;
2505 OrderedSegments.push_back(&Segment);
2506 OrderedSegments.push_back(&Obj.ElfHdrSegment);
2507 OrderedSegments.push_back(&Obj.ProgramHdrSegment);
2509
2511 if (OnlyKeepDebug) {
2512
2513
2514
2515 uint64_t HdrEnd =
2516 sizeof(Elf_Ehdr) + llvm::size(Obj.segments()) * sizeof(Elf_Phdr);
2520 } else {
2521
2522
2523
2526 }
2527
2528
2529 if (WriteSectionHeaders)
2532}
2533
2534template size_t ELFWriter::totalSize() const {
2535
2536
2537 if (!WriteSectionHeaders)
2538 return Obj.SHOff;
2539 size_t ShdrCount = Obj.sections().size() + 1;
2540 return Obj.SHOff + ShdrCount * sizeof(Elf_Shdr);
2541}
2542
2544
2545
2546 writeSegmentData();
2547 writeEhdr();
2548 writePhdrs();
2549 if (Error E = writeSectionData())
2550 return E;
2552 writeShdrs();
2553
2554
2555
2556 Out.write(Buf->getBufferStart(), Buf->getBufferSize());
2558}
2559
2561
2562
2563
2564
2565 if (Obj.isRelocatable() || Obj.SymbolTable == nullptr ||
2566 !Obj.SymbolTable->empty())
2568
2569
2570
2571 auto *StrTab = Obj.SymbolTable->getStrTab() == Obj.SectionNames
2572 ? nullptr
2573 : Obj.SymbolTable->getStrTab();
2574 return Obj.removeSections(false, [&](const SectionBase &Sec) {
2575 return &Sec == Obj.SymbolTable || &Sec == StrTab;
2576 });
2577}
2578
2580
2581
2582
2585 "cannot write section header table because "
2586 "section header string table was removed");
2587
2589 return E;
2590
2591
2592
2593 if (Obj.SymbolTable && .SymbolTable->indicesChanged())
2595 Sec.restoreSymTabLink(*Obj.SymbolTable);
2596
2597
2598
2599
2600 bool NeedsLargeIndexes = false;
2603
2604
2605 NeedsLargeIndexes =
2608
2609
2610 }
2611
2612 if (NeedsLargeIndexes) {
2613
2614
2615 if (Obj.SymbolTable != nullptr && Obj.SectionIndexTable == nullptr) {
2616
2617
2619 Obj.SymbolTable->setShndxTable(&Shndx);
2620 Shndx.setSymTab(Obj.SymbolTable);
2621 }
2622 } else {
2623
2624
2625 if (Obj.SectionIndexTable != nullptr) {
2626
2627 if (Error E = Obj.removeSections(false ,
2629 return &Sec == Obj.SectionIndexTable;
2630 }))
2631 return E;
2632 }
2633 }
2634
2635
2636
2637 if (Obj.SectionNames != nullptr)
2639 Obj.SectionNames->addString(Sec.Name);
2640
2641 initEhdrSegment();
2642
2643
2644
2645
2647 auto SecSizer = std::make_unique<ELFSectionSizer>();
2649 Sec.Index = Index++;
2650 if (Error Err = Sec.accept(*SecSizer))
2651 return Err;
2652 }
2653
2654
2655
2656
2657 if (Obj.SymbolTable != nullptr)
2658 Obj.SymbolTable->prepareForLayout();
2659
2660
2661
2664 StrTab->prepareForLayout();
2665
2666 assignOffsets();
2667
2668
2669
2670 if (Obj.SymbolTable != nullptr)
2671 Obj.SymbolTable->fillShndxTable();
2672
2673
2674
2677 Sec.HeaderOffset = Offset;
2678 Offset += sizeof(Elf_Shdr);
2680 Sec.NameIndex = Obj.SectionNames->findIndex(Sec.Name);
2681 Sec.finalize();
2682 }
2683
2684 size_t TotalSize = totalSize();
2686 if ()
2688 "failed to allocate memory buffer of " +
2690
2691 SecWriter = std::make_unique<ELFSectionWriter>(*Buf);
2693}
2694
2697 for (const SectionBase &Sec : Obj.allocSections()) {
2698 if (Sec.Type != SHT_NOBITS && Sec.Size > 0)
2699 SectionsToWrite.push_back(&Sec);
2700 }
2701
2702 if (SectionsToWrite.empty())
2704
2707 return LHS->Offset < RHS->Offset;
2708 });
2709
2710 assert(SectionsToWrite.front()->Offset == 0);
2711
2712 for (size_t i = 0; i != SectionsToWrite.size(); ++i) {
2713 const SectionBase &Sec = *SectionsToWrite[i];
2715 return Err;
2716 if (GapFill == 0)
2717 continue;
2718 uint64_t PadOffset = (i < SectionsToWrite.size() - 1)
2719 ? SectionsToWrite[i + 1]->Offset
2720 : Buf->getBufferSize();
2721 assert(PadOffset <= Buf->getBufferSize());
2723 std::fill(Buf->getBufferStart() + Sec.Offset + Sec.Size,
2724 Buf->getBufferStart() + PadOffset, GapFill);
2725 }
2726
2727
2728
2729 Out.write(Buf->getBufferStart(), Buf->getBufferSize());
2731}
2732
2734
2735
2736
2737
2740 if (Sec.ParentSegment != nullptr)
2741 Sec.Addr =
2742 Sec.Offset - Sec.ParentSegment->Offset + Sec.ParentSegment->PAddr;
2743 if (Sec.Type != SHT_NOBITS && Sec.Size > 0)
2744 MinAddr = std::min(MinAddr, Sec.Addr);
2745 }
2746
2747
2748
2749
2750
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);
2756 }
2757
2759 if ()
2761 "failed to allocate memory buffer of " +
2763 SecWriter = std::make_unique(*Buf);
2765}
2766
2772 "section '%s' address range [0x%llx, 0x%llx] is not 32 bit",
2775}
2776
2778
2781 "entry point address 0x%llx overflows 32 bits",
2782 Obj.Entry);
2783
2787 return E;
2789 }
2790 }
2791
2794 });
2795
2796 std::unique_ptr EmptyBuffer =
2798 if (!EmptyBuffer)
2800 "failed to allocate memory buffer of 0 bytes");
2801
2803 if (!ExpTotalSize)
2804 return ExpTotalSize.takeError();
2806
2808 if ()
2810 "failed to allocate memory buffer of 0x" +
2813}
2814
2815uint64_t IHexWriter::writeEntryPointRecord(uint8_t *Buf) {
2818
2820 return 0;
2821
2822 if (Obj.Entry <= 0xFFFFFU) {
2823 Data[0] = ((Obj.Entry & 0xF0000U) >> 12) & 0xFF;
2827 } else {
2831 }
2832 memcpy(Buf, HexData.data(), HexData.size());
2833 return HexData.size();
2834}
2835
2836uint64_t IHexWriter::writeEndOfFileRecord(uint8_t *Buf) {
2838 memcpy(Buf, HexData.data(), HexData.size());
2839 return HexData.size();
2840}
2841
2842Expected<size_t>
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);
2848
2849
2850
2851 return LengthCalc.getBufferOffset() +
2853 IHexRecord::getLineLength(0);
2854}
2855
2858
2861 return Err;
2862
2864
2865 Offset += writeEntryPointRecord(
2866 reinterpret_cast<uint8_t *>(Buf->getBufferStart()) + Offset);
2867
2868 Offset += writeEndOfFileRecord(
2869 reinterpret_cast<uint8_t *>(Buf->getBufferStart()) + Offset);
2871
2872
2873
2874 Out.write(Buf->getBufferStart(), Buf->getBufferSize());
2876}
2877
2879
2881 "Expected section size to have been finalized");
2882
2883
2885}
2886
2891
2896
2901
2904 memcpy(Out.getBufferStart() + Off, Data.data(), Data.size());
2905}
2906
2908
2909
2915 Off += Record.getSize();
2916 }
2918}
2919
2922 const uint32_t ChunkSize = 16;
2926 while (.empty()) {
2932 }
2933}
2934
2937 "Section size does not match the section's string table builder size");
2938 std::vector<uint8_t> Data(Sec.Size);
2939 Sec.StrTabBuilder.write(Data.data());
2942}
2943
2946 auto *Iter = Line.begin();
2947 *Iter++ = 'S';
2948 *Iter++ = '0' + Type;
2949
2951
2953
2956
2958 *Iter++ = '\r';
2959 *Iter++ = '\n';
2960 assert(Iter == Line.end());
2961 return Line;
2962}
2963
2966 Sum += (Address >> 24) & 0xFF;
2967 Sum += (Address >> 16) & 0xFF;
2968 Sum += (Address >> 8) & 0xFF;
2971 Sum += Byte;
2972 return 0xFF - (Sum & 0xFF);
2973}
2974
2979
2981 switch (Type) {
2983 return 6;
2985 return 8;
2987 return 8;
2989 return 6;
2990 default:
2991 return 4;
2992 }
2993}
2994
2997 uint8_t ChecksumSize = 1;
2999}
3000
3008
3010
3011
3012
3015 reinterpret_cast<const uint8_t *>(HeaderContents.data()),
3016 HeaderContents.size());
3018}
3019
3020size_t SRECWriter::writeHeader(uint8_t *Buf) {
3023 return Record.size();
3024}
3025
3028 "Invalid record type for terminator");
3032 return Data.size();
3033}
3034
3035Expected<size_t>
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);
3041
3042 SizeCalc.writeRecords(Obj.Entry);
3043
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();
3048}
3049
3052 writeHeader(reinterpret_cast<uint8_t *>(Buf->getBufferStart()));
3056 return E;
3057 }
3060
3061
3063 Offset += writeTerminator(
3064 reinterpret_cast<uint8_t *>(Buf->getBufferStart() + Offset),
3065 TerminatorType);
3067 Out.write(Buf->getBufferStart(), Buf->getBufferSize());
3069}
3070
3071namespace llvm {
3073namespace elf {
3074
3079
3084
3085}
3086}
3087}