OpenWatcom是否支持ELF弱符号等效机制?对应语法是什么?
OpenWatcom C 弱符号替代方案及符号处理问题
需求场景:GCC下的弱符号实现
通过GCC的弱符号特性,可以实现函数的可选替换:编译时是否引入额外源文件,决定执行简单版或复杂版函数逻辑。
实现代码
/* w1.c */ #include <stdio.h> __attribute__((weak)) void fw(void) { printf("FW1\n"); } int main(int argc, char **argv) { (void)argc; (void)argv; fw(); return 0; }
/* w2.c */ #include <stdio.h> void fw(void) { printf("FW2\n"); }
GCC编译运行效果
$ gcc -s -O2 -o prog1 w1.c $ ./prog1 FW1 $ gcc -s -O2 -o prog12 w1.c w2.c $ ./prog12 FW2
原理是:w1.c中的fw是弱符号,当存在同名非弱符号(w2.c中的fw)时,弱符号会被忽略,从而自动替换函数实现。
核心问题
需要用OpenWatcom的owcc替代GCC实现上述编译效果,但直接去掉__attribute__((weak))会导致链接阶段因符号重复失败。请问:
- OpenWatcom是否支持类似弱符号的机制?
- 替代
__attribute__((weak))的语法或编译参数是什么?
尝试过的Common符号方案(未成功)
尝试用Common符号实现类似逻辑,代码如下:
实现代码
/* w1o.c */ #include <stdio.h> void (*fwptr)(void); static void fw1(void) { printf("FW1\n"); } int main(int argc, char **argv) { (void)argc; (void)argv; (fwptr ? fwptr : fw1)(); return 0; }
/* w2o.c */ #include <stdio.h> static void fw2(void) { printf("FW2\n"); } void (*fwptr)(void) = fw2;
GCC下的运行效果
$ gcc -s -O2 -o prog1o w1o.c $ ./prog1o FW1 $ gcc -s -O2 -o prog12o w1o.c w2o.c $ ./prog12o FW2
OpenWatcom下的问题
$ owcc -s -O2 -o prog1o w1o.c $ ./prog1o FW1 $ owcc -s -O2 -o prog12o w1o.c w2o.c Warning! W1027: file w2o.o(/tmp/w2o.c): redefinition of _fwptr ignored $ ./prog12o FW1
OpenWatcom不允许重复定义符号,直接忽略了w2o.c中的fwptr定义,无法实现函数替换效果。
GCC与OpenWatcom的Common符号处理差异
为对比符号处理逻辑,使用以下测试代码:
/* symbol.c */ int sym0 = 0; int sym1 = 1; int sym2; extern int sym3; int func() { return sym0 + sym1 + sym2 + sym3; }
GCC编译后的符号情况
用readelf查看目标文件:
$ gcc -fno-pic -m32 -Os -c -o symbol.o symbol.c $ readelf -a symbol.o ... Num: Value Size Type Bind Vis Ndx Name ... 8: 00000000 28 FUNC GLOBAL DEFAULT 1 func 9: 00000000 4 OBJECT GLOBAL DEFAULT 3 sym1 10: 00000000 4 OBJECT GLOBAL DEFAULT 4 sym0 11: 00000004 4 OBJECT GLOBAL DEFAULT COM sym2 12: 00000000 0 NOTYPE GLOBAL DEFAULT UND sym3
其中sym2是Common符号,链接时可被其他定义替代。
OpenWatcom编译后的符号情况
用dmpobj查看目标文件:
- sym0: EXTDEF (type 0), PUBDEF386 (type 0), LEDATA386: 4 bytes in segment _DATA
- sym1: EXTDEF (type 0), PUBDEF386 (type 0), LEDATA386: 4 bytes in segment _DATA
- sym2: EXTDEF (type 0), PUBDEF386 (type 0), 4 bytes in segment _BSS
- sym3: EXTDEF (type 0), no PUBDEF386, no definition in _DATA or _BSS
OpenWatcom将未初始化的全局变量sym2视为普通BSS段符号,而非Common符号,因此无法被其他定义覆盖。
内容的提问来源于stack exchange,提问作者pts
相关产品推荐
相关产品推荐

