Using unwind-forcedunwind.c from nptl/sysdeps/pthread doesn't work well on ARM, see nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c for an explanation.
The following code example shows what's wrong without the ARM-specific version.
--------------------------------------------------------------------
struct Foo { ~Foo(); };
Foo::~Foo() {}
void f() { Foo a; throw 0; }
int main() { try { f(); } catch (int) { std::cerr << "caught" << std::endl; } return 0; } --------------------------------------------------------------------
Compile without any optimizations (it's important that Foo's destructor is not inlined) and link with -lpthread. The thrown exception is not caught as expected and the program aborts.
Signed-off-by: Ignacy Gawędzki ignacy.gawedzki@green-communications.fr --- libpthread/nptl/sysdeps/pthread/Makefile.in | 4 ++-- libpthread/nptl/sysdeps/pthread/pthread-unwind-forcedunwind.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 libpthread/nptl/sysdeps/pthread/pthread-unwind-forcedunwind.c
diff --git a/libpthread/nptl/sysdeps/pthread/Makefile.in b/libpthread/nptl/sysdeps/pthread/Makefile.in index 9d99f31..6325c0d 100644 --- a/libpthread/nptl/sysdeps/pthread/Makefile.in +++ b/libpthread/nptl/sysdeps/pthread/Makefile.in @@ -40,7 +40,7 @@ CFLAGS-pthread_barrier_wait.c = -D_GNU_SOURCE CFLAGS-pthread_spin_destroy.c = -D_GNU_SOURCE CFLAGS-pthread_spin_init.c = -D_GNU_SOURCE CFLAGS-pthread_spin_unlock.c = -D_GNU_SOURCE -CFLAGS-unwind-forcedunwind.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-pthread-unwind-forcedunwind.c = -fexceptions -fasynchronous-unwind-tables
CFLAGS-OMIT-librt-cancellation.c = -DIS_IN_libpthread CFLAGS-OMIT-rt-unwind-resume.c = -DIS_IN_libpthread @@ -49,7 +49,7 @@ CFLAGS-librt-cancellation.c = -DIS_IN_librt \ CFLAGS-rt-unwind-resume.c = -DIS_IN_librt \ -fexceptions -fasynchronous-unwind-tables
-libpthread-so-y += $(patsubst %,$(libpthread_pthread_OUT)/%.oS, unwind-forcedunwind) +libpthread-so-y += $(patsubst %,$(libpthread_pthread_OUT)/%.oS, pthread-unwind-forcedunwind)
librt-pt-routines-y = librt-cancellation.c librt-pt-shared-only-routines-y = rt-unwind-resume.c diff --git a/libpthread/nptl/sysdeps/pthread/pthread-unwind-forcedunwind.c b/libpthread/nptl/sysdeps/pthread/pthread-unwind-forcedunwind.c new file mode 100644 index 0000000..fc04eb4 --- /dev/null +++ b/libpthread/nptl/sysdeps/pthread/pthread-unwind-forcedunwind.c @@ -0,0 +1 @@ +#include <unwind-forcedunwind.c>
Hi Ignacy, Ignacy Gawędzki wrote,
Using unwind-forcedunwind.c from nptl/sysdeps/pthread doesn't work well on ARM, see nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c for an explanation.
The following code example shows what's wrong without the ARM-specific version.
struct Foo { ~Foo(); };
Foo::~Foo() {}
void f() { Foo a; throw 0; }
int main() { try { f(); } catch (int) { std::cerr << "caught" << std::endl; } return 0; }
Compile without any optimizations (it's important that Foo's destructor is not inlined) and link with -lpthread. The thrown exception is not caught as expected and the program aborts.
Can you please try with 1.0.18? I can not reproduce the issue with 1.0.18.
I just get "caught" with the test app.
May be it was accidentally fixed in the release.
best regards Waldemar
On Sat, Oct 01, 2016 at 01:22:37PM +0200, thus spake Waldemar Brodkorb:
Can you please try with 1.0.18? I can not reproduce the issue with 1.0.18.
I just get "caught" with the test app.
May be it was accidentally fixed in the release.
I don't get the uncaught exception with 1.0.18 indeed. This is certainly due to the way libpthread is now integrated into libc. Now the version of Unwind_Resume that is called is always the one from libgcc_1.so, even when using threads. I'm affraid that this is not the right thing to do, because the wrapping code for Unwind_Resume in libpthread was there for some reason.
On Mon, Oct 03, 2016 at 12:26:19PM +0200, thus spake Ignacy Gawedzki:
On Sat, Oct 01, 2016 at 01:22:37PM +0200, thus spake Waldemar Brodkorb:
Can you please try with 1.0.18? I can not reproduce the issue with 1.0.18.
I just get "caught" with the test app.
May be it was accidentally fixed in the release.
I don't get the uncaught exception with 1.0.18 indeed. This is certainly due to the way libpthread is now integrated into libc. Now the version of Unwind_Resume that is called is always the one from libgcc_1.so, even when using threads. I'm affraid that this is not the right thing to do, because the wrapping code for Unwind_Resume in libpthread was there for some reason.
Okay, I've explored that problem a bit more today and I have additional information. It seems that the Unwind_* functions are provided in the libc for local use and are not supposed to be visible for the dynamic linker. Compare that with GNU libc where the Unwind_* symbols are local.
Right now it also seems that none of uClibc's code actually uses these functions, at least in my case, so the incorrect Unwind_Resume inside uClibc is harmless.
The problem I was having with v1.0.17 was that by linking with libpthread, the Unwind_Resume wrapper code in that library was overriding the implementation in libgcc_s that was supposed to be called directly.
Now that libpthread (and librt for that matter) are integrated into libc, it seems the problem is gone, because the libgcc_s implementation is not overridden by uClibc's. But this happens only because libgcc_s.so is listed before libc.so in the .dynamic section, and if it were not the case anymore, for any reason, the problem would reemerge immediately.
You can force the problem to re-emerge by simply preloading libc.so using LD_PRELOAD. This makes uClibc's incorrect implementation of Unwind_Resume to be called and the execution of the example code aborts instead of outputting "caught".
Please find attached the updated patch for v1.0.18. This is more like a quick fix, since a proper fix would most probably be to make those conflicting symbols local in the resulting .so.
Cheers,
Ignacy
Ignacy Gawędzki (1): libpthread/nptl: Use arch-dependent unwind-forcedunwind.c if available
libpthread/nptl/sysdeps/pthread/Makefile.in | 7 +++++-- libpthread/nptl/sysdeps/pthread/pthread-unwind-forcedunwind.c | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 libpthread/nptl/sysdeps/pthread/pthread-unwind-forcedunwind.c
Hi Ignacy, Ignacy Gawędzki wrote,
On Mon, Oct 03, 2016 at 12:26:19PM +0200, thus spake Ignacy Gawedzki:
On Sat, Oct 01, 2016 at 01:22:37PM +0200, thus spake Waldemar Brodkorb:
Can you please try with 1.0.18? I can not reproduce the issue with 1.0.18.
I just get "caught" with the test app.
May be it was accidentally fixed in the release.
I don't get the uncaught exception with 1.0.18 indeed. This is certainly due to the way libpthread is now integrated into libc. Now the version of Unwind_Resume that is called is always the one from libgcc_1.so, even when using threads. I'm affraid that this is not the right thing to do, because the wrapping code for Unwind_Resume in libpthread was there for some reason.
Okay, I've explored that problem a bit more today and I have additional information. It seems that the Unwind_* functions are provided in the libc for local use and are not supposed to be visible for the dynamic linker. Compare that with GNU libc where the Unwind_* symbols are local.
Right now it also seems that none of uClibc's code actually uses these functions, at least in my case, so the incorrect Unwind_Resume inside uClibc is harmless.
But isn't pthread_cancel using pthread_cancel_init from libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c?
The problem I was having with v1.0.17 was that by linking with libpthread, the Unwind_Resume wrapper code in that library was overriding the implementation in libgcc_s that was supposed to be called directly.
I still do not understand the issue. As far as I know, the Unwind* functions in uClibc and GNU libc is wrapper code around gcc libgcc_s.so.1 which is loaded via dlopen at runtime.
I once asked about this on the libc mailinglist: https://sourceware.org/ml/libc-help/2014-07/msg00000.html
Now that libpthread (and librt for that matter) are integrated into libc, it seems the problem is gone, because the libgcc_s implementation is not overridden by uClibc's. But this happens only because libgcc_s.so is listed before libc.so in the .dynamic section, and if it were not the case anymore, for any reason, the problem would reemerge immediately.
You can force the problem to re-emerge by simply preloading libc.so using LD_PRELOAD. This makes uClibc's incorrect implementation of Unwind_Resume to be called and the execution of the example code aborts instead of outputting "caught".
Please find attached the updated patch for v1.0.18. This is more like a quick fix, since a proper fix would most probably be to make those conflicting symbols local in the resulting .so.
But what exactly is fixed by the patch then?
Is it still a ARM specific issue?
Could you take a look at glibc commit: commit 46abb64d6287d09100b147d062f6810066389b7e Author: Roland McGrath roland@hack.frob.com Date: Mon Jan 5 14:01:49 2015 -0800
ARM: Consolidate with generic unwinder wrapper code
I think it would be a better solution to sync with glibc and get rid of the special ARM specific versions.
best regards Waldemar
On Mon, Oct 03, 2016 at 06:13:45PM +0200, thus spake Waldemar Brodkorb:
Hi Ignacy, Ignacy Gawędzki wrote,
On Mon, Oct 03, 2016 at 12:26:19PM +0200, thus spake Ignacy Gawedzki:
On Sat, Oct 01, 2016 at 01:22:37PM +0200, thus spake Waldemar Brodkorb:
Can you please try with 1.0.18? I can not reproduce the issue with 1.0.18.
I just get "caught" with the test app.
May be it was accidentally fixed in the release.
I don't get the uncaught exception with 1.0.18 indeed. This is certainly due to the way libpthread is now integrated into libc. Now the version of Unwind_Resume that is called is always the one from libgcc_1.so, even when using threads. I'm affraid that this is not the right thing to do, because the wrapping code for Unwind_Resume in libpthread was there for some reason.
Okay, I've explored that problem a bit more today and I have additional information. It seems that the Unwind_* functions are provided in the libc for local use and are not supposed to be visible for the dynamic linker. Compare that with GNU libc where the Unwind_* symbols are local.
Right now it also seems that none of uClibc's code actually uses these functions, at least in my case, so the incorrect Unwind_Resume inside uClibc is harmless.
But isn't pthread_cancel using pthread_cancel_init from libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c?
Yes, it looks like it does. But at least _Unwind_Resume doesn't seem to be used at all.
The problem I was having with v1.0.17 was that by linking with libpthread, the Unwind_Resume wrapper code in that library was overriding the implementation in libgcc_s that was supposed to be called directly.
I still do not understand the issue. As far as I know, the Unwind* functions in uClibc and GNU libc is wrapper code around gcc libgcc_s.so.1 which is loaded via dlopen at runtime.
Yes, they are, but the problem is with the way the ARM unwinder works. Obviously, it doesn't expect to have one additional frame added by a call to _Unwind_Resume. This is why in the case of the ARM architecture, a specially-crafted version of the wrapper around _Unwind_Resume is provided which doesn't create a new frame.
I once asked about this on the libc mailinglist: https://sourceware.org/ml/libc-help/2014-07/msg00000.html
Now that libpthread (and librt for that matter) are integrated into libc, it seems the problem is gone, because the libgcc_s implementation is not overridden by uClibc's. But this happens only because libgcc_s.so is listed before libc.so in the .dynamic section, and if it were not the case anymore, for any reason, the problem would reemerge immediately.
You can force the problem to re-emerge by simply preloading libc.so using LD_PRELOAD. This makes uClibc's incorrect implementation of Unwind_Resume to be called and the execution of the example code aborts instead of outputting "caught".
Please find attached the updated patch for v1.0.18. This is more like a quick fix, since a proper fix would most probably be to make those conflicting symbols local in the resulting .so.
But what exactly is fixed by the patch then?
The patch makes _Unwind_Resume in libpthread/nptl/ be implemented by sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c in the case of ARM and by sysdeps/pthread/unwind-forcedunwind.c otherwise. So if libc.so's _Unwind_Resume ever takes over libgcc_s.so's, or if the wrapper around _Unwind_Resume is used in the future, it will simply work transparently.
The way this is achieved is inspired by how it's already done for librt with unwind-resume.c (see sysdeps/pthread/rt-unwind-resume.c).
Is it still a ARM specific issue?
Yes it is.
Could you take a look at glibc commit: commit 46abb64d6287d09100b147d062f6810066389b7e Author: Roland McGrath roland@hack.frob.com Date: Mon Jan 5 14:01:49 2015 -0800
ARM: Consolidate with generic unwinder wrapper code
I think it would be a better solution to sync with glibc and get rid of the special ARM specific versions.
I you look closely at this commit, it's exactly what I'm talking about: it's providing an ARM-specific implementation of _Unwind_Resume in assembly. For other architectures, the generic wrapper is used.
Now I agree with you that the code should sync with glibc's as much as possible in this regard, since the problem is exactly the same.
Cheers,
Ignacy
Hi Ignacy, Ignacy Gawędzki wrote,
On Mon, Oct 03, 2016 at 06:13:45PM +0200, thus spake Waldemar Brodkorb:
Hi Ignacy, Ignacy Gawędzki wrote,
On Mon, Oct 03, 2016 at 12:26:19PM +0200, thus spake Ignacy Gawedzki:
On Sat, Oct 01, 2016 at 01:22:37PM +0200, thus spake Waldemar Brodkorb:
Can you please try with 1.0.18? I can not reproduce the issue with 1.0.18.
I just get "caught" with the test app.
May be it was accidentally fixed in the release.
I don't get the uncaught exception with 1.0.18 indeed. This is certainly due to the way libpthread is now integrated into libc. Now the version of Unwind_Resume that is called is always the one from libgcc_1.so, even when using threads. I'm affraid that this is not the right thing to do, because the wrapping code for Unwind_Resume in libpthread was there for some reason.
Okay, I've explored that problem a bit more today and I have additional information. It seems that the Unwind_* functions are provided in the libc for local use and are not supposed to be visible for the dynamic linker. Compare that with GNU libc where the Unwind_* symbols are local.
Right now it also seems that none of uClibc's code actually uses these functions, at least in my case, so the incorrect Unwind_Resume inside uClibc is harmless.
But isn't pthread_cancel using pthread_cancel_init from libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c?
Yes, it looks like it does. But at least _Unwind_Resume doesn't seem to be used at all.
The problem I was having with v1.0.17 was that by linking with libpthread, the Unwind_Resume wrapper code in that library was overriding the implementation in libgcc_s that was supposed to be called directly.
I still do not understand the issue. As far as I know, the Unwind* functions in uClibc and GNU libc is wrapper code around gcc libgcc_s.so.1 which is loaded via dlopen at runtime.
Yes, they are, but the problem is with the way the ARM unwinder works. Obviously, it doesn't expect to have one additional frame added by a call to _Unwind_Resume. This is why in the case of the ARM architecture, a specially-crafted version of the wrapper around _Unwind_Resume is provided which doesn't create a new frame.
I once asked about this on the libc mailinglist: https://sourceware.org/ml/libc-help/2014-07/msg00000.html
Now that libpthread (and librt for that matter) are integrated into libc, it seems the problem is gone, because the libgcc_s implementation is not overridden by uClibc's. But this happens only because libgcc_s.so is listed before libc.so in the .dynamic section, and if it were not the case anymore, for any reason, the problem would reemerge immediately.
You can force the problem to re-emerge by simply preloading libc.so using LD_PRELOAD. This makes uClibc's incorrect implementation of Unwind_Resume to be called and the execution of the example code aborts instead of outputting "caught".
Please find attached the updated patch for v1.0.18. This is more like a quick fix, since a proper fix would most probably be to make those conflicting symbols local in the resulting .so.
But what exactly is fixed by the patch then?
The patch makes _Unwind_Resume in libpthread/nptl/ be implemented by sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c in the case of ARM and by sysdeps/pthread/unwind-forcedunwind.c otherwise. So if libc.so's _Unwind_Resume ever takes over libgcc_s.so's, or if the wrapper around _Unwind_Resume is used in the future, it will simply work transparently.
The way this is achieved is inspired by how it's already done for librt with unwind-resume.c (see sysdeps/pthread/rt-unwind-resume.c).
Is it still a ARM specific issue?
Yes it is.
Could you take a look at glibc commit: commit 46abb64d6287d09100b147d062f6810066389b7e Author: Roland McGrath roland@hack.frob.com Date: Mon Jan 5 14:01:49 2015 -0800
ARM: Consolidate with generic unwinder wrapper code
I think it would be a better solution to sync with glibc and get rid of the special ARM specific versions.
I you look closely at this commit, it's exactly what I'm talking about: it's providing an ARM-specific implementation of _Unwind_Resume in assembly. For other architectures, the generic wrapper is used.
Now I agree with you that the code should sync with glibc's as much as possible in this regard, since the problem is exactly the same.
Cheers,
Thanks, now i understand. Could you create a patch and sync the code?
best regards Waldemar
On Tue, Oct 04, 2016 at 06:46:22AM +0200, thus spake Waldemar Brodkorb:
Hi Ignacy, Ignacy Gawędzki wrote,
On Mon, Oct 03, 2016 at 06:13:45PM +0200, thus spake Waldemar Brodkorb:
Hi Ignacy, Ignacy Gawędzki wrote,
On Mon, Oct 03, 2016 at 12:26:19PM +0200, thus spake Ignacy Gawedzki:
On Sat, Oct 01, 2016 at 01:22:37PM +0200, thus spake Waldemar Brodkorb:
Can you please try with 1.0.18? I can not reproduce the issue with 1.0.18.
I just get "caught" with the test app.
May be it was accidentally fixed in the release.
I don't get the uncaught exception with 1.0.18 indeed. This is certainly due to the way libpthread is now integrated into libc. Now the version of Unwind_Resume that is called is always the one from libgcc_1.so, even when using threads. I'm affraid that this is not the right thing to do, because the wrapping code for Unwind_Resume in libpthread was there for some reason.
Okay, I've explored that problem a bit more today and I have additional information. It seems that the Unwind_* functions are provided in the libc for local use and are not supposed to be visible for the dynamic linker. Compare that with GNU libc where the Unwind_* symbols are local.
Right now it also seems that none of uClibc's code actually uses these functions, at least in my case, so the incorrect Unwind_Resume inside uClibc is harmless.
But isn't pthread_cancel using pthread_cancel_init from libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c?
Yes, it looks like it does. But at least _Unwind_Resume doesn't seem to be used at all.
The problem I was having with v1.0.17 was that by linking with libpthread, the Unwind_Resume wrapper code in that library was overriding the implementation in libgcc_s that was supposed to be called directly.
I still do not understand the issue. As far as I know, the Unwind* functions in uClibc and GNU libc is wrapper code around gcc libgcc_s.so.1 which is loaded via dlopen at runtime.
Yes, they are, but the problem is with the way the ARM unwinder works. Obviously, it doesn't expect to have one additional frame added by a call to _Unwind_Resume. This is why in the case of the ARM architecture, a specially-crafted version of the wrapper around _Unwind_Resume is provided which doesn't create a new frame.
I once asked about this on the libc mailinglist: https://sourceware.org/ml/libc-help/2014-07/msg00000.html
Now that libpthread (and librt for that matter) are integrated into libc, it seems the problem is gone, because the libgcc_s implementation is not overridden by uClibc's. But this happens only because libgcc_s.so is listed before libc.so in the .dynamic section, and if it were not the case anymore, for any reason, the problem would reemerge immediately.
You can force the problem to re-emerge by simply preloading libc.so using LD_PRELOAD. This makes uClibc's incorrect implementation of Unwind_Resume to be called and the execution of the example code aborts instead of outputting "caught".
Please find attached the updated patch for v1.0.18. This is more like a quick fix, since a proper fix would most probably be to make those conflicting symbols local in the resulting .so.
But what exactly is fixed by the patch then?
The patch makes _Unwind_Resume in libpthread/nptl/ be implemented by sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c in the case of ARM and by sysdeps/pthread/unwind-forcedunwind.c otherwise. So if libc.so's _Unwind_Resume ever takes over libgcc_s.so's, or if the wrapper around _Unwind_Resume is used in the future, it will simply work transparently.
The way this is achieved is inspired by how it's already done for librt with unwind-resume.c (see sysdeps/pthread/rt-unwind-resume.c).
Is it still a ARM specific issue?
Yes it is.
Could you take a look at glibc commit: commit 46abb64d6287d09100b147d062f6810066389b7e Author: Roland McGrath roland@hack.frob.com Date: Mon Jan 5 14:01:49 2015 -0800
ARM: Consolidate with generic unwinder wrapper code
I think it would be a better solution to sync with glibc and get rid of the special ARM specific versions.
I you look closely at this commit, it's exactly what I'm talking about: it's providing an ARM-specific implementation of _Unwind_Resume in assembly. For other architectures, the generic wrapper is used.
Now I agree with you that the code should sync with glibc's as much as possible in this regard, since the problem is exactly the same.
Cheers,
Thanks, now i understand. Could you create a patch and sync the code?
This is much more complicated than it seems. I tried to sync the code with glibc but that turned out to have too many implications. The idea behind the glibc code is twofold. First, the prototype for __gcc_personality_v0 is kept in a macro which has a generic definition in sysdeps/generic/unwind-resume.h and an ARM-specific one in sysdeps/arm/unwind-resume.h. Second, the generic implementation of _Unwind_Resume in both unwind-resume.c and unwind-forcedunwind.c is included only on the condition that there is no arch-specific version. The ARM-specific version is implemented directly in assembly.
Using the assembly source makes not much sense because it requires some macros which are missing in uClibc-ng and others that require a test at configuration-time. So I figured we can use the C source with inline assembly just as well.
Currently I struggle with the integration of all this in the existing makefiles. There are tons of variables defined with no documentation whatsoever to guide me in the process.
In glibc it seems there are two places where the code from unwind-resume is needed, that is libc and librt which are compiled with -fexceptions and use cleanup functions. That code offers an implementation of _Unwind_Resume and __gcc_personality_v0. The code from unwind-forcedunwind is needed in libpthread and offers an implementation of _Unwind_Resume and __gcc_personality_v0 along with _Unwind_ForcedUnwind, _Unwind_GetCFA, etc. So basically, whenever _Unwind_Resume or __gcc_personality_v0 is required in libc or librt, the implementation from unwind-resume is used, whereas in libpthread, it's the one from unwind-forcedunwind which is used.
In uClibc-ng, since the integration of librt and libpthread in libc, the only included implementation is from unwind-forcedunwind, which should basically just work (except that it needs a special implementation of _Unwind_Resume for ARM). I don't know if there's a way to make code in libc and librt call one implementation (from unwind-resume) and code in libpthread call the other (unwind-forcedunwind). If you agree that it's impossible or too twisted to be worth it, I propose to diverge from glibc and remove unwind-resume altogether.
In any case, I would greatly appreciate some help regarding the way to modify the makefiles.
Cheers,
Ignacy
Okay, I finally managed to get the makefiles right.
This patch will include only the code in unwind-forcedunwind, originally used by libpthread. Since the effects are pretty much the same, that works just right. This is even more harmless given the fact that none of the current libc/librt code requires exception handling as in glibc (i.e. no call to any unwinder's function is generated by GCC). As this could change in the future, it's good to have an implementation that will work already there.
Apart from the fact that the actual implementation of _Unwind_Resume for ARM was not working properly, the symbols for this and other unwinder's functions was overriding the ones in libgcc_s. The code in glibc doesn't explicitly set the hidden attribute on all these functions, but it eventually uses a version script which makes all these locals. Here, I explicitly set these functions to be hidden, thus avoiding the need to use a version script.
Ignacy Gawędzki (1): libpthread: Fix inclusion of unwind code.
libpthread/nptl/sysdeps/Makefile.commonarch | 1 + libpthread/nptl/sysdeps/arm/arm-unwind-resume.c | 67 ++++++++ libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c | 2 + libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c | 1 + libpthread/nptl/sysdeps/arm/unwind-resume.h | 33 ++++ libpthread/nptl/sysdeps/generic/unwind-resume.c | 75 +++++++++ libpthread/nptl/sysdeps/generic/unwind-resume.h | 33 ++++ .../nptl/sysdeps/pthread/unwind-forcedunwind.c | 49 +++--- libpthread/nptl/sysdeps/pthread/unwind-resume.c | 80 ---------- .../unix/sysv/linux/arm/unwind-forcedunwind.c | 177 --------------------- .../sysdeps/unix/sysv/linux/arm/unwind-resume.c | 116 -------------- 11 files changed, 230 insertions(+), 404 deletions(-) create mode 100644 libpthread/nptl/sysdeps/arm/arm-unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/arm/unwind-resume.h create mode 100644 libpthread/nptl/sysdeps/generic/unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/generic/unwind-resume.h delete mode 100644 libpthread/nptl/sysdeps/pthread/unwind-resume.c delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c
Since librt and libpthread are now integrated into libc, including unwind-resume and unwind-forcedunwind implementations of unwind code makes no sense. Only unwind-forcedunwind is now included with functions hidden to avoid them overriding the ones from libgcc_s.
* libpthread/nptl/sysdeps/generic/unwind-resume.h: New. Define generic PERSONALITY_PROTO and PERSONALITY_ARGS and set HAVE_ARCH_UNWIND_RESUME to 0.
* libpthread/nptl/sysdeps/pthread/unwind-resume.c: Move...
* libpthread/nptl/sysdeps/generic/unwind-resume.c: ... here. Include generic implementation of _Unwind_Resume on the condition that !HAVE_ARCH_UNWIND_RESUME. Make functions hidden to prevent them from overriding libgcc_s's ones.
* libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c: Likewise.
* libpthread/nptl/sysdeps/arm/unwind-resume.h: New. Define ARM-specific PERSONALITY_PROTO and PERSONALITY_ARGS and set HAVE_ARCH_UNWIND_RESUME to 1.
* libpthread/nptl/sysdeps/arm/arm-unwind-resume.c, * libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c, * libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c: New. ARM-specific implementations of _Unwind_Resume resp. for libc, libpthread and librt.
* libpthread/nptl/sysdeps/Makefile.commonarch: Remove both arm-unwind-resume and rt-arm-unwind-resume from libpthread_arch_CSRC.
* libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c, * libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c: Remove.
Signed-off-by: Ignacy Gawędzki ignacy.gawedzki@green-communications.fr --- libpthread/nptl/sysdeps/Makefile.commonarch | 1 + libpthread/nptl/sysdeps/arm/arm-unwind-resume.c | 67 ++++++++ libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c | 2 + libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c | 1 + libpthread/nptl/sysdeps/arm/unwind-resume.h | 33 ++++ libpthread/nptl/sysdeps/generic/unwind-resume.c | 75 +++++++++ libpthread/nptl/sysdeps/generic/unwind-resume.h | 33 ++++ .../nptl/sysdeps/pthread/unwind-forcedunwind.c | 49 +++--- libpthread/nptl/sysdeps/pthread/unwind-resume.c | 80 ---------- .../unix/sysv/linux/arm/unwind-forcedunwind.c | 177 --------------------- .../sysdeps/unix/sysv/linux/arm/unwind-resume.c | 116 -------------- 11 files changed, 230 insertions(+), 404 deletions(-) create mode 100644 libpthread/nptl/sysdeps/arm/arm-unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/arm/unwind-resume.h create mode 100644 libpthread/nptl/sysdeps/generic/unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/generic/unwind-resume.h delete mode 100644 libpthread/nptl/sysdeps/pthread/unwind-resume.c delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c
diff --git a/libpthread/nptl/sysdeps/Makefile.commonarch b/libpthread/nptl/sysdeps/Makefile.commonarch index 7f531f5..c206ac9 100644 --- a/libpthread/nptl/sysdeps/Makefile.commonarch +++ b/libpthread/nptl/sysdeps/Makefile.commonarch @@ -18,6 +18,7 @@ endif libpthread_arch_SSRC := $(filter-out librt-%,$(filter-out libc-%,$(notdir $(wildcard $(libpthread_arch_DIR)/*.S)))) libpthread_arch_CSRC := $(filter-out librt-%,$(filter-out libc-%,$(notdir $(wildcard $(libpthread_arch_DIR)/*.c)))) libpthread_arch_CSRC := $(filter-out gen_%,$(libpthread_arch_CSRC)) +libpthread_arch_CSRC := $(filter-out arm-unwind-resume.% rt-arm-unwind-resume.%,$(libpthread_arch_CSRC))
ifneq ($(TARGET_SUBARCH),) libpthread_subarch_SSRC := $(notdir $(wildcard $(libpthread_subarch_DIR)/*.S)) diff --git a/libpthread/nptl/sysdeps/arm/arm-unwind-resume.c b/libpthread/nptl/sysdeps/arm/arm-unwind-resume.c new file mode 100644 index 0000000..ae55582 --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/arm-unwind-resume.c @@ -0,0 +1,67 @@ +/* Copyright (C) 2003, 2005, 2010 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek jakub@redhat.com. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see http://www.gnu.org/licenses/. */ + +/* It's vitally important that _Unwind_Resume not have a stack frame; the + ARM unwinder relies on register state at entrance. So we write this in + assembly. */ + +#include <sysdep.h> + +__asm__ ( +" .globl _Unwind_Resume\n" +" .hidden _Unwind_Resume\n" +" .type _Unwind_Resume, %function\n" +"_Unwind_Resume:\n" +" " CFI_SECTIONS (.debug_frame) "\n" +" " CFI_STARTPROC "\n" +" stmfd sp!, {r4, r5, r6, lr}\n" +" " CFI_ADJUST_CFA_OFFSET (16)" \n" +" " CFI_REL_OFFSET (r4, 0) "\n" +" " CFI_REL_OFFSET (r5, 4) "\n" +" " CFI_REL_OFFSET (r6, 8) "\n" +" " CFI_REL_OFFSET (lr, 12) "\n" +" " CFI_REMEMBER_STATE "\n" +" ldr r4, 1f\n" +" ldr r5, 2f\n" +"3: add r4, pc, r4\n" +" ldr r3, [r4, r5]\n" +" mov r6, r0\n" +" cmp r3, #0\n" +" beq 4f\n" +"5: mov r0, r6\n" +" ldmfd sp!, {r4, r5, r6, lr}\n" +" " CFI_ADJUST_CFA_OFFSET (-16) "\n" +" " CFI_RESTORE (r4) "\n" +" " CFI_RESTORE (r5) "\n" +" " CFI_RESTORE (r6) "\n" +" " CFI_RESTORE (lr) "\n" +" bx r3\n" +" " CFI_RESTORE_STATE "\n" +"4: bl __libgcc_s_init\n" +" ldr r3, [r4, r5]\n" +" b 5b\n" +" " CFI_ENDPROC "\n" +" .align 2\n" +#ifdef __thumb2__ +"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 4\n" +#else +"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 8\n" +#endif +"2: .word __libgcc_s_resume(GOTOFF)\n" +" .size _Unwind_Resume, .-_Unwind_Resume\n" +); diff --git a/libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c b/libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c new file mode 100644 index 0000000..fd0cec4 --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c @@ -0,0 +1,2 @@ +__asm__ (".set __libgcc_s_init, pthread_cancel_init"); +#include <arm-unwind-resume.c> diff --git a/libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c b/libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c new file mode 100644 index 0000000..2641dc5 --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c @@ -0,0 +1 @@ +#include <arm-unwind-resume.c> diff --git a/libpthread/nptl/sysdeps/arm/unwind-resume.h b/libpthread/nptl/sysdeps/arm/unwind-resume.h new file mode 100644 index 0000000..736cc83 --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/unwind-resume.h @@ -0,0 +1,33 @@ +/* Definitions for unwind-resume.c. ARM (EABI) version. + Copyright (C) 2015-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see http://www.gnu.org/licenses/. */ + +/* The EABI personality routine has a different signature than the + canonical one. These macros tell sysdeps/gnu/unwind*.c how to + define __gcc_personality_v0. */ +#define PERSONALITY_PROTO \ + (_Unwind_State state, \ + struct _Unwind_Exception *ue_header, \ + struct _Unwind_Context *context) +#define PERSONALITY_ARGS \ + (state, ue_header, context) + +/* It's vitally important that _Unwind_Resume not have a stack frame; the + ARM unwinder relies on register state at entrance. So we write this in + assembly (see arm-unwind-resume.S). This macro tells the generic code + not to provide the generic C definition. */ +#define HAVE_ARCH_UNWIND_RESUME 1 diff --git a/libpthread/nptl/sysdeps/generic/unwind-resume.c b/libpthread/nptl/sysdeps/generic/unwind-resume.c new file mode 100644 index 0000000..a3d9466 --- /dev/null +++ b/libpthread/nptl/sysdeps/generic/unwind-resume.c @@ -0,0 +1,75 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek jakub@redhat.com. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see http://www.gnu.org/licenses/. */ + +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> +#include <unwind.h> +#include <libgcc_s.h> +#include <unwind-resume.h> + +#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY)) +#define __libc_dlsym dlsym +#define __libc_dlclose dlclose + +void (*__libgcc_s_resume) (struct _Unwind_Exception *exc) + attribute_hidden __attribute__ ((noreturn)); + +static _Unwind_Reason_Code (*libgcc_s_personality) PERSONALITY_PROTO; + +extern +void abort(void); + +void attribute_hidden __attribute__ ((cold)) +__libgcc_s_init(void) +{ + void *resume, *personality; + void *handle; + + handle = __libc_dlopen (LIBGCC_S_SO); + + if (handle == NULL + || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL + || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL) + { + fprintf (stderr, + LIBGCC_S_SO " must be installed for pthread_cancel to work\n"); + abort(); + } + + libgcc_s_resume = resume; + libgcc_s_personality = personality; +} + +#if !HAVE_ARCH_UNWIND_RESUME +void attribute_hidden +_Unwind_Resume (struct _Unwind_Exception *exc) +{ + if (__builtin_expect (libgcc_s_resume == NULL, 0)) + __libgcc_s_init (); + __libgcc_s_resume (exc); +} +#endif + +_Unwind_Reason_Code attribute_hidden +__gcc_personality_v0 PERSONALITY_PROTO +{ + if (__builtin_expect (libgcc_s_personality == NULL, 0)) + __libgcc_s_init (); + return libgcc_s_personality PERSONALITY_ARGS; +} diff --git a/libpthread/nptl/sysdeps/generic/unwind-resume.h b/libpthread/nptl/sysdeps/generic/unwind-resume.h new file mode 100644 index 0000000..a0dd638 --- /dev/null +++ b/libpthread/nptl/sysdeps/generic/unwind-resume.h @@ -0,0 +1,33 @@ +/* Definitions for unwind-resume.c. Generic version. + Copyright (C) 2015-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see http://www.gnu.org/licenses/. */ + +/* These describe the arguments to unwinder personality functions, + specifically __gcc_personality_v0. A machine-specific sysdeps + file might define them differently. */ +#define PERSONALITY_PROTO \ + (int version, _Unwind_Action actions, \ + _Unwind_Exception_Class exception_class, \ + struct _Unwind_Exception *ue_header, \ + struct _Unwind_Context *context) +#define PERSONALITY_ARGS \ + (version, actions, exception_class, ue_header, context) + +/* This is defined nonzero by a machine-specific sysdeps file if + _Unwind_Resume is provided separately and thus the generic C + version should not be defined. */ +#define HAVE_ARCH_UNWIND_RESUME 0 diff --git a/libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c b/libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c index 6b6ad6f..fd45ce1 100644 --- a/libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c +++ b/libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c @@ -22,16 +22,16 @@ #include <pthreadP.h> #include <sysdep.h> #include <libgcc_s.h> +#include <unwind-resume.h>
#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY)) #define __libc_dlsym dlsym #define __libc_dlclose dlclose
static void *libgcc_s_handle; -static void (*libgcc_s_resume) (struct _Unwind_Exception *exc); -static _Unwind_Reason_Code (*libgcc_s_personality) - (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, - struct _Unwind_Context *); +void (*__libgcc_s_resume) (struct _Unwind_Exception *exc) + attribute_hidden __attribute__ ((noreturn)); +static _Unwind_Reason_Code (*libgcc_s_personality) PERSONALITY_PROTO; static _Unwind_Reason_Code (*libgcc_s_forcedunwind) (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *); static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *); @@ -66,11 +66,12 @@ pthread_cancel_init (void) #endif ) { - printf (LIBGCC_S_SO " must be installed for pthread_cancel to work\n"); + fprintf (stderr, + LIBGCC_S_SO " must be installed for pthread_cancel to work\n"); abort(); }
- libgcc_s_resume = resume; + __libgcc_s_resume = resume; libgcc_s_personality = personality; libgcc_s_forcedunwind = forcedunwind; libgcc_s_getcfa = getcfa; @@ -93,55 +94,41 @@ __unwind_freeres (void) } }
-void +#if !HAVE_ARCH_UNWIND_RESUME +void attribute_hidden _Unwind_Resume (struct _Unwind_Exception *exc) { if (__builtin_expect (libgcc_s_handle == NULL, 0)) pthread_cancel_init ();
- void (*resume) (struct _Unwind_Exception *exc) = libgcc_s_resume; - resume (exc); + __libgcc_s_resume(exc); } +#endif
-_Unwind_Reason_Code -__gcc_personality_v0 (int version, _Unwind_Action actions, - _Unwind_Exception_Class exception_class, - struct _Unwind_Exception *ue_header, - struct _Unwind_Context *context); -_Unwind_Reason_Code -__gcc_personality_v0 (int version, _Unwind_Action actions, - _Unwind_Exception_Class exception_class, - struct _Unwind_Exception *ue_header, - struct _Unwind_Context *context) +_Unwind_Reason_Code attribute_hidden +__gcc_personality_v0 PERSONALITY_PROTO { if (__builtin_expect (libgcc_s_handle == NULL, 0)) pthread_cancel_init ();
- _Unwind_Reason_Code (*personality) - (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, - struct _Unwind_Context *) = libgcc_s_personality; - return personality (version, actions, exception_class, ue_header, context); + return libgcc_s_personality PERSONALITY_ARGS; }
-_Unwind_Reason_Code +_Unwind_Reason_Code attribute_hidden _Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop, void *stop_argument) { if (__builtin_expect (libgcc_s_handle == NULL, 0)) pthread_cancel_init ();
- _Unwind_Reason_Code (*forcedunwind) - (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *) - = libgcc_s_forcedunwind; - return forcedunwind (exc, stop, stop_argument); + return libgcc_s_forcedunwind (exc, stop, stop_argument); }
-_Unwind_Word +_Unwind_Word attribute_hidden _Unwind_GetCFA (struct _Unwind_Context *context) { if (__builtin_expect (libgcc_s_handle == NULL, 0)) pthread_cancel_init ();
- _Unwind_Word (*getcfa) (struct _Unwind_Context *) = libgcc_s_getcfa; - return getcfa (context); + return libgcc_s_getcfa (context); } diff --git a/libpthread/nptl/sysdeps/pthread/unwind-resume.c b/libpthread/nptl/sysdeps/pthread/unwind-resume.c deleted file mode 100644 index 3c1ce07..0000000 --- a/libpthread/nptl/sysdeps/pthread/unwind-resume.c +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek jakub@redhat.com. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If - not, see http://www.gnu.org/licenses/. */ - -#include <dlfcn.h> -#include <stdio.h> -#include <stdlib.h> -#include <unwind.h> -#include <libgcc_s.h> - -#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY)) -#define __libc_dlsym dlsym -#define __libc_dlclose dlclose - -static void (*libgcc_s_resume) (struct _Unwind_Exception *exc); -static _Unwind_Reason_Code (*libgcc_s_personality) - (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, - struct _Unwind_Context *); - -extern -void abort(void); - -static void -init (void) -{ - void *resume, *personality; - void *handle; - resume = personality = NULL; - handle = dlopen (LIBGCC_S_SO, (RTLD_LOCAL | RTLD_LAZY)); - - if (handle == NULL - || (resume = dlsym (handle, "_Unwind_Resume")) == NULL - || (personality = dlsym (handle, "__gcc_personality_v0")) == NULL) - { - printf (LIBGCC_S_SO " must be installed for pthread_cancel to work\n"); - abort(); - } - - libgcc_s_resume = resume; - libgcc_s_personality = personality; -} - -void -_Unwind_Resume (struct _Unwind_Exception *exc) -{ - if (__builtin_expect (libgcc_s_resume == NULL, 0)) - init (); - libgcc_s_resume (exc); -} - -_Unwind_Reason_Code -__gcc_personality_v0 (int version, _Unwind_Action actions, - _Unwind_Exception_Class exception_class, - struct _Unwind_Exception *ue_header, - struct _Unwind_Context *context); -_Unwind_Reason_Code -__gcc_personality_v0 (int version, _Unwind_Action actions, - _Unwind_Exception_Class exception_class, - struct _Unwind_Exception *ue_header, - struct _Unwind_Context *context) -{ - if (__builtin_expect (libgcc_s_personality == NULL, 0)) - init (); - return libgcc_s_personality (version, actions, exception_class, - ue_header, context); -} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c deleted file mode 100644 index a6a0515..0000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c +++ /dev/null @@ -1,177 +0,0 @@ -/* Copyright (C) 2003, 2005, 2007, 2009, 2010 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek jakub@redhat.com. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If - not, see http://www.gnu.org/licenses/. */ - -#include <dlfcn.h> -#include <stdio.h> -#include <unwind.h> -#include <pthreadP.h> - -#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY)) -#define __libc_dlsym dlsym -#define __libc_dlclose dlclose -#define __libc_fatal(x) {/*write(STDERR_FILENO, x, strlen(x));*/ abort();} - -static void *libgcc_s_handle; -static void (*libgcc_s_resume) (struct _Unwind_Exception *exc) - __attribute_used__; -static _Unwind_Reason_Code (*libgcc_s_personality) - (_Unwind_State, struct _Unwind_Exception *, struct _Unwind_Context *); -static _Unwind_Reason_Code (*libgcc_s_forcedunwind) - (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *); -static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *); - -void -__attribute_noinline__ -pthread_cancel_init (void) -{ - void *resume, *personality, *forcedunwind, *getcfa; - void *handle; - - if (__builtin_expect (libgcc_s_handle != NULL, 1)) - { - /* Force gcc to reload all values. */ - __asm__ __volatile__ ("" ::: "memory"); - return; - } - - handle = __libc_dlopen ("libgcc_s.so.1"); - - if (handle == NULL - || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL - || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL - || (forcedunwind = __libc_dlsym (handle, "_Unwind_ForcedUnwind")) - == NULL - || (getcfa = __libc_dlsym (handle, "_Unwind_GetCFA")) == NULL -#ifdef ARCH_CANCEL_INIT - || ARCH_CANCEL_INIT (handle) -#endif - ) - __libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n"); - - libgcc_s_resume = resume; - libgcc_s_personality = personality; - libgcc_s_forcedunwind = forcedunwind; - libgcc_s_getcfa = getcfa; - /* Make sure libgcc_s_getcfa is written last. Otherwise, - pthread_cancel_init might return early even when the pointer the - caller is interested in is not initialized yet. */ - atomic_write_barrier (); - libgcc_s_handle = handle; -} - -void -__libc_freeres_fn_section -__unwind_freeres (void) -{ - void *handle = libgcc_s_handle; - if (handle != NULL) - { - libgcc_s_handle = NULL; - __libc_dlclose (handle); - } -} - -#ifdef __thumb__ -void -_Unwind_Resume (struct _Unwind_Exception *exc) -{ - if (__builtin_expect (libgcc_s_resume == NULL, 0)) - pthread_cancel_init (); - - libgcc_s_resume (exc); -} - -#else -/* It's vitally important that _Unwind_Resume not have a stack frame; the - ARM unwinder relies on register state at entrance. So we write this in - assembly. */ - -__asm__ ( -" .globl _Unwind_Resume\n" -" .type _Unwind_Resume, %function\n" -"_Unwind_Resume:\n" -" .cfi_sections .debug_frame\n" -" " CFI_STARTPROC "\n" -" stmfd sp!, {r4, r5, r6, lr}\n" -" " CFI_ADJUST_CFA_OFFSET (16)" \n" -" " CFI_REL_OFFSET (r4, 0) "\n" -" " CFI_REL_OFFSET (r5, 4) "\n" -" " CFI_REL_OFFSET (r6, 8) "\n" -" " CFI_REL_OFFSET (lr, 12) "\n" -" " CFI_REMEMBER_STATE "\n" -" ldr r4, 1f\n" -" ldr r5, 2f\n" -"3: add r4, pc, r4\n" -" ldr r3, [r4, r5]\n" -" mov r6, r0\n" -" cmp r3, #0\n" -" beq 4f\n" -"5: mov r0, r6\n" -" ldmfd sp!, {r4, r5, r6, lr}\n" -" " CFI_ADJUST_CFA_OFFSET (-16) "\n" -" " CFI_RESTORE (r4) "\n" -" " CFI_RESTORE (r5) "\n" -" " CFI_RESTORE (r6) "\n" -" " CFI_RESTORE (lr) "\n" -" bx r3\n" -" " CFI_RESTORE_STATE "\n" -"4: bl pthread_cancel_init\n" -" ldr r3, [r4, r5]\n" -" b 5b\n" -" " CFI_ENDPROC "\n" -" .align 2\n" -#ifdef __thumb2__ -"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 4\n" -#else -"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 8\n" -#endif -"2: .word libgcc_s_resume(GOTOFF)\n" -" .size _Unwind_Resume, .-_Unwind_Resume\n" -); - -#endif - -_Unwind_Reason_Code -__gcc_personality_v0 (_Unwind_State state, - struct _Unwind_Exception *ue_header, - struct _Unwind_Context *context) -{ - if (__builtin_expect (libgcc_s_personality == NULL, 0)) - pthread_cancel_init (); - - return libgcc_s_personality (state, ue_header, context); -} - -_Unwind_Reason_Code -_Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop, - void *stop_argument) -{ - if (__builtin_expect (libgcc_s_forcedunwind == NULL, 0)) - pthread_cancel_init (); - - return libgcc_s_forcedunwind (exc, stop, stop_argument); -} - -_Unwind_Word -_Unwind_GetCFA (struct _Unwind_Context *context) -{ - if (__builtin_expect (libgcc_s_getcfa == NULL, 0)) - pthread_cancel_init (); - - return libgcc_s_getcfa (context); -} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c deleted file mode 100644 index e2e2e0b..0000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c +++ /dev/null @@ -1,116 +0,0 @@ -/* Copyright (C) 2003, 2005, 2010 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek jakub@redhat.com. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If - not, see http://www.gnu.org/licenses/. */ - -#include <dlfcn.h> -#include <stdio.h> -#include <unwind.h> - -#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY)) -#define __libc_dlsym dlsym -#define __libc_dlclose dlclose -#define __libc_fatal(x) {/*write(STDERR_FILENO, x, strlen(x));*/ abort();} - -static void (*libgcc_s_resume) (struct _Unwind_Exception *exc) - __attribute_used__; -static _Unwind_Reason_Code (*libgcc_s_personality) - (_Unwind_State, struct _Unwind_Exception *, struct _Unwind_Context *); - -static void init (void) __attribute_used__; - -static void -init (void) -{ - void *resume, *personality; - void *handle; - - handle = __libc_dlopen ("libgcc_s.so.1"); - - if (handle == NULL - || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL - || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL) - __libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n"); - - libgcc_s_resume = resume; - libgcc_s_personality = personality; -} -#ifdef __thumb__ -void -_Unwind_Resume (struct _Unwind_Exception *exc) -{ - if (__builtin_expect (libgcc_s_resume == NULL, 0)) - init (); - libgcc_s_resume (exc); -} -#else -/* It's vitally important that _Unwind_Resume not have a stack frame; the - ARM unwinder relies on register state at entrance. So we write this in - assembly. */ - -__asm__ ( -" .globl _Unwind_Resume\n" -" .type _Unwind_Resume, %function\n" -"_Unwind_Resume:\n" -" " CFI_SECTIONS (.debug_frame) "\n" -" " CFI_STARTPROC "\n" -" stmfd sp!, {r4, r5, r6, lr}\n" -" " CFI_ADJUST_CFA_OFFSET (16)" \n" -" " CFI_REL_OFFSET (r4, 0) "\n" -" " CFI_REL_OFFSET (r5, 4) "\n" -" " CFI_REL_OFFSET (r6, 8) "\n" -" " CFI_REL_OFFSET (lr, 12) "\n" -" " CFI_REMEMBER_STATE "\n" -" ldr r4, 1f\n" -" ldr r5, 2f\n" -"3: add r4, pc, r4\n" -" ldr r3, [r4, r5]\n" -" mov r6, r0\n" -" cmp r3, #0\n" -" beq 4f\n" -"5: mov r0, r6\n" -" ldmfd sp!, {r4, r5, r6, lr}\n" -" " CFI_ADJUST_CFA_OFFSET (-16) "\n" -" " CFI_RESTORE (r4) "\n" -" " CFI_RESTORE (r5) "\n" -" " CFI_RESTORE (r6) "\n" -" " CFI_RESTORE (lr) "\n" -" bx r3\n" -" " CFI_RESTORE_STATE "\n" -"4: bl init\n" -" ldr r3, [r4, r5]\n" -" b 5b\n" -" " CFI_ENDPROC "\n" -" .align 2\n" -#ifdef __thumb2__ -"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 4\n" -#else -"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 8\n" -#endif -"2: .word libgcc_s_resume(GOTOFF)\n" -" .size _Unwind_Resume, .-_Unwind_Resume\n" -); -#endif - -_Unwind_Reason_Code -__gcc_personality_v0 (_Unwind_State state, - struct _Unwind_Exception *ue_header, - struct _Unwind_Context *context) -{ - if (__builtin_expect (libgcc_s_personality == NULL, 0)) - init (); - return libgcc_s_personality (state, ue_header, context); -}
I failed my commit --amend of the previous version. Please disregard the previous patch. Sorry for the noise.
Ignacy Gawędzki (1): libpthread: Fix inclusion of unwind code.
libpthread/nptl/sysdeps/Makefile.commonarch | 1 + libpthread/nptl/sysdeps/arm/arm-unwind-resume.c | 67 ++++++++ libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c | 2 + libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c | 1 + libpthread/nptl/sysdeps/arm/unwind-resume.h | 33 ++++ libpthread/nptl/sysdeps/generic/unwind-resume.c | 75 +++++++++ libpthread/nptl/sysdeps/generic/unwind-resume.h | 33 ++++ .../nptl/sysdeps/pthread/unwind-forcedunwind.c | 49 +++--- libpthread/nptl/sysdeps/pthread/unwind-resume.c | 80 ---------- .../unix/sysv/linux/arm/unwind-forcedunwind.c | 177 --------------------- .../sysdeps/unix/sysv/linux/arm/unwind-resume.c | 116 -------------- 11 files changed, 230 insertions(+), 404 deletions(-) create mode 100644 libpthread/nptl/sysdeps/arm/arm-unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/arm/unwind-resume.h create mode 100644 libpthread/nptl/sysdeps/generic/unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/generic/unwind-resume.h delete mode 100644 libpthread/nptl/sysdeps/pthread/unwind-resume.c delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c
Since librt and libpthread are now integrated into libc, including unwind-resume and unwind-forcedunwind implementations of unwind code makes no sense. Only unwind-forcedunwind is now included with functions hidden to avoid them overriding the ones from libgcc_s.
* libpthread/nptl/sysdeps/generic/unwind-resume.h: New. Define generic PERSONALITY_PROTO and PERSONALITY_ARGS and set HAVE_ARCH_UNWIND_RESUME to 0.
* libpthread/nptl/sysdeps/pthread/unwind-resume.c: Move...
* libpthread/nptl/sysdeps/generic/unwind-resume.c: ... here. Include generic implementation of _Unwind_Resume on the condition that !HAVE_ARCH_UNWIND_RESUME. Make functions hidden to prevent them from overriding libgcc_s's ones.
* libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c: Likewise.
* libpthread/nptl/sysdeps/arm/unwind-resume.h: New. Define ARM-specific PERSONALITY_PROTO and PERSONALITY_ARGS and set HAVE_ARCH_UNWIND_RESUME to 1.
* libpthread/nptl/sysdeps/arm/arm-unwind-resume.c, * libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c, * libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c: New. ARM-specific implementations of _Unwind_Resume resp. for libc, libpthread and librt.
* libpthread/nptl/sysdeps/Makefile.commonarch: Remove both arm-unwind-resume and rt-arm-unwind-resume from libpthread_arch_CSRC.
* libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c, * libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c: Remove.
Signed-off-by: Ignacy Gawędzki ignacy.gawedzki@green-communications.fr --- libpthread/nptl/sysdeps/Makefile.commonarch | 1 + libpthread/nptl/sysdeps/arm/arm-unwind-resume.c | 67 ++++++++ libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c | 2 + libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c | 1 + libpthread/nptl/sysdeps/arm/unwind-resume.h | 33 ++++ libpthread/nptl/sysdeps/generic/unwind-resume.c | 75 +++++++++ libpthread/nptl/sysdeps/generic/unwind-resume.h | 33 ++++ .../nptl/sysdeps/pthread/unwind-forcedunwind.c | 49 +++--- libpthread/nptl/sysdeps/pthread/unwind-resume.c | 80 ---------- .../unix/sysv/linux/arm/unwind-forcedunwind.c | 177 --------------------- .../sysdeps/unix/sysv/linux/arm/unwind-resume.c | 116 -------------- 11 files changed, 230 insertions(+), 404 deletions(-) create mode 100644 libpthread/nptl/sysdeps/arm/arm-unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/arm/unwind-resume.h create mode 100644 libpthread/nptl/sysdeps/generic/unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/generic/unwind-resume.h delete mode 100644 libpthread/nptl/sysdeps/pthread/unwind-resume.c delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c
diff --git a/libpthread/nptl/sysdeps/Makefile.commonarch b/libpthread/nptl/sysdeps/Makefile.commonarch index 7f531f5..c206ac9 100644 --- a/libpthread/nptl/sysdeps/Makefile.commonarch +++ b/libpthread/nptl/sysdeps/Makefile.commonarch @@ -18,6 +18,7 @@ endif libpthread_arch_SSRC := $(filter-out librt-%,$(filter-out libc-%,$(notdir $(wildcard $(libpthread_arch_DIR)/*.S)))) libpthread_arch_CSRC := $(filter-out librt-%,$(filter-out libc-%,$(notdir $(wildcard $(libpthread_arch_DIR)/*.c)))) libpthread_arch_CSRC := $(filter-out gen_%,$(libpthread_arch_CSRC)) +libpthread_arch_CSRC := $(filter-out arm-unwind-resume.% rt-arm-unwind-resume.%,$(libpthread_arch_CSRC))
ifneq ($(TARGET_SUBARCH),) libpthread_subarch_SSRC := $(notdir $(wildcard $(libpthread_subarch_DIR)/*.S)) diff --git a/libpthread/nptl/sysdeps/arm/arm-unwind-resume.c b/libpthread/nptl/sysdeps/arm/arm-unwind-resume.c new file mode 100644 index 0000000..ae55582 --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/arm-unwind-resume.c @@ -0,0 +1,67 @@ +/* Copyright (C) 2003, 2005, 2010 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek jakub@redhat.com. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see http://www.gnu.org/licenses/. */ + +/* It's vitally important that _Unwind_Resume not have a stack frame; the + ARM unwinder relies on register state at entrance. So we write this in + assembly. */ + +#include <sysdep.h> + +__asm__ ( +" .globl _Unwind_Resume\n" +" .hidden _Unwind_Resume\n" +" .type _Unwind_Resume, %function\n" +"_Unwind_Resume:\n" +" " CFI_SECTIONS (.debug_frame) "\n" +" " CFI_STARTPROC "\n" +" stmfd sp!, {r4, r5, r6, lr}\n" +" " CFI_ADJUST_CFA_OFFSET (16)" \n" +" " CFI_REL_OFFSET (r4, 0) "\n" +" " CFI_REL_OFFSET (r5, 4) "\n" +" " CFI_REL_OFFSET (r6, 8) "\n" +" " CFI_REL_OFFSET (lr, 12) "\n" +" " CFI_REMEMBER_STATE "\n" +" ldr r4, 1f\n" +" ldr r5, 2f\n" +"3: add r4, pc, r4\n" +" ldr r3, [r4, r5]\n" +" mov r6, r0\n" +" cmp r3, #0\n" +" beq 4f\n" +"5: mov r0, r6\n" +" ldmfd sp!, {r4, r5, r6, lr}\n" +" " CFI_ADJUST_CFA_OFFSET (-16) "\n" +" " CFI_RESTORE (r4) "\n" +" " CFI_RESTORE (r5) "\n" +" " CFI_RESTORE (r6) "\n" +" " CFI_RESTORE (lr) "\n" +" bx r3\n" +" " CFI_RESTORE_STATE "\n" +"4: bl __libgcc_s_init\n" +" ldr r3, [r4, r5]\n" +" b 5b\n" +" " CFI_ENDPROC "\n" +" .align 2\n" +#ifdef __thumb2__ +"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 4\n" +#else +"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 8\n" +#endif +"2: .word __libgcc_s_resume(GOTOFF)\n" +" .size _Unwind_Resume, .-_Unwind_Resume\n" +); diff --git a/libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c b/libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c new file mode 100644 index 0000000..fd0cec4 --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c @@ -0,0 +1,2 @@ +__asm__ (".set __libgcc_s_init, pthread_cancel_init"); +#include <arm-unwind-resume.c> diff --git a/libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c b/libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c new file mode 100644 index 0000000..2641dc5 --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c @@ -0,0 +1 @@ +#include <arm-unwind-resume.c> diff --git a/libpthread/nptl/sysdeps/arm/unwind-resume.h b/libpthread/nptl/sysdeps/arm/unwind-resume.h new file mode 100644 index 0000000..736cc83 --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/unwind-resume.h @@ -0,0 +1,33 @@ +/* Definitions for unwind-resume.c. ARM (EABI) version. + Copyright (C) 2015-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see http://www.gnu.org/licenses/. */ + +/* The EABI personality routine has a different signature than the + canonical one. These macros tell sysdeps/gnu/unwind*.c how to + define __gcc_personality_v0. */ +#define PERSONALITY_PROTO \ + (_Unwind_State state, \ + struct _Unwind_Exception *ue_header, \ + struct _Unwind_Context *context) +#define PERSONALITY_ARGS \ + (state, ue_header, context) + +/* It's vitally important that _Unwind_Resume not have a stack frame; the + ARM unwinder relies on register state at entrance. So we write this in + assembly (see arm-unwind-resume.S). This macro tells the generic code + not to provide the generic C definition. */ +#define HAVE_ARCH_UNWIND_RESUME 1 diff --git a/libpthread/nptl/sysdeps/generic/unwind-resume.c b/libpthread/nptl/sysdeps/generic/unwind-resume.c new file mode 100644 index 0000000..cd9df9f --- /dev/null +++ b/libpthread/nptl/sysdeps/generic/unwind-resume.c @@ -0,0 +1,75 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek jakub@redhat.com. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see http://www.gnu.org/licenses/. */ + +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> +#include <unwind.h> +#include <libgcc_s.h> +#include <unwind-resume.h> + +#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY)) +#define __libc_dlsym dlsym +#define __libc_dlclose dlclose + +void (*__libgcc_s_resume) (struct _Unwind_Exception *exc) + attribute_hidden __attribute__ ((noreturn)); + +static _Unwind_Reason_Code (*libgcc_s_personality) PERSONALITY_PROTO; + +extern +void abort(void); + +void attribute_hidden __attribute__ ((cold)) +__libgcc_s_init(void) +{ + void *resume, *personality; + void *handle; + + handle = __libc_dlopen (LIBGCC_S_SO); + + if (handle == NULL + || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL + || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL) + { + fprintf (stderr, + LIBGCC_S_SO " must be installed for pthread_cancel to work\n"); + abort(); + } + + __libgcc_s_resume = resume; + libgcc_s_personality = personality; +} + +#if !HAVE_ARCH_UNWIND_RESUME +void attribute_hidden +_Unwind_Resume (struct _Unwind_Exception *exc) +{ + if (__builtin_expect (libgcc_s_resume == NULL, 0)) + __libgcc_s_init (); + __libgcc_s_resume (exc); +} +#endif + +_Unwind_Reason_Code attribute_hidden +__gcc_personality_v0 PERSONALITY_PROTO +{ + if (__builtin_expect (libgcc_s_personality == NULL, 0)) + __libgcc_s_init (); + return libgcc_s_personality PERSONALITY_ARGS; +} diff --git a/libpthread/nptl/sysdeps/generic/unwind-resume.h b/libpthread/nptl/sysdeps/generic/unwind-resume.h new file mode 100644 index 0000000..a0dd638 --- /dev/null +++ b/libpthread/nptl/sysdeps/generic/unwind-resume.h @@ -0,0 +1,33 @@ +/* Definitions for unwind-resume.c. Generic version. + Copyright (C) 2015-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If + not, see http://www.gnu.org/licenses/. */ + +/* These describe the arguments to unwinder personality functions, + specifically __gcc_personality_v0. A machine-specific sysdeps + file might define them differently. */ +#define PERSONALITY_PROTO \ + (int version, _Unwind_Action actions, \ + _Unwind_Exception_Class exception_class, \ + struct _Unwind_Exception *ue_header, \ + struct _Unwind_Context *context) +#define PERSONALITY_ARGS \ + (version, actions, exception_class, ue_header, context) + +/* This is defined nonzero by a machine-specific sysdeps file if + _Unwind_Resume is provided separately and thus the generic C + version should not be defined. */ +#define HAVE_ARCH_UNWIND_RESUME 0 diff --git a/libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c b/libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c index 6b6ad6f..fd45ce1 100644 --- a/libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c +++ b/libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c @@ -22,16 +22,16 @@ #include <pthreadP.h> #include <sysdep.h> #include <libgcc_s.h> +#include <unwind-resume.h>
#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY)) #define __libc_dlsym dlsym #define __libc_dlclose dlclose
static void *libgcc_s_handle; -static void (*libgcc_s_resume) (struct _Unwind_Exception *exc); -static _Unwind_Reason_Code (*libgcc_s_personality) - (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, - struct _Unwind_Context *); +void (*__libgcc_s_resume) (struct _Unwind_Exception *exc) + attribute_hidden __attribute__ ((noreturn)); +static _Unwind_Reason_Code (*libgcc_s_personality) PERSONALITY_PROTO; static _Unwind_Reason_Code (*libgcc_s_forcedunwind) (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *); static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *); @@ -66,11 +66,12 @@ pthread_cancel_init (void) #endif ) { - printf (LIBGCC_S_SO " must be installed for pthread_cancel to work\n"); + fprintf (stderr, + LIBGCC_S_SO " must be installed for pthread_cancel to work\n"); abort(); }
- libgcc_s_resume = resume; + __libgcc_s_resume = resume; libgcc_s_personality = personality; libgcc_s_forcedunwind = forcedunwind; libgcc_s_getcfa = getcfa; @@ -93,55 +94,41 @@ __unwind_freeres (void) } }
-void +#if !HAVE_ARCH_UNWIND_RESUME +void attribute_hidden _Unwind_Resume (struct _Unwind_Exception *exc) { if (__builtin_expect (libgcc_s_handle == NULL, 0)) pthread_cancel_init ();
- void (*resume) (struct _Unwind_Exception *exc) = libgcc_s_resume; - resume (exc); + __libgcc_s_resume(exc); } +#endif
-_Unwind_Reason_Code -__gcc_personality_v0 (int version, _Unwind_Action actions, - _Unwind_Exception_Class exception_class, - struct _Unwind_Exception *ue_header, - struct _Unwind_Context *context); -_Unwind_Reason_Code -__gcc_personality_v0 (int version, _Unwind_Action actions, - _Unwind_Exception_Class exception_class, - struct _Unwind_Exception *ue_header, - struct _Unwind_Context *context) +_Unwind_Reason_Code attribute_hidden +__gcc_personality_v0 PERSONALITY_PROTO { if (__builtin_expect (libgcc_s_handle == NULL, 0)) pthread_cancel_init ();
- _Unwind_Reason_Code (*personality) - (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, - struct _Unwind_Context *) = libgcc_s_personality; - return personality (version, actions, exception_class, ue_header, context); + return libgcc_s_personality PERSONALITY_ARGS; }
-_Unwind_Reason_Code +_Unwind_Reason_Code attribute_hidden _Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop, void *stop_argument) { if (__builtin_expect (libgcc_s_handle == NULL, 0)) pthread_cancel_init ();
- _Unwind_Reason_Code (*forcedunwind) - (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *) - = libgcc_s_forcedunwind; - return forcedunwind (exc, stop, stop_argument); + return libgcc_s_forcedunwind (exc, stop, stop_argument); }
-_Unwind_Word +_Unwind_Word attribute_hidden _Unwind_GetCFA (struct _Unwind_Context *context) { if (__builtin_expect (libgcc_s_handle == NULL, 0)) pthread_cancel_init ();
- _Unwind_Word (*getcfa) (struct _Unwind_Context *) = libgcc_s_getcfa; - return getcfa (context); + return libgcc_s_getcfa (context); } diff --git a/libpthread/nptl/sysdeps/pthread/unwind-resume.c b/libpthread/nptl/sysdeps/pthread/unwind-resume.c deleted file mode 100644 index 3c1ce07..0000000 --- a/libpthread/nptl/sysdeps/pthread/unwind-resume.c +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek jakub@redhat.com. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If - not, see http://www.gnu.org/licenses/. */ - -#include <dlfcn.h> -#include <stdio.h> -#include <stdlib.h> -#include <unwind.h> -#include <libgcc_s.h> - -#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY)) -#define __libc_dlsym dlsym -#define __libc_dlclose dlclose - -static void (*libgcc_s_resume) (struct _Unwind_Exception *exc); -static _Unwind_Reason_Code (*libgcc_s_personality) - (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, - struct _Unwind_Context *); - -extern -void abort(void); - -static void -init (void) -{ - void *resume, *personality; - void *handle; - resume = personality = NULL; - handle = dlopen (LIBGCC_S_SO, (RTLD_LOCAL | RTLD_LAZY)); - - if (handle == NULL - || (resume = dlsym (handle, "_Unwind_Resume")) == NULL - || (personality = dlsym (handle, "__gcc_personality_v0")) == NULL) - { - printf (LIBGCC_S_SO " must be installed for pthread_cancel to work\n"); - abort(); - } - - libgcc_s_resume = resume; - libgcc_s_personality = personality; -} - -void -_Unwind_Resume (struct _Unwind_Exception *exc) -{ - if (__builtin_expect (libgcc_s_resume == NULL, 0)) - init (); - libgcc_s_resume (exc); -} - -_Unwind_Reason_Code -__gcc_personality_v0 (int version, _Unwind_Action actions, - _Unwind_Exception_Class exception_class, - struct _Unwind_Exception *ue_header, - struct _Unwind_Context *context); -_Unwind_Reason_Code -__gcc_personality_v0 (int version, _Unwind_Action actions, - _Unwind_Exception_Class exception_class, - struct _Unwind_Exception *ue_header, - struct _Unwind_Context *context) -{ - if (__builtin_expect (libgcc_s_personality == NULL, 0)) - init (); - return libgcc_s_personality (version, actions, exception_class, - ue_header, context); -} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c deleted file mode 100644 index a6a0515..0000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c +++ /dev/null @@ -1,177 +0,0 @@ -/* Copyright (C) 2003, 2005, 2007, 2009, 2010 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek jakub@redhat.com. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If - not, see http://www.gnu.org/licenses/. */ - -#include <dlfcn.h> -#include <stdio.h> -#include <unwind.h> -#include <pthreadP.h> - -#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY)) -#define __libc_dlsym dlsym -#define __libc_dlclose dlclose -#define __libc_fatal(x) {/*write(STDERR_FILENO, x, strlen(x));*/ abort();} - -static void *libgcc_s_handle; -static void (*libgcc_s_resume) (struct _Unwind_Exception *exc) - __attribute_used__; -static _Unwind_Reason_Code (*libgcc_s_personality) - (_Unwind_State, struct _Unwind_Exception *, struct _Unwind_Context *); -static _Unwind_Reason_Code (*libgcc_s_forcedunwind) - (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *); -static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *); - -void -__attribute_noinline__ -pthread_cancel_init (void) -{ - void *resume, *personality, *forcedunwind, *getcfa; - void *handle; - - if (__builtin_expect (libgcc_s_handle != NULL, 1)) - { - /* Force gcc to reload all values. */ - __asm__ __volatile__ ("" ::: "memory"); - return; - } - - handle = __libc_dlopen ("libgcc_s.so.1"); - - if (handle == NULL - || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL - || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL - || (forcedunwind = __libc_dlsym (handle, "_Unwind_ForcedUnwind")) - == NULL - || (getcfa = __libc_dlsym (handle, "_Unwind_GetCFA")) == NULL -#ifdef ARCH_CANCEL_INIT - || ARCH_CANCEL_INIT (handle) -#endif - ) - __libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n"); - - libgcc_s_resume = resume; - libgcc_s_personality = personality; - libgcc_s_forcedunwind = forcedunwind; - libgcc_s_getcfa = getcfa; - /* Make sure libgcc_s_getcfa is written last. Otherwise, - pthread_cancel_init might return early even when the pointer the - caller is interested in is not initialized yet. */ - atomic_write_barrier (); - libgcc_s_handle = handle; -} - -void -__libc_freeres_fn_section -__unwind_freeres (void) -{ - void *handle = libgcc_s_handle; - if (handle != NULL) - { - libgcc_s_handle = NULL; - __libc_dlclose (handle); - } -} - -#ifdef __thumb__ -void -_Unwind_Resume (struct _Unwind_Exception *exc) -{ - if (__builtin_expect (libgcc_s_resume == NULL, 0)) - pthread_cancel_init (); - - libgcc_s_resume (exc); -} - -#else -/* It's vitally important that _Unwind_Resume not have a stack frame; the - ARM unwinder relies on register state at entrance. So we write this in - assembly. */ - -__asm__ ( -" .globl _Unwind_Resume\n" -" .type _Unwind_Resume, %function\n" -"_Unwind_Resume:\n" -" .cfi_sections .debug_frame\n" -" " CFI_STARTPROC "\n" -" stmfd sp!, {r4, r5, r6, lr}\n" -" " CFI_ADJUST_CFA_OFFSET (16)" \n" -" " CFI_REL_OFFSET (r4, 0) "\n" -" " CFI_REL_OFFSET (r5, 4) "\n" -" " CFI_REL_OFFSET (r6, 8) "\n" -" " CFI_REL_OFFSET (lr, 12) "\n" -" " CFI_REMEMBER_STATE "\n" -" ldr r4, 1f\n" -" ldr r5, 2f\n" -"3: add r4, pc, r4\n" -" ldr r3, [r4, r5]\n" -" mov r6, r0\n" -" cmp r3, #0\n" -" beq 4f\n" -"5: mov r0, r6\n" -" ldmfd sp!, {r4, r5, r6, lr}\n" -" " CFI_ADJUST_CFA_OFFSET (-16) "\n" -" " CFI_RESTORE (r4) "\n" -" " CFI_RESTORE (r5) "\n" -" " CFI_RESTORE (r6) "\n" -" " CFI_RESTORE (lr) "\n" -" bx r3\n" -" " CFI_RESTORE_STATE "\n" -"4: bl pthread_cancel_init\n" -" ldr r3, [r4, r5]\n" -" b 5b\n" -" " CFI_ENDPROC "\n" -" .align 2\n" -#ifdef __thumb2__ -"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 4\n" -#else -"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 8\n" -#endif -"2: .word libgcc_s_resume(GOTOFF)\n" -" .size _Unwind_Resume, .-_Unwind_Resume\n" -); - -#endif - -_Unwind_Reason_Code -__gcc_personality_v0 (_Unwind_State state, - struct _Unwind_Exception *ue_header, - struct _Unwind_Context *context) -{ - if (__builtin_expect (libgcc_s_personality == NULL, 0)) - pthread_cancel_init (); - - return libgcc_s_personality (state, ue_header, context); -} - -_Unwind_Reason_Code -_Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop, - void *stop_argument) -{ - if (__builtin_expect (libgcc_s_forcedunwind == NULL, 0)) - pthread_cancel_init (); - - return libgcc_s_forcedunwind (exc, stop, stop_argument); -} - -_Unwind_Word -_Unwind_GetCFA (struct _Unwind_Context *context) -{ - if (__builtin_expect (libgcc_s_getcfa == NULL, 0)) - pthread_cancel_init (); - - return libgcc_s_getcfa (context); -} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c deleted file mode 100644 index e2e2e0b..0000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c +++ /dev/null @@ -1,116 +0,0 @@ -/* Copyright (C) 2003, 2005, 2010 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek jakub@redhat.com. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If - not, see http://www.gnu.org/licenses/. */ - -#include <dlfcn.h> -#include <stdio.h> -#include <unwind.h> - -#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY)) -#define __libc_dlsym dlsym -#define __libc_dlclose dlclose -#define __libc_fatal(x) {/*write(STDERR_FILENO, x, strlen(x));*/ abort();} - -static void (*libgcc_s_resume) (struct _Unwind_Exception *exc) - __attribute_used__; -static _Unwind_Reason_Code (*libgcc_s_personality) - (_Unwind_State, struct _Unwind_Exception *, struct _Unwind_Context *); - -static void init (void) __attribute_used__; - -static void -init (void) -{ - void *resume, *personality; - void *handle; - - handle = __libc_dlopen ("libgcc_s.so.1"); - - if (handle == NULL - || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL - || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL) - __libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n"); - - libgcc_s_resume = resume; - libgcc_s_personality = personality; -} -#ifdef __thumb__ -void -_Unwind_Resume (struct _Unwind_Exception *exc) -{ - if (__builtin_expect (libgcc_s_resume == NULL, 0)) - init (); - libgcc_s_resume (exc); -} -#else -/* It's vitally important that _Unwind_Resume not have a stack frame; the - ARM unwinder relies on register state at entrance. So we write this in - assembly. */ - -__asm__ ( -" .globl _Unwind_Resume\n" -" .type _Unwind_Resume, %function\n" -"_Unwind_Resume:\n" -" " CFI_SECTIONS (.debug_frame) "\n" -" " CFI_STARTPROC "\n" -" stmfd sp!, {r4, r5, r6, lr}\n" -" " CFI_ADJUST_CFA_OFFSET (16)" \n" -" " CFI_REL_OFFSET (r4, 0) "\n" -" " CFI_REL_OFFSET (r5, 4) "\n" -" " CFI_REL_OFFSET (r6, 8) "\n" -" " CFI_REL_OFFSET (lr, 12) "\n" -" " CFI_REMEMBER_STATE "\n" -" ldr r4, 1f\n" -" ldr r5, 2f\n" -"3: add r4, pc, r4\n" -" ldr r3, [r4, r5]\n" -" mov r6, r0\n" -" cmp r3, #0\n" -" beq 4f\n" -"5: mov r0, r6\n" -" ldmfd sp!, {r4, r5, r6, lr}\n" -" " CFI_ADJUST_CFA_OFFSET (-16) "\n" -" " CFI_RESTORE (r4) "\n" -" " CFI_RESTORE (r5) "\n" -" " CFI_RESTORE (r6) "\n" -" " CFI_RESTORE (lr) "\n" -" bx r3\n" -" " CFI_RESTORE_STATE "\n" -"4: bl init\n" -" ldr r3, [r4, r5]\n" -" b 5b\n" -" " CFI_ENDPROC "\n" -" .align 2\n" -#ifdef __thumb2__ -"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 4\n" -#else -"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 8\n" -#endif -"2: .word libgcc_s_resume(GOTOFF)\n" -" .size _Unwind_Resume, .-_Unwind_Resume\n" -); -#endif - -_Unwind_Reason_Code -__gcc_personality_v0 (_Unwind_State state, - struct _Unwind_Exception *ue_header, - struct _Unwind_Context *context) -{ - if (__builtin_expect (libgcc_s_personality == NULL, 0)) - init (); - return libgcc_s_personality (state, ue_header, context); -}
Hi Ignacy,
I tried v4, but it adds regressions for other architectures. For example MIPS Little endian running uClibc-ng testsuite.
Any idea? Can you try to reproduce the regressions on your side?
Thanks for the work so far, Waldemar
Ignacy Gawędzki wrote,
Since librt and libpthread are now integrated into libc, including unwind-resume and unwind-forcedunwind implementations of unwind code makes no sense. Only unwind-forcedunwind is now included with functions hidden to avoid them overriding the ones from libgcc_s.
libpthread/nptl/sysdeps/generic/unwind-resume.h: New. Define generic PERSONALITY_PROTO and PERSONALITY_ARGS and set HAVE_ARCH_UNWIND_RESUME to 0.
libpthread/nptl/sysdeps/pthread/unwind-resume.c: Move...
libpthread/nptl/sysdeps/generic/unwind-resume.c: ... here. Include generic implementation of _Unwind_Resume on the condition that !HAVE_ARCH_UNWIND_RESUME. Make functions hidden to prevent them from overriding libgcc_s's ones.
libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c: Likewise.
libpthread/nptl/sysdeps/arm/unwind-resume.h: New. Define ARM-specific PERSONALITY_PROTO and PERSONALITY_ARGS and set HAVE_ARCH_UNWIND_RESUME to 1.
libpthread/nptl/sysdeps/arm/arm-unwind-resume.c,
libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c,
libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c: New. ARM-specific implementations of _Unwind_Resume resp. for libc, libpthread and librt.
libpthread/nptl/sysdeps/Makefile.commonarch: Remove both arm-unwind-resume and rt-arm-unwind-resume from libpthread_arch_CSRC.
libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c,
libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c: Remove.
Signed-off-by: Ignacy Gawędzki ignacy.gawedzki@green-communications.fr
libpthread/nptl/sysdeps/Makefile.commonarch | 1 + libpthread/nptl/sysdeps/arm/arm-unwind-resume.c | 67 ++++++++ libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c | 2 + libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c | 1 + libpthread/nptl/sysdeps/arm/unwind-resume.h | 33 ++++ libpthread/nptl/sysdeps/generic/unwind-resume.c | 75 +++++++++ libpthread/nptl/sysdeps/generic/unwind-resume.h | 33 ++++ .../nptl/sysdeps/pthread/unwind-forcedunwind.c | 49 +++--- libpthread/nptl/sysdeps/pthread/unwind-resume.c | 80 ---------- .../unix/sysv/linux/arm/unwind-forcedunwind.c | 177 --------------------- .../sysdeps/unix/sysv/linux/arm/unwind-resume.c | 116 -------------- 11 files changed, 230 insertions(+), 404 deletions(-) create mode 100644 libpthread/nptl/sysdeps/arm/arm-unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/arm/unwind-resume.h create mode 100644 libpthread/nptl/sysdeps/generic/unwind-resume.c create mode 100644 libpthread/nptl/sysdeps/generic/unwind-resume.h delete mode 100644 libpthread/nptl/sysdeps/pthread/unwind-resume.c delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c delete mode 100644 libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c
diff --git a/libpthread/nptl/sysdeps/Makefile.commonarch b/libpthread/nptl/sysdeps/Makefile.commonarch index 7f531f5..c206ac9 100644 --- a/libpthread/nptl/sysdeps/Makefile.commonarch +++ b/libpthread/nptl/sysdeps/Makefile.commonarch @@ -18,6 +18,7 @@ endif libpthread_arch_SSRC := $(filter-out librt-%,$(filter-out libc-%,$(notdir $(wildcard $(libpthread_arch_DIR)/*.S)))) libpthread_arch_CSRC := $(filter-out librt-%,$(filter-out libc-%,$(notdir $(wildcard $(libpthread_arch_DIR)/*.c)))) libpthread_arch_CSRC := $(filter-out gen_%,$(libpthread_arch_CSRC)) +libpthread_arch_CSRC := $(filter-out arm-unwind-resume.% rt-arm-unwind-resume.%,$(libpthread_arch_CSRC))
ifneq ($(TARGET_SUBARCH),) libpthread_subarch_SSRC := $(notdir $(wildcard $(libpthread_subarch_DIR)/*.S)) diff --git a/libpthread/nptl/sysdeps/arm/arm-unwind-resume.c b/libpthread/nptl/sysdeps/arm/arm-unwind-resume.c new file mode 100644 index 0000000..ae55582 --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/arm-unwind-resume.c @@ -0,0 +1,67 @@ +/* Copyright (C) 2003, 2005, 2010 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Jakub Jelinek jakub@redhat.com.
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 2.1 of the
- License, or (at your option) any later version.
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; see the file COPYING.LIB. If
- not, see http://www.gnu.org/licenses/. */
+/* It's vitally important that _Unwind_Resume not have a stack frame; the
- ARM unwinder relies on register state at entrance. So we write this in
- assembly. */
+#include <sysdep.h>
+__asm__ ( +" .globl _Unwind_Resume\n" +" .hidden _Unwind_Resume\n" +" .type _Unwind_Resume, %function\n" +"_Unwind_Resume:\n" +" " CFI_SECTIONS (.debug_frame) "\n" +" " CFI_STARTPROC "\n" +" stmfd sp!, {r4, r5, r6, lr}\n" +" " CFI_ADJUST_CFA_OFFSET (16)" \n" +" " CFI_REL_OFFSET (r4, 0) "\n" +" " CFI_REL_OFFSET (r5, 4) "\n" +" " CFI_REL_OFFSET (r6, 8) "\n" +" " CFI_REL_OFFSET (lr, 12) "\n" +" " CFI_REMEMBER_STATE "\n" +" ldr r4, 1f\n" +" ldr r5, 2f\n" +"3: add r4, pc, r4\n" +" ldr r3, [r4, r5]\n" +" mov r6, r0\n" +" cmp r3, #0\n" +" beq 4f\n" +"5: mov r0, r6\n" +" ldmfd sp!, {r4, r5, r6, lr}\n" +" " CFI_ADJUST_CFA_OFFSET (-16) "\n" +" " CFI_RESTORE (r4) "\n" +" " CFI_RESTORE (r5) "\n" +" " CFI_RESTORE (r6) "\n" +" " CFI_RESTORE (lr) "\n" +" bx r3\n" +" " CFI_RESTORE_STATE "\n" +"4: bl __libgcc_s_init\n" +" ldr r3, [r4, r5]\n" +" b 5b\n" +" " CFI_ENDPROC "\n" +" .align 2\n" +#ifdef __thumb2__ +"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 4\n" +#else +"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 8\n" +#endif +"2: .word __libgcc_s_resume(GOTOFF)\n" +" .size _Unwind_Resume, .-_Unwind_Resume\n" +); diff --git a/libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c b/libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c new file mode 100644 index 0000000..fd0cec4 --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/pt-arm-unwind-resume.c @@ -0,0 +1,2 @@ +__asm__ (".set __libgcc_s_init, pthread_cancel_init"); +#include <arm-unwind-resume.c> diff --git a/libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c b/libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c new file mode 100644 index 0000000..2641dc5 --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/rt-arm-unwind-resume.c @@ -0,0 +1 @@ +#include <arm-unwind-resume.c> diff --git a/libpthread/nptl/sysdeps/arm/unwind-resume.h b/libpthread/nptl/sysdeps/arm/unwind-resume.h new file mode 100644 index 0000000..736cc83 --- /dev/null +++ b/libpthread/nptl/sysdeps/arm/unwind-resume.h @@ -0,0 +1,33 @@ +/* Definitions for unwind-resume.c. ARM (EABI) version.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 2.1 of the
- License, or (at your option) any later version.
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; see the file COPYING.LIB. If
- not, see http://www.gnu.org/licenses/. */
+/* The EABI personality routine has a different signature than the
- canonical one. These macros tell sysdeps/gnu/unwind*.c how to
- define __gcc_personality_v0. */
+#define PERSONALITY_PROTO \
- (_Unwind_State state, \
- struct _Unwind_Exception *ue_header, \
- struct _Unwind_Context *context)
+#define PERSONALITY_ARGS \
- (state, ue_header, context)
+/* It's vitally important that _Unwind_Resume not have a stack frame; the
- ARM unwinder relies on register state at entrance. So we write this in
- assembly (see arm-unwind-resume.S). This macro tells the generic code
- not to provide the generic C definition. */
+#define HAVE_ARCH_UNWIND_RESUME 1 diff --git a/libpthread/nptl/sysdeps/generic/unwind-resume.c b/libpthread/nptl/sysdeps/generic/unwind-resume.c new file mode 100644 index 0000000..cd9df9f --- /dev/null +++ b/libpthread/nptl/sysdeps/generic/unwind-resume.c @@ -0,0 +1,75 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Jakub Jelinek jakub@redhat.com.
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 2.1 of the
- License, or (at your option) any later version.
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; see the file COPYING.LIB. If
- not, see http://www.gnu.org/licenses/. */
+#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> +#include <unwind.h> +#include <libgcc_s.h> +#include <unwind-resume.h>
+#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY)) +#define __libc_dlsym dlsym +#define __libc_dlclose dlclose
+void (*__libgcc_s_resume) (struct _Unwind_Exception *exc)
- attribute_hidden __attribute__ ((noreturn));
+static _Unwind_Reason_Code (*libgcc_s_personality) PERSONALITY_PROTO;
+extern +void abort(void);
+void attribute_hidden __attribute__ ((cold)) +__libgcc_s_init(void) +{
- void *resume, *personality;
- void *handle;
- handle = __libc_dlopen (LIBGCC_S_SO);
- if (handle == NULL
|| (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
|| (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL)
- {
- fprintf (stderr,
LIBGCC_S_SO " must be installed for pthread_cancel to work\n");
- abort();
- }
- __libgcc_s_resume = resume;
- libgcc_s_personality = personality;
+}
+#if !HAVE_ARCH_UNWIND_RESUME +void attribute_hidden +_Unwind_Resume (struct _Unwind_Exception *exc) +{
- if (__builtin_expect (libgcc_s_resume == NULL, 0))
- __libgcc_s_init ();
- __libgcc_s_resume (exc);
+} +#endif
+_Unwind_Reason_Code attribute_hidden +__gcc_personality_v0 PERSONALITY_PROTO +{
- if (__builtin_expect (libgcc_s_personality == NULL, 0))
- __libgcc_s_init ();
- return libgcc_s_personality PERSONALITY_ARGS;
+} diff --git a/libpthread/nptl/sysdeps/generic/unwind-resume.h b/libpthread/nptl/sysdeps/generic/unwind-resume.h new file mode 100644 index 0000000..a0dd638 --- /dev/null +++ b/libpthread/nptl/sysdeps/generic/unwind-resume.h @@ -0,0 +1,33 @@ +/* Definitions for unwind-resume.c. Generic version.
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 2.1 of the
- License, or (at your option) any later version.
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; see the file COPYING.LIB. If
- not, see http://www.gnu.org/licenses/. */
+/* These describe the arguments to unwinder personality functions,
- specifically __gcc_personality_v0. A machine-specific sysdeps
- file might define them differently. */
+#define PERSONALITY_PROTO \
- (int version, _Unwind_Action actions, \
- _Unwind_Exception_Class exception_class, \
- struct _Unwind_Exception *ue_header, \
- struct _Unwind_Context *context)
+#define PERSONALITY_ARGS \
- (version, actions, exception_class, ue_header, context)
+/* This is defined nonzero by a machine-specific sysdeps file if
- _Unwind_Resume is provided separately and thus the generic C
- version should not be defined. */
+#define HAVE_ARCH_UNWIND_RESUME 0 diff --git a/libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c b/libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c index 6b6ad6f..fd45ce1 100644 --- a/libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c +++ b/libpthread/nptl/sysdeps/pthread/unwind-forcedunwind.c @@ -22,16 +22,16 @@ #include <pthreadP.h> #include <sysdep.h> #include <libgcc_s.h> +#include <unwind-resume.h>
#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY)) #define __libc_dlsym dlsym #define __libc_dlclose dlclose
static void *libgcc_s_handle; -static void (*libgcc_s_resume) (struct _Unwind_Exception *exc); -static _Unwind_Reason_Code (*libgcc_s_personality)
- (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
- struct _Unwind_Context *);
+void (*__libgcc_s_resume) (struct _Unwind_Exception *exc)
- attribute_hidden __attribute__ ((noreturn));
+static _Unwind_Reason_Code (*libgcc_s_personality) PERSONALITY_PROTO; static _Unwind_Reason_Code (*libgcc_s_forcedunwind) (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *); static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *); @@ -66,11 +66,12 @@ pthread_cancel_init (void) #endif ) {
- printf (LIBGCC_S_SO " must be installed for pthread_cancel to work\n");
- fprintf (stderr,
abort(); }LIBGCC_S_SO " must be installed for pthread_cancel to work\n");
- libgcc_s_resume = resume;
- __libgcc_s_resume = resume; libgcc_s_personality = personality; libgcc_s_forcedunwind = forcedunwind; libgcc_s_getcfa = getcfa;
@@ -93,55 +94,41 @@ __unwind_freeres (void) } }
-void +#if !HAVE_ARCH_UNWIND_RESUME +void attribute_hidden _Unwind_Resume (struct _Unwind_Exception *exc) { if (__builtin_expect (libgcc_s_handle == NULL, 0)) pthread_cancel_init ();
- void (*resume) (struct _Unwind_Exception *exc) = libgcc_s_resume;
- resume (exc);
- __libgcc_s_resume(exc);
} +#endif
-_Unwind_Reason_Code -__gcc_personality_v0 (int version, _Unwind_Action actions,
_Unwind_Exception_Class exception_class,
struct _Unwind_Exception *ue_header,
struct _Unwind_Context *context);
-_Unwind_Reason_Code -__gcc_personality_v0 (int version, _Unwind_Action actions,
_Unwind_Exception_Class exception_class,
struct _Unwind_Exception *ue_header,
struct _Unwind_Context *context)
+_Unwind_Reason_Code attribute_hidden +__gcc_personality_v0 PERSONALITY_PROTO { if (__builtin_expect (libgcc_s_handle == NULL, 0)) pthread_cancel_init ();
- _Unwind_Reason_Code (*personality)
- (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
struct _Unwind_Context *) = libgcc_s_personality;
- return personality (version, actions, exception_class, ue_header, context);
- return libgcc_s_personality PERSONALITY_ARGS;
}
-_Unwind_Reason_Code +_Unwind_Reason_Code attribute_hidden _Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop, void *stop_argument) { if (__builtin_expect (libgcc_s_handle == NULL, 0)) pthread_cancel_init ();
- _Unwind_Reason_Code (*forcedunwind)
- (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *)
- = libgcc_s_forcedunwind;
- return forcedunwind (exc, stop, stop_argument);
- return libgcc_s_forcedunwind (exc, stop, stop_argument);
}
-_Unwind_Word +_Unwind_Word attribute_hidden _Unwind_GetCFA (struct _Unwind_Context *context) { if (__builtin_expect (libgcc_s_handle == NULL, 0)) pthread_cancel_init ();
- _Unwind_Word (*getcfa) (struct _Unwind_Context *) = libgcc_s_getcfa;
- return getcfa (context);
- return libgcc_s_getcfa (context);
} diff --git a/libpthread/nptl/sysdeps/pthread/unwind-resume.c b/libpthread/nptl/sysdeps/pthread/unwind-resume.c deleted file mode 100644 index 3c1ce07..0000000 --- a/libpthread/nptl/sysdeps/pthread/unwind-resume.c +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Jakub Jelinek jakub@redhat.com.
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 2.1 of the
- License, or (at your option) any later version.
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; see the file COPYING.LIB. If
- not, see http://www.gnu.org/licenses/. */
-#include <dlfcn.h> -#include <stdio.h> -#include <stdlib.h> -#include <unwind.h> -#include <libgcc_s.h>
-#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY)) -#define __libc_dlsym dlsym -#define __libc_dlclose dlclose
-static void (*libgcc_s_resume) (struct _Unwind_Exception *exc); -static _Unwind_Reason_Code (*libgcc_s_personality)
- (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
- struct _Unwind_Context *);
-extern -void abort(void);
-static void -init (void) -{
- void *resume, *personality;
- void *handle;
- resume = personality = NULL;
- handle = dlopen (LIBGCC_S_SO, (RTLD_LOCAL | RTLD_LAZY));
- if (handle == NULL
|| (resume = dlsym (handle, "_Unwind_Resume")) == NULL
|| (personality = dlsym (handle, "__gcc_personality_v0")) == NULL)
- {
- printf (LIBGCC_S_SO " must be installed for pthread_cancel to work\n");
- abort();
- }
- libgcc_s_resume = resume;
- libgcc_s_personality = personality;
-}
-void -_Unwind_Resume (struct _Unwind_Exception *exc) -{
- if (__builtin_expect (libgcc_s_resume == NULL, 0))
- init ();
- libgcc_s_resume (exc);
-}
-_Unwind_Reason_Code -__gcc_personality_v0 (int version, _Unwind_Action actions,
_Unwind_Exception_Class exception_class,
struct _Unwind_Exception *ue_header,
struct _Unwind_Context *context);
-_Unwind_Reason_Code -__gcc_personality_v0 (int version, _Unwind_Action actions,
_Unwind_Exception_Class exception_class,
struct _Unwind_Exception *ue_header,
struct _Unwind_Context *context)
-{
- if (__builtin_expect (libgcc_s_personality == NULL, 0))
- init ();
- return libgcc_s_personality (version, actions, exception_class,
ue_header, context);
-} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c deleted file mode 100644 index a6a0515..0000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c +++ /dev/null @@ -1,177 +0,0 @@ -/* Copyright (C) 2003, 2005, 2007, 2009, 2010 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Jakub Jelinek jakub@redhat.com.
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 2.1 of the
- License, or (at your option) any later version.
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; see the file COPYING.LIB. If
- not, see http://www.gnu.org/licenses/. */
-#include <dlfcn.h> -#include <stdio.h> -#include <unwind.h> -#include <pthreadP.h>
-#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY)) -#define __libc_dlsym dlsym -#define __libc_dlclose dlclose -#define __libc_fatal(x) {/*write(STDERR_FILENO, x, strlen(x));*/ abort();}
-static void *libgcc_s_handle; -static void (*libgcc_s_resume) (struct _Unwind_Exception *exc)
- __attribute_used__;
-static _Unwind_Reason_Code (*libgcc_s_personality)
- (_Unwind_State, struct _Unwind_Exception *, struct _Unwind_Context *);
-static _Unwind_Reason_Code (*libgcc_s_forcedunwind)
- (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *);
-static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *);
-void -__attribute_noinline__ -pthread_cancel_init (void) -{
- void *resume, *personality, *forcedunwind, *getcfa;
- void *handle;
- if (__builtin_expect (libgcc_s_handle != NULL, 1))
- {
/* Force gcc to reload all values. */
__asm__ __volatile__ ("" ::: "memory");
return;
- }
- handle = __libc_dlopen ("libgcc_s.so.1");
- if (handle == NULL
|| (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
|| (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL
|| (forcedunwind = __libc_dlsym (handle, "_Unwind_ForcedUnwind"))
== NULL
|| (getcfa = __libc_dlsym (handle, "_Unwind_GetCFA")) == NULL
-#ifdef ARCH_CANCEL_INIT
|| ARCH_CANCEL_INIT (handle)
-#endif
)
- __libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n");
- libgcc_s_resume = resume;
- libgcc_s_personality = personality;
- libgcc_s_forcedunwind = forcedunwind;
- libgcc_s_getcfa = getcfa;
- /* Make sure libgcc_s_getcfa is written last. Otherwise,
pthread_cancel_init might return early even when the pointer the
caller is interested in is not initialized yet. */
- atomic_write_barrier ();
- libgcc_s_handle = handle;
-}
-void -__libc_freeres_fn_section -__unwind_freeres (void) -{
- void *handle = libgcc_s_handle;
- if (handle != NULL)
- {
libgcc_s_handle = NULL;
__libc_dlclose (handle);
- }
-}
-#ifdef __thumb__ -void -_Unwind_Resume (struct _Unwind_Exception *exc) -{
- if (__builtin_expect (libgcc_s_resume == NULL, 0))
- pthread_cancel_init ();
- libgcc_s_resume (exc);
-}
-#else -/* It's vitally important that _Unwind_Resume not have a stack frame; the
- ARM unwinder relies on register state at entrance. So we write this in
- assembly. */
-__asm__ ( -" .globl _Unwind_Resume\n" -" .type _Unwind_Resume, %function\n" -"_Unwind_Resume:\n" -" .cfi_sections .debug_frame\n" -" " CFI_STARTPROC "\n" -" stmfd sp!, {r4, r5, r6, lr}\n" -" " CFI_ADJUST_CFA_OFFSET (16)" \n" -" " CFI_REL_OFFSET (r4, 0) "\n" -" " CFI_REL_OFFSET (r5, 4) "\n" -" " CFI_REL_OFFSET (r6, 8) "\n" -" " CFI_REL_OFFSET (lr, 12) "\n" -" " CFI_REMEMBER_STATE "\n" -" ldr r4, 1f\n" -" ldr r5, 2f\n" -"3: add r4, pc, r4\n" -" ldr r3, [r4, r5]\n" -" mov r6, r0\n" -" cmp r3, #0\n" -" beq 4f\n" -"5: mov r0, r6\n" -" ldmfd sp!, {r4, r5, r6, lr}\n" -" " CFI_ADJUST_CFA_OFFSET (-16) "\n" -" " CFI_RESTORE (r4) "\n" -" " CFI_RESTORE (r5) "\n" -" " CFI_RESTORE (r6) "\n" -" " CFI_RESTORE (lr) "\n" -" bx r3\n" -" " CFI_RESTORE_STATE "\n" -"4: bl pthread_cancel_init\n" -" ldr r3, [r4, r5]\n" -" b 5b\n" -" " CFI_ENDPROC "\n" -" .align 2\n" -#ifdef __thumb2__ -"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 4\n" -#else -"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 8\n" -#endif -"2: .word libgcc_s_resume(GOTOFF)\n" -" .size _Unwind_Resume, .-_Unwind_Resume\n" -);
-#endif
-_Unwind_Reason_Code -__gcc_personality_v0 (_Unwind_State state,
struct _Unwind_Exception *ue_header,
struct _Unwind_Context *context)
-{
- if (__builtin_expect (libgcc_s_personality == NULL, 0))
- pthread_cancel_init ();
- return libgcc_s_personality (state, ue_header, context);
-}
-_Unwind_Reason_Code -_Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop,
void *stop_argument)
-{
- if (__builtin_expect (libgcc_s_forcedunwind == NULL, 0))
- pthread_cancel_init ();
- return libgcc_s_forcedunwind (exc, stop, stop_argument);
-}
-_Unwind_Word -_Unwind_GetCFA (struct _Unwind_Context *context) -{
- if (__builtin_expect (libgcc_s_getcfa == NULL, 0))
- pthread_cancel_init ();
- return libgcc_s_getcfa (context);
-} diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c b/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c deleted file mode 100644 index e2e2e0b..0000000 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/arm/unwind-resume.c +++ /dev/null @@ -1,116 +0,0 @@ -/* Copyright (C) 2003, 2005, 2010 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Jakub Jelinek jakub@redhat.com.
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 2.1 of the
- License, or (at your option) any later version.
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; see the file COPYING.LIB. If
- not, see http://www.gnu.org/licenses/. */
-#include <dlfcn.h> -#include <stdio.h> -#include <unwind.h>
-#define __libc_dlopen(x) dlopen(x, (RTLD_LOCAL | RTLD_LAZY)) -#define __libc_dlsym dlsym -#define __libc_dlclose dlclose -#define __libc_fatal(x) {/*write(STDERR_FILENO, x, strlen(x));*/ abort();}
-static void (*libgcc_s_resume) (struct _Unwind_Exception *exc)
- __attribute_used__;
-static _Unwind_Reason_Code (*libgcc_s_personality)
- (_Unwind_State, struct _Unwind_Exception *, struct _Unwind_Context *);
-static void init (void) __attribute_used__;
-static void -init (void) -{
- void *resume, *personality;
- void *handle;
- handle = __libc_dlopen ("libgcc_s.so.1");
- if (handle == NULL
|| (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL
|| (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL)
- __libc_fatal ("libgcc_s.so.1 must be installed for pthread_cancel to work\n");
- libgcc_s_resume = resume;
- libgcc_s_personality = personality;
-} -#ifdef __thumb__ -void -_Unwind_Resume (struct _Unwind_Exception *exc) -{
- if (__builtin_expect (libgcc_s_resume == NULL, 0))
- init ();
- libgcc_s_resume (exc);
-} -#else -/* It's vitally important that _Unwind_Resume not have a stack frame; the
- ARM unwinder relies on register state at entrance. So we write this in
- assembly. */
-__asm__ ( -" .globl _Unwind_Resume\n" -" .type _Unwind_Resume, %function\n" -"_Unwind_Resume:\n" -" " CFI_SECTIONS (.debug_frame) "\n" -" " CFI_STARTPROC "\n" -" stmfd sp!, {r4, r5, r6, lr}\n" -" " CFI_ADJUST_CFA_OFFSET (16)" \n" -" " CFI_REL_OFFSET (r4, 0) "\n" -" " CFI_REL_OFFSET (r5, 4) "\n" -" " CFI_REL_OFFSET (r6, 8) "\n" -" " CFI_REL_OFFSET (lr, 12) "\n" -" " CFI_REMEMBER_STATE "\n" -" ldr r4, 1f\n" -" ldr r5, 2f\n" -"3: add r4, pc, r4\n" -" ldr r3, [r4, r5]\n" -" mov r6, r0\n" -" cmp r3, #0\n" -" beq 4f\n" -"5: mov r0, r6\n" -" ldmfd sp!, {r4, r5, r6, lr}\n" -" " CFI_ADJUST_CFA_OFFSET (-16) "\n" -" " CFI_RESTORE (r4) "\n" -" " CFI_RESTORE (r5) "\n" -" " CFI_RESTORE (r6) "\n" -" " CFI_RESTORE (lr) "\n" -" bx r3\n" -" " CFI_RESTORE_STATE "\n" -"4: bl init\n" -" ldr r3, [r4, r5]\n" -" b 5b\n" -" " CFI_ENDPROC "\n" -" .align 2\n" -#ifdef __thumb2__ -"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 4\n" -#else -"1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 8\n" -#endif -"2: .word libgcc_s_resume(GOTOFF)\n" -" .size _Unwind_Resume, .-_Unwind_Resume\n" -); -#endif
-_Unwind_Reason_Code -__gcc_personality_v0 (_Unwind_State state,
struct _Unwind_Exception *ue_header,
struct _Unwind_Context *context)
-{
- if (__builtin_expect (libgcc_s_personality == NULL, 0))
- init ();
- return libgcc_s_personality (state, ue_header, context);
-}
2.7.4
On Thu, Oct 13, 2016 at 12:44:38PM +0200, thus spake Waldemar Brodkorb:
Hi Ignacy,
I tried v4, but it adds regressions for other architectures. For example MIPS Little endian running uClibc-ng testsuite.
Any idea? Can you try to reproduce the regressions on your side?
I just tried by building a buildroot toolchain for mipsel. So far make check fails even without my patch telling me that it doesn't know how to make target test/Makefile, needed by termios.
Could you please send me your .config for mipsel that fails the make check?
Thanks,
Ignacy
On Thu, Oct 13, 2016 at 05:17:32PM +0200, thus spake Ignacy Gawedzki:
On Thu, Oct 13, 2016 at 12:44:38PM +0200, thus spake Waldemar Brodkorb:
Hi Ignacy,
I tried v4, but it adds regressions for other architectures. For example MIPS Little endian running uClibc-ng testsuite.
Any idea? Can you try to reproduce the regressions on your side?
I just tried by building a buildroot toolchain for mipsel. So far make check fails even without my patch telling me that it doesn't know how to make target test/Makefile, needed by termios.
It looks just like make check doesn't work with a separate build directory (make O=/path/to/somewhere/else check). Do you confirm?
Cheers,
Ignacy
On Thu, Oct 13, 2016 at 05:32:35PM +0200, thus spake Ignacy Gawedzki:
On Thu, Oct 13, 2016 at 05:17:32PM +0200, thus spake Ignacy Gawedzki:
On Thu, Oct 13, 2016 at 12:44:38PM +0200, thus spake Waldemar Brodkorb:
Hi Ignacy,
I tried v4, but it adds regressions for other architectures. For example MIPS Little endian running uClibc-ng testsuite.
Any idea? Can you try to reproduce the regressions on your side?
I just tried by building a buildroot toolchain for mipsel. So far make check fails even without my patch telling me that it doesn't know how to make target test/Makefile, needed by termios.
It looks just like make check doesn't work with a separate build directory (make O=/path/to/somewhere/else check). Do you confirm?
I fixed a few things in test/Makefile and test/Rules.mak (patch coming soon) and it looks like make check now works with a separate build directory. But still, I'm getting errors in test/math regarding __builtin_isfinite and the like not getting floating-point arguments. To me it looks like the test code is wrong, but I may be wrong myself.
Any idea how to fix that?
On Thu, Oct 13, 2016 at 06:10:15PM +0200, thus spake Ignacy Gawedzki:
On Thu, Oct 13, 2016 at 05:32:35PM +0200, thus spake Ignacy Gawedzki:
On Thu, Oct 13, 2016 at 05:17:32PM +0200, thus spake Ignacy Gawedzki:
On Thu, Oct 13, 2016 at 12:44:38PM +0200, thus spake Waldemar Brodkorb:
Hi Ignacy,
I tried v4, but it adds regressions for other architectures. For example MIPS Little endian running uClibc-ng testsuite.
Any idea? Can you try to reproduce the regressions on your side?
I just tried by building a buildroot toolchain for mipsel. So far make check fails even without my patch telling me that it doesn't know how to make target test/Makefile, needed by termios.
It looks just like make check doesn't work with a separate build directory (make O=/path/to/somewhere/else check). Do you confirm?
I fixed a few things in test/Makefile and test/Rules.mak (patch coming soon) and it looks like make check now works with a separate build directory. But still, I'm getting errors in test/math regarding __builtin_isfinite and the like not getting floating-point arguments. To me it looks like the test code is wrong, but I may be wrong myself.
Any idea how to fix that?
Okay, apart from the fact that you're not supposed to call isfinite nor isnormal with anything except floating point arguments (tests in glibc do this by using intermediate variables initialized with the integer literals), and should cast those literals explicitly to FLOAT, I discovered that I can disable glibc tests by passing UCLIBC_ONLY=1 (these errors were triggered by my local native glibc). :/
But still, some tests that run a mipsel binary using qemu-mipsel fail miserably. Some because they just assume the binary is run natively (as test/crypt which defines a WRAPPER variable to run the binary using env), which is simply not working when SIMULATOR_uclibc equals some qemu binary. Some other because of reasons unknown to me at this time: test/unistd/clone (somehow the child processes seem to be un-wait4-able with qemu).
I'd *really* like to reproduce the failed tests because of my patch, but without any more information (actual uclibc-ng's .config, buildroot's .config, exact way to run the testsuite for mipsel on an amd64 machine), I'm fighting with unrelated problems so far.
Hi Ignacy, Ignacy Gawędzki wrote,
On Thu, Oct 13, 2016 at 06:10:15PM +0200, thus spake Ignacy Gawedzki:
On Thu, Oct 13, 2016 at 05:32:35PM +0200, thus spake Ignacy Gawedzki:
On Thu, Oct 13, 2016 at 05:17:32PM +0200, thus spake Ignacy Gawedzki:
On Thu, Oct 13, 2016 at 12:44:38PM +0200, thus spake Waldemar Brodkorb:
Hi Ignacy,
I tried v4, but it adds regressions for other architectures. For example MIPS Little endian running uClibc-ng testsuite.
Any idea? Can you try to reproduce the regressions on your side?
I just tried by building a buildroot toolchain for mipsel. So far make check fails even without my patch telling me that it doesn't know how to make target test/Makefile, needed by termios.
It looks just like make check doesn't work with a separate build directory (make O=/path/to/somewhere/else check). Do you confirm?
I fixed a few things in test/Makefile and test/Rules.mak (patch coming soon) and it looks like make check now works with a separate build directory. But still, I'm getting errors in test/math regarding __builtin_isfinite and the like not getting floating-point arguments. To me it looks like the test code is wrong, but I may be wrong myself.
Any idea how to fix that?
Okay, apart from the fact that you're not supposed to call isfinite nor isnormal with anything except floating point arguments (tests in glibc do this by using intermediate variables initialized with the integer literals), and should cast those literals explicitly to FLOAT, I discovered that I can disable glibc tests by passing UCLIBC_ONLY=1 (these errors were triggered by my local native glibc). :/
But still, some tests that run a mipsel binary using qemu-mipsel fail miserably. Some because they just assume the binary is run natively (as test/crypt which defines a WRAPPER variable to run the binary using env), which is simply not working when SIMULATOR_uclibc equals some qemu binary. Some other because of reasons unknown to me at this time: test/unistd/clone (somehow the child processes seem to be un-wait4-able with qemu).
I'd *really* like to reproduce the failed tests because of my patch, but without any more information (actual uclibc-ng's .config, buildroot's .config, exact way to run the testsuite for mipsel on an amd64 machine), I'm fighting with unrelated problems so far.
Sorry I visited ELCE 2016 in Berlin, so I had no time to give you the required information. I will sent you buildroot instructions later.
If you want you can try it with my embedded-test script (you need mksh and qemu installed): git clone git://git.embedded-test.org/git/embedded-test cd embedded-test git clone git://git.uclibc-ng.org/git/uclibc-ng mksh embedded-test.sh --arch=mipsel --libc=uclibc-ng \ --libc-source=uclibc-ng --test=libc
Only 3 tests should fail. Then apply your patch and run it again, it will automatically do a complete clean build.
best regards Waldemar
On Thu, Oct 13, 2016 at 09:19:19PM +0200, thus spake Waldemar Brodkorb:
If you want you can try it with my embedded-test script (you need mksh and qemu installed): git clone git://git.embedded-test.org/git/embedded-test cd embedded-test git clone git://git.uclibc-ng.org/git/uclibc-ng mksh embedded-test.sh --arch=mipsel --libc=uclibc-ng \ --libc-source=uclibc-ng --test=libc
Only 3 tests should fail. Then apply your patch and run it again, it will automatically do a complete clean build.
Okay I did this several times yesterday. On the first attempts, 11 tests failed without my patch vs. 12 with it. The additional test that failed with my patch was nptl/tst-cancelx10. I started investigating what could possibly go wrong and tried several things, from running the binary with qemu-mipsel to logging into the vm used for tests and running the test from there. It seemed at first that with my patch the binary got killed with SIGABRT. I re-ran embedded-test.sh several times in the process and at some point noticed that the SHA-1 for openadk is not the same. Since that moment, I re-ran embedded-test.sh with a pristine setup in both cases (with and without my patch). Now in both cases I have 11 failed tests and nptl/tst-cancelx10 doesn't fail.
So I'm wondering whether anything in openadk could have changed in the meantime that makes the tests work well in both cases.
Could you please run the tests again yourself to check this?
Cheers,
Ignacy
Hi, Ignacy Gawędzki wrote,
On Thu, Oct 13, 2016 at 09:19:19PM +0200, thus spake Waldemar Brodkorb:
If you want you can try it with my embedded-test script (you need mksh and qemu installed): git clone git://git.embedded-test.org/git/embedded-test cd embedded-test git clone git://git.uclibc-ng.org/git/uclibc-ng mksh embedded-test.sh --arch=mipsel --libc=uclibc-ng \ --libc-source=uclibc-ng --test=libc
Only 3 tests should fail. Then apply your patch and run it again, it will automatically do a complete clean build.
Okay I did this several times yesterday. On the first attempts, 11 tests failed without my patch vs. 12 with it. The additional test that failed with my patch was nptl/tst-cancelx10. I started investigating what could possibly go wrong and tried several things, from running the binary with qemu-mipsel to logging into the vm used for tests and running the test from there. It seemed at first that with my patch the binary got killed with SIGABRT. I re-ran embedded-test.sh several times in the process and at some point noticed that the SHA-1 for openadk is not the same. Since that moment, I re-ran embedded-test.sh with a pristine setup in both cases (with and without my patch). Now in both cases I have 11 failed tests and nptl/tst-cancelx10 doesn't fail.
So I'm wondering whether anything in openadk could have changed in the meantime that makes the tests work well in both cases.
Could you please run the tests again yourself to check this?
I tested again. With uClibc-ng master i get exactly 3 errors. Tried three times.
With your patch I get sometime 11 or 12 errors. Seems a timeout issue.
What version of Qemu are you using?
qemu-system-mips -version QEMU emulator version 2.6.1, Copyright (c) 2003-2008 Fabrice Bellard
We recently had issues with the testsuite build without the full gcc and I thinking of separating the testsuite to its own project.
OpenADK does not change between runs of embedded-test as long as you don't use --update.
Are you sure you use uClibc-ng fresh checkout and referencing the directory with --libc-source? 1.0.18 release would have 11/12 errors, which is the fallback when no special directory is used.
best regards Waldemar
On Sun, Oct 16, 2016 at 05:45:40PM +0200, thus spake Waldemar Brodkorb:
I tested again. With uClibc-ng master i get exactly 3 errors. Tried three times.
I was using d4d4f37 and my patch applied on top of it.
With your patch I get sometime 11 or 12 errors. Seems a timeout issue.
What version of Qemu are you using?
qemu-system-mips -version QEMU emulator version 2.6.1, Copyright (c) 2003-2008 Fabrice Bellard
I'm using 2.5.0.
We recently had issues with the testsuite build without the full gcc and I thinking of separating the testsuite to its own project.
OpenADK does not change between runs of embedded-test as long as you don't use --update.
Yes, but I ran my tests in two copies of embedded-test.git, and most probably the second one cloned a more recent version of openadk.
Are you sure you use uClibc-ng fresh checkout and referencing the directory with --libc-source? 1.0.18 release would have 11/12 errors, which is the fallback when no special directory is used.
As I said, I used d4d4f37 and not strictly origin/master. But I otherwise used the command line you gave me, including --libc-source.
I will re-run the tests with origin/master and my patch on top of it.
Cheers,
Ignacy
Hi, Ignacy Gawędzki wrote,
On Sun, Oct 16, 2016 at 05:45:40PM +0200, thus spake Waldemar Brodkorb:
I tested again. With uClibc-ng master i get exactly 3 errors. Tried three times.
I was using d4d4f37 and my patch applied on top of it.
With your patch I get sometime 11 or 12 errors. Seems a timeout issue.
What version of Qemu are you using?
qemu-system-mips -version QEMU emulator version 2.6.1, Copyright (c) 2003-2008 Fabrice Bellard
I'm using 2.5.0.
We recently had issues with the testsuite build without the full gcc and I thinking of separating the testsuite to its own project.
OpenADK does not change between runs of embedded-test as long as you don't use --update.
Yes, but I ran my tests in two copies of embedded-test.git, and most probably the second one cloned a more recent version of openadk.
Are you sure you use uClibc-ng fresh checkout and referencing the directory with --libc-source? 1.0.18 release would have 11/12 errors, which is the fallback when no special directory is used.
As I said, I used d4d4f37 and not strictly origin/master. But I otherwise used the command line you gave me, including --libc-source.
But 17ad14e5780533db90171e16b95dbeda4e81ffb0 contains a workaround for exactly the seen problem.
I will re-run the tests with origin/master and my patch on top of it.
Okay, thanks. Waldemar
On Sun, Oct 16, 2016 at 10:01:30PM +0200, thus spake Waldemar Brodkorb:
As I said, I used d4d4f37 and not strictly origin/master. But I otherwise used the command line you gave me, including --libc-source.
But 17ad14e5780533db90171e16b95dbeda4e81ffb0 contains a workaround for exactly the seen problem.
I will re-run the tests with origin/master and my patch on top of it.
I found a few interesting things. The test binaries are compiled by openadk with the "initial" GCC and not the "final" one. The difference is that the implementation of the unwinder code is then taken from libgcc.a. I get the same behavior if I explicitly add this library to the list of objects to link into the test binary. With a final version of GCC, the implementation is taken from libgcc_s.so as it should and the behavior is maybe not ideal but to me it looks far better (is that because the initial GCC doesn't really implement any unwinder code?).
The reason why this works without my patch is that the implementation of the unwinder code is then linked dynamically from libc.so, which, as I've said previously, is not supposed to be used by code from outside the lib itself.
I haven't had time yet to look into openadk in order to understand why it's not using the final GCC to build the tests. Do you have any idea?
On Mon, Oct 17, 2016 at 03:40:04PM +0200, thus spake Ignacy Gawedzki:
On Sun, Oct 16, 2016 at 10:01:30PM +0200, thus spake Waldemar Brodkorb:
As I said, I used d4d4f37 and not strictly origin/master. But I otherwise used the command line you gave me, including --libc-source.
But 17ad14e5780533db90171e16b95dbeda4e81ffb0 contains a workaround for exactly the seen problem.
I will re-run the tests with origin/master and my patch on top of it.
I found a few interesting things. The test binaries are compiled by openadk with the "initial" GCC and not the "final" one. The difference is that the implementation of the unwinder code is then taken from libgcc.a. I get the same behavior if I explicitly add this library to the list of objects to link into the test binary. With a final version of GCC, the implementation is taken from libgcc_s.so as it should and the behavior is maybe not ideal but to me it looks far better (is that because the initial GCC doesn't really implement any unwinder code?).
BTW, the initial GCC is built with --disable-threads. Could that possibly be the reason some of the tests in nptl fail?
Hi Ignacy, Ignacy Gawędzki wrote,
On Sun, Oct 16, 2016 at 10:01:30PM +0200, thus spake Waldemar Brodkorb:
As I said, I used d4d4f37 and not strictly origin/master. But I otherwise used the command line you gave me, including --libc-source.
But 17ad14e5780533db90171e16b95dbeda4e81ffb0 contains a workaround for exactly the seen problem.
I will re-run the tests with origin/master and my patch on top of it.
I found a few interesting things. The test binaries are compiled by openadk with the "initial" GCC and not the "final" one. The difference is that the implementation of the unwinder code is then taken from libgcc.a. I get the same behavior if I explicitly add this library to the list of objects to link into the test binary. With a final version of GCC, the implementation is taken from libgcc_s.so as it should and the behavior is maybe not ideal but to me it looks far better (is that because the initial GCC doesn't really implement any unwinder code?).
The reason why this works without my patch is that the implementation of the unwinder code is then linked dynamically from libc.so, which, as I've said previously, is not supposed to be used by code from outside the lib itself.
I haven't had time yet to look into openadk in order to understand why it's not using the final GCC to build the tests. Do you have any idea?
Because it is compiled as part of the toolchain. I think it is similary done in Buildroot.
I sent a proposal to the list, how we might fix these kind of issues in the future.
best regards Waldemar
Hi Ignacy, Ignacy Gawędzki wrote,
Since librt and libpthread are now integrated into libc, including unwind-resume and unwind-forcedunwind implementations of unwind code makes no sense. Only unwind-forcedunwind is now included with functions hidden to avoid them overriding the ones from libgcc_s.
I tested the patch and I think I will push it in the next days.
Sorry that it took a while, but the removal of the test suite took a while. Now the test suite is compiled as a normal software package and not with the initial gcc. Therefore no regressions seen with your patch.
Any other news to the patch?
best regards Waldemar
On Wed, Nov 30, 2016 at 06:40:01AM +0100, thus spake Waldemar Brodkorb:
Hi Ignacy,
Hi Waldemar,
Ignacy Gawędzki wrote,
Since librt and libpthread are now integrated into libc, including unwind-resume and unwind-forcedunwind implementations of unwind code makes no sense. Only unwind-forcedunwind is now included with functions hidden to avoid them overriding the ones from libgcc_s.
I tested the patch and I think I will push it in the next days.
Nice.
Sorry that it took a while, but the removal of the test suite took a while. Now the test suite is compiled as a normal software package and not with the initial gcc.
That's definitely the right way to go.
Therefore no regressions seen with your patch.
I'm happy to hear that. =)
Any other news to the patch?
No. We've been using it on uClibc-ng 1.0.18 in-house for weeks without any noticeable problem.
Regards,
Ignacy
Using unwind-forcedunwind.c from nptl/sysdeps/pthread doesn't work well on ARM, see nptl/sysdeps/unix/sysv/linux/arm/unwind-forcedunwind.c for an explanation.
The following code example shows what's wrong without the ARM-specific version.
--------------------------------------------------------------------
struct Foo { ~Foo(); };
Foo::~Foo() {}
void f() { Foo a; throw 0; }
int main() { try { f(); } catch (int) { std::cerr << "caught" << std::endl; } return 0; } --------------------------------------------------------------------
Compile without any optimizations (it's important that Foo's destructor is not inlined) and run with uClibc preloaded using LD_PRELOAD to ensure uClibc's implementation of Unwind_Resume overrides the one from libgcc_s. The thrown exception is not caught as expected and the program aborts.
Signed-off-by: Ignacy Gawędzki ignacy.gawedzki@green-communications.fr --- libpthread/nptl/sysdeps/pthread/Makefile.in | 7 +++++-- libpthread/nptl/sysdeps/pthread/pthread-unwind-forcedunwind.c | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 libpthread/nptl/sysdeps/pthread/pthread-unwind-forcedunwind.c
diff --git a/libpthread/nptl/sysdeps/pthread/Makefile.in b/libpthread/nptl/sysdeps/pthread/Makefile.in index a501b64..1496252 100644 --- a/libpthread/nptl/sysdeps/pthread/Makefile.in +++ b/libpthread/nptl/sysdeps/pthread/Makefile.in @@ -40,12 +40,15 @@ CFLAGS-pthread_barrier_wait.c = -D_GNU_SOURCE CFLAGS-pthread_spin_destroy.c = -D_GNU_SOURCE CFLAGS-pthread_spin_init.c = -D_GNU_SOURCE CFLAGS-pthread_spin_unlock.c = -D_GNU_SOURCE -CFLAGS-unwind-forcedunwind.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-pthread-unwind-forcedunwind.c = -fexceptions -fasynchronous-unwind-tables
CFLAGS-OMIT-librt-cancellation.c = -DIS_IN_libpthread CFLAGS-librt-cancellation.c = -DIS_IN_librt \ -fexceptions -fasynchronous-unwind-tables -libpthread-so-y += $(patsubst %,$(libpthread_pthread_OUT)/%.oS, unwind-forcedunwind) +CFLAGS-rt-unwind-resume.c = -DIS_IN_librt \ + -fexceptions -fasynchronous-unwind-tables + +libpthread-so-y += $(patsubst %,$(libpthread_pthread_OUT)/%.oS, pthread-unwind-forcedunwind)
librt-pt-routines-y = librt-cancellation.c
diff --git a/libpthread/nptl/sysdeps/pthread/pthread-unwind-forcedunwind.c b/libpthread/nptl/sysdeps/pthread/pthread-unwind-forcedunwind.c new file mode 100644 index 0000000..fc04eb4 --- /dev/null +++ b/libpthread/nptl/sysdeps/pthread/pthread-unwind-forcedunwind.c @@ -0,0 +1 @@ +#include <unwind-forcedunwind.c>