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