From 487d1e0d6983f01a771c4c391ad2b2f99089bdb83536c48fe22af26f728e1470 Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Fri, 4 Feb 2011 04:30:37 +0000 Subject: [PATCH] OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=48 --- glibc-fini-unwind.diff | 60 +++++++++ glibc-gconvcache-s390.diff | 22 +++ glibc-malloc-arena-max.diff | 235 +++++++++++++++++++++++++++++++++ glibc-vfprintf-positional.diff | 20 +++ glibc.changes | 7 + glibc.spec | 109 ++++++++------- 6 files changed, 403 insertions(+), 50 deletions(-) create mode 100644 glibc-fini-unwind.diff create mode 100644 glibc-gconvcache-s390.diff create mode 100644 glibc-malloc-arena-max.diff create mode 100644 glibc-vfprintf-positional.diff diff --git a/glibc-fini-unwind.diff b/glibc-fini-unwind.diff new file mode 100644 index 0000000..e2da629 --- /dev/null +++ b/glibc-fini-unwind.diff @@ -0,0 +1,60 @@ +Index: sysdeps/x86_64/elf/initfini.c +=================================================================== +--- sysdeps/x86_64/elf/initfini.c.orig 2004-08-16 06:50:55.000000000 +0200 ++++ sysdeps/x86_64/elf/initfini.c 2010-04-16 16:41:11.000000000 +0200 +@@ -44,6 +44,25 @@ + * crtn.s puts the corresponding function epilogues + in the .init and .fini sections. */ + ++/* The unwind annotation for _fini is peculiar for good reasons: ++ (a) We need a real function that isn't constructed separately ++ (i.e. one which has a .size directive) in order to attach unwind ++ info to it. Hence _fini is a wrapper around _real_fini, the ++ former being a normal function, the latter being the first ++ instruction of the traditional _fini. ++ (b) We must not fiddle with the stack pointer in _real_fini, ++ as we wouldn't be able to describe the effects in unwind info ++ (c) some versions of GCC have no correct unwind info for ++ __do_global_dtors_aux, meaning they can't properly restore %rbp ++ (unwinding through it is possible but later up when we next ++ need %rbp we can't access it anymore) ++ Therefore we save/restore it in _fini for uses later up the call chain. ++ But we don't make the CFA use that register (that would lead to ++ the above problem) ++ (d) We want an 16-aligned stack pointer at _real_fini. Because of (a) ++ we can't align it in _real_fini, hence we do it in the caller by ++ subtracting 8, making in 8mod16 which the call then make 0mod16 ++ again. */ + __asm__ ("\n\ + #include \"defs.h\"\n\ + \n\ +@@ -88,16 +107,28 @@ _init:\n\ + .globl _fini\n\ + .type _fini,@function\n\ + _fini:\n\ ++ .cfi_startproc\n\ ++ push %rbp\n\ ++ .cfi_def_cfa_offset 16\n\ ++ .cfi_offset 6,-16\n\ + subq $8, %rsp\n\ ++ .cfi_def_cfa_offset 24\n\ ++ call _real_fini\n\ ++ addq $8, %rsp\n\ ++ .cfi_def_cfa_offset 16\n\ ++ pop %rbp\n\ ++ ret\n\ ++ .cfi_endproc\n\ + ALIGN\n\ + END_FINI\n\ ++.size _fini, .-_fini\n\ ++_real_fini:\n\ + \n\ + /*@_fini_PROLOG_ENDS*/\n\ + call i_am_not_a_leaf@PLT\n\ + \n\ + /*@_fini_EPILOG_BEGINS*/\n\ + .section .fini\n\ +- addq $8, %rsp\n\ + ret\n\ + END_FINI\n\ + \n\ diff --git a/glibc-gconvcache-s390.diff b/glibc-gconvcache-s390.diff new file mode 100644 index 0000000..93d58c7 --- /dev/null +++ b/glibc-gconvcache-s390.diff @@ -0,0 +1,22 @@ +Index: glibc/sysdeps/s390/s390-64/Makefile +=================================================================== +--- sysdeps/s390/s390-64/Makefile 2009-08-03 10:18:31.000000000 +0200 ++++ sysdeps/s390/s390-64/Makefile 2010-04-07 10:01:35.000000000 +0200 +@@ -74,5 +74,17 @@ $(objpfx)gconv-modules-s390: gconv-modul + + $(inst_gconvdir)/gconv-modules: $(objpfx)gconv-modules-s390 $(+force) + $(do-install) ++ifeq (no,$(cross-compiling)) ++# Update the $(prefix)/lib/gconv/gconv-modules.cache file. This is necessary ++# if this libc has more gconv modules than the previously installed one. ++ if test -f "$(inst_gconvdir)/gconv-modules.cache"; then \ ++ LC_ALL=C LANGUAGE=C \ ++ $(common-objpfx)elf/ld.so --library-path $(rpath-link) \ ++ $(common-objpfx)iconv/iconvconfig \ ++ $(addprefix --prefix=,$(install_root)); \ ++ fi ++else ++ @echo '*@*@*@ You should recreate $(inst_gconvdir)/gconv-modules.cache' ++endif + + endif diff --git a/glibc-malloc-arena-max.diff b/glibc-malloc-arena-max.diff new file mode 100644 index 0000000..24b91dc --- /dev/null +++ b/glibc-malloc-arena-max.diff @@ -0,0 +1,235 @@ +Allow M_ARENA_MAX / MALLOC_ARENA_MAX limit even with PER_THREAD disabled + +With the new PER_THREAD compile-time option, the allocator also offers +a way to limit the total number of arenas using MALLOC_ARENA_MAX +environment variable or mallopt(M_ARENA_MAX). + +In principle, this feature is not tied to the PER_THREAD option. This +patch makes it possible to use it even with the default compilation +settings. + +One motivation to limit the number of arenas may be libhugetlbfs users +that rely on its __morecore hook providing hugetlbfs-backed memory for +the allocator - this can work only with a single arena and multi-threaded +programs wishing to use this feature need a way to limit the allocator +to a single arena. Another motivation is avoiding pathological behavior +in extremely thread-intensive applications. + + +2011-02-04 Petr Baudis + + * malloc/arena.c: Define and manage narenas even ifndef + PER_THREAD. + * malloc/arena.c (ptmalloc_init_minimal): Likewise. + * malloc/arena.c (_int_new_arena): Likewise. + * malloc/arena.c (ptmalloc_init): Implement MALLOC_ARENA_MAX + even ifndef PER_THREAD. + * malloc/arena.c (reused_arena): Split off get_narenas_limit(), + define even ifndef PER_THREAD. + * malloc/arena.c (arena_get2): Adjust for get_narenas_limit() + split, call reused_arena even ifndef PER_THREAD. + * malloc/hooks.c (public_gET_STATe): Set arena_max, narenas + even ifndef PER_THREAD. + * malloc/hooks.c (public_sET_STATe): Likewise. + * malloc/malloc.c (malloc_par): Define arena_max even ifndef + PER_THREAD. + * malloc/malloc.c (mALLOPt): Implement M_ARENA_MAX even ifndef + PER_THREAD. + * malloc/malloc.c: Remove redundant M_* defines. + +diff --git a/malloc/arena.c b/malloc/arena.c +index 4d0deef..ea80724 100644 +--- a/malloc/arena.c ++++ b/malloc/arena.c +@@ -78,8 +78,8 @@ extern int sanity_check_heap_info_alignment[(sizeof (heap_info) + + static tsd_key_t arena_key; + static mutex_t list_lock; +-#ifdef PER_THREAD + static size_t narenas; ++#ifdef PER_THREAD + static mstate free_list; + #endif + +@@ -416,8 +416,8 @@ ptmalloc_init_minimal (void) + #ifdef PER_THREAD + # define NARENAS_FROM_NCORES(n) ((n) * (sizeof(long) == 4 ? 2 : 8)) + mp_.arena_test = NARENAS_FROM_NCORES (1); +- narenas = 1; + #endif ++ narenas = 1; + } + + +@@ -574,10 +574,8 @@ ptmalloc_init (void) + { + if (memcmp (envline, "MMAP_MAX_", 9) == 0) + mALLOPt(M_MMAP_MAX, atoi(&envline[10])); +-#ifdef PER_THREAD + else if (memcmp (envline, "ARENA_MAX", 9) == 0) + mALLOPt(M_ARENA_MAX, atoi(&envline[10])); +-#endif + } + break; + #ifdef PER_THREAD +@@ -946,9 +944,9 @@ _int_new_arena(size_t size) + atomic_write_barrier (); + main_arena.next = a; + +-#ifdef PER_THREAD + ++narenas; + ++#ifdef PER_THREAD + (void)mutex_unlock(&list_lock); + #endif + +@@ -982,13 +980,9 @@ get_free_list (void) + return result; + } + +- +-static mstate +-reused_arena (void) ++static int ++get_narenas_limit (void) __attribute__((pure)) + { +- if (narenas <= mp_.arena_test) +- return NULL; +- + static int narenas_limit; + if (narenas_limit == 0) + { +@@ -1006,10 +1000,16 @@ reused_arena (void) + narenas_limit = NARENAS_FROM_NCORES (2); + } + } ++ return narenas_limit; ++} ++#endif + +- if (narenas < narenas_limit) +- return NULL; + ++/* Reuse and return one of the existing arenas; if all arenas are busy, ++ * pick one in a round-robin fashion and block until it becomes available. */ ++static mstate ++reused_arena (void) ++{ + mstate result; + static mstate next_to_use; + if (next_to_use == NULL) +@@ -1035,7 +1035,6 @@ reused_arena (void) + + return result; + } +-#endif + + static mstate + internal_function +@@ -1048,10 +1047,15 @@ arena_get2(a_tsd, size) mstate a_tsd; size_t size; + mstate a; + + #ifdef PER_THREAD +- if ((a = get_free_list ()) == NULL +- && (a = reused_arena ()) == NULL) +- /* Nothing immediately available, so generate a new arena. */ +- a = _int_new_arena(size); ++ if ((a = get_free_list ()) == NULL) ++ { ++ if (narenas > mp_.arena_test && narenas >= get_narenas_limit()) ++ a = reused_arena (); ++ else ++ /* Nothing immediately available, but we can still generate more ++ * arenas, so get a new one. */ ++ a = _int_new_arena(size); ++ } + #else + if(!a_tsd) + a = a_tsd = &main_arena; +@@ -1093,8 +1097,14 @@ arena_get2(a_tsd, size) mstate a_tsd; size_t size; + goto repeat; + } + +- /* Nothing immediately available, so generate a new arena. */ +- a = _int_new_arena(size); ++ if (__builtin_expect(mp_.arena_max > 0, 0) && narenas >= mp_.arena_max) ++ /* Try again, this time blocking in case we are still unable to find ++ * a free arena. */ ++ a = reused_arena(); ++ else ++ /* Nothing immediately available, so generate a new arena. */ ++ a = _int_new_arena(size); ++ + (void)mutex_unlock(&list_lock); + #endif + +diff --git a/malloc/hooks.c b/malloc/hooks.c +index 28845ee..e938492 100644 +--- a/malloc/hooks.c ++++ b/malloc/hooks.c +@@ -579,9 +579,9 @@ public_gET_STATe(void) + ms->max_fast = get_max_fast(); + #ifdef PER_THREAD + ms->arena_test = mp_.arena_test; ++#endif + ms->arena_max = mp_.arena_max; + ms->narenas = narenas; +-#endif + (void)mutex_unlock(&main_arena.mutex); + return (Void_t*)ms; + } +@@ -683,9 +683,9 @@ public_sET_STATe(Void_t* msptr) + if (ms->version >= 4) { + #ifdef PER_THREAD + mp_.arena_test = ms->arena_test; ++#endif + mp_.arena_max = ms->arena_max; + narenas = ms->narenas; +-#endif + } + check_malloc_state(&main_arena); + +diff --git a/malloc/malloc.c b/malloc/malloc.c +index b1d43c6..8dbadfa 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -2406,9 +2406,10 @@ struct malloc_par { + INTERNAL_SIZE_T top_pad; + INTERNAL_SIZE_T mmap_threshold; + #ifdef PER_THREAD ++ /* Lower bound for arena_max. */ + INTERNAL_SIZE_T arena_test; +- INTERNAL_SIZE_T arena_max; + #endif ++ INTERNAL_SIZE_T arena_max; + + /* Memory map support */ + int n_mmaps; +@@ -2446,13 +2447,6 @@ static struct malloc_state main_arena; + static struct malloc_par mp_; + + +-#ifdef PER_THREAD +-/* Non public mallopt parameters. */ +-#define M_ARENA_TEST -7 +-#define M_ARENA_MAX -8 +-#endif +- +- + /* Maximum size of memory handled in fastbins. */ + static INTERNAL_SIZE_T global_max_fast; + +@@ -6095,12 +6089,12 @@ int mALLOPt(param_number, value) int param_number; int value; + if (value > 0) + mp_.arena_test = value; + break; ++#endif + + case M_ARENA_MAX: + if (value > 0) + mp_.arena_max = value; + break; +-#endif + } + (void)mutex_unlock(&av->mutex); + return res; diff --git a/glibc-vfprintf-positional.diff b/glibc-vfprintf-positional.diff new file mode 100644 index 0000000..9947188 --- /dev/null +++ b/glibc-vfprintf-positional.diff @@ -0,0 +1,20 @@ +2011-01-27 Petr Baudis + + * stdio-common/vfprintf.c (vfprintf): Pass correct newlen + to extend_alloca(). + +diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c +index fc370e8..ecf5dfa 100644 +--- a/stdio-common/vfprintf.c ++++ b/stdio-common/vfprintf.c +@@ -1682,7 +1682,9 @@ do_positional: + { + /* Extend the array of format specifiers. */ + struct printf_spec *old = specs; +- specs = extend_alloca (specs, nspecs_max, 2 * nspecs_max); ++ specs = extend_alloca (specs, nspecs_max, ++ 2 * nspecs_max ++ * sizeof (struct printf_spec)); + + /* Copy the old array's elements to the new space. */ + memmove (specs, old, nspecs * sizeof (struct printf_spec)); diff --git a/glibc.changes b/glibc.changes index c1c9221..0fa266b 100644 --- a/glibc.changes +++ b/glibc.changes @@ -18,6 +18,13 @@ Fri Feb 4 00:46:40 CET 2011 - pbaudis@suse.cz convincing case for keeping the functions with all the associated maintenance headaches; AMD does not recommend keeping their custom versions of the functions either. +- Introduce MALLOC_ARENA_MAX and M_ARENA_MAX support [bnc#659090] +- Fixed stack unwinding past glibc _fini function (proper showing + of destructor backtraces) [bnc#585879] +- Fix gconv cache generation on s390 [bnc#592944] +- Add missing iconvconfig for refreshing gconv.cache to glibc-locale %post +- Fixed stack corruption in *printf() with large number of positional + specifiers [bnc#666179] ------------------------------------------------------------------- Fri Jan 28 14:53:35 UTC 2011 - rguenther@novell.com diff --git a/glibc.spec b/glibc.spec index 2aac1de..5b40911 100644 --- a/glibc.spec +++ b/glibc.spec @@ -98,41 +98,45 @@ Patch9: glibc-2.3-regcomp.diff Patch10: glibc-2.3.2-revert_tcsetattr.diff Patch11: glibc-2.3.1.localedef.diff Patch12: glibc-2.3.2.no_archive.diff -Patch14: libm-x86-64.diff.bz2 -Patch15: glibc-2.3.90-bindresvport.blacklist.diff -Patch16: glibc-suse-note.diff -Patch17: glibc-2.4.90-no_NO.diff -Patch18: glibc-2.3.90-ld.so-madvise.diff -Patch19: glibc-2.3.3-amd64-s_ceil.diff -Patch20: glibc-2.3.3-execstack.diff -Patch21: glibc-2.4-china.diff -Patch22: glibc-2.3.4-gb18030-big5hkscs.diff.bz2 -Patch23: glibc-2.4.90-nscd.diff -Patch24: glibc-2.3.3-nscd-db-path.diff -Patch25: glibc-2.3.5-nscd-zeronegtimeout.diff -Patch26: glibc-2.3.90-langpackdir.diff -Patch27: glibc-nptl-2.4-nofixsyscallnr.diff -Patch30: glibc-2.6-configure.diff -Patch31: glibc-2.2-sunrpc.diff -Patch32: glibc-2.8-getconf.diff -Patch33: getaddrinfo-ipv6-sanity.diff -Patch35: ppc-atomic.diff -Patch36: glibc-2.8-clone.diff -Patch39: glibc-compiled-binaries.diff -Patch40: glibc-selinux.diff -Patch41: glibc-check-native-missing-include.diff -Patch42: glibc-no-unwind-tables.diff -Patch43: glibc-2.10-nscd-nostack.diff -Patch44: glibc-cpusetsize.diff -Patch46: glibc-2.10.99-ia64-include.diff -Patch47: libm-x86-64-exceptions.diff -Patch48: glibc-uio-cell.diff -Patch54: glibc-statfs64-ia64.diff -Patch60: ld-prelink-unique.diff -Patch61: glibc-ppc64-vdso-time.diff -Patch64: glibc-gai-private4.diff -Patch65: glibc-resolv-mdnshint.diff -Patch69: glibc-nscd-hconf.diff +Patch13: libm-x86-64.diff.bz2 +Patch14: glibc-2.3.90-bindresvport.blacklist.diff +Patch15: glibc-suse-note.diff +Patch16: glibc-2.4.90-no_NO.diff +Patch17: glibc-2.3.90-ld.so-madvise.diff +Patch18: glibc-2.3.3-amd64-s_ceil.diff +Patch19: glibc-2.3.3-execstack.diff +Patch20: glibc-2.4-china.diff +Patch21: glibc-2.3.4-gb18030-big5hkscs.diff.bz2 +Patch22: glibc-2.4.90-nscd.diff +Patch23: glibc-2.3.3-nscd-db-path.diff +Patch24: glibc-2.3.5-nscd-zeronegtimeout.diff +Patch25: glibc-2.3.90-langpackdir.diff +Patch26: glibc-nptl-2.4-nofixsyscallnr.diff +Patch27: glibc-2.6-configure.diff +Patch28: glibc-2.2-sunrpc.diff +Patch29: glibc-2.8-getconf.diff +Patch30: getaddrinfo-ipv6-sanity.diff +Patch31: ppc-atomic.diff +Patch32: glibc-2.8-clone.diff +Patch33: glibc-compiled-binaries.diff +Patch34: glibc-selinux.diff +Patch35: glibc-check-native-missing-include.diff +Patch36: glibc-no-unwind-tables.diff +Patch37: glibc-2.10-nscd-nostack.diff +Patch38: glibc-cpusetsize.diff +Patch39: glibc-2.10.99-ia64-include.diff +Patch40: libm-x86-64-exceptions.diff +Patch41: glibc-uio-cell.diff +Patch42: glibc-statfs64-ia64.diff +Patch43: ld-prelink-unique.diff +Patch44: glibc-ppc64-vdso-time.diff +Patch45: glibc-gai-private4.diff +Patch46: glibc-resolv-mdnshint.diff +Patch47: glibc-nscd-hconf.diff +Patch48: glibc-malloc-arena-max.diff +Patch49: glibc-fini-unwind.diff +Patch50: glibc-gconvcache-s390.diff +Patch51: glibc-vfprintf-positional.diff Patch500: ARM_glibc-2.10.1-local-eabi-wchar.diff Patch501: ARM_glibc-2.10.1-local-hwcap-updates.diff Patch502: ARM_glibc-2.10.1-local-lowlevellock.diff @@ -305,9 +309,10 @@ versions of your software. %patch10 %patch11 %patch12 -%patch14 -E -# We have s_sincos.c in patch14, remove duplicate +%patch13 -E +# We have s_sincos.c in patch13, remove duplicate rm sysdeps/x86_64/fpu/s_sincos.S +%patch14 %patch15 %patch16 %patch17 @@ -315,38 +320,41 @@ rm sysdeps/x86_64/fpu/s_sincos.S %patch19 %patch20 %patch21 -%patch22 # avoid changing nscd_stat.c mtime to avoid code generation # differences on each rebuild touch -r nscd/nscd_stat.c nscd/s-stamp +%patch22 %patch23 %patch24 -%patch25 touch -r nscd/s-stamp nscd/nscd_stat.c rm nscd/s-stamp +%patch25 %patch26 %patch27 +%patch28 +%patch29 %patch30 %patch31 %patch32 %patch33 +%patch34 %patch35 %patch36 +%patch37 +%patch38 %patch39 %patch40 -%patch41 +%patch41 -p1 %patch42 -%patch43 -%patch44 -%patch46 -%patch47 +%patch43 -p1 +%patch44 -p1 +%patch45 +%patch46 -p1 +%patch47 -p1 %patch48 -p1 -%patch54 -%patch60 -p1 -%patch61 -p1 -%patch64 -%patch65 -p1 -%patch69 -p1 +%patch49 +%patch50 +%patch51 -p1 %ifarch %arm armv5tel armv7l %patch500 %patch501 @@ -769,6 +777,7 @@ for l in /usr/share/locale/locale.alias %{_libdir}/gconv/gconv-modules; do echo "###X# The following is autogenerated from extra files in the .d directory:" >>"$l" cat "$l.d"/* >>"$l" done +/usr/sbin/iconvconfig %post info %install_info --info-dir=%{_infodir} %{_infodir}/libc.info.gz