PowerPC-Zweigstellen haben nur 24 Bits für den Zieloffset verfügbar. Wenn der Textabschnitt zu groß wird, können Zweige an einem Ende die Ziele nicht erreichen das andere. Es gibt eine längere Befehlsfolge, die weiter entfernte Ziele erreichen kann (der Offset beträgt 32 statt 24 Bits), aber GCC verwendet sie standardmäßig nicht, es sei denn, Sie übergeben die Option -mlongcall
. Aber auch mit dieser Option auf, noch GCC erzeugt kurze Anrufe für bestimmte Funktionen, nämlich operator new
und operator delete
GCC weigert sich, lange Aufrufe für Operator neu/Löschen auf PowerPC auszugeben
Zum Beispiel gegeben diesen Code:
extern void foo();
int main(int argc, char** argv) {
foo();
new char;
}
Ein normaler Lauf der GCC die Assembly generiert:
bl _Z3foov // void foo()
bl _Znwj // operator new(unsigned int)
Lauf GCC mit der -mlongcall
Option generiert:
lis r9, [email protected]
addi r9, r9, [email protected]
mtctr r9
bctrl
bl _Znwj
Die ersten vier Anweisungen sind wie erwartet ein langer Anruf an foo()
, aber der Aufruf an operator new
ist unverändert. Aufrufe in zufällige libc- und libstdC++ - Funktionen werden alle wie erwartet in lange Aufrufe konvertiert. Warum enden die Anrufe operator new
und operator delete
immer noch als bl
Anweisungen? Gibt es eine Möglichkeit, GCC dazu zu zwingen, auch lange Anrufe zu machen? Ich benutze GCC 4.7.2 auf einem 64-Bit PowerPC Fedora-Rechner (obwohl ich 32-Bit baue)
Welche Version von GCC? Haben Sie auf http://gcc.gnu.org/bugzilla/ einen Fehlerbericht erstellt? Hast du es mit dem letzten GCC (4.7.2 und bald 4.8) versucht? –
Kneif mich, es ist spät hier, und vielleicht träume ich schon. Oder habe ich gerade eine gute Frage gefunden? –
Nur wundernd, ist es das gleiche, wenn Sie einen Ersatz definieren 'void * operator new (std :: size_t);'? – aschepler