Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add plain glibc 2.12.2 + TLS/thread-safety patch dynamic loader #835

Merged
merged 1 commit into from Jul 7, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions cmssw-tool-conf.spec
Expand Up @@ -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
Expand Down
102 changes: 102 additions & 0 deletions 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)
17 changes: 17 additions & 0 deletions 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
<tool name="glibc" version="@TOOL_VERSION@">
<info url="http://www.gnu.org/software/libc/libc.html"/>
<client>
<environment name="GLIBC_BASE" default="@TOOL_ROOT@"/>
</client>
<runtime name="GLIBC_ROOT" value="$GLIBC_BASE" type="path"/>
</tool>
EOF_TOOLFILE
## IMPORT scram-tools-post
31 changes: 31 additions & 0 deletions 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