From: Willy Tarreau Date: Thu, 14 Apr 2022 14:57:12 +0000 (+0200) Subject: BUILD: compiler: use a more portable set of asm(".weak") statements X-Git-Tag: v2.6-dev6~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fb1b6f5bc;p=thirdparty%2Fhaproxy.git 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. --- diff --git a/include/haproxy/bug.h b/include/haproxy/bug.h index 997a114600..84dabd9097 100644 --- a/include/haproxy/bug.h +++ b/include/haproxy/bug.h @@ -234,8 +234,8 @@ struct mem_stats { .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); \ @@ -251,8 +251,8 @@ struct mem_stats { .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); \ @@ -265,8 +265,8 @@ struct mem_stats { .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); \ } \ @@ -283,8 +283,8 @@ struct mem_stats { .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); \ @@ -297,8 +297,8 @@ struct mem_stats { .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); \ @@ -311,8 +311,8 @@ struct mem_stats { .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 3943fe6459..4859d1301c 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 0692d27d6c..dffec04d17 100644 --- a/include/haproxy/initcall.h +++ b/include/haproxy/initcall.h @@ -96,11 +96,9 @@ struct initcall { * as a pointer (args are cast to (void*)). Do not use this macro directly, * use INITCALL{0..3}() instead. */ -#define __HA_GLOBL1(sym) __asm__(".weak " #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) { \