Control: tags -1 patch

Michael,

My theory as to what is going on here follows.

Libfastjson uses modf(3) as implemented in libm, but does not declare NEEDED
against the library:

$ grep -r modf /tmp/libfastjson/
/tmp/libfastjson/json_print.c:  // needed for modf()
/tmp/libfastjson/json_print.c:  result = buffer_printf(buffer, 
(modf(jso->o.c_double.value, &dummy)==0)?"%.17g.0":"%.17g", 
jso->o.c_double.value);
/tmp/libfastjson/json_object.c: double dummy;  /* needed for modf() */
/tmp/libfastjson/json_object.c:                 (modf(jso->o.c_double.value, 
&dummy)==0)?"%.17g.0":"%.17g",
$ objdump -x /usr/lib/x86_64-linux-gnu/libfastjson.so | grep NEEDED             
                             
  NEEDED               libc.so.6

The default Debian build of src:rsyslog links with libsystemd.

$ grep LIBSYSTEMD_LIBS rsyslog/configure.ac
RSRT_LIBS="\$(RSRT_LIBS1) \$(LIBESTR_LIBS) \$(LIBFASTJSON_LIBS) 
\$(LIBSYSTEMD_LIBS)"

LIBSYSTEMD_LIBS is specified *after* LIBFASTJSON_LIBS and contains -lsystemd.

Libsystemd.so itself NEEDS libm and so at compile time the correct modf()
implementation is linked and all is well.

$ objdump -x /usr/lib/x86_64-linux-gnu/libsystemd.so | grep NEEDED              
                             
  NEEDED               libm.so.6
  NEEDED               libc.so.6
  NEEDED               ld-linux-x86-64.so.2

When building rsyslog without libsystemd (--disable-libsystemd), LIBSYSTEMD_LIBS
is empty. Although rsyslog specifies -lm, it is *before* -lfastjson. So in lines
such as this:

libtool: link: gcc -g -O2 -Werror=implicit-function-declaration 
-ffile-prefix-map=/build/rsyslog-8.2510.0=. -fstack-protector-strong 
-fstack-clash-protection -Wformat -Werror=format-security -fcf-protection 
-Wl,-z -Wl,relro -Wl,-z -Wl,now -o rsyslogd rsyslogd-syslogd.o 
rsyslogd-rsyslogd.o rsyslogd-omshell.o rsyslogd-omusrmsg.o rsyslogd-omfwd.o 
rsyslogd-omfile.o rsyslogd-ompipe.o rsyslogd-omdiscard.o rsyslogd-pmrfc5424.o 
rsyslogd-pmrfc3164.o rsyslogd-smtradfile.o rsyslogd-smfile.o rsyslogd-smfwd.o 
rsyslogd-smtradfwd.o rsyslogd-iminternal.o -Wl,--export-dynamic  
../grammar/.libs/libgrammar.a ../compat/.libs/compat.a -lz -lpthread 
../runtime/.libs/librsyslog.a -lm -lestr -lfastjson -luuid

modf() in libfastjson is not resolved and this produces the IFUNC runtime error
observed.

 /usr/sbin/rsyslogd: Relink `/usr/lib/x86_64-linux-gnu/libfastjson.so.4' with 
`/usr/lib/x86_64-linux-gnu/libm.so.6' for IFUNC symbol `modf'

There apear to be 2 possible fixes:

 1) Add -lm to libfastjson.pc, as implemented in the current upstream fix.

 2) Rebuild libfastjson with explicit -lm linkage as suggested by the error 
message.

To me, 2) makes more sense; surely it is libfastjson's responsibility to link
the correct symbols?

Adding the following patch to libfastjson, adds the correct libm NEEDED

+ diff -u /tmp/libfastjson/Makefile.am 
/var/cache/pbuilder/build/cow.393/libfastjson-1.2304.0/Makefile.am
--- /tmp/libfastjson/Makefile.am        2025-12-05 16:35:42.382689052 +0000
+++ /var/cache/pbuilder/build/cow.393/libfastjson-1.2304.0/Makefile.am  
2025-12-08 08:24:40.794398879 +0000
@@ -1,4 +1,3 @@
-
 EXTRA_DIST = README.html
 
 SUBDIRS = . tests
@@ -27,7 +26,7 @@
        -export-symbols-regex '^fjson_.*' \
        -no-undefined \
        @JSON_BSYMBOLIC_LDFLAGS@
-libfastjson_la_LIBADD = libfastjson-internal.la
+libfastjson_la_LIBADD = libfastjson-internal.la -lm
 
 libfastjson_la_SOURCES = \
        json_version.c \

$ objdump -x /libfastjson-1.2304.0/.libs/libfastjson.so | grep NEEDED           
                             
  NEEDED               libm.so.6
  NEEDED               libc.so.6

and rebuilding rsyslog without libsystemd against the patched libfastjson

$ objdump -x tools/rsyslogd|grep NEEDED
  NEEDED               libz.so.1
  NEEDED               libm.so.6
  NEEDED               libestr.so.0
  NEEDED               libfastjson.so.4
  NEEDED               libuuid.so.1
  NEEDED               libc.so.6

no longer produces a runtime error.

Which solution do you prefer?

Best wishes

Mark

Reply via email to