有没有一种方法可以使用GNU binutils取消隐藏可见符号?

3
我正在编写一个脚本,使得uClibc可在现有的glibc目标gcc/binutils工具链上使用。但是,我遇到的唯一问题是pthread_cancel需要dlopen libgcc_s.so.1。主机gcc提供的版本与glibc相关联,因此我使用ld-u选项从libgcc_eh.a中提取所需的符号(及其依赖项),以制作替换的libgcc_s.so.1
gcc -specs uclibc.specs -Wl,-u,_Unwind_Resume -Wl,-u,__gcc_personality_v0 \
    -Wl,-u,_Unwind_ForcedUnwind -Wl,-u,_Unwind_GetCFA -shared -o libgcc_s.so.1

原则上来说,我的工作已经完成了,但是在libgcc_eh.a中的所有符号都被设置为隐藏状态,因此在输出的.so文件中,它们都变成了本地符号,并没有添加到.dynsym符号表中。
我正在寻找一种使用binutils(可能是objcopy?或者是一个链接脚本?)的方法,无论是在.so文件上还是在libgcc_eh.a中的原始.o文件上,将这些符号取消隐藏。这是可能的吗?
2个回答

4

objcopy 没有这个功能,但是你可以使用 ELFkickers 的 rebind 工具 来实现:

rebind --visibility default file.o SYMBOLS...

这必须在原始的.o文件上完成。如果您尝试在.so上进行,那么为时已晚,因为隐藏符号将从.dynsym部分中省略。


1

我认为你应该能够在objcopy中使用--globalize-symbol

例如:

$ nm /usr/lib/gcc/i686-redhat-linux/4.6.3/libgcc_eh.a | grep emutls_alloc
00000000 t emutls_alloc $ objcopy --globalize-symbol=emutls_alloc /usr/lib/gcc/i686-redhat-linux/4.6.3/libgcc_eh.a /tmp/libgcc_eh.a $ nm /tmp/libgcc_eh.a |grep emutls_alloc 00000000 T emutls_alloc

您可以多次向objcopy提供--globalize-symbol,但需要明确提及您想要全局化的所有符号的完整名称。

虽然我不确定将libgcc_eh.a转换为共享对象可能会出现什么问题,因为libgcc_eh.a可能是没有使用-fpic/-fPIC编译的。 结果发现libgcc_eh.a是作为位置无关代码编译的。


假定libgcc_eh.a中的目标文件应该可用于PIC共享库或PIE可执行文件,因为当未使用共享libgcc_s.so时,它会被拉入其中,但我可能是错的。无论如何,在允许textrels的i386上至少可以工作。 - R.. GitHub STOP HELPING ICE
刚刚看到你的编辑。我仍然留下我的评论,因为我认为它解释了为什么代码会被编译为PIC。 - R.. GitHub STOP HELPING ICE
1
不幸的是,“--globalize-symbol”只能改变全局/本地状态。据我所知,objcopy没有更改默认/隐藏状态的选项。 - mhsmith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接