[hurd,commited] hurd: Avoid more libc.so local PLTs

Message ID 20180403003817.21337-1-samuel.thibault@ens-lyon.org
State New
Headers show
Series
  • [hurd,commited] hurd: Avoid more libc.so local PLTs
Related show

Commit Message

Samuel Thibault April 3, 2018, 12:38 a.m.
* hurd/catch-signal.c (__hurd_catch_signal): Call __libc_siglongjmp
	instead if siglongjmp.
	(hurd_safe_memmove): Call __libc_longjmp instead of longjmp.
	* hurd/hurdfault.c (faulted): Call __libc_longjmp instead of longjmp.
	* include/setjmp.h (__libc_siglongjmp, __libc_longjmp): New hidden
	prototypes.
	* libio/iolibio.h (_IO_puts): New hidden prototype.
	* libio/ioputs.c (_IO_puts): New hidden def.
	* setjmp/longjmp.c (__libc_longjmp, __libc_siglongjmp): New hidden
	defs.
	* sysdeps/mach/hurd/sigwait.c (__sigwait): Call __libc_longjmp instead
	of longjmp.
---
 ChangeLog                   | 12 ++++++++++++
 hurd/catch-signal.c         |  4 ++--
 hurd/hurdfault.c            |  2 +-
 include/setjmp.h            |  3 +++
 libio/iolibio.h             |  1 +
 libio/ioputs.c              |  1 +
 setjmp/longjmp.c            |  2 ++
 sysdeps/mach/hurd/sigwait.c |  2 +-
 8 files changed, 23 insertions(+), 4 deletions(-)

Comments

Andreas Schwab April 3, 2018, 8:10 a.m. | #1
On Apr 03 2018, Samuel Thibault <samuel.thibault@ens-lyon.org> wrote:

> 	* hurd/catch-signal.c (__hurd_catch_signal): Call __libc_siglongjmp
> 	instead if siglongjmp.
> 	(hurd_safe_memmove): Call __libc_longjmp instead of longjmp.
> 	* hurd/hurdfault.c (faulted): Call __libc_longjmp instead of longjmp.
> 	* include/setjmp.h (__libc_siglongjmp, __libc_longjmp): New hidden
> 	prototypes.
> 	* libio/iolibio.h (_IO_puts): New hidden prototype.
> 	* libio/ioputs.c (_IO_puts): New hidden def.
> 	* setjmp/longjmp.c (__libc_longjmp, __libc_siglongjmp): New hidden
> 	defs.
> 	* sysdeps/mach/hurd/sigwait.c (__sigwait): Call __libc_longjmp instead
> 	of longjmp.

https://build.opensuse.org/package/live_build_log/home:Andreas_Schwab:glibc/glibc/s/s390x

In file included from <command-line>:0:0:
../sysdeps/s390/longjmp.c:35:34: error: '__libc_longjmp' aliased to undefined symbol '__libc_siglongjmp'
 strong_alias (__libc_siglongjmp, __libc_longjmp)
                                  ^
./../include/libc-symbols.h:135:26: note: in definition of macro '_strong_alias'
   extern __typeof (name) aliasname __attribute__ ((alias (#name)));
                          ^~~~~~~~~
../sysdeps/s390/longjmp.c:35:1: note: in expansion of macro 'strong_alias'
 strong_alias (__libc_siglongjmp, __libc_longjmp)
 ^~~~~~~~~~~~

Andreas.
Samuel Thibault April 3, 2018, 8:20 a.m. | #2
Andreas Schwab, on mar. 03 avril 2018 10:10:21 +0200, wrote:
> On Apr 03 2018, Samuel Thibault <samuel.thibault@ens-lyon.org> wrote:
> 
> > 	* hurd/catch-signal.c (__hurd_catch_signal): Call __libc_siglongjmp
> > 	instead if siglongjmp.
> > 	(hurd_safe_memmove): Call __libc_longjmp instead of longjmp.
> > 	* hurd/hurdfault.c (faulted): Call __libc_longjmp instead of longjmp.
> > 	* include/setjmp.h (__libc_siglongjmp, __libc_longjmp): New hidden
> > 	prototypes.
> > 	* libio/iolibio.h (_IO_puts): New hidden prototype.
> > 	* libio/ioputs.c (_IO_puts): New hidden def.
> > 	* setjmp/longjmp.c (__libc_longjmp, __libc_siglongjmp): New hidden
> > 	defs.
> > 	* sysdeps/mach/hurd/sigwait.c (__sigwait): Call __libc_longjmp instead
> > 	of longjmp.
> 
> https://build.opensuse.org/package/live_build_log/home:Andreas_Schwab:glibc/glibc/s/s390x
> 
> In file included from <command-line>:0:0:
> ../sysdeps/s390/longjmp.c:35:34: error: '__libc_longjmp' aliased to undefined symbol '__libc_siglongjmp'
>  strong_alias (__libc_siglongjmp, __libc_longjmp)
>                                   ^
> ./../include/libc-symbols.h:135:26: note: in definition of macro '_strong_alias'
>    extern __typeof (name) aliasname __attribute__ ((alias (#name)));
>                           ^~~~~~~~~
> ../sysdeps/s390/longjmp.c:35:1: note: in expansion of macro 'strong_alias'
>  strong_alias (__libc_siglongjmp, __libc_longjmp)

Ah, there is #define __libc_siglongjmp magic here indeed.  Does the
attached patch fix it?

Samuel
diff --git a/sysdeps/s390/longjmp.c b/sysdeps/s390/longjmp.c
index e61cdba2a3..e543415df0 100644
--- a/sysdeps/s390/longjmp.c
+++ b/sysdeps/s390/longjmp.c
@@ -33,6 +33,8 @@
    but were reverted before 2.20. Thus both versions are the same function.  */
 
 strong_alias (__libc_siglongjmp, __libc_longjmp)
+libc_hidden_def (__libc_longjmp)
+libc_hidden_def (__libc_siglongjmp)
 
 weak_alias (__libc_siglongjmp, __v1_longjmp)
 weak_alias (__libc_siglongjmp, __v2_longjmp)
Stefan Liebler April 3, 2018, 9:02 a.m. | #3
On 04/03/2018 10:20 AM, Samuel Thibault wrote:
> Andreas Schwab, on mar. 03 avril 2018 10:10:21 +0200, wrote:
>> On Apr 03 2018, Samuel Thibault <samuel.thibault@ens-lyon.org> wrote:
>>
>>> 	* hurd/catch-signal.c (__hurd_catch_signal): Call __libc_siglongjmp
>>> 	instead if siglongjmp.
>>> 	(hurd_safe_memmove): Call __libc_longjmp instead of longjmp.
>>> 	* hurd/hurdfault.c (faulted): Call __libc_longjmp instead of longjmp.
>>> 	* include/setjmp.h (__libc_siglongjmp, __libc_longjmp): New hidden
>>> 	prototypes.
>>> 	* libio/iolibio.h (_IO_puts): New hidden prototype.
>>> 	* libio/ioputs.c (_IO_puts): New hidden def.
>>> 	* setjmp/longjmp.c (__libc_longjmp, __libc_siglongjmp): New hidden
>>> 	defs.
>>> 	* sysdeps/mach/hurd/sigwait.c (__sigwait): Call __libc_longjmp instead
>>> 	of longjmp.
>>
>> https://build.opensuse.org/package/live_build_log/home:Andreas_Schwab:glibc/glibc/s/s390x
>>
>> In file included from <command-line>:0:0:
>> ../sysdeps/s390/longjmp.c:35:34: error: '__libc_longjmp' aliased to undefined symbol '__libc_siglongjmp'
>>   strong_alias (__libc_siglongjmp, __libc_longjmp)
>>                                    ^
>> ./../include/libc-symbols.h:135:26: note: in definition of macro '_strong_alias'
>>     extern __typeof (name) aliasname __attribute__ ((alias (#name)));
>>                            ^~~~~~~~~
>> ../sysdeps/s390/longjmp.c:35:1: note: in expansion of macro 'strong_alias'
>>   strong_alias (__libc_siglongjmp, __libc_longjmp)
> 
> Ah, there is #define __libc_siglongjmp magic here indeed.  Does the
> attached patch fix it?
> 
> Samuel
> 
Yes. This patch fixes the issue on s390x.

Thanks.
Stefan
H.J. Lu April 3, 2018, 7:26 p.m. | #4
On Tue, Apr 3, 2018 at 1:20 AM, Samuel Thibault
<samuel.thibault@ens-lyon.org> wrote:
> Andreas Schwab, on mar. 03 avril 2018 10:10:21 +0200, wrote:
>> On Apr 03 2018, Samuel Thibault <samuel.thibault@ens-lyon.org> wrote:
>>
>> >     * hurd/catch-signal.c (__hurd_catch_signal): Call __libc_siglongjmp
>> >     instead if siglongjmp.
>> >     (hurd_safe_memmove): Call __libc_longjmp instead of longjmp.
>> >     * hurd/hurdfault.c (faulted): Call __libc_longjmp instead of longjmp.
>> >     * include/setjmp.h (__libc_siglongjmp, __libc_longjmp): New hidden
>> >     prototypes.
>> >     * libio/iolibio.h (_IO_puts): New hidden prototype.
>> >     * libio/ioputs.c (_IO_puts): New hidden def.
>> >     * setjmp/longjmp.c (__libc_longjmp, __libc_siglongjmp): New hidden
>> >     defs.
>> >     * sysdeps/mach/hurd/sigwait.c (__sigwait): Call __libc_longjmp instead
>> >     of longjmp.
>>
>> https://build.opensuse.org/package/live_build_log/home:Andreas_Schwab:glibc/glibc/s/s390x
>>
>> In file included from <command-line>:0:0:
>> ../sysdeps/s390/longjmp.c:35:34: error: '__libc_longjmp' aliased to undefined symbol '__libc_siglongjmp'
>>  strong_alias (__libc_siglongjmp, __libc_longjmp)
>>                                   ^
>> ./../include/libc-symbols.h:135:26: note: in definition of macro '_strong_alias'
>>    extern __typeof (name) aliasname __attribute__ ((alias (#name)));
>>                           ^~~~~~~~~
>> ../sysdeps/s390/longjmp.c:35:1: note: in expansion of macro 'strong_alias'
>>  strong_alias (__libc_siglongjmp, __libc_longjmp)
>
> Ah, there is #define __libc_siglongjmp magic here indeed.  Does the
> attached patch fix it?

__libc_longjmp and __libc_siglongjmp are private external functions provided for
libpthread.  They should never be called inside libc.   Please revert
it and find another
way to fix hurd.
H.J. Lu April 3, 2018, 8:51 p.m. | #5
On Tue, Apr 3, 2018 at 12:26 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Tue, Apr 3, 2018 at 1:20 AM, Samuel Thibault
> <samuel.thibault@ens-lyon.org> wrote:
>> Andreas Schwab, on mar. 03 avril 2018 10:10:21 +0200, wrote:
>>> On Apr 03 2018, Samuel Thibault <samuel.thibault@ens-lyon.org> wrote:
>>>
>>> >     * hurd/catch-signal.c (__hurd_catch_signal): Call __libc_siglongjmp
>>> >     instead if siglongjmp.
>>> >     (hurd_safe_memmove): Call __libc_longjmp instead of longjmp.
>>> >     * hurd/hurdfault.c (faulted): Call __libc_longjmp instead of longjmp.
>>> >     * include/setjmp.h (__libc_siglongjmp, __libc_longjmp): New hidden
>>> >     prototypes.
>>> >     * libio/iolibio.h (_IO_puts): New hidden prototype.
>>> >     * libio/ioputs.c (_IO_puts): New hidden def.
>>> >     * setjmp/longjmp.c (__libc_longjmp, __libc_siglongjmp): New hidden
>>> >     defs.
>>> >     * sysdeps/mach/hurd/sigwait.c (__sigwait): Call __libc_longjmp instead
>>> >     of longjmp.
>>>
>>> https://build.opensuse.org/package/live_build_log/home:Andreas_Schwab:glibc/glibc/s/s390x
>>>
>>> In file included from <command-line>:0:0:
>>> ../sysdeps/s390/longjmp.c:35:34: error: '__libc_longjmp' aliased to undefined symbol '__libc_siglongjmp'
>>>  strong_alias (__libc_siglongjmp, __libc_longjmp)
>>>                                   ^
>>> ./../include/libc-symbols.h:135:26: note: in definition of macro '_strong_alias'
>>>    extern __typeof (name) aliasname __attribute__ ((alias (#name)));
>>>                           ^~~~~~~~~
>>> ../sysdeps/s390/longjmp.c:35:1: note: in expansion of macro 'strong_alias'
>>>  strong_alias (__libc_siglongjmp, __libc_longjmp)
>>
>> Ah, there is #define __libc_siglongjmp magic here indeed.  Does the
>> attached patch fix it?
>
> __libc_longjmp and __libc_siglongjmp are private external functions provided for
> libpthread.  They should never be called inside libc.   Please revert
> it and find another
> way to fix hurd.

Here is my patch:

https://sourceware.org/git/?p=glibc.git;a=commit;h=6253bacdc00de132dec452ff7c6ce3ba7fa23d81

which removed

libc_hidden_def (__libc_longjmp)

I am going to check in this path.
Samuel Thibault April 3, 2018, 9:07 p.m. | #6
Hello,

H.J. Lu, on mar. 03 avril 2018 12:26:33 -0700, wrote:
> __libc_longjmp and __libc_siglongjmp are private external functions provided for
> libpthread.  They should never be called inside libc.

I'm sorry for asking, but are these conventions documented somewhere?
These look like magic to me otherwise: why shouldn't they ever be called
from libc?

Samuel
H.J. Lu April 3, 2018, 9:16 p.m. | #7
On Tue, Apr 3, 2018 at 2:07 PM, Samuel Thibault
<samuel.thibault@ens-lyon.org> wrote:
> Hello,
>
> H.J. Lu, on mar. 03 avril 2018 12:26:33 -0700, wrote:
>> __libc_longjmp and __libc_siglongjmp are private external functions provided for
>> libpthread.  They should never be called inside libc.
>
> I'm sorry for asking, but are these conventions documented somewhere?
> These look like magic to me otherwise: why shouldn't they ever be called
> from libc?
>

I don't believe they are well documented.
Samuel Thibault April 3, 2018, 9:24 p.m. | #8
H.J. Lu, on mar. 03 avril 2018 14:16:50 -0700, wrote:
> On Tue, Apr 3, 2018 at 2:07 PM, Samuel Thibault
> <samuel.thibault@ens-lyon.org> wrote:
> > Hello,
> >
> > H.J. Lu, on mar. 03 avril 2018 12:26:33 -0700, wrote:
> >> __libc_longjmp and __libc_siglongjmp are private external functions provided for
> >> libpthread.  They should never be called inside libc.
> >
> > I'm sorry for asking, but are these conventions documented somewhere?
> > These look like magic to me otherwise:
> 
> I don't believe they are well documented.

Ok, then I need an answer to my question:

> > why shouldn't they ever be called from libc?

The existing hurd code does use them for catching signals, so I need to
know how to fix it.

Samuel
H.J. Lu April 3, 2018, 9:41 p.m. | #9
On Tue, Apr 3, 2018 at 2:24 PM, Samuel Thibault
<samuel.thibault@ens-lyon.org> wrote:
> H.J. Lu, on mar. 03 avril 2018 14:16:50 -0700, wrote:
>> On Tue, Apr 3, 2018 at 2:07 PM, Samuel Thibault
>> <samuel.thibault@ens-lyon.org> wrote:
>> > Hello,
>> >
>> > H.J. Lu, on mar. 03 avril 2018 12:26:33 -0700, wrote:
>> >> __libc_longjmp and __libc_siglongjmp are private external functions provided for
>> >> libpthread.  They should never be called inside libc.
>> >
>> > I'm sorry for asking, but are these conventions documented somewhere?
>> > These look like magic to me otherwise:
>>
>> I don't believe they are well documented.
>
> Ok, then I need an answer to my question:
>
>> > why shouldn't they ever be called from libc?
>
> The existing hurd code does use them for catching signals, so I need to
> know how to fix it.

Use something similar to

libc_hidden_proto (_setjmp)
libc_hidden_proto (__sigsetjmp)
Samuel Thibault April 3, 2018, 9:55 p.m. | #10
H.J. Lu, on mar. 03 avril 2018 14:41:27 -0700, wrote:
> On Tue, Apr 3, 2018 at 2:24 PM, Samuel Thibault
> <samuel.thibault@ens-lyon.org> wrote:
> > H.J. Lu, on mar. 03 avril 2018 14:16:50 -0700, wrote:
> >> On Tue, Apr 3, 2018 at 2:07 PM, Samuel Thibault
> >> <samuel.thibault@ens-lyon.org> wrote:
> >> > Hello,
> >> >
> >> > H.J. Lu, on mar. 03 avril 2018 12:26:33 -0700, wrote:
> >> >> __libc_longjmp and __libc_siglongjmp are private external functions provided for
> >> >> libpthread.  They should never be called inside libc.
> >> >
> >> > I'm sorry for asking, but are these conventions documented somewhere?
> >> > These look like magic to me otherwise:
> >>
> >> I don't believe they are well documented.
> >
> > Ok, then I need an answer to my question:
> >
> >> > why shouldn't they ever be called from libc?
> >
> > The existing hurd code does use them for catching signals, so I need to
> > know how to fix it.
> 
> Use something similar to
> 
> libc_hidden_proto (_setjmp)
> libc_hidden_proto (__sigsetjmp)

So I'd just add hidden protos & defs to longjmp and siglongjmp?

Samuel
H.J. Lu April 3, 2018, 10:14 p.m. | #11
On Tue, Apr 3, 2018 at 2:55 PM, Samuel Thibault
<samuel.thibault@ens-lyon.org> wrote:
> H.J. Lu, on mar. 03 avril 2018 14:41:27 -0700, wrote:
>> On Tue, Apr 3, 2018 at 2:24 PM, Samuel Thibault
>> <samuel.thibault@ens-lyon.org> wrote:
>> > H.J. Lu, on mar. 03 avril 2018 14:16:50 -0700, wrote:
>> >> On Tue, Apr 3, 2018 at 2:07 PM, Samuel Thibault
>> >> <samuel.thibault@ens-lyon.org> wrote:
>> >> > Hello,
>> >> >
>> >> > H.J. Lu, on mar. 03 avril 2018 12:26:33 -0700, wrote:
>> >> >> __libc_longjmp and __libc_siglongjmp are private external functions provided for
>> >> >> libpthread.  They should never be called inside libc.
>> >> >
>> >> > I'm sorry for asking, but are these conventions documented somewhere?
>> >> > These look like magic to me otherwise:
>> >>
>> >> I don't believe they are well documented.
>> >
>> > Ok, then I need an answer to my question:
>> >
>> >> > why shouldn't they ever be called from libc?
>> >
>> > The existing hurd code does use them for catching signals, so I need to
>> > know how to fix it.
>>
>> Use something similar to
>>
>> libc_hidden_proto (_setjmp)
>> libc_hidden_proto (__sigsetjmp)
>
> So I'd just add hidden protos & defs to longjmp and siglongjmp?
>

setjmp/longjmp.c has

weak_alias (__libc_siglongjmp, _longjmp)
weak_alias (__libc_siglongjmp, longjmp)

Will

libc_hidden_proto (_longjmp)

work for you?
Samuel Thibault April 3, 2018, 10:18 p.m. | #12
H.J. Lu, on mar. 03 avril 2018 15:14:16 -0700, wrote:
> On Tue, Apr 3, 2018 at 2:55 PM, Samuel Thibault
> <samuel.thibault@ens-lyon.org> wrote:
> > H.J. Lu, on mar. 03 avril 2018 14:41:27 -0700, wrote:
> >> On Tue, Apr 3, 2018 at 2:24 PM, Samuel Thibault
> >> <samuel.thibault@ens-lyon.org> wrote:
> >> > H.J. Lu, on mar. 03 avril 2018 14:16:50 -0700, wrote:
> >> >> On Tue, Apr 3, 2018 at 2:07 PM, Samuel Thibault
> >> >> <samuel.thibault@ens-lyon.org> wrote:
> >> >> > Hello,
> >> >> >
> >> >> > H.J. Lu, on mar. 03 avril 2018 12:26:33 -0700, wrote:
> >> >> >> __libc_longjmp and __libc_siglongjmp are private external functions provided for
> >> >> >> libpthread.  They should never be called inside libc.
> >> >> >
> >> >> > I'm sorry for asking, but are these conventions documented somewhere?
> >> >> > These look like magic to me otherwise:
> >> >>
> >> >> I don't believe they are well documented.
> >> >
> >> > Ok, then I need an answer to my question:
> >> >
> >> >> > why shouldn't they ever be called from libc?
> >> >
> >> > The existing hurd code does use them for catching signals, so I need to
> >> > know how to fix it.
> >>
> >> Use something similar to
> >>
> >> libc_hidden_proto (_setjmp)
> >> libc_hidden_proto (__sigsetjmp)
> >
> > So I'd just add hidden protos & defs to longjmp and siglongjmp?
> >
> 
> setjmp/longjmp.c has
> 
> weak_alias (__libc_siglongjmp, _longjmp)
> weak_alias (__libc_siglongjmp, longjmp)
> 
> Will
> 
> libc_hidden_proto (_longjmp)
> 
> work for you?

Well, _longjmp is the BSD version of longjmp with the semantic of
siglongjmp (actually it's _setjmp which makes the semantic different,
recorded in the jmp_buf). Here we do use longjmp, not _longjmp. Of
course, the end pointer is the same since it's _setjmp which makes
the semantic different, but I'd really rather not make the code more
confusing by using _longjmp while it is actually a longjmp which is
meant.

Samuel
Zack Weinberg April 3, 2018, 10:21 p.m. | #13
On Tue, Apr 3, 2018 at 5:55 PM, Samuel Thibault
<samuel.thibault@ens-lyon.org> wrote:
> H.J. Lu, on mar. 03 avril 2018 14:41:27 -0700, wrote:
>> On Tue, Apr 3, 2018 at 2:24 PM, Samuel Thibault
>> <samuel.thibault@ens-lyon.org> wrote:
>> > H.J. Lu, on mar. 03 avril 2018 14:16:50 -0700, wrote:
>> >> On Tue, Apr 3, 2018 at 2:07 PM, Samuel Thibault
>> >> <samuel.thibault@ens-lyon.org> wrote:
>> >> > Hello,
>> >> >
>> >> > H.J. Lu, on mar. 03 avril 2018 12:26:33 -0700, wrote:
>> >> >> __libc_longjmp and __libc_siglongjmp are private external functions provided for
>> >> >> libpthread.  They should never be called inside libc.
>> >> >
>> >> > I'm sorry for asking, but are these conventions documented somewhere?
>> >> > These look like magic to me otherwise:
>> >>
>> >> I don't believe they are well documented.
>> >
>> > Ok, then I need an answer to my question:
>> >
>> >> > why shouldn't they ever be called from libc?
>> >
>> > The existing hurd code does use them for catching signals, so I need to
>> > know how to fix it.
>>
>> Use something similar to
>>
>> libc_hidden_proto (_setjmp)
>> libc_hidden_proto (__sigsetjmp)
>
> So I'd just add hidden protos & defs to longjmp and siglongjmp?

Right, except it has to be the __ variety for siglongjmp because that
function is not in C89.

These are the rules as I understand them:

First, any internal call to a function that is not in C89 probably has
to call a __-prefixed name, or you will fail the checknamespace tests.
The principle here is that a strictly-conforming C89 program _could
have_ defined the unprefixed version of that name and we don't want
that to interfere.  This is true even if the unprefixed name has a
hidden_proto annotation, because those have no effect on static
linkage.  There are exceptions to this rule but I do not understand
them well enough to explain them.

Second, if an internal function is defined in libc, and should only
ever be called from within libc, then it should be given a name that
starts with __ but not with __libc_, and should be declared with
attribute_hidden on its prototype, but does not need
hidden_def/hidden_proto annotations.  This is the simple case for
avoiding unnecessary calls through the PLT.

Third, if an internal function is defined in libc and called from both
inside and outside libc, but still not by applications, you declare it
*without* attribute_hidden on its prototype and use libc_hidden_def
and libc_hidden_proto, and you still use a name that starts with __
but not with __libc_.  That bypasses the PLT for internal calls but
leaves the __-name callable from outside libc.  (It may also be
necessary to add the function to a GLIBC_PRIVATE section of a Versions
file.)

The names that start with __libc_ are needed in even more unusual
cases, such as when functions need to be defined in both libc and
libpthread.  I am actually trying to clean this up right now and it is
an ungodly mess.

libhurd and libgnumach are lower-level than libc, IIUC, so the most
important thing for them is the first principle: make sure not to
stomp on the application namespace in static linkage.  You can decide
how important PLT bypassing is to you.

zw
H.J. Lu April 3, 2018, 10:21 p.m. | #14
On Tue, Apr 3, 2018 at 3:18 PM, Samuel Thibault
<samuel.thibault@ens-lyon.org> wrote:
> H.J. Lu, on mar. 03 avril 2018 15:14:16 -0700, wrote:
>> On Tue, Apr 3, 2018 at 2:55 PM, Samuel Thibault
>> <samuel.thibault@ens-lyon.org> wrote:
>> > H.J. Lu, on mar. 03 avril 2018 14:41:27 -0700, wrote:
>> >> On Tue, Apr 3, 2018 at 2:24 PM, Samuel Thibault
>> >> <samuel.thibault@ens-lyon.org> wrote:
>> >> > H.J. Lu, on mar. 03 avril 2018 14:16:50 -0700, wrote:
>> >> >> On Tue, Apr 3, 2018 at 2:07 PM, Samuel Thibault
>> >> >> <samuel.thibault@ens-lyon.org> wrote:
>> >> >> > Hello,
>> >> >> >
>> >> >> > H.J. Lu, on mar. 03 avril 2018 12:26:33 -0700, wrote:
>> >> >> >> __libc_longjmp and __libc_siglongjmp are private external functions provided for
>> >> >> >> libpthread.  They should never be called inside libc.
>> >> >> >
>> >> >> > I'm sorry for asking, but are these conventions documented somewhere?
>> >> >> > These look like magic to me otherwise:
>> >> >>
>> >> >> I don't believe they are well documented.
>> >> >
>> >> > Ok, then I need an answer to my question:
>> >> >
>> >> >> > why shouldn't they ever be called from libc?
>> >> >
>> >> > The existing hurd code does use them for catching signals, so I need to
>> >> > know how to fix it.
>> >>
>> >> Use something similar to
>> >>
>> >> libc_hidden_proto (_setjmp)
>> >> libc_hidden_proto (__sigsetjmp)
>> >
>> > So I'd just add hidden protos & defs to longjmp and siglongjmp?
>> >
>>
>> setjmp/longjmp.c has
>>
>> weak_alias (__libc_siglongjmp, _longjmp)
>> weak_alias (__libc_siglongjmp, longjmp)
>>
>> Will
>>
>> libc_hidden_proto (_longjmp)
>>
>> work for you?
>
> Well, _longjmp is the BSD version of longjmp with the semantic of
> siglongjmp (actually it's _setjmp which makes the semantic different,
> recorded in the jmp_buf). Here we do use longjmp, not _longjmp. Of
> course, the end pointer is the same since it's _setjmp which makes
> the semantic different, but I'd really rather not make the code more
> confusing by using _longjmp while it is actually a longjmp which is
> meant.

Aren't  the internal symbols of _longjmp, longjmp and siglongjmp
pointing to the same __libc_siglongjmp function?
Samuel Thibault April 3, 2018, 10:27 p.m. | #15
Zack Weinberg, on mar. 03 avril 2018 18:21:10 -0400, wrote:
> On Tue, Apr 3, 2018 at 5:55 PM, Samuel Thibault
> <samuel.thibault@ens-lyon.org> wrote:
> > H.J. Lu, on mar. 03 avril 2018 14:41:27 -0700, wrote:
> >> On Tue, Apr 3, 2018 at 2:24 PM, Samuel Thibault
> >> <samuel.thibault@ens-lyon.org> wrote:
> >> > H.J. Lu, on mar. 03 avril 2018 14:16:50 -0700, wrote:
> >> >> On Tue, Apr 3, 2018 at 2:07 PM, Samuel Thibault
> >> >> <samuel.thibault@ens-lyon.org> wrote:
> >> >> > Hello,
> >> >> >
> >> >> > H.J. Lu, on mar. 03 avril 2018 12:26:33 -0700, wrote:
> >> >> >> __libc_longjmp and __libc_siglongjmp are private external functions provided for
> >> >> >> libpthread.  They should never be called inside libc.
> >> >> >
> >> >> > I'm sorry for asking, but are these conventions documented somewhere?
> >> >> > These look like magic to me otherwise:
> >> >>
> >> >> I don't believe they are well documented.
> >> >
> >> > Ok, then I need an answer to my question:
> >> >
> >> >> > why shouldn't they ever be called from libc?
> >> >
> >> > The existing hurd code does use them for catching signals, so I need to
> >> > know how to fix it.
> >>
> >> Use something similar to
> >>
> >> libc_hidden_proto (_setjmp)
> >> libc_hidden_proto (__sigsetjmp)
> >
> > So I'd just add hidden protos & defs to longjmp and siglongjmp?
> 
> Right, except it has to be the __ variety for siglongjmp because that
> function is not in C89.

Yes, but longjmp and siglong are only used in functions which are part
of _GNU_SOURCE, and longjmp only for fork(), so that implies their
presence, right?

(I would have already gotten the link namespace warning otherwise).

Samuel
Samuel Thibault April 3, 2018, 10:29 p.m. | #16
H.J. Lu, on mar. 03 avril 2018 15:21:33 -0700, wrote:
> On Tue, Apr 3, 2018 at 3:18 PM, Samuel Thibault
> <samuel.thibault@ens-lyon.org> wrote:
> > H.J. Lu, on mar. 03 avril 2018 15:14:16 -0700, wrote:
> >> On Tue, Apr 3, 2018 at 2:55 PM, Samuel Thibault
> >> <samuel.thibault@ens-lyon.org> wrote:
> >> > H.J. Lu, on mar. 03 avril 2018 14:41:27 -0700, wrote:
> >> >> On Tue, Apr 3, 2018 at 2:24 PM, Samuel Thibault
> >> >> <samuel.thibault@ens-lyon.org> wrote:
> >> >> > H.J. Lu, on mar. 03 avril 2018 14:16:50 -0700, wrote:
> >> >> >> On Tue, Apr 3, 2018 at 2:07 PM, Samuel Thibault
> >> >> >> <samuel.thibault@ens-lyon.org> wrote:
> >> >> >> > Hello,
> >> >> >> >
> >> >> >> > H.J. Lu, on mar. 03 avril 2018 12:26:33 -0700, wrote:
> >> >> >> >> __libc_longjmp and __libc_siglongjmp are private external functions provided for
> >> >> >> >> libpthread.  They should never be called inside libc.
> >> >> >> >
> >> >> >> > I'm sorry for asking, but are these conventions documented somewhere?
> >> >> >> > These look like magic to me otherwise:
> >> >> >>
> >> >> >> I don't believe they are well documented.
> >> >> >
> >> >> > Ok, then I need an answer to my question:
> >> >> >
> >> >> >> > why shouldn't they ever be called from libc?
> >> >> >
> >> >> > The existing hurd code does use them for catching signals, so I need to
> >> >> > know how to fix it.
> >> >>
> >> >> Use something similar to
> >> >>
> >> >> libc_hidden_proto (_setjmp)
> >> >> libc_hidden_proto (__sigsetjmp)
> >> >
> >> > So I'd just add hidden protos & defs to longjmp and siglongjmp?
> >> >
> >>
> >> setjmp/longjmp.c has
> >>
> >> weak_alias (__libc_siglongjmp, _longjmp)
> >> weak_alias (__libc_siglongjmp, longjmp)
> >>
> >> Will
> >>
> >> libc_hidden_proto (_longjmp)
> >>
> >> work for you?
> >
> > Well, _longjmp is the BSD version of longjmp with the semantic of
> > siglongjmp (actually it's _setjmp which makes the semantic different,
> > recorded in the jmp_buf). Here we do use longjmp, not _longjmp. Of
> > course, the end pointer is the same since it's _setjmp which makes
> > the semantic different, but I'd really rather not make the code more
> > confusing by using _longjmp while it is actually a longjmp which is
> > meant.
> 
> Aren't  the internal symbols of _longjmp, longjmp and siglongjmp
> pointing to the same __libc_siglongjmp function?

As I wrote above, yes.  But as I wrote above, writing _longjmp in some
source code which actually means longjmp would be very confusing (as
well as exposing a BSD symbol)

Samuel
Zack Weinberg April 3, 2018, 10:33 p.m. | #17
On Tue, Apr 3, 2018 at 6:27 PM, Samuel Thibault
<samuel.thibault@ens-lyon.org> wrote:
> Zack Weinberg, on mar. 03 avril 2018 18:21:10 -0400, wrote:
>> On Tue, Apr 3, 2018 at 5:55 PM, Samuel Thibault
>> <samuel.thibault@ens-lyon.org> wrote:
>> > H.J. Lu, on mar. 03 avril 2018 14:41:27 -0700, wrote:
>> >> On Tue, Apr 3, 2018 at 2:24 PM, Samuel Thibault
>> >> <samuel.thibault@ens-lyon.org> wrote:
>> >> > H.J. Lu, on mar. 03 avril 2018 14:16:50 -0700, wrote:
>> >> >> On Tue, Apr 3, 2018 at 2:07 PM, Samuel Thibault
>> >> >> <samuel.thibault@ens-lyon.org> wrote:
>> >> >> > Hello,
>> >> >> >
>> >> >> > H.J. Lu, on mar. 03 avril 2018 12:26:33 -0700, wrote:
>> >> >> >> __libc_longjmp and __libc_siglongjmp are private external functions provided for
>> >> >> >> libpthread.  They should never be called inside libc.
>> >> >> >
>> >> >> > I'm sorry for asking, but are these conventions documented somewhere?
>> >> >> > These look like magic to me otherwise:
>> >> >>
>> >> >> I don't believe they are well documented.
>> >> >
>> >> > Ok, then I need an answer to my question:
>> >> >
>> >> >> > why shouldn't they ever be called from libc?
>> >> >
>> >> > The existing hurd code does use them for catching signals, so I need to
>> >> > know how to fix it.
>> >>
>> >> Use something similar to
>> >>
>> >> libc_hidden_proto (_setjmp)
>> >> libc_hidden_proto (__sigsetjmp)
>> >
>> > So I'd just add hidden protos & defs to longjmp and siglongjmp?
>>
>> Right, except it has to be the __ variety for siglongjmp because that
>> function is not in C89.
>
> Yes, but longjmp and siglong are only used in functions which are part
> of _GNU_SOURCE, and longjmp only for fork(), so that implies their
> presence, right?
>
> (I would have already gotten the link namespace warning otherwise).

Joseph would know better than me, but I _think_ it's still necessary
to avoid using the application-namespace names.  For instance, a
program that uses fork, but not siglongjmp, might have defined its own
siglongjmp -- this actually isn't that farfetched if you consider
things like gnulib (and I do know of a few cases where gnulib will
override a glibc function with its own implementation).

zw
Samuel Thibault April 3, 2018, 10:38 p.m. | #18
Zack Weinberg, on mar. 03 avril 2018 18:21:10 -0400, wrote:
> These are the rules as I understand them:

Is there some place where we could put this precious knowledge? :)

Otherwise I fear that...

> The names that start with __libc_ are needed in even more unusual
> cases, such as when functions need to be defined in both libc and
> libpthread.  I am actually trying to clean this up right now and it is
> an ungodly mess.

people would continue introducing mess :)

Samuel
Andreas Schwab April 4, 2018, 7:20 a.m. | #19
On Apr 03 2018, Zack Weinberg <zackw@panix.com> wrote:

> Joseph would know better than me, but I _think_ it's still necessary
> to avoid using the application-namespace names.  For instance, a
> program that uses fork, but not siglongjmp, might have defined its own
> siglongjmp

I don't think so, since both fork and siglongjmp are part of POSIX (any
version), but neither is part of any narrower standard.

Andreas.

Patch

diff --git a/ChangeLog b/ChangeLog
index 9e2dfa934d..0b54ed73b5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -396,6 +396,18 @@ 
 	_hurd_fd_error_signal): Add hidden prototype.
 	[_HURD_FD_H_HIDDEN_DEF] (_hurd_fd_error, _hurd_fd_error_signal): Add
 	hidden def.
+	* hurd/catch-signal.c (__hurd_catch_signal): Call __libc_siglongjmp
+	instead if siglongjmp.
+	(hurd_safe_memmove): Call __libc_longjmp instead of longjmp.
+	* hurd/hurdfault.c (faulted): Call __libc_longjmp instead of longjmp.
+	* include/setjmp.h (__libc_siglongjmp, __libc_longjmp): New hidden
+	prototypes.
+	* libio/iolibio.h (_IO_puts): New hidden prototype.
+	* libio/ioputs.c (_IO_puts): New hidden def.
+	* setjmp/longjmp.c (__libc_longjmp, __libc_siglongjmp): New hidden
+	defs.
+	* sysdeps/mach/hurd/sigwait.c (__sigwait): Call __libc_longjmp instead
+	of longjmp.
 
 	* sysdeps/mach/hurd/localplt.data: New file.
 
diff --git a/hurd/catch-signal.c b/hurd/catch-signal.c
index 56ce86532d..a00ccef4fb 100644
--- a/hurd/catch-signal.c
+++ b/hurd/catch-signal.c
@@ -32,7 +32,7 @@  __hurd_catch_signal (sigset_t sigset,
      instance calling hurd_catch_signal again would then dump core.  */
   sigjmp_buf buf;
   void throw (int signo, long int sigcode, struct sigcontext *scp)
-    { siglongjmp (buf, scp->sc_error ?: EGRATUITOUS); }
+    { __libc_siglongjmp (buf, scp->sc_error ?: EGRATUITOUS); }
 
   struct hurd_signal_preemptor preemptor =
     {
@@ -121,7 +121,7 @@  hurd_safe_memmove (void *dest, const void *src, size_t nbytes)
 {
   jmp_buf buf;
   void throw (int signo, long int sigcode, struct sigcontext *scp)
-    { longjmp (buf, scp->sc_error ?: EGRATUITOUS); }
+    { __libc_longjmp (buf, scp->sc_error ?: EGRATUITOUS); }
 
   struct hurd_signal_preemptor src_preemptor =
     {
diff --git a/hurd/hurdfault.c b/hurd/hurdfault.c
index 39a4522811..c42d5e739a 100644
--- a/hurd/hurdfault.c
+++ b/hurd/hurdfault.c
@@ -152,7 +152,7 @@  faulted (void)
     __libc_fatal ("BUG: unexpected fault in signal thread\n");
 
   _hurdsig_fault_preemptor.signals = 0;
-  longjmp (_hurdsig_fault_env, 1);
+  __libc_longjmp (_hurdsig_fault_env, 1);
 }
 
 static char faultstack[1024];
diff --git a/include/setjmp.h b/include/setjmp.h
index 263bc64b3d..682ff4b5a5 100644
--- a/include/setjmp.h
+++ b/include/setjmp.h
@@ -24,6 +24,9 @@  extern void __libc_siglongjmp (sigjmp_buf env, int val)
 extern void __libc_longjmp (sigjmp_buf env, int val)
      __attribute__ ((noreturn));
 
+libc_hidden_proto (__libc_siglongjmp)
+libc_hidden_proto (__libc_longjmp)
+
 libc_hidden_proto (_setjmp)
 libc_hidden_proto (__sigsetjmp)
 
diff --git a/libio/iolibio.h b/libio/iolibio.h
index 69e1c0e699..6c94fe6d62 100644
--- a/libio/iolibio.h
+++ b/libio/iolibio.h
@@ -41,6 +41,7 @@  extern char* _IO_gets (char*);
 extern void _IO_perror (const char*) __THROW;
 extern int _IO_printf (const char*, ...);
 extern int _IO_puts (const char*);
+libc_hidden_proto (_IO_puts)
 extern int _IO_scanf (const char*, ...);
 extern void _IO_setbuffer (FILE *, char*, size_t) __THROW;
 libc_hidden_proto (_IO_setbuffer)
diff --git a/libio/ioputs.c b/libio/ioputs.c
index 0a80fb7148..c9967c3883 100644
--- a/libio/ioputs.c
+++ b/libio/ioputs.c
@@ -46,3 +46,4 @@  _IO_puts (const char *str)
 }
 
 weak_alias (_IO_puts, puts)
+libc_hidden_def (_IO_puts)
diff --git a/setjmp/longjmp.c b/setjmp/longjmp.c
index a2a7065a85..0555d6d6b7 100644
--- a/setjmp/longjmp.c
+++ b/setjmp/longjmp.c
@@ -46,4 +46,6 @@  strong_alias (__libc_siglongjmp, __libc_longjmp)
 weak_alias (__libc_siglongjmp, _longjmp)
 weak_alias (__libc_siglongjmp, longjmp)
 weak_alias (__libc_siglongjmp, siglongjmp)
+libc_hidden_def (__libc_longjmp)
+libc_hidden_def (__libc_siglongjmp)
 #endif
diff --git a/sysdeps/mach/hurd/sigwait.c b/sysdeps/mach/hurd/sigwait.c
index ce17cce895..321ab46d14 100644
--- a/sysdeps/mach/hurd/sigwait.c
+++ b/sysdeps/mach/hurd/sigwait.c
@@ -59,7 +59,7 @@  __sigwait (const sigset_t *set, int *sig)
     handler (int sig)
     {
       assert (sig == signo);
-      longjmp (buf, 1);
+      __libc_longjmp (buf, 1);
     }
 
   wait = __mach_reply_port ();