【问题标题】:Detect -nostdlib or just detect whether stdlib is available or not检测 -nostdlib 或仅检测 stdlib 是否可用
【发布时间】:2015-04-07 15:31:02
【问题描述】:

我有一个家庭作业,要求我们使用系统调用而不是标准库来打开、读取和写入文件。为了调试它,我想在测试编译项目时使用标准库。我这样做了:

#ifdef HOME
  //Home debug prinf function
  #include <stdio.h>
#else
  //Dummy prinf function
  int printf(const char* ff, ...) {
    return 0;
  }
#endif

我这样编译它:gcc -DHOME -m32 -static -O2 -o main.exe main.c

问题是我有-nostdlib参数,标准入口点是void _start,但没有参数,入口点是int main(const char** args)。你可能会这样做:

//Normal entry point
int main(const char** args) {
  _start();
}
//-nostdlib entry point
void _start() {
  //actual code
}

在这种情况下,这就是在没有-nostdlib 的情况下编译时得到的结果:

/tmp/ccZmQ4cB.o: In function `_start':
main.c:(.text+0x20): multiple definition of `_start'
/usr/lib/gcc/i486-linux-gnu/4.7/../../../i386-linux-gnu/crt1.o:(.text+0x0): first defined here

因此我需要检测是否包含stdlib,在这种情况下不要定义_start

【问题讨论】:

    标签: c gcc


    【解决方案1】:

    您的系统的低级入口点始终是_start。对于-nostdlib,链接中省略了它的定义,因此您必须提供一个。没有-nostdlib,你不能试图定义它;即使这没有从重复定义中得到链接错误,它也会严重破坏标准库运行时的启动。

    换一种方式试试:

    int main() {
      /* your code here */
    }
    #ifdef NOSTDLIB_BUILD /* you need to define this with -D */
    void _start() {
      main();
    }
    #endif
    

    您可以选择向main 添加虚假参数。但是,不可能从用 C 语言编写的 _start 获得真实的。为此,您需要在 asm 中写 _start

    注意-nostdlib 是一个链接器 选项,而不是编译时,所以没有办法自动 在编译时确定-nostdlib 正在运行要使用的。相反,只需制作自己的宏并将其作为 -DNOSTDLIB_BUILD 或类似名称在命令行中传递。

    【讨论】:

    • 我不确定这对于 SO 答案是否不太复杂,但链接器究竟如何定义 void _start
    • 它没有。默认链接器命令行(不使用-nostdlib 时)包含一个通常命名为crt1.o 之类的文件,其中包含_start 的定义。
    猜你喜欢
    • 2014-06-26
    • 1970-01-01
    • 1970-01-01
    • 2013-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    相关资源
    最近更新 更多