紧跟 swift-类结构源码探寻(一),继续 TargetClassDescriptor分析


TargetClassDescriptor 中包含了超长的基类描述,超多的using
我们分析主干思路,重在检索数据结构,暂时无关的信息暂时忽略掉
先从 TargetClassDescriptor 属性信息 整理
TargetClassDescriptor {
var SuperclassType: TargetRelativeDirectPointer // Int32
var MetadataNegativeSizeInWords: uint32_t
var MetadataPositiveSizeInWords: uint32_t
var NumImmediateMembers: uint32_t
var NumFields: uint32_t
var FieldOffsetVectorOffset: uint32_t
}
TargetTypeContextDescriptor {
var Name: TargetRelativeDirectPointer // Int32
var AccessFunctionPtr: TargetRelativeDirectPointer // Int32
var Fields: TargetRelativeDirectPointer // Int32
}
TargetContextDescriptor {
var Flags: ContextDescriptorFlags // uint32
var Parent: TargetRelativeContextPointer // Int32
}
汇总
TargetClassDescriptor {
var Flags: ContextDescriptorFlags // uint32
var Parent: TargetRelativeContextPointer // Int32
var Name: TargetRelativeDirectPointer // Int32
var AccessFunctionPtr: TargetRelativeDirectPointer // Int32
var Fields: TargetRelativeDirectPointer // Int32
var SuperclassType: TargetRelativeDirectPointer // Int32
var MetadataNegativeSizeInWords: uint32_t
var MetadataPositiveSizeInWords: uint32_t
var NumImmediateMembers: uint32_t
var NumFields: uint32_t
var FieldOffsetVectorOffset: uint32_t
}
注意FieldOffsetVectorOffset 注释信息

结合 探寻(一) 关于 Description: TargetClassDescriptor 越界描述
大概意思是 偏移出 metadata结构 之外,还存在的一些信息
接下来就是 进一步分析偏移出 metadata结构 之外的信息了, 既然提到了vector,不妨看下 探寻(一) 中生成的sil文件
既然暂时线性逻辑分析 遇到阻碍,进一步猜想,根据前面的 FieldOffsetVectorOffset 注释说明,需要找到 Descriptor 结构之后的偏移数据
跳转到 sil

继续在 Metadata.h 中搜索vtable 关键字

发现了 vtable判断逻辑,有vtable的条件下,获取trailingObjects, 说白了 就是尾部的偏移逻辑了
TargetClassDescriptor 继承父类

其中包含一个 TargetVTableDescriptorHeader,继续分析

这样,跟前面的分析中断处有了 衔接,VtableOffset 与 VtableSize 分别是
TargetClassDescriptor 结构之后的 偏移结构的 offset 与 偏移结构大小
继续补充结构
TargetClassDescriptor {
var Flags: ContextDescriptorFlags // uint32
var Parent: TargetRelativeContextPointer // Int32
var Name: TargetRelativeDirectPointer // Int32
var AccessFunctionPtr: TargetRelativeDirectPointer // Int32
var Fields: TargetRelativeDirectPointer // Int32
var SuperclassType: TargetRelativeDirectPointer // Int32
var MetadataNegativeSizeInWords: uint32_t
var MetadataPositiveSizeInWords: uint32_t
var NumImmediateMembers: uint32_t
var NumFields: uint32_t
var FieldOffsetVectorOffset: uint32_t
var VTableOffset: uint32_t
var VTableSize: uint32_t
// ......... VTable部分
}
Metadata 结构基本梳理完
swift oc 兼容缘由

注释很明确,所有堆开辟类型的元数据 通用结构 -- TargetHeapMetadata
全局搜索 HeapMetadata, 其中慢慢筛选过滤, HeapObject.h 中有包含 HeapMetadata 属性



struct HeapObject {
var metadata: HeapMetadata // UnsafeRawPointer 8字节
var refCount1 // UInt32
var refCount2 // UInt32
}
验证HeapObject结构



阅读vtable部分源码
全局搜索 VTableOffset
好在 结果不多,方便筛选
筛选掉明显不需要花精力阅读的文件及sil文件,锁定两个文件 GenMeta.cpp 与 MedataLayout.cpp 两个文件
先通过 MedataLayout.cpp 中查看
找到 addVTableEntries
在GenMeta.cpp 中搜索结果定位的位置 发现关键字 VTableEntries

在 GenMeta.cpp 中搜索 addVTableEntries, 找到了调用

目光之余 发现了 addVTable()
通过继承关系,找到父类 layout()

通过跋涉,终于看到了直给的东西
正好对应 前面整理的结构

addVTable 逻辑

正好对应 TargetClassDescriptor结构最后部分
var VTableOffset: uint32_t
var VTableSize: uint32_t
// ......... VTable部分
复习MachO验证
回想swift-类结构源码探寻(一)中的验证部分逻辑

这里存放的就是 clsss/struct/enumor descriptor的内存地址信息
0x7ABC + 0xFFFFFB80 = 0x10000763C
0x10000763C - 虚拟基址0x100000000 = 0x763C

通过这里 结合 Descriptor 结构信息 进行地址偏移,偏移13个4字节

0x7670 就是VTable部分

其中 0x7670 基址开始的第一个4字节为 method描述 Flags
0x7670 + 0x4 + offset(0xFFFFC4D0) - 虚拟基址0x100000000 + ALSR = 方法内存地址
网友评论