当前位置: 代码迷 >> 综合 >> OSDev——没有“红色区域“的libgcc
  详细解决方案

OSDev——没有“红色区域“的libgcc

热度:40   发布时间:2023-11-13 22:11:09.0

原文链接:https://wiki.osdev.org/Libgcc_without_red_zone

主页:https://blog.csdn.net/qq_37422196/article/details/122591214

下面的链接如果指向原网站的话,大概是还没有翻译

在赶了在赶了……


主条目:libgcc

本文讨论了如何构建libgcc而无需在内核中支持红色区域。如果你的目标平台不是X86-64,你就不需要它,因为i*86没有这样的要求

什么是"红色区域"

红色区域是x86-64 ABI中描述的功能

红色区域是堆栈指针(rsp)以下的128字节区域(rsp-128 ~ rsp)。该区域可供编译器自由使用,无需通知应用程序/操作系统或任何正在运行的中断处理程序

对于用户应用程序这没有问题,因为中断和其他内核相关代码不会干扰用户堆栈。然而,在你的内核中,事情可能会变得很糟糕,特别是如果你有嵌套中断并且没有红色区域支持。想象一下在你的中断处理程序运行时,gcc将一些数据放入红色区域,这时发生嵌套中断并破坏红色区域。反之亦然

为了解决这个问题,可以通过将-mno-red-zone传递给GCC来禁用红色区域

x86_64-elf-gcc $CFLAGS -mno-red-zone ...

为什么要修改libgcc

如果你链接到(也应该链接到)libgcc,则会出现一个问题:libgcc是在启用红色区域下构建的

因此,虽然你的内核工作得很好,但libgcc中的方法可能会意外地把事情搞砸。解决方案很简单——添加-mno-red-zone重构libgcc。幸运的是,GCC通过在其源代码树中提供多库支持,以直接支持这一点

准备

主条目:GCC交叉编译器

按照构建GCC交叉编译器时的说明提取和准备GCC源代码,但暂时不要运行configure

创建以下文件并将其保存为GCC源文件树下的gcc/config/i386/t-x86_64-elf

# 添加没有红色区域的libgcc multilib变体MULTILIB_OPTIONS += mno-red-zone
MULTILIB_DIRNAMES += no-red-zone

默认情况下,除非明确告知,否则GCC不会使用此新配置。在你喜欢的编辑器中打开gcc/config.gcc并搜索case块,如下所示:

x86_64-*-elf*)tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h";;

这是为x86_64-elf创建GCC交叉编译器时使用的目标配置。修改它以包含新的multilib配置:

x86_64-*-elf*)tmake_file="${tmake_file} i386/t-x86_64-elf" # include the new multilib configurationtm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h";;

构建libgcc

运行configure然后像往常一样调用all-target-libgccinstall-target-libgcc,GCC将构建两个版本的libgcc——一个启用红色区域,一个不启用。你可以通过检查已安装的libgcc.a归档文件来检查构建是否成功:

find $TOOLCHAIN_PREFIX/lib -name 'libgcc.a'

如果一切顺利,你应该会看到在no-red-zone multilib目录中安装了一个额外的libgcc:

./gcc/x86_64-pc-elf/4.9.1/libgcc.a
./gcc/x86_64-pc-elf/4.9.1/no-red-zone/libgcc.a

链接到正确的 multilib 版本

假设你使用GCC来链接你的内核。所需要的只是在进行最后的链接器调用时确保-mno-red-zone在你的LDFLAGS

x86_64-elf-gcc $LDFLAGS -mno-red-zone -o kernel $SOURCES

如果你不确定使用的哪个libgcc版本,可以通过将-mno-red-zone-print-libgcc-file-name传递给GCC来检查:

x86_64-elf-gcc -mno-red-zone -print-libgcc-file-name
lib/gcc/x86_64-pc-elf/4.9.1/no-red-zone/libgcc.a

相关内容

文章

  • GCC
  • GCC交叉编译器
  • libgcc
  • Bare Bones