Date: Friday, August 10, 2018 @ 16:41:47 Author: bpiotrowski Revision: 331347
2.28-2: backport fix for BZ#23497 and revert commit breaking proprietary electron apps The problem is in fact in lld[1] used to build Electron but it's too serious regression to fool around. [1] https://github.com/electron/electron/issues/13972#issuecomment-411532741 Added: glibc/trunk/0001-Revert-elf-Correct-absolute-SHN_ABS-symbol-run-time-.patch glibc/trunk/bz23497.patch Modified: glibc/trunk/PKGBUILD Deleted: glibc/trunk/bz20338.patch -----------------------------------------------------------------+ 0001-Revert-elf-Correct-absolute-SHN_ABS-symbol-run-time-.patch | 195 +++++++ PKGBUILD | 10 bz20338.patch | 114 ---- bz23497.patch | 262 ++++++++++ 4 files changed, 463 insertions(+), 118 deletions(-) Added: 0001-Revert-elf-Correct-absolute-SHN_ABS-symbol-run-time-.patch =================================================================== --- 0001-Revert-elf-Correct-absolute-SHN_ABS-symbol-run-time-.patch (rev 0) +++ 0001-Revert-elf-Correct-absolute-SHN_ABS-symbol-run-time-.patch 2018-08-10 16:41:47 UTC (rev 331347) @@ -0,0 +1,195 @@ +From 2cbf10ae2ea9e378ff91b8f5c4d8cb77ed05378e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bart=C5=82omiej=20Piotrowski?= <[email protected]> +Date: Fri, 10 Aug 2018 14:12:40 +0000 +Subject: [PATCH] Revert "elf: Correct absolute (SHN_ABS) symbol run-time + calculation [BZ #19818]" + +This reverts commit e7feec374c635b6a29d65c39ae5e1855528fed39. +--- + elf/Makefile | 14 ++----------- + elf/dl-addr.c | 2 -- + elf/tst-absolute-sym-lib.c | 25 ------------------------ + elf/tst-absolute-sym-lib.lds | 19 ------------------ + elf/tst-absolute-sym.c | 38 ------------------------------------ + sysdeps/generic/ldsodefs.h | 3 +-- + 6 files changed, 3 insertions(+), 98 deletions(-) + delete mode 100644 elf/tst-absolute-sym-lib.c + delete mode 100644 elf/tst-absolute-sym-lib.lds + delete mode 100644 elf/tst-absolute-sym.c + +diff --git a/elf/Makefile b/elf/Makefile +index cd0771307f..5084ba4f6f 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -186,7 +186,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ + tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \ + tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \ + tst-latepthread tst-tls-manydynamic tst-nodelete-dlclose \ +- tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note ++ tst-debug1 tst-main1 + # reldep9 + tests-internal += loadtest unload unload2 circleload1 \ + neededtest neededtest2 neededtest3 neededtest4 \ +@@ -272,9 +272,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ + tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 \ + tst-latepthreadmod $(tst-tls-many-dynamic-modules) \ + tst-nodelete-dlclose-dso tst-nodelete-dlclose-plugin \ +- tst-main1mod tst-libc_dlvsym-dso tst-absolute-sym-lib \ +- tst-absolute-zero-lib tst-big-note-lib +- ++ tst-main1mod tst-libc_dlvsym-dso + ifeq (yes,$(have-mtls-dialect-gnu2)) + tests += tst-gnu2-tls1 + modules-names += tst-gnu2-tls1mod +@@ -1465,14 +1463,6 @@ tst-main1-no-pie = yes + LDLIBS-tst-main1 = $(libsupport) + tst-main1mod.so-no-z-defs = yes + +-LDLIBS-tst-absolute-sym-lib.so = tst-absolute-sym-lib.lds +-$(objpfx)tst-absolute-sym-lib.so: $(LDLIBS-tst-absolute-sym-lib.so) +-$(objpfx)tst-absolute-sym: $(objpfx)tst-absolute-sym-lib.so +- +-LDLIBS-tst-absolute-zero-lib.so = tst-absolute-zero-lib.lds +-$(objpfx)tst-absolute-zero-lib.so: $(LDLIBS-tst-absolute-zero-lib.so) +-$(objpfx)tst-absolute-zero: $(objpfx)tst-absolute-zero-lib.so +- + # Both the main program and the DSO for tst-libc_dlvsym need to link + # against libdl. + $(objpfx)tst-libc_dlvsym: $(libdl) +diff --git a/elf/dl-addr.c b/elf/dl-addr.c +index e6c7d02094..2250617a73 100644 +--- a/elf/dl-addr.c ++++ b/elf/dl-addr.c +@@ -59,7 +59,6 @@ determine_info (const ElfW(Addr) addr, struct link_map *match, Dl_info *info, + we can omit that test here. */ + if ((symtab[symndx].st_shndx != SHN_UNDEF + || symtab[symndx].st_value != 0) +- && symtab[symndx].st_shndx != SHN_ABS + && ELFW(ST_TYPE) (symtab[symndx].st_info) != STT_TLS + && DL_ADDR_SYM_MATCH (match, &symtab[symndx], + matchsym, addr) +@@ -92,7 +91,6 @@ determine_info (const ElfW(Addr) addr, struct link_map *match, Dl_info *info, + && ELFW(ST_TYPE) (symtab->st_info) != STT_TLS + && (symtab->st_shndx != SHN_UNDEF + || symtab->st_value != 0) +- && symtab->st_shndx != SHN_ABS + && DL_ADDR_SYM_MATCH (match, symtab, matchsym, addr) + && symtab->st_name < strtabsize) + matchsym = (ElfW(Sym) *) symtab; +diff --git a/elf/tst-absolute-sym-lib.c b/elf/tst-absolute-sym-lib.c +deleted file mode 100644 +index 912cb0048a..0000000000 +--- a/elf/tst-absolute-sym-lib.c ++++ /dev/null +@@ -1,25 +0,0 @@ +-/* BZ #19818 absolute symbol calculation shared module. +- Copyright (C) 2018 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/>. */ +- +-extern char absolute; +- +-void * +-get_absolute (void) +-{ +- return &absolute; +-} +diff --git a/elf/tst-absolute-sym-lib.lds b/elf/tst-absolute-sym-lib.lds +deleted file mode 100644 +index d4a4128514..0000000000 +--- a/elf/tst-absolute-sym-lib.lds ++++ /dev/null +@@ -1,19 +0,0 @@ +-/* BZ #19818 absolute symbol calculation linker script. +- Copyright (C) 2018 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/>. */ +- +-"absolute" = 0x55aa; +diff --git a/elf/tst-absolute-sym.c b/elf/tst-absolute-sym.c +deleted file mode 100644 +index 111491d159..0000000000 +--- a/elf/tst-absolute-sym.c ++++ /dev/null +@@ -1,38 +0,0 @@ +-/* BZ #19818 absolute symbol calculation main executable. +- Copyright (C) 2018 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 <support/check.h> +-#include <support/support.h> +-#include <support/test-driver.h> +- +-void *get_absolute (void); +- +-static int +-do_test (void) +-{ +- void *ref = (void *) 0x55aa; +- void *ptr; +- +- ptr = get_absolute (); +- if (ptr != ref) +- FAIL_EXIT1 ("Got %p, expected %p\n", ptr, ref); +- +- return 0; +-} +- +-#include <support/test-driver.c> +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 95dc87519b..3cac4fa362 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -72,8 +72,7 @@ typedef struct link_map *lookup_t; + if non-NULL. Don't check for NULL map if MAP_SET is TRUE. */ + #define SYMBOL_ADDRESS(map, ref, map_set) \ + ((ref) == NULL ? 0 \ +- : (__glibc_unlikely ((ref)->st_shndx == SHN_ABS) ? 0 \ +- : LOOKUP_VALUE_ADDRESS (map, map_set)) + (ref)->st_value) ++ : LOOKUP_VALUE_ADDRESS (map, map_set) + (ref)->st_value) + + /* On some architectures a pointer to a function is not just a pointer + to the actual code of the function but rather an architecture +-- +2.18.0 + Modified: PKGBUILD =================================================================== --- PKGBUILD 2018-08-10 16:12:23 UTC (rev 331346) +++ PKGBUILD 2018-08-10 16:41:47 UTC (rev 331347) @@ -8,19 +8,20 @@ pkgbase=glibc pkgname=(glibc lib32-glibc) pkgver=2.28 -pkgrel=1 +pkgrel=2 arch=(x86_64) url='http://www.gnu.org/software/libc' license=(GPL LGPL) makedepends=(git gd lib32-gcc-libs) options=(!strip staticlibs) -_commit=23158b08a0908f381459f273a984c6fd328363cb +#_commit=23158b08a0908f381459f273a984c6fd328363cb #source=(git+https://sourceware.org/git/glibc.git#commit=$_commit source=(https://ftp.gnu.org/gnu/glibc/glibc-$pkgver.tar.xz{,.sig} locale.gen.txt locale-gen lib32-glibc.conf - bz20338.patch) + bz23497.patch + 0001-Revert-elf-Correct-absolute-SHN_ABS-symbol-run-time-.patch) validpgpkeys=(7273542B39962DF7B299931416792B4EA25340F8) # Carlos O'Donell md5sums=('c81d2388896379997bc359d4f2084239' 'SKIP' @@ -27,7 +28,8 @@ '07ac979b6ab5eeb778d55f041529d623' '476e9113489f93b348b21e144b6a8fcf' '6e052f1cb693d5d3203f50f9d4e8c33b' - 'dc0d3ad59aeaaf591b085a77de6e03e9') + '11bca140697b1bdb656742e2a12c2982' + '58ffe75a9c5a1b22c535a5c2e725db22') prepare() { mkdir -p glibc-build lib32-glibc-build Deleted: bz20338.patch =================================================================== --- bz20338.patch 2018-08-10 16:12:23 UTC (rev 331346) +++ bz20338.patch 2018-08-10 16:41:47 UTC (rev 331347) @@ -1,114 +0,0 @@ -From 74250a7cdf106d4ca7d9506e6d5dc7c448dc3434 Mon Sep 17 00:00:00 2001 -From: David Michael <[email protected]> -Date: Thu, 15 Dec 2016 15:22:57 -0800 -Subject: [PATCH] gshadow: Sync fgetsgent_r.c with grp/fgetgrent_r.c - - [BZ #20338] - * gshadow/fgetsgent_r.c: Include <libio/iolibio.h>. - (flockfile): New macro. - (funlockfile): Likewise. - (__fgetsgent_r): Sync with __fgetgrent_r. - * nss/nss_files/files-sgrp.c: Fix "fgetsgent_r.c" typo. ---- - gshadow/fgetsgent_r.c | 35 ++++++++++++++++++++++++----------- - nss/nss_files/files-sgrp.c | 2 +- - 2 files changed, 25 insertions(+), 12 deletions(-) - -diff --git a/gshadow/fgetsgent_r.c b/gshadow/fgetsgent_r.c -index b70f6fa..02cd33a 100644 ---- a/gshadow/fgetsgent_r.c -+++ b/gshadow/fgetsgent_r.c -@@ -20,39 +20,44 @@ - #include <gshadow.h> - #include <stdio.h> - -+#include <libio/iolibio.h> -+#define flockfile(s) _IO_flockfile (s) -+#define funlockfile(s) _IO_funlockfile (s) -+ - /* Define a line parsing function using the common code - used in the nss_files module. */ - - #define STRUCTURE sgrp - #define ENTNAME sgent --#define EXTERN_PARSER 1 -+#define EXTERN_PARSER 1 - struct sgent_data {}; - - #include <nss/nss_files/files-parse.c> - - --/* Read one shadow entry from the given stream. */ -+/* Read one entry from the given stream. */ - int - __fgetsgent_r (FILE *stream, struct sgrp *resbuf, char *buffer, size_t buflen, - struct sgrp **result) - { - char *p; -+ int parse_result; - -- _IO_flockfile (stream); -+ flockfile (stream); - do - { - buffer[buflen - 1] = '\xff'; - p = fgets_unlocked (buffer, buflen, stream); -- if (p == NULL && feof_unlocked (stream)) -+ if (__builtin_expect (p == NULL, 0) && feof_unlocked (stream)) - { -- _IO_funlockfile (stream); -+ funlockfile (stream); - *result = NULL; - __set_errno (ENOENT); - return errno; - } -- if (p == NULL || buffer[buflen - 1] != '\xff') -+ if (__builtin_expect (p == NULL, 0) || buffer[buflen - 1] != '\xff') - { -- _IO_funlockfile (stream); -+ funlockfile (stream); - *result = NULL; - __set_errno (ERANGE); - return errno; -@@ -61,13 +66,21 @@ __fgetsgent_r (FILE *stream, struct sgrp *resbuf, char *buffer, size_t buflen, - /* Skip leading blanks. */ - while (isspace (*p)) - ++p; -- } while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */ -+ } while (*p == '\0' || *p == '#' /* Ignore empty and comment lines. */ - /* Parse the line. If it is invalid, loop to - get the next line of the file to parse. */ -- ! parse_line (buffer, (void *) resbuf, (void *) buffer, buflen, -- &errno)); -+ || ! (parse_result = parse_line (p, resbuf, -+ (void *) buffer, buflen, -+ &errno))); -+ -+ funlockfile (stream); - -- _IO_funlockfile (stream); -+ if (__builtin_expect (parse_result, 0) == -1) -+ { -+ /* The parser ran out of space. */ -+ *result = NULL; -+ return errno; -+ } - - *result = resbuf; - return 0; -diff --git a/nss/nss_files/files-sgrp.c b/nss/nss_files/files-sgrp.c -index 15dc659..05c3805 100644 ---- a/nss/nss_files/files-sgrp.c -+++ b/nss/nss_files/files-sgrp.c -@@ -23,7 +23,7 @@ - #define DATABASE "gshadow" - struct sgent_data {}; - --/* Our parser function is already defined in sgetspent_r.c, so use that -+/* Our parser function is already defined in sgetsgent_r.c, so use that - to parse lines from the database file. */ - #define EXTERN_PARSER - #include "files-parse.c" --- -2.7.4 - Added: bz23497.patch =================================================================== --- bz23497.patch (rev 0) +++ bz23497.patch 2018-08-10 16:41:47 UTC (rev 331347) @@ -0,0 +1,262 @@ +From 4b25485f03158959cff45379eecc1d73c7dcdd11 Mon Sep 17 00:00:00 2001 +From: Florian Weimer <[email protected]> +Date: Fri, 10 Aug 2018 11:19:26 +0200 +Subject: [PATCH] Linux: Rewrite __old_getdents64 [BZ #23497] + +Commit 298d0e3129c0b5137f4989275b13fe30d0733c4d ("Consolidate Linux +getdents{64} implementation") broke the implementation because it does +not take into account struct offset differences. + +The new implementation is close to the old one, before the +consolidation, but has been cleaned up slightly. + +(cherry picked from commit 690652882b499defb3d950dfeff8fe421d13cab5) +--- + sysdeps/unix/sysv/linux/Makefile | 1 + + sysdeps/unix/sysv/linux/getdents64.c | 89 ++++++++++++++------ + sysdeps/unix/sysv/linux/tst-readdir64-compat.c | 111 +++++++++++++++++++++++++ + 3 files changed, 176 insertions(+), 25 deletions(-) + create mode 100644 sysdeps/unix/sysv/linux/tst-readdir64-compat.c + +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index f71cc39..773aaea 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -161,6 +161,7 @@ inhibit-glue = yes + + ifeq ($(subdir),dirent) + sysdep_routines += getdirentries getdirentries64 ++tests-internal += tst-readdir64-compat + endif + + ifeq ($(subdir),nis) +diff --git a/sysdeps/unix/sysv/linux/getdents64.c b/sysdeps/unix/sysv/linux/getdents64.c +index 3bde0cf..bc140b5 100644 +--- a/sysdeps/unix/sysv/linux/getdents64.c ++++ b/sysdeps/unix/sysv/linux/getdents64.c +@@ -33,41 +33,80 @@ strong_alias (__getdents64, __getdents) + # include <shlib-compat.h> + + # if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) +-# include <olddirent.h> ++# include <olddirent.h> ++# include <unistd.h> + +-/* kernel definition of as of 3.2. */ +-struct compat_linux_dirent ++static ssize_t ++handle_overflow (int fd, __off64_t offset, ssize_t count) + { +- /* Both d_ino and d_off are compat_ulong_t which are defined in all +- architectures as 'u32'. */ +- uint32_t d_ino; +- uint32_t d_off; +- unsigned short d_reclen; +- char d_name[1]; +-}; ++ /* If this is the first entry in the buffer, we can report the ++ error. */ ++ if (count == 0) ++ { ++ __set_errno (EOVERFLOW); ++ return -1; ++ } ++ ++ /* Otherwise, seek to the overflowing entry, so that the next call ++ will report the error, and return the data read so far.. */ ++ if (__lseek64 (fd, offset, SEEK_SET) != 0) ++ return -1; ++ return count; ++} + + ssize_t + __old_getdents64 (int fd, char *buf, size_t nbytes) + { +- ssize_t retval = INLINE_SYSCALL_CALL (getdents, fd, buf, nbytes); ++ /* We do not move the individual directory entries. This is only ++ possible if the target type (struct __old_dirent64) is smaller ++ than the source type. */ ++ _Static_assert (offsetof (struct __old_dirent64, d_name) ++ <= offsetof (struct dirent64, d_name), ++ "__old_dirent64 is larger than dirent64"); ++ _Static_assert (__alignof__ (struct __old_dirent64) ++ <= __alignof__ (struct dirent64), ++ "alignment of __old_dirent64 is larger than dirent64"); + +- /* The kernel added the d_type value after the name. Change this now. */ +- if (retval != -1) ++ ssize_t retval = INLINE_SYSCALL_CALL (getdents64, fd, buf, nbytes); ++ if (retval > 0) + { +- union +- { +- struct compat_linux_dirent k; +- struct dirent u; +- } *kbuf = (void *) buf; +- +- while ((char *) kbuf < buf + retval) ++ char *p = buf; ++ char *end = buf + retval; ++ while (p < end) + { +- char d_type = *((char *) kbuf + kbuf->k.d_reclen - 1); +- memmove (kbuf->u.d_name, kbuf->k.d_name, +- strlen (kbuf->k.d_name) + 1); +- kbuf->u.d_type = d_type; ++ struct dirent64 *source = (struct dirent64 *) p; ++ ++ /* Copy out the fixed-size data. */ ++ __ino_t ino = source->d_ino; ++ __off64_t offset = source->d_off; ++ unsigned int reclen = source->d_reclen; ++ unsigned char type = source->d_type; ++ ++ /* Check for ino_t overflow. */ ++ if (__glibc_unlikely (ino != source->d_ino)) ++ return handle_overflow (fd, offset, p - buf); ++ ++ /* Convert to the target layout. Use a separate struct and ++ memcpy to side-step aliasing issues. */ ++ struct __old_dirent64 result; ++ result.d_ino = ino; ++ result.d_off = offset; ++ result.d_reclen = reclen; ++ result.d_type = type; ++ ++ /* Write the fixed-sized part of the result to the ++ buffer. */ ++ size_t result_name_offset = offsetof (struct __old_dirent64, d_name); ++ memcpy (p, &result, result_name_offset); ++ ++ /* Adjust the position of the name if necessary. Copy ++ everything until the end of the record, including the ++ terminating NUL byte. */ ++ if (result_name_offset != offsetof (struct dirent64, d_name)) ++ memmove (p + result_name_offset, source->d_name, ++ reclen - offsetof (struct dirent64, d_name)); + +- kbuf = (void *) ((char *) kbuf + kbuf->k.d_reclen); ++ p += reclen; + } + } + return retval; +diff --git a/sysdeps/unix/sysv/linux/tst-readdir64-compat.c b/sysdeps/unix/sysv/linux/tst-readdir64-compat.c +new file mode 100644 +index 0000000..43c4a84 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-readdir64-compat.c +@@ -0,0 +1,111 @@ ++/* Test readdir64 compatibility symbol. ++ Copyright (C) 2018 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 <dirent.h> ++#include <dlfcn.h> ++#include <errno.h> ++#include <shlib-compat.h> ++#include <stdbool.h> ++#include <stdio.h> ++#include <string.h> ++#include <support/check.h> ++ ++/* Copied from <olddirent.h>. */ ++struct __old_dirent64 ++ { ++ __ino_t d_ino; ++ __off64_t d_off; ++ unsigned short int d_reclen; ++ unsigned char d_type; ++ char d_name[256]; ++ }; ++ ++typedef struct __old_dirent64 *(*compat_readdir64_type) (DIR *); ++ ++#if TEST_COMPAT (libc, GLIBC_2_1, GLIBC_2_2) ++struct __old_dirent64 *compat_readdir64 (DIR *); ++compat_symbol_reference (libc, compat_readdir64, readdir64, GLIBC_2_1); ++#endif ++ ++static int ++do_test (void) ++{ ++#if TEST_COMPAT (libc, GLIBC_2_1, GLIBC_2_2) ++ ++ /* Directory stream using the non-compat readdir64 symbol. The test ++ checks against this. */ ++ DIR *dir_reference = opendir ("."); ++ TEST_VERIFY_EXIT (dir_reference != NULL); ++ DIR *dir_test = opendir ("."); ++ TEST_VERIFY_EXIT (dir_test != NULL); ++ ++ /* This loop assumes that the enumeration order is consistent for ++ two different handles. Nothing should write to the current ++ directory (in the source tree) while this test runs, so there ++ should not be any difference due to races. */ ++ size_t count = 0; ++ while (true) ++ { ++ errno = 0; ++ struct dirent64 *entry_reference = readdir64 (dir_reference); ++ if (entry_reference == NULL && errno != 0) ++ FAIL_EXIT1 ("readdir64 entry %zu: %m\n", count); ++ struct __old_dirent64 *entry_test = compat_readdir64 (dir_test); ++ if (entry_reference == NULL) ++ { ++ if (errno == EOVERFLOW) ++ { ++ TEST_VERIFY (entry_reference->d_ino ++ != (__ino_t) entry_reference->d_ino); ++ printf ("info: inode number overflow at entry %zu\n", count); ++ break; ++ } ++ if (errno != 0) ++ FAIL_EXIT1 ("compat readdir64 entry %zu: %m\n", count); ++ } ++ ++ /* Check that both streams end at the same time. */ ++ if (entry_reference == NULL) ++ { ++ TEST_VERIFY (entry_test == NULL); ++ break; ++ } ++ else ++ TEST_VERIFY_EXIT (entry_test != NULL); ++ ++ /* Check that the entries are the same. */ ++ TEST_COMPARE_BLOB (entry_reference->d_name, ++ strlen (entry_reference->d_name), ++ entry_test->d_name, strlen (entry_test->d_name)); ++ TEST_COMPARE (entry_reference->d_ino, entry_test->d_ino); ++ TEST_COMPARE (entry_reference->d_off, entry_test->d_off); ++ TEST_COMPARE (entry_reference->d_type, entry_test->d_type); ++ TEST_COMPARE (entry_reference->d_reclen, entry_test->d_reclen); ++ ++ ++count; ++ } ++ printf ("info: %zu directory entries found\n", count); ++ TEST_VERIFY (count >= 3); /* ".", "..", and some source files. */ ++ ++ TEST_COMPARE (closedir (dir_test), 0); ++ TEST_COMPARE (closedir (dir_reference), 0); ++#endif ++ return 0; ++} ++ ++#include <support/test-driver.c> +-- +2.9.3 +
