Wine64如何设法处理macOS?

OCT*_*RAM 3 macos assembly wine x86-64

这是十年来的主要障碍.据报道这是不可能的.论坛会谈提到了与设置和恢复GS有关的问题.Wine HQ FAQ仍然是指ABI不兼容页面,它不是实时维基页面,而是新闻档案链接.

Wine 2.0宣布支持macOS 64位.但是......怎么样?这不是所有macOS黑客都应该知道的吗?对于任何x86-64黑客来说,也许一些优雅(或肮脏)的技巧本身就很有趣.

Ken*_*ses 10

主要障碍是由CPU在OS的控制下维护的GS段基地址(GS.base)的冲突.

在64位Windows上,GS.base用于保存每个线程的线程环境块(TEB)结构的地址.Windows应用程序希望使用%gs-relative地址访问TEB .这是硬编码到应用程序代码中而不是在API函数后面.

在macOS上,GS.base用于保存线程的线程本地存储区域的基础struct _pthread,这是Pthreads实现的内部实现细节.对于Mac应用来说,将硬编码%gs相关访问融入其中并不常见,但有些会这样做,系统库也是如此.

在Linux上,GS.base可用于64位应用程序以用于其自身目的.因此,Wine只使用操作系统提供的机制设置它.葡萄酒不能在macOS上那样做.操作系统不仅不提供任何机制来执行此操作,而且,如果Wine可以,它将破坏系统库.(它还会在上下文切换时对内核造成潜在问题和/或内核可能无法恢复Wine可能设置的任何值.)

我们想出的解决方案只是部分解决方案.TEB结构中最常访问的字段是"self"字段(%gs:0x30)和用于线程本地存储实现的字段(%gs:0x58).通常,如果应用需要访问其他字段,他们首先会阅读自我字段,然后引用它.

在MacOS,%gs:0x30%gs:0x58对应于所述线程本地存储区域的特定时隙.它们属于Apple保留的部分(而不是应用程序使用).我们发现其中一个插槽未使用.另一个用于ttyname()C库中的功能.碰巧,Wine从不调用该函数,也没有理由期望它使用的任何系统库也这样做.

因此,Wine只是在那些%gs相对位置戳了适当的值.因此,当64位Windows应用程序代码读取它们时,它会获得所需的内容.酒已分配的位于其他位置(在堆中分配的内存),但应用程序找到他们期望的TEB自身领域的地方TEB的地址,所以他们觉得这样的实际TEB.

Apple已经慷慨地将这两个插槽永久保留用于像Wine这样的用途.ttyname()现在使用不同的插槽.

也就是说,如上所述,这种解决方案只是部分解决方案.一些应用访问直接使用TEB的其他字段%gs-relative地址以比其他偏移量0x300x58.当他们这样做时,他们会获得垃圾值和/或覆盖系统其他部分使用的值.因此,Wine对64位Windows应用程序的支持在macOS上并不完整.一些此类应用程序将崩溃或以其他方式行为不端.幸运的是,它很少发生,实际上并没有太大的问题.

供参考,以下是实现此解决方案的提交:

http://source.winehq.org/git/wine.git/?a=commit;h=7501942008f91a9a137fe598ce5ce7cb47de5522 http://source.winehq.org/git/wine.git/?a=commit;h=3d8efb238808a519902e047d8673237debb0f0a2