【问题标题】:Is it possible to run __libc_start_main from C code?是否可以从 C 代码运行 __libc_start_main ?
【发布时间】:2020-03-21 20:01:19
【问题描述】:

函数__libc_start_mainlibc.so中定义,函数签名如下

void __libc_start_main(  int (*main) (int, char * *, char * *),
                    int argc, char * * ubp_av,
                    void (*init) (void),
                    void (*fini) (void),
                    void (*rtld_fini) (void),
                    void (* stack_end)); 

在正常使用中,此函数由函数_start 调用,该函数在C RunTime 对象crt1.o 中定义。

问题:

  1. 是否可以在 C 代码中调用__libc_start_main

困难:

  1. 我找不到在 C 代码中确定最后一个参数 stack_end 的值的方法。 crt1.o的实现是在汇编中,可以确定stack_end

PS:我只是好奇我们是否能够在 C 代码中调用 __libc_start_main

【问题讨论】:

    标签: glibc libc


    【解决方案1】:

    一般来说,这是不可能的,因为__libc_start_main 每个进程只能调用一次,如果您尝试从 C 代码中调用它,它将已经运行或稍后会再次调用它。两者都不会可靠地工作,未来的 glibc 更改可能会破坏此类代码。

    您应该针对您要解决的实际问题发布一个新问题。

    【讨论】:

    • 正如我的问题中提到的,这只是为了我的好奇心,我没有解决任何问题,主要是为了教育目的。我同意你的观点 __libc_start_main 每个进程只能调用一次。在我的测试用例中,我自己也提供函数 _start,而不是使用 C 运行时的 _start。函数__libc_start_main 是从我的_start 调用的,我希望这可以确保函数__libc_start_main 在我的进程中只被调用一次。感谢您的回复。
    • 哦。您不应将_start 替换为 glibc,此类更改可能会在未来的 glibc 版本中中断。您确实必须链接 glibc 附带的 CRT 文件。
    • 感谢您的回复,但有一点我不同意您的说法。 _start 不属于 libc_start是应用程序的入口点,可由用户提供。大多数_start 的实现纯粹是从libc 调用``` __libc_start_main```。如果我们可以正确调用__libc_start_main,我认为使用自定义的_start 没有任何问题。但是,在实践中不建议这样做。为了我的教育目的,我很有男子气概地问这个问题。
    • 在当前的 glibc 中,包含 _start 定义的 CRT 文件不仅仅是调用 __libc_start_main。它还为主程序运行 ELF 构造函数(出于历史原因)。如果 glibc 行为发生变化,覆盖 _start 将不得不适应(对于新二进制文件,旧二进制文件将继续保持不变运行)。
    • 对不起我说的,基于stackoverflow.com/questions/29694564/…,ELF构造函数是由函数__libc_start_main调用的,这是在current glibc中改变了吗?
    猜你喜欢
    • 1970-01-01
    • 2020-07-15
    • 1970-01-01
    • 2015-09-15
    • 1970-01-01
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多