gpt4 book ai didi

gcc - 对 _GLOBAL_OFFSET_TABLE_ 的 undefined reference (仅在生成二进制文件时)

转载 作者:行者123 更新时间:2023-12-02 22:02:57 42 4
gpt4 key购买 nike

这就是问题所在:
当我使用 ld 在 C 中链接脚本时,当我在 ld 中生成 elf32-i386 文件作为输出格式,并将其作为 OUTPUT_FORMAT() 放在 ld 脚本中时,我没有任何错误,但如果我尝试将其放入最后OUTPUT_FORMAT()“二进制”或尝试输出扩展名为 .bin 的文件,我收到如下混合错误:

kernel.o: In function `k_main':
kernel.c:(.text+0xe): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelutils.o: In function `k_clear_screen':
kernelutils.c:(.text+0xc): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelutils.o: In function `k_clear_screen_front':
kernelutils.c:(.text+0x56): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelutils.o: In function `k_printf':
kernelutils.c:(.text+0xa0): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelutils.o: In function `k_sleep_3sec':
kernelutils.c:(.text+0x152): undefined reference to `_GLOBAL_OFFSET_TABLE_'
kernelmalloc.o:kernelmalloc.c:(.text+0xc): more undefined references to `_GLOBAL_OFFSET_TABLE_' follow

这不仅发生在编译特定脚本时,所有尝试使用 ld 链接或 gcc 的脚本(因为它调用 ld)都会在尝试获取带有 .bin 扩展名的二进制文件时死亡。
当显示其中一个可执行文件的符号(上面输出中的 kernel.o)时,我看到符号 _GLOBAL_OFFSET_TABLE_ 没有定义,最可怕的部分是,上面错误输出中返回错误的所有函数都删除了它们的符号,这是 nm 输出:

cristian@mymethodman:~/Desktop/kernel/0.0.3/Archivos$ nm kernel.o
U _GLOBAL_OFFSET_TABLE_
U k_clear_screen
U k_clear_screen_front
00000000 T k_main
U k_malloc
U k_printf
U k_sleep_3sec
00000000 T __x86.get_pc_thunk.bx

我该如何解决这个问题?我将保留下面的链接器脚本,以确保它是 .ld 文件的问题,具有“获取 elf”和“获取二进制”版本。提前致谢!

Ld 脚本:
获取二进制文件:

ENTRY(loader)
OUTPUT_FORMAT(binary)

SECTIONS {
/* The kernel will live at 3GB + 1MB in the virtual
address space, which will be mapped to 1MB in the
physical address space. */
. = 0xC0100000;

.text : AT(ADDR(.text) - 0xC0000000) {
*(.text)
*(.rodata*)
}

.data ALIGN (0x1000) : AT(ADDR(.data) - 0xC0000000) {
*(.data)
}

.bss : AT(ADDR(.bss) - 0xC0000000) {
_sbss = .;
*(COMMON)
*(.bss)
_ebss = .;
}
}

获取 ELF:

ENTRY(loader)
OUTPUT_FORMAT(elf32-i386)

SECTIONS {
/* The kernel will live at 3GB + 1MB in the virtual
address space, which will be mapped to 1MB in the
physical address space. */
. = 0xC0100000;

.text : AT(ADDR(.text) - 0xC0000000) {
*(.text)
*(.rodata*)
}

.data ALIGN (0x1000) : AT(ADDR(.data) - 0xC0000000) {
*(.data)
}

.bss : AT(ADDR(.bss) - 0xC0000000) {
_sbss = .;
*(COMMON)
*(.bss)
_ebss = .;
}
}

正如您所见,两者之间仅更改了 OUTPUT_FORMAT() 行。

最佳答案

您的工具链可能默认生成位置无关的可执行文件(PIE)。尝试使用 gcc -fno-pie 进行编译。

如果出于安全原因想要保留 PIE,则需要更复杂的链接器脚本和执行初始重定位的东西(例如动态链接器,但也可以使用更简单的构造)。

关于gcc - 对 _GLOBAL_OFFSET_TABLE_ 的 undefined reference (仅在生成二进制文件时),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45422374/

42 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com