<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 18.04.22 12:35, Jinoh Kang wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:a3263138-b1bf-efbc-269d-7ddbfb1f2431@gmail.com">
      <pre class="moz-quote-pre" wrap="">On 4/18/22 22:37, Derek Lesho wrote:
</pre>
      <blockquote type="cite">
        <pre class="moz-quote-pre" wrap="">
On 16.04.22 03:58, Jinoh Kang wrote:
</pre>
        <blockquote type="cite">
          <pre class="moz-quote-pre" wrap="">On 4/15/22 00:26, Eric Pouech wrote:
</pre>
          <blockquote type="cite">
            <pre class="moz-quote-pre" wrap="">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 class="moz-quote-pre" wrap="">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 class="moz-quote-pre" wrap="">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 class="moz-quote-pre" wrap="">
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>
    <blockquote type="cite"
      cite="mid:a3263138-b1bf-efbc-269d-7ddbfb1f2431@gmail.com">
      <pre class="moz-quote-pre" wrap="">

</pre>
      <blockquote type="cite">
        <pre class="moz-quote-pre" wrap="">  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 class="moz-quote-pre" wrap="">
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"
      cite="mid:a3263138-b1bf-efbc-269d-7ddbfb1f2431@gmail.com">
      <pre class="moz-quote-pre" wrap="">

</pre>
      <blockquote type="cite">
        <blockquote type="cite">
          <pre class="moz-quote-pre" wrap="">
</pre>
          <blockquote type="cite">
            <pre class="moz-quote-pre" wrap="">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 class="moz-quote-pre" wrap="">I confirm that win32u.so also exists.

Here is a list of other Unixlibs:
</pre>
        </blockquote>
        <pre class="moz-quote-pre" wrap="">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 class="moz-quote-pre" wrap="">
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".<br>
    <blockquote type="cite"
      cite="mid:a3263138-b1bf-efbc-269d-7ddbfb1f2431@gmail.com">
      <pre class="moz-quote-pre" wrap="">

</pre>
      <blockquote type="cite">
        <blockquote type="cite">
          <pre class="moz-quote-pre" wrap="">
   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 class="moz-quote-pre" wrap="">- exception handling?
</pre>
          </blockquote>
          <pre class="moz-quote-pre" wrap="">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 class="moz-quote-pre" wrap="">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 class="moz-quote-pre" wrap="">
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 class="moz-txt-link-freetext" href="https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/ntdll/ntdll.spec#l1640">https://source.winehq.org/git/wine.git/blob/HEAD:/dlls/ntdll/ntdll.spec#l1640</a>
      :<br>
    </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; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: pre; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; display: inline !important; float: none;">@ stdcall </span><span class="hl opt" 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; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: pre; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; 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; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: pre; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; display: inline !important; float: none;">syscall __wine_unix_call</span><span class="hl opt" 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; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: pre; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; 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; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: pre; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; display: inline !important; float: none;">int64 long ptr</span><span class="hl opt" 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; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: pre; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">)</span><br>
      </blockquote>
    </p>
    <blockquote type="cite"
      cite="mid:a3263138-b1bf-efbc-269d-7ddbfb1f2431@gmail.com">
      <pre class="moz-quote-pre" wrap="">

</pre>
      <blockquote type="cite">
        <blockquote type="cite">
          <pre class="moz-quote-pre" wrap="">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 class="moz-quote-pre" wrap="">
</pre>
      </blockquote>
      <pre class="moz-quote-pre" wrap="">

</pre>
    </blockquote>
  </body>
</html>