Hi Max,

On Thu, Apr 23, 2015 at 12:18:10AM +0300, Max Filippov wrote:
> I've got a segfault in ltrace on uClibc-based system, caused by infinite
> recursion in the dwfl_report_elf function [1]. This happens because there
> is no symbol versioning support in uClibc and there are two versions of
> that function, one of them calling the other.

elfutils really depends on symbol versioning to keep ABI compatibility.
I cannot say I am a fan of supporting a libc that doesn't support it.

> Does the below patch look
> like a good solution to this?

It does. Before pushing it I have added ChangeLog entries and added an
extra warning in configure.ac to make clear this isn't recommended. You
are on your own if you use this configure option though.

What do the test results look like on your setup?

Thanks,

Mark
>From e1fa2f39edbb9cbe6a42054048af02cc81a98544 Mon Sep 17 00:00:00 2001
From: Max Filippov <jcmvb...@gmail.com>
Date: Thu, 23 Apr 2015 20:46:59 +0200
Subject: [PATCH] Allow disabling symbol versioning at configure time

Due to missing symbol versioning support in uClibc calls to versioned
functions that internally call different version of themselves results
in infinite recursion.

Introduce macro SYMBOL_VERSIONING and use it instead of plain SHARED to
decide whether symbol versioning is needed. Control this macro
definition with new configure option --disable-symbol-versioning.

Signed-off-by: Max Filippov <jcmvb...@gmail.com>
Signed-off-by: Mark Wielaard <m...@redhat.com>
---
 ChangeLog                      |  4 ++++
 config/eu.am                   | 10 ++++++++--
 configure.ac                   |  7 +++++++
 lib/ChangeLog                  |  4 ++++
 lib/eu-config.h                |  6 +++---
 libdwfl/ChangeLog              |  9 +++++++++
 libdwfl/core-file.c            |  2 +-
 libdwfl/dwfl_module_build_id.c |  2 +-
 libdwfl/dwfl_report_elf.c      |  2 +-
 9 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9a0a82d..d45bf67 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2015-04-23  Max Filippov  <jcmvb...@gmail.com>
+
+       * configure.ac: Add --disable-symbol-versioning.
+
 2015-04-14  Mark Wielaard  <m...@redhat.com>
 
        * configure.ac (ac_cv_c99): Add explicit checks for all GNU99
diff --git a/config/eu.am b/config/eu.am
index faf8add..6103a3e 100644
--- a/config/eu.am
+++ b/config/eu.am
@@ -38,16 +38,22 @@ AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \
 
 COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE))
 
+DEFS.os = -DPIC -DSHARED
+if SYMBOL_VERSIONING
+DEFS.os += -DSYMBOL_VERSIONING
+else
+endif
+
 %.os: %.c %.o
 if AMDEP
-       if $(COMPILE.os) -c -o $@ -fpic -DPIC -DSHARED -MT $@ -MD -MP \
+       if $(COMPILE.os) -c -o $@ -fpic $(DEFS.os) -MT $@ -MD -MP \
          -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \
        then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \
             rm -f "$(DEPDIR)/$*.Tpo"; \
        else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
        fi
 else
-       $(COMPILE.os) -c -o $@ -fpic -DPIC -DSHARED $<
+       $(COMPILE.os) -c -o $@ -fpic $(DEFS.os) $<
 endif
 
 CLEANFILES = *.gcno *.gcda
diff --git a/configure.ac b/configure.ac
index ed2c964..be01573 100644
--- a/configure.ac
+++ b/configure.ac
@@ -241,6 +241,13 @@ AS_HELP_STRING([--disable-textrelcheck],
                [Disable textrelcheck being a fatal error]))
 AM_CONDITIONAL(FATAL_TEXTREL, [test "x$enable_textrelcheck" != "xno"])
 
+AC_ARG_ENABLE([symbol-versioning],
+AS_HELP_STRING([--disable-symbol-versioning],
+               [Disable symbol versioning in shared objects]))
+AM_CONDITIONAL(SYMBOL_VERSIONING, [test "x$enable_symbol_versioning" != "xno"])
+AS_IF([test "x$enable_symbol_versioning" = "xno"],
+      [AC_MSG_WARN([Disabling symbol versioning breaks ABI compatibility.])])
+
 dnl The directories with content.
 
 dnl Documentation.
diff --git a/lib/ChangeLog b/lib/ChangeLog
index 4415213..166f047 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,7 @@
+2015-04-23  Max Filippov  <jcmvb...@gmail.com>
+
+       * eu-config.h: Use SYMBOL_VERSIONING as guard.
+
 2014-01-17  Lei Zhang  <thes...@google.com>
 
        * crc32_file.c: Include config.h.
diff --git a/lib/eu-config.h b/lib/eu-config.h
index 3afff26..5bb21c1 100644
--- a/lib/eu-config.h
+++ b/lib/eu-config.h
@@ -163,7 +163,7 @@ asm (".section predict_data, \"aw\"; .previous\n"
 #define ELFUTILS_HEADER(name) <lib##name.h>
 
 
-#ifdef SHARED
+#ifdef SYMBOL_VERSIONING
 # define OLD_VERSION(name, version) \
   asm (".globl _compat." #version "." #name "\n" \
        "_compat." #version "." #name " = " #name "\n" \
@@ -181,8 +181,8 @@ asm (".section predict_data, \"aw\"; .previous\n"
 # define OLD_VERSION(name, version) /* Nothing for static linking.  */
 # define NEW_VERSION(name, version) /* Nothing for static linking.  */
 # define COMPAT_VERSION_NEWPROTO(name, version, prefix) \
-  error "should use #ifdef SHARED"
-# define COMPAT_VERSION(name, version, prefix) error "should use #ifdef SHARED"
+  error "should use #ifdef SYMBOL_VERSIONING"
+# define COMPAT_VERSION(name, version, prefix) error "should use #ifdef 
SYMBOL_VERSIONING"
 #endif
 
 
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index d4cd3f5..cbaad85 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,12 @@
+2015-04-23  Max Filippov  <jcmvb...@gmail.com>
+
+       * core-file.c (_compat_without_executable_dwfl_core_file_report):
+       Guard with SYMBOL_VERSIONING.
+       * dwfl_module_build_id.c (_compat_vaddr_at_end_dwfl_module_build_id):
+       Likewise.
+       * dwfl_report_elf.c (_compat_without_add_p_vaddr_dwfl_report_elf):
+       Likewise.
+
 2015-04-02  Mark Wielaard  <m...@redhat.com>
 
        * segment.c (insert): Check correct number of lookup_elts.
diff --git a/libdwfl/core-file.c b/libdwfl/core-file.c
index 324e9d2..bbe0899 100644
--- a/libdwfl/core-file.c
+++ b/libdwfl/core-file.c
@@ -588,7 +588,7 @@ dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char 
*executable)
 INTDEF (dwfl_core_file_report)
 NEW_VERSION (dwfl_core_file_report, ELFUTILS_0.158)
 
-#ifdef SHARED
+#ifdef SYMBOL_VERSIONING
 int _compat_without_executable_dwfl_core_file_report (Dwfl *dwfl, Elf *elf);
 COMPAT_VERSION_NEWPROTO (dwfl_core_file_report, ELFUTILS_0.146,
                         without_executable)
diff --git a/libdwfl/dwfl_module_build_id.c b/libdwfl/dwfl_module_build_id.c
index 350bbf8..c9a42ca 100644
--- a/libdwfl/dwfl_module_build_id.c
+++ b/libdwfl/dwfl_module_build_id.c
@@ -101,7 +101,7 @@ dwfl_module_build_id (Dwfl_Module *mod,
 INTDEF (dwfl_module_build_id)
 NEW_VERSION (dwfl_module_build_id, ELFUTILS_0.138)
 
-#ifdef SHARED
+#ifdef SYMBOL_VERSIONING
 COMPAT_VERSION (dwfl_module_build_id, ELFUTILS_0.130, vaddr_at_end)
 
 int
diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c
index 3a4ae2e..624284c 100644
--- a/libdwfl/dwfl_report_elf.c
+++ b/libdwfl/dwfl_report_elf.c
@@ -321,7 +321,7 @@ dwfl_report_elf (Dwfl *dwfl, const char *name, const char 
*file_name, int fd,
 INTDEF (dwfl_report_elf)
 NEW_VERSION (dwfl_report_elf, ELFUTILS_0.156)
 
-#ifdef SHARED
+#ifdef SYMBOL_VERSIONING
 Dwfl_Module *
   _compat_without_add_p_vaddr_dwfl_report_elf (Dwfl *dwfl, const char *name,
                                               const char *file_name, int fd,
-- 
2.1.0

Reply via email to