Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 5 Aug 2023 02:17:28 +0200
From:      Yuri <yuri@aetern.org>
To:        freebsd-hackers@freebsd.org
Subject:   Re: amd64-gcc12 seems to break linker sets
Message-ID:  <bb2936e1-6f33-a350-597f-1d4b3e79ef79@aetern.org>
In-Reply-To: <6a0f626c-95b4-2398-0a6d-9428c440131b@aetern.org>
References:  <6a0f626c-95b4-2398-0a6d-9428c440131b@aetern.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Yuri wrote:
> I noticed that kernel built using amd64-gcc12 panics on `kldload dtraceall`:
> 
> panic: probe defined without a provider
> cpuid = 4
> time = 1691186663
> KDB: stack backtrace:
> db_trace_self_wrapper() at db_trace_self_wrapper+0x35/frame
> 0xfffffe00c448b8a0
> vpanic() at vpanic+0x232/frame 0xfffffe00c448b950
> panic() at panic+0x3c/frame 0xfffffe00c448b9b0
> sdt_kld_load_probes() at sdt_kld_load_probes+0x346/frame 0xfffffe00c448bb70
> sdt_load_probes_cb() at sdt_load_probes_cb+0x9/frame 0xfffffe00c448bb80
> linker_file_foreach() at linker_file_foreach+0x53/frame 0xfffffe00c448bbc0
> linker_load_dependencies() at linker_load_dependencies+0xe18/frame
> 0xfffffe00c448bc70
> link_elf_load_file() at link_elf_load_file+0x10c6/frame 0xfffffe00c448bd50
> sys_kldload() at sys_kldload+0x820/frame 0xfffffe00c448bdf0
> amd64_syscall() at amd64_syscall+0x11b/frame 0xfffffe00c448bf30
> fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe00c448bf30
> --- syscall (304, FreeBSD ELF64, kldload), rip = 0x7e7e919615a, rsp =
> 0x7e7e70ef498, rbp = 0x7e7e70efa10 ---
> 
> Looking into it, gcc12 seems to discard the __start_set_... and
> __stop_set_... symbols declared in sys/linker_set.h as __WEAK(), i.e.
> __asm__(".weak ...").
> 
> The following small test shows the problem:
> ---
> int
> main(void)
> {
>         return (0);
> }
> 
> __asm__(".weak __start_set_sdt_providers_set");
> static void const * const __set_sdt_providers_set_sym_sdt_provider_tst
> __attribute__((__section__("set_" "sdt_providers_set")))
> __attribute__((__used__)) = &(main);
> __asm__(".weak __stop_set_sdt_providers_set");
> ---
> 
> When built using system clang:
> ---
> $ cc -c -o t.o t.c; nm t.o
> 0000000000000000 r __set_sdt_providers_set_sym_sdt_provider_tst
>                  w __start_set_sdt_providers_set
>                  w __stop_set_sdt_providers_set
> 0000000000000000 T main
> ---
> 
> When built using amd64-gcc12:
> ---
> $ /usr/local/bin/x86_64-unknown-freebsd14.0-gcc12 -c -o t.o t.c; nm t.o
> 0000000000000000 r __set_sdt_providers_set_sym_sdt_provider_tst
> 0000000000000000 T main
> ---
> 
> I haven't found any options to tell gcc to stop doing that; any hints?

Apparently it's any gcc version (starting with oldest available in
ports, 4.8) and it's something that was changed in:
---
commit 32231805fbe2b9438c2de50c229b43c016207a08
Author: Greg V <greg@unrelenting.technology>
Date:   Tue Apr 20 01:47:15 2021 +0100

    linker_set: fix globl/weak symbol redefinitions to work on clang 12
---

While fixing clang, it seems to broke gcc.

The following patch (reverting to previous definition for !clang) seems
to work for both clang and gcc, dtraceall kld loads successfully, dtrace
shows all defined std probes:

diff --git a/sys/sys/cdefs.h b/sys/sys/cdefs.h
index 1de042339c3..e1d3cf636dd 100644
--- a/sys/sys/cdefs.h
+++ b/sys/sys/cdefs.h
@@ -562,7 +562,11 @@
 #endif /* __GNUC__ */

 #define        __GLOBL(sym)    __asm__(".globl " __XSTRING(sym))
+#ifdef __clang__
 #define        __WEAK(sym)     __asm__(".weak " __XSTRING(sym))
+#else
+#define        __WEAK(sym)     __GLOBL(sym)
+#endif

 #if defined(__GNUC__)
 #define        __IDSTRING(name,string) __asm__(".ident\t\"" string "\"")



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bb2936e1-6f33-a350-597f-1d4b3e79ef79>