链接器如何确定.rodata节中某些数据的地址?

所以testing平台在Linux 32位上。

我用这个方法使用gcc生成一个quickSort的obj文件:

gcc -S quickSort.c

生成的quickSort.o是一个可重定位的ELF:

#file quickSort.o quickSort.o:ELF 32位LSB可重新定位,英特尔80386,版本1(SYSV),未剥离

然后我使用objdump来拆卸它:

objdump -d quickSort.o 

并查看生成的asm文件,我对此感到困惑:

 51: b8 00 00 00 00 mov $0x0,%eax 56: 89 04 24 mov %eax,(%esp) 59: e8 fc ff ff ff call 5a <main+0x5a> 5e: c7 44 24 3c 00 00 00 movl $0x0,0x3c(%esp) 

上面的代码是调用printf函数并打印出一个string,如果我编译quicksort.c到quicksort.s,它应该是这样的:

  movl $.LC0, %eax movl %eax, (%esp) call printf 

所以通过查看重定位表,我可以很容易地发现“5a”和printf之间的关系,我确信链接器可以用这种方式重新定位printf,用“fc ff ff f”代替printf的实际地址,

但是我很困惑如何.LC0(这是.rodata节中的string)的地址重新定位? 我在关系表中找不到任何线索(我使用readelf -r quickSort.o得到重定位表)

任何人都可以给我一些关于链接器如何在.rodata部分find一些数据的真实内存地址的帮助?

这是以同样的方式完成的。 您应该看到针对.rodata的重定位条目,其中.rodata表示当前对象文件中的.rodata部分的起始地址。

请注意, objdump -dr可能是更好的工具。