一些背景:

作为个人项目,我一直在用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标志。当然,由于我链接到系统的支持库,因此它们可能有也可能没有(在我的情况下,它们没有)兼容的调用约定...导致了不错的内核恐慌。由于这些函数是隐式的(我的任何文件中都没有原型(prototype)),并且它们的名称很长且整齐,因此(几乎)不可能向其添加asmlinkage属性。

我想到了3种可能的解决方案。
  • 忘记支持
    -mregparm在一起。
  • 用以下命令重新编译这2个支持库
    与内核相同的标志。这个
    可能会令人讨厌并且有点
    不切实际(我不知道他们是否
    可以与gcc完全隔离
    构建和工具链升级可以
    会非常痛苦),但应该可以。
  • 以某种方式使编译器忽略
    -mregparm,当调用在特定.a / .o文件中找到的代码时。

  • 选项3是否可行?我的直觉不是,但我想问一下,因为这里有一些g++专家:-)。

    最佳答案

    您可能最好选择选项1或2(显然更容易选择1)。据我所知,g++对于选项3没有特定的开关。

    10-04 20:13