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 ToRemove(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 isAlnum(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 ToRemove(*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 && Obj.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 (Buf)

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 (Buf)

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 (Buf)

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 (Data.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}