@@ -1535,6 +1535,15 @@ void ObjCProcessor::ProcessObjCData()
1535
1535
m_relocationPointerRewrites.clear ();
1536
1536
}
1537
1537
1538
+ void ObjCProcessor::ProcessObjCLiterals ()
1539
+ {
1540
+ ProcessCFStrings ();
1541
+ ProcessNSConstantArrays ();
1542
+ ProcessNSConstantDictionaries ();
1543
+ ProcessNSConstantIntegerNumbers ();
1544
+ ProcessNSConstantFloatingPointNumbers ();
1545
+ ProcessNSConstantDatas ();
1546
+ }
1538
1547
1539
1548
void ObjCProcessor::ProcessCFStrings ()
1540
1549
{
@@ -1651,6 +1660,274 @@ void ObjCProcessor::ProcessCFStrings()
1651
1660
}
1652
1661
}
1653
1662
1663
+ void ObjCProcessor::ProcessNSConstantArrays ()
1664
+ {
1665
+ m_symbolQueue = new SymbolQueue ();
1666
+ uint64_t ptrSize = m_data->GetAddressSize ();
1667
+
1668
+ auto idType = Type::NamedType (m_data, m_typeNames.id );
1669
+ StructureBuilder nsConstantArrayBuilder;
1670
+ nsConstantArrayBuilder.AddMember (Type::PointerType (ptrSize, Type::VoidType ()), " isa" );
1671
+ nsConstantArrayBuilder.AddMember (Type::IntegerType (ptrSize, false ), " count" );
1672
+ nsConstantArrayBuilder.AddMember (Type::PointerType (ptrSize, idType), " objects" );
1673
+ auto type = finalizeStructureBuilder (m_data, nsConstantArrayBuilder, " __NSConstantArray" );
1674
+ m_typeNames.nsConstantArray = type.first ;
1675
+
1676
+ auto reader = GetReader ();
1677
+ if (auto arrays = GetSectionWithName (" __objc_arrayobj" ))
1678
+ {
1679
+ auto start = arrays->GetStart ();
1680
+ auto end = arrays->GetEnd ();
1681
+ auto typeWidth = Type::NamedType (m_data, m_typeNames.nsConstantArray )->GetWidth ();
1682
+ m_data->BeginBulkModifySymbols ();
1683
+ for (view_ptr_t i = start; i < end; i += typeWidth)
1684
+ {
1685
+ reader->Seek (i + ptrSize);
1686
+ uint64_t count = reader->ReadPointer ();
1687
+ auto dataLoc = ReadPointerAccountingForRelocations (reader.get ());
1688
+ DefineObjCSymbol (
1689
+ DataSymbol, Type::ArrayType (idType, count), fmt::format (" nsarray_{:x}_data" , i), dataLoc, true );
1690
+ DefineObjCSymbol (DataSymbol, Type::NamedType (m_data, m_typeNames.nsConstantArray ),
1691
+ fmt::format (" nsarray_{:x}" , i), i, true );
1692
+ }
1693
+ auto id = m_data->BeginUndoActions ();
1694
+ m_symbolQueue->Process ();
1695
+ m_data->EndBulkModifySymbols ();
1696
+ m_data->ForgetUndoActions (id);
1697
+ }
1698
+ delete m_symbolQueue;
1699
+ }
1700
+
1701
+ void ObjCProcessor::ProcessNSConstantDictionaries ()
1702
+ {
1703
+ m_symbolQueue = new SymbolQueue ();
1704
+ uint64_t ptrSize = m_data->GetAddressSize ();
1705
+
1706
+ auto idType = Type::NamedType (m_data, m_typeNames.id );
1707
+ StructureBuilder nsConstantDictionaryBuilder;
1708
+ nsConstantDictionaryBuilder.AddMember (Type::PointerType (ptrSize, Type::VoidType ()), " isa" );
1709
+ nsConstantDictionaryBuilder.AddMember (Type::IntegerType (ptrSize, false ), " options" );
1710
+ nsConstantDictionaryBuilder.AddMember (Type::IntegerType (ptrSize, false ), " count" );
1711
+ nsConstantDictionaryBuilder.AddMember (Type::PointerType (ptrSize, idType), " keys" );
1712
+ nsConstantDictionaryBuilder.AddMember (Type::PointerType (ptrSize, idType), " objects" );
1713
+ auto type = finalizeStructureBuilder (m_data, nsConstantDictionaryBuilder, " __NSConstantDictionary" );
1714
+ m_typeNames.nsConstantDictionary = type.first ;
1715
+
1716
+ auto reader = GetReader ();
1717
+ if (auto dicts = GetSectionWithName (" __objc_dictobj" ))
1718
+ {
1719
+ auto start = dicts->GetStart ();
1720
+ auto end = dicts->GetEnd ();
1721
+ auto typeWidth = Type::NamedType (m_data, m_typeNames.nsConstantDictionary )->GetWidth ();
1722
+ m_data->BeginBulkModifySymbols ();
1723
+ for (view_ptr_t i = start; i < end; i += typeWidth)
1724
+ {
1725
+ reader->Seek (i + (ptrSize * 2 ));
1726
+ // TODO: Do we need to do anything with `options`? It appears to always be 1.
1727
+ uint64_t count = reader->ReadPointer ();
1728
+ auto keysLoc = ReadPointerAccountingForRelocations (reader.get ());
1729
+ auto objectsLoc = ReadPointerAccountingForRelocations (reader.get ());
1730
+ DefineObjCSymbol (
1731
+ DataSymbol, Type::ArrayType (idType, count), fmt::format (" nsdict_{:x}_keys" , i), keysLoc, true );
1732
+ DefineObjCSymbol (
1733
+ DataSymbol, Type::ArrayType (idType, count), fmt::format (" nsdict_{:x}_objects" , i), objectsLoc, true );
1734
+ DefineObjCSymbol (DataSymbol, Type::NamedType (m_data, m_typeNames.nsConstantDictionary ),
1735
+ fmt::format (" nsdict_{:x}" , i), i, true );
1736
+ }
1737
+ auto id = m_data->BeginUndoActions ();
1738
+ m_symbolQueue->Process ();
1739
+ m_data->EndBulkModifySymbols ();
1740
+ m_data->ForgetUndoActions (id);
1741
+ }
1742
+ delete m_symbolQueue;
1743
+ }
1744
+
1745
+ void ObjCProcessor::ProcessNSConstantIntegerNumbers ()
1746
+ {
1747
+ m_symbolQueue = new SymbolQueue ();
1748
+ uint64_t ptrSize = m_data->GetAddressSize ();
1749
+
1750
+ StructureBuilder nsConstantIntegerNumberBuilder;
1751
+ nsConstantIntegerNumberBuilder.AddMember (Type::PointerType (ptrSize, Type::VoidType ()), " isa" );
1752
+ nsConstantIntegerNumberBuilder.AddMember (Type::PointerType (ptrSize, Type::IntegerType (1 , true )), " encoding" );
1753
+ nsConstantIntegerNumberBuilder.AddMember (Type::IntegerType (ptrSize, true ), " value" );
1754
+ auto type = finalizeStructureBuilder (m_data, nsConstantIntegerNumberBuilder, " __NSConstantIntegerNumber" );
1755
+ m_typeNames.nsConstantIntegerNumber = type.first ;
1756
+
1757
+ auto reader = GetReader ();
1758
+ if (auto numbers = GetSectionWithName (" __objc_intobj" ))
1759
+ {
1760
+ auto start = numbers->GetStart ();
1761
+ auto end = numbers->GetEnd ();
1762
+ auto typeWidth = Type::NamedType (m_data, m_typeNames.nsConstantIntegerNumber )->GetWidth ();
1763
+ m_data->BeginBulkModifySymbols ();
1764
+ for (view_ptr_t i = start; i < end; i += typeWidth)
1765
+ {
1766
+ reader->Seek (i + ptrSize);
1767
+ uint64_t encodingLoc = ReadPointerAccountingForRelocations (reader.get ());
1768
+ uint64_t value = reader->Read64 ();
1769
+ reader->Seek (encodingLoc);
1770
+ uint8_t encoding = reader->Read8 ();
1771
+
1772
+ switch (encoding)
1773
+ {
1774
+ case ' c' :
1775
+ case ' s' :
1776
+ case ' i' :
1777
+ case ' l' :
1778
+ case ' q' :
1779
+ DefineObjCSymbol (DataSymbol, Type::NamedType (m_data, m_typeNames.nsConstantIntegerNumber ),
1780
+ fmt::format (" nsint_{:x}_{}" , i, (int64_t )value), i, true );
1781
+ break ;
1782
+ case ' C' :
1783
+ case ' S' :
1784
+ case ' I' :
1785
+ case ' L' :
1786
+ case ' Q' :
1787
+ DefineObjCSymbol (DataSymbol, Type::NamedType (m_data, m_typeNames.nsConstantIntegerNumber ),
1788
+ fmt::format (" nsint_{:x}_{}" , i, value), i, true );
1789
+ break ;
1790
+ default :
1791
+ m_logger->LogWarn (" Unknown type encoding '%c' in number literal object at %p" , encoding, i);
1792
+ continue ;
1793
+ }
1794
+ }
1795
+ auto id = m_data->BeginUndoActions ();
1796
+ m_symbolQueue->Process ();
1797
+ m_data->EndBulkModifySymbols ();
1798
+ m_data->ForgetUndoActions (id);
1799
+ }
1800
+ delete m_symbolQueue;
1801
+ }
1802
+
1803
+ void ObjCProcessor::ProcessNSConstantFloatingPointNumbers ()
1804
+ {
1805
+ uint64_t ptrSize = m_data->GetAddressSize ();
1806
+
1807
+ StructureBuilder nsConstantFloatNumberBuilder;
1808
+ nsConstantFloatNumberBuilder.AddMember (Type::PointerType (ptrSize, Type::VoidType ()), " isa" );
1809
+ nsConstantFloatNumberBuilder.AddMember (Type::FloatType (4 ), " value" );
1810
+ auto type = finalizeStructureBuilder (m_data, nsConstantFloatNumberBuilder, " __NSConstantFloatNumber" );
1811
+ m_typeNames.nsConstantFloatNumber = type.first ;
1812
+
1813
+ StructureBuilder nsConstantDoubleNumberBuilder;
1814
+ nsConstantDoubleNumberBuilder.AddMember (Type::PointerType (ptrSize, Type::VoidType ()), " isa" );
1815
+ nsConstantDoubleNumberBuilder.AddMember (Type::FloatType (8 ), " value" );
1816
+ type = finalizeStructureBuilder (m_data, nsConstantDoubleNumberBuilder, " __NSConstantDoubleNumber" );
1817
+ m_typeNames.nsConstantDoubleNumber = type.first ;
1818
+
1819
+ StructureBuilder nsConstantDateBuilder;
1820
+ nsConstantDateBuilder.AddMember (Type::PointerType (ptrSize, Type::VoidType ()), " isa" );
1821
+ nsConstantDateBuilder.AddMember (Type::FloatType (8 ), " ti" );
1822
+ type = finalizeStructureBuilder (m_data, nsConstantDateBuilder, " __NSConstantDate" );
1823
+ m_typeNames.nsConstantDate = type.first ;
1824
+
1825
+ enum SectionType
1826
+ {
1827
+ Float,
1828
+ Double,
1829
+ Date,
1830
+ };
1831
+
1832
+ constexpr std::pair<std::string_view, SectionType> sections[] = {
1833
+ {" __objc_floatobj" , Float},
1834
+ {" __objc_doubleobj" , Double},
1835
+ {" __objc_dateobj" , Date},
1836
+ };
1837
+
1838
+ auto reader = GetReader ();
1839
+ for (auto & [sectionName, sectionType] : sections)
1840
+ {
1841
+ auto numbers = GetSectionWithName (sectionName.data ());
1842
+ if (!numbers)
1843
+ continue ;
1844
+
1845
+ m_symbolQueue = new SymbolQueue ();
1846
+ auto start = numbers->GetStart ();
1847
+ auto end = numbers->GetEnd ();
1848
+ auto typeWidth = Type::NamedType (m_data, m_typeNames.nsConstantDoubleNumber )->GetWidth ();
1849
+ m_data->BeginBulkModifySymbols ();
1850
+ for (view_ptr_t i = start; i < end; i += typeWidth)
1851
+ {
1852
+ reader->Seek (i + ptrSize);
1853
+
1854
+ QualifiedName* typeName = nullptr ;
1855
+ std::string name;
1856
+
1857
+ switch (sectionType)
1858
+ {
1859
+ case Float:
1860
+ {
1861
+ float value = 0 ;
1862
+ reader->Read (&value, sizeof (value));
1863
+ name = fmt::format (" nsfloat_{:x}_{}" , i, value);
1864
+ typeName = &m_typeNames.nsConstantFloatNumber ;
1865
+ break ;
1866
+ }
1867
+ case Double:
1868
+ {
1869
+ double value = 0 ;
1870
+ reader->Read (&value, sizeof (value));
1871
+ name = fmt::format (" nsdouble_{:x}_{}" , i, value);
1872
+ typeName = &m_typeNames.nsConstantDoubleNumber ;
1873
+ break ;
1874
+ }
1875
+ case Date:
1876
+ {
1877
+ double value = 0 ;
1878
+ reader->Read (&value, sizeof (value));
1879
+ name = fmt::format (" nsdate_{:x}_{}" , i, value);
1880
+ typeName = &m_typeNames.nsConstantDate ;
1881
+ break ;
1882
+ }
1883
+ }
1884
+ DefineObjCSymbol (DataSymbol, Type::NamedType (m_data, *typeName), name, i, true );
1885
+ }
1886
+ auto id = m_data->BeginUndoActions ();
1887
+ m_symbolQueue->Process ();
1888
+ m_data->EndBulkModifySymbols ();
1889
+ m_data->ForgetUndoActions (id);
1890
+ delete m_symbolQueue;
1891
+ }
1892
+ }
1893
+
1894
+ void ObjCProcessor::ProcessNSConstantDatas ()
1895
+ {
1896
+ m_symbolQueue = new SymbolQueue ();
1897
+ uint64_t ptrSize = m_data->GetAddressSize ();
1898
+
1899
+ StructureBuilder nsConstantDataBuilder;
1900
+ nsConstantDataBuilder.AddMember (Type::PointerType (ptrSize, Type::VoidType ()), " isa" );
1901
+ nsConstantDataBuilder.AddMember (Type::IntegerType (ptrSize, false ), " length" );
1902
+ nsConstantDataBuilder.AddMember (Type::PointerType (ptrSize, Type::IntegerType (1 , false )), " bytes" );
1903
+ auto type = finalizeStructureBuilder (m_data, nsConstantDataBuilder, " __NSConstantData" );
1904
+ m_typeNames.nsConstantData = type.first ;
1905
+
1906
+ auto reader = GetReader ();
1907
+ if (auto datas = GetSectionWithName (" __objc_dataobj" ))
1908
+ {
1909
+ auto start = datas->GetStart ();
1910
+ auto end = datas->GetEnd ();
1911
+ auto typeWidth = Type::NamedType (m_data, m_typeNames.nsConstantData )->GetWidth ();
1912
+ m_data->BeginBulkModifySymbols ();
1913
+ for (view_ptr_t i = start; i < end; i += typeWidth)
1914
+ {
1915
+ reader->Seek (i + ptrSize);
1916
+ uint64_t length = reader->ReadPointer ();
1917
+ auto dataLoc = ReadPointerAccountingForRelocations (reader.get ());
1918
+ DefineObjCSymbol (DataSymbol, Type::ArrayType (Type::IntegerType (1 , false ), length),
1919
+ fmt::format (" nsdata_{:x}_data" , i), dataLoc, true );
1920
+ DefineObjCSymbol (
1921
+ DataSymbol, Type::NamedType (m_data, m_typeNames.nsConstantData ), fmt::format (" nsdata_{:x}" , i), i, true );
1922
+ }
1923
+ auto id = m_data->BeginUndoActions ();
1924
+ m_symbolQueue->Process ();
1925
+ m_data->EndBulkModifySymbols ();
1926
+ m_data->ForgetUndoActions (id);
1927
+ }
1928
+ delete m_symbolQueue;
1929
+ }
1930
+
1654
1931
void ObjCProcessor::AddRelocatedPointer (uint64_t location, uint64_t rewrite)
1655
1932
{
1656
1933
m_relocationPointerRewrites[location] = rewrite;
0 commit comments