【问题标题】:Is there a way to unhide hidden-visibility symbols with GNU binutils?有没有办法用 GNU binutils 取消隐藏隐藏的可见性符号?
【发布时间】:2012-04-30 01:43:12
【问题描述】:

我正在编写一个脚本,以使 uClibc 可以在现有的 glibc 目标 gcc/binutils 工具链上使用,而我剩下的一个问题是 pthread_cancel 需要 dlopen libgcc_s.so.1。主机 gcc 提供的版本链接到依赖 glibc,所以我改为使用 ld-u 选项从 libgcc_eh.a 中提取所需的符号(及其依赖项)以替换 @987654327 @:

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 符号表。

我正在寻找一种在.so 文件或libgcc_eh.a 中的原始.o 文件上使用binutils(可能是objcopy?或链接器脚本?)的方法来取消隐藏这些符号。这可能吗?

【问题讨论】:

    标签: c gcc visibility binutils


    【解决方案1】:

    objcopy 好像没有这个功能,不过你可以用ELFkickers rebind tool 做到:

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

    这必须在原始 .o 文件上完成。如果您尝试在 .so 上执行此操作,则为时已晚,因为 .dynsym 部分中将省略隐藏符号。

    【讨论】:

      【解决方案2】:

      我认为你应该可以在 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 上工作。
      • 刚刚看到您的编辑。留下我的评论,因为我认为它解释了为什么代码被编译为 PIC。
      • 不幸的是,--globalize-symbol 只会更改 GLOBAL/LOCAL 状态。据我所知,objcopy 没有更改默认/隐藏状态的选项。
      猜你喜欢
      • 2016-02-01
      • 1970-01-01
      • 2015-04-01
      • 2013-06-01
      • 2012-05-10
      • 2015-12-11
      • 2021-04-28
      • 2019-01-23
      • 1970-01-01
      相关资源
      最近更新 更多