Add private_function for private functions within glibc [BZ #21598]

Message ID 20170808182536.GA24765@gmail.com
State New
Headers show

Commit Message

H.J. Lu Aug. 8, 2017, 6:25 p.m.
USE_REGPARMS in config.h.in is only used to control how parameters are
passed for internal functions on i386.  On i386, we fine

 # define internal_function __attribute__ ((regparm (3), stdcall))

so that we pass up to 3 integer parameters in registers for internal
functuons on i386.  i386 has

_dl_runtime_resolve:

        movl (%esp), %ecx
        movl %eax, (%esp)       # Store the function address.
        movl 4(%esp), %eax
        ret $12                 # Jump to function address.

which is incompatible with Shadow Stack in Intel Control-flow Enforcement
Technology (CET) instructions:

https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf

since shadow stack doesn't match return stack.  We need to use register
indirect branch via %ecx.  That means only 2 parameters can be passed
in registers for external function calls with lazy binding when shadow
stack is enabled.  However, internal_function, which should be used only
with hidden function within libc.so, are also used with private function
calls between different shared objects of glibc.

This patch removes USE_REGPARMS from config.h.in.  Instead, it defines
internal_function and private_function, which is for private function
calss between different shared objects, in config.h.in.  Currently,
sysdeps/i386/configure.ac defines private_function as

 # define private_function __attribute__ ((regparm (3), stdcall))

There is no change in shared objects on Linux/i686 nor Linux/x86_64.

When shadow stack is enabled, private_function will be defined as

 # define private_function __attribute__ ((regparm (2), stdcall))

so that %ecx can be used as scratch register by _dl_runtime_resolve.

OK for master?

H.J.
---
	[BZ #21598]
	* config.h.in (USE_REGPARMS): Removed.
	(internal_function): Undef.
	(private_function): New.  Undef.
	* debug/fortify_fail.c (__fortify_fail): Replace internal_function
	with private_function.
	* elf/dl-addr.c (_dl_addr): Likewise.
	* elf/dl-error-skeleton.c (_dl_signal_error): Likewise.
	(_dl_catch_error): Likewise.
	* elf/dl-execstack.c (_dl_make_stack_executable): Likewise.
	* elf/dl-load.c (_dl_rtld_di_serinfo): Likewise.
	* elf/dl-open.c (_dl_find_dso_for_object): Likewise.
	* elf/dl-support.c (_dl_make_stack_executable_hook): Likewise.
	* elf/dl-sym.c (_dl_vsym): Likewise.
	(_dl_sym): Likewise.
	* elf/dl-tls.c (_dl_get_tls_static_info): Likewise.
	(_dl_allocate_tls_init): Likewise.
	(_dl_allocate_tls): Likewise.
	(_dl_deallocate_tls): Likewise.
	* grp/grp-merge.c (__copy_grp): Likewise.
	(__merge_grp): Likewise.
	* grp/grp-merge.h (__copy_grp): Likewise.
	(__merge_grp): Likewise.
	* include/dlfcn.h (_dl_addr): Likewise.
	(_dl_sym): Likewise.
	(_dl_vsym): Likewise.
	* include/rpc/pmap_clnt.h (__libc_rpc_getport): Likewise.
	* include/stdio.h (__fortify_fail): Likewise.
	* include/stdlib.h (__strtof_nan): Likewise.
	(__strtod_nan): Likewise.
	(__strtold_nan): Likewise.
	(__wcstof_nan): Likewise.
	(__wcstod_nan): Likewise.
	(__wcstold_nan): Likewise.
	(__strtof128_nan): Likewise.
	(__wcstof128_nan): Likewise.
	* inet/inet6_scopeid_pton.c (__inet6_scopeid_pton): Likewise.
	* inet/net-internal.h (__inet6_scopeid_pton): Likewise.
	* nptl/allocatestack.c (__make_stacks_executable): Likewise.
	* nptl/libc_pthread_init.c (__libc_pthread_init): Likewise.
	* nptl/pthreadP.h (__make_stacks_executable): Likewise.
	(__libc_pthread_init): Likewise.
	* nss/XXX-lookup.c (DB_LOOKUP_FCT): Likewise.
	(DB_COMPAT_FCT): Likewise.
	* nss/getXXbyYY_r.c (DB_LOOKUP_FCT): Likewise.
	* nss/getXXent_r.c (DB_LOOKUP_FCT): Likewise.
	* nss/nsswitch.h (db_lookup_function): Likewise.
	* resolv/gai_misc.h (__gai_sigqueue): Likewise.
	* resolv/gai_sigqueue.c (__gai_sigqueue): Likewise.
	* stdlib/strtod_nan_main.c (STRTOD_NAN): Likewise.
	* sunrpc/pm_getport.c (__libc_rpc_getport): Likewise.
	* sysdeps/generic/ldsodefs.h (_dl_make_stack_executable_hook):
	Likewise.
	(_dl_make_stack_executable): Likewise.
	(_dl_signal_error): Likewise.
	(_dl_catch_error): Likewise.
	(_dl_rtld_di_serinfo): Likewise.
	(_dl_allocate_tls): Likewise.
	(_dl_get_tls_static_info): Likewise.
	(_dl_allocate_tls_init): Likewise.
	(_dl_deallocate_tls): Likewise.
	(_dl_find_dso_for_object): Likewise.
	* sysdeps/unix/sysv/linux/dl-execstack.c
	(_dl_make_stack_executable): Likewise.
	* sysdeps/unix/sysv/linux/gai_sigqueue.c (__gai_sigqueue):
	Likewise.
	* sysdeps/unix/sysv/linux/netlink_assert_response.c
	(__netlink_assert_response): Likewise.
	* sysdeps/unix/sysv/linux/netlinkaccess.h
	(__netlink_assert_response): Likewise.
	* include/libc-symbols.h (private_function): New.
	* sysdeps/i386/configure.ac (USE_REGPARMS): Removed.
	(internal_function): New AC_DEFINE.
	(private_function): Likewise.
	* sysdeps/i386/configure: Regenerated.
---
 config.h.in                                       | 11 ++++-------
 debug/fortify_fail.c                              |  2 +-
 elf/dl-addr.c                                     |  2 +-
 elf/dl-error-skeleton.c                           |  4 ++--
 elf/dl-execstack.c                                |  2 +-
 elf/dl-load.c                                     |  2 +-
 elf/dl-open.c                                     |  2 +-
 elf/dl-support.c                                  |  2 +-
 elf/dl-sym.c                                      |  4 ++--
 elf/dl-tls.c                                      |  8 ++++----
 grp/grp-merge.c                                   |  4 ++--
 grp/grp-merge.h                                   |  4 ++--
 include/dlfcn.h                                   |  6 +++---
 include/libc-symbols.h                            |  9 +++++++--
 include/rpc/pmap_clnt.h                           |  2 +-
 include/stdio.h                                   |  2 +-
 include/stdlib.h                                  | 18 ++++++++++--------
 inet/inet6_scopeid_pton.c                         |  2 +-
 inet/net-internal.h                               |  2 +-
 nptl/allocatestack.c                              |  2 +-
 nptl/libc_pthread_init.c                          |  2 +-
 nptl/pthreadP.h                                   |  6 +++---
 nss/XXX-lookup.c                                  |  6 +++---
 nss/getXXbyYY_r.c                                 |  2 +-
 nss/getXXent_r.c                                  |  2 +-
 nss/nsswitch.h                                    |  2 +-
 resolv/gai_misc.h                                 |  2 +-
 resolv/gai_sigqueue.c                             |  2 +-
 stdlib/strtod_nan_main.c                          |  2 +-
 sunrpc/pm_getport.c                               |  2 +-
 sysdeps/generic/ldsodefs.h                        | 20 ++++++++++----------
 sysdeps/i386/configure                            | 10 ++++++++--
 sysdeps/i386/configure.ac                         |  7 ++++++-
 sysdeps/unix/sysv/linux/dl-execstack.c            |  2 +-
 sysdeps/unix/sysv/linux/gai_sigqueue.c            |  2 +-
 sysdeps/unix/sysv/linux/netlink_assert_response.c |  2 +-
 sysdeps/unix/sysv/linux/netlinkaccess.h           |  2 +-
 37 files changed, 89 insertions(+), 74 deletions(-)

Comments

Joseph Myers Aug. 8, 2017, 9:12 p.m. | #1
On Tue, 8 Aug 2017, H.J. Lu wrote:

> since shadow stack doesn't match return stack.  We need to use register
> indirect branch via %ecx.  That means only 2 parameters can be passed
> in registers for external function calls with lazy binding when shadow
> stack is enabled.  However, internal_function, which should be used only
> with hidden function within libc.so, are also used with private function
> calls between different shared objects of glibc.

Should we consider it part of the ABI that users' shared objects, not just 
glibc ones, may export functions with regparm calling convention?  It's 
certainly possible at present, but I don't know how widely used it is.

> This patch removes USE_REGPARMS from config.h.in.  Instead, it defines
> internal_function and private_function, which is for private function
> calss between different shared objects, in config.h.in.  Currently,
> sysdeps/i386/configure.ac defines private_function as

I'd expect these definitions to go in a sysdeps header (for which i386 has 
a version overriding the default version), as suggested in 
<https://sourceware.org/ml/libc-alpha/2014-06/msg00784.html>, rather than 
being defined directly from a configure.ac file.
H.J. Lu Aug. 8, 2017, 9:27 p.m. | #2
On Tue, Aug 8, 2017 at 2:12 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> On Tue, 8 Aug 2017, H.J. Lu wrote:
>
>> since shadow stack doesn't match return stack.  We need to use register
>> indirect branch via %ecx.  That means only 2 parameters can be passed
>> in registers for external function calls with lazy binding when shadow
>> stack is enabled.  However, internal_function, which should be used only
>> with hidden function within libc.so, are also used with private function
>> calls between different shared objects of glibc.
>
> Should we consider it part of the ABI that users' shared objects, not just
> glibc ones, may export functions with regparm calling convention?  It's
> certainly possible at present, but I don't know how widely used it is.

Some libraries do that:

https://sourceware.org/ml/libc-alpha/2017-06/msg01091.html

We have a similar issue on x86-64:

https://sourceware.org/bugzilla/show_bug.cgi?id=21265

CET enabled compiler should disallow  __attribute__((regparm(3))) on
i386.  When CET is disabled, __attribute__((regparm(3))) is OK.

>> This patch removes USE_REGPARMS from config.h.in.  Instead, it defines
>> internal_function and private_function, which is for private function
>> calss between different shared objects, in config.h.in.  Currently,
>> sysdeps/i386/configure.ac defines private_function as
>
> I'd expect these definitions to go in a sysdeps header (for which i386 has
> a version overriding the default version), as suggested in
> <https://sourceware.org/ml/libc-alpha/2014-06/msg00784.html>, rather than
> being defined directly from a configure.ac file.

I will do that.

Thanks.
Florian Weimer Aug. 9, 2017, 10:33 a.m. | #3
On 08/08/2017 08:25 PM, H.J. Lu wrote:
> which is incompatible with Shadow Stack in Intel Control-flow Enforcement
> Technology (CET) instructions:
> 
> https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf
> 
> since shadow stack doesn't match return stack.  We need to use register
> indirect branch via %ecx.  That means only 2 parameters can be passed
> in registers for external function calls with lazy binding when shadow
> stack is enabled.  However, internal_function, which should be used only
> with hidden function within libc.so, are also used with private function
> calls between different shared objects of glibc.

I think we should work towards removing internal_function instead.  It's
an unnecessary maintenance overhead for those working on other
architectures besides i386.

In addition, the GCC manual currently says this about %ecx:

“
Systems with the GNU C Library version 2.1 or higher and FreeBSD are
believed to be safe since the loaders there save EAX, EDX and ECX.
”
<https://gcc.gnu.org/onlinedocs/gcc/x86-Function-Attributes.html>

This means that you can recover %ecx for internal ld.so with some form
of ABI compatibility mark-up only because we pretty much guarantee that
regparm (3) is compatible with the GNU ABI.

Thanks,
Florian
H.J. Lu Aug. 9, 2017, 10:58 a.m. | #4
On Wed, Aug 9, 2017 at 3:33 AM, Florian Weimer <fweimer@redhat.com> wrote:
> On 08/08/2017 08:25 PM, H.J. Lu wrote:
>> which is incompatible with Shadow Stack in Intel Control-flow Enforcement
>> Technology (CET) instructions:
>>
>> https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf
>>
>> since shadow stack doesn't match return stack.  We need to use register
>> indirect branch via %ecx.  That means only 2 parameters can be passed
>> in registers for external function calls with lazy binding when shadow
>> stack is enabled.  However, internal_function, which should be used only
>> with hidden function within libc.so, are also used with private function
>> calls between different shared objects of glibc.
>
> I think we should work towards removing internal_function instead.  It's
> an unnecessary maintenance overhead for those working on other
> architectures besides i386.

Some i386 assembly codes call internal functions directly:

https://sourceware.org/ml/libc-alpha/2017-06/msg00764.html

Removing internal_function is too risky for i386.

> In addition, the GCC manual currently says this about %ecx:
>
> “
> Systems with the GNU C Library version 2.1 or higher and FreeBSD are
> believed to be safe since the loaders there save EAX, EDX and ECX.
> ”
> <https://gcc.gnu.org/onlinedocs/gcc/x86-Function-Attributes.html>
>
> This means that you can recover %ecx for internal ld.so with some form
> of ABI compatibility mark-up only because we pretty much guarantee that
> regparm (3) is compatible with the GNU ABI.
>

I opened:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81780
Florian Weimer Aug. 10, 2017, 12:33 p.m. | #5
On 08/09/2017 12:58 PM, H.J. Lu wrote:
> On Wed, Aug 9, 2017 at 3:33 AM, Florian Weimer <fweimer@redhat.com> wrote:
>> On 08/08/2017 08:25 PM, H.J. Lu wrote:
>>> which is incompatible with Shadow Stack in Intel Control-flow Enforcement
>>> Technology (CET) instructions:
>>>
>>> https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf
>>>
>>> since shadow stack doesn't match return stack.  We need to use register
>>> indirect branch via %ecx.  That means only 2 parameters can be passed
>>> in registers for external function calls with lazy binding when shadow
>>> stack is enabled.  However, internal_function, which should be used only
>>> with hidden function within libc.so, are also used with private function
>>> calls between different shared objects of glibc.
>>
>> I think we should work towards removing internal_function instead.  It's
>> an unnecessary maintenance overhead for those working on other
>> architectures besides i386.
> 
> Some i386 assembly codes call internal functions directly:
> 
> https://sourceware.org/ml/libc-alpha/2017-06/msg00764.html
> 
> Removing internal_function is too risky for i386.

I can use a hacked GCC which adds name mangling for regparm functions,
so that we get link errors if there are references from assembler code,
and rewrite that assembler code.

Would that work for you?

Thanks,
Florian
H.J. Lu Aug. 10, 2017, 12:44 p.m. | #6
On Thu, Aug 10, 2017 at 5:33 AM, Florian Weimer <fweimer@redhat.com> wrote:
> On 08/09/2017 12:58 PM, H.J. Lu wrote:
>> On Wed, Aug 9, 2017 at 3:33 AM, Florian Weimer <fweimer@redhat.com> wrote:
>>> On 08/08/2017 08:25 PM, H.J. Lu wrote:
>>>> which is incompatible with Shadow Stack in Intel Control-flow Enforcement
>>>> Technology (CET) instructions:
>>>>
>>>> https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf
>>>>
>>>> since shadow stack doesn't match return stack.  We need to use register
>>>> indirect branch via %ecx.  That means only 2 parameters can be passed
>>>> in registers for external function calls with lazy binding when shadow
>>>> stack is enabled.  However, internal_function, which should be used only
>>>> with hidden function within libc.so, are also used with private function
>>>> calls between different shared objects of glibc.
>>>
>>> I think we should work towards removing internal_function instead.  It's
>>> an unnecessary maintenance overhead for those working on other
>>> architectures besides i386.
>>
>> Some i386 assembly codes call internal functions directly:
>>
>> https://sourceware.org/ml/libc-alpha/2017-06/msg00764.html
>>
>> Removing internal_function is too risky for i386.
>
> I can use a hacked GCC which adds name mangling for regparm functions,
> so that we get link errors if there are references from assembler code,
> and rewrite that assembler code.
>
> Would that work for you?
>

It is OK to use __attribute__ ((regparm (3))) with CET as long as the
function is hidden.  We need to at least keep __attribute__ ((regparm (1)))
on ___tls_get_addr since it is the part of TLS ABI and we may have to
support  __attribute__ ((regparm (3))) for lazy binding when CET is disabled
forever.  Remove it from glibc doesn't buy us much.
Florian Weimer Aug. 10, 2017, 12:49 p.m. | #7
On 08/10/2017 02:44 PM, H.J. Lu wrote:

> It is OK to use __attribute__ ((regparm (3))) with CET as long as the
> function is hidden.  We need to at least keep __attribute__ ((regparm (1)))
> on ___tls_get_addr since it is the part of TLS ABI and we may have to
> support  __attribute__ ((regparm (3))) for lazy binding when CET is disabled
> forever.  Remove it from glibc doesn't buy us much.

It buys us peace of mind for those of us who do not work on i386 because
internal_function mismatches are a constant source of i386 build
failures.  I want to get rid of it because I think its presence is a
poor trade-off for the project as a whole.

We have to keep it for interfaces which are part of the ABI, of course,
but that is extremely special and confined to i386 code anyway.

Thanks,
Florian
H.J. Lu Aug. 10, 2017, 1:01 p.m. | #8
On Thu, Aug 10, 2017 at 5:49 AM, Florian Weimer <fweimer@redhat.com> wrote:
> On 08/10/2017 02:44 PM, H.J. Lu wrote:
>
>> It is OK to use __attribute__ ((regparm (3))) with CET as long as the
>> function is hidden.  We need to at least keep __attribute__ ((regparm (1)))
>> on ___tls_get_addr since it is the part of TLS ABI and we may have to
>> support  __attribute__ ((regparm (3))) for lazy binding when CET is disabled
>> forever.  Remove it from glibc doesn't buy us much.
>
> It buys us peace of mind for those of us who do not work on i386 because
> internal_function mismatches are a constant source of i386 build
> failures.  I want to get rid of it because I think its presence is a
> poor trade-off for the project as a whole.
>

That is fine with me then.

FWIW, last time when I tried it, I gave up after many segfaults :-(.
The list of places I remembered:

1. _dl_init.
2. _dl_fixup
3. TLS lookup functions.

There may be more.
Florian Weimer Aug. 12, 2017, 12:09 p.m. | #9
On 08/10/2017 03:01 PM, H.J. Lu wrote:
> On Thu, Aug 10, 2017 at 5:49 AM, Florian Weimer <fweimer@redhat.com> wrote:
>> On 08/10/2017 02:44 PM, H.J. Lu wrote:
>>
>>> It is OK to use __attribute__ ((regparm (3))) with CET as long as the
>>> function is hidden.  We need to at least keep __attribute__ ((regparm (1)))
>>> on ___tls_get_addr since it is the part of TLS ABI and we may have to
>>> support  __attribute__ ((regparm (3))) for lazy binding when CET is disabled
>>> forever.  Remove it from glibc doesn't buy us much.
>>
>> It buys us peace of mind for those of us who do not work on i386 because
>> internal_function mismatches are a constant source of i386 build
>> failures.  I want to get rid of it because I think its presence is a
>> poor trade-off for the project as a whole.
>>
> 
> That is fine with me then.
> 
> FWIW, last time when I tried it, I gave up after many segfaults :-(.
> The list of places I remembered:
> 
> 1. _dl_init.
> 2. _dl_fixup
> 3. TLS lookup functions.

I posted my first set of cleanup patches.  The first round targets
functions which have a hidden alias because my GCC hack to detect ABI
mismatches is not compatible with them at the source level.  These
functions also fail to match the guidelines for internal_function
because they are definitely called across DSO boundaries, so they are a
good candidate for removal of the attribute.

For __fortify_fail, I had to adjust the call from the assembly
implementation in __longjmp_chk.

Thanks,
Florian

Patch

diff --git a/config.h.in b/config.h.in
index 22418576a0..989554a078 100644
--- a/config.h.in
+++ b/config.h.in
@@ -47,10 +47,6 @@ 
 #undef	STACK_PROTECTOR_LEVEL
 #endif
 
-/* Define if the regparm attribute shall be used for local functions
-   (gcc on ix86 only).  */
-#undef	USE_REGPARMS
-
 /* Defined on SPARC if GCC emits GOTDATA relocations.  */
 #undef  HAVE_GCC_GOTDATA
 
@@ -101,9 +97,10 @@ 
 
 
 /* Defined to some form of __attribute__ ((...)) if the compiler supports
-   a different, more efficient calling convention.  */
-#if defined USE_REGPARMS && !defined PROF
-# define internal_function __attribute__ ((regparm (3), stdcall))
+   a different, more efficient calling convention (gcc on ix86 only).  */
+#ifndef PROF
+# undef internal_function
+# undef private_function
 #endif
 
 /* Linux specific: minimum supported kernel version.  */
diff --git a/debug/fortify_fail.c b/debug/fortify_fail.c
index a0777ae570..0987269bf8 100644
--- a/debug/fortify_fail.c
+++ b/debug/fortify_fail.c
@@ -38,7 +38,7 @@  __fortify_fail_abort (_Bool need_backtrace, const char *msg)
 }
 
 void
-__attribute__ ((noreturn)) internal_function
+__attribute__ ((noreturn)) private_function
 __fortify_fail (const char *msg)
 {
   __fortify_fail_abort (true, msg);
diff --git a/elf/dl-addr.c b/elf/dl-addr.c
index 1fac63d1a9..edd42be629 100644
--- a/elf/dl-addr.c
+++ b/elf/dl-addr.c
@@ -121,7 +121,7 @@  determine_info (const ElfW(Addr) addr, struct link_map *match, Dl_info *info,
 
 
 int
-internal_function
+private_function
 _dl_addr (const void *address, Dl_info *info,
 	  struct link_map **mapp, const ElfW(Sym) **symbolp)
 {
diff --git a/elf/dl-error-skeleton.c b/elf/dl-error-skeleton.c
index 8e5888d4bd..7d4ad30d1c 100644
--- a/elf/dl-error-skeleton.c
+++ b/elf/dl-error-skeleton.c
@@ -77,7 +77,7 @@  static receiver_fct receiver;
 #endif /* DL_ERROR_BOOTSTRAP */
 
 void
-internal_function
+private_function
 _dl_signal_error (int errcode, const char *objname, const char *occation,
 		  const char *errstring)
 {
@@ -169,7 +169,7 @@  _dl_signal_cerror (int errcode, const char *objname, const char *occation,
 
 
 int
-internal_function
+private_function
 _dl_catch_error (const char **objname, const char **errstring,
 		 bool *mallocedp, void (*operate) (void *), void *args)
 {
diff --git a/elf/dl-execstack.c b/elf/dl-execstack.c
index 875338bea5..c83de345a1 100644
--- a/elf/dl-execstack.c
+++ b/elf/dl-execstack.c
@@ -23,7 +23,7 @@ 
    so as to mprotect it.  */
 
 int
-internal_function
+private_function
 _dl_make_stack_executable (void **stack_endp)
 {
   return ENOSYS;
diff --git a/elf/dl-load.c b/elf/dl-load.c
index c1b6d4ba0f..14cf164bd2 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -2241,7 +2241,7 @@  add_path (struct add_path_state *p, const struct r_search_path_struct *sps,
 }
 
 void
-internal_function
+private_function
 _dl_rtld_di_serinfo (struct link_map *loader, Dl_serinfo *si, bool counting)
 {
   if (counting)
diff --git a/elf/dl-open.c b/elf/dl-open.c
index cec54db413..865a3ef2ba 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -162,7 +162,7 @@  add_to_global (struct link_map *new)
    address ADDR.  Returns the pointer to the link map of the matching DSO, or
    NULL if a match is not found.  */
 struct link_map *
-internal_function
+private_function
 _dl_find_dso_for_object (const ElfW(Addr) addr)
 {
   struct link_map *l;
diff --git a/elf/dl-support.c b/elf/dl-support.c
index c22be854f4..b98cc4e9df 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -181,7 +181,7 @@  ElfW(Word) _dl_stack_flags = DEFAULT_STACK_PERMS;
 /* If loading a shared object requires that we make the stack executable
    when it was not, we do it by calling this function.
    It returns an errno code or zero on success.  */
-int (*_dl_make_stack_executable_hook) (void **) internal_function
+int (*_dl_make_stack_executable_hook) (void **) private_function
   = _dl_make_stack_executable;
 
 
diff --git a/elf/dl-sym.c b/elf/dl-sym.c
index 7cd6e97643..0ad270d182 100644
--- a/elf/dl-sym.c
+++ b/elf/dl-sym.c
@@ -250,7 +250,7 @@  RTLD_NEXT used in code not dynamically loaded"));
 
 
 void *
-internal_function
+private_function
 _dl_vsym (void *handle, const char *name, const char *version, void *who)
 {
   struct r_found_version vers;
@@ -267,7 +267,7 @@  _dl_vsym (void *handle, const char *name, const char *version, void *who)
 
 
 void *
-internal_function
+private_function
 _dl_sym (void *handle, const char *name, void *who)
 {
   return do_sym (handle, name, who, NULL, DL_LOOKUP_RETURN_NEWEST);
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index 5aba33b3fa..49af79d254 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -308,7 +308,7 @@  allocate_dtv (void *result)
 
 /* Get size and alignment requirements of the static TLS block.  */
 void
-internal_function
+private_function
 _dl_get_tls_static_info (size_t *sizep, size_t *alignp)
 {
   *sizep = GL(dl_tls_static_size);
@@ -439,7 +439,7 @@  _dl_resize_dtv (dtv_t *dtv)
 
 
 void *
-internal_function
+private_function
 _dl_allocate_tls_init (void *result)
 {
   if (result == NULL)
@@ -532,7 +532,7 @@  _dl_allocate_tls_init (void *result)
 rtld_hidden_def (_dl_allocate_tls_init)
 
 void *
-internal_function
+private_function
 _dl_allocate_tls (void *mem)
 {
   return _dl_allocate_tls_init (mem == NULL
@@ -543,7 +543,7 @@  rtld_hidden_def (_dl_allocate_tls)
 
 
 void
-internal_function
+private_function
 _dl_deallocate_tls (void *tcb, bool dealloc_tcb)
 {
   dtv_t *dtv = GET_DTV (tcb);
diff --git a/grp/grp-merge.c b/grp/grp-merge.c
index 035e7a604b..1cd7774694 100644
--- a/grp/grp-merge.c
+++ b/grp/grp-merge.c
@@ -36,7 +36,7 @@ 
   })
 
 int
-internal_function
+private_function
 __copy_grp (const struct group srcgrp, const size_t buflen,
 	    struct group *destgrp, char *destbuf, char **endptr)
 {
@@ -117,7 +117,7 @@  libc_hidden_def (__copy_grp)
 /* Check that the name, GID and passwd fields match, then
    copy in the gr_mem array.  */
 int
-internal_function
+private_function
 __merge_grp (struct group *savedgrp, char *savedbuf, char *savedend,
 	     size_t buflen, struct group *mergegrp, char *mergebuf)
 {
diff --git a/grp/grp-merge.h b/grp/grp-merge.h
index 1ad9b9a539..180beff55b 100644
--- a/grp/grp-merge.h
+++ b/grp/grp-merge.h
@@ -26,12 +26,12 @@ 
 int
 __copy_grp (const struct group srcgrp, const size_t buflen,
 	    struct group *destgrp, char *destbuf, char **endptr)
-	    internal_function;
+	    private_function;
 
 /* Merge the member lists of two grp structs together.  */
 int
 __merge_grp (struct group *savedgrp, char *savedbuf, char *savedend,
 	     size_t buflen, struct group *mergegrp, char *mergebuf)
-	     internal_function;
+	     private_function;
 
 #endif /* _GRP_MERGE_H */
diff --git a/include/dlfcn.h b/include/dlfcn.h
index 2524292ebc..8fcd1727d5 100644
--- a/include/dlfcn.h
+++ b/include/dlfcn.h
@@ -44,7 +44,7 @@  libc_hidden_proto (__libc_dlclose)
 #ifdef ElfW
 extern int _dl_addr (const void *address, Dl_info *info,
 		     struct link_map **mapp, const ElfW(Sym) **symbolp)
-     internal_function;
+     private_function;
 libc_hidden_proto (_dl_addr)
 #endif
 
@@ -61,7 +61,7 @@  extern void _dl_close_worker (struct link_map *map, bool force)
    RTLD_NEXT).  WHO is the calling function, for RTLD_NEXT.  Returns
    the symbol value, which may be NULL.  */
 extern void *_dl_sym (void *handle, const char *name, void *who)
-    internal_function;
+    private_function;
 
 /* Look up version VERSION of symbol NAME in shared object HANDLE
    (which may be RTLD_DEFAULT or RTLD_NEXT).  WHO is the calling
@@ -69,7 +69,7 @@  extern void *_dl_sym (void *handle, const char *name, void *who)
    NULL.  */
 extern void *_dl_vsym (void *handle, const char *name, const char *version,
 		       void *who)
-    internal_function;
+    private_function;
 
 /* Helper function for <dlfcn.h> functions.  Runs the OPERATE function via
    _dl_catch_error.  Returns zero for success, nonzero for failure; and
diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index fe3ab81c51..a9fcd96c0a 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -196,12 +196,17 @@ 
 #endif /* __ASSEMBLER__ */
 
 /* On some platforms we can make internal function calls (i.e., calls of
-   functions not exported) a bit faster by using a different calling
-   convention.  */
+   functions within the same shared object) or private function calls
+   (i.e., calls of functions between different shared objects of glibc)
+   a bit faster by using a different calling convention.  */
 #ifndef internal_function
 # define internal_function	/* empty */
 #endif
 
+#ifndef private_function
+# define private_function	/* empty */
+#endif
+
 /* Determine the return address.  */
 #define RETURN_ADDRESS(nr) \
   __builtin_extract_return_addr (__builtin_return_address (nr))
diff --git a/include/rpc/pmap_clnt.h b/include/rpc/pmap_clnt.h
index ec907c28cc..6a60d4442f 100644
--- a/include/rpc/pmap_clnt.h
+++ b/include/rpc/pmap_clnt.h
@@ -13,7 +13,7 @@  extern int __get_socket (struct sockaddr_in *saddr)
 extern u_short __libc_rpc_getport (struct sockaddr_in *address, u_long program,
 				   u_long version, u_int protocol,
 				   time_t timeout_sec, time_t tottimeout_sec)
-     internal_function;
+     private_function;
 libc_hidden_proto (__libc_rpc_getport)
 
 libc_hidden_proto (clnt_broadcast)
diff --git a/include/stdio.h b/include/stdio.h
index 215f919990..e02d56ddbf 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -99,7 +99,7 @@  extern void __libc_fatal (const char *__message)
 extern void __libc_message (enum __libc_message_action action,
 			    const char *__fnt, ...);
 extern void __fortify_fail (const char *msg)
-     __attribute__ ((__noreturn__)) internal_function;
+     __attribute__ ((__noreturn__)) private_function;
 extern void __fortify_fail_abort (_Bool, const char *msg)
      __attribute__ ((__noreturn__)) internal_function;
 libc_hidden_proto (__fortify_fail)
diff --git a/include/stdlib.h b/include/stdlib.h
index 6fd868828b..670134b1f5 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -201,16 +201,18 @@  libc_hidden_proto (strtoll)
 libc_hidden_proto (strtoul)
 libc_hidden_proto (strtoull)
 
-extern float __strtof_nan (const char *, char **, char) internal_function;
-extern double __strtod_nan (const char *, char **, char) internal_function;
+extern float __strtof_nan (const char *, char **, char)
+     private_function;
+extern double __strtod_nan (const char *, char **, char)
+     private_function;
 extern long double __strtold_nan (const char *, char **, char)
-     internal_function;
+     private_function;
 extern float __wcstof_nan (const wchar_t *, wchar_t **, wchar_t)
-     internal_function;
+     private_function;
 extern double __wcstod_nan (const wchar_t *, wchar_t **, wchar_t)
-     internal_function;
+     private_function;
 extern long double __wcstold_nan (const wchar_t *, wchar_t **, wchar_t)
-     internal_function;
+     private_function;
 
 libc_hidden_proto (__strtof_nan)
 libc_hidden_proto (__strtod_nan)
@@ -229,9 +231,9 @@  libc_hidden_proto (__strtof128_l)
 libc_hidden_proto (strtof128)
 
 extern _Float128 __strtof128_nan (const char *, char **, char)
-     internal_function;
+     private_function;
 extern _Float128 __wcstof128_nan (const wchar_t *, wchar_t **, wchar_t)
-     internal_function;
+     private_function;
 
 libc_hidden_proto (__strtof128_nan)
 libc_hidden_proto (__wcstof128_nan)
diff --git a/inet/inet6_scopeid_pton.c b/inet/inet6_scopeid_pton.c
index e09b1cb34d..004cab219d 100644
--- a/inet/inet6_scopeid_pton.c
+++ b/inet/inet6_scopeid_pton.c
@@ -28,7 +28,7 @@ 
 
 /* Parse SOURCE as a scope ID for ADDRESS.  Return 0 on success and -1
    on error.  */
-internal_function int
+private_function int
 __inet6_scopeid_pton (const struct in6_addr *address, const char *scope,
                       uint32_t *result)
 {
diff --git a/inet/net-internal.h b/inet/net-internal.h
index 2b2632c7ba..501c2112e6 100644
--- a/inet/net-internal.h
+++ b/inet/net-internal.h
@@ -26,7 +26,7 @@ 
 
 int __inet6_scopeid_pton (const struct in6_addr *address,
                           const char *scope, uint32_t *result)
-  internal_function attribute_hidden;
+  private_function attribute_hidden;
 libc_hidden_proto (__inet6_scopeid_pton)
 
 
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index ce2e24af95..e81008f358 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -784,7 +784,7 @@  __deallocate_stack (struct pthread *pd)
 
 
 int
-internal_function
+private_function
 __make_stacks_executable (void **stack_endp)
 {
   /* First the main thread's stack.  */
diff --git a/nptl/libc_pthread_init.c b/nptl/libc_pthread_init.c
index 0db7a10893..5c00161e26 100644
--- a/nptl/libc_pthread_init.c
+++ b/nptl/libc_pthread_init.c
@@ -38,7 +38,7 @@  extern int __libc_multiple_threads attribute_hidden;
 
 int *
 #endif
-internal_function
+private_function
 __libc_pthread_init (unsigned long int *ptr, void (*reclaim) (void),
 		     const struct pthread_functions *functions)
 {
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index 6e7d6ff09e..3e376494f8 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -357,7 +357,7 @@  extern void __reclaim_stacks (void) attribute_hidden;
 
 /* Make all threads's stacks executable.  */
 extern int __make_stacks_executable (void **stack_endp)
-     internal_function attribute_hidden;
+     private_function attribute_hidden;
 
 /* longjmp handling.  */
 extern void __pthread_cleanup_upto (__jmp_buf target, char *targetframe);
@@ -388,12 +388,12 @@  hidden_proto (__nptl_death_event)
 extern void __libc_pthread_init (unsigned long int *ptr,
 				 void (*reclaim) (void),
 				 const struct pthread_functions *functions)
-     internal_function;
+     private_function;
 #else
 extern int *__libc_pthread_init (unsigned long int *ptr,
 				 void (*reclaim) (void),
 				 const struct pthread_functions *functions)
-     internal_function;
+     private_function;
 
 /* Variable set to a nonzero value either if more than one thread runs or ran,
    or if a single-threaded process is trying to cancel itself.  See
diff --git a/nss/XXX-lookup.c b/nss/XXX-lookup.c
index 5a37fdae08..84c3f525f9 100644
--- a/nss/XXX-lookup.c
+++ b/nss/XXX-lookup.c
@@ -57,11 +57,11 @@  service_user *DATABASE_NAME_SYMBOL attribute_hidden;
 
 extern int DB_LOOKUP_FCT (service_user **ni, const char *fct_name,
 			  const char *fct2_name, void **fctp)
-  internal_function;
+  private_function;
 libc_hidden_proto (DB_LOOKUP_FCT)
 
 int
-internal_function
+private_function
 DB_LOOKUP_FCT (service_user **ni, const char *fct_name, const char *fct2_name,
 	       void **fctp)
 {
@@ -79,7 +79,7 @@  libc_hidden_def (DB_LOOKUP_FCT)
 
 #ifndef NO_COMPAT
 int
-internal_function attribute_compat_text_section
+private_function attribute_compat_text_section
 DB_COMPAT_FCT (service_user **ni, const char *fct_name, void **fctp)
 {
   return DB_LOOKUP_FCT (ni, fct_name, NULL, fctp);
diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c
index 6c547ea1ca..4aa95a2bcb 100644
--- a/nss/getXXbyYY_r.c
+++ b/nss/getXXbyYY_r.c
@@ -181,7 +181,7 @@  typedef enum nss_status (*lookup_function) (ADD_PARAMS, LOOKUP_TYPE *, char *,
 /* The lookup function for the first entry of this service.  */
 extern int DB_LOOKUP_FCT (service_user **nip, const char *name,
 			  const char *name2, void **fctp)
-     internal_function;
+     private_function;
 libc_hidden_proto (DB_LOOKUP_FCT)
 
 
diff --git a/nss/getXXent_r.c b/nss/getXXent_r.c
index 2710c1cd51..9066d47e20 100644
--- a/nss/getXXent_r.c
+++ b/nss/getXXent_r.c
@@ -114,7 +114,7 @@  __libc_lock_define_initialized (static, lock)
 /* The lookup function for the first entry of this service.  */
 extern int DB_LOOKUP_FCT (service_user **nip, const char *name,
 			  const char *name2, void **fctp)
-     internal_function;
+     private_function;
 libc_hidden_proto (DB_LOOKUP_FCT)
 
 void
diff --git a/nss/nsswitch.h b/nss/nsswitch.h
index bd3fbcb082..b5e7ca14c7 100644
--- a/nss/nsswitch.h
+++ b/nss/nsswitch.h
@@ -169,7 +169,7 @@  extern void __nss_disable_nscd (void (*) (size_t, struct traced_file *));
 
 typedef int (*db_lookup_function) (service_user **, const char *, const char *,
 				   void **)
-     internal_function;
+     private_function;
 typedef enum nss_status (*setent_function) (int);
 typedef enum nss_status (*endent_function) (void);
 typedef enum nss_status (*getent_function) (void *, char *, size_t,
diff --git a/resolv/gai_misc.h b/resolv/gai_misc.h
index 6679d2b7d5..6f686c0bc7 100644
--- a/resolv/gai_misc.h
+++ b/resolv/gai_misc.h
@@ -96,6 +96,6 @@  extern int __gai_notify_only (struct sigevent *sigev, pid_t caller_pid)
 
 /* Send the signal.  */
 extern int __gai_sigqueue (int sig, const union sigval val, pid_t caller_pid)
-     internal_function;
+     private_function;
 
 #endif /* gai_misc.h */
diff --git a/resolv/gai_sigqueue.c b/resolv/gai_sigqueue.c
index ebc1e5ed46..ddec42c743 100644
--- a/resolv/gai_sigqueue.c
+++ b/resolv/gai_sigqueue.c
@@ -22,7 +22,7 @@ 
 #include <gai_misc.h>
 
 int
-internal_function
+private_function
 __gai_sigqueue (int sig, const union sigval val, pid_t caller_pid)
 {
   __set_errno (ENOSYS);
diff --git a/stdlib/strtod_nan_main.c b/stdlib/strtod_nan_main.c
index 96b788cb1e..f002abeb5d 100644
--- a/stdlib/strtod_nan_main.c
+++ b/stdlib/strtod_nan_main.c
@@ -29,7 +29,7 @@ 
    return a default NAN.  If ENDPTR is not NULL, set *ENDPTR to point
    to the character after the initial n-char-sequence.  */
 
-internal_function
+private_function
 FLOAT
 STRTOD_NAN (const STRING_TYPE *str, STRING_TYPE **endptr, STRING_TYPE endc)
 {
diff --git a/sunrpc/pm_getport.c b/sunrpc/pm_getport.c
index 54d2e439d2..0883abc663 100644
--- a/sunrpc/pm_getport.c
+++ b/sunrpc/pm_getport.c
@@ -82,7 +82,7 @@  __get_socket (struct sockaddr_in *saddr)
  * Returns 0 if no map exists.
  */
 u_short
-internal_function
+private_function
 __libc_rpc_getport (struct sockaddr_in *address, u_long program,
 		    u_long version, u_int protocol, time_t timeout_sec,
 		    time_t tottimeout_sec)
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 4508365871..3c7ebd1e16 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -377,7 +377,7 @@  struct rtld_global
   /* If loading a shared object requires that we make the stack executable
      when it was not, we do it by calling this function.
      It returns an errno code or zero on success.  */
-  EXTERN int (*_dl_make_stack_executable_hook) (void **) internal_function;
+  EXTERN int (*_dl_make_stack_executable_hook) (void **) private_function;
 
   /* Prevailing state of the stack, PF_X indicating it's executable.  */
   EXTERN ElfW(Word) _dl_stack_flags;
@@ -632,7 +632,7 @@  extern size_t _dl_phnum;
 
 /* This is the initial value of GL(dl_make_stack_executable_hook).
    A threads library can change it.  */
-extern int _dl_make_stack_executable (void **stack_endp) internal_function;
+extern int _dl_make_stack_executable (void **stack_endp) private_function;
 rtld_hidden_proto (_dl_make_stack_executable)
 
 /* Variable pointing to the end of the stack (or close to it).  This value
@@ -739,7 +739,7 @@  _dl_dprintf (int fd, const char *fmt, ...)
    problem.  */
 extern void _dl_signal_error (int errcode, const char *object,
 			      const char *occurred, const char *errstring)
-     internal_function __attribute__ ((__noreturn__));
+     private_function __attribute__ ((__noreturn__));
 libc_hidden_proto (_dl_signal_error)
 
 /* Like _dl_signal_error, but may return when called in the context of
@@ -779,7 +779,7 @@  extern void _dl_receive_error (receiver_fct fct, void (*operate) (void *),
 extern int _dl_catch_error (const char **objname, const char **errstring,
 			    bool *mallocedp, void (*operate) (void *),
 			    void *args)
-     internal_function;
+     private_function;
 libc_hidden_proto (_dl_catch_error)
 
 /* Open the shared object NAME and map in its segments.
@@ -813,7 +813,7 @@  extern void _dl_setup_hash (struct link_map *map)
    bytes to be used in filling in the result.  */
 extern void _dl_rtld_di_serinfo (struct link_map *loader,
 				 Dl_serinfo *si, bool counting)
-     internal_function;
+     private_function;
 
 
 /* Search loaded objects' symbol tables for a definition of the symbol
@@ -1012,12 +1012,12 @@  void __pthread_initialize_minimal (void) weak_function;
 #endif
 
 /* Allocate memory for static TLS block (unless MEM is nonzero) and dtv.  */
-extern void *_dl_allocate_tls (void *mem) internal_function;
+extern void *_dl_allocate_tls (void *mem) private_function;
 rtld_hidden_proto (_dl_allocate_tls)
 
 /* Get size and alignment requirements of the static TLS block.  */
 extern void _dl_get_tls_static_info (size_t *sizep, size_t *alignp)
-     internal_function;
+     private_function;
 
 extern void _dl_allocate_static_tls (struct link_map *map)
      internal_function attribute_hidden;
@@ -1026,11 +1026,11 @@  extern void _dl_allocate_static_tls (struct link_map *map)
    only used within rtld.c itself at startup time.  */
 extern void *_dl_allocate_tls_storage (void)
      internal_function attribute_hidden;
-extern void *_dl_allocate_tls_init (void *) internal_function;
+extern void *_dl_allocate_tls_init (void *) private_function;
 rtld_hidden_proto (_dl_allocate_tls_init)
 
 /* Deallocate memory allocated with _dl_allocate_tls.  */
-extern void _dl_deallocate_tls (void *tcb, bool dealloc_tcb) internal_function;
+extern void _dl_deallocate_tls (void *tcb, bool dealloc_tcb) private_function;
 rtld_hidden_proto (_dl_deallocate_tls)
 
 extern void _dl_nothread_init_static_tls (struct link_map *) attribute_hidden;
@@ -1081,7 +1081,7 @@  extern void _dl_show_scope (struct link_map *new, int from)
      attribute_hidden;
 
 extern struct link_map *_dl_find_dso_for_object (const ElfW(Addr) addr)
-     internal_function;
+     private_function;
 rtld_hidden_proto (_dl_find_dso_for_object)
 
 /* Initialization which is normally done by the dynamic linker.  */
diff --git a/sysdeps/i386/configure b/sysdeps/i386/configure
index 5b55c5affe..cf777b8251 100644
--- a/sysdeps/i386/configure
+++ b/sysdeps/i386/configure
@@ -26,7 +26,7 @@  libc_compiler_builtin_inlined=no
 cat > conftest.c <<EOF
 int _start (void) { int a, b, c; __sync_val_compare_and_swap (&a, b, c); return 0; }
 EOF
-if ! { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS
+if ! { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp
 		     -O0 -nostdlib -nostartfiles
 		     -S conftest.c -o - | fgrep "__sync_val_compare_and_swap"
 		     1>&5'
@@ -77,7 +77,13 @@  if test $libc_cv_asm_mpx = yes; then
 
 fi
 
-$as_echo "#define USE_REGPARMS 1" >>confdefs.h
+# On i386, we can make internal function calls (i.e., calls of functions
+# within the same shared object) or private function calls (i.e., calls
+# of functions between different shared objects of glibc) a bit faster
+# by passing function parameters in registers.
+$as_echo "#define internal_function __attribute__ ((regparm (3), stdcall))" >>confdefs.h
+
+$as_echo "#define private_function __attribute__ ((regparm (3), stdcall))" >>confdefs.h
 
 
 $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h
diff --git a/sysdeps/i386/configure.ac b/sysdeps/i386/configure.ac
index 19ef33f34a..cbcbcb175c 100644
--- a/sysdeps/i386/configure.ac
+++ b/sysdeps/i386/configure.ac
@@ -45,7 +45,12 @@  if test $libc_cv_asm_mpx = yes; then
   AC_DEFINE(HAVE_MPX_SUPPORT)
 fi
 
-AC_DEFINE(USE_REGPARMS)
+# On i386, we can make internal function calls (i.e., calls of functions
+# within the same shared object) or private function calls (i.e., calls
+# of functions between different shared objects of glibc) a bit faster
+# by passing function parameters in registers.
+AC_DEFINE(internal_function, __attribute__ ((regparm (3), stdcall)))
+AC_DEFINE(private_function, __attribute__ ((regparm (3), stdcall)))
 
 dnl It is always possible to access static and hidden symbols in an
 dnl position independent way.
diff --git a/sysdeps/unix/sysv/linux/dl-execstack.c b/sysdeps/unix/sysv/linux/dl-execstack.c
index 3c4de1cb46..913af76a75 100644
--- a/sysdeps/unix/sysv/linux/dl-execstack.c
+++ b/sysdeps/unix/sysv/linux/dl-execstack.c
@@ -30,7 +30,7 @@  extern int __stack_prot attribute_relro attribute_hidden;
 
 
 int
-internal_function
+private_function
 _dl_make_stack_executable (void **stack_endp)
 {
   /* This gives us the highest/lowest page that needs to be changed.  */
diff --git a/sysdeps/unix/sysv/linux/gai_sigqueue.c b/sysdeps/unix/sysv/linux/gai_sigqueue.c
index 0f7b459b5e..04c8d5008a 100644
--- a/sysdeps/unix/sysv/linux/gai_sigqueue.c
+++ b/sysdeps/unix/sysv/linux/gai_sigqueue.c
@@ -30,7 +30,7 @@ 
 
 /* Return any pending signal or wait for one for the given time.  */
 int
-internal_function
+private_function
 __gai_sigqueue (int sig, const union sigval val, pid_t caller_pid)
 {
   siginfo_t info;
diff --git a/sysdeps/unix/sysv/linux/netlink_assert_response.c b/sysdeps/unix/sysv/linux/netlink_assert_response.c
index d60eb1515e..963c879e71 100644
--- a/sysdeps/unix/sysv/linux/netlink_assert_response.c
+++ b/sysdeps/unix/sysv/linux/netlink_assert_response.c
@@ -39,7 +39,7 @@  get_address_family (int fd)
 }
 
 void
-internal_function
+private_function
 __netlink_assert_response (int fd, ssize_t result)
 {
   if (result < 0)
diff --git a/sysdeps/unix/sysv/linux/netlinkaccess.h b/sysdeps/unix/sysv/linux/netlinkaccess.h
index 6cffb65b14..bcbcc23abb 100644
--- a/sysdeps/unix/sysv/linux/netlinkaccess.h
+++ b/sysdeps/unix/sysv/linux/netlinkaccess.h
@@ -52,7 +52,7 @@  extern int __netlink_request (struct netlink_handle *h, int type);
 /* Terminate the process if RESULT is an invalid recvmsg result for
    the netlink socket FD.  */
 void __netlink_assert_response (int fd, ssize_t result)
-  internal_function;
+  private_function;
 libc_hidden_proto (__netlink_assert_response)
 
 #endif /* netlinkaccess.h */