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

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

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

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

#include 

/* Do some thing. */
int __foo() {
    puts(”I do no thing.”);
}

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

weak 和 alias 分别是两个属性。weak 使得 foo 这个符号在目标文件中作为 weak symbol 而不是 global symbol。用
nm 命令查看编译 dummy.c 生成的目标文件可用看到 foo 是一个 weak symbol,它前面的标记是 W。

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 的 weak alias 别名
socket
。实际完成工作的代码通过汇编来实现,在另外的汇编文件里面会有设置系统调用号,执行
sysenter 或者 int 等动作去请求系统调用。以前看 glibc 里面系统调用的实现的时候郁闷过很久,就是那个时候才知道了 weak alias 这个东西。

weak alias的更多相关文章

  1. __attribute__((weak, alias())))

    参考gcc的reference: 弱符号: 若两个或两个以上全局符号(函数或变量名)名字一样,而其中之一声明为weak symbol(弱符号),则这些全局符号不会引发重定义错误.链接器会忽略弱符号,去 ...

  2. weak和alias

    一.强符号和弱符号 在C语言中,如果多个模块定义同名全局符号时,链接器认为函数和已初始化的全局变量(包括显示初始化为0)是强符号,未初始化的全局变量是弱符号. 根据这个定义,Linux链接器使用下面的 ...

  3. 弱符号__attribute__((weak))

    弱符号是什么? 弱符号: 若两个或两个以上全局符号(函数或变量名)名字一样,而其中之一声明为weak symbol(弱符号),则这些全局符号不会引发重定义错误.链接器会忽略弱符号,去使用普通的全局符号 ...

  4. u-boot移植 III

    延续上一篇, 烧录完成后, 串口屁毛都没有了, 运行了代码比较工具, 看看问题在哪. board/100ask24x0/   没有问题, 除了lowlevel_init.S, 不过我没在uboot中用 ...

  5. 5.24 Declaring Attributes of Functions【转】

    转自:https://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html 5.24 Declaring Attributes o ...

  6. 特殊的attribute机制

    __attribute__机制是GNU C的一大特色,可以用来设置函数,变量和数据类型的属性,下面对工作中正好用到的两个属性做下简单介绍. 1. constructor 这个属性指定函数在main函数 ...

  7. S5P4418 uboot 分析

    瘋耔新浪微博:   http://weibo.com/cpjphone 一: 1◑ 从链接脚本文件u-boot.lds('/opt/4418-source/android/u-boot' )中可以找到 ...

  8. syscall 中断号

    #ifndef __ASM_ARM_UNISTD_H #define __ASM_ARM_UNISTD_H #define __NR_OABI_SYSCALL_BASE 0x900000 #if de ...

  9. 在U-boot中添加以太网驱动

    当定义CONFIG_CMD_NET和CONFIG_CMD_PING,编译之后执行ping命令,告警没有找到以太网. 因此,需要打开U-boot的网络功能, u-boot-sunxi-sunxi中没有找 ...

随机推荐

  1. win10下端口被占用解决办法

    调试socket通信的时候,如果程序未正常结束,重新启动会报端口被占用的错误. 一 查找被占用的端口 解决办法如下:按win+R输入cmd打开控制台,输入 netstat -ano|findstr 8 ...

  2. word文字覆盖问题

    我们在编写word文档时,偶尔会遇到这个问题: 在一个段落中的某个位置修改文字时,直接就把后面的字体给覆盖了,导致后面的句子也不完整了. 解决经过: 之前遇到这种情况,非常恼火,直接新建一个word文 ...

  3. linux配置上网

    重装系统之后,配置虚拟机的网络问题花了我三个小时,忘记了网关是vmnet8的IP还是DNS了,搞了很久,后来碰运气碰对了. 寄宿机共享的网络是vmnet8,设置IP,DNS,是vmnet8 的IPv4 ...

  4. ABP官方文档翻译 4.2 数据传输对象

    数据传输对象 DTOs的必要性 领域层的抽象 数据隐藏 序列化和懒加载问题 DTO转换和验证 示例 DTOs和实体间的自动映射 辅助接口和类 数据传输对象用来在应用层和展示层之间传输数据. 展示层调用 ...

  5. bzoj 4825: [Hnoi2017]单旋 [lct]

    4825: [Hnoi2017]单旋 题意:有趣的spaly hnoi2017刚出来我就去做,当时这题作死用了ett,调了5节课没做出来然后发现好像直接用lct就行了然后弃掉了... md用lct不知 ...

  6. BZOJ 2707: [SDOI2012]走迷宫 [高斯消元 scc缩点]

    2707: [SDOI2012]走迷宫 题意:求s走到t期望步数,\(n \le 10^4\),保证\(|SCC| \le 100\) 求scc缩点,每个scc高斯消元,scc之间直接DP 注意每次清 ...

  7. BZOJ 1097: [POI2007]旅游景点atr [DP 状压 最短路]

    传送门 题意: 一个无向图,从$1$到$n$,要求必须经过$2,3,...,k+1$,给出一些限制关系,要求在经过$v \le k+1$之前必须经过$u \le k+1$ 求最短路 预处理出$1... ...

  8. Python之CVXOPT模块

      Python中支持Convex Optimization(凸规划)的模块为CVXOPT,其安装方式为: 卸载原Pyhon中的Numpy 安装CVXOPT的whl文件,链接为:https://www ...

  9. 豹哥嵌入式好讲堂:ARM Cortex-M调试过程探析(1)- 4线接口标准(JTAG)

    大家好,我是豹哥,猎豹的豹,犀利哥的哥.今天豹哥给大家讲的是嵌入式调试里的接口标准JTAG. 在结束<ARM Cortex-M开发文件详解>系列文章之后,豹哥修整了一小段时间,但是讲课的心 ...

  10. 如何解决JavaScript中0.1+0.2不等于0.3

    console.log(0.1+0.2===0.3)// true or false?? 在正常的数学逻辑思维中,0.1+0.2=0.3这个逻辑是正确的,但是在JavaScript中0.1+0.2!= ...