about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog52
-rw-r--r--iconv/skeleton.c132
-rw-r--r--iconvdata/8bit-gap.c7
-rw-r--r--iconvdata/8bit-generic.c7
-rw-r--r--iconvdata/TESTS6
-rw-r--r--iconvdata/ansi_x3.110.c7
-rw-r--r--iconvdata/big5.c7
-rw-r--r--iconvdata/euc-cn.c7
-rw-r--r--iconvdata/euc-jp.c7
-rw-r--r--iconvdata/euc-kr.c7
-rw-r--r--iconvdata/euc-tw.c7
-rw-r--r--iconvdata/gbk.c7
-rw-r--r--iconvdata/iso-2022-cn.c7
-rw-r--r--iconvdata/iso-2022-jp.c7
-rw-r--r--iconvdata/iso-2022-kr.c7
-rw-r--r--iconvdata/iso646.c7
-rw-r--r--iconvdata/iso_6937-2.c7
-rw-r--r--iconvdata/iso_6937.c7
-rw-r--r--iconvdata/johab.c7
-rw-r--r--iconvdata/sjis.c7
-rw-r--r--iconvdata/t.61.c7
-rw-r--r--iconvdata/uhc.c7
-rw-r--r--iconvdata/unicode.c14
-rw-r--r--iconvdata/utf-16.c42
-rw-r--r--locale/programs/simple-hash.c29
-rw-r--r--malloc/Versions2
-rw-r--r--malloc/mcheck.c17
-rw-r--r--malloc/mcheck.h3
-rw-r--r--stdio-common/Makefile2
29 files changed, 311 insertions, 121 deletions
diff --git a/ChangeLog b/ChangeLog
index 9772517f35..38f845f727 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,55 @@
+2000-03-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* iconvdata/TESTS: Use UCS-2BE instead of UCS2.
+
+	* iconv/loop.c: Define get16, get32, put16, and put32 macros to
+	allow as well reading from/writing to unaligned addresses on machines
+	which don't support this in hardware.  Use FCTNAME macro to define
+	function name.  Include the file a second time for platforms which
+	need special unaligned handling.
+	* iconv/skeleton.c: Define get16u, get32u, put16u, and put32u macros
+	to access potentially unaligned addresses.  These macros are intended
+	to be used only outside the loops.
+	(unaligned): New definition.  In case the machine can handle unaligned
+	access define as zero.  Otherwise as a variable which is initialized
+	as nonzero in case the buffer passed in at runtime is unaligned with
+	respect to the character set encoding involved.
+	Call aligned or unaligned looop functions according to unaligned
+	variable.
+	* iconvdata/8bit-gap.c: Use get16, get32, put16, and put32 instead
+	of direct casting pointer to potentially handle unaligned memory
+	accesses.
+	* iconvdata/8bit-generic.c: Likewise.
+	* iconvdata/ansi_x3.110.c: Likewise.
+	* iconvdata/big5.c: Likewise.
+	* iconvdata/euc-cn.c: Likewise.
+	* iconvdata/euc-jp.c: Likewise.
+	* iconvdata/euc-kr.c: Likewise.
+	* iconvdata/euc-tw.c: Likewise.
+	* iconvdata/gbk.c: Likewise.
+	* iconvdata/iso-2022-cn.c: Likewise.
+	* iconvdata/iso-2022-jp.c: Likewise.
+	* iconvdata/iso-2022-kr.c: Likewise.
+	* iconvdata/iso646.c: Likewise.
+	* iconvdata/iso_6937-2.c: Likewise.
+	* iconvdata/iso_6937.c: Likewise.
+	* iconvdata/johab.c: Likewise.
+	* iconvdata/sjis.c: Likewise.
+	* iconvdata/t.61.c: Likewise.
+	* iconvdata/uhc.c: Likewise.
+	* iconvdata/unicode.c: Likewise.
+	* iconvdata/utf-16.c: Likewise.
+
+	* locale/programs/simple-hash.c: Little optimizations.  Remove K&R
+	prototypes.
+
+	* malloc/Versions [libc] (GLIBC_2.2): Add mcheck_check_all.
+	* malloc/mcheck.c (mcheck_check_all): Renamed from check_all and made
+	public.
+	* malloc/mcheck.h (mcheck_check_all): Declare.
+
+	* stdio-common/Makefile (tests): Add tst-obprintf.
+
 2000-03-28  Roland McGrath  <roland@baalperazim.frob.com>
 
 	* sysdeps/generic/bits/sigthread.h: Clean up conditionals.
diff --git a/iconv/skeleton.c b/iconv/skeleton.c
index 726a76f00e..ad381ec77c 100644
--- a/iconv/skeleton.c
+++ b/iconv/skeleton.c
@@ -117,6 +117,73 @@ static int to_object;
 #endif
 
 
+/* Define macros which can access unaligned buffers.  These macros are
+   supposed to be used only in code outside the inner loops.  For the inner
+   loops we have other definitions which allow optimized access.  */
+#ifdef _STRING_ARCH_unaligned
+/* We can handle unaligned memory access.  */
+# define get16(addr) *((uint16_t *) (addr))
+# define get32(addr) *((uint32_t *) (addr))
+
+/* We need no special support for writing values either.  */
+# define put16(addr, val) *((uint16_t *) (addr)) = (val)
+# define put32(addr, val) *((uint32_t *) (addr)) = (val)
+#else
+/* Distinguish between big endian and little endian.  */
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+#  define get16(addr) \
+     (((__const unsigned char *) (addr))[1] << 8			      \
+      | ((__const unsigned char *) (addr))[0])
+#  define get32(addr) \
+     (((((__const unsigned char *) (addr))[3] << 8			      \
+	| ((__const unsigned char *) (addr))[2]) << 8			      \
+       | ((__const unsigned char *) (addr))[1]) << 8			      \
+      | ((__const unsigned char *) (addr))[0])
+
+# define put16(addr, val) \
+     ({ uint16_t __val = (val);						      \
+	((__const unsigned char *) (addr))[0] = __val;			      \
+	((__const unsigned char *) (addr))[1] = __val >> 8;		      \
+	(void) 0; })
+# define put32(addr, val) \
+     ({ uint16_t __val = (val);						      \
+	((__const unsigned char *) (addr))[0] = __val;			      \
+	__val >>= 8;							      \
+	((__const unsigned char *) (addr))[1] = __val;			      \
+	__val >>= 8;							      \
+	((__const unsigned char *) (addr))[2] = __val;			      \
+	__val >>= 8;							      \
+	((__const unsigned char *) (addr))[3] = __val;			      \
+	(void) 0; })
+# else
+#  define get16(addr) \
+     (((__const unsigned char *) (addr))[0] << 8			      \
+      | ((__const unsigned char *) (addr))[1])
+#  define get32(addr) \
+     (((((__const unsigned char *) (addr))[0] << 8			      \
+	| ((__const unsigned char *) (addr))[1]) << 8			      \
+       | ((__const unsigned char *) (addr))[2]) << 8			      \
+      | ((__const unsigned char *) (addr))[3])
+
+# define put16(addr, val) \
+     ({ uint16_t __val = (val);						      \
+	((__const unsigned char *) (addr))[1] = __val;			      \
+	((__const unsigned char *) (addr))[2] = __val >> 8;		      \
+	(void) 0; })
+# define put32(addr, val) \
+     ({ uint16_t __val = (val);						      \
+	((__const unsigned char *) (addr))[3] = __val;			      \
+	__val >>= 8;							      \
+	((__const unsigned char *) (addr))[2] = __val;			      \
+	__val >>= 8;							      \
+	((__const unsigned char *) (addr))[1] = __val;			      \
+	__val >>= 8;							      \
+	((__const unsigned char *) (addr))[0] = __val;			      \
+	(void) 0; })
+# endif
+#endif
+
+
 /* For conversions from a fixed width character sets to another fixed width
    character set we we can define RESET_INPUT_BUFFER is necessary.  */
 #if !defined RESET_INPUT_BUFFER && !defined SAVE_RESET_STATE
@@ -230,6 +297,33 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
       unsigned char *outbuf = data->__outbuf;
       unsigned char *outend = data->__outbufend;
       unsigned char *outstart;
+#ifdef _STRING_ARCH_unaligned
+# define unaligned 0
+#else
+      /* The following assumes that encodings, which have a variable length
+	 what might unalign a buffer even though it is a aligned in the
+	 beginning, either don't have the minimal number of bytes as a divisor
+	 of the maximum length or have a minimum length of 1.  This is true
+	 for all known and supported encodings.  */
+      int unaligned;
+
+      unaligned = ((FROM_DIRECTION
+		    && ((MIN_NEEDED_FROM > 1
+			 && MAX_NEEDED_FROM % MIN_NEEDED_FROM == 0
+			 && (uintptr_t) inptr % MIN_NEEDED_FROM != 0)
+			|| (MIN_NEEDED_TO > 1
+			    && MAX_NEEDED_TO % MIN_NEEDED_TO == 0
+			    && (uintptr_t) outbuf % MIN_NEEDED_TO != 0)))
+		   || (!FROM_DIRECTION
+		       && ((MIN_NEEDED_FROM > 1
+			    && MAX_NEEDED_FROM % MIN_NEEDED_FROM == 0
+			    && (uintptr_t) outbuf % MIN_NEEDED_FROM != 0)
+			   || (MIN_NEEDED_TO > 1
+			       && MAX_NEEDED_TO % MIN_NEEDED_TO == 0
+			       && (uintptr_t) inptr % MIN_NEEDED_TO != 0))));
+# define GEN_unaligned(name) GEN_unaligned2 (name)
+# define GEN_unaligned2(name) name##_unaligned
+#endif
 
       /* This variable is used to count the number of characters we
 	 actually converted.  */
@@ -250,16 +344,36 @@ FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data,
 	  SAVE_RESET_STATE (1);
 #endif
 
-	  if (FROM_DIRECTION)
-	    /* Run the conversion loop.  */
-	    status = FROM_LOOP (inbuf, inbufend, &outbuf, outend,
-				data->__statep, step->__data, &converted
-				EXTRA_LOOP_ARGS);
+	  if (!unaligned)
+	    {
+	      if (FROM_DIRECTION)
+		/* Run the conversion loop.  */
+		status = FROM_LOOP (inbuf, inbufend, &outbuf, outend,
+				    data->__statep, step->__data, &converted
+				    EXTRA_LOOP_ARGS);
+	      else
+		/* Run the conversion loop.  */
+		status = TO_LOOP (inbuf, inbufend, &outbuf, outend,
+				  data->__statep, step->__data, &converted
+				  EXTRA_LOOP_ARGS);
+	    }
+#ifndef _STRING_ARCH_unaligned
 	  else
-	    /* Run the conversion loop.  */
-	    status = TO_LOOP (inbuf, inbufend, &outbuf, outend,
-			      data->__statep, step->__data, &converted
-			      EXTRA_LOOP_ARGS);
+	    {
+	      if (FROM_DIRECTION)
+		/* Run the conversion loop.  */
+		status = GEN_unaligned (FROM_LOOP) (inbuf, inbufend, &outbuf,
+						    outend, data->__statep,
+						    step->__data, &converted
+						    EXTRA_LOOP_ARGS);
+	      else
+		/* Run the conversion loop.  */
+		status = GEN_unaligned (TO_LOOP) (inbuf, inbufend, &outbuf,
+						  outend, data->__statep,
+						  step->__data, &converted
+						  EXTRA_LOOP_ARGS);
+	    }
+#endif
 
 	  /* We finished one use of the loops.  */
 	  ++data->__invocation_counter;
diff --git a/iconvdata/8bit-gap.c b/iconvdata/8bit-gap.c
index 5ab2975bde..b633c475b8 100644
--- a/iconvdata/8bit-gap.c
+++ b/iconvdata/8bit-gap.c
@@ -1,6 +1,6 @@
 /* Generic conversion to and from 8bit charsets,
    converting from UCS using gaps.
-   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -55,7 +55,8 @@ struct gap
 	break;								      \
       }									      \
 									      \
-    *((uint32_t *) outptr)++ = ch;					      \
+    put32 (outptr, ch);							      \
+    outptr += 4;							      \
     ++inptr;								      \
   }
 #include <iconv/loop.c>
@@ -68,7 +69,7 @@ struct gap
 #define BODY \
   {									      \
     const struct gap *rp = from_idx;					      \
-    uint32_t ch = *((uint32_t *) inptr);				      \
+    uint32_t ch = get32 (inptr);					      \
     unsigned char res;							      \
 									      \
     if (ch >= 0xffff)							      \
diff --git a/iconvdata/8bit-generic.c b/iconvdata/8bit-generic.c
index bd9da7a576..3543bdf004 100644
--- a/iconvdata/8bit-generic.c
+++ b/iconvdata/8bit-generic.c
@@ -1,5 +1,5 @@
 /* Generic conversion to and from 8bit charsets.
-   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -41,7 +41,8 @@
 	break;								      \
       }									      \
 									      \
-    *((uint32_t *) outptr)++ = ch;					      \
+    put32 (outptr, ch);							      \
+    outptr += 4;							      \
     ++inptr;								      \
   }
 #include <iconv/loop.c>
@@ -53,7 +54,7 @@
 #define LOOPFCT			TO_LOOP
 #define BODY \
   {									      \
-    uint32_t ch = *((uint32_t *) inptr);				      \
+    uint32_t ch = get32 (inptr);					      \
 									      \
     if (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0])		      \
 	|| (ch != 0 && from_ucs4[ch] == '\0'))				      \
diff --git a/iconvdata/TESTS b/iconvdata/TESTS
index 50ef97acd1..69d268490f 100644
--- a/iconvdata/TESTS
+++ b/iconvdata/TESTS
@@ -1,5 +1,5 @@
 # Available tests for iconv(1) (and therefore iconv(3)) in GNU libc.
-# Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+# Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 # Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 #
@@ -38,12 +38,12 @@ ISO-8859-6		ISO-8859-6		Y	UTF8
 ISO-8859-7		ISO-8859-7		Y	UTF8
 ISO-8859-8		ISO-8859-8		Y	UTF8
 ISO-8859-9		ISO-8859-9		Y	UTF8
-ISO-8859-10		ISO-8859-10		Y	UCS2 UTF8
+ISO-8859-10		ISO-8859-10		Y	UCS-2BE UTF8
 ISO-8859-14		ISO-8859-14		Y	UTF8
 ISO-8859-15		ISO-8859-15		Y	UTF8
 ANSI_X3.4-1968		ANSI_X3.4-1968		Y	UTF8
 BS_4730			BS_4730			Y	UTF8
-CSA_Z243.4-1985-1	CSA_Z243.4-1985-1	Y	UCS2
+CSA_Z243.4-1985-1	CSA_Z243.4-1985-1	Y	UCS-2BE
 CSA_Z243.4-1985-2	CSA_Z243.4-1985-2	Y	UCS4
 DIN_66003		DIN_66003		Y	UTF8
 DS_2089			DS_2089			Y	UTF8
diff --git a/iconvdata/ansi_x3.110.c b/iconvdata/ansi_x3.110.c
index 35658b50d4..1dd214bbe5 100644
--- a/iconvdata/ansi_x3.110.c
+++ b/iconvdata/ansi_x3.110.c
@@ -1,5 +1,5 @@
 /* Generic conversion to and from ANSI_X3.110-1983.
-   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -441,7 +441,8 @@ static const char from_ucs4[][2] =
       }									      \
 									      \
     inptr += incr;							      \
-    *((uint32_t *) outptr)++ = ch;					      \
+    put32 (outptr, ch);							      \
+    outptr += 4;							      \
   }
 #include <iconv/loop.c>
 
@@ -454,7 +455,7 @@ static const char from_ucs4[][2] =
 #define BODY \
   {									      \
     char tmp[2];							      \
-    uint32_t ch = *((uint32_t *) inptr);				      \
+    uint32_t ch = get32 (inptr);					      \
     const char *cp;							      \
 									      \
     if (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0]))		      \
diff --git a/iconvdata/big5.c b/iconvdata/big5.c
index 5551bbaba8..42d59c31ba 100644
--- a/iconvdata/big5.c
+++ b/iconvdata/big5.c
@@ -1,5 +1,5 @@
 /* Mapping tables for Big5 handling.
-   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -8475,7 +8475,8 @@ static const char from_ucs4_tab13[][2] =
     else								      \
       ++inptr;								      \
 									      \
-    *((uint32_t *) outptr)++ = ch;					      \
+    putr32 (outptr, ch);						      \
+    outptr += 4;							      \
   }
 #include <iconv/loop.c>
 
@@ -8487,7 +8488,7 @@ static const char from_ucs4_tab13[][2] =
 #define LOOPFCT			TO_LOOP
 #define BODY \
   {									      \
-    uint32_t ch = *((uint32_t *) inptr);				      \
+    uint32_t ch = get32 (inptr);					      \
     char buf[2];							      \
     const char *cp;							      \
 									      \
diff --git a/iconvdata/euc-cn.c b/iconvdata/euc-cn.c
index da10cdcc72..61601e7615 100644
--- a/iconvdata/euc-cn.c
+++ b/iconvdata/euc-cn.c
@@ -1,5 +1,5 @@
 /* Mapping tables for EUC-CN handling.
-   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -88,7 +88,8 @@
 	  inptr += 2;							      \
 	}								      \
 									      \
-    *((uint32_t *) outptr)++ = ch;					      \
+    put32 (outptr, ch);							      \
+    outptr += 4;							      \
   }
 #include <iconv/loop.c>
 
@@ -100,7 +101,7 @@
 #define LOOPFCT			TO_LOOP
 #define BODY \
   {									      \
-    uint32_t ch = *((uint32_t *) inptr);				      \
+    uint32_t ch = get32 (inptr);					      \
 									      \
     if (ch <= L'\x7f')							      \
       /* It's plain ASCII.  */						      \
diff --git a/iconvdata/euc-jp.c b/iconvdata/euc-jp.c
index 3d97c01ce9..2c25d7afda 100644
--- a/iconvdata/euc-jp.c
+++ b/iconvdata/euc-jp.c
@@ -1,5 +1,5 @@
 /* Mapping tables for EUC-JP handling.
-   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -121,7 +121,8 @@
 	  }								      \
       }									      \
 									      \
-    *((uint32_t *) outptr)++ = ch;					      \
+    put32 (outptr, ch);							      \
+    outptr += 4;							      \
   }
 #include <iconv/loop.c>
 
@@ -133,7 +134,7 @@
 #define LOOPFCT			TO_LOOP
 #define BODY \
   {									      \
-    uint32_t ch = *((uint32_t *) inptr);				      \
+    uint32_t ch = get32 (inptr);					      \
 									      \
     if (ch <= 0x7f)							      \
       /* It's plain ASCII.  */						      \
diff --git a/iconvdata/euc-kr.c b/iconvdata/euc-kr.c
index f74d7748f9..19516b62eb 100644
--- a/iconvdata/euc-kr.c
+++ b/iconvdata/euc-kr.c
@@ -1,5 +1,5 @@
 /* Mapping tables for EUC-KR handling.
-   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jungshik Shin <jshin@pantheon.yale.edu>
    and Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -104,7 +104,8 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp)
 	  }								      \
       }									      \
 									      \
-    *((uint32_t *) outptr)++ = ch;					      \
+    put32 (outptr, ch);							      \
+    outptr += 4;							      \
   }
 #include <iconv/loop.c>
 
@@ -116,7 +117,7 @@ euckr_from_ucs4 (uint32_t ch, unsigned char *cp)
 #define LOOPFCT			TO_LOOP
 #define BODY \
   {									      \
-    uint32_t ch = *((uint32_t *) inptr);				      \
+    uint32_t ch = get32 (inptr);					      \
     unsigned char cp[2];						      \
 									      \
     /* Decomposing Hangul syllables not available in KS C 5601 into	      \
diff --git a/iconvdata/euc-tw.c b/iconvdata/euc-tw.c
index 036baaebb1..a508c848ef 100644
--- a/iconvdata/euc-tw.c
+++ b/iconvdata/euc-tw.c
@@ -1,5 +1,5 @@
 /* Mapping tables for EUC-TW handling.
-   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -115,7 +115,8 @@
 	  }								      \
       }									      \
 									      \
-    *((uint32_t *) outptr)++ = ch;					      \
+    put32 (outptr, ch);							      \
+    outptr += 4;							      \
   }
 #include <iconv/loop.c>
 
@@ -127,7 +128,7 @@
 #define LOOPFCT			TO_LOOP
 #define BODY \
   {									      \
-    uint32_t ch = *((uint32_t *) inptr);				      \
+    uint32_t ch = get32 (inptr);					      \
 									      \
     if (ch <= 0x7f)							      \
       /* It's plain ASCII.  */						      \
diff --git a/iconvdata/gbk.c b/iconvdata/gbk.c
index 45bfcbcada..9956ea36cf 100644
--- a/iconvdata/gbk.c
+++ b/iconvdata/gbk.c
@@ -1,5 +1,5 @@
 /* Mapping tables for GBK handling.
-   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Sean Chen <sean.chen@turbolinux.com>, 1999.
 
@@ -13167,7 +13167,8 @@ static const char __gbk_from_ucs4_tab12[][2] =
 	  inptr += 2;							      \
 	}								      \
 									      \
-    *((uint32_t *) outptr)++ = ch;					      \
+    put32 (outptr, ch);							      \
+    outptr += 4;							      \
   }
 #include <iconv/loop.c>
 
@@ -13179,7 +13180,7 @@ static const char __gbk_from_ucs4_tab12[][2] =
 #define LOOPFCT			TO_LOOP
 #define BODY \
   {									      \
-    uint32_t ch = *((uint32_t *) inptr);				      \
+    uint32_t ch = get32 (inptr);					      \
     unsigned char buf[2];						      \
     const unsigned char *cp = buf;					      \
 									      \
diff --git a/iconvdata/iso-2022-cn.c b/iconvdata/iso-2022-cn.c
index 563d173d66..1b0eefbd40 100644
--- a/iconvdata/iso-2022-cn.c
+++ b/iconvdata/iso-2022-cn.c
@@ -1,5 +1,5 @@
 /* Conversion module for ISO-2022-CN.
-   Copyright (C) 1999 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
 
@@ -221,7 +221,8 @@ enum
 	  }								      \
       }									      \
 									      \
-    *((uint32_t *) outptr)++ = ch;					      \
+    put32 (outptr, ch);							      \
+    outptr += 4;							      \
   }
 #define EXTRA_LOOP_DECLS	, int *setp
 #define INIT_PARAMS		int set = *setp & CURRENT_MASK; \
@@ -240,7 +241,7 @@ enum
     uint32_t ch;							      \
     size_t written = 0;							      \
 									      \
-    ch = *((uint32_t *) inptr);						      \
+    ch = get32 (inptr);							      \
 									      \
     /* First see whether we can write the character using the currently	      \
        selected character set.  */					      \
diff --git a/iconvdata/iso-2022-jp.c b/iconvdata/iso-2022-jp.c
index a3c9f7d354..decb6c12a7 100644
--- a/iconvdata/iso-2022-jp.c
+++ b/iconvdata/iso-2022-jp.c
@@ -1,5 +1,5 @@
 /* Conversion module for ISO-2022-JP.
-   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -436,7 +436,8 @@ gconv_end (struct __gconv_step *data)
 	  }								      \
       }									      \
 									      \
-    *((uint32_t *) outptr)++ = ch;					      \
+    put32 (outptr, ch);							      \
+    outptr += 4;							      \
   }
 #define EXTRA_LOOP_DECLS	, enum variant var, int *setp
 #define INIT_PARAMS		int set = *setp % 0x100, set2 = *setp / 0x100
@@ -454,7 +455,7 @@ gconv_end (struct __gconv_step *data)
     uint32_t ch;							      \
     size_t written = 0;							      \
 									      \
-    ch = *((uint32_t *) inptr);						      \
+    ch = get32 (inptr);							      \
 									      \
     /* First see whether we can write the character using the currently	      \
        selected character set.  */					      \
diff --git a/iconvdata/iso-2022-kr.c b/iconvdata/iso-2022-kr.c
index 8ed5d210ff..ea03353065 100644
--- a/iconvdata/iso-2022-kr.c
+++ b/iconvdata/iso-2022-kr.c
@@ -1,5 +1,5 @@
 /* Conversion module for ISO-2022-KR.
-   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -189,7 +189,8 @@ enum
 	  }								      \
       }									      \
 									      \
-    *((uint32_t *) outptr)++ = ch;					      \
+    put32 (outptr, ch);							      \
+    outptr += 4;							      \
   }
 #define EXTRA_LOOP_DECLS	, int *setp
 #define INIT_PARAMS		int set = *setp
@@ -207,7 +208,7 @@ enum
     uint32_t ch;							      \
     size_t written = 0;							      \
 									      \
-    ch = *((uint32_t *) inptr);						      \
+    ch = get32 (inptr);							      \
 									      \
     /* First see whether we can write the character using the currently	      \
        selected character set.  */					      \
diff --git a/iconvdata/iso646.c b/iconvdata/iso646.c
index 5b2ba7282f..c8d0a02121 100644
--- a/iconvdata/iso646.c
+++ b/iconvdata/iso646.c
@@ -1,5 +1,5 @@
 /* Conversion to and from the various ISO 646 CCS.
-   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -410,7 +410,8 @@ gconv_end (struct __gconv_step *data)
 	result = failure;						      \
 	break;								      \
       }									      \
-    *((uint32_t *) outptr)++ = ch;					      \
+    put32 (outptr, ch);							      \
+    outptr += 4;							      \
     ++inptr;								      \
   }
 #define EXTRA_LOOP_DECLS	, enum variant var
@@ -426,7 +427,7 @@ gconv_end (struct __gconv_step *data)
     unsigned char ch;							      \
     int failure = __GCONV_OK;						      \
 									      \
-    ch = *((uint32_t *) inptr);						      \
+    ch = get32 (inptr);							      \
     switch (*((uint32_t *) inptr))					      \
       {									      \
       case 0x23:							      \
diff --git a/iconvdata/iso_6937-2.c b/iconvdata/iso_6937-2.c
index 1ec0976aac..a688b7c695 100644
--- a/iconvdata/iso_6937-2.c
+++ b/iconvdata/iso_6937-2.c
@@ -1,5 +1,5 @@
 /* Generic conversion to and from ISO 6937-2.
-   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -446,7 +446,8 @@ static const char from_ucs4[][2] =
 	++inptr;							      \
       }									      \
 									      \
-    *((uint32_t *) outptr)++ = ch;					      \
+    put32 (outptr, ch);							      \
+    outptr += 4;							      \
   }
 #include <iconv/loop.c>
 
@@ -459,7 +460,7 @@ static const char from_ucs4[][2] =
 #define BODY \
   {									      \
     char tmp[2];							      \
-    uint32_t ch = *((uint32_t *) inptr);				      \
+    uint32_t ch = get32 (inptr);					      \
     const char *cp;							      \
 									      \
     if (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0]))		      \
diff --git a/iconvdata/iso_6937.c b/iconvdata/iso_6937.c
index ca4ab0fada..81e5d0c867 100644
--- a/iconvdata/iso_6937.c
+++ b/iconvdata/iso_6937.c
@@ -1,5 +1,5 @@
 /* Generic conversion to and from ISO 6937.
-   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -438,7 +438,8 @@ static const char from_ucs4[][2] =
 	++inptr;							      \
       }									      \
 									      \
-    *((uint32_t *) outptr)++ = ch;					      \
+    put32 (outptr, ch);							      \
+    outptr += 4;							      \
   }
 #include <iconv/loop.c>
 
@@ -451,7 +452,7 @@ static const char from_ucs4[][2] =
 #define BODY \
   {									      \
     char tmp[2];							      \
-    uint32_t ch = *((uint32_t *) inptr);				      \
+    uint32_t ch = get32 (inptr);					      \
     const char *cp;							      \
 									      \
     if (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0]))		      \
diff --git a/iconvdata/johab.c b/iconvdata/johab.c
index 4cff932c2f..1822b0d491 100644
--- a/iconvdata/johab.c
+++ b/iconvdata/johab.c
@@ -1,5 +1,5 @@
 /* Mapping tables for JOHAB handling.
-   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jungshik Shin <jshin@pantheon.yale.edu>
    and Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -274,7 +274,8 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
 	inptr += 2;							      \
       }									      \
 									      \
-    *((uint32_t *) outptr)++ = ch;					      \
+    put32 (outptr, ch);							      \
+    outptr += 4;							      \
   }
 #include <iconv/loop.c>
 
@@ -286,7 +287,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
 #define LOOPFCT			TO_LOOP
 #define BODY \
   {									      \
-    uint32_t ch = *((uint32_t *) inptr);				      \
+    uint32_t ch = get32 (inptr);					      \
     /*									      \
        if (ch >= (sizeof (from_ucs4_lat1) / sizeof (from_ucs4_lat1[0])))      \
 	 {								      \
diff --git a/iconvdata/sjis.c b/iconvdata/sjis.c
index d18ab9b25e..4ca7ce985a 100644
--- a/iconvdata/sjis.c
+++ b/iconvdata/sjis.c
@@ -1,5 +1,5 @@
 /* Mapping tables for SJIS handling.
-   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -4410,7 +4410,8 @@ static const char from_ucs4_extra[0x100][2] =
 	  }								      \
       }									      \
 									      \
-    *((uint32_t *) outptr)++ = ch;					      \
+    put32 (outptr, ch);							      \
+    outptr += 4;							      \
   }
 #include <iconv/loop.c>
 
@@ -4422,7 +4423,7 @@ static const char from_ucs4_extra[0x100][2] =
 #define LOOPFCT			TO_LOOP
 #define BODY \
   {									      \
-    uint32_t ch = *((uint32_t *) inptr);				      \
+    uint32_t ch = get32 (inptr);					      \
     const char *cp;							      \
 									      \
     if (ch >= (sizeof (from_ucs4_lat1) / sizeof (from_ucs4_lat1[0])))	      \
diff --git a/iconvdata/t.61.c b/iconvdata/t.61.c
index 2b8d896238..10a52a1f38 100644
--- a/iconvdata/t.61.c
+++ b/iconvdata/t.61.c
@@ -1,5 +1,5 @@
 /* Generic conversion to and from T.61.
-   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -422,7 +422,8 @@ static const char from_ucs4[][2] =
 	break;								      \
       }									      \
 									      \
-    *((uint32_t *) outptr)++ = ch;					      \
+    put32 (outptr, ch);							      \
+    outptr += 4;							      \
   }
 #include <iconv/loop.c>
 
@@ -435,7 +436,7 @@ static const char from_ucs4[][2] =
 #define BODY \
   {									      \
     char tmp[2];							      \
-    uint32_t ch = *((uint32_t *) inptr);				      \
+    uint32_t ch = get32 (inptr);					      \
     const char *cp;							      \
 									      \
     if (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0]))		      \
diff --git a/iconvdata/uhc.c b/iconvdata/uhc.c
index ac4be8a5aa..e42cb2e000 100644
--- a/iconvdata/uhc.c
+++ b/iconvdata/uhc.c
@@ -1,5 +1,5 @@
 /* Mapping tables for UHC handling.
-   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jungshik Shin <jshin@pantheon.yale.edu>, 1998.
 
@@ -3140,7 +3140,8 @@ static const char uhc_hangul_from_ucs[11172][2] =
 	  }								      \
       }									      \
 									      \
-    *((uint32_t *) outptr)++ = ch;					      \
+    put32 (outptr, ch);							      \
+    outptr += 4;							      \
   }
 #include <iconv/loop.c>
 
@@ -3152,7 +3153,7 @@ static const char uhc_hangul_from_ucs[11172][2] =
 #define LOOPFCT			TO_LOOP
 #define BODY \
   {									      \
-    uint32_t ch = *((uint32_t *) inptr);				      \
+    uint32_t ch = get32 (inptr);					      \
 									      \
     if (ch < 0x7f)							      \
       /* XXX Think about 0x5c ; '\'.  */				      \
diff --git a/iconvdata/unicode.c b/iconvdata/unicode.c
index b29976b0c8..0db7a0106b 100644
--- a/iconvdata/unicode.c
+++ b/iconvdata/unicode.c
@@ -50,10 +50,10 @@
 	  if (inptr + 2 > inbufend)					      \
 	    return __GCONV_EMPTY_INPUT;					      \
 									      \
-	  if (*(uint16_t *) inptr == BOM)				      \
+	  if (get16u (inptr) == BOM)					      \
 	    /* Simply ignore the BOM character.  */			      \
 	    inptr += 2;							      \
-	  else if (*(uint16_t *) inptr == BOM_OE)			      \
+	  else if (get16u (inptr) == BOM_OE)				      \
 	    {								      \
 	      ((struct unicode_data *) step->__data)->swap = 1;		      \
 	      inptr += 2;						      \
@@ -66,7 +66,7 @@
       if (outbuf + 2 > outend)						      \
 	return __GCONV_FULL_OUTPUT;					      \
 									      \
-      *(uint16_t *) outbuf = BOM;					      \
+      put16u (outbuf, BOM);						      \
       outbuf += 2;							      \
     }									      \
   swap = ((struct unicode_data *) step->__data)->swap;
@@ -147,7 +147,7 @@ gconv_end (struct __gconv_step *data)
 #define LOOPFCT			TO_LOOP
 #define BODY \
   {									      \
-    uint32_t c = *((uint32_t *) inptr);					      \
+    uint32_t c = get32 (inptr);						      \
 									      \
     if (c >= 0x10000)							      \
       {									      \
@@ -155,7 +155,7 @@ gconv_end (struct __gconv_step *data)
 	break;								      \
       }									      \
 									      \
-    *((uint16_t *) outptr) = c;						      \
+    put16 (outptr, c);							      \
 									      \
     outptr += 2;							      \
     inptr += 4;								      \
@@ -171,12 +171,12 @@ gconv_end (struct __gconv_step *data)
 #define LOOPFCT			FROM_LOOP
 #define BODY \
   {									      \
-    uint16_t u1 = *(uint16_t *) inptr;					      \
+    uint16_t u1 = get16 (inptr);					      \
 									      \
     if (swap)								      \
       u1 = bswap_16 (u1);						      \
 									      \
-    *((uint32_t *) outptr) = u1;					      \
+    put32 (outptr, u1);							      \
 									      \
     inptr += 2;								      \
     outptr += 4;							      \
diff --git a/iconvdata/utf-16.c b/iconvdata/utf-16.c
index c7e677e376..b0b9c47896 100644
--- a/iconvdata/utf-16.c
+++ b/iconvdata/utf-16.c
@@ -52,10 +52,10 @@
 	  if (inptr + 2 > inbufend)					      \
 	    return __GCONV_EMPTY_INPUT;					      \
 									      \
-	  if (*(uint16_t *) inptr == BOM)				      \
+	  if (get16u (inptr) == BOM)					      \
 	    /* Simply ignore the BOM character.  */			      \
 	    inptr += 2;							      \
-	  else if (*(uint16_t *) inptr == BOM_OE)			      \
+	  else if (get16u (inptr) == BOM_OE)				      \
 	    {								      \
 	      ((struct utf16_data *) step->__data)->swap = 1;		      \
 	      inptr += 2;						      \
@@ -69,7 +69,7 @@
       if (outbuf + 2 > outend)						      \
 	return __GCONV_FULL_OUTPUT;					      \
 									      \
-      *(uint16_t *) outbuf = BOM;					      \
+      put16u (outbuf, BOM);						      \
       outbuf += 2;							      \
     }
 #define EXTRA_LOOP_ARGS		, var, data, swap
@@ -193,7 +193,7 @@ gconv_end (struct __gconv_step *data)
 #define LOOPFCT			TO_LOOP
 #define BODY \
   {									      \
-    uint32_t c = *((uint32_t *) inptr);					      \
+    uint32_t c = get32 (inptr);						      \
 									      \
     if (swap)								      \
       {									      \
@@ -213,12 +213,12 @@ gconv_end (struct __gconv_step *data)
 		break;							      \
 	      }								      \
 									      \
-	    *((uint16_t *) outptr) = bswap_16 (0xd7c0 + (c >> 10));	      \
+	    put16 (outptr, bswap_16 (0xd7c0 + (c >> 10)));		      \
 	    outptr += 2;						      \
-	    *((uint16_t *) outptr) = bswap_16 (0xdc00 + (c & 0x3ff));	      \
+	    put16 (outptr, bswap_16 (0xdc00 + (c & 0x3ff)));		      \
 	  }								      \
 	else								      \
-	  *((uint16_t *) outptr) = bswap_16 (c);			      \
+	  put16 (outptr, bswap_16 (c));					      \
       }									      \
     else								      \
       {									      \
@@ -238,12 +238,12 @@ gconv_end (struct __gconv_step *data)
 		break;							      \
 	      }								      \
 									      \
-	    *((uint16_t *) outptr) = 0xd7c0 + (c >> 10);		      \
+	    put16 (outptr, 0xd7c0 + (c >> 10));				      \
 	    outptr += 2;						      \
-	    *((uint16_t *) outptr) = 0xdc00 + (c & 0x3ff);		      \
+	    put16 (outptr, 0xdc00 + (c & 0x3ff));			      \
 	  }								      \
 	else								      \
-	  *((uint16_t *) outptr) = c;					      \
+	  put16 (outptr, c);						      \
       }									      \
     outptr += 2;							      \
     inptr += 4;								      \
@@ -260,7 +260,7 @@ gconv_end (struct __gconv_step *data)
 #define LOOPFCT			FROM_LOOP
 #define BODY \
   {									      \
-    uint16_t u1 = *(uint16_t *) inptr;					      \
+    uint16_t u1 = get16 (inptr);					      \
 									      \
     if (swap)								      \
       {									      \
@@ -269,7 +269,7 @@ gconv_end (struct __gconv_step *data)
 	if (u1 < 0xd800 || u1 > 0xdfff)					      \
 	  {								      \
 	    /* No surrogate.  */					      \
-	    *((uint32_t *) outptr) = u1;				      \
+	    put32 (outptr, u1);				      \
 	    inptr += 2;							      \
 	  }								      \
 	else								      \
@@ -286,16 +286,18 @@ gconv_end (struct __gconv_step *data)
 		break;							      \
 	      }								      \
 									      \
-	    u2 = bswap_16 (((uint16_t *) inptr)[1]);			      \
+	    inptr += 2;							      \
+	    u2 = bswap_16 (get16 (inptr));				      \
 	    if (u2 < 0xdc00 || u2 >= 0xdfff)				      \
 	      {								      \
 		/* This is no valid second word for a surrogate.  */	      \
 		result = __GCONV_ILLEGAL_INPUT;				      \
+		inptr -= 2;						      \
 		break;							      \
 	      }								      \
 									      \
-	    *((uint32_t *) outptr) = ((u1 - 0xd7c0) << 10) + (u2 - 0xdc00);   \
-	    inptr += 4;							      \
+	    put32 (outptr, ((u1 - 0xd7c0) << 10) + (u2 - 0xdc00));	      \
+	    inptr += 2;							      \
 	  }								      \
       }									      \
     else								      \
@@ -303,7 +305,7 @@ gconv_end (struct __gconv_step *data)
 	if (u1 < 0xd800 || u1 > 0xdfff)					      \
 	  {								      \
 	    /* No surrogate.  */					      \
-	    *((uint32_t *) outptr) = u1;				      \
+	    put32 (outptr, u1);						      \
 	    inptr += 2;							      \
 	  }								      \
 	else								      \
@@ -320,16 +322,18 @@ gconv_end (struct __gconv_step *data)
 		break;							      \
 	      }								      \
 									      \
-	    u2 = ((uint16_t *) inptr)[1];				      \
+	    inptr += 2;							      \
+	    u2 = get16 (inptr);						      \
 	    if (u2 < 0xdc00 || u2 >= 0xdfff)				      \
 	      {								      \
 		/* This is no valid second word for a surrogate.  */	      \
 		result = __GCONV_ILLEGAL_INPUT;				      \
+		inptr -= 2;						      \
 		break;							      \
 	      }								      \
 									      \
-	    *((uint32_t *) outptr) = ((u1 - 0xd7c0) << 10) + (u2 - 0xdc00);   \
-	    inptr += 4;							      \
+	    put32 (outptr, ((u1 - 0xd7c0) << 10) + (u2 - 0xdc00));	      \
+	    inptr += 2;							      \
 	  }								      \
       }									      \
     outptr += 4;							      \
diff --git a/locale/programs/simple-hash.c b/locale/programs/simple-hash.c
index 5d8a93cda9..a21e9bbfe0 100644
--- a/locale/programs/simple-hash.c
+++ b/locale/programs/simple-hash.c
@@ -1,5 +1,5 @@
 /* Implement simple hashing table with string based keys.
-   Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1994, 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
    Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, October 1994.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -53,7 +53,8 @@
 # define bcopy(s, d, n)	memcpy ((d), (s), (n))
 #endif
 
-void *xmalloc __P ((size_t __n));
+extern void *xmalloc (size_t __n);
+extern void *xcalloc (size_t __n, size_t __m);
 
 typedef struct hash_entry
 {
@@ -66,15 +67,14 @@ typedef struct hash_entry
 hash_entry;
 
 /* Prototypes for local functions.  */
-static void insert_entry_2 __P ((hash_table *htab, const void *key,
-				 size_t keylen, unsigned long hval,
-				 size_t idx, void *data));
-static size_t lookup __P ((hash_table *htab, const void *key, size_t keylen,
-			   unsigned long int hval));
-static size_t lookup_2 __P ((hash_table *htab, const void *key,
-			     size_t keylen, unsigned long int hval));
-static unsigned long compute_hashval __P ((const void *key, size_t keylen));
-static int is_prime __P ((unsigned long int candidate));
+static void insert_entry_2 (hash_table *htab, const void *key, size_t keylen,
+			    unsigned long hval, size_t idx, void *data);
+static size_t lookup (hash_table *htab, const void *key, size_t keylen,
+		      unsigned long int hval);
+static size_t lookup_2 (hash_table *htab, const void *key, size_t keylen,
+			unsigned long int hval);
+static unsigned long compute_hashval (const void *key, size_t keylen);
+static int is_prime (unsigned long int candidate);
 
 
 int
@@ -89,11 +89,10 @@ init_hash (htab, init_size)
   htab->size = init_size;
   htab->filled = 0;
   htab->first = NULL;
-  htab->table = (void *) xmalloc ((init_size + 1) * sizeof (hash_entry));
+  htab->table = (void *) xcalloc (init_size + 1, sizeof (hash_entry));
   if (htab->table == NULL)
     return -1;
 
-  memset (htab->table, '\0', (init_size + 1) * sizeof (hash_entry));
   obstack_init (&htab->mem_pool);
 
   return 0;
@@ -171,9 +170,7 @@ insert_entry_2 (htab, key, keylen, hval, idx, data)
       htab->size = next_prime (htab->size * 2);
       htab->filled = 0;
       htab->first = NULL;
-      htab->table = (void *) xmalloc ((1 + htab->size)
-				      * sizeof (hash_entry));
-      memset (htab->table, '\0', (1 + htab->size) * sizeof (hash_entry));
+      htab->table = (void *) xcalloc (1 + htab->size, sizeof (hash_entry));
 
       for (idx = 1; idx <= old_size; ++idx)
 	if (table[idx].used)
diff --git a/malloc/Versions b/malloc/Versions
index 43207549a6..759a0636c1 100644
--- a/malloc/Versions
+++ b/malloc/Versions
@@ -50,6 +50,6 @@ libc {
   }
   GLIBC_2.2 {
     # m*
-    mcheck_pedantic;
+    mcheck_check_all; mcheck_pedantic;
   }
 }
diff --git a/malloc/mcheck.c b/malloc/mcheck.c
index 0d32fc17f7..9aa07a2e1f 100644
--- a/malloc/mcheck.c
+++ b/malloc/mcheck.c
@@ -103,9 +103,8 @@ checkhdr (hdr)
   return status;
 }
 
-static void check_all __P ((void));
-static void
-check_all ()
+void
+mcheck_check_all ()
 {
   /* Walk through all the active blocks and test whether they were tempered
      with.  */
@@ -172,7 +171,7 @@ freehook (ptr, caller)
      const __ptr_t caller;
 {
   if (pedantic)
-    check_all ();
+    mcheck_check_all ();
   if (ptr)
     {
       struct hdr *hdr = ((struct hdr *) ptr) - 1;
@@ -200,7 +199,7 @@ mallochook (size, caller)
   struct hdr *hdr;
 
   if (pedantic)
-    check_all ();
+    mcheck_check_all ();
 
   __malloc_hook = old_malloc_hook;
   if (old_malloc_hook != NULL)
@@ -230,7 +229,7 @@ reallochook (ptr, size, caller)
   __malloc_size_t osize;
 
   if (pedantic)
-    check_all ();
+    mcheck_check_all ();
 
   if (ptr)
     {
@@ -331,8 +330,10 @@ int
 mcheck_pedantic (func)
       void (*func) __P ((enum mcheck_status));
 {
-  pedantic = 1;
-  return mcheck (func);
+  int res = mcheck (func);
+  if (res == 0)
+    pedantic = 1;
+  return res;
 }
 
 enum mcheck_status
diff --git a/malloc/mcheck.h b/malloc/mcheck.h
index 2b8bbb2cbf..afc7335403 100644
--- a/malloc/mcheck.h
+++ b/malloc/mcheck.h
@@ -45,6 +45,9 @@ extern int mcheck (void (*__abortfunc) (enum mcheck_status)) __THROW;
    the memory handling functions is called.  This can be very slow.  */
 extern int mcheck_pedantic (void (*__abortfunc) (enum mcheck_status)) __THROW;
 
+/* Force check of all blocks now.  */
+extern void mcheck_check_all (void);
+
 /* Check for aberrations in a particular malloc'd block.  You must have
    called `mcheck' already.  These are the same checks that `mcheck' does
    when you free or reallocate a block.  */
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
index c93ead6454..85f3b8ec1a 100644
--- a/stdio-common/Makefile
+++ b/stdio-common/Makefile
@@ -54,7 +54,7 @@ tests := tst-printf tstscanf test_rdwr test-popen tstgetln test-fseek \
 	 bug1 bug2 bug3 bug4 bug5 bug6 bug7 bug8 bug9 bug10 bug11 bug12 bug13 \
 	 tfformat tiformat tllformat tstdiomisc tst-printfsz tst-wc-printf \
 	 scanf1 scanf2 scanf3 scanf4 scanf5 scanf7 scanf8 scanf9 scanf10 \
-	 scanf12 tst-tmpnam tst-cookie
+	 scanf12 tst-tmpnam tst-cookie tst-obprintf
 
 include ../Rules