c - 对 '__divdi3' 的 undefined reference

标签 c compiler-errors linker linker-errors

在链接一些对 long long 类型的整数执行除法和模运算的代码时,我收到以下两个错误:

util.c:(.text+0x1af): undefined reference to '__divdi3'
util.c:(.text+0x1ef): undefined reference to '__moddi3'

我也尝试过使用 unsigned long long,但是会导致以下错误:

util.c:(.text+0x1af): undefined reference to '__udivdi3'
util.c:(.text+0x1ef): undefined reference to '__umoddi3'

long long 替换为 intlong 可以解决问题,但我需要使用 unsigned long long.

我正在使用以下命令行来编译和链接程序:

gcc -ffreestanding -c kernel/util.c -o kernel/util.o
ld -o kernel32.bin -Ttext 0x500 kernel/util.o kernel/kernel.o --oformat binary

这是函数:

char* itoa(unsigned long long i, char b[]){
    if (i == 0){
        b[0] = '0';
        b[1] = '\0';
        return b;
    }
    char const digit[] = "0123456789";
    char* p = b;
    if (i < 0){
        *p++ = '-';
        i *= -1;
    }
    unsigned long long shifter = i;
    while (shifter){
        ++p;
        shifter = shifter / 10;
    }
    *p = '\0';
    while (i){
        *--p = digit[i % 10];
        i = i / 10;
    }
    return b;
}

很明显,编译器正在引用 __udivdi3 来除以整数,但链接器找不到它..

顺便说一下,二进制文件是作为32位操作系统使用的,因此缺少很多标准库

编辑:我正在使用 gcc 4.8.4 和 ld 2.24

最佳答案

当为不为 GCC 用作 [unsigned] long long 的数据类型提供硬件支持的体系结构构建代码时,GCC 生成对值进行算术运算的代码涉及调用由它自己的支持库 libgcc 提供的函数的类型。 __divdi3() 等就在其中。这不是 GCC 可以做到的唯一方式,但它非常适合 GCC 支持多种架构的目标。

当被指示充当独立编译器时,GCC 不会自动链接 libgcc,因此不会自动提供这些功能的实现。这一直是之前投诉的主题,例如 this onethis later one . GCC 维护者认为这不是 GCC 缺陷,并且不会导致 GCC 不符合要求。我发现他们的推理有问题,但不太可能改变。至少,这是一个实现质量问题。

不过,我确实看到了 GCC 维护者的来历:一个独立的环境几乎不提供任何标准库,并且除非根据提供给它的代码,否则不得解释大多数函数调用。那么,如果该代码包含对与 libgcc 中某些函数同名的函数的显式调用怎么办?除非用户明确表示他需要 libgcc,否则编译器不应该假定它是需要的函数的那些版本。但问题是,如果 编译器 插入此类调用,那么它不仅知道预期的实现是什么,而且如果链接的是不兼容的实现,结果也是错误的。因此,这是 GCC 自己造成的问题。

底线是您可以明确请求链接 libgcc。您需要指定它是静态链接的,因为您不能依赖上下文中的动态链接器。这些额外的链接选项应该可以做到:

-static-libgcc -lgcc

或者,您可以自己编写这些函数的实现,或者抄袭 GCC 的源代码,但我不明白您为什么更喜欢这些选项中的任何一个。

关于c - 对 '__divdi3' 的 undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34532528/

相关文章:

c++ - 编译时错误,参数被识别为引用

c++ - 未知原因的编译器错误 (C++)

c++ - C++ 中的内联 asm 与 __asm

c - Gtk:Gtk-CRITICAL **:gtk_spin_button_get_value_as_int:断言 'GTK_IS_SPIN_BUTTON (spin_button)' 失败

c - 使用 OpenCL 传输

c - 这段代码有错误吗?如果有的话,在哪里

python c 扩展,mac os 上的 dlopen 问题

c++ - OpenAL:如何添加 ALUT

c++ - 如何找到在静态库中定义符号的位置

c++ - 所有 OpenGL 纹理调用中使用的 "level"参数到底是什么?