| 329 | } |
| 330 | |
| 331 | void ObjCProcessor::LoadClasses(ObjCReader* reader, Ref<Section> classPtrSection) |
| 332 | { |
| 333 | if (!classPtrSection) |
| 334 | return; |
| 335 | auto size = classPtrSection->GetEnd() - classPtrSection->GetStart(); |
| 336 | if (size == 0) |
| 337 | return; |
| 338 | auto ptrSize = m_data->GetAddressSize(); |
| 339 | auto ptrCount = size / ptrSize; |
| 340 | |
| 341 | auto classPtrSectionStart = classPtrSection->GetStart(); |
| 342 | for (size_t i = 0; i < ptrCount; i++) |
| 343 | { |
| 344 | Class cls; |
| 345 | |
| 346 | view_ptr_t classPtr; |
| 347 | class_t clsStruct; |
| 348 | class_ro_t classRO; |
| 349 | |
| 350 | bool hasValidMetaClass = false; |
| 351 | bool hasValidMetaClassRO = false; |
| 352 | class_t metaClsStruct; |
| 353 | class_ro_t metaClassRO; |
| 354 | |
| 355 | view_ptr_t classPointerLocation = classPtrSectionStart + (i * m_data->GetAddressSize()); |
| 356 | reader->Seek(classPointerLocation); |
| 357 | |
| 358 | classPtr = ReadPointerAccountingForRelocations(reader); |
| 359 | reader->Seek(classPtr); |
| 360 | try |
| 361 | { |
| 362 | clsStruct.isa = ReadPointerAccountingForRelocations(reader); |
| 363 | clsStruct.super = reader->ReadPointer(); |
| 364 | clsStruct.cache = reader->ReadPointer(); |
| 365 | clsStruct.vtable = reader->ReadPointer(); |
| 366 | clsStruct.data = ReadPointerAccountingForRelocations(reader); |
| 367 | } |
| 368 | catch (...) |
| 369 | { |
| 370 | m_logger->LogError("Failed to read class data at 0x%llx pointed to by @ 0x%llx", reader->GetOffset(), |
| 371 | classPointerLocation); |
| 372 | continue; |
| 373 | } |
| 374 | if (clsStruct.data & 1) |
| 375 | { |
| 376 | m_logger->LogInfo("Skipping class at 0x%llx as it contains swift types", classPtr); |
| 377 | continue; |
| 378 | } |
| 379 | // unset first two bits |
| 380 | view_ptr_t classROPtr = clsStruct.data & ~3; |
| 381 | reader->Seek(classROPtr); |
| 382 | try |
| 383 | { |
| 384 | classRO.flags = reader->Read32(); |
| 385 | classRO.instanceStart = reader->Read32(); |
| 386 | classRO.instanceSize = reader->Read32(); |
| 387 | if (m_data->GetAddressSize() == 8) |
| 388 | classRO.reserved = reader->Read32(); |
nothing calls this directly
no test coverage detected