Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective-C运行时如何检索类和方法列表?_Objective C_Assembly_Objective C Runtime - Fatal编程技术网

Objective-C运行时如何检索类和方法列表?

Objective-C运行时如何检索类和方法列表?,objective-c,assembly,objective-c-runtime,Objective C,Assembly,Objective C Runtime,如果我得到以下Objective-C源文件: // test.m #import <objc/Object.h> @interface MySuperClass: Object { } -(void) myMessage1; @end @implementation MySuperClass -(void) myMessage1 { } @end @interface MyClass: MySuperClass { } -(void) myMessage2; @end

如果我得到以下Objective-C源文件:

// test.m
#import <objc/Object.h>

@interface MySuperClass: Object {

}
-(void) myMessage1;
@end

@implementation MySuperClass
-(void) myMessage1 {

}
@end

@interface MyClass: MySuperClass {

}
-(void) myMessage2;
@end

@implementation MyClass
-(void) myMessage2 {

}
@end

int main() {

    return 0;
}

我的问题是:Objective-C运行时库(必须链接到
test.o
)才能成功创建可执行文件)如何检索方法列表以创建(例如)vtable?是否可以使用
.section…,@function
.section…,@object
.section…,@progbits
汇编指令来获取此信息,至少在链接时间上是这样?

运行时并不知道如何读取程序,但是objc前端必须将代码库转换为使用运行时。

编译器、链接器和运行时协同工作

首先,编译器解析每个类的源代码,并发出指令,如
.long
.zero
.quad
,描述类的实例变量、属性、选择器和方法。汇编程序将这些指令转换为原始数据

数据的格式是运行时可以理解的。例如,从symbol
OBJC\u CLASS\u$\ u MyClass
开始的数据与运行时的
struct CLASS\u t
布局匹配(在中定义)。symbol
l_OBJC\u CLASS\u RO\u$\u MyClass
处的数据与运行时的
struct CLASS\u RO\u t
的布局匹配(尽管大多数字段为0,因为运行时在加载类时会更新它们)。
struct class\u ro\u t
有一个类型为
method\u list\u t*
baseMethods
字段,在
l\u OBJC\u class\u ro\u$\u MyClass
的情况下,该字段被初始化为
l\u OBJC\u$\u INSTANCE\u METHODS\u MyClass
。在
l\u OBJC\u$\u INSTANCE\u METHODS\u MyClass
中,您会发现数据以
struct method\u list\t
的数组结尾,数组中包含
struct method\u t
,类中每个方法对应一个。在您的示例中,这不是很有趣,因为每个类只有一个方法

编译器使用
.section
指令告诉链接器如何将数据块分组在一起。例如,所有的
struct class\u t
块将放在一个名为
\uuujc\u classlist
的部分中。这样,运行时只需查找名为
\uuujc\uclasslist
的节,然后将整个节作为
结构类的数组进行处理。查看中的
GETSECT

链接器安排函数
\u objc\u init
(in)在进程生命周期的早期运行,在
main
之前。
\u objc\u init
函数向动态加载程序注册一些回调。特别是,它告诉加载程序调用
map\u images
(In),它调用
map\u images\u nolock
,它最终调用
\u read\u images
\u read\u images
函数实际上解析了编译器发出的那些数据块,并将它们转换成数据结构,
objc\u msgSend
使用这些数据结构向对象发送消息


了解更多。此归档文件还包含iOS/ARM(甚至Windows!)的源文件,尽管它可能与iOS的任何版本都不完全对应。

是的,您是对的,但上面的汇编代码是编译器为使用objective-c运行时生成的(我想)。它引用了属于Objective-C运行时的符号(
objc\u msgSend\u fixup
\u objc\u empty\u cache
\u objc\u empty\u vtable
)。但是,例如,
objc\u msgSend\u fixup
函数需要获取类的方法,我想这是通过读取可执行文件的特定部分来完成的。所以,我想知道这是什么部分以及如何完成的。我发现
L\u OBJC\u LABEL\u CLASS\u$
标签(在程序集文件的末尾)后面是数组中所有实现的类地址的列表。这可能有用…很好,伙计!这正是我想知道的。非常感谢你!
    .file   "test.m"
    .text
    .align  16, 0x90
    .type   _2D__5B_MySuperClass_20_myMessage1_5D_,@function
_2D__5B_MySuperClass_20_myMessage1_5D_: # @"\01-[MySuperClass myMessage1]"
.Ltmp0:
    .cfi_startproc
# BB#0:
    movq    %rdi, -8(%rsp)
    movq    %rsi, -16(%rsp)
    ret
.Ltmp1:
    .size   _2D__5B_MySuperClass_20_myMessage1_5D_, .Ltmp1-_2D__5B_MySuperClass_20_myMessage1_5D_
.Ltmp2:
    .cfi_endproc
.Leh_func_end0:

    .align  16, 0x90
    .type   _2D__5B_MyClass_20_myMessage2_5D_,@function
_2D__5B_MyClass_20_myMessage2_5D_:      # @"\01-[MyClass myMessage2]"
.Ltmp3:
    .cfi_startproc
# BB#0:
    movq    %rdi, -8(%rsp)
    movq    %rsi, -16(%rsp)
    ret
.Ltmp4:
    .size   _2D__5B_MyClass_20_myMessage2_5D_, .Ltmp4-_2D__5B_MyClass_20_myMessage2_5D_
.Ltmp5:
    .cfi_endproc
.Leh_func_end1:

    .globl  main
    .align  16, 0x90
    .type   main,@function
main:                                   # @main
.Ltmp6:
    .cfi_startproc
# BB#0:
    movl    $0, %eax
    movl    $0, -4(%rsp)
    ret
.Ltmp7:
    .size   main, .Ltmp7-main
.Ltmp8:
    .cfi_endproc
.Leh_func_end2:

    .type   L_OBJC_CLASS_NAME_,@object # @"\01L_OBJC_CLASS_NAME_"
    .section    "__TEXT,__objc_classname,cstring_literals","aw",@progbits
L_OBJC_CLASS_NAME_:
    .asciz   "MySuperClass"
    .size   L_OBJC_CLASS_NAME_, 13

    .type   l_OBJC_METACLASS_RO_$_MySuperClass,@object # @"\01l_OBJC_METACLASS_RO_$_MySuperClass"
    .section    "__DATA, __objc_const","aw",@progbits
    .align  8
l_OBJC_METACLASS_RO_$_MySuperClass:
    .long   1                       # 0x1
    .long   40                      # 0x28
    .long   40                      # 0x28
    .zero   4
    .quad   0
    .quad   L_OBJC_CLASS_NAME_
    .quad   0
    .quad   0
    .quad   0
    .quad   0
    .quad   0
    .size   l_OBJC_METACLASS_RO_$_MySuperClass, 72

    .type   OBJC_METACLASS_$_MySuperClass,@object # @"OBJC_METACLASS_$_MySuperClass"
    .section    "__DATA, __objc_data","aw",@progbits
    .globl  OBJC_METACLASS_$_MySuperClass
    .align  8
OBJC_METACLASS_$_MySuperClass:
    .quad   OBJC_METACLASS_$_Object
    .quad   OBJC_METACLASS_$_Object
    .quad   _objc_empty_cache
    .quad   _objc_empty_vtable
    .quad   l_OBJC_METACLASS_RO_$_MySuperClass
    .size   OBJC_METACLASS_$_MySuperClass, 40

    .type   L_OBJC_METH_VAR_NAME_,@object # @"\01L_OBJC_METH_VAR_NAME_"
    .section    "__TEXT,__objc_methname,cstring_literals","aw",@progbits
L_OBJC_METH_VAR_NAME_:
    .asciz   "myMessage1"
    .size   L_OBJC_METH_VAR_NAME_, 11

    .type   L_OBJC_METH_VAR_TYPE_,@object # @"\01L_OBJC_METH_VAR_TYPE_"
    .section    "__TEXT,__objc_methtype,cstring_literals","aw",@progbits
L_OBJC_METH_VAR_TYPE_:
    .asciz   "v16@0:8"
    .size   L_OBJC_METH_VAR_TYPE_, 8

    .type   l_OBJC_$_INSTANCE_METHODS_MySuperClass,@object # @"\01l_OBJC_$_INSTANCE_METHODS_MySuperClass"
    .section    "__DATA, __objc_const","aw",@progbits
    .align  8
l_OBJC_$_INSTANCE_METHODS_MySuperClass:
    .long   24                      # 0x18
    .long   1                       # 0x1
    .quad   L_OBJC_METH_VAR_NAME_
    .quad   L_OBJC_METH_VAR_TYPE_
    .quad   _2D__5B_MySuperClass_20_myMessage1_5D_
    .size   l_OBJC_$_INSTANCE_METHODS_MySuperClass, 32

    .type   l_OBJC_CLASS_RO_$_MySuperClass,@object # @"\01l_OBJC_CLASS_RO_$_MySuperClass"
    .align  8
l_OBJC_CLASS_RO_$_MySuperClass:
    .long   0                       # 0x0
    .long   8                       # 0x8
    .long   8                       # 0x8
    .zero   4
    .quad   0
    .quad   L_OBJC_CLASS_NAME_
    .quad   l_OBJC_$_INSTANCE_METHODS_MySuperClass
    .quad   0
    .quad   0
    .quad   0
    .quad   0
    .size   l_OBJC_CLASS_RO_$_MySuperClass, 72

    .type   OBJC_CLASS_$_MySuperClass,@object # @"OBJC_CLASS_$_MySuperClass"
    .section    "__DATA, __objc_data","aw",@progbits
    .globl  OBJC_CLASS_$_MySuperClass
    .align  8
OBJC_CLASS_$_MySuperClass:
    .quad   OBJC_METACLASS_$_MySuperClass
    .quad   OBJC_CLASS_$_Object
    .quad   _objc_empty_cache
    .quad   _objc_empty_vtable
    .quad   l_OBJC_CLASS_RO_$_MySuperClass
    .size   OBJC_CLASS_$_MySuperClass, 40

    .type   L_OBJC_CLASS_NAME_1,@object # @"\01L_OBJC_CLASS_NAME_1"
    .section    "__TEXT,__objc_classname,cstring_literals","aw",@progbits
L_OBJC_CLASS_NAME_1:
    .asciz   "MyClass"
    .size   L_OBJC_CLASS_NAME_1, 8

    .type   l_OBJC_METACLASS_RO_$_MyClass,@object # @"\01l_OBJC_METACLASS_RO_$_MyClass"
    .section    "__DATA, __objc_const","aw",@progbits
    .align  8
l_OBJC_METACLASS_RO_$_MyClass:
    .long   1                       # 0x1
    .long   40                      # 0x28
    .long   40                      # 0x28
    .zero   4
    .quad   0
    .quad   L_OBJC_CLASS_NAME_1
    .quad   0
    .quad   0
    .quad   0
    .quad   0
    .quad   0
    .size   l_OBJC_METACLASS_RO_$_MyClass, 72

    .type   OBJC_METACLASS_$_MyClass,@object # @"OBJC_METACLASS_$_MyClass"
    .section    "__DATA, __objc_data","aw",@progbits
    .globl  OBJC_METACLASS_$_MyClass
    .align  8
OBJC_METACLASS_$_MyClass:
    .quad   OBJC_METACLASS_$_Object
    .quad   OBJC_METACLASS_$_MySuperClass
    .quad   _objc_empty_cache
    .quad   _objc_empty_vtable
    .quad   l_OBJC_METACLASS_RO_$_MyClass
    .size   OBJC_METACLASS_$_MyClass, 40

    .type   L_OBJC_METH_VAR_NAME_2,@object # @"\01L_OBJC_METH_VAR_NAME_2"
    .section    "__TEXT,__objc_methname,cstring_literals","aw",@progbits
L_OBJC_METH_VAR_NAME_2:
    .asciz   "myMessage2"
    .size   L_OBJC_METH_VAR_NAME_2, 11

    .type   l_OBJC_$_INSTANCE_METHODS_MyClass,@object # @"\01l_OBJC_$_INSTANCE_METHODS_MyClass"
    .section    "__DATA, __objc_const","aw",@progbits
    .align  8
l_OBJC_$_INSTANCE_METHODS_MyClass:
    .long   24                      # 0x18
    .long   1                       # 0x1
    .quad   L_OBJC_METH_VAR_NAME_2
    .quad   L_OBJC_METH_VAR_TYPE_
    .quad   _2D__5B_MyClass_20_myMessage2_5D_
    .size   l_OBJC_$_INSTANCE_METHODS_MyClass, 32

    .type   l_OBJC_CLASS_RO_$_MyClass,@object # @"\01l_OBJC_CLASS_RO_$_MyClass"
    .align  8
l_OBJC_CLASS_RO_$_MyClass:
    .long   0                       # 0x0
    .long   8                       # 0x8
    .long   8                       # 0x8
    .zero   4
    .quad   0
    .quad   L_OBJC_CLASS_NAME_1
    .quad   l_OBJC_$_INSTANCE_METHODS_MyClass
    .quad   0
    .quad   0
    .quad   0
    .quad   0
    .size   l_OBJC_CLASS_RO_$_MyClass, 72

    .type   OBJC_CLASS_$_MyClass,@object # @"OBJC_CLASS_$_MyClass"
    .section    "__DATA, __objc_data","aw",@progbits
    .globl  OBJC_CLASS_$_MyClass
    .align  8
OBJC_CLASS_$_MyClass:
    .quad   OBJC_METACLASS_$_MyClass
    .quad   OBJC_CLASS_$_MySuperClass
    .quad   _objc_empty_cache
    .quad   _objc_empty_vtable
    .quad   l_OBJC_CLASS_RO_$_MyClass
    .size   OBJC_CLASS_$_MyClass, 40

    .type   L_OBJC_LABEL_CLASS_$,@object # @"\01L_OBJC_LABEL_CLASS_$"
    .section    "__DATA, __objc_classlist, regular, no_dead_strip","aw",@progbits
    .align  8
L_OBJC_LABEL_CLASS_$:
    .quad   OBJC_CLASS_$_MySuperClass
    .quad   OBJC_CLASS_$_MyClass
    .size   L_OBJC_LABEL_CLASS_$, 16

    .type   L_OBJC_IMAGE_INFO,@object # @"\01L_OBJC_IMAGE_INFO"
    .section    "__DATA, __objc_imageinfo, regular, no_dead_strip","a",@progbits
    .align  4
L_OBJC_IMAGE_INFO:
    .long   0                       # 0x0
    .long   16                      # 0x10
    .size   L_OBJC_IMAGE_INFO, 8


    .section    ".note.GNU-stack","",@progbits