iphone + LDC, a new ARM adventure

Dan Olson zans.is.for.cans at yahoo.com
Mon Jan 6 09:36:55 PST 2014


David Nadlinger <code at klickverbot.at> writes:

> They are for (un)registering the exception handling context with the
> global table of active handlers. The parameter to
> _Unwind_SjLj_Register is constructed by the setjmp() part of SJLJ
> (it's in fact an optimized, inlined version instead of an actual
> function call).  When an exception is raised, this global linked list
> is walked, calling the personality functions for the respective
> entries to determine whether to longjmp to them.
>
>> I read llvm source code for a while yesterday and really haven't wrapped
>> by brain around it yet.
>
> I'd start out by getting a feel for the LLVM IR we need to generate.
> For this, you can have a look at the respective Clang output (-S
> -emit-llvm). The LLVM docs also have a page on the subject, but
> unfortunately, it is rather sparse:
> http://llvm.org/docs/ExceptionHandling.html#setjmp-longjmp-exception-handling
>
> The more involved part will likely be to get the personality function
> right. Fortunately, at least the related parts of libunwind are open
> source: http://www.opensource.apple.com/source/libunwind/libunwind-35.3/src/Unwind-sjlj.c.
> The source for the GCC/Clang personality function
> (__gxx_personality_sj0) is probably available somewhere as well, but I
> don't know where to look right now (libc++, probably).
>
> David

I decided it was time to carefully study what clang is doing.
A grep of SjLj in the llvm source and build trees hopefully is
showing where I should pay attention to the design.

In ToolChains.cpp I see how sjlj is enabled.

bool Darwin::UseSjLjExceptions() const {
  // Darwin uses SjLj exceptions on ARM.
  return (getTriple().getArch() == llvm::Triple::arm ||
          getTriple().getArch() == llvm::Triple::thumb);
}

And then in CodeGen/Passes.cpp I see that SjLj has to work with
dwarf eh.  It is in the SjLjEHPrepare class code that something goes
wrong with ldc2.

  switch (TM->getMCAsmInfo()->getExceptionHandlingType()) {
  case ExceptionHandling::SjLj:
    // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both
    // Dwarf EH prepare needs to be run after SjLj prepare. Otherwise,
    // catch info can get misplaced when a selector ends up more than one block
    // removed from the parent invoke(s). This could happen when a landing
    // pad is shared by multiple invokes and is also a target of a normal
    // edge from elsewhere.
    addPass(createSjLjEHPreparePass(TM->getTargetLowering()));
    // FALLTHROUGH
  case ExceptionHandling::DwarfCFI:
  case ExceptionHandling::ARM:
  case ExceptionHandling::Win64:
    addPass(createDwarfEHPass(TM));
    break;

I'll spend some more time over the next few days and see what clang
does to make the sjlj pass happy.

Thanks for all the help so far,
Dan


More information about the digitalmars-d-ldc mailing list