Как Wine64 справился с macOS? - PullRequest
0 голосов
/ 11 ноября 2018

Это было серьезным препятствием на протяжении десятилетия. Было объявлено невозможным . На форуме обсуждались вопросы, связанные с установкой и восстановлением GS . FAQ по HQ для вина по-прежнему ссылается на страницу несовместимости ABI , которая не является живой вики-страницей, а ссылкой на архив новостей.

Wine 2.0 объявила о поддержке macOS 64-bit . Но как? Разве это не то, что должны знать все хакеры macOS? Может быть, какой-нибудь элегантный (или грязный) трюк, интересный сам по себе для любого хакера x86-64.

1 Ответ

0 голосов
/ 11 ноября 2018

Основным препятствием является конфликт по базовому адресу сегмента GS (GS.base), поддерживаемый ЦП под управлением ОС.

В 64-битной Windows GS.base используется для храненияадрес структуры блока среды потока (TEB) для каждого потока.Приложения Windows ожидают доступа к TEB, используя %gs -относительные адреса.Это жестко запрограммировано в коде приложения, а не в функции API.

В macOS GS.base используется для хранения базы области локального хранилища потока struct _pthread,внутренняя деталь реализации реализации Pthreads.В приложениях Mac реже встречаются жестко запрограммированные %gs -относительные доступы, но некоторые делают и делают системные библиотеки.

В Linux GS.base доступен для 64-битных приложенийиспользовать для своих целей.Итак, Wine просто устанавливает его, используя механизм, предоставляемый ОС.Wine не может сделать это на macOS.Мало того, что ОС не предоставляет никакого механизма для этого, но, если Wine сможет, это сломает системные библиотеки.(Это также создает потенциальные проблемы для ядра при переключении контекста, и / или ядро ​​может не восстановить любое значение, которое мог установить Wine.)

Решение, которое мы выяснили, является лишь частичным решением.К наиболее часто используемым полям структуры TEB относятся поле self (%gs:0x30) и поле для реализации локального хранилища потока (%gs:0x58).Часто, если приложениям требуется доступ к другим полям, они сначала читают поле self, а затем ссылаются на него.

В macOS %gs:0x30 и %gs:0x58 соответствуют определенным слотам области локального потока потока,Они принадлежат Apple (а не, скажем, приложениям).Мы обнаружили, что один из этих слотов не использовался.Другой использовался для функции ttyname() в библиотеке C.Как это случается, Wine никогда не вызывает эту функцию, и нет никаких оснований ожидать, что любая из системных библиотек, которые он использует для этого, тоже.

Итак, Wine просто задает соответствующие значения в этих %gs -относительныхместах.Поэтому, когда 64-битный код приложения Windows читает их, он получает то, что ему нужно.Фактический TEB, выделенный Wine, находится в другом месте (в выделенной куче памяти), но приложения находят адрес TEB в месте, которое, как они ожидают, являются собственным полем TEB, поэтому они находят его таким образом.

Apple с тех пор любезно зарезервировала оба этих слота для использования как Wine.ttyname() теперь использует другой слот.

Тем не менее, как уже упоминалось выше, это решение является лишь частичным.Некоторые приложения обращаются к другим полям TEB напрямую, используя %gs -относительные адреса со смещениями, отличными от 0x30 или 0x58.Когда они это делают, они получают нежелательные значения и / или значения перезаписи, используемые другими частями системы.Таким образом, поддержка 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...