未定义的引用'__divdi3'

Div*_*ero 6 c linker compiler-errors linker-errors

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

util.c:(.text+0x1af): undefined reference to '__divdi3'
util.c:(.text+0x1ef): undefined reference to '__moddi3'
Run Code Online (Sandbox Code Playgroud)

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

util.c:(.text+0x1af): undefined reference to '__udivdi3'
util.c:(.text+0x1ef): undefined reference to '__umoddi3'
Run Code Online (Sandbox Code Playgroud)

更换long longintlong解决问题,但我需要使用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
Run Code Online (Sandbox Code Playgroud)

这是功能:

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;
}
Run Code Online (Sandbox Code Playgroud)

显然,编译器引用__udivdi3除以整数但链接器找不到它.

顺便说一下,二进制文件将用作32位操作系统,因此缺少许多标准库

编辑:我使用的是gcc 4.8.4和ld 2.24

Joh*_*ger 14

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

当被指示充当独立编译器时,GCC不会自动链接libgcc,结果是不会自动提供这些函数的实现.这一直是以前投诉的主题,例如这个后来的投诉.GCC维护者采取的立场是,这不是GCC的缺陷,并且它不会使GCC不符合要求.我觉得他们的推理有问题,但不太可能改变.至少,这是一个实施质量问题.

我确实看到了GCC维护者的来源,但是:独立环境几乎不提供标准库,并且除了根据提供给它的代码之外,不得解释大多数函数调用.那么,如果该代码包含对与libgcc中某些函数具有相同名称的函数的显式调用,那该怎么办?除非用户明确表示他想要libgcc,否则编译器不应该假设它是所需函数的那些版本.但问题是,如果编译器插入这样的调用,那么它不仅知道哪些实现是预期的,而且如果链接了不兼容的实现,则结果是错误的.因此,这是海湾合作委员会自己制定的问题.

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

-static-libgcc -lgcc
Run Code Online (Sandbox Code Playgroud)

或者,您可以编写自己的这些函数的实现,或者从GCC中获取源代码,但我不明白为什么您更喜欢这些选项.