LibUnwind into Compiler-RT?

So, I remember we discussed this earlier this year, but I can't find the thread.

The idea is to move libunwind into compiler-rt for the simple reasons below:

1. Unwinding is not exclusive to C++, nor exception handling.
2. Clang still includes libgcc_s and libgcc_eh when using compiler-rt
(maybe eh isn't needed, but it was there for libgcc).
3. Testing the libunwind with libc++ on ARM is not possible, because
libgcc_s merges RT abi with unwind, duplicating the implementation of
some, but not all, unwind functions.

I'm not sure how the move would take place, but I remember most people
being in favour, so I'm expecting that someone already has a plan. :slight_smile:

I'm guessing that the libgcc_eh EH functions are implemented in
libc++, while the libgcc_s unwind is in libc++abi. If not, we might
have a hard time linking them together independently.

We'd have to be sure to move the tests as well, which could be the
hardest part, since all libc++ unwind-depending tests would have to
either be moved or rely on implicit dependencies.

An alternative to fix the libc++ tests on ARM would be to require
Compiler-RT to be there as well, but, as I said, Clang links gcc_eh
and gcc_s when you choose --rtlib=compiler-rt, making the exercise
moot.

Or we could just say that libc++ *needs* compiler-RT and call it a day.

Ideas?

cheers,
--renato

I remember there being a ARM EHABI reason why this won't work, but I don't
remember the specifics. IIRC, had something to do with how c++ rtti is required
to be handled by the catch handlers, and would mean layering problems if we
moved it. Antoine, do you remember the specifics?

So, I remember we discussed this earlier this year, but I can't find the thread.

The idea is to move libunwind into compiler-rt for the simple reasons below:

1. Unwinding is not exclusive to C++, nor exception handling.
2. Clang still includes libgcc_s and libgcc_eh when using compiler-rt
(maybe eh isn't needed, but it was there for libgcc).
3. Testing the libunwind with libc++ on ARM is not possible, because
libgcc_s merges RT abi with unwind, duplicating the implementation of
some, but not all, unwind functions.

I do compiler_rt + libc++abi + libc++ + clang (with a custom ToolChain) testing
of libc++ on bare-metal ARM.... so it is possible. Perhaps you mean to say that
it's not possible to test libunwind on arm-linux when using compiler_rt?

I'm not sure how the move would take place, but I remember most people
being in favour, so I'm expecting that someone already has a plan. :slight_smile:

I'm guessing that the libgcc_eh EH functions are implemented in
libc++, while the libgcc_s unwind is in libc++abi. If not, we might
have a hard time linking them together independently.

We'd have to be sure to move the tests as well, which could be the
hardest part, since all libc++ unwind-depending tests would have to
either be moved or rely on implicit dependencies.

An alternative to fix the libc++ tests on ARM would be to require
Compiler-RT to be there as well, but, as I said, Clang links gcc_eh
and gcc_s when you choose --rtlib=compiler-rt, making the exercise
moot.

Clang's code isn't frozen... :wink:

Or we could just say that libc++ *needs* compiler-RT and call it a day.

This makes me uncomfortable (which I gather is what you're going for) in that
not saying so, and maintaining compatibility to build with libgcc as the rtlib
keeps us honest.

Cheers,

Jon

I do compiler_rt + libc++abi + libc++ + clang (with a custom ToolChain) testing
of libc++ on bare-metal ARM.... so it is possible. Perhaps you mean to say that
it's not possible to test libunwind on arm-linux when using compiler_rt?

Yeah, it's hard and clumsy, not impossible.

Basically, I want to avoid requiring people to link against
libunwind+rt+libcxxabi if all they need is libcxx or rt.

An alternative to fix the libc++ tests on ARM would be to require
Compiler-RT to be there as well, but, as I said, Clang links gcc_eh
and gcc_s when you choose --rtlib=compiler-rt, making the exercise
moot.

Clang's code isn't frozen... :wink:

I know, I put it there. :slight_smile:

I did it because that was what libgcc required, and I didn't want to
make compiler-RT depend on libc++, at least not at a Clang level.
Since gcc_s and gcc_eh are both provided by libgcc, it makes sense in
the GNU case. Maybe, a better approach would be to warn users if they
choose compiler-rt (via --rtlib=compiler-rt) and not libunwind or
libgcc_s variants.

The other problem is symbol clashing. If we start including multiple
libraries that implement and export the same symbols, we'll be in
trouble soon enough. This already happens with --rtlib=compiler-rt and
will happen if I include -lgcc_s on libc++abi tests on ARM (for the
RTABI part). Having libunwind on its own repository is also not a
horrible idea, but I don't know the logistics of that.

Or we could just say that libc++ *needs* compiler-RT and call it a day.

This makes me uncomfortable (which I gather is what you're going for) in that
not saying so, and maintaining compatibility to build with libgcc as the rtlib
keeps us honest.

Me too, but I have to say it's by far the easiest option.

We only have that kind of problem because we split the symbols in a
way that is different than GNU tools, so that we'll always have
clashes when we try to interoperate. The other easy option is to split
in the *exact* same way as libgcc, so that we can mix and match, but
that's not free of problems, either.

Someone with more knowledge in linkers can chime in on how the symbols
are dropped, so that at least we can be sure of which library
overrides which.

cheers,
--renato

I remember there being a ARM EHABI reason why this won't work, but I don't
remember the specifics. IIRC, had something to do with how c++ rtti is
required
to be handled by the catch handlers, and would mean layering problems if we
moved it. Antoine, do you remember the specifics?

For a complete implementation, the arm-defined PRs
(__aeabi_unwind_cpp_pr[0-2]) need to call the functions in 8.4.2 in phase
2, which are in libc++abi. In particular, as you mention, __cxa_type_match
needs the rtti info.

That said, currently this part is not implemented in libunwind, among
others because clang never generates code that uses arm-defined PRs for
exceptions and cleanup, only for trivial frame unwinding (it always uses
__gxx_personality_v0 for exceptions/cleanup), so I don't think today
libunwind depends on libc++abi, except for the recent patch for
_Unwind_Backtrace.

Antoine

That said, currently this part is not implemented in libunwind, among others
because clang never generates code that uses arm-defined PRs for exceptions
and cleanup, only for trivial frame unwinding (it always uses
__gxx_personality_v0 for exceptions/cleanup),

AFAIK, we'll be using the gxx_personality_v0 for the time being.

so I don't think today
libunwind depends on libc++abi, except for the recent patch for
_Unwind_Backtrace.

Which patch?

--renato

> That said, currently this part is not implemented in libunwind, among
others
> because clang never generates code that uses arm-defined PRs for
exceptions
> and cleanup, only for trivial frame unwinding (it always uses
> __gxx_personality_v0 for exceptions/cleanup),

AFAIK, we'll be using the gxx_personality_v0 for the time being.

The question is whether or not you want to support non-clang compiled code
with libunwind.

> so I don't think today
> libunwind depends on libc++abi, except for the recent patch for
> _Unwind_Backtrace.

Which patch?

http://reviews.llvm.org/rL217459

Antoine

I do compiler_rt + libc++abi + libc++ + clang (with a custom ToolChain) testing
of libc++ on bare-metal ARM.... so it is possible. Perhaps you mean to say that
it's not possible to test libunwind on arm-linux when using compiler_rt?

Yeah, it's hard and clumsy, not impossible.

Basically, I want to avoid requiring people to link against
libunwind+rt+libcxxabi if all they need is libcxx or rt.

An alternative to fix the libc++ tests on ARM would be to require
Compiler-RT to be there as well, but, as I said, Clang links gcc_eh
and gcc_s when you choose --rtlib=compiler-rt, making the exercise
moot.

Clang's code isn't frozen... :wink:

I know, I put it there. :slight_smile:

I did it because that was what libgcc required, and I didn't want to
make compiler-RT depend on libc++, at least not at a Clang level.
Since gcc_s and gcc_eh are both provided by libgcc, it makes sense in
the GNU case. Maybe, a better approach would be to warn users if they
choose compiler-rt (via --rtlib=compiler-rt) and not libunwind or
libgcc_s variants.

The other problem is symbol clashing. If we start including multiple
libraries that implement and export the same symbols, we'll be in
trouble soon enough. This already happens with --rtlib=compiler-rt and
will happen if I include -lgcc_s on libc++abi tests on ARM (for the
RTABI part). Having libunwind on its own repository is also not a
horrible idea, but I don't know the logistics of that.

Or we could just say that libc++ *needs* compiler-RT and call it a day.

This makes me uncomfortable (which I gather is what you're going for) in that
not saying so, and maintaining compatibility to build with libgcc as the rtlib
keeps us honest.

Me too, but I have to say it's by far the easiest option.

We only have that kind of problem because we split the symbols in a
way that is different than GNU tools, so that we'll always have
clashes when we try to interoperate. The other easy option is to split
in the *exact* same way as libgcc, so that we can mix and match, but
that's not free of problems, either.

The only idea I heard back when this was previously discussed would be
to put all of compiler-rt, libunwind, and libc++abi into one project with
platform specific build rules to pull the right mix of code into the right
libraries for each platform.
But at the time compiler-rt had a “very unique” build system, making it
hard to merge with other more conventional CMake based systems.

Someone with more knowledge in linkers can chime in on how the symbols
are dropped, so that at least we can be sure of which library
overrides which.

I do know that libunwind is API compatible with libgcc_s but uses different
data structure layouts, so the two are not ABI compatible. That means
in any process all the unwinding APIs have to come one or the other - no mixing.

-Nick

The question is whether or not you want to support non-clang compiled code with libunwind

This is required for Android for the time being.

The only idea I heard back when this was previously discussed would be
to put all of compiler-rt, libunwind, and libc++abi into one project with
platform specific build rules to pull the right mix of code into the right
libraries for each platform.

This would be a build nightmare, but if people more familiar with
CMake are comfortable, I'm ok with it.

I do know that libunwind is API compatible with libgcc_s but uses different
data structure layouts, so the two are not ABI compatible. That means
in any process all the unwinding APIs have to come one or the other - no mixing.

I didn't mean mixing unwind libraries themselves, but mixing libgcc +
libunwind or compiler-rt + libgcc_s or compiler-rt + libunwind.

The problem is that libgcc_s contains some, but not all, of the unwind
routines, in addition to RT calls (such as hardware divide, etc). For
that reason, libunwind cannot be linked with libgcc without libgcc_s
on ARM. Also, libgcc_eh has the rest of the unwinding functions for
C++, which is more in line with libc++, not libunwind or libc++abi.

Is there any case where people use libc++ with libgcc? Or are all
toolchains using compiler-rt? I can do that, at least on ARM, so that
we avoid any code movement for the time being. I don't *need* to use
libgcc at all, I'm just trying to figure out the best way to do things
on ARM.

cheers,
--renato