<div dir="auto"><div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Apr 19, 2022, 2:03 AM Derek Lesho <<a href="mailto:dlesho@codeweavers.com">dlesho@codeweavers.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div>
    <p><br>
    </p>
    <div>On 18.04.22 12:35, Jinoh Kang wrote:<br>
    </div>
    <blockquote type="cite">
      <pre>On 4/18/22 22:37, Derek Lesho wrote:
</pre>
      <blockquote type="cite">
        <pre>On 16.04.22 03:58, Jinoh Kang wrote:
</pre>
        <blockquote type="cite">
          <pre>On 4/15/22 00:26, Eric Pouech wrote:
</pre>
          <blockquote type="cite">
            <pre>For modules requiring linking to .so files, the scheme has to be extended by
generating an additional ELF library, tied to the PE module.
   +-----------------+           +-----------------+                +-----------+
   | FOOBAR.dll (PE) |           | FOOBAR.so (ELF) | -------------> | helper.so |
   |                 | --------> | (unixlib)       | ELF dyn link   +-----------+
   |                 |           |                 |
   +-----------------+           +-----------------+

Addind this extra module in the middle allows to:
- do the translation from a entities defined in PE world into entities
   defined in the ELF world (ABI are different, structures layout are different)
- this provides an abstraction of the library for the PE world.
- decide what to migrate from the existing code into the PE part (remember
   existing library in old model lives in the ELF world)

One can see the FOOBAR.so like a Wine-"system driver" for providing the required
support from the host.

But, it brings constraints too. The ELF part cannot call back into the PE part
of the module, nor into other PE modules.
</pre>
          </blockquote>
          <pre>To clarify: the ELF part cannot call back into PE modules *without performance penalty or interference with stack unwinding*.

ELF modules calls back into user-supplied functions just fine, think e.g. window procedures.
This however involves KeUserModeCallback(), accompanied by its context-switching overhead.

Perhaps we intend to say: "The ELF part cannot link directly to dlls. Also, calling back to the PE side comes with performance penalty or interferes with stack unwinding, depending on which callback approach is used."
</pre>
        </blockquote>
        <pre>Can you describe the two approaches you're referring to?  I'm aware of KeUserModeCallback, and I assume the other method is to create a win32 PE thread which waits on callbacks from the unixlib?
</pre>
      </blockquote>
      <pre>I meant calling it directly.  Which (kind of) messes with syscall frame state.</pre>
    </blockquote>
    Is this allowed in upstream wine, even as an intermediate step in
    the transition?<br></div></blockquote></div></div><div dir="auto"><br></div><div dir="auto">I was only suggesting a possibility, not necessarily what is allowed in upstream codebase policy.</div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>
    <blockquote type="cite">
      <pre></pre>
      <blockquote type="cite">
        <pre>  As far as I know, KeUserModeCallback doesn't involve context switching, just the usual context saving/restoring required for syscalls in general.
</pre>
      </blockquote>
      <pre>Oh, maybe not a context switch per se.  It's actually:

1. __wine_setjmp: save Unix-side state
2. emulated syscall return: divert into KiUserCallbackDispatcher
3. syscall: call into NtCallbackReturn
4. __wine_longjmp: restore Unix-side state

So it's still a lot of work.</pre>
    </blockquote>
    Yeah, and of course it should be noted that this only works on
    threads created by wine.<br>
    <blockquote type="cite">
      <pre></pre>
      <blockquote type="cite">
        <blockquote type="cite">
          <pre></pre>
          <blockquote type="cite">
            <pre>If this ELF parts requires some Wine "kernel features", the it can (using ELF
dynamic linking) use the APIs provided by ntdll.so ELF library.

   +-----------------+           +-----------------+                +-----------+
   | FOOBAR.dll (PE) |           | FOOBAR.so (ELF) | -------------> | ntdll.so  |
   |                 | --------> | (unixlib)       | ELF dyn link   +-----------+
   |                 |           |                 | -------------> | helper.so |
   +-----------------+           +-----------------+                +-----------+

Note: likely some other modules .so should be available too (like win32u) (to be
confirmed)
</pre>
          </blockquote>
          <pre>I confirm that win32u.so also exists.

Here is a list of other Unixlibs:
</pre>
        </blockquote>
        <pre>I think what Eric was getting at here was what base unix libraries all other unix libraries can be linked against.  (For example, using win32u.so from winevulkan.so).
</pre>
      </blockquote>
      <pre>Pretty much every Unix library can link to one another if they want to, barring abstraction layer issues.
I think this aligns with what Eric is trying to convey.</pre>
    </blockquote>
    Yeah, it's definitely possible to link to any unix library you want,
    but in terms of making sense of the system, it's possibly useful to
    clearly differentiate between unix libraries which in addition to
    their primary purpose can also be used as helper libraries for other
    unix libraries (like ntdll, win32u), and which unix libraries have
    the sole purpose of providing a link to the unix world for an
    optional PE dll (bcrypt, gphoto2, winegstreamer, winepulse, etc).<br>
    <br>
    The former category would be those providing what Eric referred to
    as "kernel features".</div></blockquote></div></div><div dir="auto"><br></div><div dir="auto">You're right. Maybe I wasn't reading this thoroughly...</div><div dir="auto"></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>
    <blockquote type="cite">
      <pre></pre>
      <blockquote type="cite">
        <blockquote type="cite">
          <pre>   avicap32.so, bcrypt.so, capi2032.so, crypt32.so, ctapi32.so, dnsapi.so,
   dwrite.so, gphoto2.so, kerberos.so, mountmgr.so, msv1_0.so, netapi32.so,
   nsiproxy.so, odbc32.so, opencl.so, qcap.so, sane.so, secur32.so, winealsa.so,
   winebus.so, winecoreaudio.so, winegstreamer.so, wineoss.so, winepulse.so,
   winevulkan.so, winspool.so, wldap32.so, wpcap.so, ws2_32.so

</pre>
          <blockquote type="cite">
            <pre>- exception handling?
</pre>
          </blockquote>
          <pre>To accurately mimic stack unwinding as it happens on Windows, one should stick to the syscall interface instead of the unixlib interface.
</pre>
        </blockquote>
        <pre>Assuming you're referring to the __wine_init_unix_lib approach, the unixlib interface doesn't even exist anymore.  (Was removed right before wine 7.0-rc1)
</pre>
      </blockquote>
      <pre>I really meant __wine_unix_call.  There's no syscall gate in-between, exposing DWARF frames that could confuse Win32 debuggers/monitors (probably as part of some DRM/obfuscation/anti-RE)</pre>
    </blockquote>
    <p>__wine_unix_call is part of the syscall interface, so you won't
      run into the problems mentioned by using it.<br>
    </p>
    <p><a href="https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/ntdll/ntdll.spec#l1640" target="_blank" rel="noreferrer">https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/ntdll/ntdll.spec#l1640</a>
      :<br>
    </p>
    <p>
      </p><blockquote type="cite"><span style="color:rgb(0,0,0);font-family:monospace;font-size:12px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:pre-wrap;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;display:inline!important;float:none">@ stdcall </span><span style="color:rgb(0,0,0);font-family:monospace;font-size:12px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:pre-wrap;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial">-</span><span style="color:rgb(0,0,0);font-family:monospace;font-size:12px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:pre-wrap;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;display:inline!important;float:none">syscall __wine_unix_call</span><span style="color:rgb(0,0,0);font-family:monospace;font-size:12px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:pre-wrap;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial">(</span><span style="color:rgb(0,0,0);font-family:monospace;font-size:12px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:pre-wrap;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;display:inline!important;float:none">int64 long ptr</span><span style="color:rgb(0,0,0);font-family:monospace;font-size:12px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:pre-wrap;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial">)</span></blockquote></div></blockquote></div></div><div dir="auto">I stand corrected.</div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><blockquote type="cite"><br>
      </blockquote>
    <p></p>
    <blockquote type="cite">
      <pre></pre>
      <blockquote type="cite">
        <blockquote type="cite">
          <pre>This way, unix-side stack frames will never appear in RtlVirtualUnwind() output (since they are effectively kernel-mode frames, not user-mode ones).


</pre>
        </blockquote>
        <pre></pre>
      </blockquote>
      <pre></pre>
    </blockquote>
  </div>

</blockquote></div></div></div>