简体   繁体   English

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

[英]Global variable in shared pic library has different access way in 32 and 64 bits binary, as well as its locations?

Recently I took a look into how plt and got implemented, and wrote a chunk of sample code for tracing as below. 最近,我研究了plt的实现方式,并编写了以下示例代码以进行跟踪。 And something I saw confused me a lot. 我看到的东西让我很困惑。

got.c 得到了

#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;
}

extern.c 外部

#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);
}

and compile it like this: 并像这样编译它:

gcc -shared -fpic extern.c -o extern.so
sudo cp extern.so /lib/libextern.so
gcc -g got.c -o got.bin -lextern

question 1: why global variable address of count in libextern.so is 0x601048 ? 问题1:为什么libextern.so中count的全局变量地址为0x601048?

question 2: for external symbol, use .plt and .got.plt for lazy binding, but for global variable like count, why 32-bits use get_pc_thunk for reference .got, and 64-bits just 0xXXX(%rip) for addressing .got ? 问题2:对于外部符号,请使用.plt和.got.plt进行延迟绑定,但对于诸如count之类的全局变量,为什么32位使用get_pc_thunk引用.got,而64位仅使用0xXXX(%rip)进行寻址。得到 ? Or 32-bit can use this rip + offset way for addressing .got of libextern.so ? 或者32位可以使用这种rip + offset方法来解决libextern.so的.got吗?

Thanks in advance! 提前致谢!

when -m32 compiled function add_count: 当-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 

when function add_count compiled to X86_64 64 bits: 当函数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 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]

当您切换架构时,这是正常的……只需检查链接脚本以查看内存映射有何不同。

Finally, I found the answer to that tow question and put here for someone may need this. 最后,我找到了这个拖曳问题的答案,并放在这里,因为有人可能需要这个。 1. For fPIC build library, each global variable will be treat as defined external, and there is one copy of this variable in main executable file .bss section. 1.对于fPIC构建库,每个全局变量将被视为外部定义的变量,并且主可执行文件.bss节中有该变量的一个副本。 2. it seems, in IA 32-bits assembly, we cannot get %eip register as base registers. 2.看来,在IA 32位汇编中,我们无法将%eip寄存器作为基址寄存器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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