[v2,1/2] posix: Add compat glob symbol to not follow dangling symbols

Message ID 834f27ab-310d-c976-207e-683509a5eac1@linaro.org
State Dropped
Headers

Commit Message

Adhemerval Zanella Netto Sept. 19, 2017, 1:08 p.m. UTC
  On 18/09/2017 13:53, Paul Eggert wrote:
> I looked only at the posix/glob.c changes, since they're shared with Gnulib.
> 
> The macro GLOB_LSTAT_COMPAT has a confusing name. The name sounds like it involves glob using lstat. But the name really means "glob should not call lstat, to be compatible with older versions". I suggest renaming it to something like GLOB_NO_LSTAT to make this clearer.
> 
> Why have a named type 'union glob_stat'? It's used only once, and the old code didn't give it a name, so why give it a name now?
> 
>> +  return __builtin_expect (flags & GLOB_ALTDIRFUNC, 0)                         +/* Use on glob-lstat-compat.c to provide a compat symbol which does not        +   use lstat / gl_lstat.  */                                                   +#ifdef GLOB_LSTAT_COMPAT                                                       +         ? (*pglob->gl_stat) (fullname, &ust.st)                               +         : __stat64 (fullname, &ust.st64);                                     +#else                                                                          +         ? (*pglob->gl_lstat) (fullname, &ust.st)                              +         : __lstat64 (fullname, &ust.st64);                                    +#endif                                                                         
> 
> Please reformulate so that the #ifdef does not appear within a statement or expression; it's confusing to have #ifs containing just parts of statements.
> 
> A minor point: there is no need for the '*' prefix operator; the use of '*' in this code goes back to pre-C89 compilers and we don't need to worry about that any more.
> 
> Perhaps something like the following instead? It addresses the above points.
> 
> #ifdef GLOB_NO_STAT
> # define GL_LSTAT gl_stat
> # define LSTAT64 __stat64
> #else
> # define GL_LSTAT gl_lstat
> # define LSTAT64 __lstat64
> #endif
> 
> ...
> 
>   union
>   {
>     struct stat st;
>     struct_stat64 st64;
>   } ust;
>   return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
>           ? pglob->GL_LSTAT (fullname, &ust.st)
>           : LSTAT64 (fullname, &ust.st64));

Thanks for the reviews, all points addresses in the patch below:

---

	* include/gnu-versions.h (_GNU_GLOB_INTERFACE_VERSION): Increase
	version to 2.
	* posix/Makefile (routines): Add glob-lstat-compat and
	glob64-lstat-compat.
	* posix/Versions (GLIBC_2.27, glob, glob64): Add symbol version.
	* posix/glob-lstat-compat.c: New file.
	* posix/glob64-lstat-compat.c: Likewise.
	* posix/tst-glob_lstat_compat.c: Likewise.
	* sysdeps/unix/sysv/linux/glob-lstat-compat.c: Likewise.
	* sysdeps/unix/sysv/linux/alpha/glob-lstat-compat.c: Likewise.
	* sysdeps/unix/sysv/linux/glob64-lstat-compat.c: Likewise.
	* sysdeps/unix/sysv/linux/alpha/glob.c: Remove file.
	* posix/glob.c (glob_lstat): New function.
	(glob): Rename to __glob and add versioned symbol to 2.27.
	(glob_in_dir): Use glob_lstat.
	* posix/glob64.c (glob64): Add GLOB_ATTRIBUTE.
	* sysdeps/unix/sysv/linux/arm/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/glob.c (glob): Add versioned symbol for
	2.27.
	* sysdeps/unix/sysv/linux/glob64.c (glob64): Likewise.
	* sysdeps/unix/sysv/linux/oldglob.c (GLOB_NO_LSTAT): Define.
	* sysdeps/unix/sysv/linux/alpha/oldglob.c (__old_glob): Do not use
	gl_lstat on glob call.
	* sysdeps/unix/sysv/linux/aarch64/libc.abilist: Add GLIBC_2.27 glob
	and glob64 symbols.
	* sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/hppa/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/i386/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/microblaze/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/nios2/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist:
	Likewise.
	* sysdeps/unix/linux/powerpc/powerpc32/nofpu/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sh/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist: Likewise.

---

-- 
2.7.4
  

Comments

Adhemerval Zanella Netto Sept. 22, 2017, 1:02 p.m. UTC | #1
On 19/09/2017 10:08, Adhemerval Zanella wrote:
> 

> 

> On 18/09/2017 13:53, Paul Eggert wrote:

>> I looked only at the posix/glob.c changes, since they're shared with Gnulib.

>>

>> The macro GLOB_LSTAT_COMPAT has a confusing name. The name sounds like it involves glob using lstat. But the name really means "glob should not call lstat, to be compatible with older versions". I suggest renaming it to something like GLOB_NO_LSTAT to make this clearer.

>>

>> Why have a named type 'union glob_stat'? It's used only once, and the old code didn't give it a name, so why give it a name now?

>>

>>> +  return __builtin_expect (flags & GLOB_ALTDIRFUNC, 0)                         +/* Use on glob-lstat-compat.c to provide a compat symbol which does not        +   use lstat / gl_lstat.  */                                                   +#ifdef GLOB_LSTAT_COMPAT                                                       +         ? (*pglob->gl_stat) (fullname, &ust.st)                               +         : __stat64 (fullname, &ust.st64);                                     +#else                                                                          +         ? (*pglob->gl_lstat) (fullname, &ust.st)                              +         : __lstat64 (fullname, &ust.st64);                                    +#endif                                                                         

>>

>> Please reformulate so that the #ifdef does not appear within a statement or expression; it's confusing to have #ifs containing just parts of statements.

>>

>> A minor point: there is no need for the '*' prefix operator; the use of '*' in this code goes back to pre-C89 compilers and we don't need to worry about that any more.

>>

>> Perhaps something like the following instead? It addresses the above points.

>>

>> #ifdef GLOB_NO_STAT

>> # define GL_LSTAT gl_stat

>> # define LSTAT64 __stat64

>> #else

>> # define GL_LSTAT gl_lstat

>> # define LSTAT64 __lstat64

>> #endif

>>

>> ...

>>

>>   union

>>   {

>>     struct stat st;

>>     struct_stat64 st64;

>>   } ust;

>>   return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)

>>           ? pglob->GL_LSTAT (fullname, &ust.st)

>>           : LSTAT64 (fullname, &ust.st64));

> 

> Thanks for the reviews, all points addresses in the patch below:


Paul, any objection to this version?

> 

> ---

> 

> 	* include/gnu-versions.h (_GNU_GLOB_INTERFACE_VERSION): Increase

> 	version to 2.

> 	* posix/Makefile (routines): Add glob-lstat-compat and

> 	glob64-lstat-compat.

> 	* posix/Versions (GLIBC_2.27, glob, glob64): Add symbol version.

> 	* posix/glob-lstat-compat.c: New file.

> 	* posix/glob64-lstat-compat.c: Likewise.

> 	* posix/tst-glob_lstat_compat.c: Likewise.

> 	* sysdeps/unix/sysv/linux/glob-lstat-compat.c: Likewise.

> 	* sysdeps/unix/sysv/linux/alpha/glob-lstat-compat.c: Likewise.

> 	* sysdeps/unix/sysv/linux/glob64-lstat-compat.c: Likewise.

> 	* sysdeps/unix/sysv/linux/alpha/glob.c: Remove file.

> 	* posix/glob.c (glob_lstat): New function.

> 	(glob): Rename to __glob and add versioned symbol to 2.27.

> 	(glob_in_dir): Use glob_lstat.

> 	* posix/glob64.c (glob64): Add GLOB_ATTRIBUTE.

> 	* sysdeps/unix/sysv/linux/arm/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/glob.c (glob): Add versioned symbol for

> 	2.27.

> 	* sysdeps/unix/sysv/linux/glob64.c (glob64): Likewise.

> 	* sysdeps/unix/sysv/linux/oldglob.c (GLOB_NO_LSTAT): Define.

> 	* sysdeps/unix/sysv/linux/alpha/oldglob.c (__old_glob): Do not use

> 	gl_lstat on glob call.

> 	* sysdeps/unix/sysv/linux/aarch64/libc.abilist: Add GLIBC_2.27 glob

> 	and glob64 symbols.

> 	* sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/hppa/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/i386/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/microblaze/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/nios2/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist:

> 	Likewise.

> 	* sysdeps/unix/linux/powerpc/powerpc32/nofpu/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/sh/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise.

> 	* sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist: Likewise.

> 

> ---

> 

> diff --git a/include/gnu-versions.h b/include/gnu-versions.h

> index 40f2bfc..ce26254 100644

> --- a/include/gnu-versions.h

> +++ b/include/gnu-versions.h

> @@ -45,7 +45,7 @@

>  

>  #define _GNU_OBSTACK_INTERFACE_VERSION	1 /* vs malloc/obstack.c */

>  #define _GNU_REGEX_INTERFACE_VERSION	1 /* vs posix/regex.c */

> -#define _GNU_GLOB_INTERFACE_VERSION	1 /* vs posix/glob.c */

> +#define _GNU_GLOB_INTERFACE_VERSION	2 /* vs posix/glob.c */

>  #define _GNU_GETOPT_INTERFACE_VERSION	2 /* vs posix/getopt.c and

>  					     posix/getopt1.c */

>  

> diff --git a/posix/Makefile b/posix/Makefile

> index 7188cba..203555a 100644

> --- a/posix/Makefile

> +++ b/posix/Makefile

> @@ -46,6 +46,7 @@ routines :=								      \

>  	getresuid getresgid setresuid setresgid				      \

>  	pathconf sysconf fpathconf					      \

>  	glob glob64 globfree globfree64 glob_pattern_p fnmatch regex	      \

> +	glob-lstat-compat glob64-lstat-compat				      \

>  	confstr								      \

>  	getopt getopt1 							      \

>  	sched_setp sched_getp sched_sets sched_gets sched_yield sched_primax  \

> @@ -95,7 +96,8 @@ tests		:= test-errno tstgetopt testfnm runtests runptests \

>  		   tst-posix_fadvise tst-posix_fadvise64 \

>  		   tst-sysconf-empty-chroot tst-glob_symlinks

>  tests-internal	:= bug-regex5 bug-regex20 bug-regex33 \

> -		   tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3

> +		   tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 \

> +		   tst-glob_lstat_compat

>  xtests		:= bug-ga2

>  ifeq (yes,$(build-shared))

>  test-srcs	:= globtest

> diff --git a/posix/Versions b/posix/Versions

> index bb481a5..65e9687 100644

> --- a/posix/Versions

> +++ b/posix/Versions

> @@ -134,6 +134,9 @@ libc {

>    GLIBC_2.11 {

>      execvpe;

>    }

> +  GLIBC_2.27 {

> +    glob; glob64;

> +  }

>    GLIBC_PRIVATE {

>      __libc_fork; __libc_pread; __libc_pwrite;

>    }

> diff --git a/posix/glob-lstat-compat.c b/posix/glob-lstat-compat.c

> new file mode 100644

> index 0000000..e30d343

> --- /dev/null

> +++ b/posix/glob-lstat-compat.c

> @@ -0,0 +1,36 @@

> +/* Compat glob which does not use gl_lstat for GLOB_ALTDIRFUNC.

> +   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 <shlib-compat.h>

> +

> +#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_27)

> +

> +# include <glob.h>

> +

> +# define __glob(pattern, flags, errfunc, pglob) \

> +  __glob_lstat_compat (pattern, flags, errfunc, pglob)

> +

> +# define GLOB_ATTRIBUTE attribute_compat_text_section

> +

> +/* Avoid calling gl_lstat with GLOB_ALTDIRFUNC.  */

> +# define GLOB_NO_LSTAT

> +

> +# include <posix/glob.c>

> +

> +compat_symbol (libc, __glob_lstat_compat, glob, GLIBC_2_0);

> +#endif

> diff --git a/posix/glob.c b/posix/glob.c

> index c699177..795cebe 100644

> --- a/posix/glob.c

> +++ b/posix/glob.c

> @@ -57,7 +57,9 @@

>  # endif

>  # define struct_stat64		struct stat64

>  # define FLEXIBLE_ARRAY_MEMBER

> +# include <shlib-compat.h>

>  #else /* !_LIBC */

> +# define __glob                 glob

>  # define __getlogin_r(buf, len) getlogin_r (buf, len)

>  # define __lstat64(fname, buf)  lstat (fname, buf)

>  # define __stat64(fname, buf)   stat (fname, buf)

> @@ -179,6 +181,29 @@ convert_dirent64 (const struct dirent64 *source)

>      ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0)

>  #endif

>  

> +static int

> +glob_lstat (glob_t *pglob, int flags, const char *fullname)

> +{

> +/* Use on glob-lstat-compat.c to provide a compat symbol which does not

> +   use lstat / gl_lstat.  */

> +#ifdef GLOB_NO_LSTAT

> +# define GL_LSTAT gl_stat

> +# define LSTAT64 __stat64

> +#else

> +# define GL_LSTAT gl_lstat

> +# define LSTAT64 __lstat64

> +#endif

> +

> +  union

> +  {

> +    struct stat st;

> +    struct_stat64 st64;

> +  } ust;

> +  return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)

> +          ? pglob->GL_LSTAT (fullname, &ust.st)

> +          : LSTAT64 (fullname, &ust.st64));

> +}

> +

>  /* Set *R = A + B.  Return true if the answer is mathematically

>     incorrect due to overflow; in this case, *R is the low order

>     bits of the correct answer.  */

> @@ -248,6 +273,9 @@ next_brace_sub (const char *cp, int flags)

>    return *cp != '\0' ? cp : NULL;

>  }

>  

> +#ifndef GLOB_ATTRIBUTE

> +# define GLOB_ATTRIBUTE

> +#endif

>  

>  /* Do glob searching for PATTERN, placing results in PGLOB.

>     The bits defined above may be set in FLAGS.

> @@ -258,11 +286,9 @@ next_brace_sub (const char *cp, int flags)

>     If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.

>     Otherwise, 'glob' returns zero.  */

>  int

> -#ifdef GLOB_ATTRIBUTE

>  GLOB_ATTRIBUTE

> -#endif

> -glob (const char *pattern, int flags, int (*errfunc) (const char *, int),

> -      glob_t *pglob)

> +__glob (const char *pattern, int flags, int (*errfunc) (const char *, int),

> +	glob_t *pglob)

>  {

>    const char *filename;

>    char *dirname = NULL;

> @@ -406,9 +432,9 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),

>  	      /* Construct the new glob expression.  */

>  	      mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);

>  

> -	      result = glob (onealt,

> -			     ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))

> -			      | GLOB_APPEND), errfunc, pglob);

> +	      result = __glob (onealt,

> +			       ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))

> +			       | GLOB_APPEND), errfunc, pglob);

>  

>  	      /* If we got an error, return it.  */

>  	      if (result && result != GLOB_NOMATCH)

> @@ -557,7 +583,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),

>  		  flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);

>  		}

>  	    }

> -	  int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);

> +	  int val = __glob (dirname, flags | GLOB_MARK, errfunc, pglob);

>  	  if (val == 0)

>  	    pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)

>  			       | (flags & GLOB_MARK));

> @@ -931,11 +957,10 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),

>  	  dirs.gl_lstat = pglob->gl_lstat;

>  	}

>  

> -      status = glob (dirname,

> -		     ((flags & (GLOB_ERR | GLOB_NOESCAPE

> -				| GLOB_ALTDIRFUNC))

> -		      | GLOB_NOSORT | GLOB_ONLYDIR),

> -		     errfunc, &dirs);

> +      status = __glob (dirname,

> +		       ((flags & (GLOB_ERR | GLOB_NOESCAPE | GLOB_ALTDIRFUNC))

> +		       | GLOB_NOSORT | GLOB_ONLYDIR),

> +		       errfunc, &dirs);

>        if (status != 0)

>  	{

>  	  if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH)

> @@ -1133,8 +1158,9 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int),

>  

>    return retval;

>  }

> -#if defined _LIBC && !defined glob

> -libc_hidden_def (glob)

> +#if defined _LIBC && !defined __glob

> +versioned_symbol (libc, __glob, glob, GLIBC_2_27);

> +libc_hidden_ver (__glob, glob)

>  #endif

>  

>  

> @@ -1250,11 +1276,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags,

>      }

>    else if (meta == GLOBPAT_NONE)

>      {

> -      union

> -      {

> -	struct stat st;

> -	struct_stat64 st64;

> -      } ust;

>        size_t patlen = strlen (pattern);

>        size_t fullsize;

>        bool alloca_fullname

> @@ -1273,10 +1294,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags,

>        mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),

>  			"/", 1),

>  	       pattern, patlen + 1);

> -      if (((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)

> -	   ? (*pglob->gl_lstat) (fullname, &ust.st)

> -	    : __lstat64 (fullname, &ust.st64))

> -	   == 0)

> +      if (glob_lstat (pglob, flags, fullname) == 0

>  	  || errno == EOVERFLOW)

>  	/* We found this file to be existing.  Now tell the rest

>  	   of the function to copy this name into the result.  */

> diff --git a/posix/glob64-lstat-compat.c b/posix/glob64-lstat-compat.c

> new file mode 100644

> index 0000000..1fabf86

> --- /dev/null

> +++ b/posix/glob64-lstat-compat.c

> @@ -0,0 +1,36 @@

> +/* Compat glob which does not use gl_lstat for GLOB_ALTDIRFUNC.

> +   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 <shlib-compat.h>

> +

> +#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_27)

> +

> +# include <glob.h>

> +

> +# define glob(pattern, flags, errfunc, pglob) \

> +  __glob64_lstat_compat (pattern, flags, errfunc, pglob)

> +

> +# define GLOB_ATTRIBUTE attribute_compat_text_section

> +

> +/* Avoid calling gl_lstat with GLOB_ALTDIRFUNC.  */

> +# define GLOB_NO_LSTAT

> +

> +# include <posix/glob64.c>

> +

> +compat_symbol (libc, __glob64_lstat_compat, glob64, GLIBC_2_0);

> +#endif

> diff --git a/posix/glob64.c b/posix/glob64.c

> index a515a1c..ee7ef84 100644

> --- a/posix/glob64.c

> +++ b/posix/glob64.c

> @@ -20,6 +20,10 @@

>  #include <glob.h>

>  #include <errno.h>

>  

> +#ifdef GLOB_ATTRIBUTE

> +# define GLOB_ATTRIBUTE

> +#endif

> +

>  /* Do glob searching for PATTERN, placing results in PGLOB.

>     The bits defined above may be set in FLAGS.

>     If a directory cannot be opened or read and ERRFUNC is not nil,

> @@ -29,6 +33,7 @@

>     If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.

>     Otherwise, `glob' returns zero.  */

>  int

> +GLOB_ATTRIBUTE

>  glob64 (const char *pattern, int flags,

>  	int (*errfunc) (const char *, int), glob64_t *pglob)

>  {

> diff --git a/posix/tst-glob_lstat_compat.c b/posix/tst-glob_lstat_compat.c

> new file mode 100644

> index 0000000..c5b9a27

> --- /dev/null

> +++ b/posix/tst-glob_lstat_compat.c

> @@ -0,0 +1,263 @@

> +/* Test glob compat symbol which avoid call GLOB_ALTDIRFUNC/gl_lstat.

> +   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 <glob.h>

> +#include <errno.h>

> +#include <stdlib.h>

> +#include <string.h>

> +#include <sys/types.h>

> +#include <dirent.h>

> +#include <sys/types.h>

> +#include <sys/stat.h>

> +#include <unistd.h>

> +

> +#include <stdio.h>

> +

> +#include <shlib-compat.h>

> +#include <support/check.h>

> +#include <support/temp_file.h>

> +

> +#if TEST_COMPAT (libc, GLIBC_2_0, GLIBC_2_27)

> +

> +__typeof (glob) glob;

> +compat_symbol_reference (libc, glob, glob, GLIBC_2_0);

> +

> +/* Compat glob should not call gl_lstat since for some old binaries it

> +   might be unitialized (for instance GNUmake).  Check if it is indeed

> +   not called.  */

> +static bool stat_called;

> +static bool lstat_called;

> +

> +static struct

> +{

> +  const char *name;

> +  int level;

> +  int type;

> +} filesystem[] =

> +{

> +  { ".", 1, DT_DIR },

> +  { "..", 1, DT_DIR },

> +  { "dir1lev1", 1, DT_UNKNOWN },

> +    { ".", 2, DT_DIR },

> +    { "..", 2, DT_DIR },

> +    { "file1lev2", 2, DT_REG },

> +    { "file2lev2", 2, DT_REG },

> +};

> +static const size_t nfiles = sizeof (filesystem) / sizeof (filesystem [0]);

> +

> +typedef struct

> +{

> +  int level;

> +  int idx;

> +  struct dirent d;

> +  char room_for_dirent[NAME_MAX];

> +} my_DIR;

> +

> +static long int

> +find_file (const char *s)

> +{

> +  int level = 1;

> +  long int idx = 0;

> +

> +  while (s[0] == '/')

> +    {

> +      if (s[1] == '\0')

> +	{

> +	  s = ".";

> +	  break;

> +	}

> +      ++s;

> +    }

> +

> +  if (strcmp (s, ".") == 0)

> +    return 0;

> +

> +  if (s[0] == '.' && s[1] == '/')

> +    s += 2;

> +

> +  while (*s != '\0')

> +    {

> +      char *endp = strchrnul (s, '/');

> +

> +      while (idx < nfiles && filesystem[idx].level >= level)

> +	{

> +	  if (filesystem[idx].level == level

> +	      && memcmp (s, filesystem[idx].name, endp - s) == 0

> +	      && filesystem[idx].name[endp - s] == '\0')

> +	    break;

> +	  ++idx;

> +	}

> +

> +      if (idx == nfiles || filesystem[idx].level < level)

> +	{

> +	  errno = ENOENT;

> +	  return -1;

> +	}

> +

> +      if (*endp == '\0')

> +	return idx + 1;

> +

> +      if (filesystem[idx].type != DT_DIR

> +	  && (idx + 1 >= nfiles

> +	      || filesystem[idx].level >= filesystem[idx + 1].level))

> +	{

> +	  errno = ENOTDIR;

> +	  return -1;

> +	}

> +

> +      ++idx;

> +

> +      s = endp + 1;

> +      ++level;

> +    }

> +

> +  errno = ENOENT;

> +  return -1;

> +}

> +

> +static void *

> +my_opendir (const char *s)

> +{

> +  long int idx = find_file (s);

> +  if (idx == -1 || filesystem[idx].type != DT_DIR)

> +    return NULL;

> +

> +  my_DIR *dir = malloc (sizeof (my_DIR));

> +  if (dir == NULL)

> +    FAIL_EXIT1 ("cannot allocate directory handle");

> +

> +  dir->level = filesystem[idx].level;

> +  dir->idx = idx;

> +

> +  return dir;

> +}

> +

> +static struct dirent *

> +my_readdir (void *gdir)

> +{

> +  my_DIR *dir = gdir;

> +

> +  if (dir->idx == -1)

> +    return NULL;

> +

> +  while (dir->idx < nfiles && filesystem[dir->idx].level > dir->level)

> +    ++dir->idx;

> +

> +  if (dir->idx == nfiles || filesystem[dir->idx].level < dir->level)

> +    {

> +      dir->idx = -1;

> +      return NULL;

> +    }

> +

> +  dir->d.d_ino = 1;		/* glob should not skip this entry.  */

> +

> +#ifdef _DIRENT_HAVE_D_TYPE

> +  dir->d.d_type = filesystem[dir->idx].type;

> +#endif

> +

> +  strcpy (dir->d.d_name, filesystem[dir->idx].name);

> +

> +  ++dir->idx;

> +

> +  return &dir->d;

> +}

> +

> +static void

> +my_closedir (void *dir)

> +{

> +  free (dir);

> +}

> +

> +static int

> +my_stat (const char *name, struct stat *st)

> +{

> +  stat_called = true;

> +

> +  long int idx = find_file (name);

> +  if (idx == -1)

> +    return -1;

> +

> +  memset (st, '\0', sizeof (*st));

> +

> +  if (filesystem[idx].type == DT_UNKNOWN)

> +    st->st_mode = DTTOIF (idx + 1 < nfiles

> +			  && filesystem[idx].level < filesystem[idx + 1].level

> +			  ? DT_DIR : DT_REG) | 0777;

> +  else

> +    st->st_mode = DTTOIF (filesystem[idx].type) | 0777;

> +  return 0;

> +}

> +

> +static int

> +my_lstat (const char *name, struct stat *st)

> +{

> +  lstat_called = true;

> +

> +  long int idx = find_file (name);

> +  if (idx == -1)

> +    return -1;

> +

> +  memset (st, '\0', sizeof (*st));

> +

> +  if (filesystem[idx].type == DT_UNKNOWN)

> +    st->st_mode = DTTOIF (idx + 1 < nfiles

> +			  && filesystem[idx].level < filesystem[idx + 1].level

> +			  ? DT_DIR : DT_REG) | 0777;

> +  else

> +    st->st_mode = DTTOIF (filesystem[idx].type) | 0777;

> +  return 0;

> +}

> +

> +static int

> +do_test (void)

> +{

> +  glob_t gl;

> +

> +  memset (&gl, '\0', sizeof (gl));

> +

> +  gl.gl_closedir = my_closedir;

> +  gl.gl_readdir = my_readdir;

> +  gl.gl_opendir = my_opendir;

> +  gl.gl_lstat = my_lstat;

> +  gl.gl_stat = my_stat;

> +

> +  int flags = GLOB_ALTDIRFUNC;

> +

> +  stat_called = false;

> +  lstat_called = false;

> +

> +  TEST_VERIFY_EXIT (glob ("*/file1lev2", flags, NULL, &gl) == 0);

> +  TEST_VERIFY_EXIT (gl.gl_pathc == 1);

> +  TEST_VERIFY_EXIT (strcmp (gl.gl_pathv[0], "dir1lev1/file1lev2") == 0);

> +

> +  TEST_VERIFY_EXIT (stat_called == true);

> +  TEST_VERIFY_EXIT (lstat_called == false);

> +

> +  return 0;

> +}

> +

> +#else /* TEST_COMPAT (libc, GLIBC_2_0, GLIBC_2_27)  */

> +

> +static int

> +do_test (void)

> +{ 

> +  return 77;

> +}

> +#endif

> +

> +#include <support/test-driver.c>

> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist

> index 81e4fe9..e7438c5 100644

> --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist

> @@ -2103,3 +2103,6 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

> diff --git a/sysdeps/unix/sysv/linux/alpha/glob-lstat-compat.c b/sysdeps/unix/sysv/linux/alpha/glob-lstat-compat.c

> new file mode 100644

> index 0000000..a76471d

> --- /dev/null

> +++ b/sysdeps/unix/sysv/linux/alpha/glob-lstat-compat.c

> @@ -0,0 +1,2 @@

> +#define GLOB_LSTAT_VERSION GLIBC_2_1

> +#include <sysdeps/unix/sysv/linux/glob-lstat-compat.c>

> diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist

> index fab7331..4836ea0 100644

> --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist

> @@ -2014,6 +2014,9 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.3 GLIBC_2.3 A

>  GLIBC_2.3 __ctype_b_loc F

>  GLIBC_2.3 __ctype_tolower_loc F

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

> index 988c92b..b54624c 100644

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

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

> @@ -59,7 +59,9 @@ __old_glob (const char *pattern, int flags,

>    correct.gl_closedir = pglob->gl_closedir;

>    correct.gl_readdir = pglob->gl_readdir;

>    correct.gl_opendir = pglob->gl_opendir;

> -  correct.gl_lstat = pglob->gl_lstat;

> +  /* Set gl_lstat and gl_stat for both gl_stat for compatibility with old

> +     implementation that did not follow dangling symlinks.  */

> +  correct.gl_lstat = pglob->gl_stat;

>    correct.gl_stat = pglob->gl_stat;

>  

>    result = glob (pattern, flags, errfunc, &correct);

> @@ -72,7 +74,7 @@ __old_glob (const char *pattern, int flags,

>    pglob->gl_closedir = correct.gl_closedir;

>    pglob->gl_readdir = correct.gl_readdir;

>    pglob->gl_opendir = correct.gl_opendir;

> -  pglob->gl_lstat = correct.gl_lstat;

> +  /* Only need to restore gl_stat.  */

>    pglob->gl_stat = correct.gl_stat;

>  

>    return result;

> diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist

> index d2a206a..5b70e1b 100644

> --- a/sysdeps/unix/sysv/linux/arm/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/arm/libc.abilist

> @@ -104,6 +104,9 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.4 GLIBC_2.4 A

>  GLIBC_2.4 _Exit F

>  GLIBC_2.4 _IO_2_1_stderr_ D 0xa0

> diff --git a/sysdeps/unix/sysv/linux/alpha/glob.c b/sysdeps/unix/sysv/linux/glob-lstat-compat.c

> similarity index 50%

> rename from sysdeps/unix/sysv/linux/alpha/glob.c

> rename to sysdeps/unix/sysv/linux/glob-lstat-compat.c

> index 1b813c1..9867e2f 100644

> --- a/sysdeps/unix/sysv/linux/alpha/glob.c

> +++ b/sysdeps/unix/sysv/linux/glob-lstat-compat.c

> @@ -1,4 +1,6 @@

> -/* Copyright (C) 1998-2017 Free Software Foundation, Inc.

> +/* Compat glob which does not use gl_lstat for GLOB_ALTDIRFUNC.

> +   Linux version which handles LFS when required.

> +   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

> @@ -12,36 +14,34 @@

>     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

> +   License along with the GNU C Library; if not, see

>     <http://www.gnu.org/licenses/>.  */

>  

> -#define glob64 __no_glob64_decl

> -#define globfree64 __no_globfree64_decl

> -

> -#include <sys/types.h>

> -#include <glob.h>

> +#include <sys/stat.h>

> +#include <kernel_stat.h>

>  #include <shlib-compat.h>

>  

> -/* For Linux/Alpha we have to make the glob symbols versioned.  */

> -#define glob(pattern, flags, errfunc, pglob) \

> -  __new_glob (pattern, flags, errfunc, pglob)

> -#define globfree(pglob) \

> -  __new_globfree (pglob)

> +#define glob64 __no_glob64_decl

> +#include <glob.h>

> +#undef glob64

>  

> -/* We need prototypes for these new names.  */

> -extern int __new_glob (const char *__pattern, int __flags,

> -		       int (*__errfunc) (const char *, int),

> -		       glob_t *__pglob);

> -extern void __new_globfree (glob_t *__pglob);

> +#define __glob __glob_lstat_compat

>  

> -#include <posix/glob.c>

> +#define GLOB_ATTRIBUTE attribute_compat_text_section

>  

> -#undef glob

> -#undef globfree

> -#undef glob64

> -#undef globfree64

> +/* Avoid calling gl_lstat with GLOB_ALTDIRFUNC.  */

> +#define GLOB_NO_LSTAT

>  

> -versioned_symbol (libc, __new_glob, glob, GLIBC_2_1);

> -libc_hidden_ver (__new_glob, glob)

> +#include <posix/glob.c>

>  

> -weak_alias (__new_glob, glob64)

> +#ifndef GLOB_LSTAT_VERSION

> +# define GLOB_LSTAT_VERSION GLIBC_2_0

> +#endif

> +

> +#if SHLIB_COMPAT(libc, GLOB_LSTAT_VERSION, GLIBC_2_27)

> +compat_symbol (libc, __glob_lstat_compat, glob, GLOB_LSTAT_VERSION);

> +# if XSTAT_IS_XSTAT64

> +strong_alias (__glob_lstat_compat, __glob64_lstat_compat)

> +compat_symbol (libc, __glob64_lstat_compat, glob64, GLOB_LSTAT_VERSION);

> +# endif

> +#endif

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

> index 057ae7f..e354799 100644

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

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

> @@ -20,9 +20,12 @@

>  #include <kernel_stat.h>

>  

>  #define glob64 __no_glob64_decl

> +#define __glob64 __no___glob64_decl

>  #include <posix/glob.c>

>  #undef glob64

> +#undef __glob64

>  

>  #if XSTAT_IS_XSTAT64

> -weak_alias (glob, glob64)

> +strong_alias (__glob, __glob64)

> +versioned_symbol (libc, __glob64, glob64, GLIBC_2_27);

>  #endif

> diff --git a/sysdeps/unix/sysv/linux/glob64-lstat-compat.c b/sysdeps/unix/sysv/linux/glob64-lstat-compat.c

> new file mode 100644

> index 0000000..f4e468d

> --- /dev/null

> +++ b/sysdeps/unix/sysv/linux/glob64-lstat-compat.c

> @@ -0,0 +1,51 @@

> +/* Compat glob which does not use gl_lstat for GLOB_ALTDIRFUNC.

> +   Linux version which handles LFS when required.

> +   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>

> +# include <dirent.h>

> +# include <sys/stat.h>

> +# include <shlib-compat.h>

> +

> +# define dirent dirent64

> +# define __readdir(dirp) __readdir64 (dirp)

> +

> +# define glob_t glob64_t

> +# define __glob __glob64_lstat_compat

> +# define globfree globfree64

> +

> +# undef stat

> +# define stat stat64

> +

> +# define COMPILE_GLOB64	1

> +

> +# define GLOB_ATTRIBUTE attribute_compat_text_section

> +

> +/* Avoid calling gl_lstat with GLOB_ALTDIRFUNC.  */

> +# define GLOB_NO_LSTAT

> +

> +# include <posix/glob.c>

> +

> +# if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_27)

> +compat_symbol (libc, __glob64_lstat_compat, glob64, GLIBC_2_2);

> +# endif

> +#endif /* XSTAT_IS_XSTAT64  */

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

> index 428bbac..0189d1c 100644

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

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

> @@ -28,8 +28,7 @@

>  # define __readdir(dirp) __readdir64 (dirp)

>  

>  # define glob_t glob64_t

> -# define glob(pattern, flags, errfunc, pglob) \

> -  __glob64 (pattern, flags, errfunc, pglob)

> +# define __glob __glob64

>  # define globfree(pglob) globfree64 (pglob)

>  

>  # undef stat

> @@ -39,13 +38,13 @@

>  

>  # include <posix/glob.c>

>  

> -# include "shlib-compat.h"

> +# 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);

> +versioned_symbol (libc, __glob64, glob64, GLIBC_2_27);

>  libc_hidden_ver (__glob64, glob64)

>  # endif

>  #endif /* XSTAT_IS_XSTAT64  */

> diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist

> index 24bb730..6a2500a 100644

> --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist

> @@ -1868,6 +1868,9 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.3 GLIBC_2.3 A

>  GLIBC_2.3 __ctype_b_loc F

>  GLIBC_2.3 __ctype_tolower_loc F

> diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist

> index 12e77bd..9ab4e36 100644

> --- a/sysdeps/unix/sysv/linux/i386/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist

> @@ -2033,6 +2033,9 @@ GLIBC_2.26 strtof128 F

>  GLIBC_2.26 strtof128_l F

>  GLIBC_2.26 wcstof128 F

>  GLIBC_2.26 wcstof128_l F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.3 GLIBC_2.3 A

>  GLIBC_2.3 __ctype_b_loc F

>  GLIBC_2.3 __ctype_tolower_loc F

> diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist

> index 62b67b8..81bb623 100644

> --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist

> @@ -1897,6 +1897,9 @@ GLIBC_2.26 strtof128 F

>  GLIBC_2.26 strtof128_l F

>  GLIBC_2.26 wcstof128 F

>  GLIBC_2.26 wcstof128_l F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.3 GLIBC_2.3 A

>  GLIBC_2.3 __ctype_b_loc F

>  GLIBC_2.3 __ctype_tolower_loc F

> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist

> index b594ebd..5a33b57 100644

> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist

> @@ -105,6 +105,9 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.4 GLIBC_2.4 A

>  GLIBC_2.4 _Exit F

>  GLIBC_2.4 _IO_2_1_stderr_ D 0x98

> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist

> index a36739d..50a86e7 100644

> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist

> @@ -1982,6 +1982,9 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.3 GLIBC_2.3 A

>  GLIBC_2.3 __ctype_b_loc F

>  GLIBC_2.3 __ctype_tolower_loc F

> diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist

> index 16aa254..250ef30 100644

> --- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist

> @@ -2103,3 +2103,6 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist

> index 907ab33..87a1dc4 100644

> --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist

> @@ -1957,6 +1957,9 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.3 GLIBC_2.3 A

>  GLIBC_2.3 __ctype_b_loc F

>  GLIBC_2.3 __ctype_tolower_loc F

> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist

> index 36ee235..f2b35f2 100644

> --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist

> @@ -1955,6 +1955,9 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.3 GLIBC_2.3 A

>  GLIBC_2.3 __ctype_b_loc F

>  GLIBC_2.3 __ctype_tolower_loc F

> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist

> index 783aa73..e119842 100644

> --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist

> @@ -1953,6 +1953,9 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.3 GLIBC_2.3 A

>  GLIBC_2.3 __ctype_b_loc F

>  GLIBC_2.3 __ctype_tolower_loc F

> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist

> index e1275df..67f10f5 100644

> --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist

> @@ -1948,6 +1948,9 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.3 GLIBC_2.3 A

>  GLIBC_2.3 __ctype_b_loc F

>  GLIBC_2.3 __ctype_tolower_loc F

> diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist

> index be25228..c599dd9 100644

> --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist

> @@ -2144,3 +2144,6 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

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

> index 5402450..a034c2d 100644

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

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

> @@ -21,7 +21,7 @@ libc_hidden_proto (__old_glob64);

>  #define __readdir(dirp) __old_readdir64 (dirp)

>  

>  #define glob_t glob64_t

> -#define glob(pattern, flags, errfunc, pglob) \

> +#define __glob(pattern, flags, errfunc, pglob) \

>    __old_glob64 (pattern, flags, errfunc, pglob)

>  #define globfree(pglob) globfree64(pglob)

>  

> @@ -33,6 +33,9 @@ libc_hidden_proto (__old_glob64);

>  #undef __stat

>  #define __stat(file, buf) __xstat64 (_STAT_VER, file, buf)

>  

> +/* Avoid calling gl_lstat with GLOB_ALTDIRFUNC.  */

> +#define GLOB_NO_LSTAT

> +

>  #define GLOB_ATTRIBUTE attribute_compat_text_section

>  

>  #include <posix/glob.c>

> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist

> index e213895..385409a 100644

> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist

> @@ -1986,6 +1986,9 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.3 GLIBC_2.3 A

>  GLIBC_2.3 __ctype_b_loc F

>  GLIBC_2.3 __ctype_tolower_loc F

> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist

> index d25aefd..e99cb45 100644

> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist

> @@ -1991,6 +1991,9 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.3 GLIBC_2.3 A

>  GLIBC_2.3 __ctype_b_loc F

>  GLIBC_2.3 __ctype_tolower_loc F

> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist

> index 51a8d19..173672a 100644

> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist

> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist

> @@ -2198,3 +2198,6 @@ GLIBC_2.26 strtof128 F

>  GLIBC_2.26 strtof128_l F

>  GLIBC_2.26 wcstof128 F

>  GLIBC_2.26 wcstof128_l F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist

> index 5eb056b..8a65443 100644

> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist

> @@ -105,6 +105,9 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.3 GLIBC_2.3 A

>  GLIBC_2.3 _Exit F

>  GLIBC_2.3 _IO_2_1_stderr_ D 0xe0

> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist

> index 63d33e8..271eccc 100644

> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist

> @@ -1986,6 +1986,9 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.3 GLIBC_2.3 A

>  GLIBC_2.3 __ctype_b_loc F

>  GLIBC_2.3 __ctype_tolower_loc F

> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist

> index b1b2b29..8b96e16 100644

> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist

> @@ -1887,6 +1887,9 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.3 GLIBC_2.3 A

>  GLIBC_2.3 __ctype_b_loc F

>  GLIBC_2.3 __ctype_tolower_loc F

> diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist

> index f3a70a0..0f840e6 100644

> --- a/sysdeps/unix/sysv/linux/sh/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/sh/libc.abilist

> @@ -1872,6 +1872,9 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.3 GLIBC_2.3 A

>  GLIBC_2.3 __ctype_b_loc F

>  GLIBC_2.3 __ctype_tolower_loc F

> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist

> index 8c4c2e5..7f7449f 100644

> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist

> @@ -1978,6 +1978,9 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.3 GLIBC_2.3 A

>  GLIBC_2.3 __ctype_b_loc F

>  GLIBC_2.3 __ctype_tolower_loc F

> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist

> index 1653164..a50485e 100644

> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist

> @@ -1916,6 +1916,9 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.3 GLIBC_2.3 A

>  GLIBC_2.3 __ctype_b_loc F

>  GLIBC_2.3 __ctype_tolower_loc F

> diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist

> index 41647d4..38a96d3 100644

> --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist

> @@ -2110,3 +2110,6 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

> diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist

> index 1088923..572b917 100644

> --- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist

> @@ -2110,3 +2110,6 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

> diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist

> index 41647d4..38a96d3 100644

> --- a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist

> @@ -2110,3 +2110,6 @@ GLIBC_2.26 preadv64v2 F

>  GLIBC_2.26 pwritev2 F

>  GLIBC_2.26 pwritev64v2 F

>  GLIBC_2.26 reallocarray F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist

> index 8bff2b2..b83d25c 100644

> --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist

> @@ -1874,6 +1874,9 @@ GLIBC_2.26 strtof128 F

>  GLIBC_2.26 strtof128_l F

>  GLIBC_2.26 wcstof128 F

>  GLIBC_2.26 wcstof128_l F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>  GLIBC_2.3 GLIBC_2.3 A

>  GLIBC_2.3 __ctype_b_loc F

>  GLIBC_2.3 __ctype_tolower_loc F

> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist

> index d91a038..cba1d59 100644

> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist

> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist

> @@ -2117,3 +2117,6 @@ GLIBC_2.26 strtof128 F

>  GLIBC_2.26 strtof128_l F

>  GLIBC_2.26 wcstof128 F

>  GLIBC_2.26 wcstof128_l F

> +GLIBC_2.27 GLIBC_2.27 A

> +GLIBC_2.27 glob F

> +GLIBC_2.27 glob64 F

>
  

Patch

diff --git a/include/gnu-versions.h b/include/gnu-versions.h
index 40f2bfc..ce26254 100644
--- a/include/gnu-versions.h
+++ b/include/gnu-versions.h
@@ -45,7 +45,7 @@ 
 
 #define _GNU_OBSTACK_INTERFACE_VERSION	1 /* vs malloc/obstack.c */
 #define _GNU_REGEX_INTERFACE_VERSION	1 /* vs posix/regex.c */
-#define _GNU_GLOB_INTERFACE_VERSION	1 /* vs posix/glob.c */
+#define _GNU_GLOB_INTERFACE_VERSION	2 /* vs posix/glob.c */
 #define _GNU_GETOPT_INTERFACE_VERSION	2 /* vs posix/getopt.c and
 					     posix/getopt1.c */
 
diff --git a/posix/Makefile b/posix/Makefile
index 7188cba..203555a 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -46,6 +46,7 @@  routines :=								      \
 	getresuid getresgid setresuid setresgid				      \
 	pathconf sysconf fpathconf					      \
 	glob glob64 globfree globfree64 glob_pattern_p fnmatch regex	      \
+	glob-lstat-compat glob64-lstat-compat				      \
 	confstr								      \
 	getopt getopt1 							      \
 	sched_setp sched_getp sched_sets sched_gets sched_yield sched_primax  \
@@ -95,7 +96,8 @@  tests		:= test-errno tstgetopt testfnm runtests runptests \
 		   tst-posix_fadvise tst-posix_fadvise64 \
 		   tst-sysconf-empty-chroot tst-glob_symlinks
 tests-internal	:= bug-regex5 bug-regex20 bug-regex33 \
-		   tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3
+		   tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 \
+		   tst-glob_lstat_compat
 xtests		:= bug-ga2
 ifeq (yes,$(build-shared))
 test-srcs	:= globtest
diff --git a/posix/Versions b/posix/Versions
index bb481a5..65e9687 100644
--- a/posix/Versions
+++ b/posix/Versions
@@ -134,6 +134,9 @@  libc {
   GLIBC_2.11 {
     execvpe;
   }
+  GLIBC_2.27 {
+    glob; glob64;
+  }
   GLIBC_PRIVATE {
     __libc_fork; __libc_pread; __libc_pwrite;
   }
diff --git a/posix/glob-lstat-compat.c b/posix/glob-lstat-compat.c
new file mode 100644
index 0000000..e30d343
--- /dev/null
+++ b/posix/glob-lstat-compat.c
@@ -0,0 +1,36 @@ 
+/* Compat glob which does not use gl_lstat for GLOB_ALTDIRFUNC.
+   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 <shlib-compat.h>
+
+#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_27)
+
+# include <glob.h>
+
+# define __glob(pattern, flags, errfunc, pglob) \
+  __glob_lstat_compat (pattern, flags, errfunc, pglob)
+
+# define GLOB_ATTRIBUTE attribute_compat_text_section
+
+/* Avoid calling gl_lstat with GLOB_ALTDIRFUNC.  */
+# define GLOB_NO_LSTAT
+
+# include <posix/glob.c>
+
+compat_symbol (libc, __glob_lstat_compat, glob, GLIBC_2_0);
+#endif
diff --git a/posix/glob.c b/posix/glob.c
index c699177..795cebe 100644
--- a/posix/glob.c
+++ b/posix/glob.c
@@ -57,7 +57,9 @@ 
 # endif
 # define struct_stat64		struct stat64
 # define FLEXIBLE_ARRAY_MEMBER
+# include <shlib-compat.h>
 #else /* !_LIBC */
+# define __glob                 glob
 # define __getlogin_r(buf, len) getlogin_r (buf, len)
 # define __lstat64(fname, buf)  lstat (fname, buf)
 # define __stat64(fname, buf)   stat (fname, buf)
@@ -179,6 +181,29 @@  convert_dirent64 (const struct dirent64 *source)
     ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0)
 #endif
 
+static int
+glob_lstat (glob_t *pglob, int flags, const char *fullname)
+{
+/* Use on glob-lstat-compat.c to provide a compat symbol which does not
+   use lstat / gl_lstat.  */
+#ifdef GLOB_NO_LSTAT
+# define GL_LSTAT gl_stat
+# define LSTAT64 __stat64
+#else
+# define GL_LSTAT gl_lstat
+# define LSTAT64 __lstat64
+#endif
+
+  union
+  {
+    struct stat st;
+    struct_stat64 st64;
+  } ust;
+  return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC)
+          ? pglob->GL_LSTAT (fullname, &ust.st)
+          : LSTAT64 (fullname, &ust.st64));
+}
+
 /* Set *R = A + B.  Return true if the answer is mathematically
    incorrect due to overflow; in this case, *R is the low order
    bits of the correct answer.  */
@@ -248,6 +273,9 @@  next_brace_sub (const char *cp, int flags)
   return *cp != '\0' ? cp : NULL;
 }
 
+#ifndef GLOB_ATTRIBUTE
+# define GLOB_ATTRIBUTE
+#endif
 
 /* Do glob searching for PATTERN, placing results in PGLOB.
    The bits defined above may be set in FLAGS.
@@ -258,11 +286,9 @@  next_brace_sub (const char *cp, int flags)
    If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
    Otherwise, 'glob' returns zero.  */
 int
-#ifdef GLOB_ATTRIBUTE
 GLOB_ATTRIBUTE
-#endif
-glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
-      glob_t *pglob)
+__glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
+	glob_t *pglob)
 {
   const char *filename;
   char *dirname = NULL;
@@ -406,9 +432,9 @@  glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
 	      /* Construct the new glob expression.  */
 	      mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
 
-	      result = glob (onealt,
-			     ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))
-			      | GLOB_APPEND), errfunc, pglob);
+	      result = __glob (onealt,
+			       ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))
+			       | GLOB_APPEND), errfunc, pglob);
 
 	      /* If we got an error, return it.  */
 	      if (result && result != GLOB_NOMATCH)
@@ -557,7 +583,7 @@  glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
 		  flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
 		}
 	    }
-	  int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
+	  int val = __glob (dirname, flags | GLOB_MARK, errfunc, pglob);
 	  if (val == 0)
 	    pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
 			       | (flags & GLOB_MARK));
@@ -931,11 +957,10 @@  glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
 	  dirs.gl_lstat = pglob->gl_lstat;
 	}
 
-      status = glob (dirname,
-		     ((flags & (GLOB_ERR | GLOB_NOESCAPE
-				| GLOB_ALTDIRFUNC))
-		      | GLOB_NOSORT | GLOB_ONLYDIR),
-		     errfunc, &dirs);
+      status = __glob (dirname,
+		       ((flags & (GLOB_ERR | GLOB_NOESCAPE | GLOB_ALTDIRFUNC))
+		       | GLOB_NOSORT | GLOB_ONLYDIR),
+		       errfunc, &dirs);
       if (status != 0)
 	{
 	  if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH)
@@ -1133,8 +1158,9 @@  glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
 
   return retval;
 }
-#if defined _LIBC && !defined glob
-libc_hidden_def (glob)
+#if defined _LIBC && !defined __glob
+versioned_symbol (libc, __glob, glob, GLIBC_2_27);
+libc_hidden_ver (__glob, glob)
 #endif
 
 
@@ -1250,11 +1276,6 @@  glob_in_dir (const char *pattern, const char *directory, int flags,
     }
   else if (meta == GLOBPAT_NONE)
     {
-      union
-      {
-	struct stat st;
-	struct_stat64 st64;
-      } ust;
       size_t patlen = strlen (pattern);
       size_t fullsize;
       bool alloca_fullname
@@ -1273,10 +1294,7 @@  glob_in_dir (const char *pattern, const char *directory, int flags,
       mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
 			"/", 1),
 	       pattern, patlen + 1);
-      if (((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
-	   ? (*pglob->gl_lstat) (fullname, &ust.st)
-	    : __lstat64 (fullname, &ust.st64))
-	   == 0)
+      if (glob_lstat (pglob, flags, fullname) == 0
 	  || errno == EOVERFLOW)
 	/* We found this file to be existing.  Now tell the rest
 	   of the function to copy this name into the result.  */
diff --git a/posix/glob64-lstat-compat.c b/posix/glob64-lstat-compat.c
new file mode 100644
index 0000000..1fabf86
--- /dev/null
+++ b/posix/glob64-lstat-compat.c
@@ -0,0 +1,36 @@ 
+/* Compat glob which does not use gl_lstat for GLOB_ALTDIRFUNC.
+   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 <shlib-compat.h>
+
+#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_27)
+
+# include <glob.h>
+
+# define glob(pattern, flags, errfunc, pglob) \
+  __glob64_lstat_compat (pattern, flags, errfunc, pglob)
+
+# define GLOB_ATTRIBUTE attribute_compat_text_section
+
+/* Avoid calling gl_lstat with GLOB_ALTDIRFUNC.  */
+# define GLOB_NO_LSTAT
+
+# include <posix/glob64.c>
+
+compat_symbol (libc, __glob64_lstat_compat, glob64, GLIBC_2_0);
+#endif
diff --git a/posix/glob64.c b/posix/glob64.c
index a515a1c..ee7ef84 100644
--- a/posix/glob64.c
+++ b/posix/glob64.c
@@ -20,6 +20,10 @@ 
 #include <glob.h>
 #include <errno.h>
 
+#ifdef GLOB_ATTRIBUTE
+# define GLOB_ATTRIBUTE
+#endif
+
 /* Do glob searching for PATTERN, placing results in PGLOB.
    The bits defined above may be set in FLAGS.
    If a directory cannot be opened or read and ERRFUNC is not nil,
@@ -29,6 +33,7 @@ 
    If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
    Otherwise, `glob' returns zero.  */
 int
+GLOB_ATTRIBUTE
 glob64 (const char *pattern, int flags,
 	int (*errfunc) (const char *, int), glob64_t *pglob)
 {
diff --git a/posix/tst-glob_lstat_compat.c b/posix/tst-glob_lstat_compat.c
new file mode 100644
index 0000000..c5b9a27
--- /dev/null
+++ b/posix/tst-glob_lstat_compat.c
@@ -0,0 +1,263 @@ 
+/* Test glob compat symbol which avoid call GLOB_ALTDIRFUNC/gl_lstat.
+   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 <glob.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <stdio.h>
+
+#include <shlib-compat.h>
+#include <support/check.h>
+#include <support/temp_file.h>
+
+#if TEST_COMPAT (libc, GLIBC_2_0, GLIBC_2_27)
+
+__typeof (glob) glob;
+compat_symbol_reference (libc, glob, glob, GLIBC_2_0);
+
+/* Compat glob should not call gl_lstat since for some old binaries it
+   might be unitialized (for instance GNUmake).  Check if it is indeed
+   not called.  */
+static bool stat_called;
+static bool lstat_called;
+
+static struct
+{
+  const char *name;
+  int level;
+  int type;
+} filesystem[] =
+{
+  { ".", 1, DT_DIR },
+  { "..", 1, DT_DIR },
+  { "dir1lev1", 1, DT_UNKNOWN },
+    { ".", 2, DT_DIR },
+    { "..", 2, DT_DIR },
+    { "file1lev2", 2, DT_REG },
+    { "file2lev2", 2, DT_REG },
+};
+static const size_t nfiles = sizeof (filesystem) / sizeof (filesystem [0]);
+
+typedef struct
+{
+  int level;
+  int idx;
+  struct dirent d;
+  char room_for_dirent[NAME_MAX];
+} my_DIR;
+
+static long int
+find_file (const char *s)
+{
+  int level = 1;
+  long int idx = 0;
+
+  while (s[0] == '/')
+    {
+      if (s[1] == '\0')
+	{
+	  s = ".";
+	  break;
+	}
+      ++s;
+    }
+
+  if (strcmp (s, ".") == 0)
+    return 0;
+
+  if (s[0] == '.' && s[1] == '/')
+    s += 2;
+
+  while (*s != '\0')
+    {
+      char *endp = strchrnul (s, '/');
+
+      while (idx < nfiles && filesystem[idx].level >= level)
+	{
+	  if (filesystem[idx].level == level
+	      && memcmp (s, filesystem[idx].name, endp - s) == 0
+	      && filesystem[idx].name[endp - s] == '\0')
+	    break;
+	  ++idx;
+	}
+
+      if (idx == nfiles || filesystem[idx].level < level)
+	{
+	  errno = ENOENT;
+	  return -1;
+	}
+
+      if (*endp == '\0')
+	return idx + 1;
+
+      if (filesystem[idx].type != DT_DIR
+	  && (idx + 1 >= nfiles
+	      || filesystem[idx].level >= filesystem[idx + 1].level))
+	{
+	  errno = ENOTDIR;
+	  return -1;
+	}
+
+      ++idx;
+
+      s = endp + 1;
+      ++level;
+    }
+
+  errno = ENOENT;
+  return -1;
+}
+
+static void *
+my_opendir (const char *s)
+{
+  long int idx = find_file (s);
+  if (idx == -1 || filesystem[idx].type != DT_DIR)
+    return NULL;
+
+  my_DIR *dir = malloc (sizeof (my_DIR));
+  if (dir == NULL)
+    FAIL_EXIT1 ("cannot allocate directory handle");
+
+  dir->level = filesystem[idx].level;
+  dir->idx = idx;
+
+  return dir;
+}
+
+static struct dirent *
+my_readdir (void *gdir)
+{
+  my_DIR *dir = gdir;
+
+  if (dir->idx == -1)
+    return NULL;
+
+  while (dir->idx < nfiles && filesystem[dir->idx].level > dir->level)
+    ++dir->idx;
+
+  if (dir->idx == nfiles || filesystem[dir->idx].level < dir->level)
+    {
+      dir->idx = -1;
+      return NULL;
+    }
+
+  dir->d.d_ino = 1;		/* glob should not skip this entry.  */
+
+#ifdef _DIRENT_HAVE_D_TYPE
+  dir->d.d_type = filesystem[dir->idx].type;
+#endif
+
+  strcpy (dir->d.d_name, filesystem[dir->idx].name);
+
+  ++dir->idx;
+
+  return &dir->d;
+}
+
+static void
+my_closedir (void *dir)
+{
+  free (dir);
+}
+
+static int
+my_stat (const char *name, struct stat *st)
+{
+  stat_called = true;
+
+  long int idx = find_file (name);
+  if (idx == -1)
+    return -1;
+
+  memset (st, '\0', sizeof (*st));
+
+  if (filesystem[idx].type == DT_UNKNOWN)
+    st->st_mode = DTTOIF (idx + 1 < nfiles
+			  && filesystem[idx].level < filesystem[idx + 1].level
+			  ? DT_DIR : DT_REG) | 0777;
+  else
+    st->st_mode = DTTOIF (filesystem[idx].type) | 0777;
+  return 0;
+}
+
+static int
+my_lstat (const char *name, struct stat *st)
+{
+  lstat_called = true;
+
+  long int idx = find_file (name);
+  if (idx == -1)
+    return -1;
+
+  memset (st, '\0', sizeof (*st));
+
+  if (filesystem[idx].type == DT_UNKNOWN)
+    st->st_mode = DTTOIF (idx + 1 < nfiles
+			  && filesystem[idx].level < filesystem[idx + 1].level
+			  ? DT_DIR : DT_REG) | 0777;
+  else
+    st->st_mode = DTTOIF (filesystem[idx].type) | 0777;
+  return 0;
+}
+
+static int
+do_test (void)
+{
+  glob_t gl;
+
+  memset (&gl, '\0', sizeof (gl));
+
+  gl.gl_closedir = my_closedir;
+  gl.gl_readdir = my_readdir;
+  gl.gl_opendir = my_opendir;
+  gl.gl_lstat = my_lstat;
+  gl.gl_stat = my_stat;
+
+  int flags = GLOB_ALTDIRFUNC;
+
+  stat_called = false;
+  lstat_called = false;
+
+  TEST_VERIFY_EXIT (glob ("*/file1lev2", flags, NULL, &gl) == 0);
+  TEST_VERIFY_EXIT (gl.gl_pathc == 1);
+  TEST_VERIFY_EXIT (strcmp (gl.gl_pathv[0], "dir1lev1/file1lev2") == 0);
+
+  TEST_VERIFY_EXIT (stat_called == true);
+  TEST_VERIFY_EXIT (lstat_called == false);
+
+  return 0;
+}
+
+#else /* TEST_COMPAT (libc, GLIBC_2_0, GLIBC_2_27)  */
+
+static int
+do_test (void)
+{ 
+  return 77;
+}
+#endif
+
+#include <support/test-driver.c>
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 81e4fe9..e7438c5 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2103,3 +2103,6 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
diff --git a/sysdeps/unix/sysv/linux/alpha/glob-lstat-compat.c b/sysdeps/unix/sysv/linux/alpha/glob-lstat-compat.c
new file mode 100644
index 0000000..a76471d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/glob-lstat-compat.c
@@ -0,0 +1,2 @@ 
+#define GLOB_LSTAT_VERSION GLIBC_2_1
+#include <sysdeps/unix/sysv/linux/glob-lstat-compat.c>
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index fab7331..4836ea0 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2014,6 +2014,9 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/alpha/oldglob.c b/sysdeps/unix/sysv/linux/alpha/oldglob.c
index 988c92b..b54624c 100644
--- a/sysdeps/unix/sysv/linux/alpha/oldglob.c
+++ b/sysdeps/unix/sysv/linux/alpha/oldglob.c
@@ -59,7 +59,9 @@  __old_glob (const char *pattern, int flags,
   correct.gl_closedir = pglob->gl_closedir;
   correct.gl_readdir = pglob->gl_readdir;
   correct.gl_opendir = pglob->gl_opendir;
-  correct.gl_lstat = pglob->gl_lstat;
+  /* Set gl_lstat and gl_stat for both gl_stat for compatibility with old
+     implementation that did not follow dangling symlinks.  */
+  correct.gl_lstat = pglob->gl_stat;
   correct.gl_stat = pglob->gl_stat;
 
   result = glob (pattern, flags, errfunc, &correct);
@@ -72,7 +74,7 @@  __old_glob (const char *pattern, int flags,
   pglob->gl_closedir = correct.gl_closedir;
   pglob->gl_readdir = correct.gl_readdir;
   pglob->gl_opendir = correct.gl_opendir;
-  pglob->gl_lstat = correct.gl_lstat;
+  /* Only need to restore gl_stat.  */
   pglob->gl_stat = correct.gl_stat;
 
   return result;
diff --git a/sysdeps/unix/sysv/linux/arm/libc.abilist b/sysdeps/unix/sysv/linux/arm/libc.abilist
index d2a206a..5b70e1b 100644
--- a/sysdeps/unix/sysv/linux/arm/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/libc.abilist
@@ -104,6 +104,9 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.4 GLIBC_2.4 A
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
diff --git a/sysdeps/unix/sysv/linux/alpha/glob.c b/sysdeps/unix/sysv/linux/glob-lstat-compat.c
similarity index 50%
rename from sysdeps/unix/sysv/linux/alpha/glob.c
rename to sysdeps/unix/sysv/linux/glob-lstat-compat.c
index 1b813c1..9867e2f 100644
--- a/sysdeps/unix/sysv/linux/alpha/glob.c
+++ b/sysdeps/unix/sysv/linux/glob-lstat-compat.c
@@ -1,4 +1,6 @@ 
-/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+/* Compat glob which does not use gl_lstat for GLOB_ALTDIRFUNC.
+   Linux version which handles LFS when required.
+   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
@@ -12,36 +14,34 @@ 
    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
+   License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define glob64 __no_glob64_decl
-#define globfree64 __no_globfree64_decl
-
-#include <sys/types.h>
-#include <glob.h>
+#include <sys/stat.h>
+#include <kernel_stat.h>
 #include <shlib-compat.h>
 
-/* For Linux/Alpha we have to make the glob symbols versioned.  */
-#define glob(pattern, flags, errfunc, pglob) \
-  __new_glob (pattern, flags, errfunc, pglob)
-#define globfree(pglob) \
-  __new_globfree (pglob)
+#define glob64 __no_glob64_decl
+#include <glob.h>
+#undef glob64
 
-/* We need prototypes for these new names.  */
-extern int __new_glob (const char *__pattern, int __flags,
-		       int (*__errfunc) (const char *, int),
-		       glob_t *__pglob);
-extern void __new_globfree (glob_t *__pglob);
+#define __glob __glob_lstat_compat
 
-#include <posix/glob.c>
+#define GLOB_ATTRIBUTE attribute_compat_text_section
 
-#undef glob
-#undef globfree
-#undef glob64
-#undef globfree64
+/* Avoid calling gl_lstat with GLOB_ALTDIRFUNC.  */
+#define GLOB_NO_LSTAT
 
-versioned_symbol (libc, __new_glob, glob, GLIBC_2_1);
-libc_hidden_ver (__new_glob, glob)
+#include <posix/glob.c>
 
-weak_alias (__new_glob, glob64)
+#ifndef GLOB_LSTAT_VERSION
+# define GLOB_LSTAT_VERSION GLIBC_2_0
+#endif
+
+#if SHLIB_COMPAT(libc, GLOB_LSTAT_VERSION, GLIBC_2_27)
+compat_symbol (libc, __glob_lstat_compat, glob, GLOB_LSTAT_VERSION);
+# if XSTAT_IS_XSTAT64
+strong_alias (__glob_lstat_compat, __glob64_lstat_compat)
+compat_symbol (libc, __glob64_lstat_compat, glob64, GLOB_LSTAT_VERSION);
+# endif
+#endif
diff --git a/sysdeps/unix/sysv/linux/glob.c b/sysdeps/unix/sysv/linux/glob.c
index 057ae7f..e354799 100644
--- a/sysdeps/unix/sysv/linux/glob.c
+++ b/sysdeps/unix/sysv/linux/glob.c
@@ -20,9 +20,12 @@ 
 #include <kernel_stat.h>
 
 #define glob64 __no_glob64_decl
+#define __glob64 __no___glob64_decl
 #include <posix/glob.c>
 #undef glob64
+#undef __glob64
 
 #if XSTAT_IS_XSTAT64
-weak_alias (glob, glob64)
+strong_alias (__glob, __glob64)
+versioned_symbol (libc, __glob64, glob64, GLIBC_2_27);
 #endif
diff --git a/sysdeps/unix/sysv/linux/glob64-lstat-compat.c b/sysdeps/unix/sysv/linux/glob64-lstat-compat.c
new file mode 100644
index 0000000..f4e468d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/glob64-lstat-compat.c
@@ -0,0 +1,51 @@ 
+/* Compat glob which does not use gl_lstat for GLOB_ALTDIRFUNC.
+   Linux version which handles LFS when required.
+   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>
+# include <dirent.h>
+# include <sys/stat.h>
+# include <shlib-compat.h>
+
+# define dirent dirent64
+# define __readdir(dirp) __readdir64 (dirp)
+
+# define glob_t glob64_t
+# define __glob __glob64_lstat_compat
+# define globfree globfree64
+
+# undef stat
+# define stat stat64
+
+# define COMPILE_GLOB64	1
+
+# define GLOB_ATTRIBUTE attribute_compat_text_section
+
+/* Avoid calling gl_lstat with GLOB_ALTDIRFUNC.  */
+# define GLOB_NO_LSTAT
+
+# include <posix/glob.c>
+
+# if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_27)
+compat_symbol (libc, __glob64_lstat_compat, glob64, GLIBC_2_2);
+# endif
+#endif /* XSTAT_IS_XSTAT64  */
diff --git a/sysdeps/unix/sysv/linux/glob64.c b/sysdeps/unix/sysv/linux/glob64.c
index 428bbac..0189d1c 100644
--- a/sysdeps/unix/sysv/linux/glob64.c
+++ b/sysdeps/unix/sysv/linux/glob64.c
@@ -28,8 +28,7 @@ 
 # define __readdir(dirp) __readdir64 (dirp)
 
 # define glob_t glob64_t
-# define glob(pattern, flags, errfunc, pglob) \
-  __glob64 (pattern, flags, errfunc, pglob)
+# define __glob __glob64
 # define globfree(pglob) globfree64 (pglob)
 
 # undef stat
@@ -39,13 +38,13 @@ 
 
 # include <posix/glob.c>
 
-# include "shlib-compat.h"
+# 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);
+versioned_symbol (libc, __glob64, glob64, GLIBC_2_27);
 libc_hidden_ver (__glob64, glob64)
 # endif
 #endif /* XSTAT_IS_XSTAT64  */
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 24bb730..6a2500a 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -1868,6 +1868,9 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 12e77bd..9ab4e36 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2033,6 +2033,9 @@  GLIBC_2.26 strtof128 F
 GLIBC_2.26 strtof128_l F
 GLIBC_2.26 wcstof128 F
 GLIBC_2.26 wcstof128_l F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 62b67b8..81bb623 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -1897,6 +1897,9 @@  GLIBC_2.26 strtof128 F
 GLIBC_2.26 strtof128_l F
 GLIBC_2.26 wcstof128 F
 GLIBC_2.26 wcstof128_l F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index b594ebd..5a33b57 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -105,6 +105,9 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.4 GLIBC_2.4 A
 GLIBC_2.4 _Exit F
 GLIBC_2.4 _IO_2_1_stderr_ D 0x98
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index a36739d..50a86e7 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -1982,6 +1982,9 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/microblaze/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
index 16aa254..250ef30 100644
--- a/sysdeps/unix/sysv/linux/microblaze/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/libc.abilist
@@ -2103,3 +2103,6 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 907ab33..87a1dc4 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -1957,6 +1957,9 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 36ee235..f2b35f2 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -1955,6 +1955,9 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 783aa73..e119842 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -1953,6 +1953,9 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index e1275df..67f10f5 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -1948,6 +1948,9 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index be25228..c599dd9 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2144,3 +2144,6 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
diff --git a/sysdeps/unix/sysv/linux/oldglob.c b/sysdeps/unix/sysv/linux/oldglob.c
index 5402450..a034c2d 100644
--- a/sysdeps/unix/sysv/linux/oldglob.c
+++ b/sysdeps/unix/sysv/linux/oldglob.c
@@ -21,7 +21,7 @@  libc_hidden_proto (__old_glob64);
 #define __readdir(dirp) __old_readdir64 (dirp)
 
 #define glob_t glob64_t
-#define glob(pattern, flags, errfunc, pglob) \
+#define __glob(pattern, flags, errfunc, pglob) \
   __old_glob64 (pattern, flags, errfunc, pglob)
 #define globfree(pglob) globfree64(pglob)
 
@@ -33,6 +33,9 @@  libc_hidden_proto (__old_glob64);
 #undef __stat
 #define __stat(file, buf) __xstat64 (_STAT_VER, file, buf)
 
+/* Avoid calling gl_lstat with GLOB_ALTDIRFUNC.  */
+#define GLOB_NO_LSTAT
+
 #define GLOB_ATTRIBUTE attribute_compat_text_section
 
 #include <posix/glob.c>
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index e213895..385409a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -1986,6 +1986,9 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index d25aefd..e99cb45 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -1991,6 +1991,9 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
index 51a8d19..173672a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist
@@ -2198,3 +2198,6 @@  GLIBC_2.26 strtof128 F
 GLIBC_2.26 strtof128_l F
 GLIBC_2.26 wcstof128 F
 GLIBC_2.26 wcstof128_l F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
index 5eb056b..8a65443 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist
@@ -105,6 +105,9 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 _Exit F
 GLIBC_2.3 _IO_2_1_stderr_ D 0xe0
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index 63d33e8..271eccc 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -1986,6 +1986,9 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index b1b2b29..8b96e16 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -1887,6 +1887,9 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sh/libc.abilist b/sysdeps/unix/sysv/linux/sh/libc.abilist
index f3a70a0..0f840e6 100644
--- a/sysdeps/unix/sysv/linux/sh/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/libc.abilist
@@ -1872,6 +1872,9 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index 8c4c2e5..7f7449f 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -1978,6 +1978,9 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 1653164..a50485e 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -1916,6 +1916,9 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
index 41647d4..38a96d3 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist
@@ -2110,3 +2110,6 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
diff --git a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
index 1088923..572b917 100644
--- a/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist
@@ -2110,3 +2110,6 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
diff --git a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
index 41647d4..38a96d3 100644
--- a/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
+++ b/sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist
@@ -2110,3 +2110,6 @@  GLIBC_2.26 preadv64v2 F
 GLIBC_2.26 pwritev2 F
 GLIBC_2.26 pwritev64v2 F
 GLIBC_2.26 reallocarray F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 8bff2b2..b83d25c 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -1874,6 +1874,9 @@  GLIBC_2.26 strtof128 F
 GLIBC_2.26 strtof128_l F
 GLIBC_2.26 wcstof128 F
 GLIBC_2.26 wcstof128_l F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F
 GLIBC_2.3 GLIBC_2.3 A
 GLIBC_2.3 __ctype_b_loc F
 GLIBC_2.3 __ctype_tolower_loc F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index d91a038..cba1d59 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2117,3 +2117,6 @@  GLIBC_2.26 strtof128 F
 GLIBC_2.26 strtof128_l F
 GLIBC_2.26 wcstof128 F
 GLIBC_2.26 wcstof128_l F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 glob F
+GLIBC_2.27 glob64 F