diff --git a/assert/__libc_assert_fail.c b/assert/__libc_assert_fail.c
index b50637a893..2d4654bd41 100644
--- a/assert/__libc_assert_fail.c
+++ b/assert/__libc_assert_fail.c
@@ -28,6 +28,6 @@ __libc_assert_fail (const char *assertion, const char *file, unsigned int line,
   char linebuf[INT_BUFSIZE_BOUND (unsigned int)];
   array_end (linebuf)[-1] = '\0';
   char *linestr = _itoa_word (line, array_end (linebuf) - 1, 10, 0);
-  __libc_message ("Fatal glibc error: %s:%s (%s): assertion failed: %s\n",
-                  file, linestr, function, assertion);
+  __libc_assert_message ("Fatal glibc error: %s:%s (%s): assertion failed: %s\n",
+			 file, linestr, function, assertion);
 }
diff --git a/assert/assert-perr.c b/assert/assert-perr.c
index 83f0b3a76f..1de96c8790 100644
--- a/assert/assert-perr.c
+++ b/assert/assert-perr.c
@@ -15,10 +15,15 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+#include <_itoa.h>
+#include <array_length.h>
 #include <assert.h>
+#include <intprops.h>
 #include <libintl.h>
 #include <string.h>
+#include <stdio.h>
 
+extern const char *__progname;
 
 /* This function, when passed an error number, a filename, and a line
    number, prints a message on the standard error stream of the form:
@@ -31,8 +36,19 @@ __assert_perror_fail (int errnum,
 {
   char errbuf[1024];
 
-  char *e = __strerror_r (errnum, errbuf, sizeof errbuf);
-  __assert_fail_base (_("%s%s%s:%u: %s%sUnexpected error: %s.\n"),
-		      e, file, line, function);
+  const char *e = __strerror_r (errnum, errbuf, sizeof errbuf);
+
+  char linebuf[INT_BUFSIZE_BOUND (unsigned int)];
+  array_end (linebuf)[-1] = '\0';
+  char *linestr = _itoa_word (line, array_end (linebuf) - 1, 10, 0);
+
+  __libc_assert_message (_("%s%s%s:%s: %s%sUnexpected error: %s.\n"),
+			 __progname,
+			 __progname[0] ? ": " : "",
+			 file,
+			 linestr,
+			 function ? function : "",
+			 function ? ": " : "",
+			 e);
 }
 libc_hidden_def (__assert_perror_fail)
diff --git a/assert/assert.c b/assert/assert.c
index d21d76fa62..095266e45d 100644
--- a/assert/assert.c
+++ b/assert/assert.c
@@ -15,115 +15,31 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+#include <array_length.h>
 #include <intprops.h>
 #include <ldsodefs.h>
 #include <libc-pointer-arith.h>
 #include <libintl.h>
-#include <libio/iolibio.h>
-#include <setvmaname.h>
-#include <sys/uio.h>
-#include <unistd.h>
+#include <stdio.h>
 
 
 extern const char *__progname;
 
-#define fflush(s) _IO_fflush (s)
-
-/* This function, when passed a string containing an asserted
-   expression, a filename, and a line number, prints a message
-   on the standard error stream of the form:
-	a.c:10: foobar: Assertion `a == b' failed.
-   It then aborts program execution via a call to `abort'.  */
-
-#ifdef FATAL_PREPARE_INCLUDE
-# include FATAL_PREPARE_INCLUDE
-#endif
-
-
-void
-__assert_fail_base (const char *fmt, const char *assertion, const char *file,
-		    unsigned int line, const char *function)
-{
-  char *str;
-
-#ifdef FATAL_PREPARE
-  FATAL_PREPARE;
-#endif
-
-  int total = __asprintf (&str, fmt,
-			  __progname, __progname[0] ? ": " : "",
-			  file, line,
-			  function ? function : "", function ? ": " : "",
-			  assertion);
-  if (total >= 0)
-    {
-      /* Print the message.  */
-      (void) __fxprintf (NULL, "%s", str);
-      (void) fflush (stderr);
-
-      total = ALIGN_UP (total + sizeof (struct abort_msg_s) + 1,
-			GLRO(dl_pagesize));
-      struct abort_msg_s *buf = __mmap (NULL, total, PROT_READ | PROT_WRITE,
-					MAP_ANON | MAP_PRIVATE, -1, 0);
-      if (__glibc_likely (buf != MAP_FAILED))
-	{
-	  buf->size = total;
-	  strcpy (buf->msg, str);
-	  __set_vma_name (buf, total, " glibc: assert");
-
-	  /* We have to free the old buffer since the application might
-	     catch the SIGABRT signal.  */
-	  struct abort_msg_s *old = atomic_exchange_acquire (&__abort_msg, buf);
-
-	  if (old != NULL)
-	    __munmap (old, old->size);
-	}
-
-      free (str);
-    }
-  else
-    {
-      /* At least print a minimal message.  */
-      char linebuf[INT_STRLEN_BOUND (int) + sizeof ":: "];
-      struct iovec v[9];
-      int i = 0;
-
-#define WS(s) (v[i].iov_len = strlen (v[i].iov_base = (void *) (s)), i++)
-
-      if (__progname)
-	{
-	  WS (__progname);
-	  WS (": ");
-	}
-
-      WS (file);
-      v[i++] = (struct iovec) {.iov_base = linebuf,
-	.iov_len = sprintf (linebuf, ":%d: ", line)};
-
-      if (function)
-	{
-	  WS (function);
-	  WS (": ");
-	}
-
-      WS ("Assertion `");
-      WS (assertion);
-      /* We omit the '.' here so that the assert tests can tell when
-         this code path is taken.  */
-      WS ("' failed\n");
-
-      (void) __writev (STDERR_FILENO, v, i);
-    }
-
-  abort ();
-}
-
-
 #undef __assert_fail
 void
 __assert_fail (const char *assertion, const char *file, unsigned int line,
 	       const char *function)
 {
-  __assert_fail_base (_("%s%s%s:%u: %s%sAssertion `%s' failed.\n"),
-		      assertion, file, line, function);
+  char linebuf[INT_BUFSIZE_BOUND (unsigned int)];
+  array_end (linebuf)[-1] = '\0';
+  char *linestr = _itoa_word (line, array_end (linebuf) - 1, 10, 0);
+
+  __libc_assert_message (_("%s%s%s:%s: %s%sAssertion `%s' failed.\n"),
+			 __progname,
+			 __progname[0] ? ": " : "",
+			 file,
+			 linestr,
+			 function ? function : "",
+			 function ? ": " : "",
+			 assertion);
 }
diff --git a/assert/test-assert-2.c b/assert/test-assert-2.c
index 6d54ef9ba6..9997c98d1a 100644
--- a/assert/test-assert-2.c
+++ b/assert/test-assert-2.c
@@ -127,7 +127,7 @@ check_posix (const char *buf, int rv, int line,
 }
 
 static void
-one_test (void (*func)(void *), int which_path)
+one_test (void (*func)(void *))
 {
   struct support_capture_subprocess sp;
   int rv;
@@ -140,17 +140,7 @@ one_test (void (*func)(void *), int which_path)
 
   check_posix (sp.err.buffer, rv, do_lineno, do_funcname, "1 == 2");
 
-  /* Look for intentional subtle differences in messages to verify
-     that the intended code path was taken.  */
-  switch (which_path)
-    {
-    case 0:
-      TEST_VERIFY (strstr (sp.err.buffer, "failed.\n") != NULL);
-      break;
-    case 1:
-      TEST_VERIFY (strstr (sp.err.buffer, "failed\n") != NULL);
-      break;
-    }
+  TEST_VERIFY (strstr (sp.err.buffer, "failed.\n") != NULL);
 
   support_capture_subprocess_free (&sp);
 }
@@ -158,8 +148,8 @@ one_test (void (*func)(void *), int which_path)
 static int
 do_test(void)
 {
-  one_test (test_assert_normal, 0);
-  one_test (test_assert_nomalloc, 1);
+  one_test (test_assert_normal);
+  one_test (test_assert_nomalloc);
 
   return 0;
 }
diff --git a/include/stdio.h b/include/stdio.h
index e48d709919..683b212d14 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -171,33 +171,64 @@ extern void __fortify_fail (const char *msg) __attribute__ ((__noreturn__));
 libc_hidden_proto (__fortify_fail)
 
 /* The maximum number of varargs allowed in a __libc_message format string */
-#define LIBC_MESSAGE_MAX_ARGS 4
+#define LIBC_MESSAGE_MAX_ARGS 7
 
-_Noreturn void __libc_message_impl (const char *__fnt, ...) attribute_hidden
-     __attribute__ ((__format__ (__printf__, 1, 2)));
+_Noreturn void __libc_message_impl (const char *__vmaname, const char *__fmt,
+				    ...) attribute_hidden
+     __attribute__ ((__format__ (__printf__, 2, 3)));
+
+#define __libc_fatal_vma_name  "glibc: fatal"
+#define __libc_assert_vma_name "glibc: assert"
 
 #define __libc_message0(fmt) \
-   __libc_message_impl (fmt)
+   __libc_message_impl (__libc_fatal_vma_name, fmt)
 #define __libc_message1(fmt, a1) \
-   __libc_message_impl (fmt, a1)
+   __libc_message_impl (__libc_fatal_vma_name, fmt, a1)
 #define __libc_message2(fmt, a1, a2) \
-   __libc_message_impl (fmt, a1, a2)
+   __libc_message_impl (__libc_fatal_vma_name, fmt, a1, a2)
 #define __libc_message3(fmt, a1, a2, a3) \
-   __libc_message_impl (fmt, a1, a2, a3)
+   __libc_message_impl (__libc_fatal_vma_name, fmt, a1, a2, a3)
 #define __libc_message4(fmt, a1, a2, a3, a4) \
-   __libc_message_impl (fmt, a1, a2, a3, a4)
+   __libc_message_impl (__libc_fatal_vma_name, fmt, a1, a2, a3, a4)
+#define __libc_message5(fmt, a1, a2, a3, a4, a5) \
+   __libc_message_impl (__libc_fatal_vma_name, fmt, a1, a2, a3, a4, a5)
+#define __libc_message6(fmt, a1, a2, a3, a4, a5, a6) \
+   __libc_message_impl (__libc_fatal_vma_name, fmt, a1, a2, a3, a4, a5, a6)
+#define __libc_message7(fmt, a1, a2, a3, a4, a5, a6, a7) \
+   __libc_message_impl (__libc_fatal_vma_name, fmt, a1, a2, a3, a4, a5, a6, a7)
+
+#define __libc_assert_message0(fmt) \
+   __libc_message_impl (__libc_assert_vma_name, fmt)
+#define __libc_assert_message1(fmt, a1) \
+   __libc_message_impl (__libc_assert_vma_name, fmt, a1)
+#define __libc_assert_message2(fmt, a1, a2) \
+   __libc_message_impl (__libc_assert_vma_name, fmt, a1, a2)
+#define __libc_assert_message3(fmt, a1, a2, a3) \
+   __libc_message_impl (__libc_assert_vma_name, fmt, a1, a2, a3)
+#define __libc_assert_message4(fmt, a1, a2, a3, a4) \
+   __libc_message_impl (__libc_assert_vma_name, fmt, a1, a2, a3, a4)
+#define __libc_assert_message5(fmt, a1, a2, a3, a4, a5) \
+   __libc_message_impl (__libc_assert_vma_name, fmt, a1, a2, a3, a4, a5)
+#define __libc_assert_message6(fmt, a1, a2, a3, a4, a5, a6) \
+   __libc_message_impl (__libc_assert_vma_name, fmt, a1, a2, a3, a4, a5, a6)
+#define __libc_assert_message7(fmt, a1, a2, a3, a4, a5, a6, a7) \
+   __libc_message_impl (__libc_assert_vma_name, fmt, a1, a2, a3, a4, a5, a6, a7)
 
 #define __libc_message_concat_x(a,b)  a##b
 #define __libc_message_concat(a,b)    __libc_message_concat_x (a, b)
 
-#define __libc_message_nargs_x(a0,a1,a2,a3,a4,a5,a6,...) a6
+#define __libc_message_nargs_x(a0,a1,a2,a3,a4,a5,a6,a7,...) a7
 #define __libc_message_nargs(b, ...) \
-   __libc_message_nargs_x (__VA_ARGS__,6,5,4,3,2,1,0,)
+   __libc_message_nargs_x (__VA_ARGS__,7,6,5,4,3,2,1,0,)
 #define __libc_message_disp(b, ...) \
    __libc_message_concat (b, __libc_message_nargs (__VA_ARGS__))(__VA_ARGS__)
+
 #define __libc_message(...) \
    __libc_message_disp (__libc_message, __VA_ARGS__)
 
+#define __libc_assert_message(...) \
+   __libc_message_disp (__libc_assert_message, __VA_ARGS__)
+
 /* Acquire ownership of STREAM.  */
 extern void __flockfile (FILE *__stream) attribute_hidden;
 
diff --git a/sysdeps/posix/libc_fatal.c b/sysdeps/posix/libc_fatal.c
index d90cc6c681..818f911675 100644
--- a/sysdeps/posix/libc_fatal.c
+++ b/sysdeps/posix/libc_fatal.c
@@ -49,7 +49,7 @@ writev_for_fatal (int fd, const struct iovec *iov, size_t niov, size_t total)
 
 /* Abort with an error message.  */
 void
-__libc_message_impl (const char *fmt, ...)
+__libc_message_impl (const char *vma_name, const char *fmt, ...)
 {
   va_list ap;
   int fd = -1;
@@ -119,7 +119,7 @@ __libc_message_impl (const char *fmt, ...)
 	    wp = mempcpy (wp, iov[cnt].iov_base, iov[cnt].iov_len);
 	  *wp = '\0';
 
-	  __set_vma_name (buf, total, " glibc: fatal");
+	  __set_vma_name (buf, total, vma_name);
 
 	  /* We have to free the old buffer since the application might
 	     catch the SIGABRT signal.  */
