Einige Hintergrundinformationen:Wie mache ich g ++ ignorieren -mregparm für bestimmten Code?
Als persönliches Projekt, ich habe einen Kernel in C++ entwickelt. Die Dinge laufen gut, in der Tat habe ich sehr gute Unterstützung für viel von C++, das im Kernelland verfügbar ist (ich habe fast die gesamte libc und libstdC++ implementiert).
Einer der schwierigeren und Compiler spezifischen Dinge ist RTTI und Ausnahme-Unterstützung. Momentan deaktiviere ich Ausnahmen vollständig, aber RTTI ist etwas, was ich will, da Dinge wie dynamic_cast
sehr nützlich sein können. Um dies zu erreichen, habe ich eine grundlegende Implementierung von std :: type_info, die mit dem übereinstimmt, was g ++ erwartet, und verbinde mich dann mit g ++ libsupc++.a
und libgcc_eh.a
. Das funktioniert großartig. RTTI funktioniert wie ein Champion!
Die Frage:
Ich habe mit einigen Optimierungsmöglichkeiten worden liebäugelt und möchte einen Tag -mregparm als Kompilierung Wahl haben. Da es sich dabei um einen Kernel handelt und man mit Assemblercode interagieren muss, gibt es bestimmte Funktionen, die nicht gut funktionieren, wenn man nicht die Parameter auf dem Stack hat. Um das zu lösen, verwende ich das folgende Makro:
#define asmlinkage attribute((regparm(0)))
Noch einmal, das funktioniert sehr gut. Das Problem ist, dass wenn Sie eine dynamic_cast
tun. Die Kompilierung gibt Aufrufe an einige implizit definierte interne Funktionen (definiert in den zuvor erwähnten Unterstützungsbibliotheken) aus und beachtet dabei das Flag -mregparm. Natürlich, da ich mit den Unterstützungsbibliotheken des Systems verbunden bin, kann es sein, dass sie (vielleicht in meinem Fall) keine kompatible Aufrufkonvention haben ... was zu einer schönen Kernel-Panik führt. Da diese Funktionen implizit sind (kein Prototyp in irgendeiner meiner Dateien) und sie lange, verstümmelte Namen haben, ist es (fast) unmöglich, ihnen mein Attribut asmlinkage hinzuzufügen.
Es gibt 3 mögliche Lösungen, die in den Sinn kommen.
- vergessen zu unterstützen -mregparm ist alles zusammen.
- kompilieren Sie diese 2 Support-Bibliotheken mit die gleichen Flags wie der Kernel. Diese könnte ärgerlich und leicht unpraktisch sein (Ich weiß nicht, ob sie sauber von der GCC Build-und Toolchain-Upgrades könnte sehr schmerzhaft isoliert werden), sollte aber funktionieren.
- irgendwie den Compiler ignorieren -mregparm beim Aufrufen von Code in einer bestimmten .a/.o-Datei gefunden.
Ist Option 3 möglich? Mein Bauchgefühl ist nein, aber ich dachte, dass ich fragen würde, da hier ein paar g ++ Gurus sind :-).