[PATCH 3/3] ntdll: For Mac 64-bit, poke NtCurrentTeb()->ThreadLocalStoragePointer to the corresponding offset from %gs.

Ken Thomases ken at codeweavers.com
Wed Jul 27 12:42:56 CDT 2016


On Jul 27, 2016, at 12:14 PM, Sebastian Lackner <sebastian at fds-team.de> wrote:
> 
> On 27.07.2016 18:27, Ken Thomases wrote:
>> On Jul 27, 2016, at 11:06 AM, Sebastian Lackner <sebastian at fds-team.de> wrote:
>>> 
>>> On 27.07.2016 17:42, Ken Thomases wrote:
>>>> 64-bit Windows apps have hard-coded accesses to %gs:0x58 baked into them.  They
>>>> need to find the ThreadLocalStoragePointer there.
>>>> 
>>>> Technically, the gsbase register and the memory it points to belong to the
>>>> pthread implementation on macOS.  It's used for the pthread TLS implementation.
>>>> Slot 11 (offset 0x58) is currently used for the implementation of the ttyname()
>>>> system library function.  We do not anticipate that Wine or any of the system
>>>> libraries or frameworks it uses will call ttyname().  Furthermore, Apple has
>>>> made it so that future releases of macOS will no longer use that slot.  So, we
>>>> hijack it for our purposes.
>>>> 
>>>> Signed-off-by: Ken Thomases <ken at codeweavers.com>
>>>> ---
>>>> dlls/ntdll/loader.c        | 11 +++++++-
>>>> dlls/ntdll/signal_x86_64.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++
>>>> 2 files changed, 72 insertions(+), 1 deletion(-)
>>> 
>>> I'm not sure if I correctly understand the purpose of this patch. If you have to
>>> set %gs:0x58 to some specific value, why not just use an assembly instruction for that?
>>> 
>> 
>> alloc_tls_slot() is setting ThreadLocalStoragePointer for all threads, not just the current one.
>> 
>> -Ken
>> 
> 
> Hm, I see. Do you know if the offset really changed in the past?

Yes, it has changed in the past.

> I am asking
> because I assume the bruteforcing is an attempt to make the code more reliable,
> however on the other hand you still make the assumption that pthread keys
> directly correspond to indices into the %gs segment, which could also change.

Well, we made various proposals to Apple to get a more comprehensive, less kludgy fix and they were rejected because of binary compatibility.  Basically, they were unwilling to change how pthread_getspecific() works.  Mono depends on it, for example.  So, it seems pretty reliable.

> A check that it matches expected behavior is probably sufficient.
> 
> Besides that, if the gsbase cannot be located, it probably would be preferred
> to skip this code on following attempts.

It already does that.  gsbase_offset is static.  It will only be negative on the first call.

-Ken




More information about the wine-devel mailing list