_start 是否调用我的程序的主函数和其他基本设置函数?

_start 是否调用我的程序的主函数和其他基本设置函数?

我正在阅读一本描述加载程序如何工作的教科书:

当加载程序运行时,它将可执行目标文件的块复制到代码和数据段中。接下来,加载器跳转到程序的入口点,该入口点始终是函数的地址。_start_start函数调用系统启动函数,__libc_start_main

从答案来看这个堆栈溢出问题,我们有以下关于执行流程的伪代码:

_start:
   call __setup_for_c       ; set up C environment
   call __libc_start_main   ; set up standard library
   call _main               ; call your main
   call __libc_stop_main    ; tear down standard library
   call __teardown_for_c    ; tear down C environment
   jmp  __exit              ; return to OS

我的问题是:

  1. 我曾经objdump检查过程序的汇编代码,发现只有如下图所示的_start调用:__libc_start_main

    在此输入图像描述

    其余的函数如call __setup_for_c_main等呢?尤其是我的程序的main函数,我看不到它是如何被调用的。那么关于执行流程的伪代码是否正确呢?

  2. __libc_start_main设置标准库是什么意思?为什么需要设置标准库?那个标准库不是只需要在程序加载时通过动态链接器来链接吗?

答案1

  1. 链接答案中描述的其他函数调用给出了需要发生的事情的概要; GNU C 库中的实际实现细节有所不同,要么使用“构造函数”( _dl_start_user),要么在__libc_start_main.__libc_start_main还负责调用用户的main,这就是为什么你看不到它被称为在你的反汇编中 - 但它的地址被传递(参见leacallq__libc_start_main还负责程序退出,并且永不返回;这就是hlt紧随其后的原因callq,如果函数返回,它将使程序崩溃。

  2. 如今,该库需要进行大量设置:

    • 一些自己的搬迁
    • 线程本地存储设置
    • 并行线程设置
    • 析构函数注册
    • vDSO 设置(在 Linux 上)
    • ctype初始化
    • 将程序名称、参数和环境复制到各种库变量

    等等。请参阅 x86-64 特定的sysdeps/x86_64/start.S和通用的csu/libc-start.c,csu/init-first.c, 和misc/init-misc.c除其他外。

相关内容