Discussion:
amd64-gcc12 seems to break linker sets
(too old to reply)
Yuri
2023-08-04 22:48:28 UTC
Permalink
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?


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Yuri
2023-08-05 00:17:28 UTC
Permalink
Post by Yuri
panic: probe defined without a provider
cpuid = 4
time = 1691186663
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 ...").
---
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");
---
---
$ 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
---
---
$ /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 <***@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 "\"")


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Yuri
2023-08-05 00:42:46 UTC
Permalink
Post by Yuri
Post by Yuri
panic: probe defined without a provider
cpuid = 4
time = 1691186663
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 ...").
---
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");
---
---
$ 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
---
---
$ /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
---
commit 32231805fbe2b9438c2de50c229b43c016207a08
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
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 "\"")
https://reviews.freebsd.org/D41329


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Loading...