如何将库定义的符号加载到指定的位置?

测试在Ubuntu 12.04,32位, gcc 4.6.3。

基本上我正在对ELF二进制文件进行一些二进制操作工作,我现在要做的是组装一个汇编程序并保证libc符号被我加载到预定义的地址。

让我在一个简单的例子中详细说明。

假设在原始代码中使用了libc符号stdout@GLIBC_2.0

 #include  int main() { FILE* fout = stdout; fprintf( fout, "hello\n" ); } 

当我编译它并使用以下命令检查符号地址时:

 gcc main.c readelf -s a.out | grep stdout 

我懂了:

 0804a020 4 OBJECT GLOBAL DEFAULT 25 stdout@GLIBC_2.0 (2) 0804a020 4 OBJECT GLOBAL DEFAULT 25 stdout@@GLIBC_2.0 

.bss部分是这样的:

  readelf -S a.out | grep bss [25] .bss NOBITS 0804a020 001014 00000c 00 WA 0 0 32 

现在我要做的是将stdout符号加载到预定义的地址中,所以我这样做了:

 echo "stdout = 0x804a024;" > symbolfile gcc -Wl,--just-symbols=symbolfile main.c 

然后,当我检查.bss部分和符号stdout ,我得到了这个:

  [25] .bss NOBITS 0804a014 001014 000008 00 WA 0 0 4 4: 0804a024 0 NOTYPE GLOBAL DEFAULT ABS stdout 49: 0804a024 0 NOTYPE GLOBAL DEFAULT ABS stdout 
  1. 似乎我没有成功加载符号stdout@@GLIBC_2.0 ,而只是一个有线stdout 。 (我试着在symbolfile stdout@@GLIBC_2.0中写入stdout@@GLIBC_2.0 symbolfile ,但它无法编译……)

  2. 看来,正如我没有做到的那样, .bss部分的起始地址也发生了变化,这使得stdout符号的地址在非截面区域中。 在运行时,从0x804a024加载时会引发分段错误。

谁能帮助我如何在预定义的地址成功加载库符号? 谢谢!