[PATCH] lib: remove usage of `sys/cdefs.h`

2021-08-20 Thread Saleem Abdulrasool via Elfutils-devel
This header is a BSD header that is also available in glibc.  However,
this is a not a standard C header and was used for `__CONCAT`.  Because
this is not a standard header, not all libc implementations provide the
header.  Remove the usage of the header and always use the previously
fallback path.  This is needed in order to build with musl.

Signed-off-by: Saleem Abdulrasool 
---
 lib/fixedsizehash.h | 5 -
 1 file changed, 5 deletions(-)

diff --git a/lib/fixedsizehash.h b/lib/fixedsizehash.h
index dac2a5f5..f333ad99 100644
--- a/lib/fixedsizehash.h
+++ b/lib/fixedsizehash.h
@@ -30,17 +30,12 @@
 #include 
 #include 
 #include 
-#include 
 
 #include 
 
-#ifdef __CONCAT
-#define CONCAT(t1,t2) __CONCAT (t1,t2)
-#else
 #define STROF(t2) t2
 #define CONCAT_EXPANDED(t1,t2) t1 ## t2
 #define CONCAT(t1,t2) CONCAT_EXPANDED(t1,t2)
-#endif
 
 /* Before including this file the following macros must be defined:
 
-- 
2.33.0.rc2.250.ged5fa647cd-goog



[PATCH] debuginfod, elfclassify: remove unnecessary header inclusion

2021-08-20 Thread Saleem Abdulrasool via Elfutils-devel
`error.h`'s inclusion was centralised into the `system.h` header.  As
the implementation currently includes `system.h` already, the inclusion
of `error.h` is unnecessary.  This prepares for a future portability
change to allow elfutil to build with alternate libc implementations.

Signed-off-by: Saleem Abdulrasool 
---
 debuginfod/debuginfod.cxx | 1 -
 src/elfclassify.c | 1 -
 2 files changed, 2 deletions(-)

diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx
index fca07f61..b560fdcb 100644
--- a/debuginfod/debuginfod.cxx
+++ b/debuginfod/debuginfod.cxx
@@ -46,7 +46,6 @@ extern "C" {
 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/src/elfclassify.c b/src/elfclassify.c
index fe7d..2f70b29a 100644
--- a/src/elfclassify.c
+++ b/src/elfclassify.c
@@ -19,7 +19,6 @@
 #include 
 
 #include 
-#include 
 #include 
 #include 
 #include 
-- 
2.33.0.rc2.250.ged5fa647cd-goog



[PATCH] handle libc implemntations which do not provide `error.h`

2021-08-20 Thread Saleem Abdulrasool via Elfutils-devel
Introduce a configure time check for the presence of `error.h`.  In the
case that `error.h` is not available, we can fall back to `err.h`.
Although `err.h` is not a C standard header (it is a BSD extension),
many libc implementations provide.  If there are targets which do not
provide an implementation of `err.h`, it would be possible to further
extend the implementation to be more portable.

This resolves PR21008.

Signed-off-by: Saleem Abdulrasool 
---
 configure.ac |  3 +++
 lib/system.h | 23 ++-
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 7caff2c5..177bb1a2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -431,6 +431,9 @@ AC_CHECK_DECLS([reallocarray],[],[],
 
 AC_CHECK_FUNCS([process_vm_readv])
 
+AC_CHECK_HEADERS([error.h])
+AC_CHECK_HEADERS([err.h])
+
 old_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -D_GNU_SOURCE"
 AC_FUNC_STRERROR_R()
diff --git a/lib/system.h b/lib/system.h
index 58d9deee..8adb5848 100644
--- a/lib/system.h
+++ b/lib/system.h
@@ -29,8 +29,9 @@
 #ifndef LIB_SYSTEM_H
 #define LIB_SYSTEM_H   1
 
+#include 
+
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -40,6 +41,26 @@
 #include 
 #include 
 
+#if defined(HAVE_ERROR_H)
+#include 
+#elif defined(HAVE_ERR_H)
+static int error_message_count = 0;
+
+static inline void error(int status, int errnum, const char *format, ...) {
+  va_list argp;
+
+  va_start(argp, format);
+  verr(status, format, argp);
+  va_end(argp);
+
+  if (status)
+exit(status);
+  ++error_message_count;
+}
+#else
+#error "err.h or error.h must be available"
+#endif
+
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 # define LE32(n)   (n)
 # define LE64(n)   (n)
-- 
2.33.0.rc2.250.ged5fa647cd-goog



Re: [PATCH] handle libc implemntations which do not provide `error.h`

2021-08-20 Thread Saleem Abdulrasool via Elfutils-devel
Hi,

Sorry, this change is missing a modification that I seemed to have
left out accidentally.  I missed the inclusion of `err.h` in the
`HAVE_ERR_H` when I was staging the changes locally.  I'll send out a
new version of this patch.


On Fri, Aug 20, 2021 at 11:23 AM Saleem Abdulrasool  wrote:
>
> Introduce a configure time check for the presence of `error.h`.  In the
> case that `error.h` is not available, we can fall back to `err.h`.
> Although `err.h` is not a C standard header (it is a BSD extension),
> many libc implementations provide.  If there are targets which do not
> provide an implementation of `err.h`, it would be possible to further
> extend the implementation to be more portable.
>
> This resolves PR21008.
>
> Signed-off-by: Saleem Abdulrasool 
> ---
>  configure.ac |  3 +++
>  lib/system.h | 23 ++-
>  2 files changed, 25 insertions(+), 1 deletion(-)
>
> diff --git a/configure.ac b/configure.ac
> index 7caff2c5..177bb1a2 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -431,6 +431,9 @@ AC_CHECK_DECLS([reallocarray],[],[],
>
>  AC_CHECK_FUNCS([process_vm_readv])
>
> +AC_CHECK_HEADERS([error.h])
> +AC_CHECK_HEADERS([err.h])
> +
>  old_CFLAGS="$CFLAGS"
>  CFLAGS="$CFLAGS -D_GNU_SOURCE"
>  AC_FUNC_STRERROR_R()
> diff --git a/lib/system.h b/lib/system.h
> index 58d9deee..8adb5848 100644
> --- a/lib/system.h
> +++ b/lib/system.h
> @@ -29,8 +29,9 @@
>  #ifndef LIB_SYSTEM_H
>  #define LIB_SYSTEM_H   1
>
> +#include 
> +
>  #include 
> -#include 
>  #include 
>  #include 
>  #include 
> @@ -40,6 +41,26 @@
>  #include 
>  #include 
>
> +#if defined(HAVE_ERROR_H)
> +#include 
> +#elif defined(HAVE_ERR_H)
> +static int error_message_count = 0;
> +
> +static inline void error(int status, int errnum, const char *format, ...) {
> +  va_list argp;
> +
> +  va_start(argp, format);
> +  verr(status, format, argp);
> +  va_end(argp);
> +
> +  if (status)
> +exit(status);
> +  ++error_message_count;
> +}
> +#else
> +#error "err.h or error.h must be available"
> +#endif
> +
>  #if __BYTE_ORDER == __LITTLE_ENDIAN
>  # define LE32(n)   (n)
>  # define LE64(n)   (n)
> --
> 2.33.0.rc2.250.ged5fa647cd-goog
>


[PATCH v2] handle libc implemntations which do not provide `error.h`

2021-08-20 Thread Saleem Abdulrasool via Elfutils-devel
Introduce a configure time check for the presence of `error.h`.  In the
case that `error.h` is not available, we can fall back to `err.h`.
Although `err.h` is not a C standard header (it is a BSD extension),
many libc implementations provide.  If there are targets which do not
provide an implementation of `err.h`, it would be possible to further
extend the implementation to be more portable.

This resolves bug #21008.

Signed-off-by: Saleem Abdulrasool 
---
 configure.ac |  3 +++
 lib/system.h | 26 +-
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 7caff2c5..177bb1a2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -431,6 +431,9 @@ AC_CHECK_DECLS([reallocarray],[],[],
 
 AC_CHECK_FUNCS([process_vm_readv])
 
+AC_CHECK_HEADERS([error.h])
+AC_CHECK_HEADERS([err.h])
+
 old_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -D_GNU_SOURCE"
 AC_FUNC_STRERROR_R()
diff --git a/lib/system.h b/lib/system.h
index 58d9deee..b963fd15 100644
--- a/lib/system.h
+++ b/lib/system.h
@@ -29,8 +29,9 @@
 #ifndef LIB_SYSTEM_H
 #define LIB_SYSTEM_H   1
 
+#include 
+
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -38,8 +39,31 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
+#if defined(HAVE_ERROR_H)
+#include 
+#elif defined(HAVE_ERR_H)
+#include 
+
+static int error_message_count = 0;
+
+static inline void error(int status, int errnum, const char *format, ...) {
+  va_list argp;
+
+  va_start(argp, format);
+  verr(status, format, argp);
+  va_end(argp);
+
+  if (status)
+exit(status);
+  ++error_message_count;
+}
+#else
+#error "err.h or error.h must be available"
+#endif
+
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 # define LE32(n)   (n)
 # define LE64(n)   (n)
-- 
2.33.0.rc2.250.ged5fa647cd-goog



Re: [PATCH] lib: remove usage of `sys/cdefs.h`

2021-08-23 Thread Saleem Abdulrasool via Elfutils-devel
Hi Érico,

Yes, it seems that `STROF` can be removed as well.  However, I'd
prefer to do that in a separate change.  This way the change is a
separate clean up rather than just happens to come along with the
sys/cdefs.h removal.

On Mon, Aug 23, 2021 at 5:48 AM Érico Nogueira  wrote:
>
> On Fri Aug 20, 2021 at 3:20 PM -03, Saleem Abdulrasool via Elfutils-devel 
> wrote:
> > This header is a BSD header that is also available in glibc. However,
> > this is a not a standard C header and was used for `__CONCAT`. Because
> > this is not a standard header, not all libc implementations provide the
> > header. Remove the usage of the header and always use the previously
> > fallback path. This is needed in order to build with musl.
>
> On Void we provide our own  file, since way too many
> packages require them. Explains why I missed this :)
>
> >
> > Signed-off-by: Saleem Abdulrasool 
> > ---
> > lib/fixedsizehash.h | 5 -
> > 1 file changed, 5 deletions(-)
> >
> > diff --git a/lib/fixedsizehash.h b/lib/fixedsizehash.h
> > index dac2a5f5..f333ad99 100644
> > --- a/lib/fixedsizehash.h
> > +++ b/lib/fixedsizehash.h
> > @@ -30,17 +30,12 @@
> > #include 
> > #include 
> > #include 
> > -#include 
> >
> > #include 
> >
> > -#ifdef __CONCAT
> > -#define CONCAT(t1,t2) __CONCAT (t1,t2)
> > -#else
> > #define STROF(t2) t2
> > #define CONCAT_EXPANDED(t1,t2) t1 ## t2
> > #define CONCAT(t1,t2) CONCAT_EXPANDED(t1,t2)
> > -#endif
>
> I think you can remove STROF from here too, can't you? I don't see it
> being used anywhere.
>
> >
> > /* Before including this file the following macros must be defined:
> >
> > --
> > 2.33.0.rc2.250.ged5fa647cd-goog
>


[PATCH] lib: remove unused `STROF` definition (NFC)

2021-08-27 Thread Saleem Abdulrasool via Elfutils-devel
This definition was in the fallback path, where `sys/cdefs.h` is not
available.  Now that we have a single path through here, this macro gets
defined, though is unused.  Remove the unused macro definition.

Signed-off-by: Saleem Abdulrasool 
---
 lib/ChangeLog   | 4 
 lib/fixedsizehash.h | 1 -
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/lib/ChangeLog b/lib/ChangeLog
index a95f8041..5f1de1e2 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,7 @@
+2021-08-21  Saleem Abdulrasool  
+
+   * fixedsizehash.h: Remove unused STROF macro.
+
 2021-08-20  Saleem Abdulrasool  
 
* fixedsizehash.h: Remove sys/cdefs.h include. Unconditionally
diff --git a/lib/fixedsizehash.h b/lib/fixedsizehash.h
index f333ad99..14f0fb88 100644
--- a/lib/fixedsizehash.h
+++ b/lib/fixedsizehash.h
@@ -33,7 +33,6 @@
 
 #include 
 
-#define STROF(t2) t2
 #define CONCAT_EXPANDED(t1,t2) t1 ## t2
 #define CONCAT(t1,t2) CONCAT_EXPANDED(t1,t2)
 
-- 
2.33.0.259.gc128427fd7-goog



Re: [PATCH v2] handle libc implemntations which do not provide `error.h`

2021-08-27 Thread Saleem Abdulrasool via Elfutils-devel
I think that this is not exactly ideal, as it will introduce a local
error_message_count in each translation unit, rather than giving it
vague linkage as I had hoped.  I think it may be better to introduce a new
source file here.  I can move the implementation around though.

A second issue is that playing with this further, it doesn't fully resolve
the PR as this only fixes it for libelf (which I realized only recently).

On Fri, Aug 20, 2021 at 1:28 PM Saleem Abdulrasool 
wrote:

> Introduce a configure time check for the presence of `error.h`.  In the
> case that `error.h` is not available, we can fall back to `err.h`.
> Although `err.h` is not a C standard header (it is a BSD extension),
> many libc implementations provide.  If there are targets which do not
> provide an implementation of `err.h`, it would be possible to further
> extend the implementation to be more portable.
>
> This resolves bug #21008.
>
> Signed-off-by: Saleem Abdulrasool 
> ---
>  configure.ac |  3 +++
>  lib/system.h | 26 +-
>  2 files changed, 28 insertions(+), 1 deletion(-)
>
> diff --git a/configure.ac b/configure.ac
> index 7caff2c5..177bb1a2 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -431,6 +431,9 @@ AC_CHECK_DECLS([reallocarray],[],[],
>
>  AC_CHECK_FUNCS([process_vm_readv])
>
> +AC_CHECK_HEADERS([error.h])
> +AC_CHECK_HEADERS([err.h])
> +
>  old_CFLAGS="$CFLAGS"
>  CFLAGS="$CFLAGS -D_GNU_SOURCE"
>  AC_FUNC_STRERROR_R()
> diff --git a/lib/system.h b/lib/system.h
> index 58d9deee..b963fd15 100644
> --- a/lib/system.h
> +++ b/lib/system.h
> @@ -29,8 +29,9 @@
>  #ifndef LIB_SYSTEM_H
>  #define LIB_SYSTEM_H   1
>
> +#include 
> +
>  #include 
> -#include 
>  #include 
>  #include 
>  #include 
> @@ -38,8 +39,31 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>
> +#if defined(HAVE_ERROR_H)
> +#include 
> +#elif defined(HAVE_ERR_H)
> +#include 
> +
> +static int error_message_count = 0;
> +
> +static inline void error(int status, int errnum, const char *format, ...)
> {
> +  va_list argp;
> +
> +  va_start(argp, format);
> +  verr(status, format, argp);
> +  va_end(argp);
> +
> +  if (status)
> +exit(status);
> +  ++error_message_count;
> +}
> +#else
> +#error "err.h or error.h must be available"
> +#endif
> +
>  #if __BYTE_ORDER == __LITTLE_ENDIAN
>  # define LE32(n)   (n)
>  # define LE64(n)   (n)
> --
> 2.33.0.rc2.250.ged5fa647cd-goog
>
>


[PATCH v3] handle libc implemntations which do not provide `error.h`

2021-08-27 Thread Saleem Abdulrasool via Elfutils-devel
Introduce a configure time check for the presence of `error.h`.  In the
case that `error.h` is not available, we can fall back to `err.h`.
Although `err.h` is not a C standard header (it is a BSD extension),
many libc implementations provide.  If there are targets which do not
provide an implementation of `err.h`, it would be possible to further
extend the implementation to be more portable.

This partially resolves bug #21008.

Signed-off-by: Saleem Abdulrasool 
---
 configure.ac|  3 +++
 lib/ChangeLog   |  7 +++
 lib/Makefile.am |  2 +-
 lib/error.c | 49 +
 lib/system.h| 13 -
 5 files changed, 72 insertions(+), 2 deletions(-)
 create mode 100644 lib/error.c

diff --git a/configure.ac b/configure.ac
index 7caff2c5..177bb1a2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -431,6 +431,9 @@ AC_CHECK_DECLS([reallocarray],[],[],
 
 AC_CHECK_FUNCS([process_vm_readv])
 
+AC_CHECK_HEADERS([error.h])
+AC_CHECK_HEADERS([err.h])
+
 old_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -D_GNU_SOURCE"
 AC_FUNC_STRERROR_R()
diff --git a/lib/ChangeLog b/lib/ChangeLog
index a95f8041..101a4e6f 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,10 @@
+2021-08-20  Saleem Abdulrasool  
+
+   * error.c: New file, adds error_number_count and error fallbacks.
+   * system.h: Declare error_number_count and error fallbacks for when
+   error.h is unavailable.
+   * Makefile.am (libeu_a_SOURCES): add error.c.
+
 2021-08-20  Saleem Abdulrasool  
 
* fixedsizehash.h: Remove sys/cdefs.h include. Unconditionally
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 97bf7329..766fbcd7 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -35,7 +35,7 @@ noinst_LIBRARIES = libeu.a
 
 libeu_a_SOURCES = xstrdup.c xstrndup.c xmalloc.c next_prime.c \
  crc32.c crc32_file.c \
- color.c printversion.c
+ color.c error.c printversion.c
 
 noinst_HEADERS = fixedsizehash.h libeu.h system.h dynamicsizehash.h list.h \
 eu-config.h color.h printversion.h bpf.h \
diff --git a/lib/error.c b/lib/error.c
new file mode 100644
index ..b0264efb
--- /dev/null
+++ b/lib/error.c
@@ -0,0 +1,49 @@
+/* Definitions for error handling fallback functions.
+   Copyright (C) 2021 Google, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+   Software Foundation; either version 3 of the License, or (at
+   your option) any later version
+
+   or
+
+ * the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at
+   your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see .  */
+
+#include 
+
+#if !defined(HAVE_ERROR_H) && defined(HAVE_ERR_H)
+#include 
+#include 
+#include 
+
+unsigned int error_message_count = 0;
+
+void error(int status, int errnum, const char *format, ...) {
+  va_list argp;
+
+  va_start(argp, format);
+  verr(status, format, argp);
+  va_end(argp);
+
+  if (status)
+exit(status);
+  ++error_message_count;
+}
+#endif
diff --git a/lib/system.h b/lib/system.h
index 58d9deee..edbc8488 100644
--- a/lib/system.h
+++ b/lib/system.h
@@ -29,8 +29,9 @@
 #ifndef LIB_SYSTEM_H
 #define LIB_SYSTEM_H   1
 
+#include 
+
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -38,8 +39,18 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
+#if defined(HAVE_ERROR_H)
+#include 
+#elif defined(HAVE_ERR_H)
+extern int error_message_count;
+void error(int status, int errnum, const char *format, ...);
+#else
+#error "err.h or error.h must be available"
+#endif
+
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 # define LE32(n)   (n)
 # define LE64(n)   (n)
-- 
2.33.0.259.gc128427fd7-goog



Re: [PATCH v2] handle libc implemntations which do not provide `error.h`

2021-08-27 Thread Saleem Abdulrasool via Elfutils-devel
We have two choices:
- revert and use the updated patch I already sent
- I can do a follow up change to migrate the code

I don't particularly have a strong opinion on which approach we take, since
the commit has already been done.  Since glibc systems are completely
untouched by the changes neither path should cause problems for bisection
in the future for previously supported systems.  I'd go with whatever is
most commonly done in this project.

On Fri, Aug 27, 2021 at 8:39 AM Mark Wielaard  wrote:

> Hi Saleem,
>
> On Fri, 2021-08-27 at 08:24 -0700, Saleem Abdulrasool via Elfutils-devel
> wrote:
> > I think that this is not exactly ideal, as it will introduce a local
> > error_message_count in each translation unit, rather than giving it
> > vague linkage as I had hoped.  I think it may be better to introduce a
> new
> > source file here.  I can move the implementation around though.
> >
> > A second issue is that playing with this further, it doesn't fully
> resolve
> > the PR as this only fixes it for libelf (which I realized only recently).
>
> Oops. Our messages crossed and I just pushed:
>
> commit 76c84c137a82a7cacbc69b1696052491b3bb81cb
> Author: Saleem Abdulrasool 
> Date:   Fri Aug 20 20:28:23 2021 +
>
> handle libc implementations which do not provide `error.h`
>
> Introduce a configure time check for the presence of `error.h`.  In the
> case that `error.h` is not available, we can fall back to `err.h`.
> Although `err.h` is not a C standard header (it is a BSD extension),
> many libc implementations provide.  If there are targets which do not
> provide an implementation of `err.h`, it would be possible to further
> extend the implementation to be more portable.
>
> This resolves bug #21008.
>
> Signed-off-by: Saleem Abdulrasool 
>
> It passes all local tests and it is currently going through the buildbot:
> https://builder.wildebeest.org/buildbot/#/changes/2530
> But of course all those systems use normal glibc.
>
> Should I revert the commit?
>
> Thanks,
>
> Mark
>


[PATCH] lib: avoid potential problems with `-fno-common`

2021-08-27 Thread Saleem Abdulrasool via Elfutils-devel
This properly homes the fallback function into a translation unit rather
than trying to define an inline common definition for the fallback path.
The intent of the original approach was to actually simply avoid adding
a new source file that is used for the fallback path.  However, that may
cause trouble with multiple definitions if the symbol does not get vague
linkage (which itself is not particularly great).  This simplifies the
behaviour at the cost of an extra inode.
---
 lib/ChangeLog   |  9 +
 lib/Makefile.am |  2 +-
 lib/error.c | 49 +
 lib/system.h| 17 ++---
 4 files changed, 61 insertions(+), 16 deletions(-)
 create mode 100644 lib/error.c

diff --git a/lib/ChangeLog b/lib/ChangeLog
index 589953cf..c784b689 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,12 @@
+2021-08-23  Saleem Abdulrasool  
+
+   * system.h: Remove inline definition for error and error_message_count
+   in the fallback path.
+   * Makefile.am (libeu_a_SOURCES): Add error.c.
+   * error.c: New file, moves the previous inline definitions to avoid
+   multiple definitions properly rather than relying on -fcommon and vague
+   linkage.
+
 2021-08-20  Saleem Abdulrasool  
 
* system.h: Check for HAVE_ERROR_H and HAVE_ERR_H and define
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 97bf7329..766fbcd7 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -35,7 +35,7 @@ noinst_LIBRARIES = libeu.a
 
 libeu_a_SOURCES = xstrdup.c xstrndup.c xmalloc.c next_prime.c \
  crc32.c crc32_file.c \
- color.c printversion.c
+ color.c error.c printversion.c
 
 noinst_HEADERS = fixedsizehash.h libeu.h system.h dynamicsizehash.h list.h \
 eu-config.h color.h printversion.h bpf.h \
diff --git a/lib/error.c b/lib/error.c
new file mode 100644
index ..75e964fd
--- /dev/null
+++ b/lib/error.c
@@ -0,0 +1,49 @@
+/* Definitions for error fallback functions.
+   Copyright (C) 2021 Google, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+   Software Foundation; either version 3 of the License, or (at
+   your option) any later version
+
+   or
+
+ * the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at
+   your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see .  */
+
+#include 
+
+#if !defined(HAVE_ERROR_H) && defined(HAVE_ERR_H)
+#include 
+#include 
+#include 
+
+unsigned int error_message_count = 0;
+
+void error(int status, int errnum, const char *format, ...) {
+  va_list argp;
+
+  va_start(argp, format);
+  verr(status, format, argp);
+  va_end(argp);
+
+  if (status)
+exit(status);
+  ++error_message_count;
+}
+#endif
diff --git a/lib/system.h b/lib/system.h
index b963fd15..edbc8488 100644
--- a/lib/system.h
+++ b/lib/system.h
@@ -45,21 +45,8 @@
 #if defined(HAVE_ERROR_H)
 #include 
 #elif defined(HAVE_ERR_H)
-#include 
-
-static int error_message_count = 0;
-
-static inline void error(int status, int errnum, const char *format, ...) {
-  va_list argp;
-
-  va_start(argp, format);
-  verr(status, format, argp);
-  va_end(argp);
-
-  if (status)
-exit(status);
-  ++error_message_count;
-}
+extern int error_message_count;
+void error(int status, int errnum, const char *format, ...);
 #else
 #error "err.h or error.h must be available"
 #endif
-- 
2.33.0.259.gc128427fd7-goog