Page MenuHomeFreeBSD

amd64/*sigtramp.S: re-enable some cfi annotations for special registers
ClosedPublic

Authored by kib on Sat, Sep 19, 10:09 AM.
Tags
None
Referenced Files
F173733724: D59838.diff
Mon, Sep 28, 12:45 AM
F173701832: D59838.diff
Sun, Sep 27, 8:10 PM
Unknown Object (File)
Sun, Sep 27, 7:27 AM
Unknown Object (File)
Sun, Sep 27, 5:38 AM
Unknown Object (File)
Sat, Sep 26, 11:27 PM
Unknown Object (File)
Sat, Sep 26, 11:18 PM
Unknown Object (File)
Sat, Sep 26, 6:44 PM
Unknown Object (File)
Sat, Sep 26, 5:11 PM
Subscribers

Details

Summary
Also explicitly specify .cfi_sections to emit the cfi bytecode into the
loadable .eh_frame section.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

kib requested review of this revision.Sat, Sep 19, 10:09 AM

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,"",@progbits

and 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)

From the list of supported compiler versions for main, gcc12 worked so I assume gcc versions above that also work.

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 -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)

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.

In D59838#1373575, @kib wrote:

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)

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.

Wrap changes with the version check.

Move the historical complaint up to the WORKING_CFI definition.

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
mchoo added inline comments.
sys/amd64/ia32/ia32_sigtramp.S
53–57

Huh, interesting....

This revision is now accepted and ready to land.Sun, Sep 20, 2:45 PM
In D59838#1373575, @kib wrote:

...

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.