+1997-09-27 01:14 Ulrich Drepper <drepper@cygnus.com>
+
+ * Makeconfig (extra-objs): Depend in before-compile.
+
+ * configure.in: Locate Perl and substitute with complete path.
+ * config.make.in: Add PERL for substitution.
+ * elf/Makefile (routines): Add dl-addr.
+ * elf/dladdr.c: Move the real code into ...
+ * elf/dl-addr.c: New file.
+ * elf/link.h: Add prototype for _dl_addr.
+
+ * elf/dladdr.c (dladdr): Change address argument to be const.
+ * elf/dlfcn.h: Likewise.
+
+ * locale/C_name.c: Add _nl_POSIX_name.
+ * locale/localeinfo.h: Add declaration of _nl_POSIX_name.
+ * locale/findlocale.c (_nl_find_locale): Use _nl_POSIX_name.
+ (_nl_remove_locale): Free name of data set.
+ * locale/setlocale.c (clever_copy): Remove.
+ (new_composite_name): Use _nl_C_name and _nl_POSIX_name in compare.
+ (setname): Only remove old name when it is for category LC_ALL.
+
+ Change malloc, free, realloc, and memalign hooks for glibc to take
+ another parameter indicating the location of the caller.
+ * malloc/malloc.c: Change hook functions and variables.
+ * malloc/malloc.h: Likewise.
+ * malloc/mcheck.c: Likewise. Make sure later hooked function also
+ get the original caller address.
+ * malloc/mtrace.c: Likewise.
+ (tr_where): If no information in _mtrace_file is given use the
+ information about the caller.
+ * malloc/Makefile (distribute): Replace mtrace.awk by mtrace.pl.
+ Add rules to install mtrace.pl after rewriting.
+ * malloc/mtrace.pl: New file. Based on the old AWK script but
+ with extended functionality.
+ * malloc/mtrace.awk: Removed.
+
+ * po/fr.po: New version.
+
+ * string/Makefile: Do use builtins for tester.c and inl-tester.c.
+ * string/tester.c: Rewrite. Split in many small functions to not
+ exceed gcc's limits.
+
+ * sysdeps/unix/sysv/linux/syscalls.list: Add prctl.
+
+1997-09-25 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * string/bits/string2.h (__stpcpy_small): Don't use casts as
+ lvalues.
+
+1997-09-26 Andreas Jaeger <aj@arthur.rhein-neckar.de>
+
+ * manual/time.texi (Formatting Date and Time): Clarify
+ explanation of strftime flags a bit.
+ Suggested by Robert Bihlmeyer <robbe@orcus.priv.at>.
+
+1997-09-25 00:13 David S. Miller <davem@tanya.rutgers.edu>
+
+ * sysdeps/libm-ieee754/s_exp2f.c: Protect _GNU_SOURCE definition.
+ Fix typo, it is FLT_MANT_DIG.
+
+1997-09-24 18:52 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * math/atest-exp2.c: Include <stdlib/gmp.h> instead of <gmp.h>.
+
+1997-08-27 08:10 H.J. Lu <hjl@gnu.ai.mit.edu>
+
+ * libio/libio.h, libio/libioP.h: Support libio in libstdc++.
+
+ * libio/libio.h (_IO_peekc): Defined as _IO_peekc_unlocked if
+ _IO_MTSAFE_IO is undefined.
+
+1997-09-24 23:27 Richard Henderson <rth@cygnus.com>
+
+ * elf/dl-runtime.c (fixup): Don't go through elf_machine_relplt, but
+ lookup the value of the target symbol ourselves and call the new
+ elf_machine_fixup_plt. This kills the ELF_FIXUP_RETURN_VALUE hack.
+ (profile_fixup): Likewise, but don't fix up the plt.
+ * elf/rtld.c (_dl_main): ELF_MACHINE_RELOC_NOPLT renamed _JMP_SLOT.
+ * sysdeps/alpha/dl-machine.h (ELF_MACHINE_RELOC_NOPLT): Renamed.
+ (elf_alpha_fix_plt): Renamed elf_machine_fixup_plt.
+ * sysdeps/i386/dl-machine.h (elf_machine_relplt): Killed.
+ (ELF_MACHINE_JMP_SLOT): Renamed.
+ (elf_machine_fixup_plt): New function.
+ * sysdeps/m68k/dl-machine.h: Likewise.
+ * sysdeps/powerpc/dl-machine.h: Likewise.
+ (elf_machine_rela): Moved JMP_SLOT fixup out to elf_machine_fixup_plt.
+ * sysdeps/sparc/sparc32/dl-machine.h: Likewise.
+ * sysdeps/sparc/sparc64/dl-machine.h: Likewise.
+ * sysdeps/stub/dl-machine.h: Update, sorta.
+
+ * sysdeps/alpha/dl-machine.h (elf_machine_runtime_setup): Do profiling.
+ (TRAMPOLINE_TEMPLATE): From the carcas of _RUNTIME_TRAMPOLINE, do
+ both normal and profile code.
+ (elf_machine_rela): Handle r_addend for .got and .plt too.
+
1997-09-25 00:23 Ulrich Drepper <drepper@cygnus.com>
* elf/dl-profile.c: Correct implementation.
[Q24] ``I have set up /etc/nis.conf, and the Linux libc 5 with NYS
works great. But the glibc NIS+ doesn't seem to work.''
+
+[Q25] ``After installing glibc name resolving doesn't work properly.''
+
\f
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
[Q1] ``What systems does the GNU C Library run on?''
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+[Q25] ``After installing glibc name resolving doesn't work properly.''
+
+[A25] {AJ} You probable should read the manual section describing
+``nsswitch.conf'' (just type `info libc "NSS Configuration File"').
+The NSS configuration file is usually the culprit.
+
+
+~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
\f
Answers were given by:
{UD} Ulrich Drepper, <drepper@cygnus.com>
$(do-install-program)
endif
+ifdef extra-objs
+$(addprefix $(objpfx),$(extra-objs)): $(before-compile)
+endif
ifneq (,$(versioned))
# Produce three sets of rules as above for all the smaller versioned libraries.
INSTALL_DATA = @INSTALL_DATA@
LN_S = @LN_S@
MSGFMT = @MSGFMT@
+
+# Script execution tools.
BASH = @BASH@
KSH = @KSH@
+PERL = @PERL@
# More variables may be inserted below by configure.
fi
+for ac_prog in perl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1691: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$PERL" in
+ /*)
+ ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_PERL="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+PERL="$ac_cv_path_PERL"
+if test -n "$PERL"; then
+ echo "$ac_t""$PERL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$PERL" && break
+done
+test -n "$PERL" || PERL="no"
+
+
+
echo $ac_n "checking for signed size_t type""... $ac_c" 1>&6
-echo "configure:1687: checking for signed size_t type" >&5
+echo "configure:1726: checking for signed size_t type" >&5
if eval "test \"`echo '$''{'libc_cv_signed_size_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
fi
echo $ac_n "checking for libc-friendly stddef.h""... $ac_c" 1>&6
-echo "configure:1711: checking for libc-friendly stddef.h" >&5
+echo "configure:1750: checking for libc-friendly stddef.h" >&5
if eval "test \"`echo '$''{'libc_cv_friendly_stddef'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1716 "configure"
+#line 1755 "configure"
#include "confdefs.h"
#define __need_size_t
#define __need_wchar_t
if (&size == NULL || &wchar == NULL) abort ();
; return 0; }
EOF
-if { (eval echo configure:1731: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1770: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
libc_cv_friendly_stddef=yes
else
fi
echo $ac_n "checking whether we need to use -P to assemble .S files""... $ac_c" 1>&6
-echo "configure:1750: checking whether we need to use -P to assemble .S files" >&5
+echo "configure:1789: checking whether we need to use -P to assemble .S files" >&5
if eval "test \"`echo '$''{'libc_cv_need_minus_P'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
fi
echo $ac_n "checking for assembler global-symbol directive""... $ac_c" 1>&6
-echo "configure:1773: checking for assembler global-symbol directive" >&5
+echo "configure:1812: checking for assembler global-symbol directive" >&5
if eval "test \"`echo '$''{'libc_cv_asm_global_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
fi
echo $ac_n "checking for .set assembler directive""... $ac_c" 1>&6
-echo "configure:1803: checking for .set assembler directive" >&5
+echo "configure:1842: checking for .set assembler directive" >&5
if eval "test \"`echo '$''{'libc_cv_asm_set_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
fi
echo $ac_n "checking for .symver assembler directive""... $ac_c" 1>&6
-echo "configure:1837: checking for .symver assembler directive" >&5
+echo "configure:1876: checking for .symver assembler directive" >&5
if eval "test \"`echo '$''{'libc_cv_asm_symver_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
echo "$ac_t""$libc_cv_asm_symver_directive" 1>&6
echo $ac_n "checking for ld --version-script""... $ac_c" 1>&6
-echo "configure:1856: checking for ld --version-script" >&5
+echo "configure:1895: checking for ld --version-script" >&5
if eval "test \"`echo '$''{'libc_cv_ld_version_script_option'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if { ac_try='${CC-cc} $CFLAGS -shared -o conftest.so conftest.o
-nostartfiles -nostdlib
-Wl,--version-script,conftest.map
- 1>&5'; { (eval echo configure:1875: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
+ 1>&5'; { (eval echo configure:1914: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
then
libc_cv_ld_version_script_option=yes
else
if test $elf = yes; then
echo $ac_n "checking for .previous assembler directive""... $ac_c" 1>&6
-echo "configure:1906: checking for .previous assembler directive" >&5
+echo "configure:1945: checking for .previous assembler directive" >&5
if eval "test \"`echo '$''{'libc_cv_asm_previous_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
.section foo_section
.previous
EOF
- if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1914: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+ if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1953: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
libc_cv_asm_previous_directive=yes
else
libc_cv_asm_previous_directive=no
else
echo $ac_n "checking for .popsection assembler directive""... $ac_c" 1>&6
-echo "configure:1930: checking for .popsection assembler directive" >&5
+echo "configure:1969: checking for .popsection assembler directive" >&5
if eval "test \"`echo '$''{'libc_cv_asm_popsection_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
.pushsection foo_section
.popsection
EOF
- if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1938: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+ if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1977: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
libc_cv_asm_popsection_directive=yes
else
libc_cv_asm_popsection_directive=no
if test $elf != yes; then
echo $ac_n "checking for .init and .fini sections""... $ac_c" 1>&6
-echo "configure:1958: checking for .init and .fini sections" >&5
+echo "configure:1997: checking for .init and .fini sections" >&5
if eval "test \"`echo '$''{'libc_cv_have_initfini'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1963 "configure"
+#line 2002 "configure"
#include "confdefs.h"
int main() {
asm (".text");
; return 0; }
EOF
-if { (eval echo configure:1972: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2011: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
libc_cv_have_initfini=yes
else
else
if test $ac_cv_prog_cc_works = yes; then
echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
-echo "configure:2000: checking for _ prefix on C symbol names" >&5
+echo "configure:2039: checking for _ prefix on C symbol names" >&5
if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2005 "configure"
+#line 2044 "configure"
#include "confdefs.h"
asm ("_glibc_foobar:");
int main() {
glibc_foobar ();
; return 0; }
EOF
-if { (eval echo configure:2012: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2051: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
libc_cv_asm_underscores=yes
else
echo "$ac_t""$libc_cv_asm_underscores" 1>&6
else
echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
-echo "configure:2027: checking for _ prefix on C symbol names" >&5
+echo "configure:2066: checking for _ prefix on C symbol names" >&5
if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2032 "configure"
+#line 2071 "configure"
#include "confdefs.h"
void underscore_test(void) {
return; }
EOF
-if { (eval echo configure:2037: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2076: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if grep _underscore_test conftest* >/dev/null; then
rm -f conftest*
libc_cv_asm_underscores=yes
libc_cv_asm_weakext_directive=no
else
echo $ac_n "checking for assembler .weak directive""... $ac_c" 1>&6
-echo "configure:2070: checking for assembler .weak directive" >&5
+echo "configure:2109: checking for assembler .weak directive" >&5
if eval "test \"`echo '$''{'libc_cv_asm_weak_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test $libc_cv_asm_weak_directive = no; then
echo $ac_n "checking for assembler .weakext directive""... $ac_c" 1>&6
-echo "configure:2093: checking for assembler .weakext directive" >&5
+echo "configure:2132: checking for assembler .weakext directive" >&5
if eval "test \"`echo '$''{'libc_cv_asm_weakext_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
fi
echo $ac_n "checking for ld --no-whole-archive""... $ac_c" 1>&6
-echo "configure:2130: checking for ld --no-whole-archive" >&5
+echo "configure:2169: checking for ld --no-whole-archive" >&5
if eval "test \"`echo '$''{'libc_cv_ld_no_whole_archive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
EOF
if { ac_try='${CC-cc} $CFLAGS
-nostdlib -nostartfiles -Wl,--no-whole-archive
- -o conftest conftest.c 1>&5'; { (eval echo configure:2141: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+ -o conftest conftest.c 1>&5'; { (eval echo configure:2180: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
libc_cv_ld_no_whole_archive=yes
else
libc_cv_ld_no_whole_archive=no
echo "$ac_t""$libc_cv_ld_no_whole_archive" 1>&6
echo $ac_n "checking for gcc -fno-exceptions""... $ac_c" 1>&6
-echo "configure:2152: checking for gcc -fno-exceptions" >&5
+echo "configure:2191: checking for gcc -fno-exceptions" >&5
if eval "test \"`echo '$''{'libc_cv_gcc_no_exceptions'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
EOF
if { ac_try='${CC-cc} $CFLAGS
-nostdlib -nostartfiles -fno-exceptions
- -o conftest conftest.c 1>&5'; { (eval echo configure:2163: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+ -o conftest conftest.c 1>&5'; { (eval echo configure:2202: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
libc_cv_gcc_no_exceptions=yes
else
libc_cv_gcc_no_exceptions=no
echo "$ac_t""$libc_cv_gcc_no_exceptions" 1>&6
echo $ac_n "checking for DWARF2 unwind info support""... $ac_c" 1>&6
-echo "configure:2174: checking for DWARF2 unwind info support" >&5
+echo "configure:2213: checking for DWARF2 unwind info support" >&5
if eval "test \"`echo '$''{'libc_cv_gcc_dwarf2_unwind_info'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.c <<EOF
-#line 2179 "configure"
+#line 2218 "configure"
static char __EH_FRAME_BEGIN__;
_start ()
{
EOF
if { ac_try='${CC-cc} $CFLAGS
-nostdlib -nostartfiles
- -o conftest conftest.c -lgcc >&5'; { (eval echo configure:2199: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+ -o conftest conftest.c -lgcc >&5'; { (eval echo configure:2238: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
libc_cv_gcc_dwarf2_unwind_info=yes
else
libc_cv_gcc_dwarf2_unwind_info=no
fi
echo $ac_n "checking OS release for uname""... $ac_c" 1>&6
-echo "configure:2257: checking OS release for uname" >&5
+echo "configure:2296: checking OS release for uname" >&5
if eval "test \"`echo '$''{'libc_cv_uname_release'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
uname_release="$libc_cv_uname_release"
echo $ac_n "checking OS version for uname""... $ac_c" 1>&6
-echo "configure:2279: checking OS version for uname" >&5
+echo "configure:2318: checking OS version for uname" >&5
if eval "test \"`echo '$''{'libc_cv_uname_version'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
fi
echo $ac_n "checking stdio selection""... $ac_c" 1>&6
-echo "configure:2301: checking stdio selection" >&5
+echo "configure:2340: checking stdio selection" >&5
case $stdio in
libio) cat >> confdefs.h <<\EOF
echo "$ac_t""$stdio" 1>&6
echo $ac_n "checking ldap selection""... $ac_c" 1>&6
-echo "configure:2313: checking ldap selection" >&5
+echo "configure:2352: checking ldap selection" >&5
case $add_ons in
*ldap*)
s%@libc_cv_have_bash2@%$libc_cv_have_bash2%g
s%@KSH@%$KSH%g
s%@libc_cv_have_ksh@%$libc_cv_have_ksh%g
+s%@PERL@%$PERL%g
s%@VERSIONING@%$VERSIONING%g
s%@libc_cv_have_initfini@%$libc_cv_have_initfini%g
s%@libc_cv_ld_no_whole_archive@%$libc_cv_ld_no_whole_archive%g
fi
AC_SUBST(libc_cv_have_ksh)
+AC_PATH_PROGS(PERL, perl, no)
+AC_SUBST(PERL)
+
AC_CACHE_CHECK(for signed size_t type, libc_cv_signed_size_t, [dnl
echo '#include <stddef.h>
FOOBAR __SIZE_TYPE__ FOOBAR' > conftest.c
headers = elf.h bits/elfclass.h bits/dlfcn.h link.h dlfcn.h
routines = $(dl-routines) dl-open dl-close dl-symbol dl-support \
- enbl-secure
+ dl-addr enbl-secure
# The core dynamic linking functions are in libc for the static and
# profiled libraries.
--- /dev/null
+/* Locate the shared object symbol nearest a given address.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stddef.h>
+#include <link.h>
+#include <dlfcn.h>
+
+
+int
+_dl_addr (const void *address, Dl_info *info)
+{
+ const ElfW(Addr) addr = (ElfW(Addr)) address;
+ struct link_map *l, *match;
+ const ElfW(Sym) *symtab, *matchsym;
+ const char *strtab;
+
+ /* Find the highest-addressed object that ADDRESS is not below. */
+ match = NULL;
+ for (l = _dl_loaded; l; l = l->l_next)
+ if (addr >= l->l_addr && !match || match->l_addr < l->l_addr)
+ match = l;
+
+ if (match)
+ {
+ /* We know ADDRESS lies within MATCH if in any shared object.
+ Make sure it isn't past the end of MATCH's segments. */
+ size_t n = match->l_phnum;
+ do
+ --n;
+ while (match->l_phdr[n].p_type != PT_LOAD);
+ if (addr >= (match->l_addr +
+ match->l_phdr[n].p_vaddr + match->l_phdr[n].p_memsz))
+ /* Off the end of the highest-addressed shared object. */
+ return 0;
+ }
+ else
+ return 0;
+
+ /* Now we know what object the address lies in. */
+ info->dli_fname = match->l_name;
+ info->dli_fbase = (void *) match->l_addr;
+
+ symtab = ((void *) match->l_addr + match->l_info[DT_SYMTAB]->d_un.d_ptr);
+ strtab = ((void *) match->l_addr + match->l_info[DT_STRTAB]->d_un.d_ptr);
+
+ /* We assume that the string table follows the symbol table, because
+ there is no way in ELF to know the size of the dynamic symbol table!! */
+ for (matchsym = NULL; (void *) symtab < (void *) strtab; ++symtab)
+ if (addr >= match->l_addr + symtab->st_value && !matchsym ||
+ matchsym->st_value < symtab->st_value &&
+ ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL ||
+ ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
+ matchsym = symtab;
+
+ if (matchsym)
+ {
+ /* We found a symbol close by. Fill in its name and exact address. */
+ info->dli_sname = strtab + matchsym->st_name;
+ info->dli_saddr = (void *) (match->l_addr + matchsym->st_value);
+ }
+ else
+ {
+ /* No symbol matches. We return only the containing object. */
+ info->dli_sname = NULL;
+ info->dli_saddr = NULL;
+ }
+
+ return 1;
+}
\f
#include "dynamic-link.h"
-/* Figure out the right type, Rel or Rela. */
-#define elf_machine_rel 1
-#define elf_machine_rela 2
-#if elf_machine_relplt == elf_machine_rel
-# define PLTREL ElfW(Rel)
-#elif elf_machine_relplt == elf_machine_rela
-# define PLTREL ElfW(Rela)
+#if !defined ELF_MACHINE_NO_RELA || ELF_MACHINE_NO_REL
+# define PLTREL ElfW(Rela)
#else
-# error "dl-machine.h bug: elf_machine_relplt not rel or rela"
+# define PLTREL ElfW(Rel)
#endif
-#undef elf_machine_rel
-#undef elf_machine_rela
#ifndef VERSYMIDX
# define VERSYMIDX(sym) (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (sym))
#endif
-#ifndef ELF_FIXUP_RETURN_VALUE
-#define ELF_FIXUP_RETURN_VALUE(map, result) (result)
-#endif
-
-/* We need to define the function as a local symbol so that the reference
- in the trampoline code will be a local PC-relative call. Tell the
- compiler not to worry that the function appears not to be called. */
-
-static ElfW(Addr) fixup (
-#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
- ELF_MACHINE_RUNTIME_FIXUP_ARGS,
-#endif
- struct link_map *l, ElfW(Word) reloc_offset)
- __attribute__ ((unused));
/* This function is called through a special trampoline from the PLT the
first time each PLT entry is called. We must perform the relocation
to that address. Future calls will bounce directly from the PLT to the
function. */
-static ElfW(Addr)
+static ElfW(Addr) __attribute__ ((unused))
fixup (
#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
const PLTREL *const reloc
= (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
reloc_offset);
- ElfW(Addr) *const rel_addr = (ElfW(Addr) *)(l->l_addr + reloc->r_offset);
+ const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
+ void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
+ ElfW(Addr) value;
/* Set up the scope to find symbols referenced by this object. */
struct link_map **scope = _dl_object_relocation_scope (l);
- {
- const struct r_found_version *here_version;
-
- /* This macro is used as a callback from the elf_machine_relplt code. */
-#define RESOLVE(ref, version, flags) \
- ((version) != NULL && (version)->hash != 0 \
- ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, (ref), scope, \
- l->l_name, (version), (flags)) \
- : _dl_lookup_symbol (strtab + (*ref)->st_name, (ref), scope, \
- l->l_name, (flags)))
-#include "dynamic-link.h"
+ /* Sanity check that we're really looking at a PLT relocation. */
+ assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
- /* Perform the specified relocation. */
- if (l->l_info[VERSYMIDX (DT_VERSYM)])
+ /* Look up the target symbol. */
+ switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+ {
+ default:
{
- const ElfW(Half) *version =
- (const ElfW(Half) *) (l->l_addr +
- l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
- ElfW(Half) ndx = version[ELFW(R_SYM) (reloc->r_info)];
-
- here_version = &l->l_versions[ndx];
+ const ElfW(Half) *vernum = (const ElfW(Half) *)
+ (l->l_addr + l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
+ ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
+ const struct r_found_version *version = &l->l_versions[ndx];
+
+ if (version->hash != 0)
+ {
+ value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
+ &sym, scope, l->l_name,
+ version, ELF_MACHINE_JMP_SLOT);
+ break;
+ }
}
- else
- here_version = NULL;
+ case 0:
+ value = _dl_lookup_symbol (strtab + sym->st_name, &sym, scope,
+ l->l_name, ELF_MACHINE_JMP_SLOT);
+ }
+
+ /* Currently value contains the base load address of the object
+ that defines sym. Now add in the symbol offset. */
+ value = (sym ? value + sym->st_value : 0);
+
+ /* And now the relocation addend. */
+#ifndef ELF_MACHINE_NO_RELA
+ if (l->l_info[DT_PLTRELSZ]->d_un.d_val == sizeof (ElfW(Rela)))
+ value += reloc->r_addend;
+#elif ELF_MACHINE_NO_REL
+ value += reloc->r_addend;
+#endif
- elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
- here_version, (void *) rel_addr);
- }
+ /* Finally, fix up the plt itself. */
+ elf_machine_fixup_plt (l, reloc, rel_addr, value);
*_dl_global_scope_end = NULL;
- /* Return the address that was written by the relocation. */
- return ELF_FIXUP_RETURN_VALUE(l, *rel_addr);
+ return value;
}
#ifndef PROF
-static ElfW(Addr)
-profile_fixup (
-#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
- ELF_MACHINE_RUNTIME_FIXUP_ARGS,
-#endif
- struct link_map *l, ElfW(Word) reloc_offset, ElfW(Addr) retaddr)
- __attribute__ ((unused));
-static ElfW(Addr)
+static ElfW(Addr) __attribute__ ((unused))
profile_fixup (
#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
struct link_map *l, ElfW(Word) reloc_offset, ElfW(Addr) retaddr)
{
void (*mcount_fct) (ElfW(Addr), ElfW(Addr)) = _dl_mcount;
+
const ElfW(Sym) *const symtab
= (const ElfW(Sym) *) (l->l_addr + l->l_info[DT_SYMTAB]->d_un.d_ptr);
const char *strtab =
const PLTREL *const reloc
= (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
reloc_offset);
- ElfW(Addr) result;
+ const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
+ ElfW(Addr) value;
/* Set up the scope to find symbols referenced by this object. */
struct link_map **scope = _dl_object_relocation_scope (l);
- {
- const struct r_found_version *here_version;
+ /* Sanity check that we're really looking at a PLT relocation. */
+ assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);
- /* This macro is used as a callback from the elf_machine_relplt code. */
-#define RESOLVE(ref, version, flags) \
- ((version) != NULL && (version)->hash != 0 \
- ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, (ref), scope, \
- l->l_name, (version), (flags)) \
- : _dl_lookup_symbol (strtab + (*ref)->st_name, (ref), scope, \
- l->l_name, (flags)))
-#include "dynamic-link.h"
-
- /* Perform the specified relocation. */
- if (l->l_info[VERSYMIDX (DT_VERSYM)])
+ /* Look up the target symbol. */
+ switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+ {
+ default:
{
- const ElfW(Half) *version =
- (const ElfW(Half) *) (l->l_addr +
- l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
- ElfW(Half) ndx = version[ELFW(R_SYM) (reloc->r_info)];
-
- here_version = &l->l_versions[ndx];
+ const ElfW(Half) *vernum = (const ElfW(Half) *)
+ (l->l_addr + l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr);
+ ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
+ const struct r_found_version *version = &l->l_versions[ndx];
+
+ if (version->hash != 0)
+ {
+ value = _dl_lookup_versioned_symbol(strtab + sym->st_name,
+ &sym, scope, l->l_name,
+ version, ELF_MACHINE_JMP_SLOT);
+ break;
+ }
}
- else
- here_version = NULL;
+ case 0:
+ value = _dl_lookup_symbol (strtab + sym->st_name, &sym, scope,
+ l->l_name, ELF_MACHINE_JMP_SLOT);
+ }
+
+ /* Currently value contains the base load address of the object
+ that defines sym. Now add in the symbol offset. */
+ value = (sym ? value + sym->st_value : 0);
- elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)],
- here_version, (void *) &result);
- }
+ /* And now the relocation addend. */
+#ifndef ELF_MACHINE_NO_RELA
+ if (l->l_info[DT_PLTRELSZ]->d_un.d_val == sizeof (ElfW(Rela)))
+ value += reloc->r_addend;
+#elif ELF_MACHINE_NO_REL
+ value += reloc->r_addend;
+#endif
*_dl_global_scope_end = NULL;
- (*mcount_fct) (retaddr, ELF_FIXUP_RETURN_VALUE (l, result));
+ (*mcount_fct) (retaddr, value);
- /* Return the address that was written by the relocation. */
- return ELF_FIXUP_RETURN_VALUE (l, result);
+ return value;
}
-#endif
+
+#endif /* PROF */
/* This macro is defined in dl-machine.h to define the entry point called
-/* dladdr -- Locate the shared object symbol nearest a given address.
- Copyright (C) 1996 Free Software Foundation, Inc.
+/* Locate the shared object symbol nearest a given address.
+ Copyright (C) 1996, 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
int
-dladdr (void *address, Dl_info *info)
+dladdr (const void *address, Dl_info *info)
{
- const ElfW(Addr) addr = (ElfW(Addr)) address;
- struct link_map *l, *match;
- const ElfW(Sym) *symtab, *matchsym;
- const char *strtab;
-
- /* Find the highest-addressed object that ADDRESS is not below. */
- match = NULL;
- for (l = _dl_loaded; l; l = l->l_next)
- if (addr >= l->l_addr && !match || match->l_addr < l->l_addr)
- match = l;
-
- if (match)
- {
- /* We know ADDRESS lies within MATCH if in any shared object.
- Make sure it isn't past the end of MATCH's segments. */
- size_t n = match->l_phnum;
- do
- --n;
- while (match->l_phdr[n].p_type != PT_LOAD);
- if (addr >= (match->l_addr +
- match->l_phdr[n].p_vaddr + match->l_phdr[n].p_memsz))
- /* Off the end of the highest-addressed shared object. */
- return 0;
- }
- else
- return 0;
-
- /* Now we know what object the address lies in. */
- info->dli_fname = match->l_name;
- info->dli_fbase = (void *) match->l_addr;
-
- symtab = ((void *) match->l_addr + match->l_info[DT_SYMTAB]->d_un.d_ptr);
- strtab = ((void *) match->l_addr + match->l_info[DT_STRTAB]->d_un.d_ptr);
-
- /* We assume that the string table follows the symbol table, because
- there is no way in ELF to know the size of the dynamic symbol table!! */
- for (matchsym = NULL; (void *) symtab < (void *) strtab; ++symtab)
- if (addr >= match->l_addr + symtab->st_value && !matchsym ||
- matchsym->st_value < symtab->st_value &&
- ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL ||
- ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
- matchsym = symtab;
-
- if (matchsym)
- {
- /* We found a symbol close by. Fill in its name and exact address. */
- info->dli_sname = strtab + matchsym->st_name;
- info->dli_saddr = (void *) (match->l_addr + matchsym->st_value);
- }
- else
- {
- /* No symbol matches. We return only the containing object. */
- info->dli_sname = NULL;
- info->dli_saddr = NULL;
- }
-
- return 1;
+ return _dl_addr (address, info);
}
__const char *dli_sname; /* Name of nearest symbol. */
void *dli_saddr; /* Exact value of nearest symbol. */
} Dl_info;
-extern int dladdr __P ((void *__address, Dl_info *__info));
+extern int dladdr __P ((const void *__address, Dl_info *__info));
__END_DECLS
#include <stddef.h>
#include <elf.h>
+#include <dlfcn.h>
__BEGIN_DECLS
const struct r_found_version *version,
struct link_map *skip_this);
+/* Locate shared object containing the given address. */
+extern int _dl_addr (const void *address, Dl_info *info);
+
/* Look up symbol NAME in MAP's scope and return its run-time address. */
extern ElfW(Addr) _dl_symbol_value (struct link_map *map, const char *name);
ElfW(Addr) loadbase = _dl_lookup_symbol (_dl_argv[i], &ref,
&_dl_default_scope[2],
"argument",
- ELF_MACHINE_RELOC_NOPLT);
+ ELF_MACHINE_JMP_SLOT);
char buf[20], *bp;
buf[sizeof buf - 1] = '\0';
bp = _itoa (ref->st_value, &buf[sizeof buf - 1], 16, 0);
#ifndef _IO_STDIO_H
#define _IO_STDIO_H
-#include <features.h>
#include <_G_config.h>
#define _IO_pos_t _G_fpos_t /* obsolete */
# define _IO_USE_DTOA 1
#endif
-#if 0
-# ifdef _IO_NEED_STDARG_H
-# include <stdarg.h>
-# endif
-#endif
-
#ifndef EOF
# define EOF (-1)
#endif
/* Handle lock. */
#ifdef _IO_MTSAFE_IO
-# include <bits/stdio-lock.h>
+# if defined __GLIBC__ && __GLIBC__ >= 2
+# include <bits/stdio-lock.h>
+# else
+/*# include <comthread.h>*/
+# endif
#else
typedef void _IO_lock_t;
#endif
extern void _IO_funlockfile __P ((_IO_FILE *));
extern int _IO_ftrylockfile __P ((_IO_FILE *));
-#ifndef _IO_MTSAFE_IO
+#ifdef _IO_MTSAFE_IO
+# define _IO_peekc(_fp) _IO_peekc_locked (_fp)
+#else
+# define _IO_peekc(_fp) _IO_peekc_unlocked (_fp)
# define _IO_flockfile(_fp) /**/
# define _IO_funlockfile(_fp) /**/
# define _IO_ftrylockfile(_fp) /**/
# define _IO_cleanup_region_end(_Doit) /**/
#endif /* !_IO_MTSAFE_IO */
-#define _IO_peekc(_fp) _IO_peekc_locked (_fp)
-
extern int _IO_vfscanf __P ((_IO_FILE *, const char *, _IO_va_list, int *));
extern int _IO_vfprintf __P ((_IO_FILE *, const char *, _IO_va_list));
extern _IO_ssize_t _IO_padn __P ((_IO_FILE *, int, _IO_ssize_t));
General Public License. */
#include <errno.h>
-#include <bits/libc-lock.h>
+#ifndef __set_errno
+# define __set_errno(Val) errno = (Val)
+#endif
+#if defined __GLIBC__ && __GLIBC__ >= 2
+# include <bits/libc-lock.h>
+#else
+/*# include <comthread.h>*/
+#endif
#include "iolibio.h"
/* Name of our standard locale. */
const char _nl_C_name[] = "C";
+const char _nl_POSIX_name[] = "POSIX";
*name = (char *) _nl_C_name;
}
- if (strcmp (*name, _nl_C_name) == 0 || strcmp (*name, "POSIX") == 0)
+ if (strcmp (*name, _nl_C_name) == 0 || strcmp (*name, _nl_POSIX_name) == 0)
{
/* We need not load anything. The needed data is contained in
the library itself. */
ptr->decided = 0;
ptr->data = NULL;
+ /* Free the name. */
+ free ((char *) data->name);
+
/* Really delete the data. First delete the real data. */
if (data->mmaped)
{
extern const size_t _nl_category_name_sizes[LC_ALL + 1];
extern struct locale_data * *const _nl_current[LC_ALL + 1];
-/* Name of the standard locale. */
+/* Name of the standard locales. */
extern const char _nl_C_name[];
+extern const char _nl_POSIX_name[];
/* Extract the current CATEGORY locale's string for ITEM. */
#define _NL_CURRENT(category, item) \
} while (0)
-static inline char *
-clever_copy (const char *string)
-{
- size_t len;
- char *new;
-
- if (strcmp (string, "C") == 0 || strcmp (string, "POSIX") == 0)
- /* This return is dangerous because the returned string might be
- placed in read-only memory. But everything should be set up to
- handle this case. */
- return (char *) _nl_C_name;
-
- len = strlen (string) + 1;
- new = (char *) malloc (len);
- return new != NULL ? memcpy (new, string, len) : NULL;
-}
-
-
/* Construct a new composite name. */
static inline char *
new_composite_name (int category, const char *newnames[LC_ALL])
if (same)
{
/* All the categories use the same name. */
- if (strcmp (newnames[0], "C") == 0 || strcmp (newnames[0], "POSIX") == 0)
+ if (strcmp (newnames[0], _nl_C_name) == 0
+ || strcmp (newnames[0], _nl_POSIX_name) == 0)
return (char *) _nl_C_name;
new = malloc (last_len + 1);
if (_nl_current_names[category] == name)
return;
- if (_nl_current_names[category] != _nl_C_name)
- free ((void *) _nl_current_names[category]);
+ if (category == LC_ALL && _nl_current_names[category] != _nl_C_name)
+ free ((char *) _nl_current_names[category]);
_nl_current_names[category] = name;
}
goto abort_single;
/* We must not simply free a global locale since we have no
- control over the usage. So we mark it as un-deletable. */
+ control over the usage. So we mark it as un-deletable.
+
+ Note: do ont remove the `if', it's necessary to copy with
+ the builtin locale data. */
if (newdata->usage_count != MAX_USAGE_COUNT)
newdata->usage_count = MAX_USAGE_COUNT;
}
headers := $(dist-headers) obstack.h
tests := mallocbug
-distribute = thread-m.h mtrace.awk mcheck-init.c mcheck.h
+distribute = thread-m.h mtrace.pl mcheck-init.c mcheck.h
# Things which get pasted together into gmalloc.c.
gmalloc-routines := malloc morecore
# These should be removed by `make clean'.
extra-objs = mcheck-init.o libmcheck.a
+# The AWK script to analyze the output of the mtrace functions.
+ifneq ($(PERL),no)
+install-bin = mtrace
+
+# The Perl script will print addresses and to do this nicely we must know
+# whether we are on a 32 or 64 bit machine.
+ifneq ($strip($(findstring wordsize-32,$(config-sysdirs))),)
+address-width=10
+else
+address-width=18
+endif
+endif
+
include ../Rules
$(objpfx)libmcheck.a: $(objpfx)mcheck-init.o
# Uncomment this for test releases. For public releases it is too expensive.
#CPPFLAGS-malloc.o += -DMALLOC_DEBUG
+
+$(objpfx)mtrace: mtrace.pl
+ rm -fr %@.new
+ sed -e 's|@PERL@|$(PERL)|' -e 's|@XXX@|$(address-width)|' \
+ -e 's|@VERSION@|$(version)|' $^ > $@.new \
+ && rm -fr $@ && mv $@.new $@ && chmod +x $@
#ifndef NO_THREADS
static int heap_trim(heap_info *heap, size_t pad);
#endif
-#if defined(_LIBC) || defined(MALLOC_HOOKS)
+#ifdef _LIBC
+static Void_t* malloc_check(size_t sz, const Void_t *caller);
+static void free_check(Void_t* mem, const Void_t *caller);
+static Void_t* realloc_check(Void_t* oldmem, size_t bytes,
+ const Void_t *caller);
+static Void_t* memalign_check(size_t alignment, size_t bytes,
+ const Void_t *caller);
+static Void_t* malloc_starter(size_t sz, const Void_t *caller);
+static void free_starter(Void_t* mem, const Void_t *caller);
+static Void_t* malloc_atfork(size_t sz, const Void_t *caller);
+static void free_atfork(Void_t* mem, const Void_t *caller);
+#else
+#ifdef MALLOC_HOOKS
static Void_t* malloc_check(size_t sz);
static void free_check(Void_t* mem);
static Void_t* realloc_check(Void_t* oldmem, size_t bytes);
static Void_t* malloc_atfork(size_t sz);
static void free_atfork(Void_t* mem);
#endif
+#endif
#else
temporarily, because the `atfork' handler mechanism may use
malloc/free internally (e.g. in LinuxThreads). */
-#if defined(_LIBC) || defined(MALLOC_HOOKS)
+#ifdef _LIBC
+static __malloc_ptr_t (*save_malloc_hook) __MALLOC_P ((size_t __size,
+ const __malloc_ptr_t));
+static void (*save_free_hook) __MALLOC_P ((__malloc_ptr_t __ptr,
+ const __malloc_ptr_t));
+static Void_t* save_arena;
+#else
+#ifdef MALLOC_HOOKS
static __malloc_ptr_t (*save_malloc_hook) __MALLOC_P ((size_t __size));
static void (*save_free_hook) __MALLOC_P ((__malloc_ptr_t __ptr));
static Void_t* save_arena;
#endif
+#endif
static void
ptmalloc_lock_all __MALLOC_P((void))
initialization routine, then do the normal work. */
static Void_t*
+#ifdef _LIBC
+malloc_hook_ini(size_t sz, const __malloc_ptr_t caller)
+#else
#if __STD_C
malloc_hook_ini(size_t sz)
#else
malloc_hook_ini(sz) size_t sz;
#endif
+#endif
{
__malloc_hook = NULL;
__realloc_hook = NULL;
}
static Void_t*
+#ifdef _LIBC
+realloc_hook_ini(Void_t* ptr, size_t sz, const __malloc_ptr_t caller)
+#else
#if __STD_C
realloc_hook_ini(Void_t* ptr, size_t sz)
#else
realloc_hook_ini(ptr, sz) Void_t* ptr; size_t sz;
#endif
+#endif
{
__malloc_hook = NULL;
__realloc_hook = NULL;
}
static Void_t*
+#ifdef _LIBC
+memalign_hook_ini(size_t sz, size_t alignment, const __malloc_ptr_t caller)
+#else
#if __STD_C
memalign_hook_ini(size_t sz, size_t alignment)
#else
memalign_hook_ini(sz, alignment) size_t sz; size_t alignment;
#endif
+#endif
{
__malloc_hook = NULL;
__realloc_hook = NULL;
}
void weak_variable (*__malloc_initialize_hook) __MALLOC_P ((void)) = NULL;
+#ifdef _LIBC
+void weak_variable (*__free_hook) __MALLOC_P ((__malloc_ptr_t __ptr,
+ const __malloc_ptr_t)) = NULL;
+__malloc_ptr_t weak_variable (*__malloc_hook)
+ __MALLOC_P ((size_t __size, const __malloc_ptr_t)) = malloc_hook_ini;
+__malloc_ptr_t weak_variable (*__realloc_hook)
+ __MALLOC_P ((__malloc_ptr_t __ptr, size_t __size, const __malloc_ptr_t))
+ = realloc_hook_ini;
+__malloc_ptr_t weak_variable (*__memalign_hook)
+ __MALLOC_P ((size_t __size, size_t __alignment, const __malloc_ptr_t))
+ = memalign_hook_ini;
+#else
void weak_variable (*__free_hook) __MALLOC_P ((__malloc_ptr_t __ptr)) = NULL;
__malloc_ptr_t weak_variable (*__malloc_hook)
__MALLOC_P ((size_t __size)) = malloc_hook_ini;
__MALLOC_P ((__malloc_ptr_t __ptr, size_t __size)) = realloc_hook_ini;
__malloc_ptr_t weak_variable (*__memalign_hook)
__MALLOC_P ((size_t __size, size_t __alignment)) = memalign_hook_ini;
+#endif
void weak_variable (*__after_morecore_hook) __MALLOC_P ((void)) = NULL;
/* Activate a standard set of debugging hooks. */
if (__malloc_hook != NULL) {
Void_t* result;
+#ifdef _LIBC
+ result = (*__malloc_hook)(bytes, __builtin_return_address (0));
+#else
result = (*__malloc_hook)(bytes);
+#endif
return result;
}
#endif
#if defined(_LIBC) || defined(MALLOC_HOOKS)
if (__free_hook != NULL) {
+#ifdef _LIBC
+ (*__free_hook)(mem, __builtin_return_address (0));
+#else
(*__free_hook)(mem);
+#endif
return;
}
#endif
if (__realloc_hook != NULL) {
Void_t* result;
+#ifdef _LIBC
+ result = (*__realloc_hook)(oldmem, bytes, __builtin_return_address (0));
+#else
result = (*__realloc_hook)(oldmem, bytes);
+#endif
return result;
}
#endif
if (__memalign_hook != NULL) {
Void_t* result;
+#ifdef _LIBC
+ result = (*__memalign_hook)(alignment, bytes,
+ __builtin_return_address (0));
+#else
result = (*__memalign_hook)(alignment, bytes);
+#endif
return result;
}
#endif
#if defined(_LIBC) || defined(MALLOC_HOOKS)
if (__malloc_hook != NULL) {
sz = n * elem_size;
+#ifdef _LIBC
+ mem = (*__malloc_hook)(sz, __builtin_return_address (0));
+#else
mem = (*__malloc_hook)(sz);
+#endif
if(mem == 0)
return 0;
-#ifdef HAVE_MEMCPY
+#ifdef HAVE_MEMSET
return memset(mem, 0, sz);
#else
while(sz > 0) ((char*)mem)[--sz] = 0; /* rather inefficient */
}
static Void_t*
+#ifdef _LIBC
+malloc_check(size_t sz, const Void_t *caller)
+#else
#if __STD_C
malloc_check(size_t sz)
#else
malloc_check(sz) size_t sz;
#endif
+#endif
{
mchunkptr victim;
INTERNAL_SIZE_T nb = request2size(sz + 1);
}
static void
+#ifdef _LIBC
+free_check(Void_t* mem, const Void_t *caller)
+#else
#if __STD_C
free_check(Void_t* mem)
#else
free_check(mem) Void_t* mem;
#endif
+#endif
{
mchunkptr p;
}
static Void_t*
+#ifdef _LIBC
+realloc_check(Void_t* oldmem, size_t bytes, const Void_t *caller)
+#else
#if __STD_C
realloc_check(Void_t* oldmem, size_t bytes)
#else
realloc_check(oldmem, bytes) Void_t* oldmem; size_t bytes;
#endif
+#endif
{
mchunkptr oldp, newp;
INTERNAL_SIZE_T nb, oldsize;
+#ifdef _LIBC
+ if (oldmem == 0) return malloc_check(bytes, NULL);
+#else
if (oldmem == 0) return malloc_check(bytes);
+#endif
(void)mutex_lock(&main_arena.mutex);
oldp = mem2chunk_check(oldmem);
if(!oldp) {
case 2:
abort();
}
+#ifdef _LIBC
+ return malloc_check(bytes, NULL);
+#else
return malloc_check(bytes);
+#endif
}
oldsize = chunksize(oldp);
}
static Void_t*
+#ifdef _LIBC
+memalign_check(size_t alignment, size_t bytes, const Void_t *caller)
+#else
#if __STD_C
memalign_check(size_t alignment, size_t bytes)
#else
memalign_check(alignment, bytes) size_t alignment; size_t bytes;
#endif
+#endif
{
INTERNAL_SIZE_T nb;
mchunkptr p;
+#ifdef _LIBC
+ if (alignment <= MALLOC_ALIGNMENT) return malloc_check(bytes, NULL);
+#else
if (alignment <= MALLOC_ALIGNMENT) return malloc_check(bytes);
+#endif
if (alignment < MINSIZE) alignment = MINSIZE;
nb = request2size(bytes+1);
ptmalloc_init() hasn't completed yet. */
static Void_t*
+#ifdef _LIBC
+malloc_starter(size_t sz, const Void_t *caller)
+#else
#if __STD_C
malloc_starter(size_t sz)
#else
malloc_starter(sz) size_t sz;
#endif
+#endif
{
mchunkptr victim = chunk_alloc(&main_arena, request2size(sz));
}
static void
+#ifdef _LIBC
+free_starter(Void_t* mem, const Void_t *caller)
+#else
#if __STD_C
free_starter(Void_t* mem)
#else
free_starter(mem) Void_t* mem;
#endif
+#endif
{
mchunkptr p;
is active. */
static Void_t*
+#ifdef _LIBC
+malloc_atfork (size_t sz, const Void_t *caller)
+#else
#if __STD_C
malloc_atfork(size_t sz)
#else
malloc_atfork(sz) size_t sz;
#endif
+#endif
{
Void_t *vptr = NULL;
}
static void
+#ifdef _LIBC
+free_atfork(Void_t* mem, const Void_t *caller)
+#else
#if __STD_C
free_atfork(Void_t* mem)
#else
free_atfork(mem) Void_t* mem;
#endif
+#endif
{
Void_t *vptr = NULL;
arena *ar_ptr;
malloc_get_state(). */
extern int malloc_set_state __MALLOC_P ((__malloc_ptr_t __ptr));
-#if defined(__GLIBC__) || defined(MALLOC_HOOKS)
+#ifdef __GLIBC__
+/* Hooks for debugging versions. */
+extern void (*__malloc_initialize_hook) __MALLOC_P ((void));
+extern void (*__free_hook) __MALLOC_P ((__malloc_ptr_t __ptr,
+ __const __malloc_ptr_t));
+extern __malloc_ptr_t (*__malloc_hook) __MALLOC_P ((size_t __size,
+ __const __malloc_ptr_t));
+extern __malloc_ptr_t (*__realloc_hook) __MALLOC_P ((__malloc_ptr_t __ptr,
+ size_t __size,
+ __const __malloc_ptr_t));
+extern __malloc_ptr_t (*__memalign_hook) __MALLOC_P ((size_t __size,
+ size_t __alignment,
+ __const __malloc_ptr_t));
+extern void (*__after_morecore_hook) __MALLOC_P ((void));
+/* Activate a standard set of debugging hooks. */
+extern void __malloc_check_init __MALLOC_P ((void));
+#else
+#ifdef MALLOC_HOOKS
/* Hooks for debugging versions. */
extern void (*__malloc_initialize_hook) __MALLOC_P ((void));
extern void (*__free_hook) __MALLOC_P ((__malloc_ptr_t __ptr));
/* Activate a standard set of debugging hooks. */
extern void __malloc_check_init __MALLOC_P ((void));
-
+#endif
#endif
#ifdef __cplusplus
#endif
/* Old hook values. */
-static void (*old_free_hook) __P ((__ptr_t ptr));
-static __ptr_t (*old_malloc_hook) __P ((__malloc_size_t size));
-static __ptr_t (*old_realloc_hook) __P ((__ptr_t ptr, __malloc_size_t size));
+static void (*old_free_hook) __P ((__ptr_t ptr, __const __ptr_t));
+static __ptr_t (*old_malloc_hook) __P ((__malloc_size_t size, const __ptr_t));
+static __ptr_t (*old_realloc_hook) __P ((__ptr_t ptr, __malloc_size_t size,
+ __const __ptr_t));
/* Function to call when something awful happens. */
static void (*abortfunc) __P ((enum mcheck_status));
return status;
}
-static void freehook __P ((__ptr_t));
+static void freehook __P ((__ptr_t, const __ptr_t));
static void
-freehook (ptr)
+freehook (ptr, caller)
__ptr_t ptr;
+ const __ptr_t caller;
{
if (ptr)
{
ptr = (__ptr_t) hdr;
}
__free_hook = old_free_hook;
- free (ptr);
+ if (old_free_hook != NULL)
+ (*old_free_hook) (ptr, caller);
+ else
+ free (ptr);
__free_hook = freehook;
}
-static __ptr_t mallochook __P ((__malloc_size_t));
+static __ptr_t mallochook __P ((__malloc_size_t, const __ptr_t));
static __ptr_t
-mallochook (size)
+mallochook (size, caller)
__malloc_size_t size;
+ const __ptr_t caller;
{
struct hdr *hdr;
__malloc_hook = old_malloc_hook;
- hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1);
+ if (old_malloc_hook != NULL)
+ hdr = (struct hdr *) (*old_malloc_hook) (sizeof (struct hdr) + size + 1,
+ caller);
+ else
+ hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1);
__malloc_hook = mallochook;
if (hdr == NULL)
return NULL;
return (__ptr_t) (hdr + 1);
}
-static __ptr_t reallochook __P ((__ptr_t, __malloc_size_t));
+static __ptr_t reallochook __P ((__ptr_t, __malloc_size_t, const __ptr_t));
static __ptr_t
-reallochook (ptr, size)
+reallochook (ptr, size, caller)
__ptr_t ptr;
__malloc_size_t size;
+ const __ptr_t caller;
{
struct hdr *hdr;
__malloc_size_t osize;
__free_hook = old_free_hook;
__malloc_hook = old_malloc_hook;
__realloc_hook = old_realloc_hook;
- hdr = (struct hdr *) realloc ((__ptr_t) hdr, sizeof (struct hdr) + size + 1);
+ if (old_realloc_hook != NULL)
+ hdr = (struct hdr *) (*old_realloc_hook) ((__ptr_t) hdr,
+ sizeof (struct hdr) + size + 1,
+ caller);
+ else
+ hdr = (struct hdr *) realloc ((__ptr_t) hdr,
+ sizeof (struct hdr) + size + 1);
__free_hook = freehook;
__malloc_hook = mallochook;
__realloc_hook = reallochook;
+++ /dev/null
-#
-# Awk program to analyze mtrace.c output.
-#
-{
- if ($1 == "@") {
- where = " (" $2 ")"
- n = 3
- } else {
- where = ""
- n = 1
- }
- if ($n == "+") {
- if (allocated[$(n+1)] != "")
- print "+", $(n+1), "Alloc", NR, "duplicate:", allocated[$(n+1)], wherewas[$(n+1)], where;
- else {
- wherewas[$(n+1)] = where;
- allocated[$(n+1)] = $(n+2);
- }
- } else if ($n == "-") {
- if (allocated[$(n+1)] != "") {
- wherewas[$(n+1)] = "";
- allocated[$(n+1)] = "";
- if (allocated[$(n+1)] != "")
- print "DELETE FAILED", $(n+1), allocated[$(n+1)];
- } else
- print "-", $(n+1), "Free", NR, "was never alloc'd", where;
- } else if ($n == "<") {
- if (allocated[$(n+1)] != "") {
- wherewas[$(n+1)] = "";
- allocated[$(n+1)] = "";
- } else
- print "-", $(n+1), "Realloc", NR, "was never alloc'd", where;
- } else if ($n == ">") {
- if (allocated[$(n+1)] != "")
- print "+", $(n+1), "Realloc", NR, "duplicate:", allocated[$(n+1)], where;
- else {
- wherewas[$(n+1)] = $(n+2);
- allocated[$(n+1)] = $(n+2);
- }
- } else if ($n == "=") {
- # Ignore "= Start"
- } else if ($n == "!") {
- # Ignore failed realloc attempts for now
- }
-}
-END {
- for (x in allocated)
- if (allocated[x] != "")
- print "+", x, allocated[x], wherewas[x];
-}
/* More debugging hooks for `malloc'.
- Copyright (C) 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1991, 92, 93, 94, 96, 97 Free Software Foundation, Inc.
Written April 2, 1991 by John Gilmore of Cygnus Support.
Based on mcheck.c by Mike Haertel.
#include <bits/libc-lock.h>
#endif
+#ifdef HAVE_ELF
+#include <link.h>
+#endif
+
#include <stdio.h>
#ifndef __GNU_LIBRARY__
int _mtrace_line;
/* Old hook values. */
-static void (*tr_old_free_hook) __P ((__ptr_t ptr));
-static __ptr_t (*tr_old_malloc_hook) __P ((__malloc_size_t size));
-static __ptr_t (*tr_old_realloc_hook) __P ((__ptr_t ptr, __malloc_size_t size));
+static void (*tr_old_free_hook) __P ((__ptr_t ptr, const __ptr_t));
+static __ptr_t (*tr_old_malloc_hook) __P ((__malloc_size_t size,
+ const __ptr_t));
+static __ptr_t (*tr_old_realloc_hook) __P ((__ptr_t ptr,
+ __malloc_size_t size,
+ const __ptr_t));
/* This function is called when the block being alloc'd, realloc'd, or
freed has an address matching the variable "mallwatch". In a debugger,
{
}
-static void tr_where __P ((void));
+static void tr_where __P ((const __ptr_t));
static void
-tr_where ()
+tr_where (caller)
+ const __ptr_t caller;
{
if (_mtrace_file)
{
fprintf (mallstream, "@ %s:%d ", _mtrace_file, _mtrace_line);
_mtrace_file = NULL;
}
+ else if (caller != NULL)
+ {
+#ifdef HAVE_ELF
+ Dl_info info;
+ if (_dl_addr (caller, &info))
+ {
+ fprintf (mallstream, "@ %s%s%s%s%s[%p]",
+ info.dli_fname ?: "", info.dli_fname ? ":" : "",
+ info.dli_sname ? "(" : "",
+ info.dli_sname ?: "", info.dli_sname ? ") " : " ",
+ caller);
+ }
+ else
+#endif
+ fprintf (mallstream, "@ [%p] ", caller);
+ }
}
-static void tr_freehook __P ((__ptr_t));
+static void tr_freehook __P ((__ptr_t, const __ptr_t));
static void
-tr_freehook (ptr)
+tr_freehook (ptr, caller)
__ptr_t ptr;
+ const __ptr_t caller;
{
- tr_where ();
- fprintf (mallstream, "- %p\n", ptr); /* Be sure to print it first. */
+ tr_where (caller);
+ /* Be sure to print it first. */
+ fprintf (mallstream, "- %p\n", ptr);
if (ptr == mallwatch)
tr_break ();
__libc_lock_lock (lock);
__free_hook = tr_old_free_hook;
- free (ptr);
+ if (tr_old_free_hook != NULL)
+ (*tr_old_free_hook) (ptr, caller);
+ else
+ free (ptr);
__free_hook = tr_freehook;
__libc_lock_unlock (lock);
}
-static __ptr_t tr_mallochook __P ((__malloc_size_t));
+static __ptr_t tr_mallochook __P ((__malloc_size_t, const __ptr_t));
static __ptr_t
-tr_mallochook (size)
+tr_mallochook (size, caller)
__malloc_size_t size;
+ const __ptr_t caller;
{
__ptr_t hdr;
__libc_lock_lock (lock);
__malloc_hook = tr_old_malloc_hook;
- hdr = (__ptr_t) malloc (size);
+ if (tr_old_malloc_hook != NULL)
+ hdr = (__ptr_t) (*tr_old_malloc_hook) (size, caller);
+ else
+ hdr = (__ptr_t) malloc (size);
__malloc_hook = tr_mallochook;
__libc_lock_unlock (lock);
- tr_where ();
+ tr_where (caller);
/* We could be printing a NULL here; that's OK. */
- fprintf (mallstream, "+ %p %lx\n", hdr, (unsigned long)size);
+ fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long)size);
if (hdr == mallwatch)
tr_break ();
return hdr;
}
-static __ptr_t tr_reallochook __P ((__ptr_t, __malloc_size_t));
+static __ptr_t tr_reallochook __P ((__ptr_t, __malloc_size_t, const __ptr_t));
static __ptr_t
-tr_reallochook (ptr, size)
+tr_reallochook (ptr, size, caller)
__ptr_t ptr;
__malloc_size_t size;
+ const __ptr_t caller;
{
__ptr_t hdr;
__free_hook = tr_old_free_hook;
__malloc_hook = tr_old_malloc_hook;
__realloc_hook = tr_old_realloc_hook;
- hdr = (__ptr_t) realloc (ptr, size);
+ if (tr_old_realloc_hook != NULL)
+ hdr = (__ptr_t) (*tr_old_realloc_hook) (ptr, size, caller);
+ else
+ hdr = (__ptr_t) realloc (ptr, size);
__free_hook = tr_freehook;
__malloc_hook = tr_mallochook;
__realloc_hook = tr_reallochook;
__libc_lock_unlock (lock);
- tr_where ();
+ tr_where (caller);
if (hdr == NULL)
/* Failed realloc. */
- fprintf (mallstream, "! %p %lx\n", ptr, (unsigned long)size);
+ fprintf (mallstream, "! %p %#lx\n", ptr, (unsigned long)size);
else if (ptr == NULL)
- fprintf (mallstream, "+ %p %lx\n", hdr, (unsigned long)size);
+ fprintf (mallstream, "+ %p %#lx\n", hdr, (unsigned long)size);
else
- fprintf (mallstream, "< %p\n> %p %lx\n", ptr, hdr, (unsigned long)size);
+ fprintf (mallstream, "< %p\n> %p %#lx\n", ptr, hdr, (unsigned long)size);
if (hdr == mallwatch)
tr_break ();
--- /dev/null
+#! @PERL@
+eval "exec @PERL@ -S $0 $*"
+ if 0;
+# Copyright (C) 1997 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+# Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1997.
+# Based on the mtrace.awk script.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU Library General Public
+# License along with the GNU C Library; see the file COPYING.LIB. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+$VERSION = "@VERSION@";
+$PACKAGE = "libc";
+$progname = $0;
+
+sub usage {
+ print "Usage: mtrace [OPTION]... [Binary] MtraceData\n";
+ print " --help print this help, then exit\n";
+ print " --version print version number, then exit\n";
+ exit 0;
+}
+
+# We expect two arguments:
+# #1: the complete path to the binary
+# #2: the mtrace data filename
+# The usual options are also recognized.
+
+arglist: while (@ARGV) {
+ if ($ARGV[0] eq "--v" || $ARGV[0] eq "--ve" || $ARGV[0] eq "--ver" ||
+ $ARGV[0] eq "--vers" || $ARGV[0] eq "--versi" ||
+ $ARGV[0] eq "--versio" || $ARGV[0] eq "--version") {
+ print "mtrace (GNU $PACKAGE) $VERSION\n";
+ print "Copyright (C) 1997 Free Software Foundation, Inc.\n";
+ print "This is free software; see the source for copying conditions. There is NO\n";
+ print "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
+ print "Written by Ulrich Drepper <drepper\@gnu.ai.mit.edu>\n";
+
+ exit 0;
+ } elsif ($ARGV[0] eq "--h" || $ARGV[0] eq "--he" || $ARGV[0] eq "--hel" ||
+ $ARGV[0] eq "--help") {
+ &usage;
+ } elsif ($ARGV[0] =~ /^-/) {
+ print "$progname: unrecognized option `$ARGV[0]'\n";
+ print "Try `$progname --help' for more information.\n";
+ exit 1;
+ } else {
+ last arglist;
+ }
+}
+
+if ($#ARGV == 0) {
+ $binary="";
+ $data=$ARGV[0];
+} elsif ($#ARGV == 1) {
+ $binary=$ARGV[0];
+ $data=$ARGV[1];
+} else {
+ die "Wrong number of arguments.";
+}
+
+sub location {
+ my $str = pop(@_);
+ return $str if ($str eq "");
+ if ($str =~ /[[](0x[^]]*)]:(.)*/) {
+ my $addr = $1;
+ my $fct = $2;
+ return $cache{$addr} if (exists $cache{$addr});
+ if ($binary ne "" && open (ADDR, "addr2line -e $binary $addr|")) {
+ my $line = <ADDR>;
+ chomp $line;
+ close (ADDR);
+ if ($line ne '??:0') {
+ $cache{$addr} = $line;
+ return $cache{$addr};
+ }
+ }
+ $cache{$addr} = $str = "$fct @ $addr";
+ } elsif ($str =~ /^[[](0x[^]]*)]$/) {
+ my $addr = $1;
+ return $cache{$addr} if (exists $cache{$addr});
+ if ($binary ne "" && open (ADDR, "addr2line -e $binary $addr|")) {
+ my $line = <ADDR>;
+ chomp $line;
+ close (ADDR);
+ if ($line ne '??:0') {
+ $cache{$addr} = $line;
+ return $cache{$addr};
+ }
+ }
+ $cache{$addr} = $str = $addr;
+ }
+ return $str;
+}
+
+$nr=0;
+open(DATA, "<$data") || die "Cannot open mtrace data file";
+while (<DATA>) {
+ my @cols = split (' ');
+ my $n, $where;
+ if ($cols[0] eq "@") {
+ # We have address and/or function name.
+ $where=$cols[1];
+ $n=2;
+ } else {
+ $where="";
+ $n=0;
+ }
+
+ $allocaddr=$cols[$n + 1];
+ $howmuch=hex($cols[$n + 2]);
+
+ ++$nr;
+ SWITCH: {
+ if ($cols[$n] eq "+") {
+ if (defined $allocated{$allocaddr}) {
+ printf ("+ %#010x Alloc %d duplicate: %s %s\n",
+ hex($allocaddr), $nr, $wherewas{$allocaddr}, $where);
+ } else {
+ $allocated{$allocaddr}=$howmuch;
+ $wherewas{$allocaddr}=&location($where);
+ }
+ last SWITCH;
+ }
+ if ($cols[$n] eq "-") {
+ if (defined $allocated{$allocaddr}) {
+ undef $allocated{$allocaddr};
+ undef $wherewas{$allocaddr};
+ } else {
+ printf ("- %#010x Free %d was never alloc'd %s\n",
+ hex($allocaddr), $nr, &location($where));
+ }
+ last SWITCH;
+ }
+ if ($cols[$n] eq "<") {
+ if (defined $allocated{$allocaddr}) {
+ undef $allocated{$allocaddr};
+ undef $wherewas{$allocaddr};
+ } else {
+ printf ("- %#010x Realloc %d was never alloc'd %s\n",
+ hex($allocaddr), $nr, &location($where));
+ }
+ last SWITCH;
+ }
+ if ($cols[$n] eq ">") {
+ if (defined $allocated{$allocaddr}) {
+ printf ("+ %#010x Realloc %d duplicate: %#010x %s %s\n",
+ hex($allocaddr), $nr, $allocated{$allocaddr},
+ $wherewas{$allocaddr}, &location($where));
+ } else {
+ $allocated{$allocaddr}=$howmuch;
+ $wherewas{$allocaddr}=&location($where);
+ }
+ last SWITCH;
+ }
+ if ($cols[$n] eq "=") {
+ # Ignore "= Start".
+ last SWITCH;
+ }
+ if ($cols[$n] eq "!") {
+ # Ignore failed realloc for now.
+ last SWITCH;
+ }
+ }
+}
+close (DATA);
+
+# Now print all remaining entries.
+@addrs= keys %allocated;
+if ($#addrs >= 0) {
+ print "\nNot freed memory:\n-----------------\n";
+ print ' ' x (@XXX@ - 7), "Address Size Caller\n";
+ foreach $addr (sort @addrs) {
+ if (defined $allocated{$addr}) {
+ printf ("%#0@XXX@x %#8x at %s\n", hex($addr), $allocated{$addr},
+ $wherewas{$addr});
+ }
+ }
+}
+
+exit 0;
Ordinary characters appearing in the @var{template} are copied to the
output string @var{s}; this can include multibyte character sequences.
Conversion specifiers are introduced by a @samp{%} character, followed
-by an optional flag which can be one of the following. These flags,
-which are GNU extensions, affect only the output of numbers:
+by an optional flag which can be one of the following. These flags
+are all GNU extensions. The first three affect only the output of
+numbers:
@table @code
@item _
#include <stdio.h>
#include <math.h>
-#include <gmp.h>
+#include <stdlib/gmp.h>
#include <string.h>
#include <limits.h>
#include <assert.h>
#
msgid ""
msgstr ""
-"Project-Id-Version: GNU libc 2.0.3\n"
-"POT-Creation-Date: 1997-03-30 19:08+0200\n"
-"PO-Revision-Date: 1997-04-02 23:02 -0500\n"
+"Project-Id-Version: GNU libc 2.0.5\n"
+"POT-Creation-Date: 1997-08-21 04:13+0200\n"
+"PO-Revision-Date: 1997-09-23 16:00 -0500\n"
"Last-Translator: Michel Robitaille <robitail@IRO.UMontreal.CA>\n"
"Language-Team: French <fr@li.org>\n"
"MIME-Version: 1.0\n"
msgid " program vers proto port\n"
msgstr " program no_version protocole no_port\n"
-#: time/zic.c:419
+#: time/zic.c:421
#, c-format
msgid " (rule from \"%s\", line %d)"
msgstr " (règles de \"%s\", ligne %d)"
msgid " done\n"
msgstr " complété.\n"
-#: time/zic.c:416
+#: time/zic.c:418
#, c-format
msgid "\"%s\", line %d: %s"
msgstr "\"%s\", ligne %d: %s."
-#: time/zic.c:943
+#: time/zic.c:947
#, c-format
msgid "\"Zone %s\" line and -l option are mutually exclusive"
msgstr "La ligne \"Zone %s\" et l'option -l sont mutuellement exclusives."
-#: time/zic.c:951
+#: time/zic.c:955
#, c-format
msgid "\"Zone %s\" line and -p option are mutually exclusive"
msgstr "La ligne \"Zone %s\" et l'option -p sont mutuellement exclusives."
-#: time/zic.c:754
+#: time/zic.c:758
#, c-format
msgid "%s in ruleless zone"
msgstr "%s est dans une zone sans règle."
msgid "%s%sUnknown signal %d\n"
msgstr "%s%ssignal inconnu %d.\n"
-#: time/zic.c:2172
+#: time/zic.c:2185
#, c-format
msgid "%s: %d did not sign extend correctly\n"
msgstr "%s: %d n'a pas fait correctement l'expansion de la valeur signée.\n"
msgid "%s: <mb_cur_max> must be greater than <mb_cur_min>\n"
msgstr "%s: <mb_cur_max> doit être plus grande que <mb_cur_min>.\n"
-#: time/zic.c:1443
+#: time/zic.c:1456
#, c-format
msgid "%s: Can't create %s: %s\n"
msgstr "%s: ne peut créer %s: %s.\n"
-#: time/zic.c:2150
+#: time/zic.c:2163
#, c-format
msgid "%s: Can't create directory %s: %s\n"
msgstr "%s: ne peut créer le répertoire %s: %s.\n"
-#: time/zic.c:608
+#: time/zic.c:610
#, c-format
msgid "%s: Can't link from %s to %s: %s\n"
msgstr "%s: ne peut établir un lien entre %s et %s: %s.\n"
-#: time/zic.c:780
+#: time/zic.c:784
#, c-format
msgid "%s: Can't open %s: %s\n"
msgstr "%s: ne peut ouvrir %s: %s.\n"
-#: time/zic.c:1433
+#: time/zic.c:1446
#, c-format
msgid "%s: Can't remove %s: %s\n"
msgstr "%s: ne peut enlever %s: %s.\n"
-#: time/zic.c:849
+#: time/zic.c:853
#, c-format
msgid "%s: Error closing %s: %s\n"
msgstr "%s: erreur lors de la fermeture de %s: %s.\n"
-#: time/zic.c:842
+#: time/zic.c:846
#, c-format
msgid "%s: Error reading %s\n"
msgstr "%s: erreur de lecture de %s.\n"
-#: time/zic.c:1507
+#: time/zic.c:1520
#, c-format
msgid "%s: Error writing %s\n"
msgstr "%s: erreur d'écriture de %s.\n"
msgid "%s: Error writing standard output "
msgstr "%s: erreur d'écriture sur la sortie standard."
-#: time/zic.c:827
+#: time/zic.c:831
#, c-format
msgid "%s: Leap line in non leap seconds file %s\n"
msgstr ""
"%s: ligne de type `Leap' dans un fichier qui n'a pas\n"
"de délai en secondes %s.\n"
-#: time/zic.c:357
+#: time/zic.c:359
#, c-format
msgid "%s: Memory exhausted: %s\n"
msgstr "%s: mémoire épuisée: %s.\n"
-#: time/zic.c:522
+#: time/zic.c:524
#, c-format
msgid "%s: More than one -L option specified\n"
msgstr "%s: option -L spécifiée plus d'une fois.\n"
-#: time/zic.c:482
+#: time/zic.c:484
#, c-format
msgid "%s: More than one -d option specified\n"
msgstr "%s: option -d spécifiée plus d'une fois.\n"
-#: time/zic.c:492
+#: time/zic.c:494
#, c-format
msgid "%s: More than one -l option specified\n"
msgstr "%s: option -l spécifiée plus d'une fois.\n"
-#: time/zic.c:502
+#: time/zic.c:504
#, c-format
msgid "%s: More than one -p option specified\n"
msgstr "%s: option -p spécifiée plus d'une fois.\n"
-#: time/zic.c:512
+#: time/zic.c:514
#, c-format
msgid "%s: More than one -y option specified\n"
msgstr "%s: option -y spécifiée plus d'une fois.\n"
-#: time/zic.c:1872
+#: time/zic.c:1885
#, c-format
msgid "%s: command was '%s', result was %d\n"
msgstr "%s: la commande était '%s', le résultat était %d.\n"
msgid "%s: option requires an argument -- %c\n"
msgstr "%s: l'option requiert un paramètre -- %c.\n"
-#: time/zic.c:834 time/zic.c:1246 time/zic.c:1266
+#: time/zic.c:838 time/zic.c:1251 time/zic.c:1275
#, c-format
msgid "%s: panic: Invalid l_value %d\n"
msgstr "%s: panique: valeur %d de type `l_value' invalide.\n"
msgid "%s: unrecognized option `--%s'\n"
msgstr "%s: option non reconnue `--%s'.\n"
-#: time/zic.c:441
+#: time/zic.c:443
#, c-format
msgid ""
"%s: usage is %s [ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] [ -d "
msgid "Continued"
msgstr "Poursuite."
-#: catgets/gencat.c:169 db/makedb.c:120 locale/programs/locale.c:187
+#: catgets/gencat.c:169 db/makedb.c:120 locale/programs/locale.c:191
#: locale/programs/localedef.c:180
#, c-format
msgid ""
msgid "Invalid argument"
msgstr "Paramètre invalide."
-#: posix/regex.c:960
+#: posix/regex.c:978
msgid "Invalid back reference"
msgstr "Référence arrière invalide."
-#: posix/regex.c:958
+#: posix/regex.c:976
msgid "Invalid character class name"
msgstr "Nom de classe de caractères invalide."
msgid "Invalid client verifier"
msgstr "Vérificateur du client invalide."
-#: posix/regex.c:957
+#: posix/regex.c:975
msgid "Invalid collation character"
msgstr "Caractère de fusionnement invalide."
-#: posix/regex.c:964
+#: posix/regex.c:982
msgid "Invalid content of \\{\\}"
msgstr "Contenu invalide de \\{\\}"
msgid "Invalid or incomplete multibyte or wide character"
msgstr "Chaîne multi-octets ou étendue de caractères invalide ou incomplète."
-#: posix/regex.c:967
+#: posix/regex.c:985
msgid "Invalid preceding regular expression"
msgstr "Expression régulière précédente invalide."
-#: posix/regex.c:965
+#: posix/regex.c:983
msgid "Invalid range end"
msgstr "Fin d'intervalle invalide."
-#: posix/regex.c:956
+#: posix/regex.c:974
msgid "Invalid regular expression"
msgstr "Expression régulière invalide."
msgid "Machine is not on the network"
msgstr "La machine cible n'est pas sur le réseau."
-#: posix/regex.c:966
+#: posix/regex.c:984
msgid "Memory exhausted"
msgstr "Mémoire épuisée."
msgid "No locks available"
msgstr "Aucun verrou disponible."
-#: posix/regex.c:955
+#: posix/regex.c:973
msgid "No match"
msgstr "Pas de concordance."
msgid "No more records in map database"
msgstr "Aucun autre enregistrement dans la table de la base de données."
-#: posix/regex.c:5324
+#: posix/regex.c:5434
msgid "No previous regular expression"
msgstr "Aucune expression régulière ne précède."
msgid "Object is remote"
msgstr "L'objet est télé-accessible."
-#: time/zic.c:1966
+#: time/zic.c:1979
msgid "Odd number of quotation marks"
msgstr "Nombre impair de caractères apostrophe."
msgid "Power failure"
msgstr "Panne d'alimentation."
-#: posix/regex.c:968
+#: posix/regex.c:986
msgid "Premature end of regular expression"
msgstr "Fin prématurée de l'expression régulière."
msgid "Read-only file system"
msgstr "Système de fichiers accessible en lecture seulement."
-#: posix/regex.c:969
+#: posix/regex.c:987
msgid "Regular expression too big"
msgstr "Expression régulière trop grosse."
msgstr ""
"Retirer le mot de passe ou rendre les fichiers illisibles par les autres."
-#: catgets/gencat.c:224 db/makedb.c:227 locale/programs/locale.c:257
-#: locale/programs/localedef.c:412
+#: catgets/gencat.c:224 db/makedb.c:227 locale/programs/locale.c:262
+#: locale/programs/localedef.c:415
msgid "Report bugs using the `glibcbug' script to <bugs@gnu.ai.mit.edu>.\n"
msgstr ""
"Rapporter toutes anomalies via le script `glibcbug' Ã l'adresse:\n"
msgid "Structure needs cleaning"
msgstr "La structure a besoin d'un nettoyage."
-#: nis/ypclnt.c:689 nis/ypclnt.c:763 posix/regex.c:954
+#: nis/ypclnt.c:689 nis/ypclnt.c:763 posix/regex.c:972
#: stdio-common/../sysdeps/gnu/errlist.c:7
msgid "Success"
msgstr "Succès."
msgid "Trace/breakpoint trap"
msgstr "Trappe pour point d'arrêt et de trace."
-#: posix/regex.c:959
+#: posix/regex.c:977
msgid "Trailing backslash"
msgstr "Barre oblique en suffixe."
msgid "Transport endpoint is not connected"
msgstr "Le noeud final de transport n'est pas connecté."
-#: catgets/gencat.c:208 db/makedb.c:209 locale/programs/locale.c:241
-#: locale/programs/localedef.c:393
+#: catgets/gencat.c:208 db/makedb.c:209 locale/programs/locale.c:246
+#: locale/programs/localedef.c:396
#, c-format
msgid "Try `%s --help' for more information.\n"
msgstr "Pour en savoir davantage, faites: `%s --help'.\n"
msgid "Unknown ypbind error"
msgstr "Erreur inconnue de ypbind."
-#: posix/regex.c:962
+#: posix/regex.c:980
msgid "Unmatched ( or \\("
msgstr "Échec du pairage de ( ou de \\("
-#: posix/regex.c:970
+#: posix/regex.c:988
msgid "Unmatched ) or \\)"
msgstr "Échec du pairage de ) ou de \\)"
-#: posix/regex.c:961
+#: posix/regex.c:979
msgid "Unmatched [ or [^"
msgstr "Échec du pairage de [ ou de [^"
-#: posix/regex.c:963
+#: posix/regex.c:981
msgid "Unmatched \\{"
msgstr "Échec du pairage de \\{."
"Usage: %s [OPTION]... -o OUTPUT-FILE [INPUT-FILE]...\n"
" %s [OPTION]... [OUTPUT-FILE [INPUT-FILE]...]\n"
"Mandatory arguments to long options are mandatory for short options too.\n"
-" -H, --header create C header file containing symbol definitions\n"
+" -H, --header=NAME create C header file NAME containing symbol "
+"definitions\n"
" -h, --help display this help and exit\n"
" --new do not use existing catalog, force new output file\n"
" -o, --output=NAME write output to file NAME\n"
" -V, --version afficher le nom et la version du logiciel\n"
"Si le FICHIER_D_ENTRÉE est -, la lecture se fait l'entrée standard.\n"
-#: locale/programs/localedef.c:397
+#: locale/programs/localedef.c:400
#, c-format
msgid ""
"Usage: %s [OPTION]... name\n"
"Répertoire système des tables de caractères: %s\n"
" fichiers locaux: %s\n"
-#: locale/programs/locale.c:245
+#: locale/programs/locale.c:250
#, c-format
msgid ""
"Usage: %s [OPTION]... name\n"
msgid "Virtual timer expired"
msgstr "Expiration de la minuterie virtuelle."
-#: time/zic.c:1871
+#: time/zic.c:1884
msgid "Wild result from command execution"
msgstr "Résultat anarchique résultant de l'exécution de la commande."
msgid "Window changed"
msgstr "La fenêtre a changée."
-#: catgets/gencat.c:174 db/makedb.c:125 locale/programs/locale.c:192
+#: catgets/gencat.c:174 db/makedb.c:125 locale/programs/locale.c:196
#: locale/programs/localedef.c:185
#, c-format
msgid "Written by %s.\n"
msgid "You really blew it this time"
msgstr "Vous avez vraiment tout gâcher cette fois-ci."
-#: time/zic.c:1048
+#: time/zic.c:1052
msgid "Zone continuation line end time is not after end time of previous line"
msgstr ""
"Temps final de la ligne de la zone de continuation est antérieur\n"
msgid "bad argument"
msgstr "Mauvais paramètre."
-#: time/zic.c:1170
+#: time/zic.c:1174
msgid "blank FROM field on Link line"
msgstr "Champ `FROM' vide dans la ligne de type `Link'."
-#: time/zic.c:1174
+#: time/zic.c:1178
msgid "blank TO field on Link line"
msgstr "Champ `TO' vide dans la ligne de type `Link'."
msgid "cache_set: victim not found"
msgstr "cache_set: victime non repérée."
-#: time/zic.c:1698
+#: time/zic.c:1711
msgid "can't determine time zone abbreviation to use just after until time"
msgstr ""
"Ne peut déterminer l'abréviation du fuseau horaire à utiliser\n"
msgid "can't reassign procedure number %d\n"
msgstr "Ne peut réassigner le numéro de procédure %d.\n"
-#: locale/programs/localedef.c:291
+#: locale/programs/localedef.c:294
#, c-format
msgid "cannot `stat' locale file `%s'"
msgstr "Ne peut effectuer l'évaluation `stat' du fichier local `%s'."
msgid "cannot open output file `%s'"
msgstr "Ne peut ouvrir le fichier de sortie `%s'."
-#: locale/programs/locfile.c:1008
+#: locale/programs/locfile.c:1020
#, c-format
msgid "cannot open output file `%s' for category `%s'"
msgstr "Ne peut ouvrir le fichier de sortie `%s' de catégorie `%s'."
msgid "cannot process order specification"
msgstr "Ne peut traiter la spécification d'ordonnancement."
-#: locale/programs/locale.c:304
+#: locale/programs/locale.c:444
#, c-format
msgid "cannot read character map directory `%s'"
msgstr "Ne peut lire via le répertoire de la table des caractères `%s'."
-#: locale/programs/locale.c:279
+#: locale/programs/locale.c:301
#, c-format
msgid "cannot read locale directory `%s'"
msgstr "Ne peut lire via le répertoire des définitions localisées `%s'."
-#: locale/programs/localedef.c:313
+#: locale/programs/localedef.c:316
#, c-format
msgid "cannot read locale file `%s'"
msgstr "Ne peut lire le fichier des définitions localisées `%s'."
-#: locale/programs/localedef.c:338
+#: locale/programs/localedef.c:341
#, c-format
msgid "cannot write output files to `%s'"
msgstr "Ne peut écrire dans les fichiers de sortie vers `%s'."
-#: locale/programs/localedef.c:381
+#: locale/programs/localedef.c:384
msgid "category data requested more than once: should not happen"
msgstr ""
"Catégorie de données requises plus d'une fois: n'aurait pas dû se produire."
msgid "duplicate set definition"
msgstr "Duplicité de la définition d'ensemble."
-#: time/zic.c:963
+#: time/zic.c:967
#, c-format
msgid "duplicate zone name %s (file \"%s\", line %d)"
msgstr "Duplicité du nom de zone %s (fichier \"%s\", ligne %d)."
msgid "expect string argument for `copy'"
msgstr "Chaîne attendue pour le paramètre de `copy'."
-#: time/zic.c:854
+#: time/zic.c:858
msgid "expected continuation line not found"
msgstr "Ligne de continuation attendue, non repérée."
-#: locale/programs/locfile.c:1032
+#: locale/programs/locfile.c:1044
#, c-format
msgid "failure while writing data for category `%s'"
msgstr "Échec durant l'écriture des données de catégorie `%s'."
msgid "get_myaddress: ioctl (get interface configuration)"
msgstr "get_myaddress: ioctl (a obtenu la configuration de l'interface)."
-#: time/zic.c:1147
+#: time/zic.c:1151
msgid "illegal CORRECTION field on Leap line"
msgstr "CORRECTION illégale du champ dans la ligne de type `Leap'."
-#: time/zic.c:1151
+#: time/zic.c:1155
msgid "illegal Rolling/Stationary field on Leap line"
msgstr "Champ `Rolling/Stationary' illégal sur la ligne de type `Leap'."
msgid "incorrectly formatted file"
msgstr "Fichier incorrectement formaté."
-#: time/zic.c:811
+#: time/zic.c:815
msgid "input line of unknown type"
msgstr "Ligne d'entrée de type inconnu."
-#: time/zic.c:1760
+#: time/zic.c:1773
msgid "internal error - addtype called with bad isdst"
msgstr "Erreur interne - addtype appellé avec un mauvais bloc isdst."
-#: time/zic.c:1768
+#: time/zic.c:1781
msgid "internal error - addtype called with bad ttisgmt"
msgstr "Erreur interne - addtype appellé avec un mauvais bloc ttisgmt."
-#: time/zic.c:1764
+#: time/zic.c:1777
msgid "internal error - addtype called with bad ttisstd"
msgstr "Erreur interne - addtype appellé avec un mauvais bloc ttisstd."
msgid "internal error in %s, line %u"
msgstr "Erreur interne dans %s, ligne %u."
-#: time/zic.c:1019
+#: time/zic.c:1023
msgid "invalid GMT offset"
msgstr "Décalage relatif GMT invalide."
-#: time/zic.c:1022
+#: time/zic.c:1026
msgid "invalid abbreviation format"
msgstr "Format d'abréviation invalide."
-#: time/zic.c:1112 time/zic.c:1313 time/zic.c:1327
+#: time/zic.c:1116 time/zic.c:1326 time/zic.c:1340
msgid "invalid day of month"
msgstr "Jour du mois invalide."
-#: time/zic.c:1270
+#: time/zic.c:1279
msgid "invalid ending year"
msgstr "Année finale invalide."
-#: time/zic.c:1084
+#: time/zic.c:1088
msgid "invalid leaping year"
msgstr "Année bissextile invalide."
-#: time/zic.c:1099 time/zic.c:1202
+#: time/zic.c:1103 time/zic.c:1206
msgid "invalid month name"
msgstr "Nom de mois invalide."
-#: time/zic.c:918
+#: time/zic.c:922
msgid "invalid saved time"
msgstr "Temps sauvegardé invalide."
-#: time/zic.c:1250
+#: time/zic.c:1255
msgid "invalid starting year"
msgstr "Année initiale invalide."
-#: time/zic.c:1128 time/zic.c:1230
+#: time/zic.c:1132 time/zic.c:1235
msgid "invalid time of day"
msgstr "Heure du jour invalide."
-#: time/zic.c:1318
+#: time/zic.c:1331
msgid "invalid weekday name"
msgstr "Nom du jour de semaine invalide."
"La ligne avant l'ellipse ne doit pas contenir la définition d'une constante "
"de caractères."
-#: time/zic.c:791
+#: time/zic.c:795
msgid "line too long"
msgstr "Ligne trop longue."
-#: locale/programs/localedef.c:285
+#: locale/programs/localedef.c:288
#, c-format
msgid "locale file `%s', used in `copy' statement, not found"
msgstr ""
#: locale/programs/ld-collate.c:167 locale/programs/ld-collate.c:173
#: locale/programs/ld-collate.c:177 locale/programs/ld-collate.c:1442
-#: locale/programs/ld-collate.c:1471 locale/programs/locfile.c:962
+#: locale/programs/ld-collate.c:1471 locale/programs/locfile.c:974
#: locale/programs/xmalloc.c:68 posix/getconf.c:250
msgid "memory exhausted"
msgstr "Mémoire épuisée."
-#: malloc/obstack.c:462
+#: malloc/obstack.c:466
msgid "memory exhausted\n"
msgstr "Mémoire épuisée.\n"
msgid "missing era name in string %d in `era' field in category `%s'"
msgstr "Nom manquant dans la chaîne %d du champ `era' de catégorie `%s'."
-#: time/zic.c:913
+#: time/zic.c:917
msgid "nameless rule"
msgstr "Règle sans nom."
msgid "no correct regular expression for field `%s' in category `%s': %s"
msgstr "Expression reguliere incorrecte du champ `%s' de catégorie `%s': %s"
-#: time/zic.c:2086
+#: time/zic.c:2099
msgid "no day in month matches rule"
msgstr "Pas de jour dans les règles de concordance."
msgid "no other keyword shall be specified when `copy' is used"
msgstr "Aucun autre mot clé ne doit être spécifié lorsque `copy' est utilisé."
-#: locale/programs/localedef.c:344
+#: locale/programs/localedef.c:347
msgid "no output file produced because warning were issued"
msgstr "Aucun fichier de sortie généré en raison d'un avertissement déjà émis."
msgid "registerrpc: out of memory\n"
msgstr "registerrpc: mémoire épuisée.\n"
-#: time/zic.c:1821
+#: time/zic.c:1834
msgid "repeated leap second moment"
msgstr "Répétition du délai une seconde fois."
msgid "rpcinfo: can't contact portmapper: "
msgstr "rpcinfo: ne peut contacter le convertisseur de ports."
-#: time/zic.c:704 time/zic.c:706
+#: time/zic.c:708 time/zic.c:710
msgid "same rule name in multiple files"
msgstr "Même nom de règle dans plusieurs fichiers."
"La spécification de tri par le poids des symboles de\n"
"fusionnement n'a aucun sens."
-#: time/zic.c:775
+#: time/zic.c:779
msgid "standard input"
msgstr "entrée standard"
"Date initiale illégale dans la chaîne %d du champ `era'\n"
"de catégorie `%s'."
-#: time/zic.c:1274
+#: time/zic.c:1287
msgid "starting year greater than ending year"
msgstr "Année initiale plus grande que l'année finale."
+#: time/zic.c:1261 time/zic.c:1285
+msgid "starting year too high to be represented"
+msgstr "Année de départ trop grance pour être représentée."
+
+#: time/zic.c:1259 time/zic.c:1283
+msgid "starting year too low to be represented"
+msgstr "Année de départ trop petite pour être représentée"
+
#: locale/programs/ld-time.c:330
#, c-format
msgid "stopping date is illegal in string %d in `era' field in category `%s'"
"Date finale illégale dans la chaîne %d du champ `era'\\n\"\n"
"de catégorie `%s'."
+#: sunrpc/svc_run.c:81
+msgid "svc_run: - select failed"
+msgstr "svc_run: - échec de sélection"
+
#: sunrpc/svc_tcp.c:201 sunrpc/svc_tcp.c:206
msgid "svc_tcp: makefd_xprt: out of memory\n"
msgstr "svc_tcp: makefd_xprt: mémoire épuisée.\n"
# time/zic.c:1120A
# mro: Ã investiguer dans le code source
-#: time/zic.c:1117
+#: time/zic.c:1121
msgid "time before zero"
msgstr "Temps défini avant le zéro."
-#: time/zic.c:1125 time/zic.c:1986 time/zic.c:2005
+#: time/zic.c:1129 time/zic.c:1999 time/zic.c:2018
msgid "time overflow"
msgstr "Débordement du temps alloué."
msgid "too many character classes defined"
msgstr "Trop de définitions de classes de caractères."
-#: time/zic.c:1815
+#: time/zic.c:1828
msgid "too many leap seconds"
msgstr "Trop de délai en secondes."
-#: time/zic.c:1787
+#: time/zic.c:1800
msgid "too many local time types"
msgstr "Trop de types localisés pour la représentation du temps."
-#: time/zic.c:1741
+#: time/zic.c:1754
msgid "too many transitions?!"
msgstr "Trop de transitions définies?!"
msgid "too many weights"
msgstr "Trop de poids définis."
-#: time/zic.c:2109
+#: time/zic.c:2122
msgid "too many, or too long, time zone abbreviations"
msgstr "Trop ou de trop longues abréviations de fuseaux horaires."
msgid "two lines in a row containing `...' are not allowed"
msgstr "Deux lignes consécutives contenant `...' ne sont pas permises."
-#: time/zic.c:1281
+#: time/zic.c:1294
msgid "typed single year"
msgstr "Une seule année fournie."
msgid "unknown symbol `%.*s': line ignored"
msgstr "Symbole inconnu `%.*s': ligne ignorée."
-#: time/zic.c:747
+#: time/zic.c:751
msgid "unruly zone"
msgstr "Zone sans règle."
#: locale/programs/charset.c:119
msgid "upper limit in range is not smaller then lower limit"
msgstr ""
-"Limite supérieure de l'intervalle n'est pas plus petite que la limite "
-"inférieure."
+"Limite supérieure de l'intervalle n'est pas plus petite que\n"
+"la limite inférieure."
-#: time/zic.c:2052
+#: time/zic.c:2065
msgid "use of 2/29 in non leap-year"
msgstr "Utiliser 2/29 pour les années non-bissextiles."
#: locale/programs/charmap.c:245
msgid "value of <mb_cur_max> must be greater than the value of <mb_cur_min>"
msgstr ""
-"La valeur de <mb_cur_max> doit être plus grande que la valeur de "
+"La valeur de <mb_cur_max> doit être plus grande que la valeur de\n"
"<mb_cur_min>."
#: locale/programs/ld-monetary.c:139
msgstr ""
"Les valeurs du champ `%s' de catégorie `%s' ne doivent pas être égal à zéro."
-#: login/utmp_file.c:84
+#: login/utmp_file.c:76
msgid "while opening UTMP file"
msgstr "durant l'ouverture du fichier UTMP."
msgid "while opening old catalog file"
msgstr "durant l'ouverture du vieux fichier du catalogue."
+#: locale/programs/locale.c:341
+#,
+msgid "while preparing output"
+msgstr "durant la préparation de la sortie"
+
#: db/makedb.c:354
msgid "while reading database"
msgstr "durant la lecture de la base de données."
msgid "wrong number of arguments"
msgstr "Mauvais nombre de paramètres."
-#: time/zic.c:1075
+#: time/zic.c:1079
msgid "wrong number of fields on Leap line"
msgstr "Mauvais nombre de champs sur la ligne de type `Leap'."
-#: time/zic.c:1166
+#: time/zic.c:1170
msgid "wrong number of fields on Link line"
msgstr "Mauvais nombre de champs sur la ligne de type `Link'."
-#: time/zic.c:909
+#: time/zic.c:913
msgid "wrong number of fields on Rule line"
msgstr "Mauvais nombre de champs sur la ligne de type `Rule'."
-#: time/zic.c:979
+#: time/zic.c:983
msgid "wrong number of fields on Zone continuation line"
msgstr "Mauvais nombre de champs sur la ligne de type continuation de `Zone'."
-#: time/zic.c:937
+#: time/zic.c:941
msgid "wrong number of fields on Zone line"
msgstr "Mauvais nombre de champs sur la ligne de type `Zone'."
#: nis/ypclnt.c:823
msgid "yp_update: cannot get server address\n"
msgstr "yp_update: ne peut obtenir l'adresse du serveur.\n"
-
-#~ msgid "unknown signal"
-#~ msgstr "Signal inconnu."
-
-#~ msgid "yp_all: clnttcp_create failed"
-#~ msgstr "yp_all: échec de la fonction clnttcp_create()."
-
-#~ msgid "character `%c' not defined while needed as default value"
-#~ msgstr "Caractère `%c' non défini alors qu'attendu comme valeur par défaut."
-
-#~ msgid "couldn't do tcp_create\n"
-#~ msgstr "Ne peut exécuter tcp_create.\n"
-
-#~ msgid "couldn't do udp_create\n"
-#~ msgstr "Ne peut exécuter udp_create.\n"
-
-#~ msgid "portmap CALLIT: cannot fork.\n"
-#~ msgstr "portmap CALLIT: ne peut procéder à un clonage de type fork.\n"
-
-#~ msgid "portmap cannot create socket"
-#~ msgstr "portmap ne créer un socket"
-
-#~ msgid "run_svc returned unexpectedly\n"
-#~ msgstr "run_svc a retourné de façon imprévue.\n"
tester-ENV = LANGUAGE=C
inl-tester-ENV = LANGUAGE=C
noinl-tester-ENV = LANGUAGE=C
-CFLAGS-tester.c = -fno-builtin
-CFLAGS-inl-tester.c = -fno-builtin
CFLAGS-noinl-tester.c = -fno-builtin
CFLAGS-tst-strlen.c = -fno-builtin
CFLAGS-stratcliff.c = -fno-builtin
++__dest; \
break; \
case 3: \
- *((__uint16_t *) __dest)++ = \
+ *((__uint16_t *) __dest) = \
__STRING2_SMALL_GET16 (src, 0); \
+ __dest += sizeof (__uint16_t); \
*__dest = '\0'; \
break; \
case 4: \
__dest += 3; \
break; \
case 5: \
- *((__uint32_t *) __dest)++ = \
+ *((__uint32_t *) __dest) = \
__STRING2_SMALL_GET32 (src, 0); \
+ __dest += sizeof (__uint32_t); \
*__dest = '\0'; \
break; \
case 6: \
}
/* Complain if first two args don't strcmp as equal. */
-void equal (const char *a, const char *b, int number)
+void
+equal (const char *a, const char *b, int number)
{
check(a != NULL && b != NULL && STREQ (a, b), number);
}
char one[50];
char two[50];
+char *cp;
-int
-main (void)
+void
+test_strcmp (void)
{
- char *cp;
-
- /* Test strcmp first because we use it to test other things. */
it = "strcmp";
check (strcmp ("", "") == 0, 1); /* Trivial case. */
check (strcmp ("a", "a") == 0, 2); /* Identity. */
}
}
}
+}
- /* Test strcpy next because we need it to set up other tests. */
+void
+test_strcpy (void)
+{
it = "strcpy";
check (strcpy (one, "abcd") == one, 1); /* Returned value. */
equal (one, "abcd", 2); /* Basic test. */
(void) strcpy (one, "");
equal (one, "", 7); /* Boundary condition. */
+}
- /* A closely related function is stpcpy. */
+void
+test_stpcpy (void)
+{
it = "stpcpy";
check ((stpcpy (one, "a") - one) == 1, 1);
equal (one, "a", 2);
check ((stpcpy (stpcpy (stpcpy (one, "a"), "b"), "c") - one) == 3, 40);
equal (one, "abc", 41);
equal (one + 4, "xxx", 42);
+}
- /* stpncpy. */
+void
+test_stpncpy (void)
+{
it = "stpncpy";
-
memset (one, 'x', sizeof (one));
check (stpncpy (one, "abc", 2) == one + 2, 1);
check (stpncpy (one, "abc", 3) == one + 3, 2);
check (one[4] == '\0' && one[5] == 'x', 6);
check (stpncpy (one, "abcd", 6) == one + 4, 7);
check (one[4] == '\0' && one[5] == '\0' && one[6] == 'x', 8);
+}
- /* strcat. */
+void
+test_strcat (void)
+{
it = "strcat";
(void) strcpy (one, "ijk");
check (strcat (one, "lmn") == one, 1); /* Returned value. */
(void) strcpy (one, "");
(void) strcat (one, "cd");
equal (one, "cd", 9);
+}
- /* strncat - first test it as strcat, with big counts,
- then test the count mechanism. */
+void
+test_strncat (void)
+{
+ /* First test it as strcat, with big counts, then test the count
+ mechanism. */
it = "strncat";
(void) strcpy (one, "ijk");
check (strncat (one, "lmn", 99) == one, 1); /* Returned value. */
(void) strncat (one, "gh", 2);
equal (one, "abcdgh", 12); /* Count and length equal. */
+}
- /* strncmp - first test as strcmp with big counts,
- then test count code. */
+void
+test_strncmp (void)
+{
+ /* First test as strcmp with big counts, then test count code. */
it = "strncmp";
check (strncmp ("", "", 99) == 0, 1); /* Trivial case. */
check (strncmp ("a", "a", 99) == 0, 2); /* Identity. */
check (strncmp ("abce", "abc", 3) == 0, 11); /* Count == length. */
check (strncmp ("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
check (strncmp ("abc", "def", 0) == 0, 13); /* Zero count. */
+}
- /* strncpy - testing is a bit different because of odd semantics. */
+void
+test_strncpy (void)
+{
+ /* Testing is a bit different because of odd semantics. */
it = "strncpy";
check (strncpy (one, "abc", 4) == one, 1); /* Returned value. */
equal (one, "abc", 2); /* Did the copy go right? */
(void) strncpy (two, one, 9);
equal (two, "hi there", 14); /* Just paranoia. */
equal (one, "hi there", 15); /* Stomped on source? */
+}
- /* strlen. */
+void
+test_strlen (void)
+{
it = "strlen";
check (strlen ("") == 0, 1); /* Empty. */
check (strlen ("a") == 1, 2); /* Single char. */
check (strlen (p) == 2, 4+i);
}
}
+}
- /* strchr. */
+void
+test_strchr (void)
+{
it = "strchr";
check (strchr ("abcd", 'z') == NULL, 1); /* Not found. */
(void) strcpy (one, "abcd");
check (strchr (p, '/') == NULL, 9+i);
}
}
+}
-#if 0
- /* index - just like strchr. */
+void
+test_index (void)
+{
it = "index";
check (index ("abcd", 'z') == NULL, 1); /* Not found. */
(void) strcpy (one, "abcd");
(void) strcpy (one, "");
check (index (one, 'b') == NULL, 7); /* Empty string. */
check (index (one, '\0') == one, 8); /* NUL in empty string. */
-#endif
+}
- /* strrchr. */
+void
+test_strrchr (void)
+{
it = "strrchr";
check (strrchr ("abcd", 'z') == NULL, 1); /* Not found. */
(void) strcpy (one, "abcd");
check (strrchr (p, '/') == NULL, 9+i);
}
}
+}
-#if 0
- /* rindex - just like strrchr. */
+void
+test_rindex (void)
+{
it = "rindex";
check (rindex ("abcd", 'z') == NULL, 1); /* Not found. */
(void) strcpy (one, "abcd");
(void) strcpy (one, "");
check (rindex (one, 'b') == NULL, 7); /* Empty string. */
check (rindex (one, '\0') == one, 8); /* NUL in empty string. */
-#endif
+}
- /* strpbrk - somewhat like strchr. */
+void
+test_strpbrk (void)
+{
it = "strpbrk";
check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */
(void) strcpy(one, "abcd");
(void) strcpy(one, "");
check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */
check(strpbrk(one, "") == NULL, 11); /* Both strings empty. */
+}
- /* strstr - somewhat like strchr. */
+void
+test_strstr (void)
+{
it = "strstr";
check(strstr("abcd", "z") == NULL, 1); /* Not found. */
check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */
check(strstr(one, "bca") == one+2, 15); /* False start. */
(void) strcpy(one, "bbbcabbca");
check(strstr(one, "bbca") == one+1, 16); /* With overlap. */
+}
- /* strspn. */
+void
+test_strspn (void)
+{
it = "strspn";
check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
check(strspn("abcba", "ab") == 2, 2); /* Partial. */
check(strspn("abc", "qx") == 0, 3); /* None. */
check(strspn("", "ab") == 0, 4); /* Null string. */
check(strspn("abc", "") == 0, 5); /* Null search list. */
+}
- /* strcspn. */
+void
+test_strcspn (void)
+{
it = "strcspn";
check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
check(strcspn("abc", "abc") == 0, 3); /* None. */
check(strcspn("", "ab") == 0, 4); /* Null string. */
check(strcspn("abc", "") == 3, 5); /* Null search list. */
+}
- /* strtok - the hard one. */
+void
+test_strtok (void)
+{
it = "strtok";
(void) strcpy(one, "first, second, third");
equal(strtok(one, ", "), "first", 1); /* Basic test. */
equal(one, "a", 31); /* Stomped old tokens? */
equal(one+2, "b", 32);
equal(one+4, "c", 33);
+}
- /* strtok_r. */
+void
+test_strtok_r (void)
+{
it = "strtok_r";
(void) strcpy(one, "first, second, third");
equal(strtok_r(one, ", ", &cp), "first", 1); /* Basic test. */
equal(one, "a", 31); /* Stomped old tokens? */
equal(one+2, "b", 32);
equal(one+4, "c", 33);
+}
- /* strsep. */
+void
+test_strsep (void)
+{
it = "strsep";
cp = strcpy(one, "first, second, third");
equal(strsep(&cp, ", "), "first", 1); /* Basic test. */
equal(one+2, "b", 45);
equal(one+4, "c", 46);
- /* memcmp. */
+ {
+ char text[] = "This,is,a,test";
+ char *list = text;
+ it = "strsep";
+ check (!strcmp ("This", strsep (&list, ",")), 1);
+ check (!strcmp ("is", strsep (&list, ",")), 2);
+ check (!strcmp ("a", strsep (&list, ",")), 3);
+ check (!strcmp ("test", strsep (&list, ",")), 4);
+ check (strsep (&list, ",") == NULL, 5);
+ }
+}
+
+void
+test_memcmp (void)
+{
it = "memcmp";
check(memcmp("a", "a", 1) == 0, 1); /* Identity. */
check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
check(memcmp("a\203", "a\003", 2) > 0, 6);
check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */
check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */
+}
- /* memchr. */
+void
+test_memchr (void)
+{
it = "memchr";
check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */
(void) strcpy(one, "abcd");
}
}
}
+}
- /* memcpy - need not work for overlap. */
+void
+test_memcpy (void)
+{
it = "memcpy";
check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */
equal(one, "abc", 2); /* Did the copy go right? */
(void) memcpy(two, one, 9);
equal(two, "hi there", 5); /* Just paranoia. */
equal(one, "hi there", 6); /* Stomped on source? */
+}
- /* memmove - must work on overlap. */
+void
+test_memmove (void)
+{
it = "memmove";
check(memmove(one, "abc", 4) == one, 1); /* Returned value. */
equal(one, "abc", 2); /* Did the copy go right? */
(void) strcpy(one, "abcdefgh");
(void) memmove(one, one, 9);
equal(one, "abcdefgh", 9); /* 100% overlap. */
+}
- /* memccpy - first test like memcpy, then the search part
- The SVID, the only place where memccpy is mentioned, says
- overlap might fail, so we don't try it. Besides, it's hard
- to see the rationale for a non-left-to-right memccpy. */
+void
+test_memccpy (void)
+{
+ /* First test like memcpy, then the search part The SVID, the only
+ place where memccpy is mentioned, says overlap might fail, so we
+ don't try it. Besides, it's hard to see the rationale for a
+ non-left-to-right memccpy. */
it = "memccpy";
check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
equal(one, "abc", 2); /* Did the copy go right? */
(void) strcpy(one, "xyz");
check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */
equal(two, "xbcdlebee", 15);
+}
- /* memset. */
+void
+test_memset (void)
+{
it = "memset";
(void) strcpy(one, "abcdefgh");
check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */
check(0,7+i+j*256+(c != 0)*256*256);
}
}
+}
- /* bcopy - much like memcpy.
- Berklix manual is silent about overlap, so don't test it. */
+void
+test_bcopy (void)
+{
+ /* Much like memcpy. Berklix manual is silent about overlap, so
+ don't test it. */
it = "bcopy";
(void) bcopy("abc", one, 4);
equal(one, "abc", 1); /* Simple copy. */
(void) bcopy(one, two, 9);
equal(two, "hi there", 4); /* Just paranoia. */
equal(one, "hi there", 5); /* Stomped on source? */
+}
- /* bzero. */
+void
+test_bzero (void)
+{
it = "bzero";
(void) strcpy(one, "abcdef");
bzero(one+2, 2);
(void) strcpy(one, "abcdef");
bzero(one+2, 0);
equal(one, "abcdef", 4); /* Zero-length copy. */
+}
-#if 0
- /* bcmp - somewhat like memcmp. */
+void
+test_bcmp (void)
+{
it = "bcmp";
check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
check(bcmp("alph", "beta", 4) != 0, 5);
check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
-#endif
+}
- {
- char text[] = "This,is,a,test";
- char *list = text;
- it = "strsep";
- check (!strcmp ("This", strsep (&list, ",")), 1);
- check (!strcmp ("is", strsep (&list, ",")), 2);
- check (!strcmp ("a", strsep (&list, ",")), 3);
- check (!strcmp ("test", strsep (&list, ",")), 4);
- check (strsep (&list, ",") == NULL, 5);
- }
+void
+test_strerror (void)
+{
+ int f;
+ it = "strerror";
+ f = __open("/", O_WRONLY); /* Should always fail. */
+ check(f < 0 && errno > 0 && errno < _sys_nerr, 1);
+ equal(strerror(errno), _sys_errlist[errno], 2);
+}
+
+int
+main (void)
+{
+ int status;
+
+ /* Test strcmp first because we use it to test other things. */
+ test_strcmp ();
+
+ /* Test strcpy next because we need it to set up other tests. */
+ test_strcpy ();
+
+ /* A closely related function is stpcpy. */
+ test_stpcpy ();
+
+ /* stpncpy. */
+ test_stpncpy ();
+
+ /* strcat. */
+ test_strcat ();
+
+ /* strncat. */
+ test_strncat ();
+
+ /* strncmp. */
+ test_strncmp ();
+
+ /* strncpy. */
+ test_strncpy ();
+
+ /* strlen. */
+ test_strlen ();
+
+ /* strchr. */
+ test_strchr ();
+
+ /* index - just like strchr. */
+ test_index ();
+
+ /* strrchr. */
+ test_strrchr ();
+
+ /* rindex - just like strrchr. */
+ test_rindex ();
+
+ /* strpbrk - somewhat like strchr. */
+ test_strpbrk ();
+
+ /* strstr - somewhat like strchr. */
+ test_strstr ();
+
+ /* strspn. */
+ test_strspn ();
+
+ /* strcspn. */
+ test_strcspn ();
+
+ /* strtok - the hard one. */
+ test_strtok ();
+
+ /* strtok_r. */
+ test_strtok_r ();
+
+ /* strsep. */
+ test_strsep ();
+
+ /* memcmp. */
+ test_memcmp ();
+
+ /* memchr. */
+ test_memchr ();
+
+ /* memcpy - need not work for overlap. */
+ test_memcpy ();
+
+ /* memmove - must work on overlap. */
+ test_memmove ();
+
+ /* memccpy. */
+ test_memccpy ();
+
+ /* memset. */
+ test_memset ();
+
+ /* bcopy. */
+ test_bcopy ();
+
+ /* bzero. */
+ test_bzero ();
+
+ /* bcmp - somewhat like memcmp. */
+ test_bcmp ();
/* strerror - VERY system-dependent. */
- {
- int f;
- it = "strerror";
- f = __open("/", O_WRONLY); /* Should always fail. */
- check(f < 0 && errno > 0 && errno < _sys_nerr, 1);
- equal(strerror(errno), _sys_errlist[errno], 2);
- }
+ test_strerror ();
- {
- int status;
- if (errors == 0)
- {
- status = EXIT_SUCCESS;
- puts("No errors.");
- }
- else
- {
- status = EXIT_FAILURE;
- printf("%Zd errors.\n", errors);
- }
- exit(status);
- }
+
+ if (errors == 0)
+ {
+ status = EXIT_SUCCESS;
+ puts("No errors.");
+ }
+ else
+ {
+ status = EXIT_FAILURE;
+ printf("%Zd errors.\n", errors);
+ }
+ exit(status);
}
{
Elf64_Addr plt;
extern void _dl_runtime_resolve (void);
+ extern void _dl_runtime_profile (void);
if (l->l_info[DT_JMPREL] && lazy)
{
plt = l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr;
/* This function will be called to perform the relocation. */
- *(Elf64_Addr *)(plt + 16) = (Elf64_Addr) &_dl_runtime_resolve;
+ if (!profile)
+ *(Elf64_Addr *)(plt + 16) = (Elf64_Addr) &_dl_runtime_resolve;
+ else
+ {
+ *(Elf64_Addr *)(plt + 16) = (Elf64_Addr) &_dl_runtime_profile;
+ /* Say that we really want profiling and the timers are started. */
+ _dl_profile_map = l;
+ }
/* Identify this shared object */
*(Elf64_Addr *)(plt + 24) = (Elf64_Addr) l;
/* This code is used in dl-runtime.c to call the `fixup' function
and then redirect to the address it returns. */
-#define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ( \
-"/* Trampoline for _dl_runtime_resolver */
- .globl _dl_runtime_resolve
- .ent _dl_runtime_resolve
-_dl_runtime_resolve:
+#define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name, IMB) asm ( "\
+ .globl " #tramp_name "
+ .ent " #tramp_name "
+" #tramp_name ":
lda $sp, -168($sp)
.frame $sp, 168, $26
/* Preserve all registers that C normally doesn't. */
stq $29, 160($sp)
.mask 0x27ff01ff, -168
/* Set up our $gp */
- br $gp, 0f
-0: ldgp $gp, 0($gp)
+ br $gp, .+4
+ ldgp $gp, 0($gp)
.prologue 1
- /* Set up the arguments for _dl_runtime_resolve. */
+ /* Set up the arguments for fixup: */
/* $16 = link_map out of plt0 */
/* $17 = offset of reloc entry = ($28 - $27 - 20) /12 * 24 */
+ /* $18 = return address */
subq $28, $27, $17
ldq $16, 8($27)
subq $17, 20, $17
+ mov $26, $18
addq $17, $17, $17
/* Do the fixup */
- bsr $26, fixup..ng
+ bsr $26, " #fixup_name "..ng
/* Move the destination address into position. */
mov $0, $27
/* Restore program registers. */
ldq $25, 152($sp)
ldq $29, 160($sp)
/* Flush the Icache after having modified the .plt code. */
- imb
+ " #IMB "
/* Clean up and turn control to the destination */
lda $sp, 168($sp)
jmp $31, ($27)
- .end _dl_runtime_resolve");
+ .end " #tramp_name)
-/* The PLT uses Elf64_Rela relocs. */
-#define elf_machine_relplt elf_machine_rela
+#ifndef PROF
+#define ELF_MACHINE_RUNTIME_TRAMPOLINE \
+ TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup, imb); \
+ TRAMPOLINE_TEMPLATE (_dl_runtime_profile, profile_fixup, #nop);
+#else
+#define ELF_MACHINE_RUNTIME_TRAMPOLINE \
+ TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup); \
+ strong_alias (_dl_runtime_resolve, _dl_runtime_profile);
+#endif
/* Initial entry point code for the dynamic linker.
The C function `_dl_start' is the real entry point;
#define elf_machine_lookup_noexec_p(type) (0)
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
-#define ELF_MACHINE_RELOC_NOPLT R_ALPHA_JMP_SLOT
+#define ELF_MACHINE_JMP_SLOT R_ALPHA_JMP_SLOT
/* The alpha never uses Elf64_Rel relocations. */
#define ELF_MACHINE_NO_REL 1
-#endif /* !dl_machine_h */
-
-#ifdef RESOLVE
-
/* Fix up the instructions of a PLT entry to invoke the function
rather than the dynamic linker. */
static inline void
-elf_alpha_fix_plt(struct link_map *l,
- const Elf64_Rela *reloc,
- Elf64_Addr got_addr,
- Elf64_Addr value)
+elf_machine_fixup_plt(struct link_map *l, const Elf64_Rela *reloc,
+ Elf64_Addr *got_addr, Elf64_Addr value)
{
const Elf64_Rela *rela_plt;
Elf64_Word *plte;
long edisp;
+ /* Store the value we are going to load. */
+ *got_addr = value;
+
/* Recover the PLT entry address by calculating reloc's index into the
.rela.plt, and finding that entry in the .plt. */
-
rela_plt = (void *)(l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr);
-
plte = (void *)(l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr + 32);
plte += 3 * (reloc - rela_plt);
/* Find the displacement from the plt entry to the function. */
-
edisp = (long)(value - (Elf64_Addr)&plte[3]) / 4;
if (edisp >= -0x100000 && edisp < 0x100000)
lo = (short)hi;
hi = (hi - lo) >> 16;
- /* Emit "lda $27,L($27)" */
+ /* Emit "lda $27,lo($27)" */
plte[1] = 0x237b0000 | (lo & 0xffff);
/* Emit "br $31,function" */
committed to memory before the first is overwritten. */
__asm__ __volatile__("wmb" : : : "memory");
- /* Emit "ldah $27,H($27)" */
+ /* Emit "ldah $27,hi($27)" */
plte[0] = 0x277b0000 | (hi & 0xffff);
}
else
into the cache. */
int hi, lo;
- hi = got_addr - (Elf64_Addr)&plte[0];
+ hi = (Elf64_Addr)got_addr - (Elf64_Addr)&plte[0];
lo = (short)hi;
hi = (hi - lo) >> 16;
- /* Emit "ldq $27,L($27)" */
+ /* Emit "ldq $27,lo($27)" */
plte[1] = 0xa77b0000 | (lo & 0xffff);
/* Emit "jmp $31,($27)" */
committed to memory before the first is overwritten. */
__asm__ __volatile__("wmb" : : : "memory");
- /* Emit "ldah $27,H($27)" */
+ /* Emit "ldah $27,hi($27)" */
plte[0] = 0x277b0000 | (hi & 0xffff);
}
hasn't made it into Icache yet, so there's nothing to clean up. */
}
+#endif /* !dl_machine_h */
+
+#ifdef RESOLVE
+
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
MAP is the object containing the reloc. */
static inline void
loadbase = RESOLVE (&sym, version, r_type);
sym_value = sym ? loadbase + sym->st_value : 0;
+ sym_value += reloc->r_addend;
if (r_type == R_ALPHA_GLOB_DAT)
*reloc_addr = sym_value;
else if (r_type == R_ALPHA_JMP_SLOT)
- {
- *reloc_addr = sym_value;
- elf_alpha_fix_plt (map, reloc, (Elf64_Addr) reloc_addr, sym_value);
- }
+ elf_machine_fixup_plt (map, reloc, reloc_addr, sym_value);
else if (r_type == R_ALPHA_REFQUAD)
{
sym_value += *reloc_addr;
= (void *)(map->l_addr + map->l_info[DT_SYMTAB]->d_un.d_ptr);
sym_value -= map->l_addr;
sym_value -= dlsymtab[ELF64_R_SYM(reloc->r_info)].st_value;
+ sym_value -= reloc->r_addend;
}
- else
#endif
- sym_value += reloc->r_addend;
*reloc_addr = sym_value;
}
else
.previous
");
#endif
-/* The PLT uses Elf32_Rel relocs. */
-#define elf_machine_relplt elf_machine_rel
/* Mask identifying addresses reserved for the user program,
where the dynamic linker should not map anything. */
#define ELF_MACHINE_USER_ADDRESS_MASK 0xf8000000UL
-
-
/* Initial entry point code for the dynamic linker.
The C function `_dl_start' is the real entry point;
its return value is the user program's entry point. */
#define elf_machine_lookup_noplt_p(type) ((type) == R_386_JMP_SLOT)
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
-#define ELF_MACHINE_RELOC_NOPLT R_386_JMP_SLOT
+#define ELF_MACHINE_JMP_SLOT R_386_JMP_SLOT
/* The i386 never uses Elf32_Rela relocations. */
#define ELF_MACHINE_NO_RELA 1
_dl_platform = NULL;
}
+static inline void
+elf_machine_fixup_plt (struct link_map *map, const Elf32_Rel *reloc,
+ Elf32_Addr *reloc_addr, Elf32_Addr value)
+{
+ *reloc_addr = value;
+}
+
#endif /* !dl_machine_h */
#ifdef RESOLVE
It has been slightly modified to compute 2^x instead of e^x, and for
single-precision.
*/
-#define _GNU_SOURCE
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
#include <float.h>
#include <ieee754.h>
#include <math.h>
else if (isgreaterequal (x, (float) FLT_MAX_EXP))
return huge * huge;
/* And underflow (including -inf). */
- else if (isless (x, (float) (FLT_MIN_EXP - FLT_MANT_DIF)))
+ else if (isless (x, (float) (FLT_MIN_EXP - FLT_MANT_DIG)))
return TWOM100 * TWOM100;
/* Maybe the result needs to be a denormalised number... */
else if (!isnan (x))
".set _dl_runtime_profile, _dl_runtime_resolve");
#endif
#define ELF_MACHINE_RUNTIME_FIXUP_ARGS long int save_a0, long int save_a1
-/* The PLT uses Elf32_Rela relocs. */
-#define elf_machine_relplt elf_machine_rela
/* Mask identifying addresses reserved for the user program,
#define elf_machine_lookup_noplt_p(type) ((type) == R_68K_JMP_SLOT)
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
-#define ELF_MACHINE_RELOC_NOPLT R_68K_JMP_SLOT
+#define ELF_MACHINE_JMP_SLOT R_68K_JMP_SLOT
/* The m68k never uses Elf32_Rel relocations. */
#define ELF_MACHINE_NO_REL 1
+static inline void
+elf_machine_fixup_plt (struct link_map *map, const Elf32_Rela *reloc,
+ Elf32_Addr *reloc_addr, Elf32_Addr value)
+{
+ *reloc_addr = value + reloc->r_addend;
+}
+
#endif /* !dl_machine_h */
#ifdef RESOLVE
break;
case R_68K_GLOB_DAT:
case R_68K_JMP_SLOT:
- *reloc_addr = value;
+ *reloc_addr = value + reloc->r_addend;
break;
case R_68K_8:
*(char *) reloc_addr = value + reloc->r_addend;
# ...unwind the stack frame, and jump to the PLT entry we updated.
addi 1,1,48
bctr
-0:
- .size _dl_runtime_resolve,0b-_dl_runtime_resolve
+ .size _dl_runtime_resolve,.-_dl_runtime_resolve
.align 2
.globl _dl_prof_resolve
_dl_preferred_address = mapstart; \
} )
-/* We require the address of the PLT entry returned from fixup, not
- the first word of the PLT entry. */
-#define ELF_FIXUP_RETURN_VALUE(map, result) ((Elf32_Addr) &(result))
-
/* Nonzero iff TYPE should not be allowed to resolve to one of
the main executable's symbols, as for a COPY reloc. */
#define elf_machine_lookup_noexec_p(type) ((type) == R_PPC_COPY)
(type) == R_PPC_JMP_SLOT)
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
-#define ELF_MACHINE_RELOC_NOPLT R_PPC_JMP_SLOT
+#define ELF_MACHINE_JMP_SLOT R_PPC_JMP_SLOT
/* Nonzero iff TYPE describes relocation of a PLT entry, so
PLT entries should not be allowed to define the value. */
/* elf_machine_runtime_setup handles this. */
}
+static inline void
+elf_machine_fixup_plt(struct link_map *map, const Elf32_Rela *reloc,
+ Elf32_Addr *reloc_addr, Elf32_Addr finaladdr)
+{
+ Elf32_Sword delta = finaladdr - (Elf32_Word) (char *) reloc_addr;
+ if (delta << 6 >> 6 == delta)
+ *reloc_addr = OPCODE_B (delta);
+ else if (finaladdr <= 0x01fffffc || finaladdr >= 0xfe000000)
+ *reloc_addr = OPCODE_BA (finaladdr);
+ else
+ {
+ Elf32_Word *plt;
+ Elf32_Word index;
+
+ plt = (Elf32_Word *)((char *)map->l_addr
+ + map->l_info[DT_PLTGOT]->d_un.d_val);
+ index = (reloc_addr - plt - PLT_INITIAL_ENTRY_WORDS)/2;
+ if (index >= PLT_DOUBLE_SIZE)
+ {
+ /* Slots greater than or equal to 2^13 have 4 words available
+ instead of two. */
+ /* FIXME: There are some possible race conditions in this code,
+ when called from 'fixup'.
+
+ 1) Suppose that a lazy PLT entry is executing, a context switch
+ between threads (or a signal) occurs, and the new thread or
+ signal handler calls the same lazy PLT entry. Then the PLT entry
+ would be changed while it's being run, which will cause a segfault
+ (almost always).
+
+ 2) Suppose the reverse: that a lazy PLT entry is being updated,
+ a context switch occurs, and the new code calls the lazy PLT
+ entry that is being updated. Then the half-fixed PLT entry will
+ be executed, which will also almost always cause a segfault.
+
+ These problems don't happen with the 2-word entries, because
+ only one of the two instructions are changed when a lazy entry
+ is retargeted at the actual PLT entry; the li instruction stays
+ the same (we have to update it anyway, because we might not be
+ updating a lazy PLT entry). */
+
+ reloc_addr[0] = OPCODE_LI (11, finaladdr);
+ reloc_addr[1] = OPCODE_ADDIS (11, 11, finaladdr + 0x8000 >> 16);
+ reloc_addr[2] = OPCODE_MTCTR (11);
+ reloc_addr[3] = OPCODE_BCTR ();
+ }
+ else
+ {
+ Elf32_Word num_plt_entries;
+
+ num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
+ / sizeof(Elf32_Rela));
+
+ plt[index+PLT_DATA_START_WORDS (num_plt_entries)] = finaladdr;
+ reloc_addr[0] = OPCODE_LI (11, index*4);
+ reloc_addr[1] = OPCODE_B (-(4*(index*2
+ + 1
+ - PLT_LONGBRANCH_ENTRY_WORDS
+ + PLT_INITIAL_ENTRY_WORDS)));
+ }
+ }
+ MODIFIED_CODE (reloc_addr);
+}
+
#endif /* dl_machine_h */
#ifdef RESOLVE
}
else if (rinfo == R_PPC_JMP_SLOT)
{
- Elf32_Sword delta = finaladdr - (Elf32_Word) (char *) reloc_addr;
- if (delta << 6 >> 6 == delta)
- *reloc_addr = OPCODE_B (delta);
- else if (finaladdr <= 0x01fffffc || finaladdr >= 0xfe000000)
- *reloc_addr = OPCODE_BA (finaladdr);
- else
- {
- Elf32_Word *plt;
- Elf32_Word index;
-
- plt = (Elf32_Word *)((char *)map->l_addr
- + map->l_info[DT_PLTGOT]->d_un.d_val);
- index = (reloc_addr - plt - PLT_INITIAL_ENTRY_WORDS)/2;
- if (index >= PLT_DOUBLE_SIZE)
- {
- /* Slots greater than or equal to 2^13 have 4 words available
- instead of two. */
- /* FIXME: There are some possible race conditions in this code,
- when called from 'fixup'.
-
- 1) Suppose that a lazy PLT entry is executing, a
- context switch between threads (or a signal) occurs,
- and the new thread or signal handler calls the same
- lazy PLT entry. Then the PLT entry would be changed
- while it's being run, which will cause a segfault
- (almost always).
-
- 2) Suppose the reverse: that a lazy PLT entry is
- being updated, a context switch occurs, and the new
- code calls the lazy PLT entry that is being updated.
- Then the half-fixed PLT entry will be executed, which
- will also almost always cause a segfault.
-
- These problems don't happen with the 2-word entries, because
- only one of the two instructions are changed when a lazy
- entry is retargeted at the actual PLT entry; the li
- instruction stays the same (we have to update it anyway,
- because we might not be updating a lazy PLT entry). */
- reloc_addr[0] = OPCODE_LI (11, finaladdr);
- reloc_addr[1] = OPCODE_ADDIS (11, 11, finaladdr + 0x8000 >> 16);
- reloc_addr[2] = OPCODE_MTCTR (11);
- reloc_addr[3] = OPCODE_BCTR ();
- }
- else
- {
- Elf32_Word num_plt_entries;
-
- num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
- / sizeof(Elf32_Rela));
-
- plt[index+PLT_DATA_START_WORDS (num_plt_entries)] = finaladdr;
- reloc_addr[0] = OPCODE_LI (11, index*4);
- reloc_addr[1] =
- OPCODE_B (-(4*(index*2
- + 1
- - PLT_LONGBRANCH_ENTRY_WORDS
- + PLT_INITIAL_ENTRY_WORDS)));
- }
- }
- MODIFIED_CODE (reloc_addr);
+ elf_machine_fixup_plt (map, reloc, reloc_addr, finalvalue);
}
else
{
restore
.size _dl_runtime_resolve, . - _dl_runtime_resolve");
-/* The address of the JMP_SLOT reloc is the .plt entry, thus we don't
- dereference the reloc's addr to get the final destination. Ideally
- there would be a generic way to return the value of the symbol from
- elf_machine_relplt, but as it is, the address of the .plt entry is
- good enough. */
-#define ELF_FIXUP_RETURN_VALUE(map, result) ((Elf32_Addr) &(result))
-
/* Nonzero iff TYPE should not be allowed to resolve to one of
the main executable's symbols, as for a COPY reloc. */
#define elf_machine_lookup_noexec_p(type) ((type) == R_SPARC_COPY)
#define elf_machine_lookup_noplt_p(type) ((type) == R_SPARC_JMP_SLOT)
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
-#define ELF_MACHINE_RELOC_NOPLT R_SPARC_JMP_SLOT
+#define ELF_MACHINE_JMP_SLOT R_SPARC_JMP_SLOT
/* The SPARC never uses Elf32_Rel relocations. */
#define ELF_MACHINE_NO_REL 1
/* The SPARC overlaps DT_RELA and DT_PLTREL. */
#define ELF_MACHINE_PLTREL_OVERLAP 1
-/* The PLT uses Elf32_Rela relocs. */
-#define elf_machine_relplt elf_machine_rela
-
/* Initial entry point code for the dynamic linker.
The C function `_dl_start' is the real entry point;
its return value is the user program's entry point. */
.size _dl_start_user,.-_dl_start_user
.previous");
+static inline void
+elf_machine_fixup_plt (struct link_map *map, const Elf32_Rela *reloc,
+ Elf32_Addr *reloc_addr, Elf32_Addr value)
+{
+ /* For thread safety, write the instructions from the bottom and
+ flush before we overwrite the critical "b,a". This of course
+ need not be done during bootstrapping, since there are no threads.
+ But we also can't tell if we _can_ use flush, so don't. */
+
+ reloc_addr[2] = OPCODE_JMP_G1 | (value & 0x3ff);
+#ifndef RTLD_BOOTSTRAP
+ if (_dl_hwcap & HWCAP_SPARC_FLUSH)
+ __asm __volatile ("flush %0+8" : : "r"(reloc_addr));
+#endif
+
+ reloc_addr[1] = OPCODE_SETHI_G1 | (value >> 10);
+#ifndef RTLD_BOOTSTRAP
+ if (_dl_hwcap & HWCAP_SPARC_FLUSH)
+ __asm __volatile ("flush %0+4" : : "r"(reloc_addr));
+#endif
+}
+
#ifdef RESOLVE
+
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
MAP is the object containing the reloc. */
*reloc_addr = value;
break;
case R_SPARC_JMP_SLOT:
- /* For thread safety, write the instructions from the bottom and
- flush before we overwrite the critical "b,a". */
- reloc_addr[2] = OPCODE_JMP_G1 | (value & 0x3ff);
- if (_dl_hwcap & HWCAP_SPARC_FLUSH)
- __asm __volatile ("flush %0+8" : : "r"(reloc_addr));
- reloc_addr[1] = OPCODE_SETHI_G1 | (value >> 10);
- if (_dl_hwcap & HWCAP_SPARC_FLUSH)
- __asm __volatile ("flush %0+4" : : "r"(reloc_addr));
+ elf_machine_fixup_plt(map, reloc, reloc_addr, value);
break;
case R_SPARC_8:
*(char *) reloc_addr = value;
return pc - *(Elf64_Addr *)(elf_pic_register + la);
}
+static inline void
+elf_machine_fixup_plt(struct link_map *map, const Elf64_Rela *reloc,
+ Elf64_Addr *reloc_addr, Elf64_Addr value)
+{
+ Elf64_Dyn *pltfmt = map->l_info[DT_SPARC(PLTFMT)];
+ switch (pltfmt ? pltfmt->d_un.d_val : 0)
+ {
+ case 1: /* .got.plt with absolute addresses */
+ *reloc_addr = value;
+ break;
+ case 2: /* .got.plt with got-relative addresses */
+ *reloc_addr = value - (map->l_info[DT_PLTGOT]->d_un.d_ptr + map->l_addr);
+ break;
+ default:
+ assert (! "unexpected .plt format type");
+ }
+}
+
#ifdef RESOLVE
+
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
MAP is the object containing the reloc. */
break;
case R_SPARC_JMP_SLOT:
- {
- Elf64_Dyn *pltfmt = map->l_info[DT_SPARC(PLTFMT)];
- switch (pltfmt ? pltfmt->d_un.d_val : 0)
- {
- case 1: /* .got.plt with absolute addresses */
- *reloc_addr = value;
- break;
- case 2: /* .got.plt with got-relative addresses */
- *reloc_addr = value - (map->l_info[DT_PLTGOT]->d_un.d_ptr
- + map->l_addr);
- break;
- default:
- assert (! "unexpected .plt format type");
- }
- }
+ elf_machine_fixup_plt(map, reloc, reloc_addr, value);
break;
case R_SPARC_NONE: /* Alright, Wilbur. */
#define elf_machine_lookup_noplt_p(type) ((type) == R_SPARC_JMP_SLOT)
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
-#define ELF_MACHINE_RELOC_NOPLT R_SPARC_JMP_SLOT
+#define ELF_MACHINE_JMP_SLOT R_SPARC_JMP_SLOT
/* The SPARC never uses Elf64_Rel relocations. */
#define ELF_MACHINE_NO_REL 1
/* The SPARC overlaps DT_RELA and DT_PLTREL. */
#define ELF_MACHINE_PLTREL_OVERLAP 1
-/* The return value from dl-runtime's fixup, if it should be special. */
-#define ELF_FIXUP_RETURN_VALUE(map, result) \
- ((map)->l_info[DT_SPARC(PLTFMT)] \
- && (map)->l_info[DT_SPARC(PLTFMT)]->d_un.d_val == 2 \
- ? (result) + (map)->l_info[DT_PLTGOT]->d_un.d_ptr + (map)->l_addr \
- : (result))
-
/* Set up the loaded object described by L so its unrelocated PLT
entries will jump to the on-demand fixup code in dl-runtime.c. */
/* Machine-dependent ELF dynamic relocation inline functions. Stub version.
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
#error "Where am I?"
}
-/* This can modify DYNAMIC_INFO to avoid relocating code in
- the functions above if they are doing bizarre magic. */
-#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) /* nothing */
+/* Fixup a PLT entry to bounce directly to the function at VALUE. */
+
+static inline void
+elf_machine_fixup_plt (struct link_map *map, const Elf32_Rel *reloc,
+ Elf32_Addr *reloc_addr, Elf32_Addr value)
+{
+ *reloc_addr = value;
+}
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
LOADADDR is the load address of the object; INFO is an array indexed
}
-static inline void
+static inline Elf32_Addr
elf_machine_rela (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
const Elf32_Rel *reloc, const Elf32_Sym *sym,
Elf32_Addr (*resolve) (const Elf32_Sym **ref,
{
extern void _dl_runtime_resolve (Elf32_Word);
- if (lazy)
+ if (lazy)
{
/* The GOT entries for functions in the PLT have not yet been filled
in. Their initial contents will arrange when called to push an
pause - pause 0 __libc_pause pause
personality init-first personality 1 __personality personality
pipe - pipe 1 __pipe pipe
+prctl EXTRA prctl 5
query_module EXTRA query_module 5 query_module
quotactl EXTRA quotactl 4 quotactl
s_getdents EXTRA getdents 3 __getdents