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:
parent
680876d9c6
commit
d6f647d047
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
17
glibc.spec
17
glibc.spec
@ -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
|
||||
|
715
nss-separate-state-getXXent.patch
Normal file
715
nss-separate-state-getXXent.patch
Normal 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
117
powerpc-software-sqrt.patch
Normal 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
641
static-tls-dtv-limit.patch
Normal 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. */
|
Loading…
Reference in New Issue
Block a user