一些背景:
作为个人项目,我一直在用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标志。当然,由于我链接到系统的支持库,因此它们可能有也可能没有(在我的情况下,它们没有)兼容的调用约定...导致了不错的内核恐慌。由于这些函数是隐式的(我的任何文件中都没有原型(prototype)),并且它们的名称很长且整齐,因此(几乎)不可能向其添加asmlinkage属性。我想到了3种可能的解决方案。
-mregparm在一起。
与内核相同的标志。这个
可能会令人讨厌并且有点
不切实际(我不知道他们是否
可以与gcc完全隔离
构建和工具链升级可以
会非常痛苦),但应该可以。
-mregparm,当调用在特定.a / .o文件中找到的代码时。
选项3是否可行?我的直觉不是,但我想问一下,因为这里有一些g++专家:-)。
最佳答案
您可能最好选择选项1或2(显然更容易选择1)。据我所知,g++对于选项3没有特定的开关。