BUILD: re-implement an initcall variant without using executable sections
The current initcall implementation relies on dedicated sections (one
section per init stage) to store the initcall descriptors. Then upon
startup, these sections are scanned from beginning to end and all items
found there are called in sequence.
On platforms like AIX or Cygwin it seems difficult to figure the
beginning and end of sections as the linker doesn't seem to provide
the corresponding symbols. In order to replace this, this patch
simply implements an array of single linked (one per init stage)
which are fed using constructors for each register call. These
constructors are declared static, with a name depending on their
line number in the file, in order to avoid name clashes. The final
effect is the same, except that the method is slightly more expensive
in that it explicitly produces code to register these initcalls :
$ size haproxy.sections haproxy.constructor
text data bss dec hex filename
4060312 249176 1457652 5767140 57ffe4 haproxy.sections
4062862 260408 1457652 5780922 5835ba haproxy.constructor
This mechanism is enabled as an alternative to the default one when
build option USE_OBSOLETE_LINKER is set. This option is currently
enabled by default only on AIX and Cygwin, and may be attempted for
any target which fails to build complaining about missing symbols
__start_init_* and/or __stop_init_*.
Once confirmed as a reliable fix, this will likely have to be backported
to 1.9 where AIX and Cygwin do not build anymore.
diff --git a/Makefile b/Makefile
index 089353b..26dfcb4 100644
--- a/Makefile
+++ b/Makefile
@@ -47,6 +47,7 @@
# USE_DEVICEATLAS : enable DeviceAtlas api.
# USE_51DEGREES : enable third party device detection library from 51Degrees
# USE_SYSTEMD : enable sd_notify() support.
+# USE_OBSOLETE_LINKER : use when the linker fails to emit __start_init/__stop_init
#
# Options can be forced by specifying "USE_xxx=1" or can be disabled by using
# "USE_xxx=" (empty string).
@@ -279,7 +280,8 @@
USE_LINUX_SPLICE USE_LIBCRYPT USE_CRYPT_H USE_VSYSCALL \
USE_GETADDRINFO USE_OPENSSL USE_LUA USE_FUTEX USE_ACCEPT4 \
USE_MY_ACCEPT4 USE_ZLIB USE_SLZ USE_CPU_AFFINITY USE_TFO USE_NS \
- USE_DL USE_RT USE_DEVICEATLAS USE_51DEGREES USE_SYSTEMD
+ USE_DL USE_RT USE_DEVICEATLAS USE_51DEGREES USE_SYSTEMD \
+ USE_OBSOLETE_LINKER
#### Target system options
# Depending on the target platform, some options are set, as well as some
@@ -379,7 +381,7 @@
# AIX 5.1 only
ifeq ($(TARGET),aix51)
set_target_defaults = $(call default_opts, \
- USE_POLL USE_LIBCRYPT)
+ USE_POLL USE_LIBCRYPT USE_OBSOLETE_LINKER)
TARGET_CFLAGS = -Dss_family=__ss_family
DEBUG_CFLAGS =
endif
@@ -387,14 +389,15 @@
# AIX 5.2 and above
ifeq ($(TARGET),aix52)
set_target_defaults = $(call default_opts, \
- USE_POLL USE_LIBCRYPT)
+ USE_POLL USE_LIBCRYPT USE_OBSOLETE_LINKER)
TARGET_CFLAGS = -D_MSGQSUPPORT
DEBUG_CFLAGS =
endif
# Cygwin
ifeq ($(TARGET),cygwin)
- set_target_defaults = $(call default_opts,USE_POLL USE_TPROXY)
+ set_target_defaults = $(call default_opts, \
+ USE_POLL USE_TPROXY USE_OBSOLETE_LINKER)
# Cygwin adds IPv6 support only in version 1.7 (in beta right now).
TARGET_CFLAGS = $(if $(filter 1.5.%, $(shell uname -r)), -DUSE_IPV6 -DAF_INET6=23 -DINET6_ADDRSTRLEN=46, )
endif