tech-toolchain archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: [RFC] Improving compatibility of NetBSD's unwind.h (or replacing it?)



On Fri, 2018-12-07 at 23:22 +0000, Christos Zoulas wrote:
> In article <1544216124.17308.17.camel%gentoo.org@localhost>,
> Micha  Górny  <mgorny%gentoo.org@localhost> wrote:
> > -=-=-=-=-=-
> > 
> > Hi,
> > 
> > While working on building more LLVM projects on NetBSD, I've noticed
> > that libcxxabi fails to build due to incompatible unwind.h.  The example
> > of problematic code is [1]:
> > 
> >  _Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
> >                reinterpret_cast<uintptr_t>(unwind_exception));
> >  _Unwind_SetGR(context, __builtin_eh_return_data_regno(1),
> >                static_cast<uintptr_t>(results.ttypeIndex));
> >  _Unwind_SetIP(context, results.landingPad);
> > 
> > This fails to build because NetBSD's unwind.h expects the last argument
> > to _Unwind_Set{GR,IP} to be a pointer.  However, it seems that other
> > implementations expect an unsigned integer type instead.  The types used
> > for the last argument of appropriate functions (and return type of their
> > respective _Unwind_Get* counterparts) are:
> > 
> >                        SetGR/GetGR   SetIP/GetIP
> >  gcc 7.3.0 on Linux    _Unwind_Word  _Unwind_Ptr   (-> unsigned [a])
> >  clang                 _Unwind_Word  _Unwind_Word  (-> uintptr_t)
> >  llvm-libunwind        uintptr_t     uintptr_t
> >  libunwind 1.2.1       uns. long     uns. long
> > 
> >  [a] gcc is doing some __attribute__ magic on top of it
> > 
> > I think changing our header to use unsigned integer type alike other
> > implementations is the way to go.  Does this sound like the right thing
> > to do?
> > 
> > [1]:https://github.com/llvm-mirror/libcxxabi/blob/master/src/cxa_personality.cpp#L528
> > 
> 
> First we have to figure out why we have so many:
> 
> ./external/bsd/llvm/dist/clang/lib/Headers/unwind.h
> ./external/bsd/libc++/dist/libcxxrt/src/unwind.h
> 
> Ok, these 4 can be excluded I guess:
> ./external/gpl3/binutils/dist/include/mach-o/unwind.h
> ./external/gpl3/binutils.old/dist/include/mach-o/unwind.h
> ./external/gpl3/gdb/dist/include/mach-o/unwind.h
> ./external/gpl3/gdb.old/dist/include/mach-o/unwind.h
> 
> This I wrote IIRC, and it could/should be normalized:
> ./lib/libexecinfo/unwind.h 
> 
> ./sys/lib/libunwind/unwind.h
> 
> Are the others the same?
> 

Disclaimer:  I don't consider myself an expert on this.  I'm mostly
sharing what I've figured out over the time fighting clang.


I suppose the answer to 'so many' boils down to 'historical reasons'.

GCC certainly carries its own unwinder implementation in libgcc*.
On Linux, it also installs matching copy of unwind.h but apparently not
on other systems.

Then, clang doesn't have a built-in unwinder library but can use
the one from libgcc* when using the gcc runtime.  I suppose that's why
it installs its own unwind.h -- to be able to use the gcc library when
nothing else provides that header.

Then, there are out-of-the-compiler unwinder libraries which include
both the library and the matching header.  This includes libunwind
('nongnu'), llvm-libunwind, apparently libexecinfo.  Why?  Possibly
because they don't depend on compiler internals, and maybe provide
a wider API.  Clang can use them instead of gcc's built-in unwinder
library.

In the end, they all seem to share some kind of shared API that's
apparently compatible enough to somewhat work with different libunwind
implementations (or at least not fail horribly).  Apparently it's
defined as part of the binary ABI.

-- 
Best regards,
Michał Górny

Attachment: signature.asc
Description: This is a digitally signed message part



Home | Main Index | Thread Index | Old Index