Page MenuHomeFreeBSD

cdefs.h: unbreak linker sets for gcc
Needs ReviewPublic

Authored by yuripv on Aug 5 2023, 12:42 AM.
Tags
None
Referenced Files
Unknown Object (File)
Mon, Jan 27, 1:35 AM
Unknown Object (File)
Nov 1 2024, 12:54 AM
Unknown Object (File)
Sep 28 2024, 9:12 PM
Unknown Object (File)
Sep 27 2024, 10:29 AM
Unknown Object (File)
Sep 27 2024, 10:24 AM
Unknown Object (File)
Sep 23 2024, 9:32 AM
Unknown Object (File)
Sep 22 2024, 11:11 PM
Unknown Object (File)
Sep 18 2024, 6:48 PM

Details

Reviewers
jrtc27
Summary

Revert to previous definition for !clang.

Fixes: 32231805fbe ("linker_set: fix globl/weak symbol redefinitions")

Test Plan

Build kernel with system clang and amd64-gcc12
kldload dtraceall
dtrace -l -P sdt

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

This is unlikely to be a compiler issue but an assembler difference. This is also a highly suspicious change. This is probably masking some other bug. I do not think it should go in the tree as-is without a root cause analysis.

Ok, I think I understand what's going on here. Does https://termbin.com/895q resolve the issue instead for you? That's what we're actually trying to do here, I think.

Ok, I think I understand what's going on here. Does https://termbin.com/895q resolve the issue instead for you? That's what we're actually trying to do here, I think.

The following part from your patch is enough to unbreak gcc and is exactly what the patch here does:

--- a/sys/sys/linker_set.h
+++ b/sys/sys/linker_set.h
@@ -66,8 +66,8 @@
 #endif
 
 #define __MAKE_SET_QV(set, sym, qv)			\
-	__WEAK(__CONCAT(__start_set_,set));		\
-	__WEAK(__CONCAT(__stop_set_,set));		\
+	__GLOBL(__CONCAT(__start_set_,set));		\
+	__GLOBL(__CONCAT(__stop_set_,set));		\
 	static void const * qv				\
 	__NOASAN					\
 	__set_##set##_sym_##sym __section("set_" #set)	\

Ok, I think I understand what's going on here. Does https://termbin.com/895q resolve the issue instead for you? That's what we're actually trying to do here, I think.

Seems to compile for clang, breaks for gcc:

/usr/local/bin/x86_64-unknown-freebsd14.0-gcc12  -O2 -pipe -fno-common  -fno-strict-aliasing -Werror -D_KERNEL -DKLD_MODULE -nostdinc   -include /usr/obj/usr/src/amd64.amd64/sys/modules/cam/opt_global.h -I. -I/usr/src/sys -I/usr/src/sys/contrib/ck/include -fno-common  -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fdebug-prefix-map=./machine=/usr/src/sys/amd64/include -fdebug-prefix-map=./x86=/usr/src/sys/x86/include -fdebug-prefix-map=./i386=/usr/src/sys/i386/include     -MD  -MF.depend.cam_xpt.o -MTcam_xpt.o -mcmodel=kernel -mno-red-zone -mno-mmx -mno-sse -msoft-float  -fno-asynchronous-unwind-tables -ffreestanding -fwrapv -fstack-protector -Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wcast-qual -Wundef -Wno-pointer-sign -D__printf__=__freebsd_kprintf__ -Wmissing-include-dirs -fdiagnostics-show-option -Wno-unknown-pragmas -Wno-error=address -Wno-error=aggressive-loop-optimizations -Wno-error=array-bounds -Wno-error=attributes -Wno-error=cast-qual -Wno-error=enum-compare -Wno-error=maybe-uninitialized -Wno-error=misleading-indentation -Wno-error=nonnull-compare -Wno-error=overflow -Wno-error=sequence-point -Wno-error=shift-overflow -Wno-error=tautological-compare -Wno-error=unused-function -Wno-error=stringop-overflow -Wno-error=memset-elt-size -Wno-error=packed-not-aligned -Wno-address-of-packed-member -Wno-error=alloca-larger-than= -Wno-error=nonnull -Wno-dangling-pointer -Wno-zero-length-bounds -Wno-return-type -Wno-format-zero-length   -finline-limit=8000 -fms-extensions --param inline-unit-growth=100 --param large-function-growth=1000  -std=gnu99 -c /usr/src/sys/cam/cam_xpt.c -o cam_xpt.o
...
{standard input}: Assembler messages:                                                                                   {standard input}:1056: Error: junk `__weak_start_setcam_xpt_proto_set' after expression
{standard input}:1056: Error: number of operands mismatch for `cmp'
{standard input}:1063: Error: junk `__weak_start_setcam_xpt_proto_set' after expression
{standard input}:1063: Error: number of operands mismatch for `cmp'
{standard input}:2345: Error: junk `__weak_start_setcam_xpt_proto_set' after expression
{standard input}:2345: Error: number of operands mismatch for `cmp'
{standard input}:2352: Error: junk `__weak_start_setcam_xpt_proto_set' after expression
{standard input}:2352: Error: number of operands mismatch for `cmp'
{standard input}:2476: Error: junk `__weak_start_setcam_xpt_proto_set' after expression                                 {standard input}:2476: Error: number of operands mismatch for `cmp'
{standard input}:2483: Error: junk `__weak_start_setcam_xpt_proto_set' after expression
{standard input}:2483: Error: number of operands mismatch for `cmp'
{standard input}:2732: Error: junk `__weak_start_setcam_xpt_proto_set' after expression
{standard input}:2732: Error: number of operands mismatch for `cmp'
{standard input}:2739: Error: junk `__weak_start_setcam_xpt_proto_set' after expression
{standard input}:2739: Error: number of operands mismatch for `cmp'
{standard input}:2830: Error: junk `__weak_start_setcam_xpt_proto_set' after expression
{standard input}:2830: Error: number of operands mismatch for `cmp'
{standard input}:2837: Error: junk `__weak_start_setcam_xpt_proto_set' after expression
{standard input}:2837: Error: number of operands mismatch for `cmp'
...

Ok, I think I understand what's going on here. Does https://termbin.com/895q resolve the issue instead for you? That's what we're actually trying to do here, I think.

The following part from your patch is enough to unbreak gcc and is exactly what the patch here does:

--- a/sys/sys/linker_set.h
+++ b/sys/sys/linker_set.h
@@ -66,8 +66,8 @@
 #endif
 
 #define __MAKE_SET_QV(set, sym, qv)			\
-	__WEAK(__CONCAT(__start_set_,set));		\
-	__WEAK(__CONCAT(__stop_set_,set));		\
+	__GLOBL(__CONCAT(__start_set_,set));		\
+	__GLOBL(__CONCAT(__stop_set_,set));		\
 	static void const * qv				\
 	__NOASAN					\
 	__set_##set##_sym_##sym __section("set_" #set)	\

I know, but it's bogus to mix things like this. There's a lot of detail in all this that you're glossing over by just doing that. You need the rest to make it less fragile in corner cases, and of course to make it work for both LLVM's assembler and binutil's.

Ok, I think I understand what's going on here. Does https://termbin.com/895q resolve the issue instead for you? That's what we're actually trying to do here, I think.

Seems to compile for clang, breaks for gcc:

/usr/local/bin/x86_64-unknown-freebsd14.0-gcc12  -O2 -pipe -fno-common  -fno-strict-aliasing -Werror -D_KERNEL -DKLD_MODULE -nostdinc   -include /usr/obj/usr/src/amd64.amd64/sys/modules/cam/opt_global.h -I. -I/usr/src/sys -I/usr/src/sys/contrib/ck/include -fno-common  -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -fdebug-prefix-map=./machine=/usr/src/sys/amd64/include -fdebug-prefix-map=./x86=/usr/src/sys/x86/include -fdebug-prefix-map=./i386=/usr/src/sys/i386/include     -MD  -MF.depend.cam_xpt.o -MTcam_xpt.o -mcmodel=kernel -mno-red-zone -mno-mmx -mno-sse -msoft-float  -fno-asynchronous-unwind-tables -ffreestanding -fwrapv -fstack-protector -Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wcast-qual -Wundef -Wno-pointer-sign -D__printf__=__freebsd_kprintf__ -Wmissing-include-dirs -fdiagnostics-show-option -Wno-unknown-pragmas -Wno-error=address -Wno-error=aggressive-loop-optimizations -Wno-error=array-bounds -Wno-error=attributes -Wno-error=cast-qual -Wno-error=enum-compare -Wno-error=maybe-uninitialized -Wno-error=misleading-indentation -Wno-error=nonnull-compare -Wno-error=overflow -Wno-error=sequence-point -Wno-error=shift-overflow -Wno-error=tautological-compare -Wno-error=unused-function -Wno-error=stringop-overflow -Wno-error=memset-elt-size -Wno-error=packed-not-aligned -Wno-address-of-packed-member -Wno-error=alloca-larger-than= -Wno-error=nonnull -Wno-dangling-pointer -Wno-zero-length-bounds -Wno-return-type -Wno-format-zero-length   -finline-limit=8000 -fms-extensions --param inline-unit-growth=100 --param large-function-growth=1000  -std=gnu99 -c /usr/src/sys/cam/cam_xpt.c -o cam_xpt.o
...
{standard input}: Assembler messages:                                                                                   {standard input}:1056: Error: junk `__weak_start_setcam_xpt_proto_set' after expression
{standard input}:1056: Error: number of operands mismatch for `cmp'
{standard input}:1063: Error: junk `__weak_start_setcam_xpt_proto_set' after expression
{standard input}:1063: Error: number of operands mismatch for `cmp'
{standard input}:2345: Error: junk `__weak_start_setcam_xpt_proto_set' after expression
{standard input}:2345: Error: number of operands mismatch for `cmp'
{standard input}:2352: Error: junk `__weak_start_setcam_xpt_proto_set' after expression
{standard input}:2352: Error: number of operands mismatch for `cmp'
{standard input}:2476: Error: junk `__weak_start_setcam_xpt_proto_set' after expression                                 {standard input}:2476: Error: number of operands mismatch for `cmp'
{standard input}:2483: Error: junk `__weak_start_setcam_xpt_proto_set' after expression
{standard input}:2483: Error: number of operands mismatch for `cmp'
{standard input}:2732: Error: junk `__weak_start_setcam_xpt_proto_set' after expression
{standard input}:2732: Error: number of operands mismatch for `cmp'
{standard input}:2739: Error: junk `__weak_start_setcam_xpt_proto_set' after expression
{standard input}:2739: Error: number of operands mismatch for `cmp'
{standard input}:2830: Error: junk `__weak_start_setcam_xpt_proto_set' after expression
{standard input}:2830: Error: number of operands mismatch for `cmp'
{standard input}:2837: Error: junk `__weak_start_setcam_xpt_proto_set' after expression
{standard input}:2837: Error: number of operands mismatch for `cmp'
...

Yep I missed a semicolon, which led to very weird failures (but less explosive; I don't even want to think about how it was getting parsed) for an LLVM-based tinderbox. Hopefully https://termbin.com/t7iu is better, but I haven't finished tinderboxing it yet (earlier patches were totally untested until not long ago...).

Ok, I think I understand what's going on here. Does https://termbin.com/895q resolve the issue instead for you? That's what we're actually trying to do here, I think.

The following part from your patch is enough to unbreak gcc and is exactly what the patch here does:

--- a/sys/sys/linker_set.h
+++ b/sys/sys/linker_set.h
@@ -66,8 +66,8 @@
 #endif
 
 #define __MAKE_SET_QV(set, sym, qv)			\
-	__WEAK(__CONCAT(__start_set_,set));		\
-	__WEAK(__CONCAT(__stop_set_,set));		\
+	__GLOBL(__CONCAT(__start_set_,set));		\
+	__GLOBL(__CONCAT(__stop_set_,set));		\
 	static void const * qv				\
 	__NOASAN					\
 	__set_##set##_sym_##sym __section("set_" #set)	\

I know, but it's bogus to mix things like this. There's a lot of detail in all this that you're glossing over by just doing that. You need the rest to make it less fragile in corner cases, and of course to make it work for both LLVM's assembler and binutil's.

Got it, thanks Jessica!

[...]

Yep I missed a semicolon, which led to very weird failures (but less explosive; I don't even want to think about how it was getting parsed) for an LLVM-based tinderbox. Hopefully https://termbin.com/t7iu is better, but I haven't finished tinderboxing it yet (earlier patches were totally untested until not long ago...).

clang:

--- kernel.full ---
linking kernel.full
ld: error: undefined symbol: __stop_set_uart_acpi_class_set
>>> referenced by uart_cpu_acpi.c:64 (/usr/src/sys/dev/uart/uart_cpu_acpi.c:64)
>>>               uart_cpu_acpi.o:(uart_cpu_acpi_spcr)

ld: error: undefined symbol: __start_set_uart_acpi_class_set
>>> referenced by uart_cpu_acpi.c:64 (/usr/src/sys/dev/uart/uart_cpu_acpi.c:64)
>>>               uart_cpu_acpi.o:(uart_cpu_acpi_spcr)
*** [kernel.full] Error code 1

gcc:

--- all_subdir_linux ---
--- linux_elf32.o ---
{standard input}: Assembler messages:
{standard input}:19: Error: symbol `__weak_start_set_elf32_regset' is already defined
{standard input}:20: Error: symbol `__weak_stop_set_elf32_regset' is already defined
*** [linux_elf32.o] Error code 1