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

时间:2022-02-05 07:19:46

Some background:

As a personal project, I've been developing a kernel in c++. Things are going well, in fact I have very good support for much of c++ available in kernel land (I've implemented nearly the entire libc and libstdc++).

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

One of the more difficult and compiler specific things is RTTI and exception support. For now I'm disabling exceptions entirely, but RTTI is something I want since things like dynamic_cast can be very useful. To make this work, I have a basic implementation of std::type_info which matches what g++ expects and then I link to g++'s libsupc++.a and libgcc_eh.a. This works great. RTTI works like a champ!

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

The question:

I've been toying with some optimization options and would like to someday have -mregparm as a compile time choice. Obviously this being a kernel and having to interact with assembly code, there are certain functions which don't play nice with not having the parameters on the stack. To solve this, I use the following macro:

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

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

Once again, this works very well. The problem is that when you do a dynamic_cast. The compile emits calls to some implicitly defined internal functions (defined in the support libraries previously mentioned) and does so respecting the -mregparm flag. Of course since I linked to the system's support libraries, they may or may not (they don't in my case) have a compatible calling convention...leading to a nice pretty kernel panic. Since these functions are implicit (no prototype in any of my files) and they have long, mangled names, it is (nearly) impossible to add my asmlinkage attribute to them.

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

There are 3 possible solutions which come to mind.

我想到了3种可能的解决方案。

  1. forget about supporting -mregparm's all together.
  2. 忘了支持-mregparm的全部。

  3. recompile those 2 support libs with the same flags as the kernel. This might be annoying and slightly impractical (I don't know if they can be cleanly isolated from the gcc build and toolchain upgrades could be very painful), but should work.
  4. 使用与内核相同的标志重新编译这两个支持库。这可能是烦人的并且有点不切实际(我不知道它们是否可以与gcc构建完全隔离并且工具链升级可能非常痛苦),但是应该可行。

  5. somehow make the compiler ignore -mregparm when calling code found in a particular .a/.o file.
  6. 以某种方式使编译器在调用特定.a / .o文件中找到的代码时忽略-mregparm。

Is option 3 possible? My gut feeling is no, but I figured that I would ask since there are a few g++ gurus on here :-).

选项3可能吗?我的直觉是没有,但我想我会问,因为这里有几个g ++大师:-)。

1 个解决方案

#1


You are probably best going with options 1 or 2 (1 is clearly easier). To my knowledge g++ has no specific switch for option 3.

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

#1


You are probably best going with options 1 or 2 (1 is clearly easier). To my knowledge g++ has no specific switch for option 3.

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