如何为某些代码制作g ++ ignore -mregparm?

时间:2009-03-27 08:37:38

标签: c++ operating-system g++ kernel

某些背景:

作为个人项目,我一直在用c ++开发内核。事情进展顺利,事实上我对内核领域的大部分c ++都有很好的支持(我已经实现了几乎整个libc和libstdc ++)。

更困难和编译器特定的事情之一是RTTI和异常支持。现在我完全禁用异常,但RTTI是我想要的,因为像dynamic_cast这样的东西非常有用。为了使这个工作,我有一个std :: type_info的基本实现,它匹配g ++所期望的,然后我链接到g ++的libsupc++.alibgcc_eh.a。这非常有效。 RTTI就像一个冠军!

问题:

我一直在玩一些优化选项,并希望有一天能将-mregparm作为编译时选择。显然这是一个内核并且必须与汇编代码进行交互,有些函数在堆栈上没有参数的情况下效果不佳。为了解决这个问题,我使用以下宏:

#define asmlinkage  attribute((regparm(0)))

再次,这非常有效。问题是当你做dynamic_cast时。编译发出一些隐式定义的内部函数(在前面提到的支持库中定义)的调用,并且这样做是关于-mregparm标志的。当然,因为我链接到系统的支持库,它们可能会或可能不会(它们不在我的情况下)具有兼容的调用约定......导致一个漂亮的内核恐慌。由于这些函数是隐式的(在我的任何文件中都没有原型)并且它们具有冗长的名称,因此(几乎)不可能将asmlinkage属性添加到它们中。

有三种可能的解决方案可供考虑。

  1. 忘记支持 -mregparm全部在一起。
  2. 重新编译这两个支持库 与内核相同的标志。这个 可能是烦人的 不切实际(我不知道他们是不是 可以与gcc完全隔离 构建和工具链升级可以 非常痛苦),但应该工作。
  3. 以某种方式使编译器忽略 调用在特定.a / .o文件中找到的代码时调用-mregparm。
  4. 选项3可能吗?我的直觉是没有,但我想我会问,因为这里有几个g ++大师: - )。

1 个答案:

答案 0 :(得分:1)

你最好选择1或2(1显然更容易)。据我所知,g ++没有针对选项3的具体切换。