linux - 为什么 .text 部分不在 "Entry point address"附近?

标签 linux process space elf

我的 main.c 是:

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

结果是:

stack section: 0x7fffffffe1ec
heap section:  0x555555756670
.bss section:  0x55555575501c
.data section: 0x555555755014
.text section: 0x55555555473a

$ readelf -h a.out:

Entry point address: 0x630

为什么 0x630 处的“入口点地址”不在 0x55555555473a 处的“.text 部分”附近?

我的环境是:x86_64,linux-4.15.0

最佳答案

入口点 .text 部分的地址附近。

您在 $ readelf -h a.out 中看到的入口点是名义上的 在加载和重定位程序之前,由链接器静态分配的地址。

.text 部分的地址不是main 的地址,因为你的程序 假设,它是符号 __executable_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

.text 部分的标称地址是 0000000000000000。入口点 是 _start 的地址,在 .text 部分偏移 0x540 字节处,并且 main 位于偏移量 0x64a 处。报告的入口点:

$ 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`

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

关于linux - 为什么 .text 部分不在 "Entry point address"附近?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54960367/

相关文章:

linux - 为什么这个程序在退出时挂起? (信号和 sudo 之间的交互)

Java运行bash命令,同时为其提供输入并获取输出

c++ - Boost.Process - 如何让一个进程运行一个函数?

python - subprocess:删除Windows中的子进程

HTML CSS 小错误顶部白条和颜色差异

c - getrusage 返回四舍五入的数字

python - Linux下伪串口通信

java - 通过java调用外部程序

javascript - 如何在 JavaScript 中创建包含多个空格的字符串

c - 在C语言中,如何查找用户输入行内的空格数?