Compare commits
27 Commits
Author | SHA1 | Date |
---|---|---|
Mike FABIAN | bfe345d460 | |
Florian Weimer | 553bc461eb | |
Florian Weimer | bde5e87fe1 | |
Florian Weimer | 2fc493327f | |
Florian Weimer | 7c3fbba9ca | |
Florian Weimer | d8e28bee29 | |
Florian Weimer | b3a96fb7e3 | |
Florian Weimer | bcf3103e42 | |
Florian Weimer | 5b37233c62 | |
Florian Weimer | c797a16748 | |
Florian Weimer | 427e039240 | |
Jaromir Capik | befbb85eb9 | |
Jaromir Capik | 8cb7db4adb | |
Florian Weimer | d360fa845f | |
Mike FABIAN | 6a3a900270 | |
Carlos O'Donell | 1a5c2c3eb7 | |
Jaromir Capik | 0d00bc430e | |
Siddhesh Poyarekar | 36e7f523d8 | |
Alexandre Oliva | 62f49c6e75 | |
Carlos O'Donell | f132ef66b5 | |
Carlos O'Donell | 8a3ff05495 | |
Siddhesh Poyarekar | de5f208e42 | |
Carlos O'Donell | 210e27365c | |
Carlos O'Donell | 2d2d4d4848 | |
Siddhesh Poyarekar | bb07216351 | |
Carlos O'Donell | 2bd230cbfc | |
Carlos O'Donell | 098cd8cdf9 |
|
@ -0,0 +1,97 @@
|
|||
srpm glibc
|
||||
|
||||
# setup glibc
|
||||
# This path MUST be relative, not absolute
|
||||
GV=$(cd $SRC; echo glibc-2*)
|
||||
|
||||
if [ "$TARGET_ARCH" == "armv7hl" ]; then
|
||||
# rtkaio not supported on ARM
|
||||
rm -rf $SRC/$GV/rtkaio
|
||||
fi
|
||||
|
||||
GLIBCARGS="--prefix=/usr
|
||||
--with-headers=$ROOTFS/usr/include
|
||||
--enable-kernel=2.6.32
|
||||
--enable-bind-now
|
||||
--build $BUILD
|
||||
--host $TARGET
|
||||
--disable-profile
|
||||
--cache-file=config.cache
|
||||
--without-cvs
|
||||
--with-elf
|
||||
--without-gd
|
||||
--disable-sanity-checks
|
||||
--with-tls
|
||||
--with-__thread
|
||||
--enable-obsolete-rpc
|
||||
"
|
||||
|
||||
mcd $BUILDDIR/glibc
|
||||
|
||||
# prefill glibc cache
|
||||
echo libc_cv_forced_unwind=yes > config.cache
|
||||
echo libc_cv_c_cleanup=yes >> config.cache
|
||||
#echo libc_cv_ctors_header=yes >> config.cache
|
||||
echo ac_cv_header_cpuid_h=yes >> config.cache
|
||||
echo libc_cv_gcc_builtin_expect=yes >> config.cache
|
||||
|
||||
$SRC/$GV/configure $GLIBCARGS
|
||||
notparallel
|
||||
make $J ARCH=${KARCH} BUILD_CC=gcc cross-compiling=yes
|
||||
make DESTDIR=$ROOTFS $J ARCH=${KARCH} BUILD_CC=gcc cross-compiling=yes install
|
||||
|
||||
( cd $ROOTFS/usr/include/bits
|
||||
sed '/ifndef.*NO_LONG_DOUBLE/,/#endif/d' < mathdef.h > mathdef.h.new
|
||||
mv mathdef.h.new mathdef.h
|
||||
)
|
||||
|
||||
# 32-bit multilib libgcc needs 32-bit headers
|
||||
if [ ! "$TARGET32" = "" ]; then
|
||||
|
||||
old_CC=$CC
|
||||
old_CXX=$CC
|
||||
export CC="$TARGET-gcc -m32"
|
||||
export CXX="$TARGET-g++ -m32"
|
||||
|
||||
GLIBCARGS="--prefix=/usr
|
||||
--with-headers=$ROOTFS/usr/include
|
||||
--enable-kernel=2.6.32
|
||||
--enable-bind-now
|
||||
--build $BUILD
|
||||
--host $TARGET32
|
||||
--disable-profile
|
||||
--cache-file=config.cache
|
||||
--without-cvs
|
||||
--with-elf
|
||||
--without-gd
|
||||
--disable-sanity-checks
|
||||
--with-tls
|
||||
--with-__thread
|
||||
--enable-obsolete-rpc
|
||||
"
|
||||
|
||||
mcd $BUILDDIR/glibc32
|
||||
|
||||
# prefill glibc cache
|
||||
echo libc_cv_forced_unwind=yes > config.cache
|
||||
echo libc_cv_c_cleanup=yes >> config.cache
|
||||
echo libc_cv_ctors_header=yes >> config.cache
|
||||
echo ac_cv_header_cpuid_h=yes >> config.cache
|
||||
echo libc_cv_gcc_builtin_expect=yes >> config.cache
|
||||
|
||||
$SRC/$GV/configure $GLIBCARGS
|
||||
notparallel
|
||||
make $J ARCH=${KARCH} BUILD_CC=gcc cross-compiling=yes
|
||||
make DESTDIR=$ROOTFS $J ARCH=${KARCH} BUILD_CC=gcc cross-compiling=yes install
|
||||
|
||||
( cd $ROOTFS/usr/include/bits
|
||||
sed '/ifndef.*NO_LONG_DOUBLE/,/#endif/d' < mathdef.h > mathdef.h.new
|
||||
mv mathdef.h.new mathdef.h
|
||||
)
|
||||
|
||||
CC=$old_CC
|
||||
CXX=$old_CXX
|
||||
export $CC
|
||||
export $CXX
|
||||
|
||||
fi
|
|
@ -0,0 +1,117 @@
|
|||
set -vx
|
||||
srpm glibc
|
||||
|
||||
# setup glibc
|
||||
# This path MUST be relative, not absolute
|
||||
GV=$(cd $SRC; echo glibc-2*)
|
||||
GLIBCARGS="--prefix=/usr
|
||||
--with-headers=$ROOTFS/usr/include
|
||||
--enable-kernel=2.6.32
|
||||
--enable-bind-now
|
||||
--build $BUILD
|
||||
--host $TARGET
|
||||
--disable-profile
|
||||
--cache-file=config.cache
|
||||
--without-cvs
|
||||
--with-elf
|
||||
--without-gd
|
||||
--disable-sanity-checks
|
||||
--with-tls
|
||||
--with-__thread
|
||||
--enable-obsolete-rpc
|
||||
"
|
||||
|
||||
mcd $BUILDDIR/glibc-stage1
|
||||
|
||||
# prefill glibc cache
|
||||
echo libc_cv_forced_unwind=yes > config.cache
|
||||
echo libc_cv_c_cleanup=yes >> config.cache
|
||||
#echo libc_cv_ctors_header=yes >> config.cache
|
||||
echo ac_cv_header_cpuid_h=yes >> config.cache
|
||||
echo libc_cv_gcc_builtin_expect=yes >> config.cache
|
||||
|
||||
$SRC/$GV/configure $GLIBCARGS
|
||||
notparallel
|
||||
make DESTDIR=$ROOTFS $J ARCH=${KARCH} BUILD_CC=gcc cross-compiling=yes install-headers
|
||||
touch $ROOTFS/usr/include/gnu/stubs.h
|
||||
touch $ROOTFS/usr/include/bits/stdio_lim.h
|
||||
|
||||
( cd $ROOTFS/usr/include/bits
|
||||
sed '/ifndef.*NO_LONG_DOUBLE/,/#endif/d' < mathdef.h > mathdef.h.new
|
||||
mv mathdef.h.new mathdef.h
|
||||
)
|
||||
|
||||
# We also build just enough files to link libgcc.so. The fake
|
||||
# libc.so will never actually get used, but simplifies the boostrap.
|
||||
make $J ARCH=${KARCH} BUILD_CC=gcc cross-compiling=yes csu/subdir_lib
|
||||
|
||||
mkdirp $ROOTFS/usr/lib${SUFFIX}
|
||||
for file in `cd csu; echo crt*.o`; do
|
||||
echo "" | $TARGET-as -o $ROOTFS/usr/lib${SUFFIX}/$file
|
||||
done
|
||||
$TARGET-gcc -nostdlib -nostartfiles -shared -x c /dev/null\
|
||||
-o $ROOTFS/usr/lib${SUFFIX}/libc.so
|
||||
|
||||
|
||||
# 32-bit multilib libgcc needs stub 32-bit libraries
|
||||
if [ ! "$TARGET32" = "" ]; then
|
||||
|
||||
old_CC=$CC
|
||||
old_CXX=$CC
|
||||
export CC="$TARGET-gcc -m32"
|
||||
export CXX="$TARGET-g++ -m32"
|
||||
|
||||
# setup 32-bit glibc headers
|
||||
GLIBCARGS="--prefix=/usr
|
||||
--with-headers=$ROOTFS/usr/include
|
||||
--enable-kernel=2.6.32
|
||||
--enable-bind-now
|
||||
--build $BUILD
|
||||
--host $TARGET32
|
||||
--disable-profile
|
||||
--cache-file=config.cache
|
||||
--without-cvs
|
||||
--with-elf
|
||||
--without-gd
|
||||
--disable-sanity-checks
|
||||
--with-tls
|
||||
--with-__thread
|
||||
--enable-obsolete-rpc
|
||||
"
|
||||
|
||||
mcd $BUILDDIR/glibc32-stage1
|
||||
|
||||
# prefill glibc cache
|
||||
echo libc_cv_forced_unwind=yes > config.cache
|
||||
echo libc_cv_c_cleanup=yes >> config.cache
|
||||
#echo libc_cv_ctors_header=yes >> config.cache
|
||||
echo ac_cv_header_cpuid_h=yes >> config.cache
|
||||
echo libc_cv_gcc_builtin_expect=yes >> config.cache
|
||||
|
||||
$SRC/$GV/configure $GLIBCARGS
|
||||
notparallel
|
||||
make DESTDIR=$ROOTFS $J ARCH=${KARCH} BUILD_CC=gcc cross-compiling=yes install-headers
|
||||
touch $ROOTFS/usr/include/gnu/stubs.h
|
||||
touch $ROOTFS/usr/include/bits/stdio_lim.h
|
||||
|
||||
( cd $ROOTFS/usr/include/bits
|
||||
sed '/ifndef.*NO_LONG_DOUBLE/,/#endif/d' < mathdef.h > mathdef.h.new
|
||||
mv mathdef.h.new mathdef.h
|
||||
)
|
||||
|
||||
# We also build just enough files to link libgcc.so. The fake
|
||||
# libc.so will never actually get used, but simplifies the boostrap.
|
||||
make $J ARCH=${KARCH} BUILD_CC=gcc cross-compiling=yes csu/subdir_lib
|
||||
|
||||
mkdirp $ROOTFS/usr/lib
|
||||
for file in `cd csu; echo crt*.o`; do
|
||||
echo "" | $TARGET-as --32 -o $ROOTFS/usr/lib/$file
|
||||
done
|
||||
$CC -m32 -nostdlib -nostartfiles -shared -x c /dev/null\
|
||||
-o $ROOTFS/usr/lib/libc.so
|
||||
|
||||
CC=$old_CC
|
||||
CXX=$old_CXX
|
||||
export $CC
|
||||
export $CXX
|
||||
fi
|
|
@ -8,6 +8,7 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -21,6 +22,7 @@ const char *alias_file = DATADIR "/locale/locale.alias";
|
|||
const char *locar_file = PREFIX "/lib/locale/locale-archive";
|
||||
const char *tmpl_file = PREFIX "/lib/locale/locale-archive.tmpl";
|
||||
const char *loc_path = PREFIX "/lib/locale/";
|
||||
/* Flags set by `--verbose` option. */
|
||||
int be_quiet = 1;
|
||||
int verbose = 0;
|
||||
int max_locarchive_open_retry = 10;
|
||||
|
@ -122,7 +124,7 @@ open_tmpl_archive (struct locarhandle *ah)
|
|||
ah->mmaped = (head.sumhash_offset
|
||||
+ head.sumhash_size * sizeof (struct sumhashent));
|
||||
if (ah->mmaped > (unsigned long) st.st_size)
|
||||
error (EXIT_FAILURE, 0, "locale archite template file truncated");
|
||||
error (EXIT_FAILURE, 0, "locale archive template file truncated");
|
||||
ah->mmaped = st.st_size;
|
||||
ah->reserved = st.st_size;
|
||||
|
||||
|
@ -257,7 +259,9 @@ compute_data (struct locarhandle *ah, struct nameent *name, size_t sumused,
|
|||
|
||||
static int
|
||||
fill_archive (struct locarhandle *tmpl_ah,
|
||||
const char *fname, size_t nlist, char *list[],
|
||||
const char *fname,
|
||||
size_t install_langs_count, char *install_langs_list[],
|
||||
size_t nlist, char *list[],
|
||||
const char *primary)
|
||||
{
|
||||
struct locarhandle ah;
|
||||
|
@ -288,11 +292,40 @@ fill_archive (struct locarhandle *tmpl_ah,
|
|||
for (cnt = used = 0; cnt < head->namehash_size; ++cnt)
|
||||
if (namehashtab[cnt].locrec_offset != 0)
|
||||
{
|
||||
char * name;
|
||||
int i;
|
||||
assert (used < head->namehash_used);
|
||||
names[used].name = tmpl_ah->addr + namehashtab[cnt].name_offset;
|
||||
names[used++].locrec
|
||||
= (struct locrecent *) ((char *) tmpl_ah->addr +
|
||||
namehashtab[cnt].locrec_offset);
|
||||
name = tmpl_ah->addr + namehashtab[cnt].name_offset;
|
||||
if (install_langs_count == 0)
|
||||
{
|
||||
/* Always intstall the entry. */
|
||||
names[used].name = name;
|
||||
names[used++].locrec
|
||||
= (struct locrecent *) ((char *) tmpl_ah->addr +
|
||||
namehashtab[cnt].locrec_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Only install the entry if the user asked for it via
|
||||
--install-langs. */
|
||||
for (i = 0; i < install_langs_count; i++)
|
||||
{
|
||||
/* Add one for "_" and one for the null terminator. */
|
||||
size_t len = strlen (install_langs_list[i]) + 2;
|
||||
char *install_lang = (char *)xmalloc (len);
|
||||
strcpy (install_lang, install_langs_list[i]);
|
||||
if (strchr (install_lang, '_') == NULL)
|
||||
strcat (install_lang, "_");
|
||||
if (strncmp (name, install_lang, strlen (install_lang)) == 0)
|
||||
{
|
||||
names[used].name = name;
|
||||
names[used++].locrec
|
||||
= (struct locrecent *) ((char *)tmpl_ah->addr
|
||||
+ namehashtab[cnt].locrec_offset);
|
||||
}
|
||||
free (install_lang);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Sort the names. */
|
||||
|
@ -542,6 +575,62 @@ fill_archive (struct locarhandle *tmpl_ah,
|
|||
return result;
|
||||
}
|
||||
|
||||
void usage()
|
||||
{
|
||||
printf ("\
|
||||
Usage: build-locale-archive [OPTION]... [TEMPLATE-FILE] [ARCHIVE-FILE]\n\
|
||||
Builds a locale archive from a template file.\n\
|
||||
Options:\n\
|
||||
-h, --help Print this usage message.\n\
|
||||
-v, --verbose Verbose execution.\n\
|
||||
-l, --install-langs=LIST Only include locales given in LIST into the \n\
|
||||
locale archive. LIST is a colon separated list\n\
|
||||
of locale prefixes, for example \"de:en:ja\".\n\
|
||||
The special argument \"all\" means to install\n\
|
||||
all languages and it must be present by itself.\n\
|
||||
If \"all\" is present with any other language it\n\
|
||||
will be treated as the name of a locale.\n\
|
||||
If the --install-langs option is missing, all\n\
|
||||
locales are installed. The colon separated list\n\
|
||||
can contain any strings matching the beginning of\n\
|
||||
locale names.\n\
|
||||
If a string does not contain a \"_\", it is added.\n\
|
||||
Examples:\n\
|
||||
--install-langs=\"en\"\n\
|
||||
installs en_US, en_US.iso88591,\n\
|
||||
en_US.iso885915, en_US.utf8,\n\
|
||||
en_GB ...\n\
|
||||
--install-langs=\"en_US.utf8\"\n\
|
||||
installs only en_US.utf8.\n\
|
||||
--install-langs=\"ko\"\n\
|
||||
installs ko_KR, ko_KR.euckr,\n\
|
||||
ko_KR.utf8 but *not* kok_IN\n\
|
||||
because \"ko\" does not contain\n\
|
||||
\"_\" and it is silently added\n\
|
||||
--install-langs\"ko:kok\"\n\
|
||||
installs ko_KR, ko_KR.euckr,\n\
|
||||
ko_KR.utf8, kok_IN, and\n\
|
||||
kok_IN.utf8.\n\
|
||||
--install-langs=\"POSIX\" will\n\
|
||||
installs *no* locales at all\n\
|
||||
because POSIX matches none of\n\
|
||||
the locales. Actually, any string\n\
|
||||
matching nothing will do that.\n\
|
||||
POSIX and C will always be\n\
|
||||
available because they are\n\
|
||||
builtin.\n\
|
||||
Aliases are installed as well,\n\
|
||||
i.e. --install-langs=\"de\"\n\
|
||||
will install not only every locale starting with\n\
|
||||
\"de\" but also the aliases \"deutsch\"\n\
|
||||
and and \"german\" although the latter does not\n\
|
||||
start with \"de\".\n\
|
||||
\n\
|
||||
If the arguments TEMPLATE-FILE and ARCHIVE-FILE are not given the locations\n\
|
||||
where the glibc used expects these files are used by default.\n\
|
||||
");
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
char path[4096];
|
||||
|
@ -549,22 +638,133 @@ int main (int argc, char *argv[])
|
|||
struct dirent64 *d;
|
||||
struct stat64 st;
|
||||
char *list[16384], *primary;
|
||||
char *lang;
|
||||
int install_langs_count = 0;
|
||||
int i;
|
||||
char *install_langs_arg, *ila_start;
|
||||
char **install_langs_list;
|
||||
unsigned int cnt = 0;
|
||||
struct locarhandle tmpl_ah;
|
||||
char *new_locar_fname = NULL;
|
||||
size_t loc_path_len = strlen (loc_path);
|
||||
|
||||
while (1)
|
||||
{
|
||||
int c;
|
||||
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"install-langs", required_argument, 0, 'l'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
/* getopt_long stores the option index here. */
|
||||
int option_index = 0;
|
||||
|
||||
c = getopt_long (argc, argv, "vhl:",
|
||||
long_options, &option_index);
|
||||
|
||||
/* Detect the end of the options. */
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
printf ("unknown option %s", long_options[option_index].name);
|
||||
if (optarg)
|
||||
printf (" with arg %s", optarg);
|
||||
printf ("\n");
|
||||
usage ();
|
||||
exit (1);
|
||||
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
be_quiet = 0;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
usage ();
|
||||
exit (0);
|
||||
|
||||
case 'l':
|
||||
install_langs_arg = ila_start = strdup (optarg);
|
||||
/* If the argument to --install-lang is "all", do
|
||||
not limit the list of languages to install and install
|
||||
them all. We do not support installing a single locale
|
||||
called "all". */
|
||||
#define MAGIC_INSTALL_ALL "all"
|
||||
if (install_langs_arg != NULL
|
||||
&& install_langs_arg[0] != '\0'
|
||||
&& !(strncmp(install_langs_arg, MAGIC_INSTALL_ALL,
|
||||
strlen(MAGIC_INSTALL_ALL)) == 0
|
||||
&& strlen (install_langs_arg) == 3))
|
||||
{
|
||||
/* Count the number of languages we will install. */
|
||||
while (true)
|
||||
{
|
||||
lang = strtok(install_langs_arg, ":;,");
|
||||
if (lang == NULL)
|
||||
break;
|
||||
install_langs_count++;
|
||||
install_langs_arg = NULL;
|
||||
}
|
||||
free (ila_start);
|
||||
/* Copy the list. */
|
||||
install_langs_list = (char **)xmalloc (sizeof(char *) * install_langs_count);
|
||||
install_langs_arg = ila_start = strdup (optarg);
|
||||
install_langs_count = 0;
|
||||
while (true)
|
||||
{
|
||||
lang = strtok(install_langs_arg, ":;,");
|
||||
if (lang == NULL)
|
||||
break;
|
||||
install_langs_list[install_langs_count] = lang;
|
||||
install_langs_count++;
|
||||
install_langs_arg = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '?':
|
||||
/* getopt_long already printed an error message. */
|
||||
usage ();
|
||||
exit (0);
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
tmpl_ah.fname = NULL;
|
||||
if (optind < argc)
|
||||
tmpl_ah.fname = argv[optind];
|
||||
if (optind + 1 < argc)
|
||||
new_locar_fname = argv[optind + 1];
|
||||
if (verbose)
|
||||
{
|
||||
if (tmpl_ah.fname)
|
||||
printf("input archive file specified on command line: %s\n",
|
||||
tmpl_ah.fname);
|
||||
else
|
||||
printf("using default input archive file.\n");
|
||||
if (new_locar_fname)
|
||||
printf("output archive file specified on command line: %s\n",
|
||||
new_locar_fname);
|
||||
else
|
||||
printf("using default output archive file.\n");
|
||||
}
|
||||
|
||||
dirp = opendir (loc_path);
|
||||
if (dirp == NULL)
|
||||
error (EXIT_FAILURE, errno, "cannot open directory \"%s\"", loc_path);
|
||||
|
||||
/* Use the template file as specified on the command line. */
|
||||
tmpl_ah.fname = NULL;
|
||||
if (argc > 1)
|
||||
tmpl_ah.fname = argv[1];
|
||||
|
||||
open_tmpl_archive (&tmpl_ah);
|
||||
|
||||
unlink (locar_file);
|
||||
if (new_locar_fname)
|
||||
unlink (new_locar_fname);
|
||||
else
|
||||
unlink (locar_file);
|
||||
primary = getenv ("LC_ALL");
|
||||
if (primary == NULL)
|
||||
primary = getenv ("LANG");
|
||||
|
@ -575,7 +775,8 @@ int main (int argc, char *argv[])
|
|||
&& strncmp (primary, "zh", 2) != 0)
|
||||
{
|
||||
char *ptr = malloc (strlen (primary) + strlen (".utf8") + 1), *p, *q;
|
||||
|
||||
/* This leads to invalid locales sometimes:
|
||||
de_DE.iso885915@euro -> de_DE.utf8@euro */
|
||||
if (ptr != NULL)
|
||||
{
|
||||
p = ptr;
|
||||
|
@ -640,9 +841,16 @@ int main (int argc, char *argv[])
|
|||
closedir (dirp);
|
||||
/* Store the archive to the file specified as the second argument on the
|
||||
command line or the default locale archive. */
|
||||
fill_archive (&tmpl_ah, argc > 2 ? argv[2] : NULL, cnt, list, primary);
|
||||
fill_archive (&tmpl_ah, new_locar_fname,
|
||||
install_langs_count, install_langs_list,
|
||||
cnt, list, primary);
|
||||
close_archive (&tmpl_ah);
|
||||
truncate (tmpl_file, 0);
|
||||
if (install_langs_count > 0)
|
||||
{
|
||||
free (ila_start);
|
||||
free (install_langs_list);
|
||||
}
|
||||
char *tz_argv[] = { "/usr/sbin/tzdata-update", NULL };
|
||||
execve (tz_argv[0], (char *const *)tz_argv, (char *const *)&tz_argv[1]);
|
||||
exit (0);
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
#!/bin/bash
|
||||
# Autogeneries the quilt `series` from the patch order in the spec file.
|
||||
# We don't use `quilt setup` because it makes a huge mess and doesn't work.
|
||||
component="glibc"
|
||||
rm -f series.new
|
||||
extra_args="--fuzz=0"
|
||||
count=0
|
||||
# Filter out the patches, and use `_` as our pseudo-IFS to prevent expansion.
|
||||
for i in `grep '^%patch' glibc.spec | sed -e 's,%patch,,g' -e 's, ,_,g'`; do
|
||||
# Split the patch into number and arguments.
|
||||
# 1 - Patch number.
|
||||
# 2-N - Patch arguments.
|
||||
# Get back our elements by undoing pseudo-IFS change.
|
||||
elements=(`echo $i | sed -e 's,_, ,g'`)
|
||||
num=${elements[0]}
|
||||
args=${elements[@]:1}
|
||||
# Find the next patch that applies in order and write it out.
|
||||
# This way we transform the patch # list into a patch file list in order.
|
||||
grep "Patch${num}: " glibc.spec \
|
||||
| sed -e 's,Patch.*: ,,g' -e "s,\$, ${args[@]} ${extra_args},g" \
|
||||
| sed -e "s,%{name},${component},g" \
|
||||
>> series.new
|
||||
((count++))
|
||||
done
|
||||
# Double check we processed the correct number of patches.
|
||||
fcount=`wc -l series.new | sed -e 's, .*$,,g'`
|
||||
if [ $fcount -ne $count ]; then
|
||||
echo "Error! Processed patch count doesn't match spec file count ($fcount != $count)."
|
||||
exit 1
|
||||
fi
|
||||
echo "Processed $count patches."
|
||||
mv series.new series
|
||||
echo "Generated quilt ./series file, please commit."
|
||||
exit 0
|
|
@ -0,0 +1,554 @@
|
|||
Index: b/resolv/nss_dns/dns-host.c
|
||||
===================================================================
|
||||
--- a/resolv/nss_dns/dns-host.c
|
||||
+++ b/resolv/nss_dns/dns-host.c
|
||||
@@ -1031,7 +1031,10 @@ gaih_getanswer_slice (const querybuf *an
|
||||
int h_namelen = 0;
|
||||
|
||||
if (ancount == 0)
|
||||
- return NSS_STATUS_NOTFOUND;
|
||||
+ {
|
||||
+ *h_errnop = HOST_NOT_FOUND;
|
||||
+ return NSS_STATUS_NOTFOUND;
|
||||
+ }
|
||||
|
||||
while (ancount-- > 0 && cp < end_of_message && had_error == 0)
|
||||
{
|
||||
@@ -1208,7 +1211,14 @@ gaih_getanswer_slice (const querybuf *an
|
||||
/* Special case here: if the resolver sent a result but it only
|
||||
contains a CNAME while we are looking for a T_A or T_AAAA record,
|
||||
we fail with NOTFOUND instead of TRYAGAIN. */
|
||||
- return canon == NULL ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
|
||||
+ if (canon != NULL)
|
||||
+ {
|
||||
+ *h_errnop = HOST_NOT_FOUND;
|
||||
+ return NSS_STATUS_NOTFOUND;
|
||||
+ }
|
||||
+
|
||||
+ *h_errnop = NETDB_INTERNAL;
|
||||
+ return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
|
||||
@@ -1222,11 +1232,101 @@ gaih_getanswer (const querybuf *answer1,
|
||||
|
||||
enum nss_status status = NSS_STATUS_NOTFOUND;
|
||||
|
||||
+ /* Combining the NSS status of two distinct queries requires some
|
||||
+ compromise and attention to symmetry (A or AAAA queries can be
|
||||
+ returned in any order). What follows is a breakdown of how this
|
||||
+ code is expected to work and why. We discuss only SUCCESS,
|
||||
+ TRYAGAIN, NOTFOUND and UNAVAIL, since they are the only returns
|
||||
+ that apply (though RETURN and MERGE exist). We make a distinction
|
||||
+ between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable).
|
||||
+ A recoverable TRYAGAIN is almost always due to buffer size issues
|
||||
+ and returns ERANGE in errno and the caller is expected to retry
|
||||
+ with a larger buffer.
|
||||
+
|
||||
+ Lastly, you may be tempted to make significant changes to the
|
||||
+ conditions in this code to bring about symmetry between responses.
|
||||
+ Please don't change anything without due consideration for
|
||||
+ expected application behaviour. Some of the synthesized responses
|
||||
+ aren't very well thought out and sometimes appear to imply that
|
||||
+ IPv4 responses are always answer 1, and IPv6 responses are always
|
||||
+ answer 2, but that's not true (see the implemetnation of send_dg
|
||||
+ and send_vc to see response can arrive in any order, particlarly
|
||||
+ for UDP). However, we expect it holds roughly enough of the time
|
||||
+ that this code works, but certainly needs to be fixed to make this
|
||||
+ a more robust implementation.
|
||||
+
|
||||
+ ----------------------------------------------
|
||||
+ | Answer 1 Status / | Synthesized | Reason |
|
||||
+ | Answer 2 Status | Status | |
|
||||
+ |--------------------------------------------|
|
||||
+ | SUCCESS/SUCCESS | SUCCESS | [1] |
|
||||
+ | SUCCESS/TRYAGAIN | TRYAGAIN | [5] |
|
||||
+ | SUCCESS/TRYAGAIN' | SUCCESS | [1] |
|
||||
+ | SUCCESS/NOTFOUND | SUCCESS | [1] |
|
||||
+ | SUCCESS/UNAVAIL | SUCCESS | [1] |
|
||||
+ | TRYAGAIN/SUCCESS | TRYAGAIN | [2] |
|
||||
+ | TRYAGAIN/TRYAGAIN | TRYAGAIN | [2] |
|
||||
+ | TRYAGAIN/TRYAGAIN' | TRYAGAIN | [2] |
|
||||
+ | TRYAGAIN/NOTFOUND | TRYAGAIN | [2] |
|
||||
+ | TRYAGAIN/UNAVAIL | TRYAGAIN | [2] |
|
||||
+ | TRYAGAIN'/SUCCESS | SUCCESS | [3] |
|
||||
+ | TRYAGAIN'/TRYAGAIN | TRYAGAIN | [3] |
|
||||
+ | TRYAGAIN'/TRYAGAIN' | TRYAGAIN' | [3] |
|
||||
+ | TRYAGAIN'/NOTFOUND | TRYAGAIN' | [3] |
|
||||
+ | TRYAGAIN'/UNAVAIL | UNAVAIL | [3] |
|
||||
+ | NOTFOUND/SUCCESS | SUCCESS | [3] |
|
||||
+ | NOTFOUND/TRYAGAIN | TRYAGAIN | [3] |
|
||||
+ | NOTFOUND/TRYAGAIN' | TRYAGAIN' | [3] |
|
||||
+ | NOTFOUND/NOTFOUND | NOTFOUND | [3] |
|
||||
+ | NOTFOUND/UNAVAIL | UNAVAIL | [3] |
|
||||
+ | UNAVAIL/SUCCESS | UNAVAIL | [4] |
|
||||
+ | UNAVAIL/TRYAGAIN | UNAVAIL | [4] |
|
||||
+ | UNAVAIL/TRYAGAIN' | UNAVAIL | [4] |
|
||||
+ | UNAVAIL/NOTFOUND | UNAVAIL | [4] |
|
||||
+ | UNAVAIL/UNAVAIL | UNAVAIL | [4] |
|
||||
+ ----------------------------------------------
|
||||
+
|
||||
+ [1] If the first response is a success we return success.
|
||||
+ This ignores the state of the second answer and in fact
|
||||
+ incorrectly sets errno and h_errno to that of the second
|
||||
+ answer. However because the response is a success we ignore
|
||||
+ *errnop and *h_errnop (though that means you touched errno on
|
||||
+ success). We are being conservative here and returning the
|
||||
+ likely IPv4 response in the first answer as a success.
|
||||
+
|
||||
+ [2] If the first response is a recoverable TRYAGAIN we return
|
||||
+ that instead of looking at the second response. The
|
||||
+ expectation here is that we have failed to get an IPv4 response
|
||||
+ and should retry both queries.
|
||||
+
|
||||
+ [3] If the first response was not a SUCCESS and the second
|
||||
+ response is not NOTFOUND (had a SUCCESS, need to TRYAGAIN,
|
||||
+ or failed entirely e.g. TRYAGAIN' and UNAVAIL) then use the
|
||||
+ result from the second response, otherwise the first responses
|
||||
+ status is used. Again we have some odd side-effects when the
|
||||
+ second response is NOTFOUND because we overwrite *errnop and
|
||||
+ *h_errnop that means that a first answer of NOTFOUND might see
|
||||
+ its *errnop and *h_errnop values altered. Whether it matters
|
||||
+ in practice that a first response NOTFOUND has the wrong
|
||||
+ *errnop and *h_errnop is undecided.
|
||||
+
|
||||
+ [4] If the first response is UNAVAIL we return that instead of
|
||||
+ looking at the second response. The expectation here is that
|
||||
+ it will have failed similarly e.g. configuration failure.
|
||||
+
|
||||
+ [5] Testing this code is complicated by the fact that truncated
|
||||
+ second response buffers might be returned as SUCCESS if the
|
||||
+ first answer is a SUCCESS. To fix this we add symmetry to
|
||||
+ TRYAGAIN with the second response. If the second response
|
||||
+ is a recoverable error we now return TRYAGIN even if the first
|
||||
+ response was SUCCESS. */
|
||||
+
|
||||
if (anslen1 > 0)
|
||||
status = gaih_getanswer_slice(answer1, anslen1, qname,
|
||||
&pat, &buffer, &buflen,
|
||||
errnop, h_errnop, ttlp,
|
||||
&first);
|
||||
+
|
||||
if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND
|
||||
|| (status == NSS_STATUS_TRYAGAIN
|
||||
/* We want to look at the second answer in case of an
|
||||
@@ -1242,8 +1342,15 @@ gaih_getanswer (const querybuf *answer1,
|
||||
&pat, &buffer, &buflen,
|
||||
errnop, h_errnop, ttlp,
|
||||
&first);
|
||||
+ /* Use the second response status in some cases. */
|
||||
if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND)
|
||||
status = status2;
|
||||
+ /* Do not return a truncated second response (unless it was
|
||||
+ unavoidable e.g. unrecoverable TRYAGAIN). */
|
||||
+ if (status == NSS_STATUS_SUCCESS
|
||||
+ && (status2 == NSS_STATUS_TRYAGAIN
|
||||
+ && *errnop == ERANGE && *h_errnop != NO_RECOVERY))
|
||||
+ status = NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
return status;
|
||||
Index: b/resolv/res_query.c
|
||||
===================================================================
|
||||
--- a/resolv/res_query.c
|
||||
+++ b/resolv/res_query.c
|
||||
@@ -396,6 +396,7 @@ __libc_res_nsearch(res_state statp,
|
||||
{
|
||||
free (*answerp2);
|
||||
*answerp2 = NULL;
|
||||
+ *nanswerp2 = 0;
|
||||
*answerp2_malloced = 0;
|
||||
}
|
||||
}
|
||||
@@ -447,6 +448,7 @@ __libc_res_nsearch(res_state statp,
|
||||
{
|
||||
free (*answerp2);
|
||||
*answerp2 = NULL;
|
||||
+ *nanswerp2 = 0;
|
||||
*answerp2_malloced = 0;
|
||||
}
|
||||
|
||||
@@ -521,6 +523,7 @@ __libc_res_nsearch(res_state statp,
|
||||
{
|
||||
free (*answerp2);
|
||||
*answerp2 = NULL;
|
||||
+ *nanswerp2 = 0;
|
||||
*answerp2_malloced = 0;
|
||||
}
|
||||
if (saved_herrno != -1)
|
||||
Index: b/resolv/res_send.c
|
||||
===================================================================
|
||||
--- a/resolv/res_send.c
|
||||
+++ b/resolv/res_send.c
|
||||
@@ -1,3 +1,20 @@
|
||||
+/* Copyright (C) 2016 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/>. */
|
||||
+
|
||||
/*
|
||||
* Copyright (c) 1985, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@@ -361,6 +378,8 @@ __libc_res_nsend(res_state statp, const
|
||||
#ifdef USE_HOOKS
|
||||
if (__glibc_unlikely (statp->qhook || statp->rhook)) {
|
||||
if (anssiz < MAXPACKET && ansp) {
|
||||
+ /* Always allocate MAXPACKET, callers expect
|
||||
+ this specific size. */
|
||||
u_char *buf = malloc (MAXPACKET);
|
||||
if (buf == NULL)
|
||||
return (-1);
|
||||
@@ -660,6 +679,77 @@ libresolv_hidden_def (res_nsend)
|
||||
|
||||
/* Private */
|
||||
|
||||
+/* The send_vc function is responsible for sending a DNS query over TCP
|
||||
+ to the nameserver numbered NS from the res_state STATP i.e.
|
||||
+ EXT(statp).nssocks[ns]. The function supports sending both IPv4 and
|
||||
+ IPv6 queries at the same serially on the same socket.
|
||||
+
|
||||
+ Please note that for TCP there is no way to disable sending both
|
||||
+ queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP
|
||||
+ and sends the queries serially and waits for the result after each
|
||||
+ sent query. This implemetnation should be corrected to honour these
|
||||
+ options.
|
||||
+
|
||||
+ Please also note that for TCP we send both queries over the same
|
||||
+ socket one after another. This technically violates best practice
|
||||
+ since the server is allowed to read the first query, respond, and
|
||||
+ then close the socket (to service another client). If the server
|
||||
+ does this, then the remaining second query in the socket data buffer
|
||||
+ will cause the server to send the client an RST which will arrive
|
||||
+ asynchronously and the client's OS will likely tear down the socket
|
||||
+ receive buffer resulting in a potentially short read and lost
|
||||
+ response data. This will force the client to retry the query again,
|
||||
+ and this process may repeat until all servers and connection resets
|
||||
+ are exhausted and then the query will fail. It's not known if this
|
||||
+ happens with any frequency in real DNS server implementations. This
|
||||
+ implementation should be corrected to use two sockets by default for
|
||||
+ parallel queries.
|
||||
+
|
||||
+ The query stored in BUF of BUFLEN length is sent first followed by
|
||||
+ the query stored in BUF2 of BUFLEN2 length. Queries are sent
|
||||
+ serially on the same socket.
|
||||
+
|
||||
+ Answers to the query are stored firstly in *ANSP up to a max of
|
||||
+ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
|
||||
+ is non-NULL (to indicate that modifying the answer buffer is allowed)
|
||||
+ then malloc is used to allocate a new response buffer and ANSCP and
|
||||
+ ANSP will both point to the new buffer. If more than *ANSSIZP bytes
|
||||
+ are needed but ANSCP is NULL, then as much of the response as
|
||||
+ possible is read into the buffer, but the results will be truncated.
|
||||
+ When truncation happens because of a small answer buffer the DNS
|
||||
+ packets header feild TC will bet set to 1, indicating a truncated
|
||||
+ message and the rest of the socket data will be read and discarded.
|
||||
+
|
||||
+ Answers to the query are stored secondly in *ANSP2 up to a max of
|
||||
+ *ANSSIZP2 bytes, with the actual response length stored in
|
||||
+ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
|
||||
+ is non-NULL (required for a second query) then malloc is used to
|
||||
+ allocate a new response buffer, *ANSSIZP2 is set to the new buffer
|
||||
+ size and *ANSP2_MALLOCED is set to 1.
|
||||
+
|
||||
+ The ANSP2_MALLOCED argument will eventually be removed as the
|
||||
+ change in buffer pointer can be used to detect the buffer has
|
||||
+ changed and that the caller should use free on the new buffer.
|
||||
+
|
||||
+ Note that the answers may arrive in any order from the server and
|
||||
+ therefore the first and second answer buffers may not correspond to
|
||||
+ the first and second queries.
|
||||
+
|
||||
+ It is not supported to call this function with a non-NULL ANSP2
|
||||
+ but a NULL ANSCP. Put another way, you can call send_vc with a
|
||||
+ single unmodifiable buffer or two modifiable buffers, but no other
|
||||
+ combination is supported.
|
||||
+
|
||||
+ It is the caller's responsibility to free the malloc allocated
|
||||
+ buffers by detecting that the pointers have changed from their
|
||||
+ original values i.e. *ANSCP or *ANSP2 has changed.
|
||||
+
|
||||
+ If errors are encountered then *TERRNO is set to an appropriate
|
||||
+ errno value and a zero result is returned for a recoverable error,
|
||||
+ and a less-than zero result is returned for a non-recoverable error.
|
||||
+
|
||||
+ If no errors are encountered then *TERRNO is left unmodified and
|
||||
+ a the length of the first response in bytes is returned. */
|
||||
static int
|
||||
send_vc(res_state statp,
|
||||
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
|
||||
@@ -669,11 +759,7 @@ send_vc(res_state statp,
|
||||
{
|
||||
const HEADER *hp = (HEADER *) buf;
|
||||
const HEADER *hp2 = (HEADER *) buf2;
|
||||
- u_char *ans = *ansp;
|
||||
- int orig_anssizp = *anssizp;
|
||||
- // XXX REMOVE
|
||||
- // int anssiz = *anssizp;
|
||||
- HEADER *anhp = (HEADER *) ans;
|
||||
+ HEADER *anhp = (HEADER *) *ansp;
|
||||
struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns];
|
||||
int truncating, connreset, n;
|
||||
/* On some architectures compiler might emit a warning indicating
|
||||
@@ -766,6 +852,8 @@ send_vc(res_state statp,
|
||||
* Receive length & response
|
||||
*/
|
||||
int recvresp1 = 0;
|
||||
+ /* Skip the second response if there is no second query.
|
||||
+ To do that we mark the second response as received. */
|
||||
int recvresp2 = buf2 == NULL;
|
||||
uint16_t rlen16;
|
||||
read_len:
|
||||
@@ -802,40 +890,14 @@ send_vc(res_state statp,
|
||||
u_char **thisansp;
|
||||
int *thisresplenp;
|
||||
if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
|
||||
+ /* We have not received any responses
|
||||
+ yet or we only have one response to
|
||||
+ receive. */
|
||||
thisanssizp = anssizp;
|
||||
thisansp = anscp ?: ansp;
|
||||
assert (anscp != NULL || ansp2 == NULL);
|
||||
thisresplenp = &resplen;
|
||||
} else {
|
||||
- if (*anssizp != MAXPACKET) {
|
||||
- /* No buffer allocated for the first
|
||||
- reply. We can try to use the rest
|
||||
- of the user-provided buffer. */
|
||||
-#if __GNUC_PREREQ (4, 7)
|
||||
- DIAG_PUSH_NEEDS_COMMENT;
|
||||
- DIAG_IGNORE_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
|
||||
-#endif
|
||||
-#if _STRING_ARCH_unaligned
|
||||
- *anssizp2 = orig_anssizp - resplen;
|
||||
- *ansp2 = *ansp + resplen;
|
||||
-#else
|
||||
- int aligned_resplen
|
||||
- = ((resplen + __alignof__ (HEADER) - 1)
|
||||
- & ~(__alignof__ (HEADER) - 1));
|
||||
- *anssizp2 = orig_anssizp - aligned_resplen;
|
||||
- *ansp2 = *ansp + aligned_resplen;
|
||||
-#endif
|
||||
-#if __GNUC_PREREQ (4, 7)
|
||||
- DIAG_POP_NEEDS_COMMENT;
|
||||
-#endif
|
||||
- } else {
|
||||
- /* The first reply did not fit into the
|
||||
- user-provided buffer. Maybe the second
|
||||
- answer will. */
|
||||
- *anssizp2 = orig_anssizp;
|
||||
- *ansp2 = *ansp;
|
||||
- }
|
||||
-
|
||||
thisanssizp = anssizp2;
|
||||
thisansp = ansp2;
|
||||
thisresplenp = resplen2;
|
||||
@@ -843,10 +905,14 @@ send_vc(res_state statp,
|
||||
anhp = (HEADER *) *thisansp;
|
||||
|
||||
*thisresplenp = rlen;
|
||||
- if (rlen > *thisanssizp) {
|
||||
- /* Yes, we test ANSCP here. If we have two buffers
|
||||
- both will be allocatable. */
|
||||
- if (__glibc_likely (anscp != NULL)) {
|
||||
+ /* Is the answer buffer too small? */
|
||||
+ if (*thisanssizp < rlen) {
|
||||
+ /* If the current buffer is non-NULL and it's not
|
||||
+ pointing at the static user-supplied buffer then
|
||||
+ we can reallocate it. */
|
||||
+ if (thisansp != NULL && thisansp != ansp) {
|
||||
+ /* Always allocate MAXPACKET, callers expect
|
||||
+ this specific size. */
|
||||
u_char *newp = malloc (MAXPACKET);
|
||||
if (newp == NULL) {
|
||||
*terrno = ENOMEM;
|
||||
@@ -858,6 +924,9 @@ send_vc(res_state statp,
|
||||
if (thisansp == ansp2)
|
||||
*ansp2_malloced = 1;
|
||||
anhp = (HEADER *) newp;
|
||||
+ /* A uint16_t can't be larger than MAXPACKET
|
||||
+ thus it's safe to allocate MAXPACKET but
|
||||
+ read RLEN bytes instead. */
|
||||
len = rlen;
|
||||
} else {
|
||||
Dprint(statp->options & RES_DEBUG,
|
||||
@@ -1021,6 +1090,66 @@ reopen (res_state statp, int *terrno, in
|
||||
return 1;
|
||||
}
|
||||
|
||||
+/* The send_dg function is responsible for sending a DNS query over UDP
|
||||
+ to the nameserver numbered NS from the res_state STATP i.e.
|
||||
+ EXT(statp).nssocks[ns]. The function supports IPv4 and IPv6 queries
|
||||
+ along with the ability to send the query in parallel for both stacks
|
||||
+ (default) or serially (RES_SINGLKUP). It also supports serial lookup
|
||||
+ with a close and reopen of the socket used to talk to the server
|
||||
+ (RES_SNGLKUPREOP) to work around broken name servers.
|
||||
+
|
||||
+ The query stored in BUF of BUFLEN length is sent first followed by
|
||||
+ the query stored in BUF2 of BUFLEN2 length. Queries are sent
|
||||
+ in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP).
|
||||
+
|
||||
+ Answers to the query are stored firstly in *ANSP up to a max of
|
||||
+ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
|
||||
+ is non-NULL (to indicate that modifying the answer buffer is allowed)
|
||||
+ then malloc is used to allocate a new response buffer and ANSCP and
|
||||
+ ANSP will both point to the new buffer. If more than *ANSSIZP bytes
|
||||
+ are needed but ANSCP is NULL, then as much of the response as
|
||||
+ possible is read into the buffer, but the results will be truncated.
|
||||
+ When truncation happens because of a small answer buffer the DNS
|
||||
+ packets header feild TC will bet set to 1, indicating a truncated
|
||||
+ message, while the rest of the UDP packet is discarded.
|
||||
+
|
||||
+ Answers to the query are stored secondly in *ANSP2 up to a max of
|
||||
+ *ANSSIZP2 bytes, with the actual response length stored in
|
||||
+ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
|
||||
+ is non-NULL (required for a second query) then malloc is used to
|
||||
+ allocate a new response buffer, *ANSSIZP2 is set to the new buffer
|
||||
+ size and *ANSP2_MALLOCED is set to 1.
|
||||
+
|
||||
+ The ANSP2_MALLOCED argument will eventually be removed as the
|
||||
+ change in buffer pointer can be used to detect the buffer has
|
||||
+ changed and that the caller should use free on the new buffer.
|
||||
+
|
||||
+ Note that the answers may arrive in any order from the server and
|
||||
+ therefore the first and second answer buffers may not correspond to
|
||||
+ the first and second queries.
|
||||
+
|
||||
+ It is not supported to call this function with a non-NULL ANSP2
|
||||
+ but a NULL ANSCP. Put another way, you can call send_vc with a
|
||||
+ single unmodifiable buffer or two modifiable buffers, but no other
|
||||
+ combination is supported.
|
||||
+
|
||||
+ It is the caller's responsibility to free the malloc allocated
|
||||
+ buffers by detecting that the pointers have changed from their
|
||||
+ original values i.e. *ANSCP or *ANSP2 has changed.
|
||||
+
|
||||
+ If an answer is truncated because of UDP datagram DNS limits then
|
||||
+ *V_CIRCUIT is set to 1 and the return value non-zero to indicate to
|
||||
+ the caller to retry with TCP. The value *GOTSOMEWHERE is set to 1
|
||||
+ if any progress was made reading a response from the nameserver and
|
||||
+ is used by the caller to distinguish between ECONNREFUSED and
|
||||
+ ETIMEDOUT (the latter if *GOTSOMEWHERE is 1).
|
||||
+
|
||||
+ If errors are encountered then *TERRNO is set to an appropriate
|
||||
+ errno value and a zero result is returned for a recoverable error,
|
||||
+ and a less-than zero result is returned for a non-recoverable error.
|
||||
+
|
||||
+ If no errors are encountered then *TERRNO is left unmodified and
|
||||
+ a the length of the first response in bytes is returned. */
|
||||
static int
|
||||
send_dg(res_state statp,
|
||||
const u_char *buf, int buflen, const u_char *buf2, int buflen2,
|
||||
@@ -1030,8 +1159,6 @@ send_dg(res_state statp,
|
||||
{
|
||||
const HEADER *hp = (HEADER *) buf;
|
||||
const HEADER *hp2 = (HEADER *) buf2;
|
||||
- u_char *ans = *ansp;
|
||||
- int orig_anssizp = *anssizp;
|
||||
struct timespec now, timeout, finish;
|
||||
struct pollfd pfd[1];
|
||||
int ptimeout;
|
||||
@@ -1064,6 +1191,8 @@ send_dg(res_state statp,
|
||||
int need_recompute = 0;
|
||||
int nwritten = 0;
|
||||
int recvresp1 = 0;
|
||||
+ /* Skip the second response if there is no second query.
|
||||
+ To do that we mark the second response as received. */
|
||||
int recvresp2 = buf2 == NULL;
|
||||
pfd[0].fd = EXT(statp).nssocks[ns];
|
||||
pfd[0].events = POLLOUT;
|
||||
@@ -1227,55 +1356,56 @@ send_dg(res_state statp,
|
||||
int *thisresplenp;
|
||||
|
||||
if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
|
||||
+ /* We have not received any responses
|
||||
+ yet or we only have one response to
|
||||
+ receive. */
|
||||
thisanssizp = anssizp;
|
||||
thisansp = anscp ?: ansp;
|
||||
assert (anscp != NULL || ansp2 == NULL);
|
||||
thisresplenp = &resplen;
|
||||
} else {
|
||||
- if (*anssizp != MAXPACKET) {
|
||||
- /* No buffer allocated for the first
|
||||
- reply. We can try to use the rest
|
||||
- of the user-provided buffer. */
|
||||
-#if _STRING_ARCH_unaligned
|
||||
- *anssizp2 = orig_anssizp - resplen;
|
||||
- *ansp2 = *ansp + resplen;
|
||||
-#else
|
||||
- int aligned_resplen
|
||||
- = ((resplen + __alignof__ (HEADER) - 1)
|
||||
- & ~(__alignof__ (HEADER) - 1));
|
||||
- *anssizp2 = orig_anssizp - aligned_resplen;
|
||||
- *ansp2 = *ansp + aligned_resplen;
|
||||
-#endif
|
||||
- } else {
|
||||
- /* The first reply did not fit into the
|
||||
- user-provided buffer. Maybe the second
|
||||
- answer will. */
|
||||
- *anssizp2 = orig_anssizp;
|
||||
- *ansp2 = *ansp;
|
||||
- }
|
||||
-
|
||||
thisanssizp = anssizp2;
|
||||
thisansp = ansp2;
|
||||
thisresplenp = resplen2;
|
||||
}
|
||||
|
||||
if (*thisanssizp < MAXPACKET
|
||||
- /* Yes, we test ANSCP here. If we have two buffers
|
||||
- both will be allocatable. */
|
||||
- && anscp
|
||||
+ /* If the current buffer is non-NULL and it's not
|
||||
+ pointing at the static user-supplied buffer then
|
||||
+ we can reallocate it. */
|
||||
+ && (thisansp != NULL && thisansp != ansp)
|
||||
#ifdef FIONREAD
|
||||
+ /* Is the size too small? */
|
||||
&& (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0
|
||||
|| *thisanssizp < *thisresplenp)
|
||||
#endif
|
||||
) {
|
||||
+ /* Always allocate MAXPACKET, callers expect
|
||||
+ this specific size. */
|
||||
u_char *newp = malloc (MAXPACKET);
|
||||
if (newp != NULL) {
|
||||
- *anssizp = MAXPACKET;
|
||||
- *thisansp = ans = newp;
|
||||
+ *thisanssizp = MAXPACKET;
|
||||
+ *thisansp = newp;
|
||||
if (thisansp == ansp2)
|
||||
*ansp2_malloced = 1;
|
||||
}
|
||||
}
|
||||
+ /* We could end up with truncation if anscp was NULL
|
||||
+ (not allowed to change caller's buffer) and the
|
||||
+ response buffer size is too small. This isn't a
|
||||
+ reliable way to detect truncation because the ioctl
|
||||
+ may be an inaccurate report of the UDP message size.
|
||||
+ Therefore we use this only to issue debug output.
|
||||
+ To do truncation accurately with UDP we need
|
||||
+ MSG_TRUNC which is only available on Linux. We
|
||||
+ can abstract out the Linux-specific feature in the
|
||||
+ future to detect truncation. */
|
||||
+ if (__glibc_unlikely (*thisanssizp < *thisresplenp)) {
|
||||
+ Dprint(statp->options & RES_DEBUG,
|
||||
+ (stdout, ";; response may be truncated (UDP)\n")
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
HEADER *anhp = (HEADER *) *thisansp;
|
||||
socklen_t fromlen = sizeof(struct sockaddr_in6);
|
||||
assert (sizeof(from) <= fromlen);
|
|
@ -0,0 +1,270 @@
|
|||
From 2eda7b462b415105f5a05c1323372d4e39d46439 Mon Sep 17 00:00:00 2001
|
||||
From: Mike FABIAN <mfabian@redhat.com>
|
||||
Date: Mon, 10 Aug 2015 15:58:12 +0200
|
||||
Subject: [PATCH] Add a C.UTF-8 locale
|
||||
|
||||
---
|
||||
localedata/SUPPORTED | 1 +
|
||||
localedata/locales/C | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 239 insertions(+)
|
||||
create mode 100644 localedata/locales/C
|
||||
|
||||
diff --git a/localedata/SUPPORTED b/localedata/SUPPORTED
|
||||
index 8ca023e..2a78391 100644
|
||||
--- a/localedata/SUPPORTED
|
||||
+++ b/localedata/SUPPORTED
|
||||
@@ -1,6 +1,7 @@
|
||||
# This file names the currently supported and somewhat tested locales.
|
||||
# If you have any additions please file a glibc bug report.
|
||||
SUPPORTED-LOCALES=\
|
||||
+C.UTF-8/UTF-8 \
|
||||
aa_DJ.UTF-8/UTF-8 \
|
||||
aa_DJ/ISO-8859-1 \
|
||||
aa_ER/UTF-8 \
|
||||
diff --git a/localedata/locales/C b/localedata/locales/C
|
||||
new file mode 100644
|
||||
index 0000000..fdf460e
|
||||
--- /dev/null
|
||||
+++ b/localedata/locales/C
|
||||
@@ -0,0 +1,238 @@
|
||||
+escape_char /
|
||||
+comment_char %
|
||||
+% Locale for C locale in UTF-8
|
||||
+
|
||||
+LC_IDENTIFICATION
|
||||
+title "C locale"
|
||||
+source ""
|
||||
+address ""
|
||||
+contact ""
|
||||
+email "mfabian@redhat.com"
|
||||
+tel ""
|
||||
+fax ""
|
||||
+language "C"
|
||||
+territory ""
|
||||
+revision "1.0"
|
||||
+date "2015-08-10"
|
||||
+%
|
||||
+category "C:2015";LC_IDENTIFICATION
|
||||
+category "C:2015";LC_CTYPE
|
||||
+category "C:2015";LC_COLLATE
|
||||
+category "C:2015";LC_TIME
|
||||
+category "C:2015";LC_NUMERIC
|
||||
+category "C:2015";LC_MONETARY
|
||||
+category "C:2015";LC_MESSAGES
|
||||
+category "C:2015";LC_PAPER
|
||||
+category "C:2015";LC_NAME
|
||||
+category "C:2015";LC_ADDRESS
|
||||
+category "C:2015";LC_TELEPHONE
|
||||
+category "C:2015";LC_MEASUREMENT
|
||||
+END LC_IDENTIFICATION
|
||||
+
|
||||
+LC_CTYPE
|
||||
+copy "i18n"
|
||||
+
|
||||
+translit_start
|
||||
+include "translit_combining";""
|
||||
+translit_end
|
||||
+
|
||||
+END LC_CTYPE
|
||||
+
|
||||
+LC_COLLATE
|
||||
+order_start forward
|
||||
+<U0000>
|
||||
+..
|
||||
+<UFFFF>
|
||||
+<U10000>
|
||||
+..
|
||||
+<U1FFFF>
|
||||
+<U20000>
|
||||
+..
|
||||
+<U2FFFF>
|
||||
+<UE0000>
|
||||
+..
|
||||
+<UEFFFF>
|
||||
+<UF0000>
|
||||
+..
|
||||
+<UFFFFF>
|
||||
+<U100000>
|
||||
+..
|
||||
+<U10FFFF>
|
||||
+UNDEFINED
|
||||
+order_end
|
||||
+END LC_COLLATE
|
||||
+
|
||||
+LC_MONETARY
|
||||
+% This is the 14652 i18n fdcc-set definition for
|
||||
+% the LC_MONETARY category
|
||||
+% (except for the int_curr_symbol and currency_symbol, they are empty in
|
||||
+% the 14652 i18n fdcc-set definition and also empty in
|
||||
+% glibc/locale/C-monetary.c. But localedef complains in that case).
|
||||
+%
|
||||
+% Using "USD" for int_curr_symbol. But maybe "XXX" would be better?
|
||||
+% XXX is "No currency" (https://en.wikipedia.org/wiki/ISO_4217)
|
||||
+int_curr_symbol "<U0055><U0053><U0044><U0020>"
|
||||
+% Using "$" for currency_symbol. But maybe <U00A4> would be better?
|
||||
+% U+00A4 is the "generic currency symbol"
|
||||
+% (https://en.wikipedia.org/wiki/Currency_sign_%28typography%29)
|
||||
+currency_symbol "<U0024>"
|
||||
+mon_decimal_point "<U002E>"
|
||||
+mon_thousands_sep ""
|
||||
+mon_grouping -1
|
||||
+positive_sign ""
|
||||
+negative_sign "<U002D>"
|
||||
+int_frac_digits -1
|
||||
+frac_digits -1
|
||||
+p_cs_precedes -1
|
||||
+int_p_sep_by_space -1
|
||||
+p_sep_by_space -1
|
||||
+n_cs_precedes -1
|
||||
+int_n_sep_by_space -1
|
||||
+n_sep_by_space -1
|
||||
+p_sign_posn -1
|
||||
+n_sign_posn -1
|
||||
+%
|
||||
+END LC_MONETARY
|
||||
+
|
||||
+LC_NUMERIC
|
||||
+% This is the POSIX Locale definition for
|
||||
+% the LC_NUMERIC category.
|
||||
+%
|
||||
+decimal_point "<U002E>"
|
||||
+thousands_sep ""
|
||||
+grouping -1
|
||||
+END LC_NUMERIC
|
||||
+
|
||||
+LC_TIME
|
||||
+% This is the POSIX Locale definition for
|
||||
+% the LC_TIME category.
|
||||
+%
|
||||
+% Abbreviated weekday names (%a)
|
||||
+abday "<U0053><U0075><U006E>";"<U004D><U006F><U006E>";/
|
||||
+ "<U0054><U0075><U0065>";"<U0057><U0065><U0064>";/
|
||||
+ "<U0054><U0068><U0075>";"<U0046><U0072><U0069>";/
|
||||
+ "<U0053><U0061><U0074>"
|
||||
+
|
||||
+% Full weekday names (%A)
|
||||
+day "<U0053><U0075><U006E><U0064><U0061><U0079>";/
|
||||
+ "<U004D><U006F><U006E><U0064><U0061><U0079>";/
|
||||
+ "<U0054><U0075><U0065><U0073><U0064><U0061><U0079>";/
|
||||
+ "<U0057><U0065><U0064><U006E><U0065><U0073><U0064><U0061><U0079>";/
|
||||
+ "<U0054><U0068><U0075><U0072><U0073><U0064><U0061><U0079>";/
|
||||
+ "<U0046><U0072><U0069><U0064><U0061><U0079>";/
|
||||
+ "<U0053><U0061><U0074><U0075><U0072><U0064><U0061><U0079>"
|
||||
+
|
||||
+% Abbreviated month names (%b)
|
||||
+abmon "<U004A><U0061><U006E>";"<U0046><U0065><U0062>";/
|
||||
+ "<U004D><U0061><U0072>";"<U0041><U0070><U0072>";/
|
||||
+ "<U004D><U0061><U0079>";"<U004A><U0075><U006E>";/
|
||||
+ "<U004A><U0075><U006C>";"<U0041><U0075><U0067>";/
|
||||
+ "<U0053><U0065><U0070>";"<U004F><U0063><U0074>";/
|
||||
+ "<U004E><U006F><U0076>";"<U0044><U0065><U0063>"
|
||||
+
|
||||
+% Full month names (%B)
|
||||
+mon "<U004A><U0061><U006E><U0075><U0061><U0072><U0079>";/
|
||||
+ "<U0046><U0065><U0062><U0072><U0075><U0061><U0072><U0079>";/
|
||||
+ "<U004D><U0061><U0072><U0063><U0068>";/
|
||||
+ "<U0041><U0070><U0072><U0069><U006C>";/
|
||||
+ "<U004D><U0061><U0079>";/
|
||||
+ "<U004A><U0075><U006E><U0065>";/
|
||||
+ "<U004A><U0075><U006C><U0079>";/
|
||||
+ "<U0041><U0075><U0067><U0075><U0073><U0074>";/
|
||||
+ "<U0053><U0065><U0070><U0074><U0065><U006D><U0062><U0065><U0072>";/
|
||||
+ "<U004F><U0063><U0074><U006F><U0062><U0065><U0072>";/
|
||||
+ "<U004E><U006F><U0076><U0065><U006D><U0062><U0065><U0072>";/
|
||||
+ "<U0044><U0065><U0063><U0065><U006D><U0062><U0065><U0072>"
|
||||
+
|
||||
+% Week description, consists of three fields:
|
||||
+% 1. Number of days in a week.
|
||||
+% 2. Gregorian date that is a first weekday (19971130 for Sunday, 19971201 for Monday).
|
||||
+% 3. The weekday number to be contained in the first week of the year.
|
||||
+%
|
||||
+% ISO 8601 conforming applications should use the values 7, 19971201 (a
|
||||
+% Monday), and 4 (Thursday), respectively.
|
||||
+week 7;19971201;4
|
||||
+first_weekday 1
|
||||
+first_workday 1
|
||||
+
|
||||
+% Appropriate date and time representation (%c)
|
||||
+% "%a %b %e %H:%M:%S %Y"
|
||||
+d_t_fmt "<U0025><U0061><U0020><U0025><U0062><U0020><U0025><U0065><U0020><U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U0059>"
|
||||
+
|
||||
+% Appropriate date representation (%x)
|
||||
+% "%m/%d/%y"
|
||||
+d_fmt "<U0025><U006D><U002F><U0025><U0064><U002F><U0025><U0079>"
|
||||
+
|
||||
+% Appropriate time representation (%X)
|
||||
+% "%H:%M:%S"
|
||||
+t_fmt "<U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053>"
|
||||
+
|
||||
+% Appropriate AM/PM time representation (%r)
|
||||
+% "%I:%M:%S %p"
|
||||
+t_fmt_ampm "<U0025><U0049><U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U0070>"
|
||||
+
|
||||
+% Equivalent of AM/PM (%p) "AM"/"PM"
|
||||
+%
|
||||
+am_pm "<U0041><U004D>";"<U0050><U004D>"
|
||||
+
|
||||
+% Appropriate date representation (date(1)) "%a %b %e %H:%M:%S %Z %Y"
|
||||
+date_fmt "<U0025><U0061><U0020><U0025><U0062><U0020><U0025><U0065><U0020><U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U005A><U0020><U0025><U0059>"
|
||||
+END LC_TIME
|
||||
+
|
||||
+LC_MESSAGES
|
||||
+% This is the POSIX Locale definition for
|
||||
+% the LC_NUMERIC category.
|
||||
+%
|
||||
+yesexpr "<U005E><U005B><U0079><U0059><U005D>"
|
||||
+noexpr "<U005E><U005B><U006E><U004E><U005D>"
|
||||
+yesstr "<U0059><U0065><U0073>"
|
||||
+nostr "<U004E><U006F>"
|
||||
+END LC_MESSAGES
|
||||
+
|
||||
+LC_PAPER
|
||||
+% This is the ISO/IEC 14652 "i18n" definition for
|
||||
+% the LC_PAPER category.
|
||||
+% (A4 paper, this is also used in the built in C/POSIX
|
||||
+% locale in glibc/locale/C-paper.c)
|
||||
+height 297
|
||||
+width 210
|
||||
+END LC_PAPER
|
||||
+
|
||||
+LC_NAME
|
||||
+% This is the ISO/IEC 14652 "i18n" definition for
|
||||
+% the LC_NAME category.
|
||||
+% "%p%t%g%t%m%t%f"
|
||||
+% (also used in the built in C/POSIX locale in glibc/locale/C-name.c)
|
||||
+name_fmt "<U0025><U0070><U0025><U0074><U0025><U0067><U0025><U0074>/
|
||||
+<U0025><U006D><U0025><U0074><U0025><U0066>"
|
||||
+END LC_NAME
|
||||
+
|
||||
+LC_ADDRESS
|
||||
+% This is the ISO/IEC 14652 "i18n" definition for
|
||||
+% the LC_ADDRESS category.
|
||||
+% "%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N"
|
||||
+% (also used in the built in C/POSIX locale in glibc/locale/C-address.c)
|
||||
+postal_fmt "<U0025><U0061><U0025><U004E><U0025><U0066><U0025><U004E>/
|
||||
+<U0025><U0064><U0025><U004E><U0025><U0062><U0025><U004E><U0025><U0073>/
|
||||
+<U0020><U0025><U0068><U0020><U0025><U0065><U0020><U0025><U0072><U0025>/
|
||||
+<U004E><U0025><U0043><U002D><U0025><U007A><U0020><U0025><U0054><U0025>/
|
||||
+<U004E><U0025><U0063><U0025><U004E>"
|
||||
+END LC_ADDRESS
|
||||
+
|
||||
+LC_TELEPHONE
|
||||
+% This is the ISO/IEC 14652 "i18n" definition for
|
||||
+% the LC_TELEPHONE category.
|
||||
+% "+%c %a %l"
|
||||
+tel_int_fmt "<U002B><U0025><U0063><U0020><U0025><U0061><U0020><U0025>/
|
||||
+<U006C>"
|
||||
+% (also used in the built in C/POSIX locale in glibc/locale/C-telephone.c)
|
||||
+END LC_TELEPHONE
|
||||
+
|
||||
+LC_MEASUREMENT
|
||||
+% This is the ISO/IEC 14652 "i18n" definition for
|
||||
+% the LC_MEASUREMENT category.
|
||||
+% (same as in the built in C/POSIX locale in glibc/locale/C-measurement.c)
|
||||
+%metric
|
||||
+measurement 1
|
||||
+END LC_MEASUREMENT
|
||||
+
|
||||
--
|
||||
2.4.3
|
||||
|
|
@ -1,655 +0,0 @@
|
|||
commit ca677d3c3cd0eba7d1f03092517aea553a0e8569
|
||||
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
|
||||
Date: Fri Jun 27 14:00:18 2014 -0700
|
||||
|
||||
Add x86 32 bit vDSO time function support
|
||||
|
||||
Linux 3.15 adds support for clock_gettime, gettimeofday, and time vDSO
|
||||
(commit id 37c975545ec63320789962bf307f000f08fabd48). This patch adds
|
||||
GLIBC supports to use such symbol when they are avaiable.
|
||||
|
||||
Along with x86 vDSO support, this patch cleanup x86_64 code by moving
|
||||
all common code to x86 common folder. Only init-first.c is different
|
||||
between implementations.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/i386/gettimeofday.c b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
|
||||
new file mode 100644
|
||||
index 0000000..3e00eb4
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
|
||||
@@ -0,0 +1,39 @@
|
||||
+/* gettimeofday - get the time. Linux/i386 version.
|
||||
+ Copyright (C) 2015 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/time.h>
|
||||
+
|
||||
+#ifdef SHARED
|
||||
+
|
||||
+# include <dl-vdso.h>
|
||||
+# include <errno.h>
|
||||
+
|
||||
+/* If the vDSO is not available we fall back on the syscall. */
|
||||
+static int
|
||||
+__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
|
||||
+{
|
||||
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
|
||||
+}
|
||||
+# define GETTIMEOFAY_FALLBACK (void*) (&__gettimeofday_syscall)
|
||||
+# undef libc_ifunc_hidden_def
|
||||
+# define libc_ifunc_hidden_def(name) \
|
||||
+ libc_ifunc_hidden_def1 (__GI_##name, __gettimeofday_syscall)
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
|
||||
diff --git a/sysdeps/unix/sysv/linux/i386/init-first.c b/sysdeps/unix/sysv/linux/i386/init-first.c
|
||||
new file mode 100644
|
||||
index 0000000..4be65d7
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/i386/init-first.c
|
||||
@@ -0,0 +1,52 @@
|
||||
+/* Initialization code run first thing by the ELF startup code. Linux/i386.
|
||||
+ Copyright (C) 2015 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/>. */
|
||||
+
|
||||
+#ifdef SHARED
|
||||
+# include <time.h>
|
||||
+# include <sysdep.h>
|
||||
+# include <dl-vdso.h>
|
||||
+# include <libc-vdso.h>
|
||||
+
|
||||
+long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
|
||||
+ __attribute__ ((nocommon));
|
||||
+libc_hidden_proto (__vdso_clock_gettime)
|
||||
+libc_hidden_data_def (__vdso_clock_gettime)
|
||||
+
|
||||
+static long int
|
||||
+clock_gettime_syscall (clockid_t id, struct timespec *tp)
|
||||
+{
|
||||
+ INTERNAL_SYSCALL_DECL (err);
|
||||
+ return INTERNAL_SYSCALL (clock_gettime, err, 2, id, tp);
|
||||
+}
|
||||
+
|
||||
+static inline void
|
||||
+__vdso_platform_setup (void)
|
||||
+{
|
||||
+ PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
|
||||
+
|
||||
+ void *p = _dl_vdso_vsym ("__vdso_clock_gettime", &linux26);
|
||||
+ if (p == NULL)
|
||||
+ p = clock_gettime_syscall;
|
||||
+ PTR_MANGLE (p);
|
||||
+ __vdso_clock_gettime = p;
|
||||
+}
|
||||
+
|
||||
+# define VDSO_SETUP __vdso_platform_setup
|
||||
+#endif
|
||||
+
|
||||
+#include <csu/init-first.c>
|
||||
diff --git a/sysdeps/unix/sysv/linux/i386/time.c b/sysdeps/unix/sysv/linux/i386/time.c
|
||||
new file mode 100644
|
||||
index 0000000..e8a4e59
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/i386/time.c
|
||||
@@ -0,0 +1,37 @@
|
||||
+/* time -- Get number of seconds since Epoch. Linux/i386 version.
|
||||
+ Copyright (C) 2015 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/>. */
|
||||
+
|
||||
+#ifdef SHARED
|
||||
+
|
||||
+# include <dl-vdso.h>
|
||||
+# include <errno.h>
|
||||
+
|
||||
+/* If the vDSO is not available we fall back on the old vsyscall. */
|
||||
+static time_t
|
||||
+__time_syscall (time_t *t)
|
||||
+{
|
||||
+ INTERNAL_SYSCALL_DECL (err);
|
||||
+ return INTERNAL_SYSCALL (time, err, 1, t);
|
||||
+}
|
||||
+# define TIME_FALLBACK (void*) &__time_syscall
|
||||
+# undef libc_ifunc_hidden_def
|
||||
+# define libc_ifunc_hidden_def(name) \
|
||||
+ libc_ifunc_hidden_def1 (__GI_##name, __time_syscall)
|
||||
+#endif
|
||||
+
|
||||
+#include <sysdeps/unix/sysv/linux/x86/time.c>
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86/Makefile b/sysdeps/unix/sysv/linux/x86/Makefile
|
||||
index 0281f87..d6be472 100644
|
||||
--- a/sysdeps/unix/sysv/linux/x86/Makefile
|
||||
+++ b/sysdeps/unix/sysv/linux/x86/Makefile
|
||||
@@ -19,3 +19,7 @@ libpthread-sysdep_routines += init-arch
|
||||
libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \
|
||||
elision-trylock
|
||||
endif
|
||||
+
|
||||
+ifeq ($(subdir),elf)
|
||||
+sysdep_routines += dl-vdso
|
||||
+endif
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86/clock_gettime.c b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
|
||||
new file mode 100644
|
||||
index 0000000..98ffb01
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/x86/clock_gettime.c
|
||||
@@ -0,0 +1,34 @@
|
||||
+/* Get the current value of a clock. Linux/x86 version.
|
||||
+ Copyright (C) 2015 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 <libc-vdso.h>
|
||||
+
|
||||
+#ifdef SHARED
|
||||
+# define SYSCALL_GETTIME(id, tp) \
|
||||
+ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
|
||||
+ long int v_ret; \
|
||||
+ PTR_DEMANGLE (f); \
|
||||
+ v_ret = (*f) (id, tp); \
|
||||
+ if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
|
||||
+ __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
|
||||
+ v_ret = -1; \
|
||||
+ } \
|
||||
+ v_ret; })
|
||||
+#endif
|
||||
+
|
||||
+#include <sysdeps/unix/sysv/linux/clock_gettime.c>
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
|
||||
new file mode 100644
|
||||
index 0000000..c820fd7
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
|
||||
@@ -0,0 +1,54 @@
|
||||
+/* gettimeofday - get the time. Linux/x86 version.
|
||||
+ Copyright (C) 2015 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/time.h>
|
||||
+
|
||||
+#ifdef SHARED
|
||||
+
|
||||
+# include <dl-vdso.h>
|
||||
+
|
||||
+void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
|
||||
+
|
||||
+void *
|
||||
+gettimeofday_ifunc (void)
|
||||
+{
|
||||
+ PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
|
||||
+
|
||||
+ /* If the vDSO is not available we fall back on the old vsyscall. */
|
||||
+ return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
|
||||
+ ?: GETTIMEOFAY_FALLBACK);
|
||||
+}
|
||||
+asm (".type __gettimeofday, %gnu_indirect_function");
|
||||
+
|
||||
+libc_ifunc_hidden_def(__gettimeofday)
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+# include <sysdep.h>
|
||||
+# include <errno.h>
|
||||
+
|
||||
+int
|
||||
+__gettimeofday (struct timeval *tv, struct timezone *tz)
|
||||
+{
|
||||
+ return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
|
||||
+}
|
||||
+libc_hidden_def (__gettimeofday)
|
||||
+
|
||||
+#endif
|
||||
+weak_alias (__gettimeofday, gettimeofday)
|
||||
+libc_hidden_weak (gettimeofday)
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86/libc-vdso.h b/sysdeps/unix/sysv/linux/x86/libc-vdso.h
|
||||
new file mode 100644
|
||||
index 0000000..03ff875
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/x86/libc-vdso.h
|
||||
@@ -0,0 +1,31 @@
|
||||
+/* Resolve function pointers to VDSO functions.
|
||||
+ Copyright (C) 2005-2015 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/>. */
|
||||
+
|
||||
+#ifndef _LIBC_VDSO_H
|
||||
+#define _LIBC_VDSO_H
|
||||
+
|
||||
+#include <time.h>
|
||||
+#include <sys/time.h>
|
||||
+
|
||||
+#ifdef SHARED
|
||||
+
|
||||
+extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+#endif /* _LIBC_VDSO_H */
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86/time.c b/sysdeps/unix/sysv/linux/x86/time.c
|
||||
new file mode 100644
|
||||
index 0000000..1ab9248
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/x86/time.c
|
||||
@@ -0,0 +1,49 @@
|
||||
+/* time -- Get number of seconds since Epoch. Linux/x86 version.
|
||||
+ Copyright (C) 2015 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 <time.h>
|
||||
+
|
||||
+#ifdef SHARED
|
||||
+
|
||||
+#include <dl-vdso.h>
|
||||
+
|
||||
+void *time_ifunc (void) __asm__ ("time");
|
||||
+
|
||||
+void *
|
||||
+time_ifunc (void)
|
||||
+{
|
||||
+ PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
|
||||
+
|
||||
+ return _dl_vdso_vsym ("__vdso_time", &linux26) ?: TIME_FALLBACK;
|
||||
+}
|
||||
+asm (".type time, %gnu_indirect_function");
|
||||
+
|
||||
+libc_ifunc_hidden_def(time)
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+# include <sysdep.h>
|
||||
+
|
||||
+time_t
|
||||
+time (time_t *t)
|
||||
+{
|
||||
+ INTERNAL_SYSCALL_DECL (err);
|
||||
+ return INTERNAL_SYSCALL (time, err, 1, t);
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86/timespec_get.c b/sysdeps/unix/sysv/linux/x86/timespec_get.c
|
||||
new file mode 100644
|
||||
index 0000000..b21efce
|
||||
--- /dev/null
|
||||
+++ b/sysdeps/unix/sysv/linux/x86/timespec_get.c
|
||||
@@ -0,0 +1,29 @@
|
||||
+/* timespec_get -- returns the calendar time based on a given time base.
|
||||
+ Linux/x86 version.
|
||||
+ Copyright (C) 2015 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 <libc-vdso.h>
|
||||
+
|
||||
+#ifdef SHARED
|
||||
+# define INTERNAL_GETTIME(id, tp) \
|
||||
+ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
|
||||
+ PTR_DEMANGLE (f); \
|
||||
+ (*f) (id, tp); })
|
||||
+#endif
|
||||
+
|
||||
+#include <sysdeps/unix/sysv/linux/timespec_get.c>
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86_64/Makefile b/sysdeps/unix/sysv/linux/x86_64/Makefile
|
||||
index d6a9d36..9b82155 100644
|
||||
--- a/sysdeps/unix/sysv/linux/x86_64/Makefile
|
||||
+++ b/sysdeps/unix/sysv/linux/x86_64/Makefile
|
||||
@@ -13,7 +13,3 @@ endif
|
||||
ifeq ($(subdir),misc)
|
||||
gen-as-const-headers += sigaltstack-offsets.sym
|
||||
endif
|
||||
-
|
||||
-ifeq ($(subdir),elf)
|
||||
-sysdep_routines += dl-vdso
|
||||
-endif
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
|
||||
deleted file mode 100644
|
||||
index 03ff875..0000000
|
||||
--- a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
|
||||
+++ /dev/null
|
||||
@@ -1,31 +0,0 @@
|
||||
-/* Resolve function pointers to VDSO functions.
|
||||
- Copyright (C) 2005-2015 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/>. */
|
||||
-
|
||||
-#ifndef _LIBC_VDSO_H
|
||||
-#define _LIBC_VDSO_H
|
||||
-
|
||||
-#include <time.h>
|
||||
-#include <sys/time.h>
|
||||
-
|
||||
-#ifdef SHARED
|
||||
-
|
||||
-extern long int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
|
||||
-
|
||||
-#endif
|
||||
-
|
||||
-#endif /* _LIBC_VDSO_H */
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c b/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
|
||||
deleted file mode 100644
|
||||
index f712110..0000000
|
||||
--- a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c
|
||||
+++ /dev/null
|
||||
@@ -1,20 +0,0 @@
|
||||
-#include "bits/libc-vdso.h"
|
||||
-
|
||||
-#ifdef SHARED
|
||||
-# define SYSCALL_GETTIME(id, tp) \
|
||||
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
|
||||
- long int v_ret; \
|
||||
- PTR_DEMANGLE (f); \
|
||||
- v_ret = f (id, tp); \
|
||||
- if (INTERNAL_SYSCALL_ERROR_P (v_ret, )) { \
|
||||
- __set_errno (INTERNAL_SYSCALL_ERRNO (v_ret, )); \
|
||||
- v_ret = -1; \
|
||||
- } \
|
||||
- v_ret; })
|
||||
-# define INTERNAL_GETTIME(id, tp) \
|
||||
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
|
||||
- PTR_DEMANGLE (f); \
|
||||
- f (id, tp); })
|
||||
-#endif
|
||||
-
|
||||
-#include "../clock_gettime.c"
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
|
||||
index 866d9c1..daa14de 100644
|
||||
--- a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
|
||||
+++ b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c
|
||||
@@ -18,42 +18,9 @@
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef SHARED
|
||||
-
|
||||
-# include <dl-vdso.h>
|
||||
-
|
||||
+/* If the vDSO is not available we fall back on the old vsyscall. */
|
||||
# define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000ul
|
||||
-
|
||||
-void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
|
||||
-
|
||||
-void *
|
||||
-gettimeofday_ifunc (void)
|
||||
-{
|
||||
- PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
|
||||
-
|
||||
- /* If the vDSO is not available we fall back on the old vsyscall. */
|
||||
- return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
|
||||
- ?: (void *) VSYSCALL_ADDR_vgettimeofday);
|
||||
-}
|
||||
-asm (".type __gettimeofday, %gnu_indirect_function");
|
||||
-
|
||||
-/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
|
||||
- let us do it in C because it doesn't know we're defining __gettimeofday
|
||||
- here in this file. */
|
||||
-asm (".globl __GI___gettimeofday\n"
|
||||
- "__GI___gettimeofday = __gettimeofday");
|
||||
-
|
||||
-#else
|
||||
-
|
||||
-# include <sysdep.h>
|
||||
-# include <errno.h>
|
||||
-
|
||||
-int
|
||||
-__gettimeofday (struct timeval *tv, struct timezone *tz)
|
||||
-{
|
||||
- return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
|
||||
-}
|
||||
-libc_hidden_def (__gettimeofday)
|
||||
-
|
||||
+# define GETTIMEOFAY_FALLBACK (void*)VSYSCALL_ADDR_vgettimeofday
|
||||
#endif
|
||||
-weak_alias (__gettimeofday, gettimeofday)
|
||||
-libc_hidden_weak (gettimeofday)
|
||||
+
|
||||
+#include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86_64/init-first.c b/sysdeps/unix/sysv/linux/x86_64/init-first.c
|
||||
index e3bc712..36f9afc 100644
|
||||
--- a/sysdeps/unix/sysv/linux/x86_64/init-first.c
|
||||
+++ b/sysdeps/unix/sysv/linux/x86_64/init-first.c
|
||||
@@ -20,20 +20,20 @@
|
||||
# include <time.h>
|
||||
# include <sysdep.h>
|
||||
# include <dl-vdso.h>
|
||||
-# include <bits/libc-vdso.h>
|
||||
+# include <libc-vdso.h>
|
||||
|
||||
long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
|
||||
__attribute__ ((nocommon));
|
||||
-strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden)
|
||||
+libc_hidden_proto (__vdso_clock_gettime)
|
||||
+libc_hidden_data_def (__vdso_clock_gettime)
|
||||
|
||||
long int (*__vdso_getcpu) (unsigned *, unsigned *, void *) attribute_hidden;
|
||||
|
||||
-
|
||||
extern long int __syscall_clock_gettime (clockid_t, struct timespec *);
|
||||
|
||||
|
||||
static inline void
|
||||
-_libc_vdso_platform_setup (void)
|
||||
+__vdso_platform_setup (void)
|
||||
{
|
||||
PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
|
||||
|
||||
@@ -41,7 +41,7 @@ _libc_vdso_platform_setup (void)
|
||||
if (p == NULL)
|
||||
p = __syscall_clock_gettime;
|
||||
PTR_MANGLE (p);
|
||||
- __GI___vdso_clock_gettime = p;
|
||||
+ __vdso_clock_gettime = p;
|
||||
|
||||
p = _dl_vdso_vsym ("__vdso_getcpu", &linux26);
|
||||
/* If the vDSO is not available we fall back on the old vsyscall. */
|
||||
@@ -52,7 +52,7 @@ _libc_vdso_platform_setup (void)
|
||||
__vdso_getcpu = p;
|
||||
}
|
||||
|
||||
-# define VDSO_SETUP _libc_vdso_platform_setup
|
||||
+# define VDSO_SETUP __vdso_platform_setup
|
||||
#endif
|
||||
|
||||
#include <csu/init-first.c>
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86_64/time.c b/sysdeps/unix/sysv/linux/x86_64/time.c
|
||||
index c00b5be..6ceb819 100644
|
||||
--- a/sysdeps/unix/sysv/linux/x86_64/time.c
|
||||
+++ b/sysdeps/unix/sysv/linux/x86_64/time.c
|
||||
@@ -16,45 +16,9 @@
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifdef SHARED
|
||||
-/* Redefine time so that the compiler won't complain about the type
|
||||
- mismatch with the IFUNC selector in strong_alias, below. */
|
||||
-#undef time
|
||||
-#define time __redirect_time
|
||||
-#include <time.h>
|
||||
-
|
||||
-#include <dl-vdso.h>
|
||||
-
|
||||
+/* If the vDSO is not available we fall back on the old vsyscall. */
|
||||
#define VSYSCALL_ADDR_vtime 0xffffffffff600400
|
||||
-
|
||||
-/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
|
||||
- ifunc symbol properly. */
|
||||
-extern __typeof (__redirect_time) __libc_time;
|
||||
-void *time_ifunc (void) __asm__ ("__libc_time");
|
||||
-
|
||||
-void *
|
||||
-time_ifunc (void)
|
||||
-{
|
||||
- PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
|
||||
-
|
||||
- /* If the vDSO is not available we fall back on the old vsyscall. */
|
||||
- return _dl_vdso_vsym ("__vdso_time", &linux26) ?: (void *) VSYSCALL_ADDR_vtime;
|
||||
-}
|
||||
-__asm (".type __libc_time, %gnu_indirect_function");
|
||||
-
|
||||
-#undef time
|
||||
-strong_alias (__libc_time, time)
|
||||
-libc_hidden_ver (__libc_time, time)
|
||||
-
|
||||
-#else
|
||||
-
|
||||
-# include <time.h>
|
||||
-# include <sysdep.h>
|
||||
-
|
||||
-time_t
|
||||
-time (time_t *t)
|
||||
-{
|
||||
- INTERNAL_SYSCALL_DECL (err);
|
||||
- return INTERNAL_SYSCALL (time, err, 1, t);
|
||||
-}
|
||||
-
|
||||
+#define TIME_FALLBACK (void*)VSYSCALL_ADDR_vtime
|
||||
#endif
|
||||
+
|
||||
+#include <sysdeps/unix/sysv/linux/x86/time.c>
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86_64/timespec_get.c b/sysdeps/unix/sysv/linux/x86_64/timespec_get.c
|
||||
deleted file mode 100644
|
||||
index cb26068..0000000
|
||||
--- a/sysdeps/unix/sysv/linux/x86_64/timespec_get.c
|
||||
+++ /dev/null
|
||||
@@ -1,10 +0,0 @@
|
||||
-#include "bits/libc-vdso.h"
|
||||
-
|
||||
-#ifdef SHARED
|
||||
-# define INTERNAL_GETTIME(id, tp) \
|
||||
- ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \
|
||||
- PTR_DEMANGLE (f); \
|
||||
- f (id, tp); })
|
||||
-#endif
|
||||
-
|
||||
-#include "../timespec_get.c"
|
||||
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/init-first.c b/sysdeps/unix/sysv/linux/x86_64/x32/init-first.c
|
||||
index 88369e5..93e0508 100644
|
||||
--- a/sysdeps/unix/sysv/linux/x86_64/x32/init-first.c
|
||||
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/init-first.c
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#ifdef SHARED
|
||||
# include <dl-vdso.h>
|
||||
-# include <bits/libc-vdso.h>
|
||||
+# include <libc-vdso.h>
|
||||
|
||||
long int (*__vdso_clock_gettime) (clockid_t, struct timespec *)
|
||||
__attribute__ ((nocommon));
|
|
@ -0,0 +1,47 @@
|
|||
Upstream patch:
|
||||
|
||||
commit ff889b196575c2fbf6aa7130abb1ec862714ea4e
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Feb 19 14:21:34 2016 +0100
|
||||
|
||||
Remove trailing newline from date_fmt in Serbian locales [BZ #19581]
|
||||
|
||||
diff --git a/localedata/locales/sr_ME b/localedata/locales/sr_ME
|
||||
index 4f243dc..dd68df8 100644
|
||||
--- a/localedata/locales/sr_ME
|
||||
+++ b/localedata/locales/sr_ME
|
||||
@@ -119,7 +119,7 @@ am_pm "";""
|
||||
t_fmt_ampm "<U0025><U0054>"
|
||||
date_fmt "<U0025><U0061><U002c><U0020><U0025><U0065><U002E><U0020>/
|
||||
<U0025><U0062><U0020><U0025><U0059><U002E><U0020><U0020><U0025><U0048>/
|
||||
-<U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U005A><U000A>"
|
||||
+<U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U005A>"
|
||||
week 7;19971130;4
|
||||
first_weekday 2
|
||||
first_workday 2
|
||||
diff --git a/localedata/locales/sr_RS b/localedata/locales/sr_RS
|
||||
index 2ae085b..ffea86f 100644
|
||||
--- a/localedata/locales/sr_RS
|
||||
+++ b/localedata/locales/sr_RS
|
||||
@@ -300,7 +300,7 @@ am_pm "";""
|
||||
t_fmt_ampm "<U0025><U0054>"
|
||||
date_fmt "<U0025><U0061><U002C><U0020><U0025><U0065><U002E><U0020>/
|
||||
<U0025><U0062><U0020><U0025><U0059><U002E><U0020><U0020><U0025><U0048>/
|
||||
-<U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U005A><U000A>"
|
||||
+<U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U005A>"
|
||||
week 7;19971130;4
|
||||
first_weekday 2
|
||||
first_workday 2
|
||||
diff --git a/localedata/locales/sr_RS@latin b/localedata/locales/sr_RS@latin
|
||||
index da6628b..fd10ea6 100644
|
||||
--- a/localedata/locales/sr_RS@latin
|
||||
+++ b/localedata/locales/sr_RS@latin
|
||||
@@ -120,7 +120,7 @@ am_pm "";""
|
||||
t_fmt_ampm "<U0025><U0054>"
|
||||
date_fmt "<U0025><U0061><U002c><U0020><U0025><U0065><U002E><U0020>/
|
||||
<U0025><U0062><U0020><U0025><U0059><U002E><U0020><U0020><U0025><U0048>/
|
||||
-<U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U005A><U000A>"
|
||||
+<U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U005A>"
|
||||
week 7;19971130;4
|
||||
first_weekday 2
|
||||
first_workday 2
|
|
@ -0,0 +1,45 @@
|
|||
commit 333e1ba4e53456a603621274177ae9393b9d5385
|
||||
Author: Paul Eggert <eggert@cs.ucla.edu>
|
||||
Date: Fri May 22 14:57:11 2015 -0700
|
||||
|
||||
Remove obsolete aliases that broke 'locale -a'
|
||||
|
||||
[BZ #18412]
|
||||
* intl/locale.alias: Remove obsolete aliases "bokmål" and "français"
|
||||
which caused 'locale -a' to output Latin-1 data in UTF-8 locales,
|
||||
breaking some applications that use 'locale -a' output.
|
||||
Change the encoding of this file from Latin-1 to ASCII to avoid
|
||||
other potential problems with people grepping this file.
|
||||
|
||||
diff --git a/intl/locale.alias b/intl/locale.alias
|
||||
index ab1cb7a..fe19e1b 100644
|
||||
--- a/intl/locale.alias
|
||||
+++ b/intl/locale.alias
|
||||
@@ -24,8 +24,18 @@
|
||||
# backward compatibility. Nobody should rely on the names defined here.
|
||||
# Locales should always be specified by their full name.
|
||||
|
||||
+# Note: This file used to contain the following lines:
|
||||
+# bokmaal nb_NO.ISO-8859-1
|
||||
+# franc,ais fr_FR.ISO-8859-1
|
||||
+# except that the "aa" was actually the byte '\0xE5' (the Latin-1
|
||||
+# encoding for U+00E5 LATIN SMALL LETTER A WITH RING ABOVE) and the
|
||||
+# "c," was actually the byte '\xE7' (the Latin-1 encoding for U+00E7
|
||||
+# LATIN SMALL LETTER C WITH CEDILLA). These lines were removed
|
||||
+# because they caused 'locale -a' to output text encoded in Latin-1,
|
||||
+# which broke applications in UTF-8 locales. See:
|
||||
+# https://sourceware.org/bugzilla/show_bug.cgi?id=18412
|
||||
+
|
||||
bokmal nb_NO.ISO-8859-1
|
||||
-bokmål nb_NO.ISO-8859-1
|
||||
catalan ca_ES.ISO-8859-1
|
||||
croatian hr_HR.ISO-8859-2
|
||||
czech cs_CZ.ISO-8859-2
|
||||
@@ -36,7 +46,6 @@ dutch nl_NL.ISO-8859-1
|
||||
eesti et_EE.ISO-8859-1
|
||||
estonian et_EE.ISO-8859-1
|
||||
finnish fi_FI.ISO-8859-1
|
||||
-français fr_FR.ISO-8859-1
|
||||
french fr_FR.ISO-8859-1
|
||||
galego gl_ES.ISO-8859-1
|
||||
galician gl_ES.ISO-8859-1
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,22 @@
|
|||
Upstream commits:
|
||||
|
||||
commit 2959eda9272a033863c271aff62095abd01bd4e3
|
||||
Author: Arjun Shankar <arjun.is@lostca.se>
|
||||
Date: Tue Apr 21 14:06:31 2015 +0200
|
||||
|
||||
CVE-2015-1781: resolv/nss_dns/dns-host.c buffer overflow [BZ#18287]
|
||||
|
||||
Index: glibc-2.21/resolv/nss_dns/dns-host.c
|
||||
===================================================================
|
||||
--- glibc-2.21.orig/resolv/nss_dns/dns-host.c
|
||||
+++ glibc-2.21/resolv/nss_dns/dns-host.c
|
||||
@@ -615,7 +615,8 @@ getanswer_r (const querybuf *answer, int
|
||||
int have_to_map = 0;
|
||||
uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
|
||||
buffer += pad;
|
||||
- if (__glibc_unlikely (buflen < sizeof (struct host_data) + pad))
|
||||
+ buflen = buflen > pad ? buflen - pad : 0;
|
||||
+ if (__glibc_unlikely (buflen < sizeof (struct host_data)))
|
||||
{
|
||||
/* The buffer is too small. */
|
||||
too_small:
|
|
@ -0,0 +1,34 @@
|
|||
commit 1c1e3125206ef810dc7282023f6267a33b486233
|
||||
Author: Carlos O'Donell <carlos@systemhalted.org>
|
||||
Date: Wed Jul 8 09:26:45 2015 -0400
|
||||
|
||||
Add missing Advanced API (RFC3542) (1) defines.
|
||||
|
||||
Fixes bug 18643.
|
||||
|
||||
Defines IPV6_RECVPATHMTU, IPV6_PATHMTU, and IPV6_DONTFRAG for Linux.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/bits/in.h b/sysdeps/unix/sysv/linux/bits/in.h
|
||||
index f684736..887719f 100644
|
||||
--- a/sysdeps/unix/sysv/linux/bits/in.h
|
||||
+++ b/sysdeps/unix/sysv/linux/bits/in.h
|
||||
@@ -184,6 +184,7 @@ struct in_pktinfo
|
||||
#define IPV6_IPSEC_POLICY 34
|
||||
#define IPV6_XFRM_POLICY 35
|
||||
|
||||
+/* Advanced API (RFC3542) (1). */
|
||||
#define IPV6_RECVPKTINFO 49
|
||||
#define IPV6_PKTINFO 50
|
||||
#define IPV6_RECVHOPLIMIT 51
|
||||
@@ -195,7 +196,11 @@ struct in_pktinfo
|
||||
#define IPV6_RTHDR 57
|
||||
#define IPV6_RECVDSTOPTS 58
|
||||
#define IPV6_DSTOPTS 59
|
||||
+#define IPV6_RECVPATHMTU 60
|
||||
+#define IPV6_PATHMTU 61
|
||||
+#define IPV6_DONTFRAG 62
|
||||
|
||||
+/* Advanced API (RFC3542) (2). */
|
||||
#define IPV6_RECVTCLASS 66
|
||||
#define IPV6_TCLASS 67
|
||||
|
|
@ -0,0 +1,584 @@
|
|||
commit 85ee11e317058d44d5c6c29bb4c53acc6c0e22c9
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed Oct 28 19:32:46 2015 +0100
|
||||
|
||||
malloc: Prevent arena free_list from turning cyclic [BZ #19048]
|
||||
|
||||
[BZ# 19048]
|
||||
* malloc/malloc.c (struct malloc_state): Update comment. Add
|
||||
attached_threads member.
|
||||
(main_arena): Initialize attached_threads.
|
||||
* malloc/arena.c (list_lock): Update comment.
|
||||
(ptmalloc_lock_all, ptmalloc_unlock_all): Likewise.
|
||||
(ptmalloc_unlock_all2): Reinitialize arena reference counts.
|
||||
(deattach_arena): New function.
|
||||
(_int_new_arena): Initialize arena reference count and deattach
|
||||
replaced arena.
|
||||
(get_free_list, reused_arena): Update reference count and deattach
|
||||
replaced arena.
|
||||
(arena_thread_freeres): Update arena reference count and only put
|
||||
unreferenced arenas on the free list.
|
||||
|
||||
(Backport reintroduces tsd_getspecific, tsd_setspecific.)
|
||||
|
||||
commit 3da825ce483903e3a881a016113b3e59fd4041de
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed Dec 16 12:39:48 2015 +0100
|
||||
|
||||
malloc: Fix attached thread reference count handling [BZ #19243]
|
||||
|
||||
reused_arena can increase the attached thread count of arenas on the
|
||||
free list. This means that the assertion that the reference count is
|
||||
zero is incorrect. In this case, the reference count initialization
|
||||
is incorrect as well and could cause arenas to be put on the free
|
||||
list too early (while they still have attached threads).
|
||||
|
||||
commit 90c400bd4904b0240a148f0b357a5cbc36179239
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Dec 21 16:42:46 2015 +0100
|
||||
|
||||
malloc: Fix list_lock/arena lock deadlock [BZ #19182]
|
||||
|
||||
commit 7962541a32eff5597bc4207e781cfac8d1bb0d87
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Wed Dec 23 17:23:33 2015 +0100
|
||||
|
||||
malloc: Update comment for list_lock
|
||||
|
||||
Index: b/malloc/arena.c
|
||||
===================================================================
|
||||
--- a/malloc/arena.c
|
||||
+++ b/malloc/arena.c
|
||||
@@ -67,10 +67,30 @@ extern int sanity_check_heap_info_alignm
|
||||
/* Thread specific data */
|
||||
|
||||
static tsd_key_t arena_key;
|
||||
-static mutex_t list_lock = MUTEX_INITIALIZER;
|
||||
+
|
||||
+/* Arena free list. free_list_lock synchronizes access to the
|
||||
+ free_list variable below, and the next_free and attached_threads
|
||||
+ members of struct malloc_state objects. No other locks must be
|
||||
+ acquired after free_list_lock has been acquired. */
|
||||
+
|
||||
+static mutex_t free_list_lock = MUTEX_INITIALIZER;
|
||||
static size_t narenas = 1;
|
||||
static mstate free_list;
|
||||
|
||||
+/* list_lock prevents concurrent writes to the next member of struct
|
||||
+ malloc_state objects.
|
||||
+
|
||||
+ Read access to the next member is supposed to synchronize with the
|
||||
+ atomic_write_barrier and the write to the next member in
|
||||
+ _int_new_arena. This suffers from data races; see the FIXME
|
||||
+ comments in _int_new_arena and reused_arena.
|
||||
+
|
||||
+ list_lock also prevents concurrent forks. At the time list_lock is
|
||||
+ acquired, no arena lock must have been acquired, but it is
|
||||
+ permitted to acquire arena locks subsequently, while list_lock is
|
||||
+ acquired. */
|
||||
+static mutex_t list_lock = MUTEX_INITIALIZER;
|
||||
+
|
||||
/* Mapped memory in non-main arenas (reliable only for NO_THREADS). */
|
||||
static unsigned long arena_mem;
|
||||
|
||||
@@ -210,6 +230,9 @@ ptmalloc_lock_all (void)
|
||||
if (__malloc_initialized < 1)
|
||||
return;
|
||||
|
||||
+ /* We do not acquire free_list_lock here because we completely
|
||||
+ reconstruct free_list in ptmalloc_unlock_all2. */
|
||||
+
|
||||
if (mutex_trylock (&list_lock))
|
||||
{
|
||||
void *my_arena;
|
||||
@@ -233,7 +256,10 @@ ptmalloc_lock_all (void)
|
||||
save_free_hook = __free_hook;
|
||||
__malloc_hook = malloc_atfork;
|
||||
__free_hook = free_atfork;
|
||||
- /* Only the current thread may perform malloc/free calls now. */
|
||||
+ /* Only the current thread may perform malloc/free calls now.
|
||||
+ save_arena will be reattached to the current thread, in
|
||||
+ ptmalloc_lock_all, so save_arena->attached_threads is not
|
||||
+ updated. */
|
||||
tsd_getspecific (arena_key, save_arena);
|
||||
tsd_setspecific (arena_key, ATFORK_ARENA_PTR);
|
||||
out:
|
||||
@@ -251,6 +277,9 @@ ptmalloc_unlock_all (void)
|
||||
if (--atfork_recursive_cntr != 0)
|
||||
return;
|
||||
|
||||
+ /* Replace ATFORK_ARENA_PTR with save_arena.
|
||||
+ save_arena->attached_threads was not changed in ptmalloc_lock_all
|
||||
+ and is still correct. */
|
||||
tsd_setspecific (arena_key, save_arena);
|
||||
__malloc_hook = save_malloc_hook;
|
||||
__free_hook = save_free_hook;
|
||||
@@ -282,12 +311,20 @@ ptmalloc_unlock_all2 (void)
|
||||
tsd_setspecific (arena_key, save_arena);
|
||||
__malloc_hook = save_malloc_hook;
|
||||
__free_hook = save_free_hook;
|
||||
+
|
||||
+ /* Push all arenas to the free list, except save_arena, which is
|
||||
+ attached to the current thread. */
|
||||
+ mutex_init (&free_list_lock);
|
||||
+ if (save_arena != NULL)
|
||||
+ ((mstate) save_arena)->attached_threads = 1;
|
||||
free_list = NULL;
|
||||
for (ar_ptr = &main_arena;; )
|
||||
{
|
||||
mutex_init (&ar_ptr->mutex);
|
||||
if (ar_ptr != save_arena)
|
||||
{
|
||||
+ /* This arena is no longer attached to any thread. */
|
||||
+ ar_ptr->attached_threads = 0;
|
||||
ar_ptr->next_free = free_list;
|
||||
free_list = ar_ptr;
|
||||
}
|
||||
@@ -295,6 +332,7 @@ ptmalloc_unlock_all2 (void)
|
||||
if (ar_ptr == &main_arena)
|
||||
break;
|
||||
}
|
||||
+
|
||||
mutex_init (&list_lock);
|
||||
atfork_recursive_cntr = 0;
|
||||
}
|
||||
@@ -714,6 +752,22 @@ heap_trim (heap_info *heap, size_t pad)
|
||||
|
||||
/* Create a new arena with initial size "size". */
|
||||
|
||||
+/* If REPLACED_ARENA is not NULL, detach it from this thread. Must be
|
||||
+ called while free_list_lock is held. */
|
||||
+static void
|
||||
+detach_arena (mstate replaced_arena)
|
||||
+{
|
||||
+ if (replaced_arena != NULL)
|
||||
+ {
|
||||
+ assert (replaced_arena->attached_threads > 0);
|
||||
+ /* The current implementation only detaches from main_arena in
|
||||
+ case of allocation failure. This means that it is likely not
|
||||
+ beneficial to put the arena on free_list even if the
|
||||
+ reference count reaches zero. */
|
||||
+ --replaced_arena->attached_threads;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static mstate
|
||||
_int_new_arena (size_t size)
|
||||
{
|
||||
@@ -735,6 +789,7 @@ _int_new_arena (size_t size)
|
||||
}
|
||||
a = h->ar_ptr = (mstate) (h + 1);
|
||||
malloc_init_state (a);
|
||||
+ a->attached_threads = 1;
|
||||
/*a->next = NULL;*/
|
||||
a->system_mem = a->max_system_mem = h->size;
|
||||
arena_mem += h->size;
|
||||
@@ -748,34 +803,67 @@ _int_new_arena (size_t size)
|
||||
set_head (top (a), (((char *) h + h->size) - ptr) | PREV_INUSE);
|
||||
|
||||
LIBC_PROBE (memory_arena_new, 2, a, size);
|
||||
+ mstate replaced_arena;
|
||||
+ {
|
||||
+ void *vptr = NULL;
|
||||
+ replaced_arena = tsd_getspecific (arena_key, vptr);
|
||||
+ }
|
||||
tsd_setspecific (arena_key, (void *) a);
|
||||
mutex_init (&a->mutex);
|
||||
- (void) mutex_lock (&a->mutex);
|
||||
|
||||
(void) mutex_lock (&list_lock);
|
||||
|
||||
/* Add the new arena to the global list. */
|
||||
a->next = main_arena.next;
|
||||
+ /* FIXME: The barrier is an attempt to synchronize with read access
|
||||
+ in reused_arena, which does not acquire list_lock while
|
||||
+ traversing the list. */
|
||||
atomic_write_barrier ();
|
||||
main_arena.next = a;
|
||||
|
||||
(void) mutex_unlock (&list_lock);
|
||||
|
||||
+ (void) mutex_lock (&free_list_lock);
|
||||
+ detach_arena (replaced_arena);
|
||||
+ (void) mutex_unlock (&free_list_lock);
|
||||
+
|
||||
+ /* Lock this arena. NB: Another thread may have been attached to
|
||||
+ this arena because the arena is now accessible from the
|
||||
+ main_arena.next list and could have been picked by reused_arena.
|
||||
+ This can only happen for the last arena created (before the arena
|
||||
+ limit is reached). At this point, some arena has to be attached
|
||||
+ to two threads. We could acquire the arena lock before list_lock
|
||||
+ to make it less likely that reused_arena picks this new arena,
|
||||
+ but this could result in a deadlock with ptmalloc_lock_all. */
|
||||
+
|
||||
+ (void) mutex_lock (&a->mutex);
|
||||
+
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
+/* Remove an arena from free_list. The arena may be in use because it
|
||||
+ was attached concurrently to a thread by reused_arena below. */
|
||||
static mstate
|
||||
get_free_list (void)
|
||||
{
|
||||
+ void *vptr = NULL;
|
||||
+ mstate replaced_arena = tsd_getspecific (arena_key, vptr);
|
||||
mstate result = free_list;
|
||||
if (result != NULL)
|
||||
{
|
||||
- (void) mutex_lock (&list_lock);
|
||||
+ (void) mutex_lock (&free_list_lock);
|
||||
result = free_list;
|
||||
if (result != NULL)
|
||||
- free_list = result->next_free;
|
||||
- (void) mutex_unlock (&list_lock);
|
||||
+ {
|
||||
+ free_list = result->next_free;
|
||||
+
|
||||
+ /* The arena will be attached to this thread. */
|
||||
+ ++result->attached_threads;
|
||||
+
|
||||
+ detach_arena (replaced_arena);
|
||||
+ }
|
||||
+ (void) mutex_unlock (&free_list_lock);
|
||||
|
||||
if (result != NULL)
|
||||
{
|
||||
@@ -795,16 +883,20 @@ static mstate
|
||||
reused_arena (mstate avoid_arena)
|
||||
{
|
||||
mstate result;
|
||||
+ /* FIXME: Access to next_to_use suffers from data races. */
|
||||
static mstate next_to_use;
|
||||
if (next_to_use == NULL)
|
||||
next_to_use = &main_arena;
|
||||
|
||||
+ /* Iterate over all arenas (including those linked from
|
||||
+ free_list). */
|
||||
result = next_to_use;
|
||||
do
|
||||
{
|
||||
if (!mutex_trylock (&result->mutex))
|
||||
goto out;
|
||||
|
||||
+ /* FIXME: This is a data race, see _int_new_arena. */
|
||||
result = result->next;
|
||||
}
|
||||
while (result != next_to_use);
|
||||
@@ -819,6 +911,18 @@ reused_arena (mstate avoid_arena)
|
||||
(void) mutex_lock (&result->mutex);
|
||||
|
||||
out:
|
||||
+ /* Attach the arena to the current thread. Note that we may have
|
||||
+ selected an arena which was on free_list. */
|
||||
+ {
|
||||
+ /* Update the arena thread attachment counters. */
|
||||
+ void *vptr = NULL;
|
||||
+ mstate replaced_arena = tsd_getspecific (arena_key, vptr);
|
||||
+ (void) mutex_lock (&free_list_lock);
|
||||
+ detach_arena (replaced_arena);
|
||||
+ ++result->attached_threads;
|
||||
+ (void) mutex_unlock (&free_list_lock);
|
||||
+ }
|
||||
+
|
||||
LIBC_PROBE (memory_arena_reuse, 2, result, avoid_arena);
|
||||
tsd_setspecific (arena_key, (void *) result);
|
||||
next_to_use = result->next;
|
||||
@@ -911,10 +1015,16 @@ arena_thread_freeres (void)
|
||||
|
||||
if (a != NULL)
|
||||
{
|
||||
- (void) mutex_lock (&list_lock);
|
||||
- a->next_free = free_list;
|
||||
- free_list = a;
|
||||
- (void) mutex_unlock (&list_lock);
|
||||
+ (void) mutex_lock (&free_list_lock);
|
||||
+ /* If this was the last attached thread for this arena, put the
|
||||
+ arena on the free list. */
|
||||
+ assert (a->attached_threads > 0);
|
||||
+ if (--a->attached_threads == 0)
|
||||
+ {
|
||||
+ a->next_free = free_list;
|
||||
+ free_list = a;
|
||||
+ }
|
||||
+ (void) mutex_unlock (&free_list_lock);
|
||||
}
|
||||
}
|
||||
text_set_element (__libc_thread_subfreeres, arena_thread_freeres);
|
||||
Index: b/malloc/malloc.c
|
||||
===================================================================
|
||||
--- a/malloc/malloc.c
|
||||
+++ b/malloc/malloc.c
|
||||
@@ -1700,9 +1700,15 @@ struct malloc_state
|
||||
/* Linked list */
|
||||
struct malloc_state *next;
|
||||
|
||||
- /* Linked list for free arenas. */
|
||||
+ /* Linked list for free arenas. Access to this field is serialized
|
||||
+ by free_list_lock in arena.c. */
|
||||
struct malloc_state *next_free;
|
||||
|
||||
+ /* Number of threads attached to this arena. 0 if the arena is on
|
||||
+ the free list. Access to this field is serialized by
|
||||
+ free_list_lock in arena.c. */
|
||||
+ INTERNAL_SIZE_T attached_threads;
|
||||
+
|
||||
/* Memory allocated from the system in this arena. */
|
||||
INTERNAL_SIZE_T system_mem;
|
||||
INTERNAL_SIZE_T max_system_mem;
|
||||
@@ -1746,7 +1752,8 @@ struct malloc_par
|
||||
static struct malloc_state main_arena =
|
||||
{
|
||||
.mutex = MUTEX_INITIALIZER,
|
||||
- .next = &main_arena
|
||||
+ .next = &main_arena,
|
||||
+ .attached_threads = 1
|
||||
};
|
||||
|
||||
/* There is only one instance of the malloc parameters. */
|
||||
Index: b/malloc/Makefile
|
||||
===================================================================
|
||||
--- a/malloc/Makefile
|
||||
+++ b/malloc/Makefile
|
||||
@@ -27,7 +27,8 @@ headers := $(dist-headers) obstack.h mch
|
||||
tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
|
||||
tst-mallocstate tst-mcheck tst-mallocfork tst-trim1 \
|
||||
tst-malloc-usable tst-realloc tst-posix_memalign \
|
||||
- tst-pvalloc tst-memalign tst-mallopt
|
||||
+ tst-pvalloc tst-memalign tst-mallopt \
|
||||
+ tst-malloc-thread-exit
|
||||
test-srcs = tst-mtrace
|
||||
|
||||
routines = malloc morecore mcheck mtrace obstack
|
||||
@@ -154,5 +155,8 @@ $(objpfx)memusage: memusage.sh
|
||||
# The implementation uses `dlsym'
|
||||
$(objpfx)libmemusage.so: $(libdl)
|
||||
|
||||
+$(objpfx)tst-malloc-thread-exit: $(common-objpfx)nptl/libpthread.so \
|
||||
+ $(common-objpfx)nptl/libpthread_nonshared.a
|
||||
+
|
||||
# Extra dependencies
|
||||
$(foreach o,$(all-object-suffixes),$(objpfx)malloc$(o)): arena.c hooks.c
|
||||
Index: b/malloc/tst-malloc-thread-exit.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ b/malloc/tst-malloc-thread-exit.c
|
||||
@@ -0,0 +1,217 @@
|
||||
+/* Test malloc with concurrent thread termination.
|
||||
+ Copyright (C) 2015 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/>. */
|
||||
+
|
||||
+/* This thread spawns a number of outer threads, equal to the arena
|
||||
+ limit. The outer threads run a loop which start and join two
|
||||
+ different kinds of threads: the first kind allocates (attaching an
|
||||
+ arena to the thread; malloc_first_thread) and waits, the second
|
||||
+ kind waits and allocates (wait_first_threads). Both kinds of
|
||||
+ threads exit immediately after waiting. The hope is that this will
|
||||
+ exhibit races in thread termination and arena management,
|
||||
+ particularly related to the arena free list. */
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <pthread.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#define TIMEOUT 7
|
||||
+
|
||||
+static bool termination_requested;
|
||||
+static int inner_thread_count = 4;
|
||||
+static size_t malloc_size = 32;
|
||||
+
|
||||
+static void
|
||||
+__attribute__ ((noinline, noclone))
|
||||
+unoptimized_free (void *ptr)
|
||||
+{
|
||||
+ free (ptr);
|
||||
+}
|
||||
+
|
||||
+static void *
|
||||
+malloc_first_thread (void * closure)
|
||||
+{
|
||||
+ pthread_barrier_t *barrier = closure;
|
||||
+ void *ptr = malloc (malloc_size);
|
||||
+ if (ptr == NULL)
|
||||
+ {
|
||||
+ printf ("error: malloc: %m\n");
|
||||
+ abort ();
|
||||
+ }
|
||||
+ int ret = pthread_barrier_wait (barrier);
|
||||
+ if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD)
|
||||
+ {
|
||||
+ errno = ret;
|
||||
+ printf ("error: pthread_barrier_wait: %m\n");
|
||||
+ abort ();
|
||||
+ }
|
||||
+ unoptimized_free (ptr);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void *
|
||||
+wait_first_thread (void * closure)
|
||||
+{
|
||||
+ pthread_barrier_t *barrier = closure;
|
||||
+ int ret = pthread_barrier_wait (barrier);
|
||||
+ if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD)
|
||||
+ {
|
||||
+ errno = ret;
|
||||
+ printf ("error: pthread_barrier_wait: %m\n");
|
||||
+ abort ();
|
||||
+ }
|
||||
+ void *ptr = malloc (malloc_size);
|
||||
+ if (ptr == NULL)
|
||||
+ {
|
||||
+ printf ("error: malloc: %m\n");
|
||||
+ abort ();
|
||||
+ }
|
||||
+ unoptimized_free (ptr);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void *
|
||||
+outer_thread (void *closure)
|
||||
+{
|
||||
+ pthread_t *threads = calloc (sizeof (*threads), inner_thread_count);
|
||||
+ if (threads == NULL)
|
||||
+ {
|
||||
+ printf ("error: calloc: %m\n");
|
||||
+ abort ();
|
||||
+ }
|
||||
+
|
||||
+ while (!__atomic_load_n (&termination_requested, __ATOMIC_RELAXED))
|
||||
+ {
|
||||
+ pthread_barrier_t barrier;
|
||||
+ int ret = pthread_barrier_init (&barrier, NULL, inner_thread_count + 1);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ errno = ret;
|
||||
+ printf ("pthread_barrier_init: %m\n");
|
||||
+ abort ();
|
||||
+ }
|
||||
+ for (int i = 0; i < inner_thread_count; ++i)
|
||||
+ {
|
||||
+ void *(*func) (void *);
|
||||
+ if ((i % 2) == 0)
|
||||
+ func = malloc_first_thread;
|
||||
+ else
|
||||
+ func = wait_first_thread;
|
||||
+ ret = pthread_create (threads + i, NULL, func, &barrier);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ errno = ret;
|
||||
+ printf ("error: pthread_create: %m\n");
|
||||
+ abort ();
|
||||
+ }
|
||||
+ }
|
||||
+ ret = pthread_barrier_wait (&barrier);
|
||||
+ if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD)
|
||||
+ {
|
||||
+ errno = ret;
|
||||
+ printf ("pthread_wait: %m\n");
|
||||
+ abort ();
|
||||
+ }
|
||||
+ for (int i = 0; i < inner_thread_count; ++i)
|
||||
+ {
|
||||
+ ret = pthread_join (threads[i], NULL);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ ret = errno;
|
||||
+ printf ("error: pthread_join: %m\n");
|
||||
+ abort ();
|
||||
+ }
|
||||
+ }
|
||||
+ ret = pthread_barrier_destroy (&barrier);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ ret = errno;
|
||||
+ printf ("pthread_barrier_destroy: %m\n");
|
||||
+ abort ();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ free (threads);
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ /* The number of top-level threads should be equal to the number of
|
||||
+ arenas. See arena_get2. */
|
||||
+ long outer_thread_count = sysconf (_SC_NPROCESSORS_ONLN);
|
||||
+ if (outer_thread_count >= 1)
|
||||
+ {
|
||||
+ /* See NARENAS_FROM_NCORES in malloc.c. */
|
||||
+ if (sizeof (long) == 4)
|
||||
+ outer_thread_count *= 2;
|
||||
+ else
|
||||
+ outer_thread_count *= 8;
|
||||
+ }
|
||||
+
|
||||
+ /* Leave some room for shutting down all threads gracefully. */
|
||||
+ int timeout = TIMEOUT - 2;
|
||||
+
|
||||
+ pthread_t *threads = calloc (sizeof (*threads), outer_thread_count);
|
||||
+ if (threads == NULL)
|
||||
+ {
|
||||
+ printf ("error: calloc: %m\n");
|
||||
+ abort ();
|
||||
+ }
|
||||
+
|
||||
+ for (long i = 0; i < outer_thread_count; ++i)
|
||||
+ {
|
||||
+ int ret = pthread_create (threads + i, NULL, outer_thread, NULL);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ errno = ret;
|
||||
+ printf ("error: pthread_create: %m\n");
|
||||
+ abort ();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ struct timespec ts = {timeout, 0};
|
||||
+ if (nanosleep (&ts, NULL))
|
||||
+ {
|
||||
+ printf ("error: error: nanosleep: %m\n");
|
||||
+ abort ();
|
||||
+ }
|
||||
+
|
||||
+ __atomic_store_n (&termination_requested, true, __ATOMIC_RELAXED);
|
||||
+
|
||||
+ for (long i = 0; i < outer_thread_count; ++i)
|
||||
+ {
|
||||
+ int ret = pthread_join (threads[i], NULL);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ errno = ret;
|
||||
+ printf ("error: pthread_join: %m\n");
|
||||
+ abort ();
|
||||
+ }
|
||||
+ }
|
||||
+ free (threads);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#define TEST_FUNCTION do_test ()
|
||||
+#include "../test-skeleton.c"
|
|
@ -0,0 +1,66 @@
|
|||
commit a014cecd82b71b70a6a843e250e06b541ad524f7
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu Oct 15 09:23:07 2015 +0200
|
||||
|
||||
Always enable pointer guard [BZ #18928]
|
||||
|
||||
Honoring the LD_POINTER_GUARD environment variable in AT_SECURE mode
|
||||
has security implications. This commit enables pointer guard
|
||||
unconditionally, and the environment variable is now ignored.
|
||||
|
||||
Index: b/elf/rtld.c
|
||||
===================================================================
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -160,7 +160,6 @@ struct rtld_global_ro _rtld_global_ro at
|
||||
._dl_hwcap_mask = HWCAP_IMPORTANT,
|
||||
._dl_lazy = 1,
|
||||
._dl_fpu_control = _FPU_DEFAULT,
|
||||
- ._dl_pointer_guard = 1,
|
||||
._dl_pagesize = EXEC_PAGESIZE,
|
||||
._dl_inhibit_cache = 0,
|
||||
|
||||
@@ -707,15 +706,12 @@ security_init (void)
|
||||
#endif
|
||||
|
||||
/* Set up the pointer guard as well, if necessary. */
|
||||
- if (GLRO(dl_pointer_guard))
|
||||
- {
|
||||
- uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random,
|
||||
- stack_chk_guard);
|
||||
+ uintptr_t pointer_chk_guard
|
||||
+ = _dl_setup_pointer_guard (_dl_random, stack_chk_guard);
|
||||
#ifdef THREAD_SET_POINTER_GUARD
|
||||
- THREAD_SET_POINTER_GUARD (pointer_chk_guard);
|
||||
+ THREAD_SET_POINTER_GUARD (pointer_chk_guard);
|
||||
#endif
|
||||
- __pointer_chk_guard_local = pointer_chk_guard;
|
||||
- }
|
||||
+ __pointer_chk_guard_local = pointer_chk_guard;
|
||||
|
||||
/* We do not need the _dl_random value anymore. The less
|
||||
information we leave behind, the better, so clear the
|
||||
@@ -2467,9 +2463,6 @@ process_envvars (enum mode *modep)
|
||||
GLRO(dl_use_load_bias) = envline[14] == '1' ? -1 : 0;
|
||||
break;
|
||||
}
|
||||
-
|
||||
- if (memcmp (envline, "POINTER_GUARD", 13) == 0)
|
||||
- GLRO(dl_pointer_guard) = envline[14] != '0';
|
||||
break;
|
||||
|
||||
case 14:
|
||||
Index: b/sysdeps/generic/ldsodefs.h
|
||||
===================================================================
|
||||
--- a/sysdeps/generic/ldsodefs.h
|
||||
+++ b/sysdeps/generic/ldsodefs.h
|
||||
@@ -592,9 +592,6 @@ struct rtld_global_ro
|
||||
/* List of auditing interfaces. */
|
||||
struct audit_ifaces *_dl_audit;
|
||||
unsigned int _dl_naudit;
|
||||
-
|
||||
- /* 0 if internal pointer values should not be guarded, 1 if they should. */
|
||||
- EXTERN int _dl_pointer_guard;
|
||||
};
|
||||
# define __rtld_global_attribute__
|
||||
# if IS_IN (rtld)
|
|
@ -0,0 +1,378 @@
|
|||
commit 99e1dc0a688d6c25d3f422bc9f3fa29adb483339
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Oct 6 21:27:55 2015 +0200
|
||||
|
||||
Add a test case for C++11 thread_local support
|
||||
|
||||
This requires a C++ compiler with thread_local support, and a new
|
||||
configure check is needed.
|
||||
|
||||
Index: b/config.make.in
|
||||
===================================================================
|
||||
--- a/config.make.in
|
||||
+++ b/config.make.in
|
||||
@@ -66,6 +66,7 @@ bind-now = @bindnow@
|
||||
have-hash-style = @libc_cv_hashstyle@
|
||||
use-default-link = @use_default_link@
|
||||
output-format = @libc_cv_output_format@
|
||||
+have-cxx-thread_local = @libc_cv_cxx_thread_local@
|
||||
|
||||
static-libgcc = @libc_cv_gcc_static_libgcc@
|
||||
|
||||
Index: b/configure
|
||||
===================================================================
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -613,6 +613,7 @@ use_nscd
|
||||
libc_cv_gcc_unwind_find_fde
|
||||
libc_extra_cppflags
|
||||
libc_extra_cflags
|
||||
+libc_cv_cxx_thread_local
|
||||
CPPUNDEFS
|
||||
sizeof_long_double
|
||||
have_selinux
|
||||
@@ -7047,6 +7048,61 @@ if test $libc_cv_builtin_trap = yes; the
|
||||
|
||||
fi
|
||||
|
||||
+ac_ext=cpp
|
||||
+ac_cpp='$CXXCPP $CPPFLAGS'
|
||||
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
+
|
||||
+
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler supports thread_local" >&5
|
||||
+$as_echo_n "checking whether the C++ compiler supports thread_local... " >&6; }
|
||||
+if ${libc_cv_cxx_thread_local+:} false; then :
|
||||
+ $as_echo_n "(cached) " >&6
|
||||
+else
|
||||
+
|
||||
+old_CXXFLAGS="$CXXFLAGS"
|
||||
+CXXFLAGS="$CXXFLAGS -std=gnu++11"
|
||||
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
+/* end confdefs.h. */
|
||||
+
|
||||
+#include <thread>
|
||||
+
|
||||
+// Compiler support.
|
||||
+struct S
|
||||
+{
|
||||
+ S ();
|
||||
+ ~S ();
|
||||
+};
|
||||
+thread_local S s;
|
||||
+S * get () { return &s; }
|
||||
+
|
||||
+// libstdc++ support.
|
||||
+#ifndef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL
|
||||
+#error __cxa_thread_atexit_impl not supported
|
||||
+#endif
|
||||
+
|
||||
+_ACEOF
|
||||
+if ac_fn_cxx_try_compile "$LINENO"; then :
|
||||
+ libc_cv_cxx_thread_local=yes
|
||||
+else
|
||||
+ libc_cv_cxx_thread_local=no
|
||||
+fi
|
||||
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
+CXXFLAGS="$old_CXXFLAGS"
|
||||
+
|
||||
+fi
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cxx_thread_local" >&5
|
||||
+$as_echo "$libc_cv_cxx_thread_local" >&6; }
|
||||
+
|
||||
+
|
||||
+ac_ext=c
|
||||
+ac_cpp='$CPP $CPPFLAGS'
|
||||
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
+
|
||||
+
|
||||
### End of automated tests.
|
||||
### Now run sysdeps configure fragments.
|
||||
|
||||
Index: b/configure.ac
|
||||
===================================================================
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -1925,6 +1925,39 @@ if test $libc_cv_builtin_trap = yes; the
|
||||
AC_DEFINE([HAVE_BUILTIN_TRAP])
|
||||
fi
|
||||
|
||||
+dnl C++ feature tests.
|
||||
+AC_LANG_PUSH([C++])
|
||||
+
|
||||
+AC_CACHE_CHECK([whether the C++ compiler supports thread_local],
|
||||
+ libc_cv_cxx_thread_local, [
|
||||
+old_CXXFLAGS="$CXXFLAGS"
|
||||
+CXXFLAGS="$CXXFLAGS -std=gnu++11"
|
||||
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([
|
||||
+#include <thread>
|
||||
+
|
||||
+// Compiler support.
|
||||
+struct S
|
||||
+{
|
||||
+ S ();
|
||||
+ ~S ();
|
||||
+};
|
||||
+thread_local S s;
|
||||
+S * get () { return &s; }
|
||||
+
|
||||
+// libstdc++ support.
|
||||
+#ifndef _GLIBCXX_HAVE___CXA_THREAD_ATEXIT_IMPL
|
||||
+#error __cxa_thread_atexit_impl not supported
|
||||
+#endif
|
||||
+])],
|
||||
+ [libc_cv_cxx_thread_local=yes],
|
||||
+ [libc_cv_cxx_thread_local=no])
|
||||
+CXXFLAGS="$old_CXXFLAGS"
|
||||
+])
|
||||
+AC_SUBST(libc_cv_cxx_thread_local)
|
||||
+
|
||||
+AC_LANG_POP([C++])
|
||||
+dnl End of C++ feature tests.
|
||||
+
|
||||
### End of automated tests.
|
||||
### Now run sysdeps configure fragments.
|
||||
|
||||
Index: b/nptl/Makefile
|
||||
===================================================================
|
||||
--- a/nptl/Makefile
|
||||
+++ b/nptl/Makefile
|
||||
@@ -205,6 +205,8 @@ CFLAGS-send.c = -fexceptions -fasynchron
|
||||
|
||||
CFLAGS-pt-system.c = -fexceptions
|
||||
|
||||
+CFLAGS-tst-thread_local1.o = -std=gnu++11
|
||||
+LDLIBS-tst-thread_local1 = -lstdc++
|
||||
|
||||
tests = tst-typesizes \
|
||||
tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
|
||||
@@ -274,7 +276,8 @@ tests = tst-typesizes \
|
||||
tst-getpid1 tst-getpid2 tst-getpid3 \
|
||||
tst-setuid3 \
|
||||
tst-initializers1 $(addprefix tst-initializers1-,c89 gnu89 c99 gnu99) \
|
||||
- tst-bad-schedattr
|
||||
+ tst-bad-schedattr \
|
||||
+ tst-thread_local1
|
||||
xtests = tst-setuid1 tst-setuid1-static tst-setuid2 \
|
||||
tst-mutexpp1 tst-mutexpp6 tst-mutexpp10
|
||||
test-srcs = tst-oddstacklimit
|
||||
@@ -385,6 +388,11 @@ tests-special += $(objpfx)tst-tls6.out $
|
||||
endif
|
||||
endif
|
||||
|
||||
+# These tests require a C++ compiler and runtime with thread_local support.
|
||||
+ifneq ($(have-cxx-thread_local),yes)
|
||||
+tests-unsupported += tst-thread_local1
|
||||
+endif
|
||||
+
|
||||
include ../Rules
|
||||
|
||||
ifeq (yes,$(build-shared))
|
||||
Index: b/nptl/tst-thread_local1.cc
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ b/nptl/tst-thread_local1.cc
|
||||
@@ -0,0 +1,199 @@
|
||||
+/* Test basic thread_local support.
|
||||
+ Copyright (C) 2015 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 <errno.h>
|
||||
+#include <pthread.h>
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+#include <functional>
|
||||
+#include <string>
|
||||
+#include <thread>
|
||||
+
|
||||
+struct counter
|
||||
+{
|
||||
+ int constructed {};
|
||||
+ int destructed {};
|
||||
+
|
||||
+ void reset ();
|
||||
+};
|
||||
+
|
||||
+void
|
||||
+counter::reset ()
|
||||
+{
|
||||
+ constructed = 0;
|
||||
+ destructed = 0;
|
||||
+}
|
||||
+
|
||||
+static std::string
|
||||
+to_string (const counter &c)
|
||||
+{
|
||||
+ char buf[128];
|
||||
+ snprintf (buf, sizeof (buf), "%d/%d",
|
||||
+ c.constructed, c.destructed);
|
||||
+ return buf;
|
||||
+}
|
||||
+
|
||||
+template <counter *Counter>
|
||||
+struct counting
|
||||
+{
|
||||
+ counting () __attribute__ ((noinline, noclone));
|
||||
+ ~counting () __attribute__ ((noinline, noclone));
|
||||
+ void operation () __attribute__ ((noinline, noclone));
|
||||
+};
|
||||
+
|
||||
+template<counter *Counter>
|
||||
+__attribute__ ((noinline, noclone))
|
||||
+counting<Counter>::counting ()
|
||||
+{
|
||||
+ ++Counter->constructed;
|
||||
+}
|
||||
+
|
||||
+template<counter *Counter>
|
||||
+__attribute__ ((noinline, noclone))
|
||||
+counting<Counter>::~counting ()
|
||||
+{
|
||||
+ ++Counter->destructed;
|
||||
+}
|
||||
+
|
||||
+template<counter *Counter>
|
||||
+void __attribute__ ((noinline, noclone))
|
||||
+counting<Counter>::operation ()
|
||||
+{
|
||||
+ // Optimization barrier.
|
||||
+ asm ("");
|
||||
+}
|
||||
+
|
||||
+static counter counter_static;
|
||||
+static counter counter_anonymous_namespace;
|
||||
+static counter counter_extern;
|
||||
+static counter counter_function_local;
|
||||
+static bool errors (false);
|
||||
+
|
||||
+static std::string
|
||||
+all_counters ()
|
||||
+{
|
||||
+ return to_string (counter_static)
|
||||
+ + ' ' + to_string (counter_anonymous_namespace)
|
||||
+ + ' ' + to_string (counter_extern)
|
||||
+ + ' ' + to_string (counter_function_local);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+check_counters (const char *name, const char *expected)
|
||||
+{
|
||||
+ std::string actual{all_counters ()};
|
||||
+ if (actual != expected)
|
||||
+ {
|
||||
+ printf ("error: %s: (%s) != (%s)\n",
|
||||
+ name, actual.c_str (), expected);
|
||||
+ errors = true;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+reset_all ()
|
||||
+{
|
||||
+ counter_static.reset ();
|
||||
+ counter_anonymous_namespace.reset ();
|
||||
+ counter_extern.reset ();
|
||||
+ counter_function_local.reset ();
|
||||
+}
|
||||
+
|
||||
+static thread_local counting<&counter_static> counting_static;
|
||||
+namespace {
|
||||
+ thread_local counting<&counter_anonymous_namespace>
|
||||
+ counting_anonymous_namespace;
|
||||
+}
|
||||
+extern thread_local counting<&counter_extern> counting_extern;
|
||||
+thread_local counting<&counter_extern> counting_extern;
|
||||
+
|
||||
+static void *
|
||||
+thread_without_access (void *)
|
||||
+{
|
||||
+ return nullptr;
|
||||
+}
|
||||
+
|
||||
+static void *
|
||||
+thread_with_access (void *)
|
||||
+{
|
||||
+ thread_local counting<&counter_function_local> counting_function_local;
|
||||
+ counting_function_local.operation ();
|
||||
+ check_counters ("early in thread_with_access", "0/0 0/0 0/0 1/0");
|
||||
+ counting_static.operation ();
|
||||
+ counting_anonymous_namespace.operation ();
|
||||
+ counting_extern.operation ();
|
||||
+ check_counters ("in thread_with_access", "1/0 1/0 1/0 1/0");
|
||||
+ return nullptr;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ std::function<void (void *(void *))> do_pthread =
|
||||
+ [](void *(func) (void *))
|
||||
+ {
|
||||
+ pthread_t thr;
|
||||
+ int ret = pthread_create (&thr, nullptr, func, nullptr);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ errno = ret;
|
||||
+ printf ("error: pthread_create: %m\n");
|
||||
+ errors = true;
|
||||
+ return;
|
||||
+ }
|
||||
+ ret = pthread_join (thr, nullptr);
|
||||
+ if (ret != 0)
|
||||
+ {
|
||||
+ errno = ret;
|
||||
+ printf ("error: pthread_join: %m\n");
|
||||
+ errors = true;
|
||||
+ return;
|
||||
+ }
|
||||
+ };
|
||||
+ std::function<void (void *(void *))> do_std_thread =
|
||||
+ [](void *(func) (void *))
|
||||
+ {
|
||||
+ std::thread thr{[func] {func (nullptr);}};
|
||||
+ thr.join ();
|
||||
+ };
|
||||
+
|
||||
+ std::array<std::pair<const char *, std::function<void (void *(void *))>>, 2>
|
||||
+ do_thread_X
|
||||
+ {{
|
||||
+ {"pthread_create", do_pthread},
|
||||
+ {"std::thread", do_std_thread},
|
||||
+ }};
|
||||
+
|
||||
+ for (auto do_thread : do_thread_X)
|
||||
+ {
|
||||
+ printf ("info: testing %s\n", do_thread.first);
|
||||
+ check_counters ("initial", "0/0 0/0 0/0 0/0");
|
||||
+ do_thread.second (thread_without_access);
|
||||
+ check_counters ("after thread_without_access", "0/0 0/0 0/0 0/0");
|
||||
+ reset_all ();
|
||||
+ do_thread.second (thread_with_access);
|
||||
+ check_counters ("after thread_with_access", "1/1 1/1 1/1 1/1");
|
||||
+ reset_all ();
|
||||
+ }
|
||||
+
|
||||
+ return errors;
|
||||
+}
|
||||
+
|
||||
+#define TEST_FUNCTION do_test ()
|
||||
+#include "../test-skeleton.c"
|
|
@ -0,0 +1,36 @@
|
|||
commit f586e1328681b400078c995a0bb6ad301ef73549
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Oct 6 13:12:36 2015 +0200
|
||||
|
||||
Harden tls_dtor_list with pointer mangling [BZ #19018]
|
||||
|
||||
Index: b/stdlib/cxa_thread_atexit_impl.c
|
||||
===================================================================
|
||||
--- a/stdlib/cxa_thread_atexit_impl.c
|
||||
+++ b/stdlib/cxa_thread_atexit_impl.c
|
||||
@@ -42,6 +42,10 @@ static __thread struct link_map *lm_cach
|
||||
int
|
||||
__cxa_thread_atexit_impl (dtor_func func, void *obj, void *dso_symbol)
|
||||
{
|
||||
+#ifdef PTR_MANGLE
|
||||
+ PTR_MANGLE (func);
|
||||
+#endif
|
||||
+
|
||||
/* Prepend. */
|
||||
struct dtor_list *new = calloc (1, sizeof (struct dtor_list));
|
||||
new->func = func;
|
||||
@@ -83,9 +87,13 @@ __call_tls_dtors (void)
|
||||
while (tls_dtor_list)
|
||||
{
|
||||
struct dtor_list *cur = tls_dtor_list;
|
||||
+ dtor_func func = cur->func;
|
||||
+#ifdef PTR_DEMANGLE
|
||||
+ PTR_DEMANGLE (func);
|
||||
+#endif
|
||||
tls_dtor_list = tls_dtor_list->next;
|
||||
|
||||
- cur->func (cur->obj);
|
||||
+ func (cur->obj);
|
||||
|
||||
__rtld_lock_lock_recursive (GL(dl_load_lock));
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
Backport part of this upstream commit:
|
||||
|
||||
commit 016495b818cb61df7d0d10e6db54074271b3e3a5
|
||||
Author: Stefan Liebler <stli@linux.vnet.ibm.com>
|
||||
Date: Mon Nov 9 16:14:49 2015 +0100
|
||||
|
||||
S390: Call direct system calls for socket operations.
|
||||
|
||||
this patch calls direct system calls for socket operations in the same way as power does. The system calls were introduced in kernel commit https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=977108f89c989b1eeb5c8d938e1e71913391eb5f.
|
||||
There are no direct recv, send, accept syscalls available on s390. Thus
|
||||
recvfrom, sendto, accept4 are called instead of the socketcall by defining __ASSUME_*_FOR_*_SYSCALL macros. See recv.c, send.c, accept.c in sysdeps/unix/sysv/linux/ folder.
|
||||
|
||||
The socketcalls in syscalls.list for s390-64 are removed. They were never used on s390x.
|
||||
|
||||
|
||||
The removal is required due to the kernel change because otherwise,
|
||||
these system calls will be used unconditionally with new kernel
|
||||
headers.
|
||||
|
||||
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list b/sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list
|
||||
index 5b8c102..9f03d26 100644
|
||||
--- a/sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list
|
||||
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list
|
||||
@@ -12,22 +12,3 @@ shmget - shmget i:iii __shmget shmget
|
||||
semop - semop i:ipi __semop semop
|
||||
semget - semget i:iii __semget semget
|
||||
semctl - semctl i:iiii __semctl semctl
|
||||
-
|
||||
-# proper socket implementations:
|
||||
-accept - accept Ci:iBN __libc_accept __accept accept
|
||||
-bind - bind i:ipi __bind bind
|
||||
-connect - connect Ci:ipi __libc_connect __connect connect
|
||||
-getpeername - getpeername i:ipp __getpeername getpeername
|
||||
-getsockname - getsockname i:ipp __getsockname getsockname
|
||||
-getsockopt - getsockopt i:iiiBN __getsockopt getsockopt
|
||||
-listen - listen i:ii __listen listen
|
||||
-recv - recv Ci:ibni __libc_recv __recv recv
|
||||
-recvfrom - recvfrom Ci:ibniBN __libc_recvfrom __recvfrom recvfrom
|
||||
-recvmsg - recvmsg Ci:ipi __libc_recvmsg __recvmsg recvmsg
|
||||
-send - send Ci:ibni __libc_send __send send
|
||||
-sendmsg - sendmsg Ci:ipi __libc_sendmsg __sendmsg sendmsg
|
||||
-sendto - sendto Ci:ibnibn __libc_sendto __sendto sendto
|
||||
-setsockopt - setsockopt i:iiibn __setsockopt setsockopt
|
||||
-shutdown - shutdown i:ii __shutdown shutdown
|
||||
-socket - socket i:iii __socket socket
|
||||
-socketpair - socketpair i:iiif __socketpair socketpair
|
|
@ -0,0 +1,19 @@
|
|||
commit 51225803259c69a792a272d067443f3fbc9b79d7
|
||||
Author: Andreas Schwab <schwab@suse.de>
|
||||
Date: Thu Jan 22 17:54:21 2015 +0100
|
||||
|
||||
Fix failure of elf/tst-audit2 when compiled with GCC-5
|
||||
|
||||
Index: b/elf/Makefile
|
||||
===================================================================
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -1016,6 +1016,8 @@ $(objpfx)tst-audit1.out: $(objpfx)tst-au
|
||||
tst-audit1-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so
|
||||
|
||||
$(objpfx)tst-audit2.out: $(objpfx)tst-auditmod1.so
|
||||
+# Prevent GCC-5 from translating a malloc/memset pair into calloc
|
||||
+CFLAGS-tst-audit2.c += -fno-builtin
|
||||
tst-audit2-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so
|
||||
|
||||
$(objpfx)tst-audit9: $(libdl)
|
|
@ -0,0 +1,102 @@
|
|||
#
|
||||
# Based on the following upstream commit:
|
||||
#
|
||||
# commit 6e6249d0b461b952d0f544792372663feb6d792a
|
||||
# Author: Roland McGrath <roland@hack.frob.com>
|
||||
# Date: Wed Oct 24 14:50:46 2012 -0700
|
||||
#
|
||||
# BZ#14743: Move clock_* symbols from librt to libc.
|
||||
#
|
||||
# We remove the clock* functions from librtkaio.so.1 and
|
||||
# use those provided in libc.so.6, matching librt.so.
|
||||
#
|
||||
--- glibc-2.21-63-gebf27d1.mod/rtkaio/clock-compat.c 1969-12-31 19:00:00.000000000 -0500
|
||||
+++ glibc-2.21-63-gebf27d1/rtkaio/clock-compat.c 2015-02-12 01:28:59.615026597 -0500
|
||||
@@ -0,0 +1,2 @@
|
||||
+#define librt librtkaio
|
||||
+#include <rt/clock-compat.c>
|
||||
diff -urN glibc-2.21-59-gd35273f.mod/rtkaio/kaio_clock_getcpuclockid.c glibc-2.21-59-gd35273f/rtkaio/kaio_clock_getcpuclockid.c
|
||||
--- glibc-2.21-59-gd35273f.mod/rtkaio/kaio_clock_getcpuclockid.c 2015-02-11 13:00:55.105400863 -0500
|
||||
+++ glibc-2.21-59-gd35273f/rtkaio/kaio_clock_getcpuclockid.c 1969-12-31 19:00:00.000000000 -0500
|
||||
@@ -1 +0,0 @@
|
||||
-#include <clock_getcpuclockid.c>
|
||||
diff -urN glibc-2.21-59-gd35273f.mod/rtkaio/kaio_clock_getres.c glibc-2.21-59-gd35273f/rtkaio/kaio_clock_getres.c
|
||||
--- glibc-2.21-59-gd35273f.mod/rtkaio/kaio_clock_getres.c 2015-02-11 13:00:55.105400863 -0500
|
||||
+++ glibc-2.21-59-gd35273f/rtkaio/kaio_clock_getres.c 1969-12-31 19:00:00.000000000 -0500
|
||||
@@ -1 +0,0 @@
|
||||
-#include <clock_getres.c>
|
||||
diff -urN glibc-2.21-59-gd35273f.mod/rtkaio/kaio_clock_gettime.c glibc-2.21-59-gd35273f/rtkaio/kaio_clock_gettime.c
|
||||
--- glibc-2.21-59-gd35273f.mod/rtkaio/kaio_clock_gettime.c 2015-02-11 13:00:55.109400738 -0500
|
||||
+++ glibc-2.21-59-gd35273f/rtkaio/kaio_clock_gettime.c 1969-12-31 19:00:00.000000000 -0500
|
||||
@@ -1 +0,0 @@
|
||||
-#include <clock_gettime.c>
|
||||
diff -urN glibc-2.21-59-gd35273f.mod/rtkaio/kaio_clock_nanosleep.c glibc-2.21-59-gd35273f/rtkaio/kaio_clock_nanosleep.c
|
||||
--- glibc-2.21-59-gd35273f.mod/rtkaio/kaio_clock_nanosleep.c 2015-02-11 13:00:55.115400552 -0500
|
||||
+++ glibc-2.21-59-gd35273f/rtkaio/kaio_clock_nanosleep.c 1969-12-31 19:00:00.000000000 -0500
|
||||
@@ -1 +0,0 @@
|
||||
-#include <clock_nanosleep.c>
|
||||
diff -urN glibc-2.21-59-gd35273f.mod/rtkaio/kaio_clock_settime.c glibc-2.21-59-gd35273f/rtkaio/kaio_clock_settime.c
|
||||
--- glibc-2.21-59-gd35273f.mod/rtkaio/kaio_clock_settime.c 2015-02-11 13:00:55.110400708 -0500
|
||||
+++ glibc-2.21-59-gd35273f/rtkaio/kaio_clock_settime.c 1969-12-31 19:00:00.000000000 -0500
|
||||
@@ -1 +0,0 @@
|
||||
-#include <clock_settime.c>
|
||||
diff -urN glibc-2.21-59-gd35273f.mod/rtkaio/kaio_get_clockfreq.c glibc-2.21-59-gd35273f/rtkaio/kaio_get_clockfreq.c
|
||||
--- glibc-2.21-59-gd35273f.mod/rtkaio/kaio_get_clockfreq.c 2015-02-11 13:00:55.118400459 -0500
|
||||
+++ glibc-2.21-59-gd35273f/rtkaio/kaio_get_clockfreq.c 1969-12-31 19:00:00.000000000 -0500
|
||||
@@ -1 +0,0 @@
|
||||
-#include <get_clockfreq.c>
|
||||
diff -urN glibc-2.21-59-gd35273f.mod/rtkaio/Makefile glibc-2.21-59-gd35273f/rtkaio/Makefile
|
||||
--- glibc-2.21-59-gd35273f.mod/rtkaio/Makefile 2015-02-11 13:00:55.107400801 -0500
|
||||
+++ glibc-2.21-59-gd35273f/rtkaio/Makefile 2015-02-11 22:46:46.930374298 -0500
|
||||
@@ -25,9 +25,6 @@
|
||||
aio_read64 aio_return aio_suspend aio_write \
|
||||
aio_write64 lio_listio lio_listio64 aio_sigqueue \
|
||||
aio_notify
|
||||
-clock-routines := get_clockfreq clock_getcpuclockid \
|
||||
- clock_getres clock_gettime clock_settime \
|
||||
- clock_nanosleep
|
||||
timer-routines := timer_create timer_delete timer_getoverr \
|
||||
timer_gettime timer_settime
|
||||
shm-routines := shm_open shm_unlink
|
||||
@@ -36,8 +33,9 @@
|
||||
mq_timedreceive
|
||||
|
||||
librtkaio-routines = $(patsubst %,k%,$(aio-routines)) \
|
||||
- $(patsubst %,kaio_%,$(clock-routines) $(timer-routines) \
|
||||
- $(shm-routines) $(mq-routines))
|
||||
+ $(patsubst %,kaio_%,$(timer-routines) \
|
||||
+ $(shm-routines) $(mq-routines)) \
|
||||
+ clock-compat
|
||||
|
||||
tests := tst-shm tst-clock tst-clock_nanosleep tst-timer tst-timer2 \
|
||||
tst-aio tst-aio64 tst-aio2 tst-aio3 tst-aio4 tst-aio5 tst-aio6 \
|
||||
@@ -64,7 +62,6 @@
|
||||
include $(..)Rules
|
||||
|
||||
CFLAGS-kaio_suspend.c = -fexceptions
|
||||
-CFLAGS-kaio_clock_nanosleep.c = -fexceptions -fasynchronous-unwind-tables
|
||||
CFLAGS-kaio_librt-cancellation.c = -fasynchronous-unwind-tables
|
||||
|
||||
LDFLAGS-rtkaio.so = -Wl,-soname=lib$(libprefix)rt.so$(librt.so-version) \
|
||||
@@ -88,9 +85,6 @@
|
||||
else
|
||||
$(addprefix $(objpfx),$(tests)): $(objpfx)librtkaio.a $(static-thread-library)
|
||||
endif
|
||||
-ifeq (yes,$(build-bounded))
|
||||
-$(tests:%=$(objpfx)%-bp): $(objpfx)librtkaio_b.a $(bounded-thread-library)
|
||||
-endif
|
||||
|
||||
tst-mqueue7-ARGS = -- $(built-program-file)
|
||||
|
||||
diff -urN glibc-2.21-59-gd35273f.mod/rtkaio/Versions glibc-2.21-59-gd35273f/rtkaio/Versions
|
||||
--- glibc-2.21-59-gd35273f.mod/rtkaio/Versions 2015-02-11 13:00:55.118400459 -0500
|
||||
+++ glibc-2.21-59-gd35273f/rtkaio/Versions 2015-02-11 22:36:11.974051389 -0500
|
||||
@@ -6,7 +6,7 @@
|
||||
aio_suspend64; aio_write; aio_write64; lio_listio; lio_listio64;
|
||||
}
|
||||
GLIBC_2.2 {
|
||||
- # c*
|
||||
+ # These have moved to libc and are still here only for compatibility.
|
||||
clock_getres; clock_gettime; clock_settime; clock_getcpuclockid;
|
||||
clock_nanosleep;
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# BZ #17949.
|
||||
#
|
||||
# commit 132a1328eccd20621b77f7810eebbeec0a1af187
|
||||
# Author: Evangelos Foutras <evangelos@foutrelis.com>
|
||||
# Date: Tue Feb 10 03:22:58 2015 +0000
|
||||
#
|
||||
# Fix __memcpy_chk on non-SSE2 CPUs
|
||||
#
|
||||
# In commit 8b4416d, the 1: jump label in __mempcpy_chk was accidentally
|
||||
# moved. This resulted in failures of mempcpy on CPU without SSE2.
|
||||
#
|
||||
diff --git a/sysdeps/i386/i686/multiarch/mempcpy_chk.S b/sysdeps/i386/i686/multiarch/mempcpy_chk.S
|
||||
index 207b648..b6fa202 100644
|
||||
--- a/sysdeps/i386/i686/multiarch/mempcpy_chk.S
|
||||
+++ b/sysdeps/i386/i686/multiarch/mempcpy_chk.S
|
||||
@@ -36,8 +36,8 @@ ENTRY(__mempcpy_chk)
|
||||
cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx)
|
||||
jne 1f
|
||||
call __init_cpu_features
|
||||
- leal __mempcpy_chk_ia32@GOTOFF(%ebx), %eax
|
||||
-1: testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx)
|
||||
+1: leal __mempcpy_chk_ia32@GOTOFF(%ebx), %eax
|
||||
+ testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx)
|
||||
jz 2f
|
||||
leal __mempcpy_chk_sse2_unaligned@GOTOFF(%ebx), %eax
|
||||
testl $bit_Fast_Unaligned_Load, FEATURE_OFFSET+index_Fast_Unaligned_Load+__cpu_features@GOTOFF(%ebx)
|
124
glibc.spec
124
glibc.spec
|
@ -1,6 +1,6 @@
|
|||
%define glibcsrcdir glibc-2.20-549-g86bba16
|
||||
%define glibcversion 2.20.90
|
||||
%define glibcrelease 20%{?dist}
|
||||
%define glibcsrcdir glibc-2.21
|
||||
%define glibcversion 2.21
|
||||
%define glibcrelease 13%{?dist}
|
||||
# Pre-release tarballs are pulled in from git using a command that is
|
||||
# effectively:
|
||||
#
|
||||
|
@ -9,7 +9,7 @@
|
|||
# gzip -9 $(git describe --match 'glibc-*').tar
|
||||
#
|
||||
# glibc_release_url is only defined when we have a release tarball.
|
||||
# % define glibc_release_url http://ftp.gnu.org/gnu/glibc/
|
||||
%define glibc_release_url http://ftp.gnu.org/gnu/glibc/
|
||||
##############################################################################
|
||||
# If run_glibc_tests is zero then tests are not run for the build.
|
||||
# You must always set run_glibc_tests to one for production builds.
|
||||
|
@ -206,14 +206,35 @@ Patch0052: %{name}-disable-rwlock-elision.patch
|
|||
# symlink to it.
|
||||
Patch0053: %{name}-cs-path.patch
|
||||
|
||||
# Temporary revert till I fix rtkaio build on i686.
|
||||
Patch0054: %{name}-revert-x86-vdso.patch
|
||||
# Remove the clock_* functions and use the ones in libc like librt does.
|
||||
Patch0054: %{name}-rtkaio-clock.patch
|
||||
|
||||
# Add C.UTF-8 locale into /usr/lib/locale/
|
||||
Patch0059: glibc-c-utf8-locale.patch
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Patches from upstream
|
||||
#
|
||||
##############################################################################
|
||||
# BZ #17949 - Fix __memcpy_chk on non-SSE2 CPUs.
|
||||
Patch1000: glibc-swbz17949.patch
|
||||
|
||||
#Unicode 7.0.0 update.
|
||||
Patch1001: glibc-rh1191059.patch
|
||||
|
||||
# BZ #18643 - Missing IPV6_* defines
|
||||
Patch1002: glibc-rh1241061.patch
|
||||
|
||||
Patch1003: glibc-rh1184168.patch
|
||||
|
||||
Patch1004: glibc-rh1276761-1.patch
|
||||
Patch1005: glibc-rh1276761-2.patch
|
||||
Patch1006: glibc-rh1276761-3.patch
|
||||
|
||||
Patch1007: glibc-rh1214152.patch
|
||||
|
||||
Patch1008: glibc-rh970866.patch
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
|
@ -246,6 +267,18 @@ Patch2031: %{name}-rh1070416.patch
|
|||
Patch2033: %{name}-aarch64-tls-fixes.patch
|
||||
Patch2034: %{name}-aarch64-workaround-nzcv-clobber-in-tlsdesc.patch
|
||||
|
||||
# Upstream BZ 19048
|
||||
Patch2035: %{name}-rh1276112.patch
|
||||
|
||||
# Upsteam BZ 18665
|
||||
Patch2107: glibc-CVE-2015-7547.patch
|
||||
|
||||
# Upstream BZ 19682
|
||||
Patch2108: glibc-rh1310168.patch
|
||||
|
||||
# Upstream BZ 19581
|
||||
Patch2109: glibc-rh1114591.patch
|
||||
|
||||
##############################################################################
|
||||
# End of glibc patches.
|
||||
##############################################################################
|
||||
|
@ -575,10 +608,24 @@ package or when debugging this package.
|
|||
%patch0047 -p1
|
||||
%patch2033 -p1
|
||||
%patch2034 -p1
|
||||
%patch2035 -p1
|
||||
%patch2107 -p1
|
||||
%patch2108 -p1
|
||||
%patch2109 -p1
|
||||
%patch0050 -p1
|
||||
%patch0052 -p1
|
||||
%patch0053 -p1
|
||||
%patch0054 -p1 -R
|
||||
%patch0054 -p1
|
||||
%patch1000 -p1
|
||||
%patch1001 -p1
|
||||
%patch1002 -p1
|
||||
%patch1003 -p1
|
||||
%patch1004 -p1
|
||||
%patch1005 -p1
|
||||
%patch1006 -p1
|
||||
%patch1007 -p1
|
||||
%patch1008 -p1
|
||||
%patch0059 -p1
|
||||
|
||||
##############################################################################
|
||||
# %%prep - Additional prep required...
|
||||
|
@ -986,7 +1033,9 @@ $olddir/build-%{target}/elf/ld.so \
|
|||
--library-path $olddir/build-%{target}/ \
|
||||
$olddir/build-%{target}/locale/localedef \
|
||||
--prefix ${RPM_BUILD_ROOT} --add-to-archive \
|
||||
*_*
|
||||
C.utf8 *_*
|
||||
# Removes all locales except C.utf8 which remains as fallback in
|
||||
# the event the user cleans the locale-archive using localedef.
|
||||
rm -rf *_*
|
||||
mv locale-archive{,.tmpl}
|
||||
popd
|
||||
|
@ -1583,7 +1632,7 @@ end
|
|||
if posix.stat("%{_prefix}/lib/locale/locale-archive.tmpl", "size") > 0 then
|
||||
pid = posix.fork()
|
||||
if pid == 0 then
|
||||
posix.exec("%{_prefix}/sbin/build-locale-archive")
|
||||
posix.exec("%{_prefix}/sbin/build-locale-archive", "--install-langs", rpm.expand("%%{_install_langs}"))
|
||||
elseif pid > 0 then
|
||||
posix.wait(pid)
|
||||
end
|
||||
|
@ -1594,7 +1643,7 @@ if posix.access("/etc/ld.so.cache") then
|
|||
if posix.stat("%{_prefix}/lib/locale/locale-archive.tmpl", "size") > 0 then
|
||||
pid = posix.fork()
|
||||
if pid == 0 then
|
||||
posix.exec("%{_prefix}/sbin/build-locale-archive")
|
||||
posix.exec("%{_prefix}/sbin/build-locale-archive", "--install-langs", rpm.expand("%%{_install_langs}"))
|
||||
elseif pid > 0 then
|
||||
posix.wait(pid)
|
||||
end
|
||||
|
@ -1686,7 +1735,7 @@ rm -f *.filelist*
|
|||
%attr(0644,root,root) %verify(not md5 size mtime) %ghost %config(missingok,noreplace) /etc/gai.conf
|
||||
%doc README NEWS INSTALL BUGS PROJECTS CONFORMANCE elf/rtld-debugger-interface.txt
|
||||
%{!?_licensedir:%global license %%doc}
|
||||
%license COPYING COPYING.LIB LICENSES
|
||||
%license COPYING COPYING.LIB LICENSES localedata/unicode-gen/unicode-license.txt
|
||||
%doc hesiod/README.hesiod
|
||||
|
||||
%if %{xenpackage}
|
||||
|
@ -1700,6 +1749,8 @@ rm -f *.filelist*
|
|||
%files -f common.filelist common
|
||||
%defattr(-,root,root)
|
||||
%dir %{_prefix}/lib/locale
|
||||
%dir %{_prefix}/lib/locale/C.utf8
|
||||
%{_prefix}/lib/locale/C.utf8/*
|
||||
%attr(0644,root,root) %verify(not md5 size mtime) %{_prefix}/lib/locale/locale-archive.tmpl
|
||||
%attr(0644,root,root) %verify(not md5 size mtime mode) %ghost %config(missingok,noreplace) %{_prefix}/lib/locale/locale-archive
|
||||
%dir %attr(755,root,root) /etc/default
|
||||
|
@ -1751,6 +1802,57 @@ rm -f *.filelist*
|
|||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed Mar 02 2016 Mike FABIAN <mfabian@redhat.com> - 2.21-13
|
||||
- Add the C.UTF-8 locale
|
||||
|
||||
* Fri Feb 19 2016 Florian Weimer <fweimer@redhat.com> - 2.21-12
|
||||
- Fix socket system call selection on s390x (#1310168).
|
||||
- Remove stray newline from Serbian locales (#1114591).
|
||||
|
||||
* Tue Feb 16 2016 Florian Weimer <fweimer@redhat.com> - 2.21-11
|
||||
- CVE-2015-7547: Stack-based buffer overflow in getaddrinfo (#1308943).
|
||||
|
||||
* Mon Feb 8 2016 Florian Weimer <fweimer@redhat.com> - 2.21-10
|
||||
- Make locale -a output ASCII-only (#1184168).
|
||||
- CVE-2015-8777: Apply additional pointer guard hardening. (#1276761)
|
||||
- CVE-2015-1781: glibc: buffer overflow in gethostbyname_r and
|
||||
related functions with misaligned buffer. (#1214152)
|
||||
- Avoid tst-audit2 failure due to GCC 5 optimization. (#970866)
|
||||
|
||||
* Wed Oct 28 2015 Florian Weimer <fweimer@redhat.com> - 2.21-9
|
||||
- Prevent malloc arena free list from becoming cyclic. (#1276112)
|
||||
|
||||
* Wed Sep 16 2015 Mike FABIAN <mfabian@redhat.com> - 2.22-8
|
||||
- build-locale-archive sometimes created empty archives (fixed by David Shea) (#1262040)
|
||||
|
||||
* Wed Jul 8 2015 Carlos O'Donell <carlos@redhat.com> - 2.21-7
|
||||
- Add missing IPV6 defines for Advanced API (RFC3542) (1) (#1241061).
|
||||
|
||||
* Tue Mar 24 2015 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.21-6
|
||||
- Support installing only those locales specified by the RPM macro
|
||||
%%_install_langs (#1204827).
|
||||
- Use rpm.expand in scripts to reduce set of required RPM features.
|
||||
|
||||
* Mon Feb 23 2015 Alexandre Oliva <aoliva@redhat.com> - 2.21-5
|
||||
- Update __STDC_ISO_10646__ following Unicode 7.0.0 update.
|
||||
|
||||
* Mon Feb 23 2015 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.21-4
|
||||
- Unicode 7.0.0 update (#1191059).
|
||||
- Add back x86 vDSO support.
|
||||
- Fix rtkaio build to reference clock_* functions from libc.
|
||||
- Fix missing clock_* IFUNCs in librtkaio.
|
||||
|
||||
* Tue Feb 17 2015 Carlos O'Donell <carlos@redhat.com> - 2.21-3
|
||||
- Change patch file to avoid rpm bug 1193603 and rebuild with new NVR
|
||||
(#1190454).
|
||||
|
||||
* Tue Feb 17 2015 Carlos O'Donell <carlos@redhat.com> - 2.21-2
|
||||
- Rebuild with new NVR.
|
||||
|
||||
* Wed Feb 11 2015 Carlos O'Donell <carlos@redhat.com> - 2.21-1
|
||||
- Fix __memcpy_chk on non-SSE2 CPUs (Upstream BZ #17949)
|
||||
- Rebase to upstream release 2.21 to provide ABI and API assurances.
|
||||
|
||||
* Wed Jan 21 2015 Siddhesh Poyarekar <siddhesh@redhat.com> - 2.20.90-20
|
||||
- Sync with upstream master.
|
||||
- Disable werror on s390x.
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#!/bin/bash
|
||||
# Patches are in the current directory.
|
||||
export QUILT_PATCHES=$PWD
|
||||
# Extract source file name from sources file,
|
||||
# and assume it's the same name as the directory.
|
||||
source=`cat sources | sed -e 's,^.* ,,g'`
|
||||
srcdir=${source%.tar.gz}
|
||||
if [ "$1" == "-f" ] && [ -d "$srcdir" ]; then
|
||||
echo Cleaning up $srcdir
|
||||
rm -rf $srcdir
|
||||
fi
|
||||
if [ -d "$srcdir" ]; then
|
||||
# Don't overwrite existing source directory.
|
||||
echo "ERROR: Source directory $srcdir already exists. Use -f to force cleanup step."
|
||||
exit 1
|
||||
fi
|
||||
tar zxvf $source
|
||||
echo "Entering $srcdir"
|
||||
pushd $srcdir
|
||||
# Apply all patches.
|
||||
quilt push -a
|
||||
popd
|
Loading…
Reference in New Issue