获取被覆盖的弱符号的地址

Getting the address of a overwritten weak symbol

我的问题假设 gcc 或 clang 用于 x86 或 x86_64。

假设我有以下文件:

// weak.c

#include <stdio.h>

__attribute__((weak))
void i_am_weak(void)
{
    printf("I am weak\n");
}

int main()
{
    i_am_weak();
    return 0;
}
// not_weak.c

#include <stdio.h>

void i_am_weak(void)
{
    printf("I am not weak\n");
}

如果我只编译 weak.c: cc weak.c -o weak 然后我 运行 它我得到消息“我很虚弱”。反过来,如果我编译和 link 两者: cc weak.c not_weak.c 我得到消息“我不弱”。这是意料之中的事。

我能以某种方式获得弱符号的地址吗?假设我想从 not_weak.cweak.c 调用 i_am_weak,类似于我在使用 --wrap 时从 __wrap_i_am_weak 使用 __real_i_am_weak 的方式linker 标志。

Can I somehow obtain the address of the weak symbol?

通常的技术是使用强内部符号,i_am_weak 是弱别名 (documentation):

#include <stdio.h>

void i_am_internal(void)
{
    printf("I am weak\n");
}

void i_am_weak(void) __attribute__((weak, alias("i_am_internal"))) 

int main()
{
    i_am_weak();
    i_am_internal();
    return 0;
}
$ gcc weak.c && ./a.out
I am weak
I am weak

$ gcc weak.c not_weak.c && ./a.out
I am not weak
I am weak

您现在还可以获取弱符号和 non-weak 符号的地址。