![](/img/trans.png)
[英]Address shared between static linked library is treated as 32 bits instead of 64 bits
[英]Global variable in shared pic library has different access way in 32 and 64 bits binary, as well as its locations?
最近,我研究了plt的实现方式,并编写了以下示例代码以进行跟踪。 我看到的东西让我很困惑。
得到了
#include <stdio.h>
static int static_data;
int global_data;
extern int count;
int
main(void)
{
static_data = 12;
global_data = 32;
add_count();
count += static_data;
count += global_data;
printf("error, %p\n", &count);
return count;
}
外部
#include <errno.h>
#include <stdio.h>
int count = 0x1;
void
add_count(void)
{
errno = 0xdead;
count += errno;
fprintf(stdout, "%p\n", &count);
fprintf(stdout, "%p\n", &count);
fprintf(stdout, "%p\n", &count);
}
并像这样编译它:
gcc -shared -fpic extern.c -o extern.so
sudo cp extern.so /lib/libextern.so
gcc -g got.c -o got.bin -lextern
问题1:为什么libextern.so中count的全局变量地址为0x601048?
问题2:对于外部符号,请使用.plt和.got.plt进行延迟绑定,但对于诸如count之类的全局变量,为什么32位使用get_pc_thunk引用.got,而64位仅使用0xXXX(%rip)进行寻址。得到 ? 或者32位可以使用这种rip + offset方法来解决libextern.so的.got吗?
提前致谢!
当-m32编译函数add_count时:
550 5bf: 83 ec 14 sub $0x14,%esp
551 5c2: e8 c9 fe ff ff call 490 <__x86.get_pc_thunk.bx>
552 5c7: 81 c3 39 1a 00 00 add $0x1a39,%ebx
553 5cd: e8 ae fe ff ff call 480 <__errno_location@plt>
554 5d2: c7 00 ad de 00 00 movl $0xdead,(%eax)
555 5d8: e8 a3 fe ff ff call 480 <__errno_location@plt>
556 5dd: 8b 10 mov (%eax),%edx
557 5df: 8b 83 e4 ff ff ff mov -0x1c(%ebx),%eax
558 5e5: 8b 00 mov (%eax),%eax
559 5e7: 01 c2 add %eax,%edx
当函数add_count编译为X86_64 64位时:
567 789: e8 d2 fe ff ff callq 660 <__errno_location@plt>
568 78e: c7 00 ad de 00 00 movl $0xdead,(%rax)
569 794: e8 c7 fe ff ff callq 660 <__errno_location@plt>
570 799: 8b 10 mov (%rax),%edx
571 79b: 48 8b 05 26 08 20 00 mov 0x200826(%rip),%rax # 200fc8 <_DYNAMIC+0x1c0>
572 7a2: 8b 00 mov (%rax),%eax
573 7a4: 01 c2 add %eax,%edx
mmap FYI
00400000-00401000 r-xp 00000000 08:01 1975032 /home/pli/validation/got.bin
00600000-00601000 r--p 00000000 08:01 1975032 /home/pli/validation/got.bin
00601000-00602000 rw-p 00001000 08:01 1975032 /home/pli/validation/got.bin
7ffff7813000-7ffff79ce000 r-xp 00000000 08:01 5771356 /lib/x86_64-linux-gnu/libc-2.19.so
7ffff79ce000-7ffff7bcd000 ---p 001bb000 08:01 5771356 /lib/x86_64-linux-gnu/libc-2.19.so
7ffff7bcd000-7ffff7bd1000 r--p 001ba000 08:01 5771356 /lib/x86_64-linux-gnu/libc-2.19.so
7ffff7bd1000-7ffff7bd3000 rw-p 001be000 08:01 5771356 /lib/x86_64-linux-gnu/libc-2.19.so
7ffff7bd3000-7ffff7bd8000 rw-p 00000000 00:00 0
7ffff7bd8000-7ffff7bd9000 r-xp 00000000 08:01 5767525 /lib/libextern.so
7ffff7bd9000-7ffff7dd8000 ---p 00001000 08:01 5767525 /lib/libextern.so
7ffff7dd8000-7ffff7dd9000 r--p 00000000 08:01 5767525 /lib/libextern.so
7ffff7dd9000-7ffff7dda000 rw-p 00001000 08:01 5767525 /lib/libextern.so
7ffff7dda000-7ffff7dfd000 r-xp 00000000 08:01 5771353 /lib/x86_64-linux-gnu/ld-2.19.so
7ffff7fed000-7ffff7ff0000 rw-p 00000000 00:00 0
7ffff7ff8000-7ffff7ffa000 rw-p 00000000 00:00 0
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00022000 08:01 5771353 /lib/x86_64-linux-gnu/ld-2.19.so
7ffff7ffd000-7ffff7ffe000 rw-p 00023000 08:01 5771353 /lib/x86_64-linux-gnu/ld-2.19.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
当您切换架构时,这是正常的……只需检查链接脚本以查看内存映射有何不同。
最后,我找到了这个拖曳问题的答案,并放在这里,因为有人可能需要这个。 1.对于fPIC构建库,每个全局变量将被视为外部定义的变量,并且主可执行文件.bss节中有该变量的一个副本。 2.看来,在IA 32位汇编中,我们无法将%eip寄存器作为基址寄存器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.