diff mbox series

[7/9] posix: Consolidate glob implementation

Message ID 1504643122-14874-8-git-send-email-adhemerval.zanella@linaro.org
State New
Headers show
Series posix: glob fixes and refactor | expand

Commit Message

Adhemerval Zanella Netto Sept. 5, 2017, 8:25 p.m. UTC
This patch consolidates the glob implementation.  The main changes are:

  * On Linux all implementation now uses a default one with the exception
    of alpha (which requires specific versioning) and s390-32 (which
    different than other 32 bits with support for v2.1 symbol does not
    add a compat one).

  * The default implementation uses XSTAT_IS_XSTAT64 to define whether
    both glob{free} and glob{free}64 should be different implementation.
    For archictures that define XSTAT_IS_XSTAT64, glob{free} alias to
    glob{free}64.

  * Move i386 olddirent.h header to Linux default directory, since it is
    the only header with this name and it is shared among different
    architectures (and used on compat glob symbol as well).

Checked on x86_64-linux-gnu and on a build using build-many-glibcs.py
for all major architectures.

	* sysdeps/gnu/globfree64.c: Remove file.
	* sysdeps/unix/sysv/linux/arm/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/i386/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/m68k/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/n64/globfree64.c: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/wordsize-64/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/wordsize-64/globfree64.c: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/x32/glob.c: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/x32/globfree.c: Likewise.
	* sysdeps/wordsize-64/glob.c: Likewise.
	* sysdeps/wordsize-64/glob64.c: Likewise.
	* sysdeps/wordsize-64/globfree64.c: Likewise.
	* sysdeps/unix/sysv/linux/glob.c: New file.
	* sysdeps/unix/sysv/linux/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/globfree.c: Likewise.
	* sysdeps/unix/sysv/linux/globfree64.c: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-32/glob64.c: Likewise.
	* sysdeps/unix/sysv/linux/oldglob.c [SHLIB_COMPAT]: Also
	adds !GLOB_NO_OLD_VERSION as an extra condition.
	* sysdeps/unix/sysv/linux/i386/alphasort64.c: Include olddirent.h
	using relative path instead of absolute one.
	* sysdeps/unix/sysv/linux/i386/getdents64.c: Likewise.
	* sysdeps/unix/sysv/linux/i386/readdir64.c: Likewise.
	* sysdeps/unix/sysv/linux/i386/readdir64_r.c: Likewise.
	* sysdeps/unix/sysv/linux/i386/versionsort64.c: Likewise.
	* sysdeps/unix/sysv/linux/i386/olddirent.h: Move to ...
	* sysdeps/unix/sysv/linux//olddirent.h: ... here.
---
 ChangeLog                                          | 31 ++++++++++++++++
 sysdeps/gnu/globfree64.c                           | 10 ------
 sysdeps/unix/sysv/linux/arm/glob64.c               |  1 -
 sysdeps/unix/sysv/linux/glob.c                     | 28 +++++++++++++++
 sysdeps/unix/sysv/linux/{i386 => }/glob64.c        | 41 +++++++++++++---------
 sysdeps/unix/sysv/linux/globfree.c                 | 30 ++++++++++++++++
 sysdeps/unix/sysv/linux/globfree64.c               | 36 +++++++++++++++++++
 sysdeps/unix/sysv/linux/i386/alphasort64.c         |  2 +-
 sysdeps/unix/sysv/linux/i386/getdents64.c          |  2 +-
 sysdeps/unix/sysv/linux/i386/readdir64.c           |  2 +-
 sysdeps/unix/sysv/linux/i386/readdir64_r.c         |  2 +-
 sysdeps/unix/sysv/linux/i386/versionsort64.c       |  2 +-
 sysdeps/unix/sysv/linux/m68k/glob64.c              |  1 -
 sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c   |  1 -
 .../unix/sysv/linux/mips/mips64/n64/globfree64.c   |  1 -
 sysdeps/unix/sysv/linux/{i386 => }/olddirent.h     |  0
 sysdeps/unix/sysv/linux/oldglob.c                  |  5 +--
 sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c |  1 -
 sysdeps/unix/sysv/linux/s390/s390-32/glob64.c      |  2 ++
 sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c     |  1 -
 sysdeps/unix/sysv/linux/wordsize-64/glob64.c       |  2 --
 sysdeps/unix/sysv/linux/wordsize-64/globfree64.c   |  2 --
 sysdeps/unix/sysv/linux/x86_64/x32/glob.c          |  1 -
 sysdeps/unix/sysv/linux/x86_64/x32/globfree.c      |  1 -
 sysdeps/wordsize-64/glob.c                         |  6 ----
 sysdeps/wordsize-64/glob64.c                       |  1 -
 sysdeps/wordsize-64/globfree64.c                   |  1 -
 27 files changed, 160 insertions(+), 53 deletions(-)
 delete mode 100644 sysdeps/gnu/globfree64.c
 delete mode 100644 sysdeps/unix/sysv/linux/arm/glob64.c
 create mode 100644 sysdeps/unix/sysv/linux/glob.c
 rename sysdeps/unix/sysv/linux/{i386 => }/glob64.c (57%)
 create mode 100644 sysdeps/unix/sysv/linux/globfree.c
 create mode 100644 sysdeps/unix/sysv/linux/globfree64.c
 delete mode 100644 sysdeps/unix/sysv/linux/m68k/glob64.c
 delete mode 100644 sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c
 delete mode 100644 sysdeps/unix/sysv/linux/mips/mips64/n64/globfree64.c
 rename sysdeps/unix/sysv/linux/{i386 => }/olddirent.h (100%)
 delete mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c
 create mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/glob64.c
 delete mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c
 delete mode 100644 sysdeps/unix/sysv/linux/wordsize-64/glob64.c
 delete mode 100644 sysdeps/unix/sysv/linux/wordsize-64/globfree64.c
 delete mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/glob.c
 delete mode 100644 sysdeps/unix/sysv/linux/x86_64/x32/globfree.c
 delete mode 100644 sysdeps/wordsize-64/glob.c
 delete mode 100644 sysdeps/wordsize-64/glob64.c
 delete mode 100644 sysdeps/wordsize-64/globfree64.c

-- 
2.7.4

Comments

Andreas Schwab Sept. 12, 2017, 7:35 a.m. UTC | #1
On Sep 05 2017, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

>   * On Linux all implementation now uses a default one with the exception

>     of alpha (which requires specific versioning) and s390-32 (which

>     different than other 32 bits with support for v2.1 symbol does not

>     add a compat one).


This drops the default glob64 symbol from s390 (the glob64@GLIBC_2.1
symbol is now hidden).

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."
Andreas Schwab Sept. 12, 2017, 12:56 p.m. UTC | #2
On Sep 05 2017, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> diff --git a/sysdeps/unix/sysv/linux/oldglob.c b/sysdeps/unix/sysv/linux/oldglob.c

> index 8233e57..5402450 100644

> --- a/sysdeps/unix/sysv/linux/oldglob.c

> +++ b/sysdeps/unix/sysv/linux/oldglob.c

> @@ -1,12 +1,13 @@

>  #include <shlib-compat.h>

>  

> -#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)

> +#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) \

> +    && !defined(GLOB_NO_OLD_VERSION)


There is nothing that defines GLOB_NO_OLD_VERSION for s390-32.

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."
Adhemerval Zanella Netto Sept. 12, 2017, 2:08 p.m. UTC | #3
On 12/09/2017 04:35, Andreas Schwab wrote:
> On Sep 05 2017, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> 

>>   * On Linux all implementation now uses a default one with the exception

>>     of alpha (which requires specific versioning) and s390-32 (which

>>     different than other 32 bits with support for v2.1 symbol does not

>>     add a compat one).

> 

> This drops the default glob64 symbol from s390 (the glob64@GLIBC_2.1

> symbol is now hidden).

> 

> Andreas.

> 


That was not what I am seeing from master:

$ file libc.so
libc.so: ELF 32-bit MSB shared object, IBM S/390, version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld.so.1, for GNU/Linux 3.2.0, not stripped
$ s390x-glibc-linux-gnu-objdump -t libc.so | grep glob64
00000000 l    df *ABS*  00000000              glob64.os
001221c8 l     F .text  0000144e              __GI___old_glob64
000b3330 l     F .text  0000144e              glob64
000b3330 l     F .text  0000144e              __GI_glob64
000b3330 l     F .text  0000144e              __glob64
001221c8 l     F .text  0000144e              __old_glob64
001221c8 g     F .text  0000144e              glob64@GLIBC_2.1

And checking the build of glob64.os for s390 I do see:

[...]
extern __typeof (__glob64) glob64 __attribute__ ((alias ("__glob64")));
extern __typeof (glob64) __EI_glob64 __asm__("" "glob64"); extern __typeof (glob64) __EI_glob64 __attribute__((alias ("" "__GI_glob64")));
[...]

$ s390x-glibc-linux-gnu-objdump -t posix/glob64.os | grep glob64
posix/glob64.os:     file format elf32-s390
000009b0 g     F .text  0000144e __glob64
000009b0 g     F .text  0000144e .hidden __GI_glob64
000009b0 g     F .text  0000144e glob64

And make check/check-abi does not report this issue as well.  That kind of issue
should be reported by make check-abi, shouldn't it? Are you seeing with on 
make check?
Andreas Schwab Sept. 12, 2017, 2:17 p.m. UTC | #4
On Sep 12 2017, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> That was not what I am seeing from master:


It comes from oldglob.

> And make check/check-abi does not report this issue as well.  That kind of issue

> should be reported by make check-abi, shouldn't it?


No, this is part of the API, not the ABI (which is still correct).

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."
Adhemerval Zanella Netto Sept. 12, 2017, 2:21 p.m. UTC | #5
On 12/09/2017 09:56, Andreas Schwab wrote:
> On Sep 05 2017, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> 

>> diff --git a/sysdeps/unix/sysv/linux/oldglob.c b/sysdeps/unix/sysv/linux/oldglob.c

>> index 8233e57..5402450 100644

>> --- a/sysdeps/unix/sysv/linux/oldglob.c

>> +++ b/sysdeps/unix/sysv/linux/oldglob.c

>> @@ -1,12 +1,13 @@

>>  #include <shlib-compat.h>

>>  

>> -#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)

>> +#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) \

>> +    && !defined(GLOB_NO_OLD_VERSION)

> 

> There is nothing that defines GLOB_NO_OLD_VERSION for s390-32.

> 

> Andreas.

> 


Yes, this is wrong since oldglob.c as default will create symbol where
for s390 it should not.  S390 requires a arch-specific oldglob.c as

#define GLOB_NO_OLD_VERSION
#include <sysdeps/unix/sysv/linux/oldglob.c>

So glob64.os will the only object providing glob64 symbols.  With this
file now I see:

$ /s390x-glibc-linux-gnu-objdump -t posix/glob64.os | grep glob64
posix/glob64.os:     file format elf32-s390
000009b0 g     F .text  0000144e __glob64
000009b0 g     F .text  0000144e .hidden __GI_glob64
000009b0 g     F .text  0000144e glob64
$ s390x-glibc-linux-gnu-objdump -t posix/oldglob.os | grep glob64
$ 

I will fix it and maybe it is confusing the linker and making you seem
the missing glob64 (since oldglob.os and glob64.os both provide the
same symbol).
Joseph Myers Sept. 12, 2017, 2:28 p.m. UTC | #6
On Tue, 12 Sep 2017, Andreas Schwab wrote:

> On Sep 05 2017, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> 

> >   * On Linux all implementation now uses a default one with the exception

> >     of alpha (which requires specific versioning) and s390-32 (which

> >     different than other 32 bits with support for v2.1 symbol does not

> >     add a compat one).

> 

> This drops the default glob64 symbol from s390 (the glob64@GLIBC_2.1

> symbol is now hidden).


Does this mean we don't have any tests that verify a call to glob64 can be 
linked (and works)?  If so, such tests should be added (generally, all 
non-compat symbols ought to be tested).

-- 
Joseph S. Myers
joseph@codesourcery.com
Andreas Schwab Sept. 12, 2017, 2:34 p.m. UTC | #7
On Sep 12 2017, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> I will fix it and maybe it is confusing the linker and making you seem

> the missing glob64 (since oldglob.os and glob64.os both provide the

> same symbol).


glob64@GLIBC_2.1 is the only version and it isn't the default, thus
becomes hidden.

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."
Andreas Schwab Sept. 12, 2017, 2:39 p.m. UTC | #8
On Sep 12 2017, Joseph Myers <joseph@codesourcery.com> wrote:

> Does this mean we don't have any tests that verify a call to glob64 can be 

> linked (and works)?  If so, such tests should be added (generally, all 

> non-compat symbols ought to be tested).


It's a long standing bug that we don't verify the API.  See the various
incidences about missing symbols on some architectures.

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."
Joseph Myers Sept. 12, 2017, 2:50 p.m. UTC | #9
On Tue, 12 Sep 2017, Andreas Schwab wrote:

> On Sep 12 2017, Joseph Myers <joseph@codesourcery.com> wrote:

> 

> > Does this mean we don't have any tests that verify a call to glob64 can be 

> > linked (and works)?  If so, such tests should be added (generally, all 

> > non-compat symbols ought to be tested).

> 

> It's a long standing bug that we don't verify the API.  See the various

> incidences about missing symbols on some architectures.


Well, I think of it as a large number of bugs that some symbol X is 
missing test coverage.  In general, each of those bugs can be addressed 
independently by adding a test or tests of an untested interface.  See 
<https://sourceware.org/ml/libc-alpha/2013-07/msg00386.html> for some 
scripts I used to produce a list of untested symbols.  Ideally, everything 
in the API would indeed be tested and documented.

-- 
Joseph S. Myers
joseph@codesourcery.com
Adhemerval Zanella Netto Sept. 13, 2017, 12:26 p.m. UTC | #10
On 12/09/2017 11:34, Andreas Schwab wrote:
> On Sep 12 2017, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote:

> 

>> I will fix it and maybe it is confusing the linker and making you seem

>> the missing glob64 (since oldglob.os and glob64.os both provide the

>> same symbol).

> 

> glob64@GLIBC_2.1 is the only version and it isn't the default, thus

> becomes hidden.

> 

> Andreas.

> 


I pushed the patch below. It removes the alpha rule to add the oldglob
and refrain s390 to build the compat code.

---

diff --git a/sysdeps/unix/sysv/linux/alpha/Makefile b/sysdeps/unix/sysv/linux/alpha/Makefile
index 47bd189..50f4fb1 100644
--- a/sysdeps/unix/sysv/linux/alpha/Makefile
+++ b/sysdeps/unix/sysv/linux/alpha/Makefile
@@ -1,7 +1,3 @@
-ifeq ($(subdir),posix)
-sysdep_routines += oldglob
-endif
-
 ifeq ($(subdir),stdlib)
 gen-as-const-headers += ucontext-offsets.sym
 endif
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c b/sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c
new file mode 100644
index 0000000..56d7d12
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c
@@ -0,0 +1,2 @@
+#define GLOB_NO_OLD_VERSION
+#include <sysdeps/unix/sysv/linux/oldglob.c>
diff mbox series

Patch

diff --git a/sysdeps/gnu/globfree64.c b/sysdeps/gnu/globfree64.c
deleted file mode 100644
index f092d0b..0000000
--- a/sysdeps/gnu/globfree64.c
+++ /dev/null
@@ -1,10 +0,0 @@ 
-#include <dirent.h>
-#include <glob.h>
-#include <sys/stat.h>
-
-#define glob_t glob64_t
-#define globfree(pglob) globfree64 (pglob)
-
-#include <posix/globfree.c>
-
-libc_hidden_def (globfree64)
diff --git a/sysdeps/unix/sysv/linux/arm/glob64.c b/sysdeps/unix/sysv/linux/arm/glob64.c
deleted file mode 100644
index 82a9a29..0000000
--- a/sysdeps/unix/sysv/linux/arm/glob64.c
+++ /dev/null
@@ -1 +0,0 @@ 
-#include <sysdeps/unix/sysv/linux/i386/glob64.c>
diff --git a/sysdeps/unix/sysv/linux/glob.c b/sysdeps/unix/sysv/linux/glob.c
new file mode 100644
index 0000000..057ae7f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/glob.c
@@ -0,0 +1,28 @@ 
+/* Find pathnames matching a pattern.  Linux version.
+   Copyright (C) 2017 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; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#define glob64 __no_glob64_decl
+#include <posix/glob.c>
+#undef glob64
+
+#if XSTAT_IS_XSTAT64
+weak_alias (glob, glob64)
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/glob64.c b/sysdeps/unix/sysv/linux/glob64.c
similarity index 57%
rename from sysdeps/unix/sysv/linux/i386/glob64.c
rename to sysdeps/unix/sysv/linux/glob64.c
index 230f9fc..428bbac 100644
--- a/sysdeps/unix/sysv/linux/i386/glob64.c
+++ b/sysdeps/unix/sysv/linux/glob64.c
@@ -1,5 +1,5 @@ 
-/* Two glob variants with 64-bit support, for dirent64 and __olddirent64.
-   Copyright (C) 1998-2017 Free Software Foundation, Inc.
+/* Find pathnames matching a pattern.  Linux version.
+   Copyright (C) 2017 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
@@ -16,27 +16,36 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <dirent.h>
-#include <glob.h>
 #include <sys/stat.h>
-#include <shlib-compat.h>
+#include <kernel_stat.h>
 
-#define dirent dirent64
-#define __readdir(dirp) __readdir64 (dirp)
+#if !XSTAT_IS_XSTAT64
+# include <glob.h>
+# include <dirent.h>
+# include <sys/stat.h>
 
-#define glob_t glob64_t
-#define glob(pattern, flags, errfunc, pglob) \
+# define dirent dirent64
+# define __readdir(dirp) __readdir64 (dirp)
+
+# define glob_t glob64_t
+# define glob(pattern, flags, errfunc, pglob) \
   __glob64 (pattern, flags, errfunc, pglob)
-#define globfree(pglob) globfree64 (pglob)
+# define globfree(pglob) globfree64 (pglob)
+
+# undef stat
+# define stat stat64
 
-#undef stat
-#define stat stat64
-#undef __stat
-#define __stat(file, buf) __xstat64 (_STAT_VER, file, buf)
+# define COMPILE_GLOB64	1
 
-#define COMPILE_GLOB64	1
+# include <posix/glob.c>
 
-#include <posix/glob.c>
+# include "shlib-compat.h"
 
+# ifdef GLOB_NO_OLD_VERSION
+strong_alias (__glob64, glob64)
+libc_hidden_def (glob64)
+# else
 versioned_symbol (libc, __glob64, glob64, GLIBC_2_2);
 libc_hidden_ver (__glob64, glob64)
+# endif
+#endif /* XSTAT_IS_XSTAT64  */
diff --git a/sysdeps/unix/sysv/linux/globfree.c b/sysdeps/unix/sysv/linux/globfree.c
new file mode 100644
index 0000000..48d4aec
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/globfree.c
@@ -0,0 +1,30 @@ 
+/* Frees the dynamically allocated storage from an earlier call to glob.
+   Linux version.
+   Copyright (C) 2017 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; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#define globfree64 __no_globfree64_decl
+#include <posix/globfree.c>
+#undef globfree64
+
+#if XSTAT_IS_XSTAT64
+weak_alias (globfree, globfree64)
+libc_hidden_ver (globfree, globfree64)
+#endif
diff --git a/sysdeps/unix/sysv/linux/globfree64.c b/sysdeps/unix/sysv/linux/globfree64.c
new file mode 100644
index 0000000..0020466
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/globfree64.c
@@ -0,0 +1,36 @@ 
+/* Frees the dynamically allocated storage from an earlier call to glob.
+   Linux version.
+   Copyright (C) 2017 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; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sys/stat.h>
+#include <kernel_stat.h>
+
+#if !XSTAT_IS_XSTAT64
+
+# include <glob.h>
+
+# define glob_t glob64_t
+# define globfree(pglob) globfree64 (pglob)
+
+# undef stat
+# define stat stat64
+
+# include <posix/globfree.c>
+
+libc_hidden_def (globfree64)
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/alphasort64.c b/sysdeps/unix/sysv/linux/i386/alphasort64.c
index d5fd47a..04b29b6 100644
--- a/sysdeps/unix/sysv/linux/i386/alphasort64.c
+++ b/sysdeps/unix/sysv/linux/i386/alphasort64.c
@@ -30,7 +30,7 @@  versioned_symbol (libc, __alphasort64, alphasort64, GLIBC_2_2);
 
 #if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
 
-#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+#include <olddirent.h>
 
 int
 __old_alphasort64 (const struct __old_dirent64 **a,
diff --git a/sysdeps/unix/sysv/linux/i386/getdents64.c b/sysdeps/unix/sysv/linux/i386/getdents64.c
index e8b257f..2010bbf 100644
--- a/sysdeps/unix/sysv/linux/i386/getdents64.c
+++ b/sysdeps/unix/sysv/linux/i386/getdents64.c
@@ -28,7 +28,7 @@ 
 
 #if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
 
-#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+#include <olddirent.h>
 
 #define __GETDENTS __old_getdents64
 #define DIRENT_TYPE struct __old_dirent64
diff --git a/sysdeps/unix/sysv/linux/i386/readdir64.c b/sysdeps/unix/sysv/linux/i386/readdir64.c
index de8669f..da3defd 100644
--- a/sysdeps/unix/sysv/linux/i386/readdir64.c
+++ b/sysdeps/unix/sysv/linux/i386/readdir64.c
@@ -31,7 +31,7 @@  versioned_symbol (libc, __readdir64, readdir64, GLIBC_2_2);
 
 #if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
 
-#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+#include <olddirent.h>
 
 #define __READDIR attribute_compat_text_section __old_readdir64
 #define __GETDENTS __old_getdents64
diff --git a/sysdeps/unix/sysv/linux/i386/readdir64_r.c b/sysdeps/unix/sysv/linux/i386/readdir64_r.c
index 344fd53..8c0262d 100644
--- a/sysdeps/unix/sysv/linux/i386/readdir64_r.c
+++ b/sysdeps/unix/sysv/linux/i386/readdir64_r.c
@@ -31,7 +31,7 @@  versioned_symbol (libc, __readdir64_r, readdir64_r, GLIBC_2_2);
 
 #if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
 
-#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+#include <olddirent.h>
 
 #define __READDIR_R attribute_compat_text_section __old_readdir64_r
 #define __GETDENTS __old_getdents64
diff --git a/sysdeps/unix/sysv/linux/i386/versionsort64.c b/sysdeps/unix/sysv/linux/i386/versionsort64.c
index 3e1c6ea..87f2f95 100644
--- a/sysdeps/unix/sysv/linux/i386/versionsort64.c
+++ b/sysdeps/unix/sysv/linux/i386/versionsort64.c
@@ -30,7 +30,7 @@  versioned_symbol (libc, __versionsort64, versionsort64, GLIBC_2_2);
 
 #if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
 
-#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+#include <olddirent.h>
 
 int
 __old_versionsort64 (const struct __old_dirent64 **a,
diff --git a/sysdeps/unix/sysv/linux/m68k/glob64.c b/sysdeps/unix/sysv/linux/m68k/glob64.c
deleted file mode 100644
index 82a9a29..0000000
--- a/sysdeps/unix/sysv/linux/m68k/glob64.c
+++ /dev/null
@@ -1 +0,0 @@ 
-#include <sysdeps/unix/sysv/linux/i386/glob64.c>
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c b/sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c
deleted file mode 100644
index 33918ea..0000000
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c
+++ /dev/null
@@ -1 +0,0 @@ 
-/* glob64 is in glob.c */
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/globfree64.c b/sysdeps/unix/sysv/linux/mips/mips64/n64/globfree64.c
deleted file mode 100644
index abc35fd..0000000
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/globfree64.c
+++ /dev/null
@@ -1 +0,0 @@ 
-/* glob64 is in globfree64.c */
diff --git a/sysdeps/unix/sysv/linux/i386/olddirent.h b/sysdeps/unix/sysv/linux/olddirent.h
similarity index 100%
rename from sysdeps/unix/sysv/linux/i386/olddirent.h
rename to sysdeps/unix/sysv/linux/olddirent.h
diff --git a/sysdeps/unix/sysv/linux/oldglob.c b/sysdeps/unix/sysv/linux/oldglob.c
index 8233e57..5402450 100644
--- a/sysdeps/unix/sysv/linux/oldglob.c
+++ b/sysdeps/unix/sysv/linux/oldglob.c
@@ -1,12 +1,13 @@ 
 #include <shlib-compat.h>
 
-#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
+#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) \
+    && !defined(GLOB_NO_OLD_VERSION)
 
 #include <dirent.h>
 #include <glob.h>
 #include <sys/stat.h>
 
-#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
+#include <olddirent.h>
 
 int __old_glob64 (const char *__pattern, int __flags,
 		  int (*__errfunc) (const char *, int),
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c b/sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c
deleted file mode 100644
index 82a9a29..0000000
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c
+++ /dev/null
@@ -1 +0,0 @@ 
-#include <sysdeps/unix/sysv/linux/i386/glob64.c>
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/glob64.c b/sysdeps/unix/sysv/linux/s390/s390-32/glob64.c
new file mode 100644
index 0000000..d220e22
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/glob64.c
@@ -0,0 +1,2 @@ 
+#define GLOB_NO_OLD_VERSION
+#include <sysdeps/unix/sysv/linux/glob64.c>
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c b/sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c
deleted file mode 100644
index 82a9a29..0000000
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c
+++ /dev/null
@@ -1 +0,0 @@ 
-#include <sysdeps/unix/sysv/linux/i386/glob64.c>
diff --git a/sysdeps/unix/sysv/linux/wordsize-64/glob64.c b/sysdeps/unix/sysv/linux/wordsize-64/glob64.c
deleted file mode 100644
index eab7703..0000000
--- a/sysdeps/unix/sysv/linux/wordsize-64/glob64.c
+++ /dev/null
@@ -1,2 +0,0 @@ 
-/* This file is here so sysdeps/gnu/glob64.c doesn't take precedence.  */
-#include <sysdeps/wordsize-64/glob64.c>
diff --git a/sysdeps/unix/sysv/linux/wordsize-64/globfree64.c b/sysdeps/unix/sysv/linux/wordsize-64/globfree64.c
deleted file mode 100644
index af035e1..0000000
--- a/sysdeps/unix/sysv/linux/wordsize-64/globfree64.c
+++ /dev/null
@@ -1,2 +0,0 @@ 
-/* This file is here so sysdeps/gnu/glob64.c doesn't take precedence.  */
-#include <sysdeps/wordsize-64/globfree64.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/glob.c b/sysdeps/unix/sysv/linux/x86_64/x32/glob.c
deleted file mode 100644
index e542747..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/x32/glob.c
+++ /dev/null
@@ -1 +0,0 @@ 
-#include <sysdeps/wordsize-64/glob.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/globfree.c b/sysdeps/unix/sysv/linux/x86_64/x32/globfree.c
deleted file mode 100644
index b76a761..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/x32/globfree.c
+++ /dev/null
@@ -1 +0,0 @@ 
-#include <sysdeps/wordsize-64/globfree.c>
diff --git a/sysdeps/wordsize-64/glob.c b/sysdeps/wordsize-64/glob.c
deleted file mode 100644
index 954e8d3..0000000
--- a/sysdeps/wordsize-64/glob.c
+++ /dev/null
@@ -1,6 +0,0 @@ 
-#define glob64 __no_glob64_decl
-#define globfree64 __no_globfree64_decl
-#include <posix/glob.c>
-#undef glob64
-#undef globfree64
-weak_alias (glob, glob64)
diff --git a/sysdeps/wordsize-64/glob64.c b/sysdeps/wordsize-64/glob64.c
deleted file mode 100644
index 33918ea..0000000
--- a/sysdeps/wordsize-64/glob64.c
+++ /dev/null
@@ -1 +0,0 @@ 
-/* glob64 is in glob.c */
diff --git a/sysdeps/wordsize-64/globfree64.c b/sysdeps/wordsize-64/globfree64.c
deleted file mode 100644
index a0f57ff..0000000
--- a/sysdeps/wordsize-64/globfree64.c
+++ /dev/null
@@ -1 +0,0 @@ 
-/* globfree64 is in globfree.c */