繁体   English   中英

共享图片库中的全局变量对32位和64位二进制文​​件及其位置具有不同的访问方式?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM