Weak Alias

Weak Alias 跟 Weak Reference 完全没有任何关系,不过是我在看到 Weak Reference的时候想到的而已。

Weak Alias 是 gcc扩展里的东西,实际上是函数的属性。这个东西在库的实现里面可能会经常用到,比如 glibc 里面就用了不少。抄录一段gcc 手册里面的话解释下函数属性是干啥的,

In GNU C, you declare certain things about functions called inyour program which help the compiler optimize function calls andcheck your code more carefully.

先上代码,看看 weak alias 怎么写。第一个文件 dummy.c 内容,

#include 


int __foo() {
    puts(”I do no thing.”);
}

int foo() __attribute__ ((weak, alias(”__foo”)));

weak 和 alias 分别是两个属性。weak使得 foo 这个符号在目标文件中作为 weaksymbol 而不是 global symbol。用 nm 命令查看编译 dummy.c 生成的目标文件可用看到 foo 是一个 weak symbol,它前面的标记是 W。给函数加上weak属性时,即使函数没定义,函数被调用也可以编译成功。

00000000 T __foo
00000000 W foo
         U puts

而 alias 则使 foo__foo 的一个别名,__foo 和foo 必须在同一个编译单元中定义,否则会编译出错。

那么这个东西的用处是?

看第二个文件,func.c,

#include 

int foo() {
    puts(”I do something.”);
}

这里有一个函数名字是 foo如果我们编译 func.c 和 dummy.c 得到两个目标文件,当我们同时使用 func.o 和 dummy.o和其他目标文件进行链接时,如果其他目标文件里面引用符号 foo,最终使用到的是 func.c 中定义的函数,而不是 __foo,虽然它有一个别名 foo也就是说,我们最终使用到的函数会是“实际做事”的那个函数。当然,单独使用dummy.o 链接的话使用的是那个“不做事”的函数如果 dummy.o 中的foo 不是 weak symbol的话,在链接时会产生冲突,这就是我们要使用 weak 的原因

glibc 的实现里面经常用 weak alias。比如它的 socket 函数,在 C 文件里面你会看到一个 __socket 函数,它几乎什么都没有做,只是设置了一些错误代码,返回些东西而已。在同一个C 文件里面会再声明一个 __socket 的 weakalias 别名 socket。实际完成工作的代码通过汇编来实现,在另外的汇编文件里面会有设置系统调用号,执行sysenter 或者 int 等动作去请求系统调用。以前看 glibc里面系统调用的实现的时候郁闷过很久,就是那个时候才知道了 weak alias 这个东西。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值