[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Windows support in libobjc2
From: |
David Chisnall |
Subject: |
Re: Windows support in libobjc2 |
Date: |
Thu, 2 Aug 2018 18:03:00 +0100 |
On 2 Aug 2018, at 16:46, Paul Landers <Paul.Landers@eggplant.io> wrote:
>
>> Is anyone using Windows and GNUstep?
>
> This is great! We at testplant use GNUstep on windows extensively.
I’ll try to put some binaries online for people to test tomorrow.
>> Have you, before this, tried using libobjc2 with clang with mingw64 w/
>> msys, or with cygwin?
>
> Our current environment is msys2(mingw-w64) with some older versions of
> libobjc2 and clang. We are looking to update those versions soon though, and
> the clang patches should be very helpful!
I haven’t used MinGW for many years, but it looks as if they provide three
different exception models:
- DWARF: Itanium-style unwinding. The same thing that most *NIX platforms use.
Not interoperable with MSVC-built code or with exceptions thrown by system
libraries.
- sjlj: GCC’s setjmp/longjmp EH support, intended for platforms where there’s
no native EH support. Doesn’t depend on a stack unwinder, but has a high cost
for every @try block. Not supported by clang.
- SEH: Windows Structured Exception Handling. Low overhead, interoperates with
Windows native libraries, but requires a recent GCC or an even more recent
clang.
The Windows exception model is quite complicated, because it doesn’t unwind the
stack until the exception is caught. On most *NIX systems, there’s an
iterative process that first scans the stack to see if there’s a handler, then
pops each stack frame that has any cleanups off the stack and runs the cleanups
from the next one on top. On Windows, the stack remains intact and each frame
provides ‘funclets’ that run on top of the stack with a pointer to the real
stack frame. This has some nice properties (it can easily be extended to
support resumable exceptions and it is possible to throw an out-of-memory
exception because, unlike the *NIX model, throwing an exception doesn’t
allocate heap memory [though you can’t throw an out-of-stack-space exception,
because it does allocate stack memory]).
The new code in libobjc2 supports SEH exceptions. Most of this was contributed
by the WinObjC team, I extended it to work with Win64 and added support for SEH
to the assembly code paths, so you can (for example) throw an exception from a
+initialize method and have it correctly propagated up to whatever sent the
message that triggered the +initialize.
>> Could you clarify what you mean by using with a different linker?
>
> I can’t recall too much about our environment, but I can say for all recent
> versions of the mingw version of clang, the clang linker still has not worked
> and it has used the gcc linker instead. I do not have Visual Studio (etc)
> installed.
The main requirement from the linker is that it correctly sorts things in PE
sections lexically by subsection[1]. I don’t know if GNU ld does, but I
believe either Microsoft’s link.exe or LLVM’s lld will work. If you can test
with GNU ld, that would be helpful.
When building libobjc2, we also rely on the linker to figure out if we refer to
__imp_objc_msgSend, but objc_msgSend is provided locally, that we actually mean
the local version. I think the GNU linker sulks about this, link.exe just
tells you that you’re a numpty[2] and continues. This is because clang doesn’t
know whether you’re building the Objective-C runtime or not and so assumes that
objc_msgSend and a bunch of other helper functions are dllimport (because in
all code that isn’t an Objective-C runtime, they are).
David
[1] On ELF platforms, we rely on GNU linker behaviour to emit magic
__start_{section name} and __stop_{section name} symbols. On PE/COFF, we emit
everything in {section name}$m and then emit zero-sized {section name}$a and
{section name}$z symbols to mark the beginning and end of the sections.
[2] Not an actual error message.