2016-05-15 3 views
2

Ich brauche longjmp/setjmp in einer .kext Datei für OS X. Leider gibt es keine offizielle Unterstützung für diese Funktionen in XNU. Gibt es einen fundamentalen Grund, warum das nicht funktioniert oder gerade nicht umgesetzt wird?setjmp/longjmp in XNU/Darwin Kernel

Irgendwelche Ideen, wie ich das zur Arbeit bringen könnte?

Wenn es hilft, will ich versuchen, Lua zu bekommen in dem O X-Kernel laufen, aber die Laufzeit scheint auf beiden longjmp/setjmp oder C++ Ausnahmen von denen beide sind nicht in XNU abzuhängen.

Antwort

1

Es gibt nichts über die standardkonforme Verwendung von setjmp/longjmp, die Sie davon abhält, sie in einem Kernelkontext zu verwenden. Im Hinblick auf den Kernel-Ausführungskontext ist es wichtig, dass der aktuelle Thread normalerweise über Zeigerarithmetik auf dem aktuellen Stack-Zeiger identifiziert wird. Anders als im Benutzerbereich können Sie keine grünen Threads verwenden oder sich anderweitig mit dem rsp-Register anlegen (auf x86-64). longjmp setzt den Stack-Pointer, aber nur auf den zuvor von setjmp gespeicherten Wert, der sich im selben Stack befindet, wenn Sie sich an die Standard-Verwendung halten, das ist also sicher.

Soweit ich weiß, behandeln Compiler nicht speziell Setjmp() - Aufrufe, so dass Sie Ihre eigene Version relativ einfach als eine Funktion in Assembler implementieren können. Setjmp muss den Rückgabezeiger, den Stapelzeiger und alle auf Abruf gespeicherten Register im Array jmp_buf speichern, das an die Funktion übergeben wurde. All dies ist in der ABI für die betreffende Plattform definiert (x86-64 sysv im Falle von OS X). Dann gebe 0 zurück (setze rax auf 0 auf x86-64). Ihre Version von longjmp muss einfach den Inhalt dieses Arrays wiederherstellen und zum gespeicherten Speicherort mit dem übergebenen Wert als Rückgabewert zurückkehren (kopieren Sie das Argument nach rax auf x86-64). Um dem Standard zu entsprechen, müssen Sie 1 zurückgeben, wenn 0 an longjmp übergeben wird.

Im Benutzerbereich wirkt sich setjmp/longjmp typischerweise auch auf die Signalmaske aus, die im Kernel nicht gilt.

+0

Mit einigem Zufall, ich bin auf Portierung über "ZFS Channel Programs" auf die OSX ZFS-Implementierung, die Lua in den Kernel lädt, so interessiert mich auch die Schlussfolgerung zu diesem Thema. Derzeit lädt es Lua ohne throw() Fähigkeiten, aber das ist eindeutig unerwünscht. – lundman