@@ -1459,8 +1459,17 @@ void ObjCProcessor::ProcessObjCData(std::optional<std::string> imageName)
1459
1459
m_relocationPointerRewrites.clear ();
1460
1460
}
1461
1461
1462
+ void ObjCProcessor::ProcessObjCLiterals (std::optional<std::string> imageName)
1463
+ {
1464
+ ProcessCFStrings (imageName);
1465
+ ProcessNSConstantArrays (imageName);
1466
+ ProcessNSConstantDictionaries (imageName);
1467
+ ProcessNSConstantIntegerNumbers (imageName);
1468
+ ProcessNSConstantFloatingPointNumbers (imageName);
1469
+ ProcessNSConstantDatas (imageName);
1470
+ }
1462
1471
1463
- void ObjCProcessor::ProcessCFStrings (std::optional<std::string> imageName)
1472
+ void ObjCProcessor::ProcessCFStrings (const std::optional<std::string>& imageName)
1464
1473
{
1465
1474
m_symbolQueue = new SymbolQueue ();
1466
1475
uint64_t ptrSize = m_data->GetAddressSize ();
@@ -1577,6 +1586,274 @@ void ObjCProcessor::ProcessCFStrings(std::optional<std::string> imageName)
1577
1586
delete m_symbolQueue;
1578
1587
}
1579
1588
1589
+ void ObjCProcessor::ProcessNSConstantArrays (const std::optional<std::string>& imageName)
1590
+ {
1591
+ m_symbolQueue = new SymbolQueue ();
1592
+ uint64_t ptrSize = m_data->GetAddressSize ();
1593
+
1594
+ auto idType = Type::NamedType (m_data, m_typeNames.id );
1595
+ StructureBuilder nsConstantArrayBuilder;
1596
+ nsConstantArrayBuilder.AddMember (Type::PointerType (ptrSize, Type::VoidType ()), " isa" );
1597
+ nsConstantArrayBuilder.AddMember (Type::IntegerType (ptrSize, false ), " count" );
1598
+ nsConstantArrayBuilder.AddMember (Type::PointerType (ptrSize, idType), " objects" );
1599
+ auto type = finalizeStructureBuilder (m_data, nsConstantArrayBuilder, " __NSConstantArray" );
1600
+ m_typeNames.nsConstantArray = type.first ;
1601
+
1602
+ auto reader = GetReader ();
1603
+ if (auto arrays = GetSectionForImage (imageName, " __objc_arrayobj" ))
1604
+ {
1605
+ auto start = arrays->GetStart ();
1606
+ auto end = arrays->GetEnd ();
1607
+ auto typeWidth = Type::NamedType (m_data, m_typeNames.nsConstantArray )->GetWidth ();
1608
+ m_data->BeginBulkModifySymbols ();
1609
+ for (view_ptr_t i = start; i < end; i += typeWidth)
1610
+ {
1611
+ reader->Seek (i + ptrSize);
1612
+ uint64_t count = reader->ReadPointer ();
1613
+ auto dataLoc = ReadPointerAccountingForRelocations (reader.get ());
1614
+ DefineObjCSymbol (
1615
+ DataSymbol, Type::ArrayType (idType, count), fmt::format (" nsarray_{:x}_data" , i), dataLoc, true );
1616
+ DefineObjCSymbol (DataSymbol, Type::NamedType (m_data, m_typeNames.nsConstantArray ),
1617
+ fmt::format (" nsarray_{:x}" , i), i, true );
1618
+ }
1619
+ auto id = m_data->BeginUndoActions ();
1620
+ m_symbolQueue->Process ();
1621
+ m_data->EndBulkModifySymbols ();
1622
+ m_data->ForgetUndoActions (id);
1623
+ }
1624
+ delete m_symbolQueue;
1625
+ }
1626
+
1627
+ void ObjCProcessor::ProcessNSConstantDictionaries (const std::optional<std::string>& imageName)
1628
+ {
1629
+ m_symbolQueue = new SymbolQueue ();
1630
+ uint64_t ptrSize = m_data->GetAddressSize ();
1631
+
1632
+ auto idType = Type::NamedType (m_data, m_typeNames.id );
1633
+ StructureBuilder nsConstantDictionaryBuilder;
1634
+ nsConstantDictionaryBuilder.AddMember (Type::PointerType (ptrSize, Type::VoidType ()), " isa" );
1635
+ nsConstantDictionaryBuilder.AddMember (Type::IntegerType (ptrSize, false ), " options" );
1636
+ nsConstantDictionaryBuilder.AddMember (Type::IntegerType (ptrSize, false ), " count" );
1637
+ nsConstantDictionaryBuilder.AddMember (Type::PointerType (ptrSize, idType), " keys" );
1638
+ nsConstantDictionaryBuilder.AddMember (Type::PointerType (ptrSize, idType), " objects" );
1639
+ auto type = finalizeStructureBuilder (m_data, nsConstantDictionaryBuilder, " __NSConstantDictionary" );
1640
+ m_typeNames.nsConstantDictionary = type.first ;
1641
+
1642
+ auto reader = GetReader ();
1643
+ if (auto dicts = GetSectionForImage (imageName, " __objc_dictobj" ))
1644
+ {
1645
+ auto start = dicts->GetStart ();
1646
+ auto end = dicts->GetEnd ();
1647
+ auto typeWidth = Type::NamedType (m_data, m_typeNames.nsConstantDictionary )->GetWidth ();
1648
+ m_data->BeginBulkModifySymbols ();
1649
+ for (view_ptr_t i = start; i < end; i += typeWidth)
1650
+ {
1651
+ reader->Seek (i + (ptrSize * 2 ));
1652
+ // TODO: Do we need to do anything with `options`? It appears to always be 1.
1653
+ uint64_t count = reader->ReadPointer ();
1654
+ auto keysLoc = ReadPointerAccountingForRelocations (reader.get ());
1655
+ auto objectsLoc = ReadPointerAccountingForRelocations (reader.get ());
1656
+ DefineObjCSymbol (
1657
+ DataSymbol, Type::ArrayType (idType, count), fmt::format (" nsdict_{:x}_keys" , i), keysLoc, true );
1658
+ DefineObjCSymbol (
1659
+ DataSymbol, Type::ArrayType (idType, count), fmt::format (" nsdict_{:x}_objects" , i), objectsLoc, true );
1660
+ DefineObjCSymbol (DataSymbol, Type::NamedType (m_data, m_typeNames.nsConstantDictionary ),
1661
+ fmt::format (" nsdict_{:x}" , i), i, true );
1662
+ }
1663
+ auto id = m_data->BeginUndoActions ();
1664
+ m_symbolQueue->Process ();
1665
+ m_data->EndBulkModifySymbols ();
1666
+ m_data->ForgetUndoActions (id);
1667
+ }
1668
+ delete m_symbolQueue;
1669
+ }
1670
+
1671
+ void ObjCProcessor::ProcessNSConstantIntegerNumbers (const std::optional<std::string>& imageName)
1672
+ {
1673
+ m_symbolQueue = new SymbolQueue ();
1674
+ uint64_t ptrSize = m_data->GetAddressSize ();
1675
+
1676
+ StructureBuilder nsConstantIntegerNumberBuilder;
1677
+ nsConstantIntegerNumberBuilder.AddMember (Type::PointerType (ptrSize, Type::VoidType ()), " isa" );
1678
+ nsConstantIntegerNumberBuilder.AddMember (Type::PointerType (ptrSize, Type::IntegerType (1 , true )), " encoding" );
1679
+ nsConstantIntegerNumberBuilder.AddMember (Type::IntegerType (ptrSize, true ), " value" );
1680
+ auto type = finalizeStructureBuilder (m_data, nsConstantIntegerNumberBuilder, " __NSConstantIntegerNumber" );
1681
+ m_typeNames.nsConstantIntegerNumber = type.first ;
1682
+
1683
+ auto reader = GetReader ();
1684
+ if (auto numbers = GetSectionForImage (imageName, " __objc_intobj" ))
1685
+ {
1686
+ auto start = numbers->GetStart ();
1687
+ auto end = numbers->GetEnd ();
1688
+ auto typeWidth = Type::NamedType (m_data, m_typeNames.nsConstantIntegerNumber )->GetWidth ();
1689
+ m_data->BeginBulkModifySymbols ();
1690
+ for (view_ptr_t i = start; i < end; i += typeWidth)
1691
+ {
1692
+ reader->Seek (i + ptrSize);
1693
+ uint64_t encodingLoc = ReadPointerAccountingForRelocations (reader.get ());
1694
+ uint64_t value = reader->Read64 ();
1695
+ reader->Seek (encodingLoc);
1696
+ uint8_t encoding = reader->Read8 ();
1697
+
1698
+ switch (encoding)
1699
+ {
1700
+ case ' c' :
1701
+ case ' s' :
1702
+ case ' i' :
1703
+ case ' l' :
1704
+ case ' q' :
1705
+ DefineObjCSymbol (DataSymbol, Type::NamedType (m_data, m_typeNames.nsConstantIntegerNumber ),
1706
+ fmt::format (" nsint_{:x}_{}" , i, (int64_t )value), i, true );
1707
+ break ;
1708
+ case ' C' :
1709
+ case ' S' :
1710
+ case ' I' :
1711
+ case ' L' :
1712
+ case ' Q' :
1713
+ DefineObjCSymbol (DataSymbol, Type::NamedType (m_data, m_typeNames.nsConstantIntegerNumber ),
1714
+ fmt::format (" nsint_{:x}_{}" , i, value), i, true );
1715
+ break ;
1716
+ default :
1717
+ m_logger->LogWarn (" Unknown type encoding '%c' in number literal object at %p" , encoding, i);
1718
+ continue ;
1719
+ }
1720
+ }
1721
+ auto id = m_data->BeginUndoActions ();
1722
+ m_symbolQueue->Process ();
1723
+ m_data->EndBulkModifySymbols ();
1724
+ m_data->ForgetUndoActions (id);
1725
+ }
1726
+ delete m_symbolQueue;
1727
+ }
1728
+
1729
+ void ObjCProcessor::ProcessNSConstantFloatingPointNumbers (const std::optional<std::string>& imageName)
1730
+ {
1731
+ uint64_t ptrSize = m_data->GetAddressSize ();
1732
+
1733
+ StructureBuilder nsConstantFloatNumberBuilder;
1734
+ nsConstantFloatNumberBuilder.AddMember (Type::PointerType (ptrSize, Type::VoidType ()), " isa" );
1735
+ nsConstantFloatNumberBuilder.AddMember (Type::FloatType (4 ), " value" );
1736
+ auto type = finalizeStructureBuilder (m_data, nsConstantFloatNumberBuilder, " __NSConstantFloatNumber" );
1737
+ m_typeNames.nsConstantFloatNumber = type.first ;
1738
+
1739
+ StructureBuilder nsConstantDoubleNumberBuilder;
1740
+ nsConstantDoubleNumberBuilder.AddMember (Type::PointerType (ptrSize, Type::VoidType ()), " isa" );
1741
+ nsConstantDoubleNumberBuilder.AddMember (Type::FloatType (8 ), " value" );
1742
+ type = finalizeStructureBuilder (m_data, nsConstantDoubleNumberBuilder, " __NSConstantDoubleNumber" );
1743
+ m_typeNames.nsConstantDoubleNumber = type.first ;
1744
+
1745
+ StructureBuilder nsConstantDateBuilder;
1746
+ nsConstantDateBuilder.AddMember (Type::PointerType (ptrSize, Type::VoidType ()), " isa" );
1747
+ nsConstantDateBuilder.AddMember (Type::FloatType (8 ), " ti" );
1748
+ type = finalizeStructureBuilder (m_data, nsConstantDateBuilder, " __NSConstantDate" );
1749
+ m_typeNames.nsConstantDate = type.first ;
1750
+
1751
+ enum SectionType
1752
+ {
1753
+ Float,
1754
+ Double,
1755
+ Date,
1756
+ };
1757
+
1758
+ constexpr std::pair<std::string_view, SectionType> sections[] = {
1759
+ {" __objc_floatobj" , Float},
1760
+ {" __objc_doubleobj" , Double},
1761
+ {" __objc_dateobj" , Date},
1762
+ };
1763
+
1764
+ auto reader = GetReader ();
1765
+ for (auto & [sectionName, sectionType] : sections)
1766
+ {
1767
+ auto numbers = GetSectionForImage (imageName, sectionName.data ());
1768
+ if (!numbers)
1769
+ continue ;
1770
+
1771
+ m_symbolQueue = new SymbolQueue ();
1772
+ auto start = numbers->GetStart ();
1773
+ auto end = numbers->GetEnd ();
1774
+ auto typeWidth = Type::NamedType (m_data, m_typeNames.nsConstantDoubleNumber )->GetWidth ();
1775
+ m_data->BeginBulkModifySymbols ();
1776
+ for (view_ptr_t i = start; i < end; i += typeWidth)
1777
+ {
1778
+ reader->Seek (i + ptrSize);
1779
+
1780
+ QualifiedName* typeName = nullptr ;
1781
+ std::string name;
1782
+
1783
+ switch (sectionType)
1784
+ {
1785
+ case Float:
1786
+ {
1787
+ float value = 0 ;
1788
+ reader->Read (&value, sizeof (value));
1789
+ name = fmt::format (" nsfloat_{:x}_{}" , i, value);
1790
+ typeName = &m_typeNames.nsConstantFloatNumber ;
1791
+ break ;
1792
+ }
1793
+ case Double:
1794
+ {
1795
+ double value = 0 ;
1796
+ reader->Read (&value, sizeof (value));
1797
+ name = fmt::format (" nsdouble_{:x}_{}" , i, value);
1798
+ typeName = &m_typeNames.nsConstantDoubleNumber ;
1799
+ break ;
1800
+ }
1801
+ case Date:
1802
+ {
1803
+ double value = 0 ;
1804
+ reader->Read (&value, sizeof (value));
1805
+ name = fmt::format (" nsdate_{:x}_{}" , i, value);
1806
+ typeName = &m_typeNames.nsConstantDate ;
1807
+ break ;
1808
+ }
1809
+ }
1810
+ DefineObjCSymbol (DataSymbol, Type::NamedType (m_data, *typeName), name, i, true );
1811
+ }
1812
+ auto id = m_data->BeginUndoActions ();
1813
+ m_symbolQueue->Process ();
1814
+ m_data->EndBulkModifySymbols ();
1815
+ m_data->ForgetUndoActions (id);
1816
+ delete m_symbolQueue;
1817
+ }
1818
+ }
1819
+
1820
+ void ObjCProcessor::ProcessNSConstantDatas (const std::optional<std::string>& imageName)
1821
+ {
1822
+ m_symbolQueue = new SymbolQueue ();
1823
+ uint64_t ptrSize = m_data->GetAddressSize ();
1824
+
1825
+ StructureBuilder nsConstantDataBuilder;
1826
+ nsConstantDataBuilder.AddMember (Type::PointerType (ptrSize, Type::VoidType ()), " isa" );
1827
+ nsConstantDataBuilder.AddMember (Type::IntegerType (ptrSize, false ), " length" );
1828
+ nsConstantDataBuilder.AddMember (Type::PointerType (ptrSize, Type::IntegerType (1 , false )), " bytes" );
1829
+ auto type = finalizeStructureBuilder (m_data, nsConstantDataBuilder, " __NSConstantData" );
1830
+ m_typeNames.nsConstantData = type.first ;
1831
+
1832
+ auto reader = GetReader ();
1833
+ if (auto datas = GetSectionForImage (imageName, " __objc_dataobj" ))
1834
+ {
1835
+ auto start = datas->GetStart ();
1836
+ auto end = datas->GetEnd ();
1837
+ auto typeWidth = Type::NamedType (m_data, m_typeNames.nsConstantData )->GetWidth ();
1838
+ m_data->BeginBulkModifySymbols ();
1839
+ for (view_ptr_t i = start; i < end; i += typeWidth)
1840
+ {
1841
+ reader->Seek (i + ptrSize);
1842
+ uint64_t length = reader->ReadPointer ();
1843
+ auto dataLoc = ReadPointerAccountingForRelocations (reader.get ());
1844
+ DefineObjCSymbol (DataSymbol, Type::ArrayType (Type::IntegerType (1 , false ), length),
1845
+ fmt::format (" nsdata_{:x}_data" , i), dataLoc, true );
1846
+ DefineObjCSymbol (
1847
+ DataSymbol, Type::NamedType (m_data, m_typeNames.nsConstantData ), fmt::format (" nsdata_{:x}" , i), i, true );
1848
+ }
1849
+ auto id = m_data->BeginUndoActions ();
1850
+ m_symbolQueue->Process ();
1851
+ m_data->EndBulkModifySymbols ();
1852
+ m_data->ForgetUndoActions (id);
1853
+ }
1854
+ delete m_symbolQueue;
1855
+ }
1856
+
1580
1857
void ObjCProcessor::AddRelocatedPointer (uint64_t location, uint64_t rewrite)
1581
1858
{
1582
1859
m_relocationPointerRewrites[location] = rewrite;
0 commit comments