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