From ee8d57eb4f677916436ccf29b673fca2871b3d7c Mon Sep 17 00:00:00 2001 From: David Abdurachmanov Date: Fri, 13 Jun 2014 13:41:29 +0200 Subject: [PATCH] Add plain glibc 2.12.2 + TLS/thread-safety patch dynamic loader The following contains plain glibc 2.12.2 with TLS/thread-safety patch on top. All the changes are contained within the dynamic loader, thus package only includes only ld-2.12.2.so. ABI and API is not modified. SCRAM tool file makes GLIBC_ROOT available in developer area for wrapper scripts. --- cmssw-tool-conf.spec | 1 + glibc-2.12.2-fix-dl-tls.patch | 102 ++++++++++++++++++++++++++++++++++ glibc-toolfile.spec | 17 ++++++ glibc.spec | 31 +++++++++++ 4 files changed, 151 insertions(+) create mode 100644 glibc-2.12.2-fix-dl-tls.patch create mode 100644 glibc-toolfile.spec create mode 100644 glibc.spec diff --git a/cmssw-tool-conf.spec b/cmssw-tool-conf.spec index e950bf2a640..52240cd6fad 100644 --- a/cmssw-tool-conf.spec +++ b/cmssw-tool-conf.spec @@ -130,6 +130,7 @@ Requires: geant4-parfullcms-toolfile # Only for Linux platform. %if %islinux +Requires: glibc-toolfile Requires: openldap-toolfile Requires: python-ldap-toolfile Requires: gdb-toolfile diff --git a/glibc-2.12.2-fix-dl-tls.patch b/glibc-2.12.2-fix-dl-tls.patch new file mode 100644 index 00000000000..34bb5c7528b --- /dev/null +++ b/glibc-2.12.2-fix-dl-tls.patch @@ -0,0 +1,102 @@ +diff --git a/elf/dl-tls.c b/elf/dl-tls.c +index 824adc1..3fa6946 100644 +--- a/elf/dl-tls.c ++++ b/elf/dl-tls.c +@@ -38,14 +38,12 @@ + + + /* Out-of-memory handler. */ +-#ifdef SHARED + static void + __attribute__ ((__noreturn__)) + oom (void) + { + _dl_fatal_printf ("cannot allocate memory for thread-local data: ABORT\n"); + } +-#endif + + + size_t +@@ -382,6 +380,11 @@ _dl_allocate_tls_init (void *result) + /* The memory allocation failed. */ + return NULL; + ++ /* Make sure we are alone. TLS allocation and dlopen() cannot happen ++ concurrently. */ ++ __rtld_lock_lock_recursive (GL(dl_load_write_lock)); ++ /*__rtld_lock_unlock_recursive (GL(dl_load_lock)); */ ++ + dtv_t *dtv = GET_DTV (result); + struct dtv_slotinfo_list *listp; + size_t total = 0; +@@ -391,6 +394,52 @@ _dl_allocate_tls_init (void *result) + TLS. For those which are dynamically loaded we add the values + indicating deferred allocation. */ + listp = GL(dl_tls_dtv_slotinfo_list); ++ ++ /* check if current dtv is big enough */ ++ if (dtv[-1].counter < GL(dl_tls_max_dtv_idx)) ++ { ++ dtv_t *newp; ++ size_t newsize = GL(dl_tls_max_dtv_idx) + DTV_SURPLUS; ++ size_t oldsize = dtv[-1].counter; ++ ++ if ( ++#ifdef SHARED ++ dtv == GL(dl_initial_dtv) ++#else ++ 0 ++#endif ++ ) ++ { ++ /* This is the initial dtv that was allocated ++ during rtld startup using the dl-minimal.c ++ malloc instead of the real malloc. We can't ++ free it, we have to abandon the old storage. */ ++ newp = malloc ((2 + newsize) * sizeof (dtv_t)); ++ if (newp == NULL) ++ oom (); ++ memcpy (newp, &dtv[-1], (2 + oldsize) * sizeof (dtv_t)); ++ } ++ else ++ { ++ newp = realloc(&dtv[-1], (2 + newsize) * sizeof (dtv_t)); ++ if (newp == NULL) ++ oom(); ++ } ++ ++ newp[0].counter = newsize; ++ ++ /* Clear the newly allocated part. */ ++ memset (newp + 2 + oldsize, '\0', (newsize - oldsize) * sizeof (dtv_t)); ++ ++ /* Point dtv to the generation counter. */ ++ dtv = &newp[1]; ++ ++ /* Install this new dtv in the given thread */ ++ INSTALL_DTV (result, newp); ++ ++ assert(dtv[-1].counter >= GL(dl_tls_max_dtv_idx)); ++ } ++ + while (1) + { + size_t cnt; +@@ -418,6 +467,7 @@ _dl_allocate_tls_init (void *result) + { + /* For dynamically loaded modules we simply store + the value indicating deferred allocation. */ ++ assert (map->l_tls_modid <= dtv[-1].counter); + dtv[map->l_tls_modid].pointer.val = TLS_DTV_UNALLOCATED; + dtv[map->l_tls_modid].pointer.is_static = false; + continue; +@@ -453,6 +503,9 @@ _dl_allocate_tls_init (void *result) + /* The DTV version is up-to-date now. */ + dtv[0].counter = maxgen; + ++ /* Release lock */ ++ __rtld_lock_unlock_recursive (GL(dl_load_write_lock)); ++ + return result; + } + rtld_hidden_def (_dl_allocate_tls_init) diff --git a/glibc-toolfile.spec b/glibc-toolfile.spec new file mode 100644 index 00000000000..950628211f3 --- /dev/null +++ b/glibc-toolfile.spec @@ -0,0 +1,17 @@ +### RPM external glibc-toolfile 1.0 +Requires: glibc + +%prep +%build +%install +mkdir -p %{i}/etc/scram.d +cat << \EOF_TOOLFILE > %{i}/etc/scram.d/glibc.xml + + + + + + + +EOF_TOOLFILE +## IMPORT scram-tools-post diff --git a/glibc.spec b/glibc.spec new file mode 100644 index 00000000000..d4d98c3c8e2 --- /dev/null +++ b/glibc.spec @@ -0,0 +1,31 @@ +### RPM external glibc 2.12.2 +## NOCOMPILER + +Source0: http://ftp.gnu.org/gnu/glibc/%{n}-%{realversion}.tar.gz + +Patch0: glibc-2.12.2-fix-dl-tls + +%prep +%setup -n %{n}-%{realversion} +%patch0 -p1 + +%build + +rm -rf ../glibc-build +mkdir ../glibc-build +cd ../glibc-build +../glibc-%{realversion}/configure \ + --prefix=/ \ + --without-selinux \ + --disable-sanity-checks + +make %{makeprocesses} + +%install +cd ../glibc-build +make install install_root=%{i} + +# Remove everything except dynamic loader. All changes are contained +# within the loader. +find %{i} ! -type d | grep -Z -v 'ld-%{realversion}' | xargs rm -f +find %{i} -empty -type d -delete