Re: [PATCH] build: allow turning off --no-undefined and -z,defs

2021-12-04 Thread Florian Weimer via Elfutils-devel
* Evgeny Vereshchagin:

> ASan, UBSan and MSan provided by clang aren't compatible with --no-undefined 
> and -z,defs:
> https://clang.llvm.org/docs/AddressSanitizer.html#usage
> https://github.com/google/sanitizers/issues/380
> so to build elfutils with clang with the sanitizers it should be possible
> to turn them off.
>
> Without this patch something like
>
> sed -i 's/^\(ZDEFS_LDFLAGS=\).*/\1/' configure.ac
> find -name Makefile.am | xargs sed -i 's/,--no-undefined//'
>
> should be used to make elfutils compile.
>
> The patch was tested in https://github.com/evverx/elfutils/pull/24 by
> compiling elfutils with both gcc and clang with and without ASan/UBsan
> and running `make check && make distcheck`. --no-undefined and -z,defs
> are still passed by default as expected.

Why isn't this a bug in the compiler driver?  Nowadays, GCC passes
-lasan if -fsanitize=address is used.  I think that's quite reasonable.

Thanks,
Florian



[PATCH v2] build: allow turning off --no-undefined and -z,defs

2021-12-04 Thread Evgeny Vereshchagin
ASan, UBSan and MSan provided by clang aren't compatible with --no-undefined 
and -z,defs:
https://clang.llvm.org/docs/AddressSanitizer.html#usage
https://github.com/google/sanitizers/issues/380
so to build elfutils with clang with the sanitizers it should be possible
to turn them off.

Without this patch something like

sed -i 's/^\(ZDEFS_LDFLAGS=\).*/\1/' configure.ac
find -name Makefile.am | xargs sed -i 's/,--no-undefined//'

should be used to make elfutils compile.

Issues like https://bugs.llvm.org/show_bug.cgi?id=30333 have been
open since at least 2016 so it seems it's safe to say that it isn't
going to be fixed anytime soon. It's so ingrained that some build
systems complain when `-fsanitize=...` is passed to clang without
turning off no-undefined.

The patch was tested in https://github.com/evverx/elfutils/pull/24 by
compiling elfutils with both gcc and clang with and without ASan/UBsan
and running `make check && make distcheck`. --no-undefined and -z,defs
are still passed by default as expected.

Signed-off-by: Evgeny Vereshchagin 
---
 ChangeLog  |  5 +
 configure.ac   | 31 ++-
 debuginfod/Makefile.am |  2 +-
 libasm/Makefile.am |  2 +-
 libdw/Makefile.am  |  2 +-
 libelf/Makefile.am |  2 +-
 6 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d61b21c7..33d20be5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2021-12-03  Evgeny Vereshchagin  
+
+   * configure.ac [--disable-no-undefined]: Allow turning off
+   --no-undefined and -z,defs to build elfutils with clang sanitizers.
+
 2021-11-10  Mark Wielaard  
 
* configure.ac (AC_INIT): Set version to 0.186.
diff --git a/configure.ac b/configure.ac
index ff9581d2..14cd2e6f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -153,16 +153,29 @@ AC_SUBST([fpie_CFLAGS])
 
 dso_LDFLAGS="-shared"
 
-ZDEFS_LDFLAGS="-Wl,-z,defs"
-AC_CACHE_CHECK([whether gcc supports $ZDEFS_LDFLAGS], ac_cv_zdefs, [dnl
-save_LDFLAGS="$LDFLAGS"
-LDFLAGS="$ZDEFS_LDFLAGS $save_LDFLAGS"
-AC_LINK_IFELSE([AC_LANG_PROGRAM()], ac_cv_zdefs=yes, ac_cv_zdefs=no)
-LDFLAGS="$save_LDFLAGS"
-])
-if test "$ac_cv_zdefs" = "yes"; then
-   dso_LDFLAGS="$dso_LDFLAGS $ZDEFS_LDFLAGS"
+# ASan, UBSan and MSan provided by clang aren't compatible with --no-undefined 
and -z,defs:
+# https://clang.llvm.org/docs/AddressSanitizer.html#usage
+# https://github.com/google/sanitizers/issues/380
+# so to build elfutils with clang with the sanitizers it should be possible
+# to turn them off.
+AC_ARG_ENABLE([no-undefined],
+AS_HELP_STRING([--disable-no-undefined],[disable --no-undefined and -z,defs]),
+[use_no_undefined=$enableval], [use_no_undefined=yes])
+if test "$use_no_undefined" = yes; then
+   ZDEFS_LDFLAGS="-Wl,-z,defs"
+   AC_CACHE_CHECK([whether gcc supports $ZDEFS_LDFLAGS], ac_cv_zdefs, [dnl
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$ZDEFS_LDFLAGS $save_LDFLAGS"
+   AC_LINK_IFELSE([AC_LANG_PROGRAM()], ac_cv_zdefs=yes, ac_cv_zdefs=no)
+   LDFLAGS="$save_LDFLAGS"
+   ])
+   if test "$ac_cv_zdefs" = "yes"; then
+   dso_LDFLAGS="$dso_LDFLAGS $ZDEFS_LDFLAGS"
+   fi
+
+   NO_UNDEFINED=",--no-undefined"
 fi
+AC_SUBST([NO_UNDEFINED])
 
 # We really want build-ids. Warn and force generating them if gcc was
 # configure without --enable-linker-build-id
diff --git a/debuginfod/Makefile.am b/debuginfod/Makefile.am
index 3adb2755..58bf71d3 100644
--- a/debuginfod/Makefile.am
+++ b/debuginfod/Makefile.am
@@ -102,7 +102,7 @@ endif
 $(LIBDEBUGINFOD_SONAME): $(srcdir)/libdebuginfod.map $(libdebuginfod_so_LIBS)
$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
-Wl,--soname,$(LIBDEBUGINFOD_SONAME) \
-   -Wl,--version-script,$<,--no-undefined \
+   -Wl,--version-script,$<$(NO_UNDEFINED) \
-Wl,--whole-archive $(libdebuginfod_so_LIBS) 
-Wl,--no-whole-archive \
$(libdebuginfod_so_LDLIBS)
@$(textrel_check)
diff --git a/libasm/Makefile.am b/libasm/Makefile.am
index c2b54811..683c9847 100644
--- a/libasm/Makefile.am
+++ b/libasm/Makefile.am
@@ -64,7 +64,7 @@ libasm_so_LIBS = libasm_pic.a
 libasm.so: $(srcdir)/libasm.map $(libasm_so_LIBS) $(libasm_so_DEPS)
$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
-Wl,--soname,$@.$(VERSION) \
-   -Wl,--version-script,$<,--no-undefined \
+   -Wl,--version-script,$<$(NO_UNDEFINED) \
-Wl,--whole-archive $(libasm_so_LIBS) -Wl,--no-whole-archive \
$(libasm_so_LDLIBS)
@$(textrel_check)
diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index 4fda33bd..534e5cc7 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -114,7 +114,7 @@ libdw_so_LDLIBS = $(libdw_so_DEPS) -ldl -lz $(argp_LDADD) 
$(fts_LIBS) $(obstack_
 libdw.so: $(srcdir)/libdw.map $(libdw_so_LIBS) $(libdw_so_DEPS)
$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
-Wl,--so

Re: [PATCH v2] build: allow turning off --no-undefined and -z,defs

2021-12-04 Thread Mark Wielaard
Hi Evgeny,

On Fri, Dec 03, 2021 at 02:17:21PM +, Evgeny Vereshchagin wrote:
> ASan, UBSan and MSan provided by clang aren't compatible with --no-undefined 
> and -z,defs:
> https://clang.llvm.org/docs/AddressSanitizer.html#usage
> https://github.com/google/sanitizers/issues/380
> so to build elfutils with clang with the sanitizers it should be possible
> to turn them off.

I have to agree with Florian, this really is a bug in the compiler you
are using.  Adding -fsanitize=address to CFLAGS/CXXFLAGS works just
fine with gcc.  I have been using it in the past in combination with
the afl fuzzer (32bit only).  It doesn't work together with
--enable-valgrind though.

That said, I really would like to add address sanitizer support. It
would be great to add this to our buildbot CI to catch more issues
early. We already support --enable-sanitize-undefined and
--enable-valgrind. But sadly we have to disable valgrind in a couple
of testcases, specifically when testing the debuginfod server.

I just testing with gcc (Debian 10.2.1-6) 10.2.1 20210110 on arm64 and
it actually found some issues. I'll post patches for those.

There is one issue with the test-nlist test because we use special
CFLAGS for that. But if we introduce an --enable-sanitize-address we
could work around that.

If clang really cannot be fixed then your patch in combination with an
--enable-sanitize-address might be a good idea. But I don't think it
makes sense as a standalone option. In the past we made the mistake of
adding configure options to disable some necessary flags, like
--disable-symbol-versioning, which was a mistake. There are now
distros shipping elfutils libraries with broken abis while using the
same SONAMEs.

Cheers,

Mark



[PATCH] readelf: Workaround stringop-truncation error

2021-12-04 Thread Mark Wielaard
In function ‘strncpy’,
inlined from ‘print_ehdr’ at readelf.c:1175:4:
error: ‘__builtin_strncpy’ specified bound 512 equals destination size
   [-Werror=stringop-truncation]

strncpy doesn't terminate the copied string if there is not enough
room. We compensate later by explicitly adding a zero terminator at
buf[sizeof (buf) - 1]. Normally gcc does see this, but with
-fsanitize=address there is too much (checking) code in between. But
it is actually better to not let strncpy do too much work, so
substract one from the size.

Signed-off-by: Mark Wielaard 
---
 src/ChangeLog | 4 
 src/readelf.c | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index 05b2522d..263e9faa 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+2021-12-04  Mark Wielaard  
+
+   * readelf.c (print_ehdr): Pass sizeof (buf) - 1 to strncpy.
+
 2021-10-20  John M Mellor-Crummey  
 
* readelf.c (print_debug_line_section): Try to read
diff --git a/src/readelf.c b/src/readelf.c
index c10038e3..93fb5989 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -1172,7 +1172,7 @@ print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
  (uint32_t) shdr->sh_link);
   else
{
- strncpy (buf, _(" ([0] not available)"), sizeof (buf));
+ strncpy (buf, _(" ([0] not available)"), sizeof (buf) - 1);
  buf[sizeof (buf) - 1] = '\0';
}
 
-- 
2.30.2



[PATCH] tests: varlocs workaround format-overflow errors

2021-12-04 Thread Mark Wielaard
In function ‘printf’,
inlined from ‘handle_attr’ at varlocs.c:932:3:
error: ‘%s’ directive argument is null [-Werror=format-overflow=]

The warning is technically correct. A %s argument should not be
NULL. Although in practice all implementations will print it as
"(null)". Workaround this by simply changing the dwarf string
functions to return an "" string. The test is for the correct
names, either "(null)" or "" would make it fail (also remove
a now unnecessary assert, the switch statement will check for unknown
opcodes anyway).

Signed-off-by: Mark Wielaard 
---
 tests/ChangeLog | 10 ++
 tests/varlocs.c | 11 +--
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/tests/ChangeLog b/tests/ChangeLog
index 9dceda89..a5673f18 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,13 @@
+2021-12-04  Mark Wielaard  
+
+   * varlocs.c (dwarf_encoding_string): Return "" instead
+   of NULL.
+   (dwarf_tag_string): Return "" instead of NULL.
+   (dwarf_attr_string): Return "" instead of NULL.
+   (dwarf_form_string): Return "" instead of NULL.
+   (dwarf_opcode_string): Return "" instead of NULL.
+   (print_expr): Remove assert.
+
 2021-11-18  Mark Wielaard  
 
* Makefile.am (dwfl_proc_attach_LDFLAGS): Add -rdynamic.
diff --git a/tests/varlocs.c b/tests/varlocs.c
index 152c6555..d2c13767 100644
--- a/tests/varlocs.c
+++ b/tests/varlocs.c
@@ -76,7 +76,7 @@ dwarf_encoding_string (unsigned int code)
   if (likely (code < sizeof (known) / sizeof (known[0])))
 return known[code];
 
-  return NULL;
+  return "";
 }
 
 static const char *
@@ -88,7 +88,7 @@ dwarf_tag_string (unsigned int tag)
   DWARF_ALL_KNOWN_DW_TAG
 #undef DWARF_ONE_KNOWN_DW_TAG
 default:
-  return NULL;
+  return "";
 }
 }
 
@@ -101,7 +101,7 @@ dwarf_attr_string (unsigned int attrnum)
   DWARF_ALL_KNOWN_DW_AT
 #undef DWARF_ONE_KNOWN_DW_AT
 default:
-  return NULL;
+  return "";
 }
 }
 
@@ -114,7 +114,7 @@ dwarf_form_string (unsigned int form)
   DWARF_ALL_KNOWN_DW_FORM
 #undef DWARF_ONE_KNOWN_DW_FORM
 default:
-  return NULL;
+  return "";
 }
 }
 
@@ -160,7 +160,7 @@ dwarf_opcode_string (unsigned int code)
   if (likely (code < sizeof (known) / sizeof (known[0])))
 return known[code];
 
-  return NULL;
+  return "";
 }
 
 // Forward reference for print_expr_block.
@@ -198,7 +198,6 @@ print_expr (Dwarf_Attribute *attr, Dwarf_Op *expr, 
Dwarf_Addr addr, int depth)
 
   uint8_t atom = expr->atom;
   const char *opname = dwarf_opcode_string (atom);
-  assert (opname != NULL);
 
   switch (atom)
 {
-- 
2.30.2



[PATCH] debuginfod: Fix debuginfod_pool leak

2021-12-04 Thread Mark Wielaard
gcc address sanitizer detected a dangling debuginfod_client handler
when debuginfod exits. Make sure to groom the debuginfod client pool
before exit after all threads are done.

Signed-off-by: Mark Wielaard 
---
 debuginfod/ChangeLog  | 4 
 debuginfod/debuginfod.cxx | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/debuginfod/ChangeLog b/debuginfod/ChangeLog
index 822bd637..c9253d6c 100644
--- a/debuginfod/ChangeLog
+++ b/debuginfod/ChangeLog
@@ -1,3 +1,7 @@
+2021-12-04  Mark Wielaard  
+
+   * debuginfod.cxx (main): Call debuginfod_pool_groom before exit.
+
 2021-11-10  Érico N. Rolim  
 
* debuginfod.cxx: include "system.h" under 'extern "C"' block.
diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx
index 764e7b94..bb8322db 100644
--- a/debuginfod/debuginfod.cxx
+++ b/debuginfod/debuginfod.cxx
@@ -3994,6 +3994,8 @@ main (int argc, char *argv[])
 }
 }
 
+  debuginfod_pool_groom ();
+
   // NB: no problem with unconditional free here - an earlier failed regcomp 
would exit program
   (void) regfree (& file_include_regex);
   (void) regfree (& file_exclude_regex);
-- 
2.30.2



[PATCH] debuginfod: sqlite3_sharedprefix_fn should not compare past end of string

2021-12-04 Thread Mark Wielaard
gcc address sanitizer detected a read after the end of string in
sqlite3_sharedprefix_fn. Make sure to stop comparing the strings when
seeing the zero terminator.

Signed-off-by: Mark Wielaard 
---
 debuginfod/debuginfod.cxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx
index bb8322db..154f14ba 100644
--- a/debuginfod/debuginfod.cxx
+++ b/debuginfod/debuginfod.cxx
@@ -3704,7 +3704,7 @@ static void sqlite3_sharedprefix_fn (sqlite3_context* c, 
int argc, sqlite3_value
   const unsigned char* a = sqlite3_value_text (argv[0]);
   const unsigned char* b = sqlite3_value_text (argv[1]);
   int i = 0;
-  while (*a++ == *b++)
+  while (*a != '\0' && *b != '\0' && *a++ == *b++)
 i++;
   sqlite3_result_int (c, i);
 }
-- 
2.30.2



[PATCH] debuginfod: Clear and reset debuginfod_client winning_headers on reuse

2021-12-04 Thread Mark Wielaard
gcc address sanitizer detected a leak of the debuginfod_client
winning_headers when the handle was reused. Make sure to free and
reset the winning_headers field before reuse.

Signed-off-by: Mark Wielaard 
---
 debuginfod/ChangeLog   | 5 +
 debuginfod/debuginfod-client.c | 7 ++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/debuginfod/ChangeLog b/debuginfod/ChangeLog
index c9253d6c..e2f07f97 100644
--- a/debuginfod/ChangeLog
+++ b/debuginfod/ChangeLog
@@ -1,3 +1,8 @@
+2021-12-04  Mark Wielaard  
+
+   * debuginfod-client.c (debuginfod_query_server): Free winning_headers.
+   Reset response_data_size when clearing response_data.
+
 2021-12-04  Mark Wielaard  
 
* debuginfod.cxx (main): Call debuginfod_pool_groom before exit.
diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c
index c875ee62..20779d9f 100644
--- a/debuginfod/debuginfod-client.c
+++ b/debuginfod/debuginfod-client.c
@@ -1028,7 +1028,11 @@ debuginfod_query_server (debuginfod_client *c,
   int committed_to = -1;
   bool verbose_reported = false;
   struct timespec start_time, cur_time;
-  c->winning_headers = NULL;
+  if (c->winning_headers != NULL)
+{
+  free (c->winning_headers);
+  c->winning_headers = NULL;
+}
   if ( maxtime > 0 && clock_gettime(CLOCK_MONOTONIC_RAW, &start_time) == -1)
 {
   rc = errno;
@@ -1072,6 +1076,7 @@ debuginfod_query_server (debuginfod_client *c,
 if (vfd >= 0 && c->winning_headers != NULL)
   dprintf(vfd, "\n%s", c->winning_headers);
 data[committed_to].response_data = NULL;
+data[committed_to].response_data_size = 0;
   }
 
   }
-- 
2.30.2



[PATCH v3] build: allow turning off --no-undefined and -z,defs

2021-12-04 Thread Evgeny Vereshchagin
ASan, UBSan and MSan provided by clang aren't compatible with --no-undefined 
and -z,defs:
https://clang.llvm.org/docs/AddressSanitizer.html#usage
https://github.com/google/sanitizers/issues/380
so to build elfutils with clang with the sanitizers it should be possible
to turn them off.

It's implemented as a standalone option because there are places like
OSS-Fuzz for example where all the sanitizer flags are passed via CFLAGS
and CXXFLAGS: 
https://google.github.io/oss-fuzz/getting-started/new-project-guide/#Requirements
and it should be possible to just turn off --no-undefined and -z,defs
withut flipping other "configure" options and interfering with all
those fine-grained -fsanitize=... and -fno-sanitize-recover=... compiler flags. 
 Other than that, while
options like --enable-sanitize-undefined are helpful shortcuts, they
simply can't cover all the usecases and it's still necessary to pass
additional compiler flags to clang via CFLAGS to for example get around issues 
like
https://github.com/evverx/elfutils/issues/16 and
https://github.com/evverx/elfutils/issues/15.

Issues like https://bugs.llvm.org/show_bug.cgi?id=30333 have been
open since at least 2016 so it seems it's safe to say that it isn't
going to be fixed anytime soon. It's so ingrained that some build
systems complain when `-fsanitize=...` is passed to clang without
turning off no-undefined.

Without this patch something like

sed -i 's/^\(ZDEFS_LDFLAGS=\).*/\1/' configure.ac
find -name Makefile.am | xargs sed -i 's/,--no-undefined//'

should be used to make elfutils compile.

The patch was tested in https://github.com/evverx/elfutils/pull/24 by
compiling elfutils with both gcc and clang with and without ASan/UBsan
and running `make check && make distcheck`. --no-undefined and -z,defs
are still passed by default as expected.

Signed-off-by: Evgeny Vereshchagin 
---
 ChangeLog  |  5 +
 configure.ac   | 31 ++-
 debuginfod/Makefile.am |  2 +-
 libasm/Makefile.am |  2 +-
 libdw/Makefile.am  |  2 +-
 libelf/Makefile.am |  2 +-
 6 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d61b21c7..33d20be5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2021-12-03  Evgeny Vereshchagin  
+
+   * configure.ac [--disable-no-undefined]: Allow turning off
+   --no-undefined and -z,defs to build elfutils with clang sanitizers.
+
 2021-11-10  Mark Wielaard  
 
* configure.ac (AC_INIT): Set version to 0.186.
diff --git a/configure.ac b/configure.ac
index ff9581d2..14cd2e6f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -153,16 +153,29 @@ AC_SUBST([fpie_CFLAGS])
 
 dso_LDFLAGS="-shared"
 
-ZDEFS_LDFLAGS="-Wl,-z,defs"
-AC_CACHE_CHECK([whether gcc supports $ZDEFS_LDFLAGS], ac_cv_zdefs, [dnl
-save_LDFLAGS="$LDFLAGS"
-LDFLAGS="$ZDEFS_LDFLAGS $save_LDFLAGS"
-AC_LINK_IFELSE([AC_LANG_PROGRAM()], ac_cv_zdefs=yes, ac_cv_zdefs=no)
-LDFLAGS="$save_LDFLAGS"
-])
-if test "$ac_cv_zdefs" = "yes"; then
-   dso_LDFLAGS="$dso_LDFLAGS $ZDEFS_LDFLAGS"
+# ASan, UBSan and MSan provided by clang aren't compatible with --no-undefined 
and -z,defs:
+# https://clang.llvm.org/docs/AddressSanitizer.html#usage
+# https://github.com/google/sanitizers/issues/380
+# so to build elfutils with clang with the sanitizers it should be possible
+# to turn them off.
+AC_ARG_ENABLE([no-undefined],
+AS_HELP_STRING([--disable-no-undefined],[disable --no-undefined and -z,defs]),
+[use_no_undefined=$enableval], [use_no_undefined=yes])
+if test "$use_no_undefined" = yes; then
+   ZDEFS_LDFLAGS="-Wl,-z,defs"
+   AC_CACHE_CHECK([whether gcc supports $ZDEFS_LDFLAGS], ac_cv_zdefs, [dnl
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$ZDEFS_LDFLAGS $save_LDFLAGS"
+   AC_LINK_IFELSE([AC_LANG_PROGRAM()], ac_cv_zdefs=yes, ac_cv_zdefs=no)
+   LDFLAGS="$save_LDFLAGS"
+   ])
+   if test "$ac_cv_zdefs" = "yes"; then
+   dso_LDFLAGS="$dso_LDFLAGS $ZDEFS_LDFLAGS"
+   fi
+
+   NO_UNDEFINED=",--no-undefined"
 fi
+AC_SUBST([NO_UNDEFINED])
 
 # We really want build-ids. Warn and force generating them if gcc was
 # configure without --enable-linker-build-id
diff --git a/debuginfod/Makefile.am b/debuginfod/Makefile.am
index 3adb2755..58bf71d3 100644
--- a/debuginfod/Makefile.am
+++ b/debuginfod/Makefile.am
@@ -102,7 +102,7 @@ endif
 $(LIBDEBUGINFOD_SONAME): $(srcdir)/libdebuginfod.map $(libdebuginfod_so_LIBS)
$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
-Wl,--soname,$(LIBDEBUGINFOD_SONAME) \
-   -Wl,--version-script,$<,--no-undefined \
+   -Wl,--version-script,$<$(NO_UNDEFINED) \
-Wl,--whole-archive $(libdebuginfod_so_LIBS) 
-Wl,--no-whole-archive \
$(libdebuginfod_so_LDLIBS)
@$(textrel_check)
diff --git a/libasm/Makefile.am b/libasm/Makefile.am
index c2b54811..683c9847 100644
--- a/libasm/Makefile.am
+++ b/libasm/Makefile.am
@@ -64,7 +64,7 @@ libasm_so_LIBS = libas

[PATCH] configure: Add --enable-sanitize-address

2021-12-04 Thread Mark Wielaard
--enable-sanitize-address makes sure that all code is compiled with
-fsanitizer=address and all tests run against libasan.

It can be combined with --enable-sanitize-undefined, but not with
--enable-valgrind.

In maintainer mode there is one program that causes leaks, i386_gendis,
so disable leak detection for that program.

One testcase, test_nlist, needs special linker flags, make sure it also
uses -fsanitizer=address when using the address sanitizer.

Signed-off-by: Mark Wielaard 
---
 ChangeLog  |  4 
 configure.ac   | 25 +
 libcpu/ChangeLog   |  5 +
 libcpu/Makefile.am | 10 +-
 tests/ChangeLog|  6 ++
 tests/Makefile.am  | 10 --
 6 files changed, 57 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d61b21c7..f00db17b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2021-12-04  Mark Wielaard  
+
+   * configure.ac: Add --enable-sanitize-address.
+
 2021-11-10  Mark Wielaard  
 
* configure.ac (AC_INIT): Set version to 0.186.
diff --git a/configure.ac b/configure.ac
index ff9581d2..48071165 100644
--- a/configure.ac
+++ b/configure.ac
@@ -307,10 +307,34 @@ esac
 AC_DEFINE_UNQUOTED(CHECK_UNDEFINED, $check_undefined_val,
   [Building with -fsanitize=undefined or not])
 
+AC_ARG_ENABLE([sanitize-address],
+  AS_HELP_STRING([--enable-sanitize-address],
+ [Use gcc address sanitizer]),
+ [use_address=$enableval], [use_address=no])
+if test "$use_address" = yes; then
+  old_CFLAGS="$CFLAGS"
+  old_CXXFLAGS="$CXXFLAGS"
+  old_LDFLAGS="$LDFLAGS"
+  # We want to fail immediately on first error, don't try to recover.
+  CFLAGS="$CFLAGS -fsanitize=address -fno-sanitize-recover"
+  CXXFLAGS="$CXXFLAGS -fsanitize=address -fno-sanitize-recover"
+  # Some compilers don't handle -fsanatize=address correctly with 
--no-undefined
+  LDFLAGS="-Wl,-z,defs -shared"
+  AC_LINK_IFELSE([AC_LANG_SOURCE([int main (int argc, char **argv) { return 0; 
}])], use_address=yes, use_address=no)
+  AS_IF([test "x$use_address" != xyes],
+AC_MSG_WARN([gcc address sanitizer not available])
+CFLAGS="$old_CFLAGS" CXXFLAGS="$old_CXXFLAGS")
+  LDFLAGS="$old_LDFLAGS"
+fi
+AM_CONDITIONAL(USE_ADDRESS_SANITIZER, test "$use_address" = yes)
+
 AC_ARG_ENABLE([valgrind],
 AS_HELP_STRING([--enable-valgrind],[run all tests under valgrind]),
 [use_valgrind=$enableval], [use_valgrind=no])
 if test "$use_valgrind" = yes; then
+  if test "$use_address" = yes; then
+AC_MSG_ERROR([cannot enable valgrind and sanitize address together])
+  fi
   AC_CHECK_PROG(HAVE_VALGRIND, valgrind, yes, no)
   if test "$HAVE_VALGRIND" = "no"; then
 AC_MSG_ERROR([valgrind not found])
@@ -809,6 +833,7 @@ AC_MSG_NOTICE([
 gcov support   : ${use_gcov}
 run all tests under valgrind   : ${use_valgrind}
 gcc undefined behaviour sanitizer  : ${use_undefined}
+gcc address sanitizer  : ${use_address}
 use rpath in tests : ${tests_use_rpath}
 test biarch: ${utrace_cv_cc_biarch}
 ])
diff --git a/libcpu/ChangeLog b/libcpu/ChangeLog
index 7cca9419..48fbba19 100644
--- a/libcpu/ChangeLog
+++ b/libcpu/ChangeLog
@@ -1,3 +1,8 @@
+2021-12-04  Mark Wielaard  
+
+   * Makefile.am (GENDIS_ENV): New variable, depends on
+   USE_ADDRESS_SANITIZER.
+
 2020-12-20  Dmitry V. Levin  
 
* .gitignore: New file.
diff --git a/libcpu/Makefile.am b/libcpu/Makefile.am
index 43844ecf..57d0a164 100644
--- a/libcpu/Makefile.am
+++ b/libcpu/Makefile.am
@@ -61,8 +61,16 @@ noinst_HEADERS += memory-access.h i386_parse.h i386_data.h
 
 noinst_PROGRAMS = i386_gendis$(EXEEXT)
 
+# i386_gendis doesn't clean up, ignore leaks.
+# It is just a build tool to generate source in maintainer mode.
+if USE_ADDRESS_SANITIZER
+GENDIS_ENV=env ASAN_OPTIONS=detect_leaks=0
+else
+GENDIS_ENV=
+endif
+
 $(srcdir)/%_dis.h: %_defs i386_gendis$(EXEEXT)
-   $(AM_V_GEN)./i386_gendis$(EXEEXT) $< > $@T
+   $(AM_V_GEN) $(GENDIS_ENV) ./i386_gendis$(EXEEXT) $< > $@T
$(AM_V_at)mv -f $@T $@
 
 else
diff --git a/tests/ChangeLog b/tests/ChangeLog
index a5673f18..76cb974a 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,9 @@
+2021-12-04  Mark Wielaard  
+
+   * Makefile.am (EXTRA_NLIST_CFLAGS): New variable depends on
+   USE_ADDRESS_SANITIZER.
+   (test_nlist_CFLAGS): Add EXTRA_NLIST_CFLAGS.
+
 2021-12-04  Mark Wielaard  
 
* varlocs.c (dwarf_encoding_string): Return "" instead
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 2298a5ae..8acaeaf2 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -87,7 +87,13 @@ endif
 
 # test_nlist checks its own symbol table, and expects various symbols
 # to be in the order as specified in the source file. Explicitly set
-# minimal CFLAGS
+# minimal CFLAGS. But add address sanitizer if in use.
+if USE_ADDRESS_SANITIZER
+EXTRA_NL