简体   繁体   English

对“__GLOBAL_OFFSET_TABLE”的未定义引用

[英]undefined reference to '__GLOBAL_OFFSET_TABLE'

I have added -fno-pie in the CFLAGS, but it still shows this error:我在 CFLAGS 中添加了 -fno-pie,但它仍然显示此错误:

ld -melf_i386 -T linker.ld -o kernel.bin start.o kernel.o console.o utils.o
kernel.o: In function `_main':
kernel.C:(.text+0x16): undefined reference to `__GLOBAL_OFFSET_TABLE_'
makefile:30: recipe for target 'kernel.bin' failed
make: *** [kernel.bin] Error 1

The make file is shown below: make文件如下图所示:

GCC_OPTIONS = -m32 -fno-pie -nostdlib -fno-builtin -nostartfiles -nodefaultlibs -fno-exceptions -fno-rtti -fno-stack-protector -fleading-underscore -fno-asynchronous-unwind-tables

all: kernel.bin

clean:
    rm -f *.o *.bin

# ==== KERNEL ENTRY POINT ====

start.o: start.asm
    nasm -f aout -o start.o start.asm

# ==== UTILITIES ====

utils.o: utils.H utils.C
    gcc $(GCC_OPTIONS) -c -o utils.o utils.C

# ==== DEVICES ====

console.o: console.H console.C
    gcc $(GCC_OPTIONS) -c -o console.o console.C

# ==== KERNEL MAIN FILE ====

kernel.o: kernel.C
    gcc $(GCC_OPTIONS) -c -o kernel.o kernel.C


kernel.bin: start.o kernel.o console.o utils.o linker.ld
    ld -melf_i386 -T linker.ld -o kernel.bin start.o kernel.o console.o utils.o

May I ask help for this question?我可以就这个问题寻求帮助吗?

Thank you in advance.先感谢您。

First thing that striked me was "why you're using .C (capitalized) extension for .c file, it's reserved for C++?".让我印象深刻的第一件事是“为什么要为 .c 文件使用 .C(大写)扩展名,它是为 C++ 保留的?”。 So I made a test:于是我做了一个测试:

# with `-fno-rtti'
$ export CFLAGS1="-m32 -fno-pie -nostdlib -fno-builtin -nostartfiles -nodefaultlibs -fno-exceptions -fno-rtti -fno-stack-protector -fleading-underscore -fno-asynchronous-unwind-tables"
# without `-fno-rtti'
$ export CFLAGS2="-m32 -fno-pie -nostdlib -fno-builtin -nostartfiles -nodefaultlibs -fno-exceptions  -fno-stack-protector -fleading-underscore -fno-asynchronous-unwind-tables"
$ mv kernel.C kernel1.C
$ cp kernel.C kernel2.c
$ gcc $CFLAGS1 -c -o kernel1.C.o kernel1.C

$ gcc $CFLAGS1 -c -o kernel2.c.o kernel2.c
cc1: warning: command line option '-fno-rtti' is valid for C++/ObjC++ but not for C
$ gcc $CFLAGS2 -c -o kernel2.c.o kernel2.c

So I bet if you decapitalize your extensions form .C into .c and .H into .h you'll get better results.所以我敢打赌,如果你将你的扩展名从.C变为.c并将.H变为.h你会得到更好的结果。 GCC is fussy in this regard. GCC 在这方面很挑剔。 If you want C code use gcc and .c extension, if you want C++ use g++ and .C or .cc or .cpp or .cxx .如果您希望 C 代码使用gcc.c扩展名,如果您希望 C++ 使用g++.C.cc.cpp.cxx


Also I think you should use gcc instead of ld as link command.另外我认为您应该使用gcc而不是ld作为链接命令。 Ld is usually "stupid" and gcc knows better. Ld 通常是“愚蠢的”,而gcc知道得更好。


PS.附注。 Let me know which one is/is not right.让我知道哪个是/哪个是不正确的。 If wrong I will remove answer to not confuse audience.如果错了,我将删除答案以免混淆观众。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM