mirror of git://sourceware.org/git/glibc.git
static tls memory leak on TLS_DTV_AT_TP archs
This commit is contained in:
parent
c1e9ea3517
commit
66bdbaa452
|
@ -1,3 +1,11 @@
|
||||||
|
2011-03-15 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* elf/dl-reloc.c (_dl_try_allocate_static_tls <TLS_DTV_AT_TP>): Handle
|
||||||
|
l_tls_firstbyte_offset non-zero. Save padding offset in
|
||||||
|
l_tls_firstbyte_offset for later use.
|
||||||
|
* elf/dl-close.c (_dl_close_worker <TLS_DTV_AT_TP>): Correct code
|
||||||
|
freeing static tls block.
|
||||||
|
|
||||||
2011-03-05 Jonathan Nieder <jrnieder@gmail.com>
|
2011-03-05 Jonathan Nieder <jrnieder@gmail.com>
|
||||||
|
|
||||||
* sysdeps/unix/sysv/linux/sys/param.h: Fix an #ifndef __undef_ARG_MAX
|
* sysdeps/unix/sysv/linux/sys/param.h: Fix an #ifndef __undef_ARG_MAX
|
||||||
|
|
|
@ -591,21 +591,37 @@ _dl_close_worker (struct link_map *map)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elif TLS_DTV_AT_TP
|
#elif TLS_DTV_AT_TP
|
||||||
if ((size_t) imap->l_tls_offset == tls_free_end)
|
if (tls_free_start == NO_TLS_OFFSET)
|
||||||
|
{
|
||||||
|
tls_free_start = imap->l_tls_firstbyte_offset;
|
||||||
|
tls_free_end = (imap->l_tls_offset
|
||||||
|
+ imap->l_tls_blocksize);
|
||||||
|
}
|
||||||
|
else if (imap->l_tls_firstbyte_offset == tls_free_end)
|
||||||
/* Extend the contiguous chunk being reclaimed. */
|
/* Extend the contiguous chunk being reclaimed. */
|
||||||
tls_free_end -= imap->l_tls_blocksize;
|
tls_free_end = imap->l_tls_offset + imap->l_tls_blocksize;
|
||||||
else if (imap->l_tls_offset + imap->l_tls_blocksize
|
else if (imap->l_tls_offset + imap->l_tls_blocksize
|
||||||
== tls_free_start)
|
== tls_free_start)
|
||||||
/* Extend the chunk backwards. */
|
/* Extend the chunk backwards. */
|
||||||
tls_free_start = imap->l_tls_offset;
|
tls_free_start = imap->l_tls_firstbyte_offset;
|
||||||
else
|
|
||||||
{
|
|
||||||
/* This isn't contiguous with the last chunk freed.
|
/* This isn't contiguous with the last chunk freed.
|
||||||
One of them will be leaked. */
|
One of them will be leaked unless we can free
|
||||||
if (tls_free_end == GL(dl_tls_static_used))
|
one block right away. */
|
||||||
|
else if (imap->l_tls_offset + imap->l_tls_blocksize
|
||||||
|
== GL(dl_tls_static_used))
|
||||||
|
GL(dl_tls_static_used) = imap->l_tls_firstbyte_offset;
|
||||||
|
else if (tls_free_end == GL(dl_tls_static_used))
|
||||||
|
{
|
||||||
GL(dl_tls_static_used) = tls_free_start;
|
GL(dl_tls_static_used) = tls_free_start;
|
||||||
tls_free_start = imap->l_tls_offset;
|
tls_free_start = imap->l_tls_firstbyte_offset;
|
||||||
tls_free_end = tls_free_start + imap->l_tls_blocksize;
|
tls_free_end = imap->l_tls_offset + imap->l_tls_blocksize;
|
||||||
|
}
|
||||||
|
else if (tls_free_end < imap->l_tls_firstbyte_offset)
|
||||||
|
{
|
||||||
|
/* We pick the later block. It has a chance to
|
||||||
|
be freed. */
|
||||||
|
tls_free_start = imap->l_tls_firstbyte_offset;
|
||||||
|
tls_free_end = imap->l_tls_offset + imap->l_tls_blocksize;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
|
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Relocate a shared object and resolve its references to other loaded objects.
|
/* Relocate a shared object and resolve its references to other loaded objects.
|
||||||
Copyright (C) 1995-2006, 2008, 2009, 2010 Free Software Foundation, Inc.
|
Copyright (C) 1995-2006, 2008-2010, 2011 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
@ -57,38 +57,34 @@ _dl_try_allocate_static_tls (struct link_map *map)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TLS_TCB_AT_TP
|
#if TLS_TCB_AT_TP
|
||||||
size_t freebytes;
|
size_t freebytes = GL(dl_tls_static_size) - GL(dl_tls_static_used);
|
||||||
size_t n;
|
|
||||||
size_t blsize;
|
|
||||||
|
|
||||||
freebytes = GL(dl_tls_static_size) - GL(dl_tls_static_used);
|
|
||||||
if (freebytes < TLS_TCB_SIZE)
|
if (freebytes < TLS_TCB_SIZE)
|
||||||
goto fail;
|
goto fail;
|
||||||
freebytes -= TLS_TCB_SIZE;
|
freebytes -= TLS_TCB_SIZE;
|
||||||
|
|
||||||
blsize = map->l_tls_blocksize + map->l_tls_firstbyte_offset;
|
size_t blsize = map->l_tls_blocksize + map->l_tls_firstbyte_offset;
|
||||||
if (freebytes < blsize)
|
if (freebytes < blsize)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
n = (freebytes - blsize) / map->l_tls_align;
|
size_t n = (freebytes - blsize) / map->l_tls_align;
|
||||||
|
|
||||||
size_t offset = GL(dl_tls_static_used) + (freebytes - n * map->l_tls_align
|
size_t offset = GL(dl_tls_static_used) + (freebytes - n * map->l_tls_align
|
||||||
- map->l_tls_firstbyte_offset);
|
- map->l_tls_firstbyte_offset);
|
||||||
|
|
||||||
map->l_tls_offset = GL(dl_tls_static_used) = offset;
|
map->l_tls_offset = GL(dl_tls_static_used) = offset;
|
||||||
#elif TLS_DTV_AT_TP
|
#elif TLS_DTV_AT_TP
|
||||||
size_t used;
|
|
||||||
size_t check;
|
|
||||||
|
|
||||||
size_t offset = roundup (GL(dl_tls_static_used), map->l_tls_align);
|
|
||||||
used = offset + map->l_tls_blocksize;
|
|
||||||
check = used;
|
|
||||||
/* dl_tls_static_used includes the TCB at the beginning. */
|
/* dl_tls_static_used includes the TCB at the beginning. */
|
||||||
|
size_t offset = (((GL(dl_tls_static_used)
|
||||||
|
- map->l_tls_firstbyte_offset
|
||||||
|
+ map->l_tls_align - 1) & -map->l_tls_align)
|
||||||
|
+ map->l_tls_firstbyte_offset);
|
||||||
|
size_t used = offset + map->l_tls_blocksize;
|
||||||
|
|
||||||
if (check > GL(dl_tls_static_size))
|
if (used > GL(dl_tls_static_size))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
map->l_tls_offset = offset;
|
map->l_tls_offset = offset;
|
||||||
|
map->l_tls_firstbyte_offset = GL(dl_tls_static_used);
|
||||||
GL(dl_tls_static_used) = used;
|
GL(dl_tls_static_used) = used;
|
||||||
#else
|
#else
|
||||||
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
|
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
|
||||||
|
|
Loading…
Reference in New Issue