SHA256
1
0
forked from pool/glibc

Accepting request 293890 from home:Andreas_Schwab:Factory

- powerpc-software-sqrt.patch: Fix powerpc software sqrt (BZ #17964, BZ
  #17967)
- nss-separate-state-getXXent.patch: Separate internal state between
  getXXent and getXXbyYY NSS calls (bsc#918187, BZ #18007)
- static-tls-dtv-limit.patch: Fix DTV race, assert, DTV_SURPLUS Static TLS
  limit, and nptl_db garbage (bsc#919678, BZ #17090, BZ #17620, BZ #17621,
  BZ #17628)

OBS-URL: https://build.opensuse.org/request/show/293890
OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=398
This commit is contained in:
Andreas Schwab 2015-04-01 09:51:42 +00:00 committed by Git OBS Bridge
parent 680876d9c6
commit d6f647d047
9 changed files with 1545 additions and 12 deletions

View File

@ -1,3 +1,14 @@
-------------------------------------------------------------------
Mon Mar 30 09:04:49 UTC 2015 - schwab@suse.de
- powerpc-software-sqrt.patch: Fix powerpc software sqrt (BZ #17964, BZ
#17967)
- nss-separate-state-getXXent.patch: Separate internal state between
getXXent and getXXbyYY NSS calls (bsc#918187, BZ #18007)
- static-tls-dtv-limit.patch: Fix DTV race, assert, DTV_SURPLUS Static TLS
limit, and nptl_db garbage (bsc#919678, BZ #17090, BZ #17620, BZ #17621,
BZ #17628)
-------------------------------------------------------------------
Mon Mar 9 13:05:32 UTC 2015 - schwab@suse.de

View File

@ -235,8 +235,14 @@ Patch306: glibc-fix-double-loopback.diff
Patch1000: htm-tabort.patch
# PATCH-FIX-UPSTREAM Fix value of O_TMPFILE for architectures with non-default O_DIRECTORY (BZ #17912)
Patch1001: o-tmpfile.patch
# PATH-FIX-UPSTREAM Fix __memcpy_chk on non-SSE2 CPUs (BZ #17949)
# PATCH-FIX-UPSTREAM Fix __memcpy_chk on non-SSE2 CPUs (BZ #17949)
Patch1002: memcpy-chk-non-SSE2.patch
# PATCH-FIX-UPSTREAM Filter out PTHREAD_MUTEX_NO_ELISION_NP bit in pthread_mutexattr_gettype (BZ #15790)
Patch1003: pthread-mutexattr-gettype-kind.patch
# PATCH-FIX-UPSTREAM Fix powerpc software sqrt (BZ #17964, BZ #17967)
Patch1004: powerpc-software-sqrt.patch
# PATCH-FIX-UPSTREAM Fix DTV race, assert, DTV_SURPLUS Static TLS limit, and nptl_db garbage (bsc#919678, BZ #17090, BZ #17620, BZ #17621, BZ #17628)
Patch1005: static-tls-dtv-limit.patch
###
# Patches awaiting upstream approval
@ -251,10 +257,10 @@ Patch2003: abort-no-flush.patch
Patch2005: glibc-memset-nontemporal.diff
# PATCH-FIX-UPSTREAM Avoid redundant shift character in iconv output at block boundary (BZ #17197)
Patch2006: ibm93x-redundant-shift-si.patch
# PATCH-FIX-UPSTREAM Filter out PTHREAD_MUTEX_NO_ELISION_NP bit in pthread_mutexattr_gettype (BZ #15790)
Patch2007: pthread-mutexattr-gettype-kind.patch
# PATCH-FIX-UPSTREAM Rewrite handling of nameserver configuration in resolver
Patch2008: resolv-nameserver-handling.patch
Patch2007: resolv-nameserver-handling.patch
# PATCH-FIX-UPSTREAM Separate internal state between getXXent and getXXbyYY NSS calls (bsc#918187, BZ #18007)
Patch2008: nss-separate-state-getXXent.patch
# Non-glibc patches
# PATCH-FIX-OPENSUSE Remove debianisms from manpages
@ -458,6 +464,9 @@ rm nscd/s-stamp
%patch1000 -p1
%patch1001 -p1
%patch1002 -p1
%patch1003 -p1
%patch1004 -p1
%patch1005 -p1
%patch2000 -p1
%patch2002 -p1

View File

@ -1,3 +1,14 @@
-------------------------------------------------------------------
Mon Mar 30 09:04:49 UTC 2015 - schwab@suse.de
- powerpc-software-sqrt.patch: Fix powerpc software sqrt (BZ #17964, BZ
#17967)
- nss-separate-state-getXXent.patch: Separate internal state between
getXXent and getXXbyYY NSS calls (bsc#918187, BZ #18007)
- static-tls-dtv-limit.patch: Fix DTV race, assert, DTV_SURPLUS Static TLS
limit, and nptl_db garbage (bsc#919678, BZ #17090, BZ #17620, BZ #17621,
BZ #17628)
-------------------------------------------------------------------
Mon Mar 9 13:05:32 UTC 2015 - schwab@suse.de

View File

@ -234,8 +234,14 @@ Patch306: glibc-fix-double-loopback.diff
Patch1000: htm-tabort.patch
# PATCH-FIX-UPSTREAM Fix value of O_TMPFILE for architectures with non-default O_DIRECTORY (BZ #17912)
Patch1001: o-tmpfile.patch
# PATH-FIX-UPSTREAM Fix __memcpy_chk on non-SSE2 CPUs (BZ #17949)
# PATCH-FIX-UPSTREAM Fix __memcpy_chk on non-SSE2 CPUs (BZ #17949)
Patch1002: memcpy-chk-non-SSE2.patch
# PATCH-FIX-UPSTREAM Filter out PTHREAD_MUTEX_NO_ELISION_NP bit in pthread_mutexattr_gettype (BZ #15790)
Patch1003: pthread-mutexattr-gettype-kind.patch
# PATCH-FIX-UPSTREAM Fix powerpc software sqrt (BZ #17964, BZ #17967)
Patch1004: powerpc-software-sqrt.patch
# PATCH-FIX-UPSTREAM Fix DTV race, assert, DTV_SURPLUS Static TLS limit, and nptl_db garbage (bsc#919678, BZ #17090, BZ #17620, BZ #17621, BZ #17628)
Patch1005: static-tls-dtv-limit.patch
###
# Patches awaiting upstream approval
@ -250,10 +256,10 @@ Patch2003: abort-no-flush.patch
Patch2005: glibc-memset-nontemporal.diff
# PATCH-FIX-UPSTREAM Avoid redundant shift character in iconv output at block boundary (BZ #17197)
Patch2006: ibm93x-redundant-shift-si.patch
# PATCH-FIX-UPSTREAM Filter out PTHREAD_MUTEX_NO_ELISION_NP bit in pthread_mutexattr_gettype (BZ #15790)
Patch2007: pthread-mutexattr-gettype-kind.patch
# PATCH-FIX-UPSTREAM Rewrite handling of nameserver configuration in resolver
Patch2008: resolv-nameserver-handling.patch
Patch2007: resolv-nameserver-handling.patch
# PATCH-FIX-UPSTREAM Separate internal state between getXXent and getXXbyYY NSS calls (bsc#918187, BZ #18007)
Patch2008: nss-separate-state-getXXent.patch
# Non-glibc patches
# PATCH-FIX-OPENSUSE Remove debianisms from manpages
@ -458,6 +464,9 @@ rm nscd/s-stamp
%patch1000 -p1
%patch1001 -p1
%patch1002 -p1
%patch1003 -p1
%patch1004 -p1
%patch1005 -p1
%patch2000 -p1
%patch2002 -p1

View File

@ -1,3 +1,14 @@
-------------------------------------------------------------------
Mon Mar 30 09:04:49 UTC 2015 - schwab@suse.de
- powerpc-software-sqrt.patch: Fix powerpc software sqrt (BZ #17964, BZ
#17967)
- nss-separate-state-getXXent.patch: Separate internal state between
getXXent and getXXbyYY NSS calls (bsc#918187, BZ #18007)
- static-tls-dtv-limit.patch: Fix DTV race, assert, DTV_SURPLUS Static TLS
limit, and nptl_db garbage (bsc#919678, BZ #17090, BZ #17620, BZ #17621,
BZ #17628)
-------------------------------------------------------------------
Mon Mar 9 13:05:32 UTC 2015 - schwab@suse.de

View File

@ -235,8 +235,14 @@ Patch306: glibc-fix-double-loopback.diff
Patch1000: htm-tabort.patch
# PATCH-FIX-UPSTREAM Fix value of O_TMPFILE for architectures with non-default O_DIRECTORY (BZ #17912)
Patch1001: o-tmpfile.patch
# PATH-FIX-UPSTREAM Fix __memcpy_chk on non-SSE2 CPUs (BZ #17949)
# PATCH-FIX-UPSTREAM Fix __memcpy_chk on non-SSE2 CPUs (BZ #17949)
Patch1002: memcpy-chk-non-SSE2.patch
# PATCH-FIX-UPSTREAM Filter out PTHREAD_MUTEX_NO_ELISION_NP bit in pthread_mutexattr_gettype (BZ #15790)
Patch1003: pthread-mutexattr-gettype-kind.patch
# PATCH-FIX-UPSTREAM Fix powerpc software sqrt (BZ #17964, BZ #17967)
Patch1004: powerpc-software-sqrt.patch
# PATCH-FIX-UPSTREAM Fix DTV race, assert, DTV_SURPLUS Static TLS limit, and nptl_db garbage (bsc#919678, BZ #17090, BZ #17620, BZ #17621, BZ #17628)
Patch1005: static-tls-dtv-limit.patch
###
# Patches awaiting upstream approval
@ -251,10 +257,10 @@ Patch2003: abort-no-flush.patch
Patch2005: glibc-memset-nontemporal.diff
# PATCH-FIX-UPSTREAM Avoid redundant shift character in iconv output at block boundary (BZ #17197)
Patch2006: ibm93x-redundant-shift-si.patch
# PATCH-FIX-UPSTREAM Filter out PTHREAD_MUTEX_NO_ELISION_NP bit in pthread_mutexattr_gettype (BZ #15790)
Patch2007: pthread-mutexattr-gettype-kind.patch
# PATCH-FIX-UPSTREAM Rewrite handling of nameserver configuration in resolver
Patch2008: resolv-nameserver-handling.patch
Patch2007: resolv-nameserver-handling.patch
# PATCH-FIX-UPSTREAM Separate internal state between getXXent and getXXbyYY NSS calls (bsc#918187, BZ #18007)
Patch2008: nss-separate-state-getXXent.patch
# Non-glibc patches
# PATCH-FIX-OPENSUSE Remove debianisms from manpages
@ -458,6 +464,9 @@ rm nscd/s-stamp
%patch1000 -p1
%patch1001 -p1
%patch1002 -p1
%patch1003 -p1
%patch1004 -p1
%patch1005 -p1
%patch2000 -p1
%patch2002 -p1

View File

@ -0,0 +1,715 @@
[BZ #18007]
* nis/nss_compat/compat-grp.c (internal_endgrent): Add parameter
needent, call nss_endgrent only if non-zero.
(_nss_compat_endgrent): Pass non-zero.
(_nss_compat_getgrnam_r, _nss_compat_getgrgid_r): Pass zero.
* nis/nss_compat/compat-pwd.c (internal_endpwent): Add parameter
needent, call nss_endpwent only if non-zero.
(_nss_compat_endpwent): Pass non-zero.
(_nss_compat_getpwnam_r, _nss_compat_getpwuid_r): Pass zero.
* nis/nss_compat/compat-spwd.c (internal_setspent): Add parameter
needent, call nss_setspent only if non-zero.
(_nss_compat_setspent): Pass non-zero.
(internal_endspent): Add parameter needent, call nss_endspent only
if non-zero.
(_nss_compat_endspent, _nss_compat_getspent_r): Pass non-zero.
(_nss_compat_getspnam_r): Pass zero.
* nss/nss_files/files-XXX.c (position, last_use, keep_stream):
Remove. All uses removed.
(internal_setent): Remove parameter stayopen, add parameter
stream. Use it instead of global variable.
(CONCAT(_nss_files_set,ENTNAME)): Pass global stream.
(internal_endent, internal_getent): Add parameter stream. Use it
instead of global variable.
(CONCAT(_nss_files_end,ENTNAME))
(CONCAT(_nss_files_get,ENTNAME_r)): Pass global stream.
(_nss_files_get##name##_r): Pass local stream. Remove locking.
* nss/nss_files/files-alias.c (position, last_use): Remove. All
uses removed.
(internal_setent, internal_endent): Add parameter stream. Use it
instead of global variable.
(_nss_files_setaliasent, _nss_files_endaliasent): Pass global
stream.
(get_next_alias): Add parameter stream.
(_nss_files_getaliasent_r): Pass global stream.
(_nss_files_getaliasbyname_r): Pass local stream. Remove locking.
* nss/nss_files/files-hosts.c (_nss_files_gethostbyname3_r)
(_nss_files_gethostbyname4_r): Pass local stream to
internal_setent, internal_getent and internal_endent. Remove
locking.
Index: glibc-2.21/nis/nss_compat/compat-grp.c
===================================================================
--- glibc-2.21.orig/nis/nss_compat/compat-grp.c
+++ glibc-2.21/nis/nss_compat/compat-grp.c
@@ -192,9 +192,9 @@ _nss_compat_setgrent (int stayopen)
static enum nss_status
-internal_endgrent (ent_t *ent)
+internal_endgrent (ent_t *ent, int needent)
{
- if (nss_endgrent)
+ if (needent && nss_endgrent)
nss_endgrent ();
if (ent->stream != NULL)
@@ -222,7 +222,7 @@ _nss_compat_endgrent (void)
__libc_lock_lock (lock);
- result = internal_endgrent (&ext_ent);
+ result = internal_endgrent (&ext_ent, 1);
__libc_lock_unlock (lock);
@@ -532,7 +532,7 @@ _nss_compat_getgrnam_r (const char *name
if (result == NSS_STATUS_SUCCESS)
result = internal_getgrnam_r (name, grp, &ent, buffer, buflen, errnop);
- internal_endgrent (&ent);
+ internal_endgrent (&ent, 0);
return result;
}
@@ -661,7 +661,7 @@ _nss_compat_getgrgid_r (gid_t gid, struc
if (result == NSS_STATUS_SUCCESS)
result = internal_getgrgid_r (gid, grp, &ent, buffer, buflen, errnop);
- internal_endgrent (&ent);
+ internal_endgrent (&ent, 0);
return result;
}
Index: glibc-2.21/nis/nss_compat/compat-pwd.c
===================================================================
--- glibc-2.21.orig/nis/nss_compat/compat-pwd.c
+++ glibc-2.21/nis/nss_compat/compat-pwd.c
@@ -309,9 +309,9 @@ _nss_compat_setpwent (int stayopen)
static enum nss_status
-internal_endpwent (ent_t *ent)
+internal_endpwent (ent_t *ent, int needent)
{
- if (nss_endpwent)
+ if (needent && nss_endpwent)
nss_endpwent ();
if (ent->stream != NULL)
@@ -346,7 +346,7 @@ _nss_compat_endpwent (void)
__libc_lock_lock (lock);
- result = internal_endpwent (&ext_ent);
+ result = internal_endpwent (&ext_ent, 1);
__libc_lock_unlock (lock);
@@ -871,7 +871,7 @@ _nss_compat_getpwnam_r (const char *name
if (result == NSS_STATUS_SUCCESS)
result = internal_getpwnam_r (name, pwd, &ent, buffer, buflen, errnop);
- internal_endpwent (&ent);
+ internal_endpwent (&ent, 0);
return result;
}
@@ -1110,7 +1110,7 @@ _nss_compat_getpwuid_r (uid_t uid, struc
if (result == NSS_STATUS_SUCCESS)
result = internal_getpwuid_r (uid, pwd, &ent, buffer, buflen, errnop);
- internal_endpwent (&ent);
+ internal_endpwent (&ent, 0);
return result;
}
Index: glibc-2.21/nis/nss_compat/compat-spwd.c
===================================================================
--- glibc-2.21.orig/nis/nss_compat/compat-spwd.c
+++ glibc-2.21/nis/nss_compat/compat-spwd.c
@@ -169,7 +169,7 @@ copy_spwd_changes (struct spwd *dest, st
}
static enum nss_status
-internal_setspent (ent_t *ent, int stayopen)
+internal_setspent (ent_t *ent, int stayopen, int needent)
{
enum nss_status status = NSS_STATUS_SUCCESS;
@@ -239,7 +239,7 @@ internal_setspent (ent_t *ent, int stayo
give_spwd_free (&ent->pwd);
- if (status == NSS_STATUS_SUCCESS && nss_setspent)
+ if (needent && status == NSS_STATUS_SUCCESS && nss_setspent)
ent->setent_status = nss_setspent (stayopen);
return status;
@@ -256,7 +256,7 @@ _nss_compat_setspent (int stayopen)
if (ni == NULL)
init_nss_interface ();
- result = internal_setspent (&ext_ent, stayopen);
+ result = internal_setspent (&ext_ent, stayopen, 1);
__libc_lock_unlock (lock);
@@ -265,9 +265,9 @@ _nss_compat_setspent (int stayopen)
static enum nss_status
-internal_endspent (ent_t *ent)
+internal_endspent (ent_t *ent, int needent)
{
- if (nss_endspent)
+ if (needent && nss_endspent)
nss_endspent ();
if (ent->stream != NULL)
@@ -303,7 +303,7 @@ _nss_compat_endspent (void)
__libc_lock_lock (lock);
- result = internal_endspent (&ext_ent);
+ result = internal_endspent (&ext_ent, 1);
__libc_lock_unlock (lock);
@@ -658,7 +658,7 @@ _nss_compat_getspent_r (struct spwd *pwd
init_nss_interface ();
if (ext_ent.stream == NULL)
- result = internal_setspent (&ext_ent, 1);
+ result = internal_setspent (&ext_ent, 1, 1);
if (result == NSS_STATUS_SUCCESS)
result = internal_getspent_r (pwd, &ext_ent, buffer, buflen, errnop);
@@ -830,12 +830,12 @@ _nss_compat_getspnam_r (const char *name
__libc_lock_unlock (lock);
- result = internal_setspent (&ent, 0);
+ result = internal_setspent (&ent, 0, 0);
if (result == NSS_STATUS_SUCCESS)
result = internal_getspnam_r (name, pwd, &ent, buffer, buflen, errnop);
- internal_endspent (&ent);
+ internal_endspent (&ent, 0);
return result;
}
Index: glibc-2.21/nss/nss_files/files-XXX.c
===================================================================
--- glibc-2.21.orig/nss/nss_files/files-XXX.c
+++ glibc-2.21/nss/nss_files/files-XXX.c
@@ -63,21 +63,18 @@ __libc_lock_define_initialized (static,
/* Maintenance of the shared stream open on the database file. */
static FILE *stream;
-static fpos_t position;
-static enum { nouse, getent, getby } last_use;
-static int keep_stream;
/* Open database file if not already opened. */
static enum nss_status
-internal_setent (int stayopen)
+internal_setent (FILE **stream)
{
enum nss_status status = NSS_STATUS_SUCCESS;
- if (stream == NULL)
+ if (*stream == NULL)
{
- stream = fopen (DATAFILE, "rce");
+ *stream = fopen (DATAFILE, "rce");
- if (stream == NULL)
+ if (*stream == NULL)
status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
else
{
@@ -90,7 +87,7 @@ internal_setent (int stayopen)
int result;
int flags;
- result = flags = fcntl (fileno (stream), F_GETFD, 0);
+ result = flags = fcntl (fileno (*stream), F_GETFD, 0);
if (result >= 0)
{
# ifdef O_CLOEXEC
@@ -100,15 +97,15 @@ internal_setent (int stayopen)
# endif
{
flags |= FD_CLOEXEC;
- result = fcntl (fileno (stream), F_SETFD, flags);
+ result = fcntl (fileno (*stream), F_SETFD, flags);
}
}
if (result < 0)
{
/* Something went wrong. Close the stream and return a
failure. */
- fclose (stream);
- stream = NULL;
+ fclose (*stream);
+ *stream = NULL;
status = NSS_STATUS_UNAVAIL;
}
}
@@ -116,11 +113,7 @@ internal_setent (int stayopen)
}
}
else
- rewind (stream);
-
- /* Remember STAYOPEN flag. */
- if (stream != NULL)
- keep_stream |= stayopen;
+ rewind (*stream);
return status;
}
@@ -134,16 +127,7 @@ CONCAT(_nss_files_set,ENTNAME) (int stay
__libc_lock_lock (lock);
- status = internal_setent (stayopen);
-
- if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
- {
- fclose (stream);
- stream = NULL;
- status = NSS_STATUS_UNAVAIL;
- }
-
- last_use = getent;
+ status = internal_setent (&stream);
__libc_lock_unlock (lock);
@@ -153,12 +137,12 @@ CONCAT(_nss_files_set,ENTNAME) (int stay
/* Close the database file. */
static void
-internal_endent (void)
+internal_endent (FILE **stream)
{
- if (stream != NULL)
+ if (*stream != NULL)
{
- fclose (stream);
- stream = NULL;
+ fclose (*stream);
+ *stream = NULL;
}
}
@@ -169,10 +153,7 @@ CONCAT(_nss_files_end,ENTNAME) (void)
{
__libc_lock_lock (lock);
- internal_endent ();
-
- /* Reset STAYOPEN flag. */
- keep_stream = 0;
+ internal_endent (&stream);
__libc_lock_unlock (lock);
@@ -227,7 +208,7 @@ get_contents (char *linebuf, size_t len,
/* Parsing the database file into `struct STRUCTURE' data structures. */
static enum nss_status
-internal_getent (struct STRUCTURE *result,
+internal_getent (FILE *stream, struct STRUCTURE *result,
char *buffer, size_t buflen, int *errnop H_ERRNO_PROTO
EXTRA_ARGS_DECL)
{
@@ -300,45 +281,14 @@ CONCAT(_nss_files_get,ENTNAME_r) (struct
{
int save_errno = errno;
- status = internal_setent (0);
+ status = internal_setent (&stream);
__set_errno (save_errno);
-
- if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
- {
- fclose (stream);
- stream = NULL;
- status = NSS_STATUS_UNAVAIL;
- }
}
if (status == NSS_STATUS_SUCCESS)
- {
- /* If the last use was not by the getent function we need the
- position the stream. */
- if (last_use != getent)
- {
- if (fsetpos (stream, &position) < 0)
- status = NSS_STATUS_UNAVAIL;
- else
- last_use = getent;
- }
-
- if (status == NSS_STATUS_SUCCESS)
- {
- status = internal_getent (result, buffer, buflen, errnop
- H_ERRNO_ARG EXTRA_ARGS_VALUE);
-
- /* Remember this position if we were successful. If the
- operation failed we give the user a chance to repeat the
- operation (perhaps the buffer was too small). */
- if (status == NSS_STATUS_SUCCESS)
- fgetpos (stream, &position);
- else
- /* We must make sure we reposition the stream the next call. */
- last_use = nouse;
- }
- }
+ status = internal_getent (stream, result, buffer, buflen, errnop
+ H_ERRNO_ARG EXTRA_ARGS_VALUE);
__libc_lock_unlock (lock);
@@ -364,27 +314,20 @@ _nss_files_get##name##_r (proto,
size_t buflen, int *errnop H_ERRNO_PROTO) \
{ \
enum nss_status status; \
+ FILE *stream = NULL; \
\
- __libc_lock_lock (lock); \
- \
- /* Reset file pointer to beginning or open file. */ \
- status = internal_setent (keep_stream); \
+ /* Open file. */ \
+ status = internal_setent (&stream); \
\
if (status == NSS_STATUS_SUCCESS) \
{ \
- /* Tell getent function that we have repositioned the file pointer. */ \
- last_use = getby; \
- \
- while ((status = internal_getent (result, buffer, buflen, errnop \
+ while ((status = internal_getent (stream, result, buffer, buflen, errnop \
H_ERRNO_ARG EXTRA_ARGS_VALUE)) \
== NSS_STATUS_SUCCESS) \
{ break_if_match } \
\
- if (! keep_stream) \
- internal_endent (); \
+ internal_endent (&stream); \
} \
\
- __libc_lock_unlock (lock); \
- \
return status; \
}
Index: glibc-2.21/nss/nss_files/files-alias.c
===================================================================
--- glibc-2.21.orig/nss/nss_files/files-alias.c
+++ glibc-2.21/nss/nss_files/files-alias.c
@@ -36,20 +36,18 @@ __libc_lock_define_initialized (static,
/* Maintenance of the shared stream open on the database file. */
static FILE *stream;
-static fpos_t position;
-static enum { nouse, getent, getby } last_use;
static enum nss_status
-internal_setent (void)
+internal_setent (FILE **stream)
{
enum nss_status status = NSS_STATUS_SUCCESS;
- if (stream == NULL)
+ if (*stream == NULL)
{
- stream = fopen ("/etc/aliases", "rce");
+ *stream = fopen ("/etc/aliases", "rce");
- if (stream == NULL)
+ if (*stream == NULL)
status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
else
{
@@ -62,7 +60,7 @@ internal_setent (void)
int result;
int flags;
- result = flags = fcntl (fileno (stream), F_GETFD, 0);
+ result = flags = fcntl (fileno (*stream), F_GETFD, 0);
if (result >= 0)
{
# ifdef O_CLOEXEC
@@ -72,14 +70,14 @@ internal_setent (void)
# endif
{
flags |= FD_CLOEXEC;
- result = fcntl (fileno (stream), F_SETFD, flags);
+ result = fcntl (fileno (*stream), F_SETFD, flags);
}
}
if (result < 0)
{
/* Something went wrong. Close the stream and return a
failure. */
- fclose (stream);
+ fclose (*stream);
stream = NULL;
status = NSS_STATUS_UNAVAIL;
}
@@ -88,7 +86,7 @@ internal_setent (void)
}
}
else
- rewind (stream);
+ rewind (*stream);
return status;
}
@@ -102,16 +100,7 @@ _nss_files_setaliasent (void)
__libc_lock_lock (lock);
- status = internal_setent ();
-
- if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
- {
- fclose (stream);
- stream = NULL;
- status = NSS_STATUS_UNAVAIL;
- }
-
- last_use = getent;
+ status = internal_setent (&stream);
__libc_lock_unlock (lock);
@@ -121,12 +110,12 @@ _nss_files_setaliasent (void)
/* Close the database file. */
static void
-internal_endent (void)
+internal_endent (FILE **stream)
{
- if (stream != NULL)
+ if (*stream != NULL)
{
- fclose (stream);
- stream = NULL;
+ fclose (*stream);
+ *stream = NULL;
}
}
@@ -137,7 +126,7 @@ _nss_files_endaliasent (void)
{
__libc_lock_lock (lock);
- internal_endent ();
+ internal_endent (&stream);
__libc_lock_unlock (lock);
@@ -146,7 +135,7 @@ _nss_files_endaliasent (void)
/* Parsing the database file into `struct aliasent' data structures. */
static enum nss_status
-get_next_alias (const char *match, struct aliasent *result,
+get_next_alias (FILE *stream, const char *match, struct aliasent *result,
char *buffer, size_t buflen, int *errnop)
{
enum nss_status status = NSS_STATUS_NOTFOUND;
@@ -397,35 +386,16 @@ _nss_files_getaliasent_r (struct aliasen
/* Be prepared that the set*ent function was not called before. */
if (stream == NULL)
- status = internal_setent ();
+ status = internal_setent (&stream);
if (status == NSS_STATUS_SUCCESS)
{
- /* If the last use was not by the getent function we need the
- position the stream. */
- if (last_use != getent)
- {
- if (fsetpos (stream, &position) < 0)
- status = NSS_STATUS_UNAVAIL;
- else
- last_use = getent;
- }
-
- if (status == NSS_STATUS_SUCCESS)
- {
- result->alias_local = 1;
+ result->alias_local = 1;
- /* Read lines until we get a definite result. */
- do
- status = get_next_alias (NULL, result, buffer, buflen, errnop);
- while (status == NSS_STATUS_RETURN);
-
- /* If we successfully read an entry remember this position. */
- if (status == NSS_STATUS_SUCCESS)
- fgetpos (stream, &position);
- else
- last_use = nouse;
- }
+ /* Read lines until we get a definite result. */
+ do
+ status = get_next_alias (stream, NULL, result, buffer, buflen, errnop);
+ while (status == NSS_STATUS_RETURN);
}
__libc_lock_unlock (lock);
@@ -440,6 +410,7 @@ _nss_files_getaliasbyname_r (const char
{
/* Return next entry in host file. */
enum nss_status status = NSS_STATUS_SUCCESS;
+ FILE *stream = NULL;
if (name == NULL)
{
@@ -447,11 +418,8 @@ _nss_files_getaliasbyname_r (const char
return NSS_STATUS_UNAVAIL;
}
- __libc_lock_lock (lock);
-
- /* Open the stream or rest it. */
- status = internal_setent ();
- last_use = getby;
+ /* Open the stream. */
+ status = internal_setent (&stream);
if (status == NSS_STATUS_SUCCESS)
{
@@ -459,13 +427,11 @@ _nss_files_getaliasbyname_r (const char
/* Read lines until we get a definite result. */
do
- status = get_next_alias (name, result, buffer, buflen, errnop);
+ status = get_next_alias (stream, name, result, buffer, buflen, errnop);
while (status == NSS_STATUS_RETURN);
}
- internal_endent ();
-
- __libc_lock_unlock (lock);
+ internal_endent (&stream);
return status;
}
Index: glibc-2.21/nss/nss_files/files-hosts.c
===================================================================
--- glibc-2.21.orig/nss/nss_files/files-hosts.c
+++ glibc-2.21/nss/nss_files/files-hosts.c
@@ -115,14 +115,13 @@ _nss_files_gethostbyname3_r (const char
char *buffer, size_t buflen, int *errnop,
int *herrnop, int32_t *ttlp, char **canonp)
{
+ FILE *stream = NULL;
uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct hostent_data);
buffer += pad;
buflen = buflen > pad ? buflen - pad : 0;
- __libc_lock_lock (lock);
-
- /* Reset file pointer to beginning or open file. */
- enum nss_status status = internal_setent (keep_stream);
+ /* Open file. */
+ enum nss_status status = internal_setent (&stream);
if (status == NSS_STATUS_SUCCESS)
{
@@ -130,10 +129,7 @@ _nss_files_gethostbyname3_r (const char
addresses to IPv6 addresses really the right thing to do? */
int flags = ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0);
- /* Tell getent function that we have repositioned the file pointer. */
- last_use = getby;
-
- while ((status = internal_getent (result, buffer, buflen, errnop,
+ while ((status = internal_getent (stream, result, buffer, buflen, errnop,
herrnop, af, flags))
== NSS_STATUS_SUCCESS)
{
@@ -160,7 +156,7 @@ _nss_files_gethostbyname3_r (const char
bufferend = (char *) &result->h_aliases[naliases + 1];
again:
- while ((status = internal_getent (&tmp_result_buf, tmp_buffer,
+ while ((status = internal_getent (stream, &tmp_result_buf, tmp_buffer,
tmp_buflen, errnop, herrnop, af,
flags))
== NSS_STATUS_SUCCESS)
@@ -336,15 +332,12 @@ _nss_files_gethostbyname3_r (const char
free (tmp_buffer);
}
- if (! keep_stream)
- internal_endent ();
+ internal_endent (&stream);
}
if (canonp && status == NSS_STATUS_SUCCESS)
*canonp = result->h_name;
- __libc_lock_unlock (lock);
-
return status;
}
@@ -373,16 +366,13 @@ _nss_files_gethostbyname4_r (const char
char *buffer, size_t buflen, int *errnop,
int *herrnop, int32_t *ttlp)
{
- __libc_lock_lock (lock);
+ FILE *stream = NULL;
- /* Reset file pointer to beginning or open file. */
- enum nss_status status = internal_setent (keep_stream);
+ /* Open file. */
+ enum nss_status status = internal_setent (&stream);
if (status == NSS_STATUS_SUCCESS)
{
- /* Tell getent function that we have repositioned the file pointer. */
- last_use = getby;
-
bool any = false;
bool got_canon = false;
while (1)
@@ -394,7 +384,7 @@ _nss_files_gethostbyname4_r (const char
buflen = buflen > pad ? buflen - pad : 0;
struct hostent result;
- status = internal_getent (&result, buffer, buflen, errnop,
+ status = internal_getent (stream, &result, buffer, buflen, errnop,
herrnop, AF_UNSPEC, 0);
if (status != NSS_STATUS_SUCCESS)
break;
@@ -470,8 +460,7 @@ _nss_files_gethostbyname4_r (const char
status = NSS_STATUS_SUCCESS;
}
- if (! keep_stream)
- internal_endent ();
+ internal_endent (&stream);
}
else if (status == NSS_STATUS_TRYAGAIN)
{
@@ -484,7 +473,5 @@ _nss_files_gethostbyname4_r (const char
*herrnop = NO_DATA;
}
- __libc_lock_unlock (lock);
-
return status;
}

117
powerpc-software-sqrt.patch Normal file
View File

@ -0,0 +1,117 @@
2015-02-13 Joseph Myers <joseph@codesourcery.com>
[BZ #17967]
* sysdeps/powerpc/fpu/e_sqrtf.c (__slow_ieee754_sqrtf): Use
__builtin_fmaf instead of relying on contraction of a * b + c.
2015-02-12 Joseph Myers <joseph@codesourcery.com>
[BZ #17964]
* sysdeps/powerpc/fpu/e_sqrt.c (__slow_ieee754_sqrt): Use
__builtin_fma instead of relying on contraction of a * b + c.
Index: glibc-2.21/sysdeps/powerpc/fpu/e_sqrt.c
===================================================================
--- glibc-2.21.orig/sysdeps/powerpc/fpu/e_sqrt.c
+++ glibc-2.21/sysdeps/powerpc/fpu/e_sqrt.c
@@ -99,38 +99,41 @@ __slow_ieee754_sqrt (double x)
/* Here we have three Newton-Raphson iterations each of a
division and a square root and the remainder of the
argument reduction, all interleaved. */
- sd = -(sg * sg - sx);
+ sd = -__builtin_fma (sg, sg, -sx);
fsgi = (xi0 + 0x40000000) >> 1 & 0x7ff00000;
sy2 = sy + sy;
- sg = sy * sd + sg; /* 16-bit approximation to sqrt(sx). */
+ sg = __builtin_fma (sy, sd, sg); /* 16-bit approximation to
+ sqrt(sx). */
/* schedule the INSERT_WORDS (fsg, fsgi, 0) to get separation
between the store and the load. */
INSERT_WORDS (fsg, fsgi, 0);
iw_u.parts.msw = fsgi;
iw_u.parts.lsw = (0);
- e = -(sy * sg - almost_half);
- sd = -(sg * sg - sx);
+ e = -__builtin_fma (sy, sg, -almost_half);
+ sd = -__builtin_fma (sg, sg, -sx);
if ((xi0 & 0x7ff00000) == 0)
goto denorm;
- sy = sy + e * sy2;
- sg = sg + sy * sd; /* 32-bit approximation to sqrt(sx). */
+ sy = __builtin_fma (e, sy2, sy);
+ sg = __builtin_fma (sy, sd, sg); /* 32-bit approximation to
+ sqrt(sx). */
sy2 = sy + sy;
/* complete the INSERT_WORDS (fsg, fsgi, 0) operation. */
fsg = iw_u.value;
- e = -(sy * sg - almost_half);
- sd = -(sg * sg - sx);
- sy = sy + e * sy2;
+ e = -__builtin_fma (sy, sg, -almost_half);
+ sd = -__builtin_fma (sg, sg, -sx);
+ sy = __builtin_fma (e, sy2, sy);
shx = sx * fsg;
- sg = sg + sy * sd; /* 64-bit approximation to sqrt(sx),
- but perhaps rounded incorrectly. */
+ sg = __builtin_fma (sy, sd, sg); /* 64-bit approximation to
+ sqrt(sx), but perhaps
+ rounded incorrectly. */
sy2 = sy + sy;
g = sg * fsg;
- e = -(sy * sg - almost_half);
- d = -(g * sg - shx);
- sy = sy + e * sy2;
+ e = -__builtin_fma (sy, sg, -almost_half);
+ d = -__builtin_fma (g, sg, -shx);
+ sy = __builtin_fma (e, sy2, sy);
fesetenv_register (fe);
- return g + sy * d;
+ return __builtin_fma (sy, d, g);
denorm:
/* For denormalised numbers, we normalise, calculate the
square root, and return an adjusted result. */
Index: glibc-2.21/sysdeps/powerpc/fpu/e_sqrtf.c
===================================================================
--- glibc-2.21.orig/sysdeps/powerpc/fpu/e_sqrtf.c
+++ glibc-2.21/sysdeps/powerpc/fpu/e_sqrtf.c
@@ -87,26 +87,28 @@ __slow_ieee754_sqrtf (float x)
/* Here we have three Newton-Raphson iterations each of a
division and a square root and the remainder of the
argument reduction, all interleaved. */
- sd = -(sg * sg - sx);
+ sd = -__builtin_fmaf (sg, sg, -sx);
fsgi = (xi + 0x40000000) >> 1 & 0x7f800000;
sy2 = sy + sy;
- sg = sy * sd + sg; /* 16-bit approximation to sqrt(sx). */
- e = -(sy * sg - almost_half);
+ sg = __builtin_fmaf (sy, sd, sg); /* 16-bit approximation to
+ sqrt(sx). */
+ e = -__builtin_fmaf (sy, sg, -almost_half);
SET_FLOAT_WORD (fsg, fsgi);
- sd = -(sg * sg - sx);
- sy = sy + e * sy2;
+ sd = -__builtin_fmaf (sg, sg, -sx);
+ sy = __builtin_fmaf (e, sy2, sy);
if ((xi & 0x7f800000) == 0)
goto denorm;
shx = sx * fsg;
- sg = sg + sy * sd; /* 32-bit approximation to sqrt(sx),
- but perhaps rounded incorrectly. */
+ sg = __builtin_fmaf (sy, sd, sg); /* 32-bit approximation to
+ sqrt(sx), but perhaps
+ rounded incorrectly. */
sy2 = sy + sy;
g = sg * fsg;
- e = -(sy * sg - almost_half);
- d = -(g * sg - shx);
- sy = sy + e * sy2;
+ e = -__builtin_fmaf (sy, sg, -almost_half);
+ d = -__builtin_fmaf (g, sg, -shx);
+ sy = __builtin_fmaf (e, sy2, sy);
fesetenv_register (fe);
- return g + sy * d;
+ return __builtin_fmaf (sy, d, g);
denorm:
/* For denormalised numbers, we normalise, calculate the
square root, and return an adjusted result. */

641
static-tls-dtv-limit.patch Normal file
View File

@ -0,0 +1,641 @@
2015-03-17 Alexandre Oliva <aoliva@redhat.com>
[BZ #17090]
[BZ #17620]
[BZ #17621]
[BZ #17628]
* NEWS: Update.
* elf/dl-tls.c (_dl_update_slotinfo): Clean up outdated DTV
entries with Static TLS too. Skip entries past the end of the
allocated DTV, from Alan Modra.
(tls_get_addr_tail): Update to glibc_likely/unlikely. Move
Static TLS DTV entry set up from...
(_dl_allocate_tls_init): ... here (fix modid assertion), ...
* elf/dl-reloc.c (_dl_nothread_init_static_tls): ... here...
* nptl/allocatestack.c (init_one_static_tls): ... and here...
* elf/dlopen.c (dl_open_worker): Drop l_tls_modid upper bound
for Static TLS.
* elf/tlsdeschtab.h (map_generation): Return size_t. Check
that the slot we find is associated with the given map before
using its generation count.
* nptl_db/db_info.c: Include ldsodefs.h.
(rtld_global, dtv_slotinfo_list, dtv_slotinfo): New typedefs.
* nptl_db/structs.def (DB_RTLD_VARIABLE): New macro.
(DB_MAIN_VARIABLE, DB_RTLD_GLOBAL_FIELD): Likewise.
(link_map::l_tls_offset): New struct field.
(dtv_t::counter): Likewise.
(rtld_global): New struct.
(_rtld_global): New rtld variable.
(dl_tls_dtv_slotinfo_list): New rtld global field.
(dtv_slotinfo_list): New struct.
(dtv_slotinfo): Likewise.
* nptl_db/td_symbol_list.c: Drop gnu/lib-names.h include.
(td_lookup): Rename to...
(td_mod_lookup): ... this. Use new mod parameter instead of
LIBPTHREAD_SO.
* nptl_db/td_thr_tlsbase.c: Include link.h.
(dtv_slotinfo_list, dtv_slotinfo): New functions.
(td_thr_tlsbase): Check DTV generation. Compute Static TLS
addresses even if the DTV is out of date or missing them.
* nptl_db/fetch-value.c (_td_locate_field): Do not refuse to
index zero-length arrays.
* nptl_db/thread_dbP.h: Include gnu/lib-names.h.
(td_lookup): Make it a macro implemented in terms of...
(td_mod_lookup): ... this declaration.
* nptl_db/db-symbols.awk (DB_RTLD_VARIABLE): Override.
(DB_MAIN_VARIABLE): Likewise.
Index: glibc-2.21/elf/dl-open.c
===================================================================
--- glibc-2.21.orig/elf/dl-open.c
+++ glibc-2.21/elf/dl-open.c
@@ -533,17 +533,7 @@ TLS generation counter wrapped! Please
&& imap->l_tls_blocksize > 0)
{
/* For static TLS we have to allocate the memory here and
- now. This includes allocating memory in the DTV. But we
- cannot change any DTV other than our own. So, if we
- cannot guarantee that there is room in the DTV we don't
- even try it and fail the load.
-
- XXX We could track the minimum DTV slots allocated in
- all threads. */
- if (! RTLD_SINGLE_THREAD_P && imap->l_tls_modid > DTV_SURPLUS)
- _dl_signal_error (0, "dlopen", NULL, N_("\
-cannot load any more object with static TLS"));
-
+ now, but we can delay updating the DTV. */
imap->l_need_tls_init = 0;
#ifdef SHARED
/* Update the slot information data for at least the
Index: glibc-2.21/elf/dl-reloc.c
===================================================================
--- glibc-2.21.orig/elf/dl-reloc.c
+++ glibc-2.21/elf/dl-reloc.c
@@ -136,12 +136,6 @@ _dl_nothread_init_static_tls (struct lin
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif
- /* Fill in the DTV slot so that a later LD/GD access will find it. */
- dtv_t *dtv = THREAD_DTV ();
- assert (map->l_tls_modid <= dtv[-1].counter);
- dtv[map->l_tls_modid].pointer.val = dest;
- dtv[map->l_tls_modid].pointer.is_static = true;
-
/* Initialize the memory. */
memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size),
'\0', map->l_tls_blocksize - map->l_tls_initimage_size);
Index: glibc-2.21/elf/dl-tls.c
===================================================================
--- glibc-2.21.orig/elf/dl-tls.c
+++ glibc-2.21/elf/dl-tls.c
@@ -493,17 +493,14 @@ _dl_allocate_tls_init (void *result)
assert (listp->slotinfo[cnt].gen <= GL(dl_tls_generation));
maxgen = MAX (maxgen, listp->slotinfo[cnt].gen);
+ dtv[map->l_tls_modid].pointer.val = TLS_DTV_UNALLOCATED;
+ dtv[map->l_tls_modid].pointer.is_static = false;
+
if (map->l_tls_offset == NO_TLS_OFFSET
|| map->l_tls_offset == FORCED_DYNAMIC_TLS_OFFSET)
- {
- /* For dynamically loaded modules we simply store
- the value indicating deferred allocation. */
- dtv[map->l_tls_modid].pointer.val = TLS_DTV_UNALLOCATED;
- dtv[map->l_tls_modid].pointer.is_static = false;
- continue;
- }
+ continue;
- assert (map->l_tls_modid == cnt);
+ assert (map->l_tls_modid == total + cnt);
assert (map->l_tls_blocksize >= map->l_tls_initimage_size);
#if TLS_TCB_AT_TP
assert ((size_t) map->l_tls_offset >= map->l_tls_blocksize);
@@ -515,8 +512,6 @@ _dl_allocate_tls_init (void *result)
#endif
/* Copy the initialization image and clear the BSS part. */
- dtv[map->l_tls_modid].pointer.val = dest;
- dtv[map->l_tls_modid].pointer.is_static = true;
memset (__mempcpy (dest, map->l_tls_initimage,
map->l_tls_initimage_size), '\0',
map->l_tls_blocksize - map->l_tls_initimage_size);
@@ -679,13 +674,16 @@ _dl_update_slotinfo (unsigned long int r
struct link_map *map = listp->slotinfo[cnt].map;
if (map == NULL)
{
- /* If this modid was used at some point the memory
- might still be allocated. */
- if (! dtv[total + cnt].pointer.is_static
- && dtv[total + cnt].pointer.val != TLS_DTV_UNALLOCATED)
+ if (dtv[-1].counter >= total + cnt)
{
- free (dtv[total + cnt].pointer.val);
+ /* If this modid was used at some point the memory
+ might still be allocated. */
+ if (! dtv[total + cnt].pointer.is_static
+ && (dtv[total + cnt].pointer.val
+ != TLS_DTV_UNALLOCATED))
+ free (dtv[total + cnt].pointer.val);
dtv[total + cnt].pointer.val = TLS_DTV_UNALLOCATED;
+ dtv[total + cnt].pointer.is_static = false;
}
continue;
@@ -718,10 +716,8 @@ _dl_update_slotinfo (unsigned long int r
memalign and not malloc. */
free (dtv[modid].pointer.val);
- /* This module is loaded dynamically- We defer memory
- allocation. */
- dtv[modid].pointer.is_static = false;
dtv[modid].pointer.val = TLS_DTV_UNALLOCATED;
+ dtv[modid].pointer.is_static = false;
if (modid == req_modid)
the_map = map;
@@ -759,13 +755,12 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t
the_map = listp->slotinfo[idx].map;
}
- again:
/* Make sure that, if a dlopen running in parallel forces the
variable into static storage, we'll wait until the address in the
static TLS block is set up, and use that. If we're undecided
yet, make sure we make the decision holding the lock as well. */
- if (__builtin_expect (the_map->l_tls_offset
- != FORCED_DYNAMIC_TLS_OFFSET, 0))
+ if (__glibc_unlikely (the_map->l_tls_offset
+ != FORCED_DYNAMIC_TLS_OFFSET))
{
__rtld_lock_lock_recursive (GL(dl_load_lock));
if (__glibc_likely (the_map->l_tls_offset == NO_TLS_OFFSET))
@@ -773,22 +768,28 @@ tls_get_addr_tail (GET_ADDR_ARGS, dtv_t
the_map->l_tls_offset = FORCED_DYNAMIC_TLS_OFFSET;
__rtld_lock_unlock_recursive (GL(dl_load_lock));
}
- else
+ else if (__glibc_likely (the_map->l_tls_offset
+ != FORCED_DYNAMIC_TLS_OFFSET))
{
+#if TLS_TCB_AT_TP
+ void *p = (char *) THREAD_SELF - the_map->l_tls_offset;
+#elif TLS_DTV_AT_TP
+ void *p = (char *) THREAD_SELF + the_map->l_tls_offset + TLS_PRE_TCB_SIZE;
+#else
+# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
+#endif
__rtld_lock_unlock_recursive (GL(dl_load_lock));
- if (__builtin_expect (the_map->l_tls_offset
- != FORCED_DYNAMIC_TLS_OFFSET, 1))
- {
- void *p = dtv[GET_ADDR_MODULE].pointer.val;
- if (__glibc_unlikely (p == TLS_DTV_UNALLOCATED))
- goto again;
- return (char *) p + GET_ADDR_OFFSET;
- }
+ dtv[GET_ADDR_MODULE].pointer.is_static = true;
+ dtv[GET_ADDR_MODULE].pointer.val = p;
+
+ return (char *) p + GET_ADDR_OFFSET;
}
+ else
+ __rtld_lock_unlock_recursive (GL(dl_load_lock));
}
void *p = dtv[GET_ADDR_MODULE].pointer.val = allocate_and_init (the_map);
- dtv[GET_ADDR_MODULE].pointer.is_static = false;
+ assert (!dtv[GET_ADDR_MODULE].pointer.is_static);
return (char *) p + GET_ADDR_OFFSET;
}
Index: glibc-2.21/elf/tlsdeschtab.h
===================================================================
--- glibc-2.21.orig/elf/tlsdeschtab.h
+++ glibc-2.21/elf/tlsdeschtab.h
@@ -42,7 +42,7 @@ eq_tlsdesc (void *p, void *q)
return tdp->tlsinfo.ti_offset == tdq->tlsinfo.ti_offset;
}
-inline static int
+inline static size_t
map_generation (struct link_map *map)
{
size_t idx = map->l_tls_modid;
@@ -58,7 +58,7 @@ map_generation (struct link_map *map)
we can assume that, if the generation count is zero, we
still haven't determined the generation count for this
module. */
- if (listp->slotinfo[idx].gen)
+ if (listp->slotinfo[idx].map == map && listp->slotinfo[idx].gen)
return listp->slotinfo[idx].gen;
else
break;
Index: glibc-2.21/nptl/allocatestack.c
===================================================================
--- glibc-2.21.orig/nptl/allocatestack.c
+++ glibc-2.21/nptl/allocatestack.c
@@ -1190,7 +1190,6 @@ __nptl_setxid (struct xid_command *cmdp)
static inline void __attribute__((always_inline))
init_one_static_tls (struct pthread *curp, struct link_map *map)
{
- dtv_t *dtv = GET_DTV (TLS_TPADJ (curp));
# if TLS_TCB_AT_TP
void *dest = (char *) curp - map->l_tls_offset;
# elif TLS_DTV_AT_TP
@@ -1199,11 +1198,9 @@ init_one_static_tls (struct pthread *cur
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
# endif
- /* Fill in the DTV slot so that a later LD/GD access will find it. */
- dtv[map->l_tls_modid].pointer.val = dest;
- dtv[map->l_tls_modid].pointer.is_static = true;
-
- /* Initialize the memory. */
+ /* We cannot delay the initialization of the Static TLS area, since
+ it can be accessed with LE or IE, but since the DTV is only used
+ by GD and LD, we can delay its update to avoid a race. */
memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size),
'\0', map->l_tls_blocksize - map->l_tls_initimage_size);
}
Index: glibc-2.21/nptl_db/db-symbols.awk
===================================================================
--- glibc-2.21.orig/nptl_db/db-symbols.awk
+++ glibc-2.21/nptl_db/db-symbols.awk
@@ -2,6 +2,8 @@
# we've just built. It checks for all the symbols used in td_symbol_list.
BEGIN {
+%define DB_RTLD_VARIABLE(name) /* Nothing. */
+%define DB_MAIN_VARIABLE(name) /* Nothing. */
%define DB_LOOKUP_NAME(idx, name) required[STRINGIFY (name)] = 1;
%define DB_LOOKUP_NAME_TH_UNIQUE(idx, name) th_unique[STRINGIFY (name)] = 1;
%include "db-symbols.h"
Index: glibc-2.21/nptl_db/db_info.c
===================================================================
--- glibc-2.21.orig/nptl_db/db_info.c
+++ glibc-2.21/nptl_db/db_info.c
@@ -21,6 +21,7 @@
#include <stdint.h>
#include "thread_dbP.h"
#include <tls.h>
+#include <ldsodefs.h>
typedef struct pthread pthread;
typedef struct pthread_key_struct pthread_key_struct;
@@ -37,6 +38,9 @@ typedef struct
} dtv;
typedef struct link_map link_map;
+typedef struct rtld_global rtld_global;
+typedef struct dtv_slotinfo_list dtv_slotinfo_list;
+typedef struct dtv_slotinfo dtv_slotinfo;
/* Actually static in nptl/init.c, but we only need it for typeof. */
extern bool __nptl_initial_report_events;
Index: glibc-2.21/nptl_db/fetch-value.c
===================================================================
--- glibc-2.21.orig/nptl_db/fetch-value.c
+++ glibc-2.21/nptl_db/fetch-value.c
@@ -69,7 +69,8 @@ _td_locate_field (td_thragent_t *ta,
}
}
- if (idx != 0 && idx - (psaddr_t) 0 > DB_DESC_NELEM (desc))
+ if (idx != 0 && DB_DESC_NELEM (desc) != 0
+ && idx - (psaddr_t) 0 > DB_DESC_NELEM (desc))
/* This is an internal indicator to callers with nonzero IDX
that the IDX value is too big. */
return TD_NOAPLIC;
Index: glibc-2.21/nptl_db/structs.def
===================================================================
--- glibc-2.21.orig/nptl_db/structs.def
+++ glibc-2.21/nptl_db/structs.def
@@ -22,6 +22,28 @@
# define STRUCTS_DEF_DEFAULTS 1
#endif
+#ifndef DB_RTLD_VARIABLE
+# define DB_RTLD_VARIABLE(name) DB_VARIABLE (name)
+#endif
+
+#ifndef DB_MAIN_VARIABLE
+# define DB_MAIN_VARIABLE(name) DB_VARIABLE (name)
+#endif
+
+#ifndef DB_RTLD_GLOBAL_FIELD
+# if !IS_IN (libpthread)
+# define DB_RTLD_GLOBAL_FIELD(field) \
+ DB_STRUCT_FIELD (rtld_global, _##field) \
+ DB_MAIN_VARIABLE (_##field)
+# elif defined SHARED
+# define DB_RTLD_GLOBAL_FIELD(field) \
+ DB_STRUCT_FIELD (rtld_global, _##field)
+# else
+# define DB_RTLD_GLOBAL_FIELD(field) \
+ DB_MAIN_VARIABLE (_##field)
+# endif
+#endif /* DB_RTLD_GLOBAL_FIELD */
+
DB_STRUCT (pthread)
DB_STRUCT_FIELD (pthread, list)
DB_STRUCT_FIELD (pthread, report_events)
@@ -70,14 +92,31 @@ DB_STRUCT (pthread_key_data_level2)
DB_STRUCT_ARRAY_FIELD (pthread_key_data_level2, data)
DB_STRUCT_FIELD (link_map, l_tls_modid)
+DB_STRUCT_FIELD (link_map, l_tls_offset)
DB_STRUCT_ARRAY_FIELD (dtv, dtv)
#define pointer_val pointer.val /* Field of anonymous struct in dtv_t. */
DB_STRUCT_FIELD (dtv_t, pointer_val)
+DB_STRUCT_FIELD (dtv_t, counter)
#if !IS_IN (libpthread) || TLS_TCB_AT_TP
DB_STRUCT_FIELD (pthread, dtvp)
#endif
+#if !(IS_IN (libpthread) && !defined SHARED)
+DB_STRUCT (rtld_global)
+DB_RTLD_VARIABLE (_rtld_global)
+#endif
+DB_RTLD_GLOBAL_FIELD (dl_tls_dtv_slotinfo_list)
+
+DB_STRUCT (dtv_slotinfo_list)
+DB_STRUCT_FIELD (dtv_slotinfo_list, len)
+DB_STRUCT_FIELD (dtv_slotinfo_list, next)
+DB_STRUCT_ARRAY_FIELD (dtv_slotinfo_list, slotinfo)
+
+DB_STRUCT (dtv_slotinfo)
+DB_STRUCT_FIELD (dtv_slotinfo, gen)
+DB_STRUCT_FIELD (dtv_slotinfo, map)
+
#ifdef STRUCTS_DEF_DEFAULTS
# undef DB_STRUCT_ARRAY_FIELD
# undef DB_ARRAY_VARIABLE
Index: glibc-2.21/nptl_db/td_symbol_list.c
===================================================================
--- glibc-2.21.orig/nptl_db/td_symbol_list.c
+++ glibc-2.21/nptl_db/td_symbol_list.c
@@ -18,7 +18,6 @@
<http://www.gnu.org/licenses/>. */
#include <assert.h>
-#include <gnu/lib-names.h>
#include "thread_dbP.h"
static const char *symbol_list_arr[] =
@@ -41,12 +40,12 @@ td_symbol_list (void)
ps_err_e
-td_lookup (struct ps_prochandle *ps, int idx, psaddr_t *sym_addr)
+td_mod_lookup (struct ps_prochandle *ps, const char *mod,
+ int idx, psaddr_t *sym_addr)
{
ps_err_e result;
assert (idx >= 0 && idx < SYM_NUM_MESSAGES);
- result = ps_pglobal_lookup (ps, LIBPTHREAD_SO, symbol_list_arr[idx],
- sym_addr);
+ result = ps_pglobal_lookup (ps, mod, symbol_list_arr[idx], sym_addr);
#ifdef HAVE_ASM_GLOBAL_DOT_NAME
/* For PowerPC, 64-bit uses dot symbols but 32-bit does not.
Index: glibc-2.21/nptl_db/td_thr_tlsbase.c
===================================================================
--- glibc-2.21.orig/nptl_db/td_thr_tlsbase.c
+++ glibc-2.21/nptl_db/td_thr_tlsbase.c
@@ -17,14 +17,118 @@
<http://www.gnu.org/licenses/>. */
#include "thread_dbP.h"
+#include <link.h>
+/* Get the DTV slotinfo list head entry from the dynamic loader state
+ into *LISTHEAD. */
+static td_err_e
+dtv_slotinfo_list (td_thragent_t *ta,
+ psaddr_t *listhead)
+{
+ td_err_e err;
+ psaddr_t head;
+
+ if (ta->ta_addr__rtld_global == 0
+ && td_mod_lookup (ta->ph, LD_SO, SYM__rtld_global,
+ &ta->ta_addr__rtld_global) != PS_OK)
+ ta->ta_addr__rtld_global = (void*)-1;
+
+ if (ta->ta_addr__rtld_global != (void*)-1)
+ {
+ err = DB_GET_FIELD (head, ta, ta->ta_addr__rtld_global,
+ rtld_global, _dl_tls_dtv_slotinfo_list, 0);
+ if (err != TD_OK)
+ return err;
+ }
+ else
+ {
+ if (ta->ta_addr__dl_tls_dtv_slotinfo_list == 0
+ && td_mod_lookup (ta->ph, NULL, SYM__dl_tls_dtv_slotinfo_list,
+ &ta->ta_addr__dl_tls_dtv_slotinfo_list) != PS_OK)
+ return TD_ERR;
+
+ err = _td_fetch_value (ta, ta->ta_var__dl_tls_dtv_slotinfo_list,
+ SYM_DESC__dl_tls_dtv_slotinfo_list,
+ 0, ta->ta_addr__dl_tls_dtv_slotinfo_list, &head);
+ if (err != TD_OK)
+ return err;
+ }
+
+ *listhead = head;
+ return TD_OK;
+}
+
+/* Get the address of the DTV slotinfo entry for MODID into
+ *DTVSLOTINFO. */
+static td_err_e
+dtv_slotinfo (td_thragent_t *ta,
+ unsigned long int modid,
+ psaddr_t *dtvslotinfo)
+{
+ td_err_e err;
+ psaddr_t slot, temp;
+ size_t slbase = 0;
+
+ err = dtv_slotinfo_list (ta, &slot);
+ if (err != TD_OK)
+ return err;
+
+ while (slot)
+ {
+ /* Get the number of entries in this list entry's array. */
+ err = DB_GET_FIELD (temp, ta, slot, dtv_slotinfo_list, len, 0);
+ if (err != TD_OK)
+ return err;
+ size_t len = (uintptr_t)temp;
+
+ /* Did we find the list entry for modid? */
+ if (modid < slbase + len)
+ break;
+
+ /* We didn't, so get the next list entry. */
+ slbase += len;
+ err = DB_GET_FIELD (temp, ta, slot, dtv_slotinfo_list,
+ next, 0);
+ if (err != TD_OK)
+ return err;
+ slot = temp;
+ }
+
+ /* We reached the end of the list and found nothing. */
+ if (!slot)
+ return TD_ERR;
+
+ /* Take the slotinfo for modid from the list entry. */
+ err = DB_GET_FIELD_ADDRESS (temp, ta, slot, dtv_slotinfo_list,
+ slotinfo, modid - slbase);
+ if (err != TD_OK)
+ return err;
+ slot = temp;
+
+ *dtvslotinfo = slot;
+ return TD_OK;
+}
+
+/* Return in *BASE the base address of the TLS block for MODID within
+ TH.
+
+ It should return success and yield the correct pointer in any
+ circumstance where the TLS block for the module and thread
+ requested has already been initialized.
+
+ It should fail with TD_TLSDEFER only when the thread could not
+ possibly have observed any values in that TLS block. That way, the
+ debugger can fall back to showing initial values from the PT_TLS
+ segment (and refusing attempts to mutate) for the TD_TLSDEFER case,
+ and never fail to make the values the program will actually see
+ available to the user of the debugger. */
td_err_e
td_thr_tlsbase (const td_thrhandle_t *th,
unsigned long int modid,
psaddr_t *base)
{
td_err_e err;
- psaddr_t dtv, dtvslot, dtvptr;
+ psaddr_t dtv, dtvslot, dtvptr, temp;
if (modid < 1)
return TD_NOTLS;
@@ -50,11 +154,75 @@ td_thr_tlsbase (const td_thrhandle_t *th
return TD_TLSDEFER;
}
+ err = dtv_slotinfo (th->th_ta_p, modid, &temp);
+ if (err != TD_OK)
+ return err;
+
+ psaddr_t slot;
+ err = DB_GET_STRUCT (slot, th->th_ta_p, temp, dtv_slotinfo);
+ if (err != TD_OK)
+ return err;
+
+ /* Take the link_map from the slotinfo. */
+ psaddr_t map;
+ err = DB_GET_FIELD_LOCAL (map, th->th_ta_p, slot, dtv_slotinfo, map, 0);
+ if (err != TD_OK)
+ return err;
+ if (!map)
+ return TD_ERR;
+
+ /* Ok, the modid is good, now find out what DTV generation it
+ requires. */
+ err = DB_GET_FIELD_LOCAL (temp, th->th_ta_p, slot, dtv_slotinfo, gen, 0);
+ if (err != TD_OK)
+ return err;
+ size_t modgen = (uintptr_t)temp;
+
/* Get the DTV pointer from the thread descriptor. */
err = DB_GET_FIELD (dtv, th->th_ta_p, pd, pthread, dtvp, 0);
if (err != TD_OK)
return err;
+ psaddr_t dtvgenloc;
+ /* Get the DTV generation count at dtv[0].counter. */
+ err = DB_GET_FIELD_ADDRESS (dtvgenloc, th->th_ta_p, dtv, dtv, dtv, 0);
+ if (err != TD_OK)
+ return err;
+ err = DB_GET_FIELD (temp, th->th_ta_p, dtvgenloc, dtv_t, counter, 0);
+ if (err != TD_OK)
+ return err;
+ size_t dtvgen = (uintptr_t)temp;
+
+ /* Is the DTV current enough? */
+ if (dtvgen < modgen)
+ {
+ try_static_tls:
+ /* If the module uses Static TLS, we're still good. */
+ err = DB_GET_FIELD (temp, th->th_ta_p, map, link_map, l_tls_offset, 0);
+ if (err != TD_OK)
+ return err;
+ ptrdiff_t tlsoff = (uintptr_t)temp;
+
+ if (tlsoff != FORCED_DYNAMIC_TLS_OFFSET
+ && tlsoff != NO_TLS_OFFSET)
+ {
+ psaddr_t tp = pd;
+
+#if TLS_TCB_AT_TP
+ dtvptr = tp - tlsoff;
+#elif TLS_DTV_AT_TP
+ dtvptr = tp + tlsoff + TLS_PRE_TCB_SIZE;
+#else
+# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
+#endif
+
+ *base = dtvptr;
+ return TD_OK;
+ }
+
+ return TD_TLSDEFER;
+ }
+
/* Find the corresponding entry in the DTV. */
err = DB_GET_FIELD_ADDRESS (dtvslot, th->th_ta_p, dtv, dtv, dtv, modid);
if (err != TD_OK)
@@ -68,7 +236,7 @@ td_thr_tlsbase (const td_thrhandle_t *th
/* It could be that the memory for this module is not allocated for
the given thread. */
if ((uintptr_t) dtvptr & 1)
- return TD_TLSDEFER;
+ goto try_static_tls;
*base = dtvptr;
return TD_OK;
Index: glibc-2.21/nptl_db/thread_dbP.h
===================================================================
--- glibc-2.21.orig/nptl_db/thread_dbP.h
+++ glibc-2.21/nptl_db/thread_dbP.h
@@ -29,6 +29,7 @@
#include "thread_db.h"
#include "../nptl/pthreadP.h" /* This is for *_BITMASK only. */
#include <list.h>
+#include <gnu/lib-names.h>
/* Indeces for the symbol names. */
enum
@@ -139,11 +140,11 @@ ta_ok (const td_thragent_t *ta)
}
-/* Internal wrapper around ps_pglobal_lookup. */
-extern ps_err_e td_lookup (struct ps_prochandle *ps,
- int idx, psaddr_t *sym_addr) attribute_hidden;
-
-
+/* Internal wrappers around ps_pglobal_lookup. */
+extern ps_err_e td_mod_lookup (struct ps_prochandle *ps, const char *modname,
+ int idx, psaddr_t *sym_addr) attribute_hidden;
+#define td_lookup(ps, idx, sym_addr) \
+ td_mod_lookup ((ps), LIBPTHREAD_SO, (idx), (sym_addr))
/* Store in psaddr_t VAR the address of inferior's symbol NAME. */