diff --git a/ChangeLog b/ChangeLog index 27ab728215..f45670ab0b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,23 @@ 2002-11-13 Roland McGrath + * scripts/abilist.awk: New file. + * Makefile (distribute): Add it. + * Makerules ($(objpfx)%.dynsym, $(objpfx)%.symlist): New rules. + (tests): Depend on .symlist file for each $(install-lib.so-versioned). + [! subdir] (tests): Depend on libc.symlist. + (generated): Add those files. + * aclocal.m4 (LIBC_PROG_BINUTILS): Check for objdump, set OBJDUMP. + * configure: Regenerated. + * config.make.in (OBJDUMP): New variable, substituted by configure. + + * malloc/mcheck.c (struct hdr): New members `block' and `magic2'. + (mallochook, reallochook): Set them up. + (checkhdr): Check HDR->magic2 value. + (freehook): Reset HDR->magic2. + (memalignhook): New static function. + (old_memalign_hook): New static variable. + (mcheck, reallochook): Set __memalign_hook to memalignhook. + * sysdeps/generic/dl-tls.c (_dl_allocate_tls_storage): Zero the space for the new TCB. diff --git a/Makefile b/Makefile index 942b28518b..0358a6c7c5 100644 --- a/Makefile +++ b/Makefile @@ -278,7 +278,7 @@ distribute := README README.libm INSTALL FAQ FAQ.in NOTES NEWS BUGS \ rellns-sh config.sub config.guess \ mkinstalldirs move-if-change install-sh \ test-installation.pl gen-FAQ.pl versions.awk\ - gen-sorted.awk abi-versions.awk \ + gen-sorted.awk abi-versions.awk abilist.awk \ firstversions.awk documented.sh cpp) distribute := $(strip $(distribute)) diff --git a/Makerules b/Makerules index 461451f8a4..1fab920a0a 100644 --- a/Makerules +++ b/Makerules @@ -1073,6 +1073,28 @@ endif # The include magic above causes those files to use this variable for flags. CPPFLAGS-nonlib = -DNOT_IN_libc=1 + + +ifeq ($(versioning),yes) +# Generate normalized lists of symbols, versions, and data sizes. +# This is handy for checking against existing library binaries. + +$(objpfx)%.symlist: $(..)scripts/abilist.awk $(objpfx)%.dynsym + $(AWK) -f $^ > $@T + mv -f $@T $@ + +$(objpfx)%.dynsym: $(objpfx)%.so + $(OBJDUMP) --dynamic-syms $< > $@T + mv -f $@T $@ + +tests: $(patsubst %.so,$(objpfx)%.symlist,$(install-lib.so-versioned)) +generated += $(install-lib.so-versioned:.so=.symlist) + +ifndef subdir +tests: $(objpfx)libc.symlist +generated += libc.symlist +endif +endif .PHONY: TAGS TAGS: $(objpfx)distinfo $(..)MakeTAGS diff --git a/aclocal.m4 b/aclocal.m4 index 30ef36d33a..7395ee836c 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -96,6 +96,8 @@ AS=`$CC -print-prog-name=as` LD=`$CC -print-prog-name=ld` AR=`$CC -print-prog-name=ar` AC_SUBST(AR) +OBJDUMP=`$CC -print-prog-name=objdump` +AC_SUBST(OBJDUMP) # ranlib has to be treated a bit differently since it might not exist at all. ac_ranlib=`$CC -print-prog-name=ranlib` diff --git a/config.make.in b/config.make.in index d1f8409bb1..ed0ad416a2 100644 --- a/config.make.in +++ b/config.make.in @@ -92,6 +92,7 @@ MIG = @MIG@ PWD_P = @PWD_P@ BISON = @BISON@ AUTOCONF = @AUTOCONF@ +OBJDUMP = @OBJDUMP@ # Installation tools. INSTALL = @INSTALL@ diff --git a/configure b/configure index d149b94da9..33737d603c 100755 --- a/configure +++ b/configure @@ -309,7 +309,7 @@ ac_includes_default="\ # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS with_fp with_cvs oldest_abi subdirs force_install all_warnings build build_cpu build_vendor build_os host host_cpu host_vendor host_os base_machine sysnames INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S PWD_P CC MAKE MSGFMT MAKEINFO SED AUTOCONF CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT BUILD_CC cross_compiling CPP AR RANLIB ac_ct_RANLIB MIG AS LD CCVERSION SYSINCLUDES libc_cv_gcc_static_libgcc BASH libc_cv_have_bash2 KSH libc_cv_have_ksh AWK PERL INSTALL_INFO OLD_DEBIAN_INSTALL_INFO BISON VERSIONING libc_cv_asm_protected_directive libc_cv_initfinit_array libc_cv_z_nodelete libc_cv_z_nodlopen libc_cv_z_initfirst libc_cv_Bgroup libc_cv_z_combreloc libc_cv_have_initfini no_whole_archive exceptions LIBGD EGREP sizeof_long_double libc_cv_gcc_unwind_find_fde uname_sysname uname_release uname_version old_glibc_headers libc_cv_slibdir libc_cv_localedir libc_cv_sysconfdir libc_cv_rootsbindir use_ldconfig ldd_rewrite_script gnu_ld gnu_as elf xcoff static shared pic_default profile omitfp bounded static_nss nopic_initfini DEFINES linux_doors mach_interface_list VERSION RELEASE LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS with_fp with_cvs oldest_abi subdirs force_install all_warnings build build_cpu build_vendor build_os host host_cpu host_vendor host_os base_machine sysnames INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S PWD_P CC MAKE MSGFMT MAKEINFO SED AUTOCONF CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT BUILD_CC cross_compiling CPP AR OBJDUMP RANLIB ac_ct_RANLIB MIG AS LD CCVERSION SYSINCLUDES libc_cv_gcc_static_libgcc BASH libc_cv_have_bash2 KSH libc_cv_have_ksh AWK PERL INSTALL_INFO OLD_DEBIAN_INSTALL_INFO BISON VERSIONING libc_cv_asm_protected_directive libc_cv_initfinit_array libc_cv_z_nodelete libc_cv_z_nodlopen libc_cv_z_initfirst libc_cv_Bgroup libc_cv_z_combreloc libc_cv_have_initfini no_whole_archive exceptions LIBGD EGREP sizeof_long_double libc_cv_gcc_unwind_find_fde uname_sysname uname_release uname_version old_glibc_headers libc_cv_slibdir libc_cv_localedir libc_cv_sysconfdir libc_cv_rootsbindir use_ldconfig ldd_rewrite_script gnu_ld gnu_as elf xcoff static shared pic_default profile omitfp bounded static_nss nopic_initfini DEFINES linux_doors mach_interface_list VERSION RELEASE LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -3500,6 +3500,8 @@ AS=`$CC -print-prog-name=as` LD=`$CC -print-prog-name=ld` AR=`$CC -print-prog-name=ar` +OBJDUMP=`$CC -print-prog-name=objdump` + # ranlib has to be treated a bit differently since it might not exist at all. ac_ranlib=`$CC -print-prog-name=ranlib` @@ -5001,7 +5003,7 @@ if test "${libc_cv_asm_underscores+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat > conftest.$ac_ext <&6 else cat > conftest.c <&6 else cat > conftest.c <&6 else cat > conftest.c <size] != MAGICBYTE) status = MCHECK_TAIL; + else if ((hdr->magic2 ^ (uintptr_t) hdr->block) != MAGICWORD) + status = MCHECK_HEAD; else status = MCHECK_OK; break; @@ -190,10 +197,11 @@ freehook (ptr, caller) struct hdr *hdr = ((struct hdr *) ptr) - 1; checkhdr (hdr); hdr->magic = MAGICFREE; + hdr->magic2 = MAGICFREE; unlink_blk (hdr); hdr->prev = hdr->next = NULL; flood (ptr, FREEFLOOD, hdr->size); - ptr = (__ptr_t) hdr; + ptr = hdr->block; } __free_hook = old_free_hook; if (old_free_hook != NULL) @@ -226,6 +234,44 @@ mallochook (size, caller) hdr->size = size; link_blk (hdr); + hdr->block = hdr; + hdr->magic2 = (uintptr_t) hdr ^ MAGICWORD; + ((char *) &hdr[1])[size] = MAGICBYTE; + flood ((__ptr_t) (hdr + 1), MALLOCFLOOD, size); + return (__ptr_t) (hdr + 1); +} + +static __ptr_t memalignhook __P ((__malloc_size_t, __malloc_size_t, + const __ptr_t)); +static __ptr_t +memalignhook (alignment, size, caller) + __malloc_size_t alignment, size; + const __ptr_t caller; +{ + struct hdr *hdr; + __malloc_size_t slop; + char *block; + + if (pedantic) + mcheck_check_all (); + + slop = (sizeof *hdr + alignment - 1) & -alignment; + + __memalign_hook = old_memalign_hook; + if (old_memalign_hook != NULL) + block = (*old_memalign_hook) (alignment, slop + size + 1, caller); + else + block = memalign (alignment, slop + size + 1); + __memalign_hook = memalignhook; + if (block == NULL) + return NULL; + + hdr = ((struct hdr *) (block + slop)) - 1; + + hdr->size = size; + link_blk (hdr); + hdr->block = (__ptr_t) block; + hdr->magic2 = (uintptr_t) block ^ MAGICWORD; ((char *) &hdr[1])[size] = MAGICBYTE; flood ((__ptr_t) (hdr + 1), MALLOCFLOOD, size); return (__ptr_t) (hdr + 1); @@ -261,6 +307,7 @@ reallochook (ptr, size, caller) } __free_hook = old_free_hook; __malloc_hook = old_malloc_hook; + __memalign_hook = old_memalign_hook; __realloc_hook = old_realloc_hook; if (old_realloc_hook != NULL) hdr = (struct hdr *) (*old_realloc_hook) ((__ptr_t) hdr, @@ -271,12 +318,15 @@ reallochook (ptr, size, caller) sizeof (struct hdr) + size + 1); __free_hook = freehook; __malloc_hook = mallochook; + __memalign_hook = memalignhook; __realloc_hook = reallochook; if (hdr == NULL) return NULL; hdr->size = size; link_blk (hdr); + hdr->block = hdr; + hdr->magic2 = (uintptr_t) hdr ^ MAGICWORD; ((char *) &hdr[1])[size] = MAGICBYTE; if (size > osize) flood ((char *) (hdr + 1) + osize, MALLOCFLOOD, size - osize); @@ -334,6 +384,8 @@ mcheck (func) __free_hook = freehook; old_malloc_hook = __malloc_hook; __malloc_hook = mallochook; + old_memalign_hook = __memalign_hook; + __memalign_hook = memalignhook; old_realloc_hook = __realloc_hook; __realloc_hook = reallochook; mcheck_used = 1; diff --git a/scripts/abilist.awk b/scripts/abilist.awk new file mode 100644 index 0000000000..385e85da80 --- /dev/null +++ b/scripts/abilist.awk @@ -0,0 +1,49 @@ +# This awk script processes the output of objdump --dynamic-syms +# into a simple format that should not change when the ABI is not changing. + +BEGIN { outpipe = "sort" } + +# Normalize columns. +/^[0-9a-fA-F]+ / { sub(/ /, " - ") } + +# Skip undefineds. +$4 == "*UND*" { next } + +# Skip locals. +$2 == "l" { next } + +$2 == "g" || $2 == "w" && NF == 7 { + weak = ($2 == "w") ? "weak" : "strong"; + type = $3; + size = strtonum("0x" $5); + version = $6; + symbol = $7; + gsub(/[()]/, "", version); + + if (version == "GLIBC_PRIVATE") next; + + if (type == "D" && $4 == ".tbss") { + print symbol, version, weak, "TLS", size | outpipe; + } + else if (type == "DO" && $4 == "*ABS*") { + print symbol, version, weak, "ABS" | outpipe; + } + else if (type == "DO") { + print symbol, version, weak, "DATA", size | outpipe; + } + else if (type == "DF") { + print symbol, version, weak, "FUNC" | outpipe; + } + else { + print symbol, version, weak, "UNEXPECTED", type, $4, $5; + } + + next; +} + +# Header crapola. +NF == 0 || /DYNAMIC SYMBOL TABLE/ || /file format/ { next } + +{ + print "Don't grok this line:", $0 +}