[LLVMdev] Technical details discussion for SEH

JB Feldman jb.feldman at kyrus-tech.com
Fri Jan 31 16:27:11 PST 2014


If LLVM can emit code that runs ok from the OS, I think what I'm trying
to do should be doable, if frustrating to implement. Can you point me to
the code that handles this functionality? I haven't poked around much,
but I can tell from reading the exception handling spec that this isn't
the default behavior. Unless I'm seriously missing things, SEH requires
placing exception handlers on the stack along with the code that they
handle, the fact that everything calls into the same _except_handler3
function is simply a matter of implementation, but the OS needs the
address of the first handler to be in fs:[0], which did not sound like
the exception handling behavior described in the documentation.

The answer to your other question is yes, LLVM transforms!

On 1/31/14, 4:41 PM, endlessroad1991 at gmail.com wrote:
> Short version: "something that works at all" - yes, "visual c++ style
> SEH" - no.
> Long version: this whole SEH mechanism breaks down to two levels,
> actually: operating system level and compiler level.
> For the operating system level, after OS catches any software/hardware
> exception, it just calls RtlUnwind to walk the stack and find the
> first stack frame that may handle this exception and execute handler
> defined in that stack frame, until exception is handled or we have to
> abort the whole program. And when the handler is called, a pointer to
> language-specific exception data is provided. On the OS level, OS
> doesn't care what the handler is, and is not responsible for providing
> the language-specific data to the exception handler; it just calls the
> handler.
> The handler and language-specific data passed to exception handler are
> decided on the compiler level. For example, for C programs, the
> handler is _except_handler3 in CRT, for .NET program, it's some
> function in .NET runtime.
> LLVM can emit code that runs fine on operating system level. The
> handler is provided by GCC runtime, and language-specific data is
> Dwarf EH data. This way we can make Dwarf style C++ exception work (on
> top of operating system level SEH). But we cannot link llvm-generated
> code and VC-generated code together, because C++ exception model is
> different.
> For VC-style SEH, it uses _except_handler3 in CRT as exception
> handler(for every stack frame that is compiled with SEH turned on),
> and use extra stack space as language-specific data structure passed
> to _except_handler3. This is not implemented in LLVM.
> Hope this explains something for you. IMHO, writing Windows driver
> using an other-than-VC compiler seems a lot of trouble.. Is there some
> feature of clang that you really want and is missing in VC?
> On Sat, Feb 1, 2014 at 6:49 AM, Jb Feldman <jb.feldman at kyrus-tech.com
> <mailto:jb.feldman at kyrus-tech.com>> wrote:
>     Can you clarify what you mean by "real SEH handling"? My company
>     has me looking at this in the hopes that I can make LLVM capable
>     of building windows drivers. If you mean "visual c++ style SEH",
>     I'm fairly sure that isn't necessary for my purposes, but it would
>     be nice. If you mean "something that works at all," then your
>     concern about generalizing LLVM exception handling probably means
>     that I will need to do some work learning about how exception
>     handling is currently implemented. Do you have a link to the patch
>     your discussing, or a revision number?
>     Thanks,
>     JB
>     On Fri, Jan 31, 2014 at 6:41 AM, Kai Nacke <kai.nacke at redstar.de
>     <mailto:kai.nacke at redstar.de>> wrote:
>         Hi Jb, Hi Tong,
>         with my patch LLVM emits unwind information for Windows 64bit.
>         The Dwarf EH encoding is used language specific data. That is
>         the same way gcc implements SEH for Windows 64bit. (As a side
>         note, PR18546 now contains a patch for Clang to use my patch
>         on mingw64.)
>         The rational behind this approach is that Windows provides
>         support for stack unwinding (RtlUnwind etc.) but LLVM is
>         inherently based on Dwarf EH. This approach combine both
>         worlds. If the personality function is tolerant enough then it
>         should also be possible to mix exceptions.
>         If you want to make exception handling MS compatible then you
>         can take my code as base. You only need to emit the MS handler
>         data instead of the Dwarf data.
>         However, at least as a first approach I would recommend to
>         implement 32bit SEH with a similar approach. It should have
>         some similarities to SjLj exception handling - this really
>         helps to understand what needs to be done.
>         "real SEH handling" requires a small function which is called
>         to decide if the exception is handled. If yes then the handler
>         is called. If not then stack unwinding continues (after a
>         possible call of a cleanup handler). I found it difficult (if
>         not impossible) to create this code based on the exception
>         design of LLVM. IMHO, some some generalizations are required.
>         Regards,
>         Kai
>         On 31.01.2014 05:29, endlessroad1991 at gmail.com
>         <mailto:endlessroad1991 at gmail.com> wrote:
>             Hi Jb,
>             It's good to see someone step up and take a shot as this
>             again. I
>             dropped this because it seems to me it wasn't a high
>             priority task for
>             LLVM/Clang.
>             Implementing SEH is more of LLVM work than Clang work.
>             For 32-bit SEH, there are prologue/epilogue instruction
>             sequence to
>             emit, setting try-level ([ebp-4]), recovering EBP
>             ([ebp-18h]), and all
>             these can only happen in LLVM, not Clang. In my opinion,
>             we should
>             implement these as LLVM intrinsics, like the gcc ones: see
>             http://llvm.org/docs/ExceptionHandling.html#exception-handling-intrinsics.
>             Also, we should emit the tables for each function, which
>             is not a simple
>             task either.
>             For 64-bit SEH, things are simpler. There are no more
>             instructions to
>             emit than no-SEH code. We have only two tasks: emit the
>             table for each
>             function, and place some code right. If I remember it
>             correctly,
>             __finally block code should be replicated at 2 places: one
>             in the
>             original function as part of the normal execution path,
>             and other one
>             separately if anything in __try block goes south.
>             As for the table part, I've seen some commits from Kai(as
>             CC'ed in this
>             email) doing it, you should ask him for details.
>             Thanks again.
>             --
>             Best Regards, Tong Shen (沈彤)
>             _______________________________________________
>             LLVM Developers mailing list
>             LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu>
>             http://llvm.cs.uiuc.edu
>             http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
> -- 
> Best Regards, Tong Shen (沈彤)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140131/081432a2/attachment.html>

More information about the llvm-dev mailing list