Assembly 为什么对_GLOBAL_OFFSET_TABLE_uu的非限定引用的nasm程序集显然可以作为PIC进行组装和链接?

Assembly 为什么对_GLOBAL_OFFSET_TABLE_uu的非限定引用的nasm程序集显然可以作为PIC进行组装和链接?,assembly,x86,nasm,elf,position-independent-code,Assembly,X86,Nasm,Elf,Position Independent Code,当包含对其got绝对地址的引用时,为什么我可以将get\u got.asm组装并链接为位置独立代码 得到你得到的 extern _GLOBAL_OFFSET_TABLE_ section .text global get_got get_got: mov rax, _GLOBAL_OFFSET_TABLE_ ret main.c #include <stdio.h> void* get_got(void); int main(int a

当包含对其got绝对地址的引用时,为什么我可以将
get\u got.asm
组装并链接为位置独立代码

得到你得到的

extern _GLOBAL_OFFSET_TABLE_

section .text
global get_got
get_got:
        mov     rax, _GLOBAL_OFFSET_TABLE_
        ret
main.c

#include <stdio.h>

void* get_got(void);

int main(int argc, char* argv[]) {
    printf("%p\n", get_got());
}

这是怎么回事?在我看来,它就像get_got,所以不知何故,它有一个烘焙的绝对地址,在运行时之前,它不会有一个已知的地址。反汇编get_get.so表明mov实际上包含一个立即数(0x201000)。很明显,我对某些事情有很大的误解。我希望这会导致nasm生成一个链接器会阻塞的重新定位。

我使用
lea-rax、[rel\u-GLOBAL\u-OFFSET\u-TABLE]构建了您的代码和修改后的版本。

我改变了
readelf-a
输出。但是,来自不同地址的噪音很大。

readelf-a get_-get.so | diff-u-注意,对于PIC,允许绝对引用数据。现在,尝试使用
-pie
。然后,您应该在最终的二进制输出中看到一个动态重新定位条目。编辑:哦,你做了一个
。所以
。。。那么,您应该在那里看到重新定位。当然,在64位代码中,您通常不需要
\u GLOBAL\u OFFSET\u TABLE\u
,您只需将rip相对寻址与
GOTPCREL
一起使用。您仍然需要从共享库导入的全局变量的GET,不是吗?您将有一个GET,但您可以以rip相对方式对其进行寻址,例如,你可以写
mov-eax,[rel-foo-wrt..get]
objdump-dR
这很明显。这回答了这个问题,但肯定会在我的脑海中提出这样一个修正的含义。谢谢。正如我所说,这就是为什么你要回避它。我相信macos甚至不允许这样做。@Jester:谢谢,我忘了在我的
别名disas='objdump-drwC-Mintel'中通常使用的
-R
之外还有一个
-R
nasm -felf64 -o get_got.o get_got.asm
gcc -fPIC -shared -o get_got.so get_got.o
gcc -Wl,-rpath=\$ORIGIN -o main main.c get_got.so
./main
0x148ba1cba000
--- readelf -a get_got.so
+++ readelf -a get_got_rel.so
....

-Dynamic section at offset 0xe40 contains 22 entries:
+Dynamic section at offset 0xe50 contains 21 entries:
...

- 0x0000000000000016 (TEXTREL)            0x0
  0x000000006ffffffe (VERNEED)            0x3b0
  0x000000006fffffff (VERNEEDNUM)         1
  0x000000006ffffff0 (VERSYM)             0x398
- 0x000000006ffffff9 (RELACOUNT)          4
+ 0x000000006ffffff9 (RELACOUNT)          3
(gdb) disas
Dump of assembler code for function get_got:
=> 0x00007f9e77b235b0 <+0>:     movabs rax,0x7f9e77d24000
   0x00007f9e77b235ba <+10>:    ret    
00000000000005b0 <get_got>:
 5b0:   48 b8 00 10 20 00 00    movabs rax,0x201000
 5b7:   00 00 00 
                        5b2: R_X86_64_RELATIVE  *ABS*+0x201000
 5ba:   c3                      ret