Vajon eddig miért nem valósított meg senki sem egy valódi, natív emulációs környezetet az OSX rendszer számára Windows alatt? Egy ilyen rendszer lehetővé tenné alkalmazások futtatását egy hibrid rendszerben.
Erre a kérdésre próbáltam választ keresni a két rendszer architekturális összehasonlításával.
Az eddigi ismeretek alapján rögtön nekiállhatunk a MachO file-ok szegmensenkénti betöltésének. Általánosságban elmondhatjuk, hogy az alkalmazások 0x1000 báziscímre kellene betölteni, ami akadályokba ütközik Windows rendszerben, hiszen annak eltérő a processzek memóriatérképe.
Találtam egy oldalt, ahol bővebb leírást találhatunk a témáról. Az alábbi kép a Win9x kernel által felépített struktúrát mutatja meg.
WinNT rendszerben az következő szerint módosul ez a kép.
A process in Windows NT can access only the bottom 2 GB of its address space and the lowest and highest 64 KB of that is inaccessible. The EXE, the application's DLLs and Windows DLLs, and memory-mapped files all reside in this space between 0x00010000 and 0x7FFEFFFF. The Windows NT kernel, executive, and device drivers all reside in the upper 2 GB, where they are completely protected from any tampering by an errant program. Memory-mapped files are safer, too.
Ez azt jelenti a számunkra, hogy az alkalmazásunk a 0x10000 és 0x7FFEFFFF közötti területtel gazdálkodhat. Ez nem is olyan nagy probléma, hiszen a VirtualAlloc függvénnyel meghatározható a lefoglalandó memóriaterület kezdőcíme. Ebből adódóan bárhol elhelyezhetjük a szegmenseinket.
Sajnos ez még nem ilyen egyszerű, mert további buktatókat találtam. Példaképpen az OSX-en használt 0xED nevű hexadecimális szerkesztőprogramok vizsgáltam meg, szegmensek közötti, nem relokált hivatkozásokat kerestem.
__jump_table:0004A098 _exit proc near ; CODE XREF: __start+DBp
__jump_table:0004A098 jmp near ptr __imp__exit
__jump_table:0004A098 _exit endp
Erre az import stub-ra mutató referenciát nézzük meg közelebbről.
__text:00008BD5 call _exit
Így még nem szembetünő, de már lehet sejteni, hogy mi lesz itt a probléma. Nézzük meg ennek az utasításnak a mnemonik kódját!
00008BD5 E8 BE 14 04 00
Bizony, relatív ugráci címet tartalmaz: 0x8BD5 + 5 + 0x414BE = 0x4A098. Számunkra ez egy komoly megkötést jelent. Azt jelenti, hogy a szegmenseket egymáshoz képest úgy kell elhelyeznünk, ahogy az eredeti file-ban szereplő virtuális címek mutatják, azaz meg kell tartanunk az egymáshoz viszonyított távolságukat.
Gondolthatnánk, hogy ez még mindig nem olyan nagy probléma, hiszen több alkalmazást megvizsgálva azt tapasztaljuk, hogy a szegmenseik címfolytonosak, egymást után illesztve, hézagmentesen helyezkednek el, tehát nemhogy szegmensekre nem kell szétbontanunk őket, de egy egész blokként foglalva a szükséges területet megoldja a problémáinkat. Sajnos ez nem így van, mert a dinamikus könyvtárak között kutatva találhatunk kivételeket, amelyek megdöntik ezt az elképzelést.