我已经看到,在libc.so中,要调用的实际strcmp_sse类型是由函数strcmp本身决定的。
这是代码:
strcmp:
.text:000000000007B9F0 cmp cs:__cpu_features.kind, 0
.text:000000000007B9F7 jnz short loc_7B9FE
.text:000000000007B9F9 call __init_cpu_features
.text:000000000007B9FE
.text:000000000007B9FE loc_7B9FE: ; CODE XREF: .text:000000000007B9F7j
.text:000000000007B9FE lea rax, __strcmp_sse2_unaligned
.text:000000000007BA05 test cs:__cpu_features.cpuid._eax, 10h
.text:000000000007BA0F jnz short locret_7BA2B
.text:000000000007BA11 lea rax, __strcmp_ssse3
.text:000000000007BA18 test cs:__cpu_features.cpuid._ecx, 200h
.text:000000000007BA22 jnz short locret_7BA2B
.text:000000000007BA24 lea rax, __strcmp_sse2
.text:000000000007BA2B
.text:000000000007BA2B locret_7BA2B: ; CODE XREF: .text:000000000007BA0Fj
.text:000000000007BA2B ; .text:000000000007BA22j
.text:000000000007BA2B retn我不明白的是,要调用的strcmp_sse函数的地址被放置在rax中,并且从未真正调用。因此,我想知道:谁会打电话*rax?什么时候?
发布于 2015-06-02 20:06:57
linker支持名为IFUNC的特殊符号类型。Strcmp很可能是作为IFUNC实现的。动态库中的“‘Regular”符号只不过是从名称到地址的映射。IFUNCs比这要复杂一点:地址并不容易获得,为了获得地址,链接器必须从库本身执行一段代码。我们在这里看到了这样一个代码的例子。注意,在x86_64中,一个函数返回RAX中的结果。
这种技术通常用于根据CPU特性选择最佳实现。请注意,选择逻辑只运行一次;除了第一次对strcmp的调用外,所有调用都是快速的。
https://stackoverflow.com/questions/30604987
复制相似问题