Message ID | db51debb-cf84-5f5a-6659-eb9ad1ea72e4@redhat.com |
---|---|
State | New |
Headers | show |
On Nov 14 2016, Florian Weimer <fweimer@redhat.com> wrote: > I came up with the attached patch. It adds a definition of the hidden > redirect to libc.so, as expected. But in addition to that, I get this ABI > difference on powerpc32: > > -GLIBC_2.3.4 __longjmp F Are you sure this is the only change you did? setjmp.* does not contain anything related to longjmp. I couldn't reproduce that. Andreas. -- Andreas Schwab, SUSE Labs, schwab@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different."
On 11/14/2016 04:37 PM, Andreas Schwab wrote: > On Nov 14 2016, Florian Weimer <fweimer@redhat.com> wrote: > >> I came up with the attached patch. It adds a definition of the hidden >> redirect to libc.so, as expected. But in addition to that, I get this ABI >> difference on powerpc32: >> >> -GLIBC_2.3.4 __longjmp F > > Are you sure this is the only change you did? setjmp.* does not contain > anything related to longjmp. I couldn't reproduce that. Thanks. It only happens in conjunction with this patch: <https://sourceware.org/ml/libc-alpha/2016-11/msg00465.html> This patch adds a reference to __longjmp to libc.so. With it, libc_pic.os has this: 8296: 00017024 492 FUNC GLOBAL HIDDEN 2 __longjmp@@GLIBC_2.3.4 9342: 00017210 184 FUNC GLOBAL DEFAULT 2 __longjmp@GLIBC_2.0 And libc.so has this: 5208: 00039c04 492 FUNC LOCAL DEFAULT 11 __longjmp@@GLIBC_2.3.4 5758: 00039df0 184 FUNC LOCAL DEFAULT 11 __longjmp@GLIBC_2.0 It turns out that libc.map lists _longjmp only, based on the entry in sysdeps/powerpc/Versions. setjmp/__longjmp.os has: 11: 00000000 492 FUNC GLOBAL DEFAULT 1 __vmx__longjmp 14: 000001ec 184 FUNC GLOBAL DEFAULT 1 __novmx__longjmp 15: 00000000 492 FUNC GLOBAL DEFAULT 1 __longjmp@@GLIBC_2.3.4 16: 000001ec 184 FUNC GLOBAL DEFAULT 1 __longjmp@GLIBC_2.0 setjmp/longjmp.os has: 21: 00000000 116 FUNC GLOBAL DEFAULT 1 __vmx__libc_longjmp 22: 00000000 116 FUNC GLOBAL DEFAULT 1 __vmx__libc_siglongjmp 23: 00000000 116 FUNC WEAK DEFAULT 1 __vmx_longjmp 24: 00000000 116 FUNC WEAK DEFAULT 1 __vmxlongjmp 25: 00000000 116 FUNC WEAK DEFAULT 1 __vmxsiglongjmp 30: 00000000 116 FUNC GLOBAL HIDDEN 1 __GI___vmx__libc_longjmp 31: 00000000 116 FUNC GLOBAL DEFAULT 1 __libc_longjmp@@GLIBC_PRIVATE 32: 00000000 116 FUNC GLOBAL DEFAULT 1 __libc_siglongjmp@@GLIBC_PRIVATE 33: 00000000 116 FUNC WEAK DEFAULT 1 _longjmp@@GLIBC_2.3.4 34: 00000000 116 FUNC WEAK DEFAULT 1 longjmp@@GLIBC_2.3.4 35: 00000000 116 FUNC WEAK DEFAULT 1 siglongjmp@@GLIBC_2.3.4 So the __GI_* aliases are missing there, too. The internal reference to __longjmp seems to cause ld to drop the exported symbol version. Adding __longjmp to sysdeps/powerpc/Versions does not change this. Neither does adding libc_hidden_ver (__vmx__libc_longjmp, __longjmp) to sysdeps/powerpc/longjmp.c. Okay, that's because the definition comes from sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S. But changing that file to contain: versioned_symbol (libc, __vmx__longjmp, __longjmp, GLIBC_2_3_4); # define __longjmp_symbol __vmx__longjmp # include "__longjmp-common.S" libc_hidden_ver (__vmx__libc_longjmp, __longjmp) does not help, either. Maybe this is relevant. __longjmp is declared *hidden*: extern void __longjmp (__jmp_buf __env, int __val) __attribute__ ((__noreturn__)) attribute_hidden; So maybe that's why a reference to it causes ld to drop the export. I wonder if this indeed the root cause. It would mean this is a spurious ABI addition. Can we drop __longjmp from the ABI in this way? Or do we have to fix this up using a powerpc-specific alias? This happens on no other architecture for which we have abilist files. It was introduced into the abilist file here: commit 0741d64c9140aa205f9df8ebee80ca0bcb018445 Author: Andreas Schwab <schwab@linux-m68k.org> Date: Tue May 1 01:12:54 2012 +0200 Update powerpc ABI data Thanks, Florian
On Nov 14 2016, Florian Weimer <fweimer@redhat.com> wrote: > This patch adds a reference to __longjmp to libc.so. With it, libc_pic.os > has this: > > 8296: 00017024 492 FUNC GLOBAL HIDDEN 2 > __longjmp@@GLIBC_2.3.4 > 9342: 00017210 184 FUNC GLOBAL DEFAULT 2 __longjmp@GLIBC_2.0 > > And libc.so has this: > > 5208: 00039c04 492 FUNC LOCAL DEFAULT 11 > __longjmp@@GLIBC_2.3.4 > 5758: 00039df0 184 FUNC LOCAL DEFAULT 11 __longjmp@GLIBC_2.0 > > It turns out that libc.map lists _longjmp only, based on the entry in > sysdeps/powerpc/Versions. So it looks like a linker bug that the symbol was exported before, probably related to the fact that it is a default version. But it is also a bug that __longjmp has a version in the first place. > setjmp/__longjmp.os has: > > 11: 00000000 492 FUNC GLOBAL DEFAULT 1 __vmx__longjmp > 14: 000001ec 184 FUNC GLOBAL DEFAULT 1 __novmx__longjmp > 15: 00000000 492 FUNC GLOBAL DEFAULT 1 > __longjmp@@GLIBC_2.3.4 > 16: 000001ec 184 FUNC GLOBAL DEFAULT 1 __longjmp@GLIBC_2.0 > > setjmp/longjmp.os has: > > 21: 00000000 116 FUNC GLOBAL DEFAULT 1 __vmx__libc_longjmp > 22: 00000000 116 FUNC GLOBAL DEFAULT 1 > __vmx__libc_siglongjmp > 23: 00000000 116 FUNC WEAK DEFAULT 1 __vmx_longjmp > 24: 00000000 116 FUNC WEAK DEFAULT 1 __vmxlongjmp > 25: 00000000 116 FUNC WEAK DEFAULT 1 __vmxsiglongjmp > 30: 00000000 116 FUNC GLOBAL HIDDEN 1 > __GI___vmx__libc_longjmp > 31: 00000000 116 FUNC GLOBAL DEFAULT 1 > __libc_longjmp@@GLIBC_PRIVATE > 32: 00000000 116 FUNC GLOBAL DEFAULT 1 > __libc_siglongjmp@@GLIBC_PRIVATE > 33: 00000000 116 FUNC WEAK DEFAULT 1 > _longjmp@@GLIBC_2.3.4 > 34: 00000000 116 FUNC WEAK DEFAULT 1 longjmp@@GLIBC_2.3.4 > 35: 00000000 116 FUNC WEAK DEFAULT 1 > siglongjmp@@GLIBC_2.3.4 The version is coming from sysdeps/powerpc/powerpc32/fpu/__longjmp.S, and was added in commit 5c76ff279f. Clearly this was a genuine error, and the versioned alias in sysdeps/powerpc/powerpc32/__longjmp.S has later been removed in commit 9b9ef82358 (without fixing the fpu version). > So the __GI_* aliases are missing there, too. There is no hidden_proto for __longjmp, only attribute_hidden, so this is correct. It is already an internal-only function. > I wonder if this indeed the root cause. It would mean this is a spurious > ABI addition. Can we drop __longjmp from the ABI in this way? Or do we > have to fix this up using a powerpc-specific alias? I'm not sure. Nobody should be using __longjmp, it's not declared or used in any public header. > This happens on no other architecture for which we have abilist files. It > was introduced into the abilist file here: > > commit 0741d64c9140aa205f9df8ebee80ca0bcb018445 > Author: Andreas Schwab <schwab@linux-m68k.org> > Date: Tue May 1 01:12:54 2012 +0200 > > Update powerpc ABI data It's unfortunate that Jakub didn't fix the fpu version back in 2004. Andreas. -- Andreas Schwab, SUSE Labs, schwab@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different."
On 11/15/2016 10:06 AM, Andreas Schwab wrote: > On Nov 14 2016, Florian Weimer <fweimer@redhat.com> wrote: > >> This patch adds a reference to __longjmp to libc.so. With it, libc_pic.os >> has this: >> >> 8296: 00017024 492 FUNC GLOBAL HIDDEN 2 >> __longjmp@@GLIBC_2.3.4 >> 9342: 00017210 184 FUNC GLOBAL DEFAULT 2 __longjmp@GLIBC_2.0 >> >> And libc.so has this: >> >> 5208: 00039c04 492 FUNC LOCAL DEFAULT 11 >> __longjmp@@GLIBC_2.3.4 >> 5758: 00039df0 184 FUNC LOCAL DEFAULT 11 __longjmp@GLIBC_2.0 >> >> It turns out that libc.map lists _longjmp only, based on the entry in >> sysdeps/powerpc/Versions. > > So it looks like a linker bug that the symbol was exported before, > probably related to the fact that it is a default version. But it is > also a bug that __longjmp has a version in the first place. I've asked for clarification of the linker behavior: <https://sourceware.org/ml/binutils/2016-11/msg00180.html> From the binutils perspective, it may work as designed. It may be a mismatch between the assembler (which does not know about a mere reference to a hidden symbol), and the C/C++ source, where visibility attributes are supported on declarations (and declarations in one translation unit are not supposed to affect how other translation units are compiled/linked). >> ABI addition. Can we drop __longjmp from the ABI in this way? Or do we >> have to fix this up using a powerpc-specific alias? > > I'm not sure. Nobody should be using __longjmp, it's not declared or > used in any public header. I don't see a reference in codesearch.debian.org (the existing ones are definitions in other libcs). I don't have ppc RPMs indexed in my symbol database, unfortunately. I suspect this is something for the powerpc maintainers to decide. Thanks, Florian
powerpc: Add hidden definition for __sigsetjmp 2016-11-14 Florian Weimer <fweimer@redhat.com> * sysdeps/powerpc/powerpc64/setjmp-common.S (__GI___sigsetjmp): Define. * sysdeps/powerpc/powerpc32/setjmp.S (__sigsetjmp): Add hidden definition. diff --git a/sysdeps/powerpc/powerpc32/fpu/setjmp.S b/sysdeps/powerpc/powerpc32/fpu/setjmp.S index 6a4016c..de6cdcf 100644 --- a/sysdeps/powerpc/powerpc32/fpu/setjmp.S +++ b/sysdeps/powerpc/powerpc32/fpu/setjmp.S @@ -32,6 +32,7 @@ versioned_symbol (libc, __vmx__sigsetjmp, __sigsetjmp, GLIBC_2_3_4) # define __sigsetjmp_symbol __vmx__sigsetjmp # define __sigjmp_save_symbol __vmx__sigjmp_save # include "setjmp-common.S" +libc_hidden_ver (__vmx__sigsetjmp, __sigsetjmp) # if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) # define __NO_VMX__ diff --git a/sysdeps/powerpc/powerpc32/setjmp.S b/sysdeps/powerpc/powerpc32/setjmp.S index 88f7f82..285d40c 100644 --- a/sysdeps/powerpc/powerpc32/setjmp.S +++ b/sysdeps/powerpc/powerpc32/setjmp.S @@ -31,6 +31,7 @@ versioned_symbol (libc, __vmx__sigsetjmp, __sigsetjmp, GLIBC_2_3_4) # define __sigsetjmp_symbol __vmx__sigsetjmp # define __sigjmp_save_symbol __vmx__sigjmp_save # include "setjmp-common.S" +libc_hidden_ver (__vmx__sigsetjmp, __sigsetjmp) # if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) # define __NO_VMX__ diff --git a/sysdeps/powerpc/powerpc64/setjmp-common.S b/sysdeps/powerpc/powerpc64/setjmp-common.S index 83361f5..b5de49e 100644 --- a/sysdeps/powerpc/powerpc64/setjmp-common.S +++ b/sysdeps/powerpc/powerpc64/setjmp-common.S @@ -232,3 +232,14 @@ L(no_vmx): blr #endif END (__sigsetjmp_symbol) + +#if defined SHARED && !IS_IN (rtld) && !defined __NO_VMX__ +/* When called from within libc we need a special version of __sigsetjmp + that saves r2 since the call won't go via a plt call stub. See + bugz #269. */ +ENTRY (__GI___sigsetjmp) + std r2,FRAME_TOC_SAVE(r1) /* Save the callers TOC in the save area. */ + CALL_MCOUNT 1 + b JUMPTARGET (GLUE(__sigsetjmp_symbol,_ent)) +END (__GI___sigsetjmp) +#endif