Skip to content

Commit a8093fc

Browse files
committed
[ObjC] Use NamedTypeReference to refer to id / SEL / BOOL
Rather than introducing duplicate definitions of these types, use a NamedTypeReference that will be resolved to the type from the libobjc type library when it is loaded. This prevents these types from showing up as id_1 / SEL_1 in some places rather than as their expected names.
1 parent 55d3bda commit a8093fc

File tree

2 files changed

+28
-21
lines changed

2 files changed

+28
-21
lines changed

objectivec/objc.cpp

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,13 @@ namespace {
106106
return component;
107107
}
108108

109+
Ref<Type> NamedType(const std::string& name)
110+
{
111+
NamedTypeReferenceBuilder builder;
112+
builder.SetName(QualifiedName(name));
113+
return Type::NamedType(builder.Finalize());
114+
}
115+
109116
} // namespace
110117

111118
Ref<Metadata> ObjCProcessor::SerializeMethod(uint64_t loc, const Method& method)
@@ -320,12 +327,12 @@ std::vector<QualifiedNameOrType> ObjCProcessor::ParseEncodedType(const std::stri
320327
nameOrType.type = Type::PointerType(m_data->GetAddressSize(), Type::IntegerType(1, true));
321328
break;
322329
case '@':
323-
qualifiedName = "id";
330+
nameOrType.type = m_types.id;
324331
// There can be a type after this, like @"NSString", that overrides this
325332
// The handler for " will catch it and drop this "id" entry.
326333
break;
327334
case ':':
328-
qualifiedName = "SEL";
335+
nameOrType.type = m_types.sel;
329336
break;
330337
case '#':
331338
qualifiedName = "objc_class_t";
@@ -1214,11 +1221,11 @@ bool ObjCProcessor::ApplyMethodType(Class& cls, Method& method, bool isInstanceM
12141221

12151222
params.push_back({"self",
12161223
cls.associatedName.IsEmpty() ?
1217-
Type::NamedType(m_data, {"id"}) :
1224+
m_types.id :
12181225
Type::PointerType(m_data->GetAddressSize(), Type::NamedType(m_data, cls.associatedName)),
12191226
true, BinaryNinja::Variable()});
12201227

1221-
params.push_back({"sel", Type::NamedType(m_data, {"SEL"}), true, BinaryNinja::Variable()});
1228+
params.push_back({"sel", m_types.sel, true, BinaryNinja::Variable()});
12221229

12231230
for (size_t i = 3; i < typeTokens.size(); i++)
12241231
{
@@ -1367,6 +1374,10 @@ ObjCProcessor::ObjCProcessor(BinaryView* data, const char* loggerName, bool skip
13671374
m_skipClassBaseProtocols(skipClassBaseProtocols), m_data(data)
13681375
{
13691376
m_logger = m_data->CreateLogger(loggerName);
1377+
1378+
m_types.id = NamedType("id");
1379+
m_types.sel = NamedType("SEL");
1380+
m_types.BOOL = NamedType("BOOL");
13701381
}
13711382

13721383
uint64_t ObjCProcessor::GetObjCRelativeMethodBaseAddress(ObjCReader* reader)
@@ -1384,11 +1395,6 @@ void ObjCProcessor::ProcessObjCData()
13841395
auto guard = ScopedSymbolQueue::Make();
13851396

13861397
auto addrSize = m_data->GetAddressSize();
1387-
1388-
m_typeNames.id = defineTypedef(m_data, {"id"}, Type::PointerType(addrSize, Type::VoidType()));
1389-
m_typeNames.sel = defineTypedef(m_data, {"SEL"}, Type::PointerType(addrSize, Type::IntegerType(1, false)));
1390-
1391-
m_typeNames.BOOL = defineTypedef(m_data, {"BOOL"}, Type::IntegerType(1, false));
13921398
m_typeNames.nsInteger = defineTypedef(m_data, {"NSInteger"}, Type::IntegerType(addrSize, true));
13931399
m_typeNames.nsuInteger = defineTypedef(m_data, {"NSUInteger"}, Type::IntegerType(addrSize, false));
13941400
m_typeNames.cgFloat = defineTypedef(m_data, {"CGFloat"}, Type::FloatType(addrSize));
@@ -1716,11 +1722,10 @@ void ObjCProcessor::ProcessNSConstantArrays()
17161722
auto guard = ScopedSymbolQueue::Make();
17171723
uint64_t ptrSize = m_data->GetAddressSize();
17181724

1719-
auto idType = Type::NamedType(m_data, m_typeNames.id);
17201725
StructureBuilder nsConstantArrayBuilder;
17211726
nsConstantArrayBuilder.AddMember(Type::PointerType(ptrSize, Type::VoidType()), "isa");
17221727
nsConstantArrayBuilder.AddMember(Type::IntegerType(ptrSize, false), "count");
1723-
nsConstantArrayBuilder.AddMember(Type::PointerType(ptrSize, idType), "objects");
1728+
nsConstantArrayBuilder.AddMember(Type::PointerType(ptrSize, m_types.id), "objects");
17241729
auto type = finalizeStructureBuilder(m_data, nsConstantArrayBuilder, "__NSConstantArray");
17251730
m_typeNames.nsConstantArray = type.first;
17261731

@@ -1737,7 +1742,7 @@ void ObjCProcessor::ProcessNSConstantArrays()
17371742
uint64_t count = reader->ReadPointer();
17381743
auto dataLoc = ReadPointerAccountingForRelocations(reader.get());
17391744
DefineObjCSymbol(
1740-
DataSymbol, Type::ArrayType(idType, count), fmt::format("nsarray_{:x}_data", i), dataLoc, true);
1745+
DataSymbol, Type::ArrayType(m_types.id, count), fmt::format("nsarray_{:x}_data", i), dataLoc, true);
17411746
DefineObjCSymbol(DataSymbol, Type::NamedType(m_data, m_typeNames.nsConstantArray),
17421747
fmt::format("nsarray_{:x}", i), i, true);
17431748
}
@@ -1754,13 +1759,12 @@ void ObjCProcessor::ProcessNSConstantDictionaries()
17541759
auto guard = ScopedSymbolQueue::Make();
17551760
uint64_t ptrSize = m_data->GetAddressSize();
17561761

1757-
auto idType = Type::NamedType(m_data, m_typeNames.id);
17581762
StructureBuilder nsConstantDictionaryBuilder;
17591763
nsConstantDictionaryBuilder.AddMember(Type::PointerType(ptrSize, Type::VoidType()), "isa");
17601764
nsConstantDictionaryBuilder.AddMember(Type::IntegerType(ptrSize, false), "options");
17611765
nsConstantDictionaryBuilder.AddMember(Type::IntegerType(ptrSize, false), "count");
1762-
nsConstantDictionaryBuilder.AddMember(Type::PointerType(ptrSize, idType), "keys");
1763-
nsConstantDictionaryBuilder.AddMember(Type::PointerType(ptrSize, idType), "objects");
1766+
nsConstantDictionaryBuilder.AddMember(Type::PointerType(ptrSize, m_types.id), "keys");
1767+
nsConstantDictionaryBuilder.AddMember(Type::PointerType(ptrSize, m_types.id), "objects");
17641768
auto type = finalizeStructureBuilder(m_data, nsConstantDictionaryBuilder, "__NSConstantDictionary");
17651769
m_typeNames.nsConstantDictionary = type.first;
17661770

@@ -1779,9 +1783,9 @@ void ObjCProcessor::ProcessNSConstantDictionaries()
17791783
auto keysLoc = ReadPointerAccountingForRelocations(reader.get());
17801784
auto objectsLoc = ReadPointerAccountingForRelocations(reader.get());
17811785
DefineObjCSymbol(
1782-
DataSymbol, Type::ArrayType(idType, count), fmt::format("nsdict_{:x}_keys", i), keysLoc, true);
1783-
DefineObjCSymbol(
1784-
DataSymbol, Type::ArrayType(idType, count), fmt::format("nsdict_{:x}_objects", i), objectsLoc, true);
1786+
DataSymbol, Type::ArrayType(m_types.id, count), fmt::format("nsdict_{:x}_keys", i), keysLoc, true);
1787+
DefineObjCSymbol(DataSymbol, Type::ArrayType(m_types.id, count), fmt::format("nsdict_{:x}_objects", i),
1788+
objectsLoc, true);
17851789
DefineObjCSymbol(DataSymbol, Type::NamedType(m_data, m_typeNames.nsConstantDictionary),
17861790
fmt::format("nsdict_{:x}", i), i, true);
17871791
}

objectivec/objc.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,12 @@ namespace BinaryNinja {
252252

253253
class ObjCProcessor {
254254
struct Types {
255-
QualifiedName id;
256-
QualifiedName sel;
257-
QualifiedName BOOL;
255+
Ref<Type> id;
256+
Ref<Type> sel;
257+
Ref<Type> BOOL;
258+
} m_types;
259+
260+
struct TypeNames {
258261
QualifiedName nsInteger;
259262
QualifiedName nsuInteger;
260263
QualifiedName cgFloat;

0 commit comments

Comments
 (0)