неопределенная ссылка на __GLOBAL_OFFSET_TABLE - PullRequest
0 голосов
/ 24 февраля 2020

Я добавил -fno-p ie в CFLAGS, но он все еще показывает эту ошибку:

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

Файл 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

Май Прошу помощи по этому вопросу?

Заранее спасибо.

1 Ответ

0 голосов
/ 25 февраля 2020

Первое, что поразило меня, это «почему вы используете расширение C (с заглавной буквы) для файла. c, оно зарезервировано для C ++?». Итак, я сделал тест:

# 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

Так что держу пари, если вы декапитализируете свои расширения из .C в .c и .H в .h, вы получите лучшие результаты. G CC суетлив в этом отношении. Если вы хотите C код, используйте g cc и .c расширение, если вы хотите C ++, используйте g ++ и .C или .cc или .cpp или .cxx.


Также я думаю, что вы должны использовать gcc вместо ld в качестве команды ссылки. Ld обычно "тупой" и gcc знает лучше.


PS. Дайте мне знать, какой из них / не прав. Если не так, я уберу ответ, чтобы не запутать аудиторию.

...