Also explicitly specify .cfi_sections to emit the cfi bytecode into the loadable .eh_frame section.
Details
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Not Applicable - Unit
Tests Not Applicable
Event Timeline
I tested
.text
.globl cfi_segments
.type cfi_segments, @function
cfi_segments:
.cfi_startproc simple
.cfi_def_cfa %rsp, 72
.cfi_offset %cs, -64
.cfi_offset %rflags, -56
.cfi_offset %ss, -48
.cfi_offset %es, -40
.cfi_offset %ds, -32
.cfi_offset %fs, -24
.cfi_offset %gs, -16
ret
.cfi_endproc
.size cfi_segments, . - cfi_segments
.section .note.GNU-stack,"",@progbitsand used llvm-dwarfdump --eh-frame to see if compilers can interprets these registers correctly.
From the list of supported compiler versions for main, gcc12 worked so I assume gcc versions above that also work. clang 18 and 19 worked but clang15 cannot recognize any of cs, ss, rflags, es, ds, fs, and gs:
00000014 00000040 00000018 FDE cie=00000000 pc=00000000...00000001 Format: DWARF32 DW_CFA_def_cfa: RSP +72 DW_CFA_offset_extended: reg4294967295 -64 DW_CFA_offset: RFLAGS -56 DW_CFA_offset_extended: reg4294967295 -48 DW_CFA_offset_extended: reg4294967295 -40 DW_CFA_offset_extended: reg4294967295 -32 DW_CFA_offset_extended: reg4294967295 -24 DW_CFA_offset_extended: reg4294967295 -16
I tested llvm 16 and 17 as well and only 17 compiles correctly, so I think we still need a if guard but replace it with #if !defined(__clang__) || (__clang_major__ >= 17)
gcc itself is irrelevant, it is binutils. Since I suspect you used the same binutils for all versions of gcc on your machine, it is not surprising.
clang 18 and 19 worked but clang15 cannot recognize any of cs, ss, rflags, es, ds, fs, and gs:
00000014 00000040 00000018 FDE cie=00000000 pc=00000000...00000001 Format: DWARF32 DW_CFA_def_cfa: RSP +72 DW_CFA_offset_extended: reg4294967295 -64 DW_CFA_offset: RFLAGS -56 DW_CFA_offset_extended: reg4294967295 -48 DW_CFA_offset_extended: reg4294967295 -40 DW_CFA_offset_extended: reg4294967295 -32 DW_CFA_offset_extended: reg4294967295 -24 DW_CFA_offset_extended: reg4294967295 -16I tested llvm 16 and 17 as well and only 17 compiles correctly, so I think we still need a if guard but replace it with #if !defined(__clang__) || (__clang_major__ >= 17)
This is unfortunate. But do we need to care about so old llvms? llvm15 sounds esp. odd, I suspect that the web page is quite outdated.
From what I see in Github workflows, we use clang15 for Ubuntu 22.04 cross compilation, so this will break CI without retiring clang15 workflow beforehand. I think we should ask srcmgr@ to approve removing llvm15 support first.
| sys/amd64/ia32/ia32_sigtramp.S | ||
|---|---|---|
| 53–57 | fs, gs, es, ds were guarded under #ifdef __clang__ but why aren't they guarded here? I tested fs.base and gs.base on gas, all those registers compiles and emits corret .eh_frame: DW_CFA_def_cfa: RSP +88 DW_CFA_offset: CS -80 DW_CFA_offset: RFLAGS -72 DW_CFA_offset: SS -64 DW_CFA_offset: ES -56 DW_CFA_offset: DS -48 DW_CFA_offset: FS -40 DW_CFA_offset: GS -32 DW_CFA_offset: FS_BASE -24 DW_CFA_offset: GS_BASE -16 DW_CFA_nop: DW_CFA_nop: CFA=RSP+88: RFLAGS=[CFA-72], ES=[CFA-56], CS=[CFA-80], SS=[CFA-64], DS=[CFA-48], FS=[CFA-40], GS=[CFA-32], FS_BASE=[CFA-24], GS_BASE=[CFA-16] | |
| sys/amd64/ia32/ia32_sigtramp.S | ||
|---|---|---|
| 53–57 | The segments on m32 work for me for gas from ports 2.44 and for locally compiled binutils 2.47, so I removed the #ifdef. But gas 2.47 locally compiled complains about %{f,g}s.base: /tmp//ccbP3VDG.s: Assembler messages: /usr/home/kostik/work/DEV/src/sys/amd64/ia32/ia32_sigtramp.S:74: Error: bad register expression /usr/home/kostik/work/DEV/src/sys/amd64/ia32/ia32_sigtramp.S:75: Error: bad register expression Amusingly, gas from ports (2.44) does not. | |
BTW, you might find it convenient. I use the following script to compile vdso asm using different toolchains. This is why tools/vdso*.sh are so heavily parametrized:
#!/usr/local/bin/bash # $Id: vdso.sh,v 1.2 2026/09/19 10:21:14 kostik Exp kostik $ set -e KERNCONF=X opt=/usr/local/opt gcc=${opt}/gcc-16.2.0 llvmver=23 binutils=${opt}/binutils local=/usr/local/bin export ELFDUMP=/usr/bin/elfdump export AWK=/usr/bin/awk export S=/usr/home/kostik/work/DEV/src/sys cd sys/amd64/compile/${KERNCONF} echo "${gcc}" export CC=${gcc}/bin/gcc export AS=${binutils}/bin/as export LD=${binutils}/bin/ld export NM=${binutils}/bin/nm sh ${S}/tools/amd64_vdso.sh sh ${S}/tools/amd64_ia32_vdso.sh echo "local/gcc" export CC=${local}/gcc export AS=${local}/as export LD=${local}/ld export NM=${local}/nm sh ${S}/tools/amd64_vdso.sh sh ${S}/tools/amd64_ia32_vdso.sh echo "base cc" export CC=/usr/bin/cc export AS=/usr/bin/cc export LD=/usr/bin/ld.lld export NM=/usr/bin/nm sh ${S}/tools/amd64_vdso.sh sh ${S}/tools/amd64_ia32_vdso.sh echo "local llvm${llvmver}" export CC=/usr/local/llvm${llvmver}/bin/clang export AS=/usr/local/llvm${llvmver}/bin/clang export LD=/usr/local/llvm${llvmver}/bin/ld.lld sh ${S}/tools/amd64_vdso.sh sh ${S}/tools/amd64_ia32_vdso.sh
| sys/amd64/ia32/ia32_sigtramp.S | ||
|---|---|---|
| 53–57 | Huh, interesting.... | |
...
This is unfortunate. But do we need to care about so old llvms? llvm15 sounds esp. odd, I suspect that the web page is quite outdated.
From what I see in Github workflows, we use clang15 for Ubuntu 22.04 cross compilation, so this will break CI without retiring clang15 workflow beforehand. I think we should ask srcmgr@ to approve removing llvm15 support first.
Hm, maybe we should upgrade those GitHub versions at some point? FreeBSD 13.5 (which is now EOL but would be an upgrade path for old machines to 14 and later) already has clang 19.