BUILD: compiler: use a more portable set of asm(".weak") statements

The two recent patches b12966af1 ("BUILD: debug: mark the
__start_mem_stats/__stop_mem_stats symbols as weak") and 2a06e248f
("BUILD: initcall: mark the __start_i_* symbols as weak, not global")
aimed at fixing a build warning and resulted in a build breakage on
MacOS which doesn't have a ".weak" asm statement.

We've already had MacOS-specific asm() statements for section names, so
this patch continues on this trend by moving HA_GLOBL() to compiler.h
and using ".globl" on MacOS since apparently nobody complains there.

It is debatable whether to expose this only when !USE_OBSOLETE_LINKER
or all the time, but since these are just macroes it's no big deal to
let them be available when needed and let the caller decide on the
build conditions.

If any of the patches above is backported, this one will need to as
well.

(cherry picked from commit fb1b6f5bc0e8eac116e2cafe8716a7f16d95b58e)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit fdefe250f6db2406214e11a086a6219086f938ce)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/include/haproxy/bug.h b/include/haproxy/bug.h
index 99892d2..13dc161 100644
--- a/include/haproxy/bug.h
+++ b/include/haproxy/bug.h
@@ -128,8 +128,8 @@
 		.file = __FILE__, .line = __LINE__,			\
 		.type = MEM_STATS_TYPE_CALLOC,				\
 	};								\
-	__asm__(".weak __start_mem_stats");				\
-	__asm__(".weak __stop_mem_stats");				\
+	HA_GLOBL("__start_mem_stats");					\
+	HA_GLOBL("__stop_mem_stats");					\
 	_HA_ATOMIC_INC(&_.calls);					\
 	_HA_ATOMIC_ADD(&_.size, __x * __y);				\
 	calloc(__x,__y);						\
@@ -145,8 +145,8 @@
 		.file = __FILE__, .line = __LINE__,			\
 		.type = MEM_STATS_TYPE_FREE,				\
 	};								\
-	__asm__(".weak __start_mem_stats");				\
-	__asm__(".weak __stop_mem_stats");				\
+	HA_GLOBL("__start_mem_stats");					\
+	HA_GLOBL("__stop_mem_stats");					\
 	if (__x)							\
 		_HA_ATOMIC_INC(&_.calls);				\
 	free(__x);							\
@@ -159,8 +159,8 @@
 		.file = __FILE__, .line = __LINE__,			\
 		.type = MEM_STATS_TYPE_FREE,				\
 	};								\
-	__asm__(".weak __start_mem_stats");				\
-	__asm__(".weak __stop_mem_stats");				\
+	HA_GLOBL("__start_mem_stats");					\
+	HA_GLOBL("__stop_mem_stats");					\
 	if (__builtin_constant_p((x)) || __builtin_constant_p(*(x))) {  \
 		HA_LINK_ERROR(call_to_ha_free_attempts_to_free_a_constant); \
 	}								\
@@ -177,8 +177,8 @@
 		.file = __FILE__, .line = __LINE__,			\
 		.type = MEM_STATS_TYPE_MALLOC,				\
 	};								\
-	__asm__(".weak __start_mem_stats");				\
-	__asm__(".weak __stop_mem_stats");				\
+	HA_GLOBL("__start_mem_stats");					\
+	HA_GLOBL("__stop_mem_stats");					\
 	_HA_ATOMIC_INC(&_.calls);					\
 	_HA_ATOMIC_ADD(&_.size, __x);					\
 	malloc(__x);							\
@@ -191,8 +191,8 @@
 		.file = __FILE__, .line = __LINE__,			\
 		.type = MEM_STATS_TYPE_REALLOC,				\
 	};								\
-	__asm__(".weak __start_mem_stats");				\
-	__asm__(".weak __stop_mem_stats");				\
+	HA_GLOBL("__start_mem_stats");					\
+	HA_GLOBL("__stop_mem_stats");					\
 	_HA_ATOMIC_INC(&_.calls);					\
 	_HA_ATOMIC_ADD(&_.size, __y);					\
 	realloc(__x,__y);						\
@@ -205,8 +205,8 @@
 		.file = __FILE__, .line = __LINE__,			\
 		.type = MEM_STATS_TYPE_STRDUP,				\
 	};								\
-	__asm__(".weak __start_mem_stats");				\
-	__asm__(".weak __stop_mem_stats");				\
+	HA_GLOBL("__start_mem_stats");					\
+	HA_GLOBL("__stop_mem_stats");					\
 	_HA_ATOMIC_INC(&_.calls);					\
 	_HA_ATOMIC_ADD(&_.size, __y);					\
 	strdup(__x);							\
diff --git a/include/haproxy/compiler.h b/include/haproxy/compiler.h
index b975412..01fb0cc 100644
--- a/include/haproxy/compiler.h
+++ b/include/haproxy/compiler.h
@@ -88,6 +88,21 @@
 
 #endif // USE_OBSOLETE_LINKER
 
+/* Declare a symbol as global and if possible, as weak. Since we don't want to
+ * error on multiple definitions, the symbol is declared weak. On MacOS ".weak"
+ * does not exist and we must continue to use ".globl" instead. Note that
+ * ".global" is to be avoided on other platforms as llvm complains about it
+ * being used for symbols declared as weak elsewhere in the code. It may or may
+ * not work depending on linkers and assemblers, this is only for advanced use
+ * anyway (and most likely it will only work with !USE_OBSOLETE_LINKER).
+ */
+#if defined(__APPLE__)
+#  define __HA_GLOBL(sym)   __asm__(".globl " #sym)
+#else
+#  define __HA_GLOBL(sym)   __asm__(".weak " #sym)
+#endif
+#define HA_GLOBL(sym)    __HA_GLOBL(sym)
+
 /* use this attribute on a variable to move it to the read_mostly section */
 #if !defined(__read_mostly)
 #define __read_mostly           HA_SECTION("read_mostly")
diff --git a/include/haproxy/initcall.h b/include/haproxy/initcall.h
index 50dedb7..9f2c2ac 100644
--- a/include/haproxy/initcall.h
+++ b/include/haproxy/initcall.h
@@ -96,11 +96,9 @@
  * as a pointer (args are cast to (void*)). Do not use this macro directly,
  * use INITCALL{0..3}() instead.
  */
-#define __HA_GLOBL1(sym)   __asm__(".globl " #sym)
-#define __HA_GLOBL(sym)    __HA_GLOBL1(sym)
 #define __DECLARE_INITCALL(stg, linenum, function, a1, a2, a3)     \
-        __HA_GLOBL(__start_i_##stg );                              \
-        __HA_GLOBL(__stop_i_##stg );                               \
+        HA_GLOBL(__start_i_##stg );                                \
+        HA_GLOBL(__stop_i_##stg );                                 \
 	static const struct initcall *__initcb_##linenum           \
 	    __attribute__((__used__)) HA_INIT_SECTION(stg) =	   \
 	        (stg < STG_SIZE) ? &(const struct initcall) {      \