一些背景:
作为个人项目,我一直在用 C++ 开发内核。一切进展顺利,事实上,我对内核领域中可用的大部分 C++ 提供了很好的支持(我几乎实现了整个 libc 和 libstdc++)。
其中一个比较困难且特定于编译器的事情是 RTTI 和异常支持。现在我完全禁用异常,但 RTTI 是我想要的东西,因为像 dynamic_cast
这样的东西可能非常有用。为了完成这项工作,我有一个 std::type_info 的基本实现,它符合 g++ 的预期,然后我链接到 g++ 的 libsupc++.a
和 libgcc_eh.a
。这很好用。 RTTI 表现出色!
问题:
我一直在研究一些优化选项,希望有一天能将 -mregparm 作为编译时的选择。显然,这是一个内核并且必须与汇编代码交互,有些函数在堆栈上没有参数的情况下效果不佳。为了解决这个问题,我使用了以下宏:
#define asmlinkage attribute((regparm(0)))
再一次,这非常有效。问题是当您执行 dynamic_cast
时。编译发出对一些隐式定义的内部函数(在前面提到的支持库中定义)的调用,并根据 -mregparm 标志执行此操作。当然,由于我链接到系统的支持库,它们可能有也可能没有(在我的情况下它们没有)具有兼容的调用约定……导致漂亮的内核 panic 。由于这些函数是隐式的(我的任何文件中都没有原型(prototype))并且它们的名称很长,而且名称错乱,因此(几乎)不可能将我的 asmlinkage 属性添加到它们。
想到了 3 种可能的解决方案。
- 忘了支持 -mregparm 都在一起。
- 重新编译这两个支持库 与内核相同的标志。这 可能有点烦人 不切实际(我不知道他们是否 可以与 gcc 完全隔离 构建和工具链升级可以 非常痛苦),但应该有效。
- 以某种方式让编译器忽略 -mregparm 调用在特定 .a/.o 文件中找到的代码时。
选项 3 可能吗?我的直觉是不,但我想我会问,因为这里有一些 g++ 专家 :-)。
最佳答案
您可能最好选择选项 1 或 2(1 显然更容易)。据我所知,g++ 没有针对选项 3 的特定开关。
关于c++ - 如何让 g++ 忽略某些代码的 -mregparm?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/688945/