【问题标题】:Is it possible to link against .symtab table symbols in an executable file?是否可以链接到可执行文件中的 .symtab 表符号?
【发布时间】:2020-05-02 16:59:21
【问题描述】:

在main.c下面给出:

#include <stdio.h>

void test()
{
  printf("test()\n");
}

int main() {
  test();
  return 0;
}

执行以下命令:

clang-10 main.c -o main
readelf -s main

插入输出复制到这里:

Symbol table '.dynsym' contains 4 entries:
... ignore ...

Symbol table '.symtab' contains 62 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
   61: 00000000004004f0    23 FUNC    GLOBAL DEFAULT   13 test

问题:

  1. 其他可重定位(目标文件或静态库)或共享库或可执行文件是否可以使用/链接/访问 .symtab 表中的 test 符号?

注意:感谢您查看问题,这个问题仅用于教育目的,我没有遇到这个问题。

编辑: 导出可执行动态表中的test符号:

clang-10 main.c -Wl,--dynamic-list=symbols.txt -fPIC -o main

symbols.txt:
{
    test;
};

test 符号显示在 .dymsym 表中。

从下面的源文件(shared.c)构建另一个共享库,依赖于上面的可执行文件ma​​in

extern void test();

void share() {
  test();
}

构建命令:

clang-10 shared.c main -fPIC -shared -o libShared.so

但是,构建失败并给出以下错误消息:

main: In function `_fini':
(.fini+0x0): multiple definition of `_fini'
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/crti.o:(.fini+0x0): first defined here
main: In function `data_start':
(.data+0x8): multiple definition of `__dso_handle'
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/crtbeginS.o:(.data.rel.local+0x0): first defined here
main: In function `_init':
(.init+0x0): multiple definition of `_init'
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/crti.o:(.init+0x0): first defined here
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/crtendS.o:(.tm_clone_table+0x0): multiple definition of `__TMC_END__'
main:(.data+0x10): first defined here
/usr/bin/ld: error in main(.eh_frame); no .eh_frame_hdr table will be created.

【问题讨论】:

    标签: c linker elf


    【解决方案1】:

    有没有可能

    没有。

    用于其他可重定位(目标文件或静态库)

    这部分问题没有意义:链接.o文件对.symtab产生什么

    如果您的意思是,将额外的foo.o 链接到现有的可执行文件,答案是否定的:ELF 链接器考虑可执行文件final。重建可执行文件所需的大部分信息在链接后被丢弃,如果没有这些信息,将可执行文件拆分并添加新代码再次重建它几乎是不可能的。

    有一个链接器(在 AIX 上)允许这种拆分和重建,但它不使用 ELF 格式。

    或共享库

    否:动态链接器不能使用.symtab。它是动态符号表中要导出的符号。

    可以使用-Wl,--export-dynamic 标志构建您的可执行文件,然后该函数将出现在.dynsym 中并可供其他共享库使用。

    或可执行文件以使用/链接/访问 .symtab 表中的测试符号?

    将一个可执行文件链接到另一个可执行文件意味着什么? 它们不能同时运行在同一个进程中(除非其中一个是与位置无关的可执行文件,这实际上是一种特殊形式的共享库)。

    更新:

    clang-10 shared.c main -fPIC -shared -o libShared.so

    就像我之前说的,你不要链接到main 可执行文件。

    您要查找的命令是:

    clang-10 shared.c -fPIC -shared -o libShared.so
    

    这是因为共享库(默认情况下)允许有未解析的符号。

    【讨论】:

    • 非常感谢您的回答。您很清楚地解释了可执行文件 .symtab 中的符号在链接编辑期间无法使用。我会看看建议的-Wl,--export-dynamic 标志。
    • 我已成功将 text 符号导出到可执行文件的 .dynsym 表中,但我无法构建另一个依赖于该可执行文件的共享库.我在问题的编辑部分添加了我的构建步骤。请您给一些建议如何解决它,好吗?非常感谢。它们可以通过删除 .eh_frame 部分来修复,我不确定这是否是修复它的正确方法。
    • 我怀疑我必须使用 dlopen 在运行时加载可执行文件才能使用 test 符号。
    • 再次感谢。可重定位(对象/静态库)和共享对象都允许有未定义的符号,这是一个正常的编译过程。此问题帖子的目的是针对可执行文件的 .dymsym 表中的公开符号进行链接。
    • @ZhongkunMa 你的问题的答案是“不”。
    猜你喜欢
    • 1970-01-01
    • 2018-10-21
    • 1970-01-01
    • 2016-10-06
    • 2018-01-11
    • 2017-07-03
    • 2010-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多