如何在 Mac OS X 上构建包含入口点的 C 程序?

Posted

技术标签:

【中文标题】如何在 Mac OS X 上构建包含入口点的 C 程序?【英文标题】:How do you build a C program that includes the entry point on Mac OS X? 【发布时间】:2011-05-20 05:30:41 【问题描述】:

我要建造:

start() 
    /* exit system call */
    asm("movl $1,%eax;"
        "xorl %ebx,%ebx;"
        "int  $0x80"
    );

但是当我跑步时:

gcc -nostdlib min.c

我总是得到:

ld: could not find entry point "start" (perhaps missing crt1.o)
collect2: ld returned 1 exit status

我为了看看它在做什么而进行的另一次尝试是运行:

gcc -nostdlib -c min.c && otool -tV min.o

输出是:

(__TEXT,__text) section
_start:
0000000000000000    pushq   %rbp
0000000000000001    movq    %rsp,%rbp
0000000000000004    leave
0000000000000005    ret

那么在“开始”函数之前的下划线是从哪里来的呢?我该如何防止这种情况发生?或者更简单地说:

谢谢, CrazyChenz

【问题讨论】:

_start 可能是一个错误的名称。在创建开始之前,请注意必须进行大量预处理,否则各种问题都会中断。要了解符号,您必须定义 try nm crt1.o。 gcc -e main 使“main”成为入口点而不是 start。您可以通过这种方式定义您想要的任何功能。我不知道如何为 Xcode 设置该选项。其他人可能会。 IIRC,MacOS call numbers 与 Linux 不同,所以 eax=1 / int 0x80 可能不是 sys_exit。并且 32 位系统 MacOS 调用采用 FreeBSD 风格的堆栈参数,而不是 EBX、ECX、EDX,...。当然,如果制作 64 位可执行文件,您需要使用 syscall 进行适当的调用数字/ arg-passing regs。 【参考方案1】:

gcc -e 选项定义了入口点,当您希望入口点不是 start 时。这样您就可以创建 mystart() 作为入口点。

gcc -e mystart mycode.c -o mycode

我不知道如何在 Xcode 中设置 -e 选项。

【讨论】:

MacOS 会使用前导 _ 来破坏名称,所以我认为您需要 gcc -e _mystart【参考方案2】:

你可以通过asm单独声明来控制gcc赋予函数的符号:

void start() asm ("start");

确保这是一个独立的声明,与函数定义分开。

您可以在此处阅读有关控制生成符号的更多详细信息:https://***.com/a/1035937/12928775

此外,正如 Peter Cordes 所指出的,您可能应该在函数定义中包含 __attribute__((naked)),以防止 gcc 在入口时生成堆栈帧。

完整的代码是:

void start() asm ("start");

__attribute__((naked)) void start() 
    /* exit system call */
    asm("movl $1,%eax;"
        "xorl %ebx,%ebx;"
        "int  $0x80"
    );

【讨论】:

原型中不需要extern。 godbolt.org/z/Vz77nS 表明 void start(void) asm("_mystart"); 产生指定的名称。此外,您可能想要void 而不是使用旧版 C 隐式-int__attribute__((naked)) 对定义来说是个好主意; start 不是一个函数,所以你不希望 -O0 在入口处创建一个堆栈帧。 要获得额外积分,请记住 C 中的 ()(与 C++ 不同)未指定 arg 类型,而不像 (void)。不妨具体一点,它不需要任何参数。

以上是关于如何在 Mac OS X 上构建包含入口点的 C 程序?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Mac OS X 上构建 DTrace?

如何在 Mac OS X 主机上为 MIPS 目标构建 GCC 4.8.x

如何在 OS X Mavericks 上使用 Clang 设置自定义 C 入口点?

如何检查库是不是是在 Mac OS X 上构建的 32 位/64 位?

在没有 Xcode 的 Mac OS X 上构建 VST 插件

无法在 Mac OS X 上使用 C + libusb 声明 USB 接口