Linux 为什么。文本部分不在“附近”;入口点地址;?

Linux 为什么。文本部分不在“附近”;入口点地址;?,linux,process,space,elf,Linux,Process,Space,Elf,我的主要意见是: #include <stdio.h> #include <stdlib.h> int bss_var; int data_var0 = 1; int main() { // stack printf("_____________________________________\n"); printf("stack section:\n"); int stack_var = 3; printf("\t%p\n",&a

我的主要意见是:

#include <stdio.h>
#include <stdlib.h>
int bss_var;
int data_var0 = 1;
int main()
{
    // stack
    printf("_____________________________________\n");
    printf("stack section:\n");
    int stack_var = 3;
    printf("\t%p\n",&stack_var);
    printf("_____________________________________\n");

    // heap
    printf("heap section:\n");
    char *p = (char*)malloc(10);
    printf("\t%p\n",p);
    printf("_____________________________________\n");

    // .bss
    printf(".bss section:\n");
    printf("\t%p\n",&bss_var);
    printf("_____________________________________\n");

    // .data
    printf(".data section:\n");
    static int data_var1 = 4;
    printf("\t%p\n",&data_var1);
    printf("\t%p\n",&data_var0);
    printf("_____________________________________\n");

    // .text
    printf(".text section:\n");
    printf("\t%p\n",main);
    printf("_____________________________________\n");

    return 0;
}
$readelf-ha.out:

Entry point address: 0x630
为什么0x630处的“入口点地址”不在0x55473A处的“.text节”附近


我的环境是:x86_64,linux-4.15.0在一个位置独立的可执行文件中,入口点地址相对于基映射地址。默认情况下,内核为每个程序运行随机确定基映射地址。在x86-64上,它通常约为
0x55550000

您可以将您的程序与
-no pie
链接,以创建位置相关的可执行文件(ELF type
ET_EXEC
而不是
ET_DYN
)。

入口点靠近
.text
部分的地址

使用
$readelf-ha.out
看到的入口点是标称值 在加载和重新定位程序之前,由链接器静态分配的地址

.text
部分的地址不是程序中的
main
的地址 假设它是符号
\uuu可执行文件\u start
的地址,并且是程序打印的内容 在运行时,不是链接器分配的标称地址,而是之后的虚拟地址 程序被加载并重新定位。见:

$ cat main.c
#include <stdio.h>

extern char __executable_start;
extern char _start;

int main(void)
{
    printf("%p: address of `.text` section\n", &__executable_start);
    printf("%p: address of `_start` \n", &_start);
    printf("%p: address of `main` \n", &main);
    return 0;
}

$ gcc -Wall main.c 

$ readelf -s a.out | egrep -w '(main|_start|__executable_start)'
    34: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS main.c
    49: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  ABS __executable_start
    57: 0000000000000540    43 FUNC    GLOBAL DEFAULT   14 _start
    59: 000000000000064a    83 FUNC    GLOBAL DEFAULT   14 main
是一样的。以及运行程序:

$ ./a.out 
0x564c5d350000: address of `.text` section
0x564c5d350540: address of `_start` 
0x564c5d35064a: address of `main`

显示与虚拟基址0x564c5d350000具有相同偏移量的符号。

@api欢迎使用Stackoverflow!请看
$ readelf -h a.out | grep 'Entry point'
Entry point address:               0x540
$ ./a.out 
0x564c5d350000: address of `.text` section
0x564c5d350540: address of `_start` 
0x564c5d35064a: address of `main`