[PATCH] Introduce error_exit as a noreturn variant of error (EXIT_FAILURE, ...)

Mark Wielaard mark@klomp.org
Sun Mar 27 21:32:15 GMT 2022


error (EXIT_FAILURE, ...) should be noreturn but on some systems it
isn't.  This may cause warnings about code that should not be
reachable.  So have an explicit error_exit wrapper that is noreturn
(because it calls exit explicitly).  Use error_exit in all tools under
the src directory.

https://bugzilla.redhat.com/show_bug.cgi?id=2068692

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 lib/ChangeLog     |   4 ++
 lib/system.h      |  10 +++
 src/ChangeLog     |  14 ++++
 src/addr2line.c   |   3 +-
 src/ar.c          |  41 ++++++-----
 src/arlib.c       |   8 +--
 src/elfcompress.c |   5 +-
 src/nm.c          |  24 +++----
 src/objdump.c     |  16 ++---
 src/readelf.c     | 170 +++++++++++++++++++---------------------------
 src/size.c        |  22 +++---
 src/strings.c     |  11 ++-
 src/strip.c       |  58 +++++++---------
 src/unstrip.c     | 166 ++++++++++++++++++++++----------------------
 14 files changed, 264 insertions(+), 288 deletions(-)

https://code.wildebeest.org/git/user/mjw/elfutils/commit/?h=error_exit

diff --git a/lib/ChangeLog b/lib/ChangeLog
index 8f4d4d9f..6b76f647 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,7 @@
+2022-03-27  Mark Wielaard  <mark@klomp.org>
+
+	* system.h: define error_exit.
+
 2021-02-14  Alexander Miller  <alex.miller@gmx.de>
 
 	* eu-config.h (used_in_asm): New macro.
diff --git a/lib/system.h b/lib/system.h
index edbc8488..d3f42c91 100644
--- a/lib/system.h
+++ b/lib/system.h
@@ -1,5 +1,6 @@
 /* Declarations for common convenience functions.
    Copyright (C) 2006-2011 Red Hat, Inc.
+   Copyright (C) 2022 Mark J. Wielaard <mark@klomp.org>
    This file is part of elfutils.
 
    This file is free software; you can redistribute it and/or modify
@@ -51,6 +52,15 @@ void error(int status, int errnum, const char *format, ...);
 #error "err.h or error.h must be available"
 #endif
 
+/* error (EXIT_FAILURE, ...) should be noreturn but on some systems it
+   isn't.  This may cause warnings about code that should not be reachable.
+   So have an explicit error_exit wrapper that is noreturn (because it
+   calls exit explicitly).  */
+#define error_exit(errnum,...) do { \
+    error (EXIT_FAILURE,errnum,__VA_ARGS__); \
+    exit (EXIT_FAILURE); \
+  } while (0)
+
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 # define LE32(n)	(n)
 # define LE64(n)	(n)
diff --git a/src/ChangeLog b/src/ChangeLog
index 1e3c31a8..c0a3db3f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,17 @@
+2022-03-27  Mark Wielaard  <mark@klomp.org>
+
+	* addr2line.c: Replace error (EXIT_FAILURE, ...) with error_exit(...).
+	* ar.c: Likewise.
+	* arlib.c: Likewise.
+	* elfcompress.c: Likewise.
+	* nm.c: Likewise.
+	* objdump.c: Likewise.
+	* readelf.c: Likewise.
+	* size.c: Likewise.
+	* strings.c: Likewise.
+	* strip.c: Likewise.
+	* unstrip.c: Likewise.
+
 2022-03-24  Mark Wielaard  <mark@klomp.org>
 
 	* elflint.c (check_note_data): Recognize NT_FDO_PACKAGING_METADATA.
diff --git a/src/addr2line.c b/src/addr2line.c
index 7c8d3a72..25db2926 100644
--- a/src/addr2line.c
+++ b/src/addr2line.c
@@ -524,8 +524,7 @@ adjust_to_section (const char *name, uintmax_t *addr, Dwfl *dwfl)
   Dwfl_Module *mod = NULL;
   if (dwfl_getmodules (dwfl, &see_one_module, &mod, 0) != 0
       || mod == NULL)
-    error (EXIT_FAILURE, 0, _("Section syntax requires"
-				     " exactly one module"));
+    error_exit (0, _("Section syntax requires exactly one module"));
 
   int nscn = dwfl_module_relocations (mod);
   for (int i = 0; i < nscn; ++i)
diff --git a/src/ar.c b/src/ar.c
index ab6098f0..9e8df120 100644
--- a/src/ar.c
+++ b/src/ar.c
@@ -386,8 +386,8 @@ open_archive (const char *arfname, int flags, int mode, Elf **elf,
       if (miss_allowed)
 	return -1;
 
-      error (EXIT_FAILURE, errno, _("cannot open archive '%s'"),
-	     arfname);
+      error_exit (errno, _("cannot open archive '%s'"),
+		  arfname);
     }
 
   if (elf != NULL)
@@ -396,16 +396,16 @@ open_archive (const char *arfname, int flags, int mode, Elf **elf,
 
       *elf = elf_begin (fd, cmd, NULL);
       if (*elf == NULL)
-	error (EXIT_FAILURE, 0, _("cannot open archive '%s': %s"),
-	       arfname, elf_errmsg (-1));
+	error_exit (0, _("cannot open archive '%s': %s"),
+		    arfname, elf_errmsg (-1));
 
       if (flags == O_RDONLY && elf_kind (*elf) != ELF_K_AR)
-	error (EXIT_FAILURE, 0, _("%s: not an archive file"), arfname);
+	error_exit (0, _("%s: not an archive file"), arfname);
     }
 
   if (st != NULL && fstat (fd, st) != 0)
-    error (EXIT_FAILURE, errno, _("cannot stat archive '%s'"),
-	   arfname);
+    error_exit (errno, _("cannot stat archive '%s'"),
+		arfname);
 
   return fd;
 }
@@ -469,14 +469,13 @@ do_oper_extract (int oper, const char *arfname, char **argv, int argc,
   int fd = open_archive (arfname, O_RDONLY, 0, &elf, NULL, false);
 
   if (hcreate (2 * argc) == 0)
-    error (EXIT_FAILURE, errno, _("cannot create hash table"));
+    error_exit (errno, _("cannot create hash table"));
 
   for (int cnt = 0; cnt < argc; ++cnt)
     {
       ENTRY entry = { .key = argv[cnt], .data = &argv[cnt] };
       if (hsearch (entry, ENTER) == NULL)
-	error (EXIT_FAILURE, errno,
-	       _("cannot insert into hash table"));
+	error_exit (errno, _("cannot insert into hash table"));
     }
 
   struct stat st;
@@ -924,14 +923,13 @@ do_oper_delete (const char *arfname, char **argv, int argc,
   int fd = open_archive (arfname, O_RDONLY, 0, &elf, &st, false);
 
   if (hcreate (2 * argc) == 0)
-    error (EXIT_FAILURE, errno, _("cannot create hash table"));
+    error_exit (errno, _("cannot create hash table"));
 
   for (int cnt = 0; cnt < argc; ++cnt)
     {
       ENTRY entry = { .key = argv[cnt], .data = &argv[cnt] };
       if (hsearch (entry, ENTER) == NULL)
-	error (EXIT_FAILURE, errno,
-	       _("cannot insert into hash table"));
+	error_exit (errno, _("cannot insert into hash table"));
     }
 
   arlib_init ();
@@ -1131,7 +1129,7 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc,
   if (oper != oper_qappend)
     {
       if (hcreate (2 * argc) == 0)
-	error (EXIT_FAILURE, errno, _("cannot create hash table"));
+	error_exit (errno, _("cannot create hash table"));
 
       for (int cnt = 0; cnt < argc; ++cnt)
 	{
@@ -1139,8 +1137,7 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc,
 	  entry.key = full_path ? argv[cnt] : basename (argv[cnt]);
 	  entry.data = &argv[cnt];
 	  if (hsearch (entry, ENTER) == NULL)
-	    error (EXIT_FAILURE, errno,
-		   _("cannot insert into hash table"));
+	    error_exit (errno, _("cannot insert into hash table"));
 	}
     }
 
@@ -1214,7 +1211,7 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc,
     next:
       cmd = elf_next (subelf);
       if (elf_end (subelf) != 0)
-	error (EXIT_FAILURE, 0, "%s: %s", arfname, elf_errmsg (-1));
+	error_exit (0, "%s: %s", arfname, elf_errmsg (-1));
     }
 
   if (oper != oper_qappend)
@@ -1222,8 +1219,8 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc,
 
  no_old:
   if (member != NULL)
-    error (EXIT_FAILURE, 0, _("position member %s not found"),
-	   member);
+    error_exit (0, _("position member %s not found"),
+		member);
 
   if (oper == oper_move)
     {
@@ -1305,8 +1302,8 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc,
 	      found[cnt]->mem = elf_rawfile (newelf, &found[cnt]->size);
 	      if (found[cnt]->mem == NULL
 		  || elf_cntl (newelf, ELF_C_FDDONE) != 0)
-		error (EXIT_FAILURE, 0, _("cannot read %s: %s"),
-		       argv[cnt], elf_errmsg (-1));
+		error_exit (0, _("cannot read %s: %s"),
+			    argv[cnt], elf_errmsg (-1));
 
 	      close (newfd);
 
@@ -1374,7 +1371,7 @@ do_oper_insert (int oper, const char *arfname, char **argv, int argc,
 		|| (arhdr = elf_getarhdr (subelf)) == NULL)
 	      /* This should never happen since we already looked at the
 		 archive content.  But who knows...  */
-	      error (EXIT_FAILURE, 0, "%s: %s", arfname, elf_errmsg (-1));
+	      error_exit (0, "%s: %s", arfname, elf_errmsg (-1));
 
 	    arlib_add_symbols (subelf, arfname, arhdr->ar_name, cur_off);
 
diff --git a/src/arlib.c b/src/arlib.c
index a14c44d3..c09fc3c6 100644
--- a/src/arlib.c
+++ b/src/arlib.c
@@ -210,8 +210,8 @@ arlib_add_symbols (Elf *elf, const char *arfname, const char *membername,
 {
   if (sizeof (off) > sizeof (uint32_t) && off > ~((uint32_t) 0))
     /* The archive is too big.  */
-    error (EXIT_FAILURE, 0, _("the archive '%s' is too large"),
-	   arfname);
+    error_exit (0, _("the archive '%s' is too large"),
+		arfname);
 
   /* We only add symbol tables for ELF files.  It makes not much sense
      to add symbols from executables but we do so for compatibility.
@@ -223,8 +223,8 @@ arlib_add_symbols (Elf *elf, const char *arfname, const char *membername,
   GElf_Ehdr ehdr_mem;
   GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
   if (ehdr == NULL)
-    error (EXIT_FAILURE, 0, _("cannot read ELF header of %s(%s): %s"),
-	   arfname, membername, elf_errmsg (-1));
+    error_exit (0, _("cannot read ELF header of %s(%s): %s"),
+		arfname, membername, elf_errmsg (-1));
 
   GElf_Word symtype;
   if (ehdr->e_type == ET_REL)
diff --git a/src/elfcompress.c b/src/elfcompress.c
index 2c6d91ba..92f2fac8 100644
--- a/src/elfcompress.c
+++ b/src/elfcompress.c
@@ -1342,12 +1342,11 @@ main (int argc, char **argv)
   /* Should already be handled by ARGP_KEY_NO_ARGS case above,
      just sanity check.  */
   if (remaining >= argc)
-    error (EXIT_FAILURE, 0, N_("No input file given"));
+    error_exit (0, N_("No input file given"));
 
   /* Likewise for the ARGP_KEY_ARGS case above, an extra sanity check.  */
   if (foutput != NULL && remaining + 1 < argc)
-    error (EXIT_FAILURE, 0,
-	   N_("Only one input file allowed together with '-o'"));
+    error_exit (0, N_("Only one input file allowed together with '-o'"));
 
   elf_version (EV_CURRENT);
 
diff --git a/src/nm.c b/src/nm.c
index 2ae29c4d..16647589 100644
--- a/src/nm.c
+++ b/src/nm.c
@@ -137,8 +137,8 @@ static int handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
 
 
 #define INTERNAL_ERROR(fname) \
-  error (EXIT_FAILURE, 0, _("%s: INTERNAL ERROR %d (%s): %s"),      \
-	 fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1))
+  error_exit (0, _("%s: INTERNAL ERROR %d (%s): %s"),      \
+	      fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1))
 
 
 /* Internal representation of symbols.  */
@@ -378,7 +378,7 @@ process_file (const char *fname, bool more_than_one)
 	    INTERNAL_ERROR (fname);
 
 	  if (close (fd) != 0)
-	    error (EXIT_FAILURE, errno, _("while closing '%s'"), fname);
+	    error_exit (errno, _("while closing '%s'"), fname);
 
 	  return result;
 	}
@@ -390,7 +390,7 @@ process_file (const char *fname, bool more_than_one)
 	    INTERNAL_ERROR (fname);
 
 	  if (close (fd) != 0)
-	    error (EXIT_FAILURE, errno, _("while closing '%s'"), fname);
+	    error_exit (errno, _("while closing '%s'"), fname);
 
 	  return result;
 	}
@@ -700,8 +700,7 @@ get_local_names (Dwarf *dbg)
 	    struct local_name **tres = tsearch (newp, &local_root,
 						local_compare);
 	    if (tres == NULL)
-              error (EXIT_FAILURE, errno,
-                     _("cannot create search tree"));
+              error_exit (errno, _("cannot create search tree"));
 	    else if (*tres != newp)
 	      free (newp);
 	  }
@@ -741,8 +740,7 @@ show_symbols_sysv (Ebl *ebl, GElf_Word strndx, const char *fullname,
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   /* Cache the section names.  */
   Elf_Scn *scn = NULL;
@@ -1234,8 +1232,7 @@ show_symbols (int fd, Ebl *ebl, GElf_Ehdr *ehdr,
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   /* The section is that large.  */
   size_t size = shdr->sh_size;
@@ -1331,10 +1328,9 @@ show_symbols (int fd, Ebl *ebl, GElf_Ehdr *ehdr,
      can use the data memory instead of copying again if what we read
      is a 64 bit file.  */
   if (nentries > SIZE_MAX / sizeof (GElf_SymX))
-    error (EXIT_FAILURE, 0,
-          _("%s: entries (%zd) in section %zd `%s' is too large"),
-          fullname, nentries, elf_ndxscn (scn),
-          elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
+    error_exit (0, _("%s: entries (%zd) in section %zd `%s' is too large"),
+		fullname, nentries, elf_ndxscn (scn),
+		elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
   GElf_SymX *sym_mem;
   if (nentries * sizeof (GElf_SymX) < MAX_STACK_ALLOC)
     sym_mem = (GElf_SymX *) alloca (nentries * sizeof (GElf_SymX));
diff --git a/src/objdump.c b/src/objdump.c
index f7ea6c92..b32de17d 100644
--- a/src/objdump.c
+++ b/src/objdump.c
@@ -100,8 +100,8 @@ static int handle_elf (Elf *elf, const char *prefix, const char *fname,
 
 
 #define INTERNAL_ERROR(fname) \
-  error (EXIT_FAILURE, 0, _("%s: INTERNAL ERROR %d (%s): %s"),      \
-	 fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1))
+  error_exit (0, _("%s: INTERNAL ERROR %d (%s): %s"),      \
+	      fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1))
 
 
 /* List of sections which should be used.  */
@@ -255,7 +255,7 @@ process_file (const char *fname, bool more_than_one)
 	    INTERNAL_ERROR (fname);
 
 	  if (close (fd) != 0)
-	    error (EXIT_FAILURE, errno, _("while close `%s'"), fname);
+	    error_exit (errno, _("while close `%s'"), fname);
 
 	  return result;
 	}
@@ -267,7 +267,7 @@ process_file (const char *fname, bool more_than_one)
 	    INTERNAL_ERROR (fname);
 
 	  if (close (fd) != 0)
-	    error (EXIT_FAILURE, errno, _("while close `%s'"), fname);
+	    error_exit (errno, _("while close `%s'"), fname);
 
 	  return result;
 	}
@@ -684,7 +684,7 @@ show_disasm (Ebl *ebl, const char *fname, uint32_t shstrndx)
 {
   DisasmCtx_t *ctx = disasm_begin (ebl, ebl->elf, NULL /* XXX TODO */);
   if (ctx == NULL)
-    error (EXIT_FAILURE, 0, _("cannot disassemble"));
+    error_exit (0, _("cannot disassemble"));
 
   Elf_Scn *scn = NULL;
   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
@@ -755,8 +755,7 @@ handle_elf (Elf *elf, const char *prefix, const char *fname,
   /* Get the backend for this object file type.  */
   Ebl *ebl = ebl_openbackend (elf);
   if (ebl == NULL)
-    error (EXIT_FAILURE, 0,
-	   _("cannot create backend for elf file"));
+    error_exit (0, _("cannot create backend for elf file"));
 
   printf ("%s: elf%d-%s\n\n",
 	  fname, gelf_getclass (elf) == ELFCLASS32 ? 32 : 64,
@@ -777,8 +776,7 @@ handle_elf (Elf *elf, const char *prefix, const char *fname,
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   int result = 0;
   if (print_disasm)
diff --git a/src/readelf.c b/src/readelf.c
index 93fb5989..41d64d32 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -828,7 +828,7 @@ create_dwfl (int fd, const char *fname)
   /* Duplicate an fd for dwfl_report_offline to swallow.  */
   int dwfl_fd = dup (fd);
   if (unlikely (dwfl_fd < 0))
-    error (EXIT_FAILURE, errno, "dup");
+    error_exit (errno, "dup");
 
   /* Use libdwfl in a trivial way to open the libdw handle for us.
      This takes care of applying relocations to DWARF data in ET_REL files.  */
@@ -951,15 +951,13 @@ process_elf_file (Dwfl_Module *dwflmod, int fd)
 
   /* Determine the number of sections.  */
   if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
-    error (EXIT_FAILURE, 0,
-	   _("cannot determine number of sections: %s"),
-	   elf_errmsg (-1));
+    error_exit (0, _("cannot determine number of sections: %s"),
+		elf_errmsg (-1));
 
   /* Determine the number of phdrs.  */
   if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
-    error (EXIT_FAILURE, 0,
-	   _("cannot determine number of program headers: %s"),
-	   elf_errmsg (-1));
+    error_exit (0, _("cannot determine number of program headers: %s"),
+		elf_errmsg (-1));
 
   /* For an ET_REL file, libdwfl has adjusted the in-core shdrs and
      may have applied relocation to some sections.  If there are any
@@ -1226,9 +1224,8 @@ print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
     {
       size_t sections;
       if (unlikely (elf_getshdrnum (ebl->elf, &sections) < 0))
-	error (EXIT_FAILURE, 0,
-	       _("cannot get number of sections: %s"),
-	       elf_errmsg (-1));
+	error_exit (0, _("cannot get number of sections: %s"),
+		    elf_errmsg (-1));
 
       printf (_("\
 There are %zd section headers, starting at offset %#" PRIx64 ":\n\
@@ -1238,9 +1235,8 @@ There are %zd section headers, starting at offset %#" PRIx64 ":\n\
 
   /* Get the section header string table index.  */
   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index: %s"),
-	   elf_errmsg (-1));
+    error_exit (0, _("cannot get section header string table index: %s"),
+		elf_errmsg (-1));
 
   puts (_("Section Headers:"));
 
@@ -1262,15 +1258,15 @@ There are %zd section headers, starting at offset %#" PRIx64 ":\n\
       Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
 
       if (unlikely (scn == NULL))
-	error (EXIT_FAILURE, 0, _("cannot get section: %s"),
-	       elf_errmsg (-1));
+	error_exit (0, _("cannot get section: %s"),
+		    elf_errmsg (-1));
 
       /* Get the section header.  */
       GElf_Shdr shdr_mem;
       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
       if (unlikely (shdr == NULL))
-	error (EXIT_FAILURE, 0, _("cannot get section header: %s"),
-	       elf_errmsg (-1));
+	error_exit (0, _("cannot get section header: %s"),
+		    elf_errmsg (-1));
 
       char flagbuf[20];
       char *cp = flagbuf;
@@ -1436,9 +1432,8 @@ print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
 
   size_t sections;
   if (unlikely (elf_getshdrnum (ebl->elf, &sections) < 0))
-    error (EXIT_FAILURE, 0,
-           _("cannot get number of sections: %s"),
-           elf_errmsg (-1));
+    error_exit (0, _("cannot get number of sections: %s"),
+		elf_errmsg (-1));
 
   if (sections == 0)
     /* No sections in the file.  Punt.  */
@@ -1447,8 +1442,7 @@ print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   puts (_("\n Section to Segment mapping:\n  Segment Sections..."));
 
@@ -1461,8 +1455,8 @@ print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
       GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
       /* This must not happen.  */
       if (unlikely (phdr == NULL))
-	error (EXIT_FAILURE, 0, _("cannot get program header: %s"),
-	       elf_errmsg (-1));
+	error_exit (0, _("cannot get program header: %s"),
+		    elf_errmsg (-1));
 
       /* Iterate over the sections.  */
       bool in_relro = false;
@@ -1472,16 +1466,15 @@ print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
 	  Elf_Scn *scn = elf_getscn (ebl->elf, inner);
 	  /* This should not happen.  */
 	  if (unlikely (scn == NULL))
-	    error (EXIT_FAILURE, 0, _("cannot get section: %s"),
-		   elf_errmsg (-1));
+	    error_exit (0, _("cannot get section: %s"),
+			elf_errmsg (-1));
 
 	  /* Get the section header.  */
 	  GElf_Shdr shdr_mem;
 	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
 	  if (unlikely (shdr == NULL))
-	    error (EXIT_FAILURE, 0,
-		   _("cannot get section header: %s"),
-		   elf_errmsg (-1));
+	    error_exit (0, _("cannot get section header: %s"),
+			elf_errmsg (-1));
 
 	  if (shdr->sh_size > 0
 	      /* Compare allocated sections by VMA, unallocated
@@ -1598,8 +1591,7 @@ handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
 
@@ -1661,10 +1653,9 @@ print_scngrp (Ebl *ebl)
 			elf_ndxscn (scn));
 	      shdr = gelf_getshdr (scn, &shdr_mem);
 	      if (unlikely (shdr == NULL))
-		error (EXIT_FAILURE, 0,
-		       _("cannot get section [%zd] header: %s"),
-		       elf_ndxscn (scn),
-		       elf_errmsg (-1));
+		error_exit (0, _("cannot get section [%zd] header: %s"),
+			    elf_ndxscn (scn),
+			    elf_errmsg (-1));
 	    }
 	  handle_scngrp (ebl, scn, shdr);
 	}
@@ -1799,15 +1790,14 @@ handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
 
   /* Get the section header string table index.  */
   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
 
   glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
   if (glink == NULL)
-    error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"),
-	   elf_ndxscn (scn));
+    error_exit (0, _("invalid sh_link value in section %zu"),
+		elf_ndxscn (scn));
 
   printf (ngettext ("\
 \nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
@@ -2005,8 +1995,7 @@ handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   if (shdr->sh_info != 0)
     printf (ngettext ("\
@@ -2195,8 +2184,7 @@ handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   if (shdr->sh_info != 0)
     printf (ngettext ("\
@@ -2373,8 +2361,8 @@ print_symtab (Ebl *ebl, int type)
 	      size_t shstrndx;
 	      const char *sname;
 	      if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
-		error (EXIT_FAILURE, 0,
-		       _("cannot get section header string table index"));
+		error_exit (0,
+			    _("cannot get section header string table index"));
 	      sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
 	      if (sname == NULL || strcmp (sname, symbol_table_section) != 0)
 		continue;
@@ -2388,9 +2376,9 @@ print_symtab (Ebl *ebl, int type)
 			elf_ndxscn (scn));
 	      shdr = gelf_getshdr (scn, &shdr_mem);
 	      if (unlikely (shdr == NULL))
-		error (EXIT_FAILURE, 0,
-		       _("cannot get section [%zd] header: %s"),
-		       elf_ndxscn (scn), elf_errmsg (-1));
+		error_exit (0,
+			    _("cannot get section [%zd] header: %s"),
+			    elf_ndxscn (scn), elf_errmsg (-1));
 	    }
 	  handle_symtab (ebl, scn, shdr);
 	}
@@ -2449,15 +2437,14 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   GElf_Shdr glink_mem;
   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
 				   &glink_mem);
   if (glink == NULL)
-    error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"),
-	   elf_ndxscn (scn));
+    error_exit (0, _("invalid sh_link value in section %zu"),
+		elf_ndxscn (scn));
 
   /* Now we can compute the number of entries in the section.  */
   unsigned int nsyms = data->d_size / (class == ELFCLASS32
@@ -2715,15 +2702,14 @@ handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   GElf_Shdr glink_mem;
   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
 				   &glink_mem);
   if (glink == NULL)
-    error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"),
-	   elf_ndxscn (scn));
+    error_exit (0, _("invalid sh_link value in section %zu"),
+		elf_ndxscn (scn));
 
   printf (ngettext ("\
 \nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
@@ -2791,15 +2777,14 @@ handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   GElf_Shdr glink_mem;
   GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
 				   &glink_mem);
   if (glink == NULL)
-    error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"),
-	   elf_ndxscn (scn));
+    error_exit (0, _("invalid sh_link value in section %zu"),
+		elf_ndxscn (scn));
 
   int class = gelf_getclass (ebl->elf);
   printf (ngettext ("\
@@ -2878,8 +2863,7 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   /* We have to find the version definition section and extract the
      version names.  */
@@ -3102,8 +3086,8 @@ handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
 				   &glink_mem);
   size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
   if (glink == NULL)
-    error (EXIT_FAILURE, 0, _("invalid sh_link value in section %zu"),
-	   elf_ndxscn (scn));
+    error_exit (0, _("invalid sh_link value in section %zu"),
+		elf_ndxscn (scn));
 
   /* Print the header.  */
   printf (ngettext ("\
@@ -3474,8 +3458,7 @@ handle_hash (Ebl *ebl)
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   Elf_Scn *scn = NULL;
   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
@@ -3495,9 +3478,8 @@ handle_hash (Ebl *ebl)
 			elf_ndxscn (scn));
 	      shdr = gelf_getshdr (scn, &shdr_mem);
 	      if (unlikely (shdr == NULL))
-		error (EXIT_FAILURE, 0,
-		       _("cannot get section [%zd] header: %s"),
-		       elf_ndxscn (scn), elf_errmsg (-1));
+		error_exit (0, _("cannot get section [%zd] header: %s"),
+			    elf_ndxscn (scn), elf_errmsg (-1));
 	    }
 
 	  if (shdr->sh_type == SHT_HASH)
@@ -3524,8 +3506,7 @@ print_liblist (Ebl *ebl)
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
     {
@@ -3594,8 +3575,7 @@ print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
     {
@@ -3832,7 +3812,7 @@ print_dwarf_addr (Dwfl_Module *dwflmod,
 	  : (address_size == 0
 	     ? printf ("%#" PRIx64, address)
 	     : printf ("%#0*" PRIx64, 2 + address_size * 2, address)))) < 0)
-    error (EXIT_FAILURE, 0, _("sprintf failure"));
+    error_exit (0, _("sprintf failure"));
 }
 
 
@@ -11405,8 +11385,7 @@ print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   /* If the .debug_info section is listed as implicitly required then
      we must make sure to handle it before handling any other debug
@@ -11579,7 +11558,7 @@ print_core_item (unsigned int colno, char sep, unsigned int wrap,
   int out_len = vasprintf (&out, format, ap);
   va_end (ap);
   if (out_len == -1)
-    error (EXIT_FAILURE, 0, _("memory exhausted"));
+    error_exit (0, _("memory exhausted"));
 
   size_t n = name_width + sizeof ": " - 1 + out_len;
 
@@ -11629,8 +11608,8 @@ convert (Elf *core, Elf_Type type, uint_fast16_t count,
 		 ? elf32_xlatetom : elf64_xlatetom)
     (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
   if (d == NULL)
-    error (EXIT_FAILURE, 0,
-	   _("cannot convert core note data: %s"), elf_errmsg (-1));
+    error_exit (0, _("cannot convert core note data: %s"),
+		elf_errmsg (-1));
 
   return data + indata.d_size;
 }
@@ -12256,8 +12235,7 @@ handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
   if (data == NULL)
   elf_error:
-    error (EXIT_FAILURE, 0,
-	   _("cannot convert core note data: %s"), elf_errmsg (-1));
+    error_exit (0, _("cannot convert core note data: %s"), elf_errmsg (-1));
 
   const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
   for (size_t i = 0; i < nauxv; ++i)
@@ -12367,8 +12345,7 @@ handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
 {
   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
   if (data == NULL)
-    error (EXIT_FAILURE, 0,
-	   _("cannot convert core note data: %s"), elf_errmsg (-1));
+    error_exit (0, _("cannot convert core note data: %s"), elf_errmsg (-1));
 
   unsigned char const *ptr = data->d_buf;
   unsigned char const *const end = data->d_buf + data->d_size;
@@ -12425,8 +12402,7 @@ handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
 {
   Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
   if (data == NULL)
-    error (EXIT_FAILURE, 0,
-	   _("cannot convert core note data: %s"), elf_errmsg (-1));
+    error_exit (0, _("cannot convert core note data: %s"), elf_errmsg (-1));
 
   unsigned char const *ptr = data->d_buf;
   unsigned char const *const end = data->d_buf + data->d_size;
@@ -12599,8 +12575,7 @@ handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
       /* Get the section header string table index.  */
       size_t shstrndx;
       if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
-	error (EXIT_FAILURE, 0,
-	       _("cannot get section header string table index"));
+	error_exit (0, _("cannot get section header string table index"));
 
       Elf_Scn *scn = NULL;
       while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
@@ -12810,8 +12785,7 @@ for_each_section_argument (Elf *elf, const struct section_argument *list,
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (elf_getshdrstrndx (elf, &shstrndx) < 0)
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   for (const struct section_argument *a = list; a != NULL; a = a->next)
     {
@@ -12831,8 +12805,8 @@ for_each_section_argument (Elf *elf, const struct section_argument *list,
 	    }
 
 	  if (gelf_getshdr (scn, &shdr_mem) == NULL)
-	    error (EXIT_FAILURE, 0, _("cannot get section header: %s"),
-		   elf_errmsg (-1));
+	    error_exit (0, _("cannot get section header: %s"),
+			elf_errmsg (-1));
 	  name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
 	  (*dump) (scn, &shdr_mem, name);
 	}
@@ -12879,8 +12853,7 @@ print_strings (Ebl *ebl)
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   Elf_Scn *scn;
   GElf_Shdr shdr_mem;
@@ -12912,9 +12885,8 @@ dump_archive_index (Elf *elf, const char *fname)
     {
       int result = elf_errno ();
       if (unlikely (result != ELF_E_NO_INDEX))
-	error (EXIT_FAILURE, 0,
-	       _("cannot get symbol index of archive '%s': %s"),
-	       fname, elf_errmsg (result));
+	error_exit (0, _("cannot get symbol index of archive '%s': %s"),
+		    fname, elf_errmsg (result));
       else
 	printf (_("\nArchive '%s' has no symbol index\n"), fname);
       return;
@@ -12937,9 +12909,9 @@ dump_archive_index (Elf *elf, const char *fname)
 #if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
 	    while (1)
 #endif
-	      error (EXIT_FAILURE, 0,
-		     _("cannot extract member at offset %zu in '%s': %s"),
-		     as_off, fname, elf_errmsg (-1));
+	      error_exit (0,
+			  _("cannot extract member at offset %zu in '%s': %s"),
+			  as_off, fname, elf_errmsg (-1));
 
 	  const Elf_Arhdr *h = elf_getarhdr (subelf);
 
diff --git a/src/size.c b/src/size.c
index 322ff53e..8f203167 100644
--- a/src/size.c
+++ b/src/size.c
@@ -102,8 +102,8 @@ static void handle_elf (Elf *elf, const char *fullname, const char *fname);
 static void show_bsd_totals (void);
 
 #define INTERNAL_ERROR(fname) \
-  error (EXIT_FAILURE, 0, _("%s: INTERNAL ERROR %d (%s): %s"),      \
-	 fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1))
+  error_exit (0, _("%s: INTERNAL ERROR %d (%s): %s"),      \
+	      fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1))
 
 
 /* User-selectable options.  */
@@ -237,7 +237,7 @@ parse_opt (int key, char *arg,
       else if (likely (strcmp (arg, "sysv") == 0))
 	format = format_sysv;
       else
-	error (EXIT_FAILURE, 0, _("Invalid format: %s"), arg);
+	error_exit (0, _("Invalid format: %s"), arg);
       break;
 
     case OPT_RADIX:
@@ -248,7 +248,7 @@ parse_opt (int key, char *arg,
       else if (strcmp (arg, "o") == 0 || strcmp (arg, "8") == 0)
 	radix = radix_octal;
       else
-	error (EXIT_FAILURE, 0, _("Invalid radix: %s"), arg);
+	error_exit (0, _("Invalid radix: %s"), arg);
       break;
 
     case 't':
@@ -285,7 +285,7 @@ process_file (const char *fname)
 	    INTERNAL_ERROR (fname);
 
 	  if (unlikely (close (fd) != 0))
-	    error (EXIT_FAILURE, errno, _("while closing '%s'"), fname);
+	    error_exit (errno, _("while closing '%s'"), fname);
 
 	  return 0;
 	}
@@ -294,7 +294,7 @@ process_file (const char *fname)
 	  int result = handle_ar (fd, elf, NULL, fname);
 
 	  if (unlikely  (close (fd) != 0))
-	    error (EXIT_FAILURE, errno, _("while closing '%s'"), fname);
+	    error_exit (errno, _("while closing '%s'"), fname);
 
 	  return result;
 	}
@@ -305,7 +305,7 @@ process_file (const char *fname)
     }
 
   if (unlikely (close (fd) != 0))
-    error (EXIT_FAILURE, errno, _("while closing '%s'"), fname);
+    error_exit (errno, _("while closing '%s'"), fname);
 
   error (0, 0, _("%s: file format not recognized"), fname);
 
@@ -394,8 +394,7 @@ show_sysv (Elf *elf, const char *prefix, const char *fname,
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (unlikely (elf_getshdrstrndx (elf, &shstrndx) < 0))
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   /* First round over the sections: determine the longest section name.  */
   Elf_Scn *scn = NULL;
@@ -466,8 +465,7 @@ show_sysv_one_line (Elf *elf)
   /* Get the section header string table index.  */
   size_t shstrndx;
   if (unlikely (elf_getshdrstrndx (elf, &shstrndx) < 0))
-    error (EXIT_FAILURE, 0,
-	   _("cannot get section header string table index"));
+    error_exit (0, _("cannot get section header string table index"));
 
   /* Iterate over all sections.  */
   GElf_Off total = 0;
@@ -479,7 +477,7 @@ show_sysv_one_line (Elf *elf)
       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
 
       if (unlikely (shdr == NULL))
-	error (EXIT_FAILURE, 0, _("cannot get section header"));
+	error_exit (0, _("cannot get section header"));
 
       /* Ignore all sections which are not used at runtime.  */
       if ((shdr->sh_flags & SHF_ALLOC) == 0)
diff --git a/src/strings.c b/src/strings.c
index eb278f8e..04aac3b6 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -298,8 +298,7 @@ parse_opt (int key, char *arg,
     case ARGP_KEY_FINI:
       /* Compute the length in bytes of any match.  */
       if (min_len <= 0 || min_len > INT_MAX / bytes_per_char)
-	error (EXIT_FAILURE, 0,
-	       _("invalid minimum length of matched string size"));
+	error_exit (0, _("invalid minimum length of matched string size"));
       min_len_bytes = min_len * bytes_per_char;
       break;
 
@@ -582,7 +581,7 @@ read_block (int fd, const char *fname, off_t fdlen, off_t from, off_t to)
       // XXX Eventually add flag which avoids this if the position
       // XXX is known to match.
       if (from != 0 && lseek (fd, from, SEEK_SET) != from)
-	error (EXIT_FAILURE, errno, _("lseek failed"));
+	error_exit (errno, _("lseek failed"));
 
       return read_block_no_mmap (fd, fname, from, to - from);
     }
@@ -599,7 +598,7 @@ read_block (int fd, const char *fname, off_t fdlen, off_t from, off_t to)
       if (mmap (elfmap, elfmap_size, PROT_READ,
 		MAP_PRIVATE | MAP_POPULATE | MAP_FIXED, fd, from)
 	  == MAP_FAILED)
-	error (EXIT_FAILURE, errno, _("re-mmap failed"));
+	error_exit (errno, _("re-mmap failed"));
       elfmap_base = elfmap;
     }
 
@@ -636,7 +635,7 @@ read_block (int fd, const char *fname, off_t fdlen, off_t from, off_t to)
 	     and for this we have to make the data writable.  */
 	  if (unlikely (mprotect (elfmap, keep_area, PROT_READ | PROT_WRITE)
 			!= 0))
-	    error (EXIT_FAILURE, errno, _("mprotect failed"));
+	    error_exit (errno, _("mprotect failed"));
 
 	  elfmap_base = elfmap + keep_area;
 	}
@@ -663,7 +662,7 @@ read_block (int fd, const char *fname, off_t fdlen, off_t from, off_t to)
 	  if (mmap (remap_base, read_now, PROT_READ,
 		    MAP_PRIVATE | MAP_POPULATE | MAP_FIXED, fd, handled_to)
 	      == MAP_FAILED)
-	    error (EXIT_FAILURE, errno, _("re-mmap failed"));
+	    error_exit (errno, _("re-mmap failed"));
 	  elfmap_off = handled_to;
 
 	  process_chunk (fname, remap_base - to_keep,
diff --git a/src/strip.c b/src/strip.c
index d5b753d7..30a1f9da 100644
--- a/src/strip.c
+++ b/src/strip.c
@@ -130,8 +130,8 @@ static void cleanup_debug (void);
 #define INTERNAL_ERROR(fname) \
   do { \
     cleanup_debug (); \
-    error (EXIT_FAILURE, 0, _("%s: INTERNAL ERROR %d (%s): %s"),      \
-	   fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1)); \
+    error_exit (0, _("%s: INTERNAL ERROR %d (%s): %s"),			\
+		fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1));	\
   } while (0)
 
 
@@ -243,14 +243,13 @@ main (int argc, char *argv[])
     return EXIT_FAILURE;
 
   if (reloc_debug && debug_fname == NULL)
-    error (EXIT_FAILURE, 0,
-	   _("--reloc-debug-sections used without -f"));
+    error_exit (0, _("--reloc-debug-sections used without -f"));
 
   if (reloc_debug_only &&
       (debug_fname != NULL || remove_secs != NULL
        || remove_comment == true || remove_debug == true))
-    error (EXIT_FAILURE, 0,
-	   _("--reloc-debug-sections-only incompatible with -f, -g, --remove-comment and --remove-section"));
+    error_exit (0,
+		_("--reloc-debug-sections-only incompatible with -f, -g, --remove-comment and --remove-section"));
 
   /* Tell the library which version we are expecting.  */
   elf_version (EV_CURRENT);
@@ -264,8 +263,7 @@ main (int argc, char *argv[])
 	 input file.  */
       if ((output_fname != NULL || debug_fname != NULL)
 	  && remaining + 1 < argc)
-	error (EXIT_FAILURE, 0, _("\
-Only one input file allowed together with '-o' and '-f'"));
+	error_exit (0, _("Only one input file allowed together with '-o' and '-f'"));
 
       /* Process all the remaining files.  */
       do
@@ -478,7 +476,7 @@ relocate (Elf *elf, GElf_Addr offset, const GElf_Sxword addend,
       || tdata->d_size - offset < size)
     {
       cleanup_debug ();
-      error (EXIT_FAILURE, 0, _("bad relocation"));
+      error_exit (0, _("bad relocation"));
     }
 
   /* When the symbol value is zero then for SHT_REL
@@ -1085,8 +1083,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
   if (unlikely (elf_getshdrstrndx (elf, &shstrndx) < 0))
     {
       cleanup_debug ();
-      error (EXIT_FAILURE, 0,
-	     _("cannot get section header string table index"));
+      error_exit (0, _("cannot get section header string table index"));
     }
 
   /* Get the number of phdrs in the old file.  */
@@ -1094,7 +1091,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
   if (elf_getphdrnum (elf, &phnum) != 0)
     {
       cleanup_debug ();
-      error (EXIT_FAILURE, 0, _("cannot get number of phdrs"));
+      error_exit (0, _("cannot get number of phdrs"));
     }
 
   /* We now create a new ELF descriptor for the same file.  We
@@ -1624,9 +1621,8 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
 	  if (scn == NULL)
 	    {
 	      cleanup_debug ();
-	      error (EXIT_FAILURE, 0,
-		     _("while generating output file: %s"),
-		     elf_errmsg (-1));
+	      error_exit (0, _("while generating output file: %s"),
+			  elf_errmsg (-1));
 	    }
 
 	  bool discard_section = (shdr_info[cnt].idx > 0
@@ -1723,8 +1719,8 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
   if (shst == NULL)
     {
       cleanup_debug ();
-      error (EXIT_FAILURE, errno, _("while preparing output for '%s'"),
-	     output_fname ?: fname);
+      error_exit (errno, _("while preparing output for '%s'"),
+		  output_fname ?: fname);
     }
 
   /* Assign new section numbers.  */
@@ -1739,8 +1735,8 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
 	if (shdr_info[cnt].newscn == NULL)
 	  {
 	    cleanup_debug ();
-	    error (EXIT_FAILURE, 0,
-		   _("while generating output file: %s"),
+	    error_exit (0,
+			_("while generating output file: %s"),
 		   elf_errmsg (-1));
 	  }
 
@@ -1784,9 +1780,8 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
       if (shdr_info[cnt].newscn == NULL)
 	{
 	  cleanup_debug ();
-	  error (EXIT_FAILURE, 0,
-		 _("while create section header section: %s"),
-		 elf_errmsg (-1));
+	  error_exit (0, _("while create section header section: %s"),
+		      elf_errmsg (-1));
 	}
       elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
 
@@ -1794,8 +1789,8 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
       if (shdr_info[cnt].data == NULL)
 	{
 	  cleanup_debug ();
-	  error (EXIT_FAILURE, 0, _("cannot allocate section data: %s"),
-		 elf_errmsg (-1));
+	  error_exit (0, _("cannot allocate section data: %s"),
+		      elf_errmsg (-1));
 	}
 
       char *debug_basename = basename (debug_fname_embed ?: debug_fname);
@@ -1847,9 +1842,8 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
   if (shdr_info[cnt].newscn == NULL)
     {
       cleanup_debug ();
-      error (EXIT_FAILURE, 0,
-	     _("while create section header section: %s"),
-	     elf_errmsg (-1));
+      error_exit (0, _("while create section header section: %s"),
+		  elf_errmsg (-1));
     }
   elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == idx);
 
@@ -1859,15 +1853,13 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
   if (shstrtab_data == NULL)
     {
       cleanup_debug ();
-      error (EXIT_FAILURE, 0,
-	     _("while create section header string table: %s"),
-	     elf_errmsg (-1));
+      error_exit (0, _("while create section header string table: %s"),
+		  elf_errmsg (-1));
     }
   if (dwelf_strtab_finalize (shst, shstrtab_data) == NULL)
     {
       cleanup_debug ();
-      error (EXIT_FAILURE, 0,
-	     _("no memory to create section header string table"));
+      error_exit (0, _("no memory to create section header string table"));
     }
 
   /* We have to set the section size.  */
@@ -2764,7 +2756,7 @@ cannot set access and modification date of '%s'"), fname);
     }
 
   if (unlikely (close (fd) != 0))
-    error (EXIT_FAILURE, errno, _("while closing '%s'"), fname);
+    error_exit (errno, _("while closing '%s'"), fname);
 
   return result;
 }
diff --git a/src/unstrip.c b/src/unstrip.c
index aacc9aad..3472637a 100644
--- a/src/unstrip.c
+++ b/src/unstrip.c
@@ -225,7 +225,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
   do									      \
     {									      \
       if (unlikely (!(call)))						      \
-	error (EXIT_FAILURE, 0, msg, elf_errmsg (-1));			      \
+	error_exit (0, msg, elf_errmsg (-1));				      \
     } while (0)
 
 /* Copy INELF to newly-created OUTELF, exit via error for any problems.  */
@@ -316,7 +316,7 @@ make_directories (const char *path)
       if (errno == ENOENT)
         make_directories (dir);
       else
-        error (EXIT_FAILURE, errno, _("cannot create directory '%s'"), dir);
+        error_exit (errno, _("cannot create directory '%s'"), dir);
     }
   free (dir);
 }
@@ -440,7 +440,7 @@ adjust_reloc (GElf_Xword *info,
   if (ndx != STN_UNDEF)
     {
       if (ndx > map_size)
-	error (EXIT_FAILURE, 0, "bad symbol ndx section");
+	error_exit (0, "bad symbol ndx section");
       *info = GELF_R_INFO (map[ndx - 1], GELF_R_TYPE (*info));
     }
 }
@@ -456,7 +456,7 @@ adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr,
     {
     case SHT_REL:
       if (shdr->sh_entsize == 0)
-	error (EXIT_FAILURE, 0, "REL section cannot have zero sh_entsize");
+	error_exit (0, "REL section cannot have zero sh_entsize");
 
       for (size_t i = 0; i < shdr->sh_size / shdr->sh_entsize; ++i)
 	{
@@ -471,7 +471,7 @@ adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr,
 
     case SHT_RELA:
       if (shdr->sh_entsize == 0)
-	error (EXIT_FAILURE, 0, "RELA section cannot have zero sh_entsize");
+	error_exit (0, "RELA section cannot have zero sh_entsize");
 
       for (size_t i = 0; i < shdr->sh_size / shdr->sh_entsize; ++i)
 	{
@@ -501,13 +501,13 @@ adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr,
       /* We must expand the table and rejigger its contents.  */
       {
 	if (shdr->sh_entsize == 0)
-	  error (EXIT_FAILURE, 0, "HASH section cannot have zero sh_entsize");
+	  error_exit (0, "HASH section cannot have zero sh_entsize");
 	if (symshdr->sh_entsize == 0)
-	  error (EXIT_FAILURE, 0, "Symbol table cannot have zero sh_entsize");
+	  error_exit (0, "Symbol table cannot have zero sh_entsize");
 	const size_t nsym = symshdr->sh_size / symshdr->sh_entsize;
 	const size_t onent = shdr->sh_size / shdr->sh_entsize;
 	if (data->d_size != shdr->sh_size)
-	  error (EXIT_FAILURE, 0, "HASH section has inconsistent size");
+	  error_exit (0, "HASH section has inconsistent size");
 
 #define CONVERT_HASH(Hash_Word)						      \
 	{								      \
@@ -517,7 +517,7 @@ adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr,
 	  const Hash_Word *const old_bucket = &old_hash[2];		      \
 	  const Hash_Word *const old_chain = &old_bucket[nbucket];	      \
 	  if (onent != 2 + nbucket + nchain)				      \
-	    error (EXIT_FAILURE, 0, "HASH section has inconsistent entsize"); \
+	    error_exit (0, "HASH section has inconsistent entsize");	      \
 									      \
 	  const size_t nent = 2 + nbucket + nsym;			      \
 	  Hash_Word *const new_hash = xcalloc (nent, sizeof new_hash[0]);     \
@@ -562,10 +562,9 @@ adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr,
       /* We must expand the table and move its elements around.  */
       {
 	if (shdr->sh_entsize == 0)
-	  error (EXIT_FAILURE, 0,
-		 "GNU_versym section cannot have zero sh_entsize");
+	  error_exit (0, "GNU_versym section cannot have zero sh_entsize");
 	if (symshdr->sh_entsize == 0)
-	  error (EXIT_FAILURE, 0, "Symbol table cannot have zero sh_entsize");
+	  error_exit (0, "Symbol table cannot have zero sh_entsize");
 	const size_t nent = symshdr->sh_size / symshdr->sh_entsize;
 	const size_t onent = shdr->sh_size / shdr->sh_entsize;
 	assert (nent >= onent);
@@ -591,9 +590,9 @@ adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr,
       break;
 
     default:
-      error (EXIT_FAILURE, 0,
-	     _("unexpected section type in [%zu] with sh_link to symtab"),
-	     elf_ndxscn (inscn));
+      error_exit (0,
+		  _("unexpected section type in [%zu] with sh_link to symtab"),
+		  elf_ndxscn (inscn));
     }
 }
 
@@ -632,7 +631,7 @@ add_new_section_symbols (Elf_Scn *old_symscn, size_t old_shnum,
   GElf_Shdr *shdr = gelf_getshdr (symscn, &shdr_mem);
   ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
   if (shdr->sh_entsize == 0)
-    error (EXIT_FAILURE, 0, "Symbol table section cannot have zero sh_entsize");
+    error_exit (0, "Symbol table section cannot have zero sh_entsize");
 
   const size_t nsym = shdr->sh_size / shdr->sh_entsize;
   size_t symndx_map[nsym - 1];
@@ -865,8 +864,8 @@ collect_symbols (Elf *outelf, bool rel, Elf_Scn *symscn, Elf_Scn *strscn,
       if (sym->st_name >= strdata->d_size
 	  || memrchr (strdata->d_buf + sym->st_name, '\0',
 		      strdata->d_size - sym->st_name) == NULL)
-	error (EXIT_FAILURE, 0,
-	       _("invalid string offset in symbol [%zu]"), i);
+	error_exit (0,
+		    _("invalid string offset in symbol [%zu]"), i);
 
       struct symbol *s = &table[i - 1];
       s->map = &map[i - 1];
@@ -948,13 +947,13 @@ compare_symbols_output (const void *a, const void *b)
 	  /* binutils always puts section symbols in section index order.  */
 	  CMP (shndx);
 	  else if (s1 != s2)
-	    error (EXIT_FAILURE, 0, "section symbols in unexpected order");
+	    error_exit (0, "section symbols in unexpected order");
 	}
 
       /* Nothing really matters, so preserve the original order.  */
       CMP (map);
       else if (s1 != s2)
-	error (EXIT_FAILURE, 0, "found two identical symbols");
+	error_exit (0, "found two identical symbols");
     }
 
   return cmp;
@@ -1024,8 +1023,8 @@ static inline const char *
 get_section_name (size_t ndx, const GElf_Shdr *shdr, const Elf_Data *shstrtab)
 {
   if (shdr->sh_name >= shstrtab->d_size)
-    error (EXIT_FAILURE, 0, _("cannot read section [%zu] name: %s"),
-	   ndx, elf_errmsg (-1));
+    error_exit (0, _("cannot read section [%zu] name: %s"),
+		ndx, elf_errmsg (-1));
   return shstrtab->d_buf + shdr->sh_name;
 }
 
@@ -1039,30 +1038,30 @@ get_group_sig (Elf *elf, GElf_Shdr *shdr)
 
   Elf_Scn *symscn = elf_getscn (elf, shdr->sh_link);
   if (symscn == NULL)
-    error (EXIT_FAILURE, 0, _("bad sh_link for group section: %s"),
-	   elf_errmsg (-1));
+    error_exit (0, _("bad sh_link for group section: %s"),
+		elf_errmsg (-1));
 
   GElf_Shdr symshdr_mem;
   GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
   if (symshdr == NULL)
-    error (EXIT_FAILURE, 0, _("couldn't get shdr for group section: %s"),
-	   elf_errmsg (-1));
+    error_exit (0, _("couldn't get shdr for group section: %s"),
+		elf_errmsg (-1));
 
   Elf_Data *symdata = elf_getdata (symscn, NULL);
   if (symdata == NULL)
-    error (EXIT_FAILURE, 0, _("bad data for group symbol section: %s"),
-	   elf_errmsg (-1));
+    error_exit (0, _("bad data for group symbol section: %s"),
+		elf_errmsg (-1));
 
   GElf_Sym sym_mem;
   GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
   if (sym == NULL)
-    error (EXIT_FAILURE, 0, _("couldn't get symbol for group section: %s"),
-	   elf_errmsg (-1));
+    error_exit (0, _("couldn't get symbol for group section: %s"),
+		elf_errmsg (-1));
 
   const char *sig = elf_strptr (elf, symshdr->sh_link, sym->st_name);
   if (sig == NULL)
-    error (EXIT_FAILURE, 0, _("bad symbol name for group section: %s"),
-	   elf_errmsg (-1));
+    error_exit (0, _("bad symbol name for group section: %s"),
+		elf_errmsg (-1));
 
   return sig;
 }
@@ -1154,8 +1153,8 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab,
       bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32;
       size_t shsize = class32 ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr);
       if (unlikely (shnum == 0 || shnum > SIZE_MAX / shsize + 1))
-	error (EXIT_FAILURE, 0, _("overflow with shnum = %zu in '%s' section"),
-	       (size_t) shnum, ".gnu.prelink_undo");
+	error_exit (0, _("overflow with shnum = %zu in '%s' section"),
+		    (size_t) shnum, ".gnu.prelink_undo");
 
       --shnum;
 
@@ -1165,8 +1164,8 @@ find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab,
       src.d_type = ELF_T_SHDR;
       if ((size_t) (src.d_buf - undodata->d_buf) > undodata->d_size
 	  || undodata->d_size - (src.d_buf - undodata->d_buf) != src.d_size)
-	error (EXIT_FAILURE, 0, _("invalid contents in '%s' section"),
-	       ".gnu.prelink_undo");
+	error_exit (0, _("invalid contents in '%s' section"),
+		    ".gnu.prelink_undo");
 
       const size_t shdr_bytes = shnum * shsize;
       void *shdr = xmalloc (shdr_bytes);
@@ -1363,7 +1362,7 @@ new_shstrtab (Elf *unstripped, size_t unstripped_shnum,
   ELF_CHECK (elf_flagdata (strtab_data, ELF_C_SET, ELF_F_DIRTY),
 	     _("cannot update section header string table data: %s"));
   if (dwelf_strtab_finalize (strtab, strtab_data) == NULL)
-    error (EXIT_FAILURE, 0, "Not enough memory to create string table");
+    error_exit (0, "Not enough memory to create string table");
 
   /* Update the sh_name fields of sections we aren't modifying later.  */
   for (size_t i = 0; i < unstripped_shnum - 1; ++i)
@@ -1405,11 +1404,11 @@ copy_elided_sections (Elf *unstripped, Elf *stripped,
 	     _("cannot get section count: %s"));
 
   if (unlikely (stripped_shnum > unstripped_shnum))
-    error (EXIT_FAILURE, 0, _("\
+    error_exit (0, _("\
 more sections in stripped file than debug file -- arguments reversed?"));
 
   if (unlikely (stripped_shnum == 0))
-    error (EXIT_FAILURE, 0, _("no sections in stripped file"));
+    error_exit (0, _("no sections in stripped file"));
 
   /* Used as sanity check for allocated section offset, if the section
      offset needs to be preserved.  We want to know the max size of the
@@ -1432,8 +1431,8 @@ more sections in stripped file than debug file -- arguments reversed?"));
       sections[i].name = elf_strptr (stripped, stripped_shstrndx,
 				     shdr->sh_name);
       if (sections[i].name == NULL)
-	error (EXIT_FAILURE, 0, _("cannot read section [%zu] name: %s"),
-	       elf_ndxscn (scn), elf_errmsg (-1));
+	error_exit (0, _("cannot read section [%zu] name: %s"),
+		    elf_ndxscn (scn), elf_errmsg (-1));
       sections[i].scn = scn;
       sections[i].outscn = NULL;
       sections[i].strent = NULL;
@@ -1552,9 +1551,8 @@ more sections in stripped file than debug file -- arguments reversed?"));
 	}
 
       if (sec == NULL)
-	error (EXIT_FAILURE, 0,
-	       _("cannot find matching section for [%zu] '%s'"),
-	       elf_ndxscn (scn), name);
+	error_exit (0, _("cannot find matching section for [%zu] '%s'"),
+		    elf_ndxscn (scn), name);
 
       sec->outscn = scn;
     }
@@ -1689,17 +1687,17 @@ more sections in stripped file than debug file -- arguments reversed?"));
 	if (sec->shdr.sh_link != SHN_UNDEF)
 	  {
 	    if (sec->shdr.sh_link > ndx_sec_num)
-	      error (EXIT_FAILURE, 0,
-		     "section [%zd] has invalid sh_link %" PRId32,
-		     elf_ndxscn (sec->scn), sec->shdr.sh_link);
+	      error_exit (0,
+			  "section [%zd] has invalid sh_link %" PRId32,
+			  elf_ndxscn (sec->scn), sec->shdr.sh_link);
 	    shdr_mem.sh_link = ndx_section[sec->shdr.sh_link - 1];
 	  }
 	if (SH_INFO_LINK_P (&sec->shdr) && sec->shdr.sh_info != 0)
 	  {
 	    if (sec->shdr.sh_info > ndx_sec_num)
-	      error (EXIT_FAILURE, 0,
-		     "section [%zd] has invalid sh_info %" PRId32,
-		     elf_ndxscn (sec->scn), sec->shdr.sh_info);
+	      error_exit (0,
+			  "section [%zd] has invalid sh_info %" PRId32,
+			  elf_ndxscn (sec->scn), sec->shdr.sh_info);
 	    shdr_mem.sh_info = ndx_section[sec->shdr.sh_info - 1];
 	  }
 
@@ -1717,9 +1715,9 @@ more sections in stripped file than debug file -- arguments reversed?"));
 	if (stripped_ehdr->e_type != ET_REL && (shdr_mem.sh_flags & SHF_ALLOC))
 	  {
 	    if (max_off > 0 && sec->shdr.sh_offset > (Elf64_Off) max_off)
-		error (EXIT_FAILURE, 0,
-		       "allocated section offset too large [%zd] %" PRIx64,
-		       elf_ndxscn (sec->scn), sec->shdr.sh_offset);
+		error_exit (0,
+			    "allocated section offset too large [%zd] %" PRIx64,
+			    elf_ndxscn (sec->scn), sec->shdr.sh_offset);
 
 	    shdr_mem.sh_offset = sec->shdr.sh_offset;
 	    placed[elf_ndxscn (sec->outscn) - 1] = true;
@@ -1740,8 +1738,8 @@ more sections in stripped file than debug file -- arguments reversed?"));
 	    Elf_Data *shndxdata = NULL;	/* XXX */
 
 	    if (shdr_mem.sh_entsize == 0)
-	      error (EXIT_FAILURE, 0,
-		     "SYMTAB section cannot have zero sh_entsize");
+	      error_exit (0,
+			  "SYMTAB section cannot have zero sh_entsize");
 	    for (size_t i = 1; i < shdr_mem.sh_size / shdr_mem.sh_entsize; ++i)
 	      {
 		GElf_Sym sym_mem;
@@ -1756,8 +1754,8 @@ more sections in stripped file than debug file -- arguments reversed?"));
 		if (shndx != SHN_UNDEF && shndx < SHN_LORESERVE)
 		  {
 		    if (shndx >= stripped_shnum)
-		      error (EXIT_FAILURE, 0,
-			     _("symbol [%zu] has invalid section index"), i);
+		      error_exit (0,
+				  _("symbol [%zu] has invalid section index"), i);
 
 		    shndx = ndx_section[shndx - 1];
 		    if (shndx < SHN_LORESERVE)
@@ -1788,8 +1786,8 @@ more sections in stripped file than debug file -- arguments reversed?"));
 	    Elf32_Word *shndx = (Elf32_Word *) outdata->d_buf;
 	    for (size_t i = 1; i < shdr_mem.sh_size / sizeof (Elf32_Word); ++i)
 	      if (shndx[i]  == SHN_UNDEF || shndx[i] >= stripped_shnum)
-		error (EXIT_FAILURE, 0,
-		       _("group has invalid section index [%zd]"), i);
+		error_exit (0,
+			    _("group has invalid section index [%zd]"), i);
 	      else
 		shndx[i] = ndx_section[shndx[i] - 1];
 	  }
@@ -1815,8 +1813,8 @@ more sections in stripped file than debug file -- arguments reversed?"));
       GElf_Shdr *shdr = gelf_getshdr (unstripped_symtab, &shdr_mem);
       ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
       if (shdr->sh_entsize == 0)
-	error (EXIT_FAILURE, 0,
-	       "unstripped SYMTAB section cannot have zero sh_entsize");
+	error_exit (0,
+		    "unstripped SYMTAB section cannot have zero sh_entsize");
       const size_t unstripped_nsym = shdr->sh_size / shdr->sh_entsize;
 
       /* First collect all the symbols from both tables.  */
@@ -1936,7 +1934,7 @@ more sections in stripped file than debug file -- arguments reversed?"));
 	}
 
       if (dwelf_strtab_finalize (symstrtab, symstrdata) == NULL)
-	error (EXIT_FAILURE, 0, "Not enough memory to create symbol table");
+	error_exit (0, "Not enough memory to create symbol table");
 
       elf_flagdata (symstrdata, ELF_C_SET, ELF_F_DIRTY);
 
@@ -2194,7 +2192,7 @@ DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"),
 			(stripped_ehdr->e_type == ET_REL
 			 ? DEFFILEMODE : ACCESSPERMS));
       if (outfd < 0)
-	error (EXIT_FAILURE, errno, _("cannot open '%s'"), output_file);
+	error_exit (errno, _("cannot open '%s'"), output_file);
       Elf *outelf = elf_begin (outfd, ELF_C_WRITE, NULL);
       ELF_CHECK (outelf != NULL, _("cannot create ELF descriptor: %s"));
 
@@ -2223,7 +2221,7 @@ open_file (const char *file, bool writable)
 {
   int fd = open (file, writable ? O_RDWR : O_RDONLY);
   if (fd < 0)
-    error (EXIT_FAILURE, errno, _("cannot open '%s'"), file);
+    error_exit (errno, _("cannot open '%s'"), file);
   return fd;
 }
 
@@ -2306,13 +2304,13 @@ handle_dwfl_module (const char *output_file, bool create_dirs, bool force,
       const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
 					      NULL, NULL, &file, NULL);
       if (file == NULL)
-	error (EXIT_FAILURE, 0,
-	       _("cannot find stripped file for module '%s': %s"),
-	       modname, dwfl_errmsg (-1));
+	error_exit (0,
+		    _("cannot find stripped file for module '%s': %s"),
+		    modname, dwfl_errmsg (-1));
       else
-	error (EXIT_FAILURE, 0,
-	       _("cannot open stripped file '%s' for module '%s': %s"),
-	       modname, file, dwfl_errmsg (-1));
+	error_exit (0,
+		    _("cannot open stripped file '%s' for module '%s': %s"),
+		    modname, file, dwfl_errmsg (-1));
     }
 
   Elf *debug = dwarf_getelf (dwfl_module_getdwarf (mod, &bias));
@@ -2325,13 +2323,13 @@ handle_dwfl_module (const char *output_file, bool create_dirs, bool force,
       const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
 					      NULL, NULL, NULL, &file);
       if (file == NULL)
-	error (EXIT_FAILURE, 0,
-	       _("cannot find debug file for module '%s': %s"),
-	       modname, dwfl_errmsg (-1));
+	error_exit (0,
+		    _("cannot find debug file for module '%s': %s"),
+		    modname, dwfl_errmsg (-1));
       else
-	error (EXIT_FAILURE, 0,
-	       _("cannot open debug file '%s' for module '%s': %s"),
-	       modname, file, dwfl_errmsg (-1));
+	error_exit (0,
+		    _("cannot open debug file '%s' for module '%s': %s"),
+		    modname, file, dwfl_errmsg (-1));
     }
 
   if (debug == stripped)
@@ -2343,8 +2341,8 @@ handle_dwfl_module (const char *output_file, bool create_dirs, bool force,
 	  const char *file;
 	  const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
 						  NULL, NULL, &file, NULL);
-	  error (EXIT_FAILURE, 0, _("module '%s' file '%s' is not stripped"),
-		 modname, file);
+	  error_exit (0, _("module '%s' file '%s' is not stripped"),
+		      modname, file);
 	}
     }
 
@@ -2373,10 +2371,10 @@ handle_dwfl_module (const char *output_file, bool create_dirs, bool force,
 	 get sh_addr values assigned have them, even ones not used in DWARF.
 	 They might still be used in the symbol table.  */
       if (dwfl_module_relocations (mod) < 0)
-	error (EXIT_FAILURE, 0,
-	       _("cannot cache section addresses for module '%s': %s"),
-	       dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
-	       dwfl_errmsg (-1));
+	error_exit (0,
+		    _("cannot cache section addresses for module '%s': %s"),
+		    dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+		    dwfl_errmsg (-1));
     }
 
   handle_file (output_file, create_dirs, stripped, &stripped_ehdr, debug);
@@ -2502,7 +2500,7 @@ handle_implicit_modules (const struct arg_info *info)
   struct match_module_info mmi = { info->args, NULL, info->match_files };
   ptrdiff_t offset = dwfl_getmodules (info->dwfl, &match_module, &mmi, 0);
   if (offset == 0)
-    error (EXIT_FAILURE, 0, _("no matching modules found"));
+    error_exit (0, _("no matching modules found"));
 
   if (info->list)
     do
@@ -2512,7 +2510,7 @@ handle_implicit_modules (const struct arg_info *info)
   else if (info->output_dir == NULL)
     {
       if (dwfl_getmodules (info->dwfl, &match_module, &mmi, offset) != 0)
-	error (EXIT_FAILURE, 0, _("matched more than one module"));
+	error_exit (0, _("matched more than one module"));
       handle_dwfl_module (info->output_file, false, info->force, mmi.found,
 			  info->all, info->ignore, info->relocate);
     }
-- 
2.30.2



More information about the Elfutils-devel mailing list