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