测试在 32 位 Linux、x86 上进行。
假设在我的汇编程序final.s
中,我必须加载一些库符号,例如stdin@@GLIBC_2.0
,并且我想加载这些符号在固定地址。
因此请遵循此 question 中的说明,我这样做了:
echo ""stdin@@GLIBC_2.0" = 0x080a7390;" > symbolfile
echo ""stdin@GLIBC_2.0 (4)" = 0x080a7390;" >> symbolfile
gcc -Wl,--just-symbols=symbolfile final.s -g
当我检查符号表的输出时,我得到了这个:
readelf -s a.out | grep stdin
53: 080a7390 4 OBJECT GLOBAL DEFAULT ABS stdin@@GLIBC_2.0
17166: 080a7390 0 NOTYPE GLOBAL DEFAULT ABS stdin@GLIBC_2.0 (4)
与需要 stdin
符号的常见 ELF 二进制文件相比:
readelf -s hello.out | grep stdin
17199: 0838b8c4 4 OBJECT GLOBAL DEFAULT 25 stdin@@GLIBC_2.0
52: 0838b8c4 4 OBJECT GLOBAL DEFAULT 25 stdin@GLIBC_2.0 (4)
所以我发现的一个明显区别是 Ndx
列,比如说,我的固定位置符号的节号是 ABS
。请查看引用文献here .
执行a.out
时,会抛出segmentation failure
错误。
所以我的问题是,如何设置符号固定位置的节号?
最佳答案
I want to load these symbols in a fixed address.
您正在从 GLIBC 导入这些符号。除非您正在进行完全静态链接,否则您无法确定这些符号最终到达的地址。
So my question is, how to set the section number of the symbol
这个问题毫无意义:节号本身毫无意义,并且 25
可能引用一个可执行文件中的 .bss
,但引用 .text
在另一个中。
您的部分25
恰好是.bss
在这个特定的系统上并且对于这个特定的构建。尝试构建一个完全静态的二进制文件,您可能会看到 24
部分。
无论如何,普通的可执行文件都会从libc.so.6
复制stdin
。你会很好地阅读this description过程的一部分,并特别注意“额外积分#2:从可执行文件引用共享库数据”部分。
但首先理解完全静态的情况可能会更容易。
关于c - 编译ELF二进制时如何设置符号的节号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28388133/