[英]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.