Bug 29749

Summary: clarify usage of .cfi_label in riscv start.S
Product: glibc Reporter: Alex Fan <alex.fan.q>
Component: libcAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: drepper.fsp, i, jsm-csl, schwab
Priority: P2    
Version: unspecified   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:

Description Alex Fan 2022-11-04 11:20:58 UTC
riscv's start.S includes a `.cfi_label dummy` directive in [1]. The comment above it says 
> use a dummy .cfi_label to force starting the FDE.`
but as I understand it, `ENTRY (ENTRY_POINT)` macro includes a `.cfi_startproc`, which should already do the same thing as comment suggests.

This directive was introduced in https://sourceware.org/bugzilla/show_bug.cgi?id=23125 , but the original patch in the first comment didn't include cfi_label and works as reported.

Zig compilation gets stuck on this directive as clang doesn't support it [2].

Can I get some help to clarify this directive and whether it is okay to remove it?

[1] https://github.com/bminor/glibc/blob/8c77e26ba8b360c851b2b9485bb4431aacc51ad1/sysdeps/riscv/start.S#L48
[2] https://github.com/ziglang/zig/issues/3340
Comment 1 Alex Fan 2022-11-04 11:23:43 UTC
btw, this issue originally opened at https://github.com/riscv-collab/riscv-gnu-toolchain/issues/1149 and I was suggested to report it here.
Comment 2 Andreas Schwab 2022-11-08 15:38:19 UTC
.cfi_startproc does *not* start the FDE.  Without .cfi_label, the DW_CFA_undefined directive is part of the CIE.

$ readelf -wf csu/start.o
Contents of the .eh_frame section:


00000000 0000000000000014 00000000 CIE
  Version:               3
  Augmentation:          "zR"
  Code alignment factor: 1
  Data alignment factor: -4
  Return address column: 1
  Augmentation data:     1b
  DW_CFA_def_cfa_register: r2 (sp)
  DW_CFA_undefined: r1 (ra)
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop

00000018 0000000000000014 0000001c FDE cie=00000000 pc=0000000000000002..000000000000002c
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop
Comment 3 Alex Fan 2022-11-11 13:16:06 UTC
(In reply to Andreas Schwab from comment #2)
> .cfi_startproc does *not* start the FDE.  Without .cfi_label, the
> DW_CFA_undefined directive is part of the CIE.

I find llvm assembler puts it into fde without needing .cfi_label. Is cfi_startproc meant to mark start of a function frame and fde is per function?

rv64d-dev0 /tmp # llvm-mc --filetype=obj -o=test.o test.s 
rv64d-dev0 /tmp # objdump --dwarf test.o

test.o:     file format elf64-littleriscv

Contents of the .eh_frame section:


00000000 0000000000000010 00000000 CIE
  Version:               1
  Augmentation:          "zR"
  Code alignment factor: 1
  Data alignment factor: -8
  Return address column: 1
  Augmentation data:     1b
  DW_CFA_def_cfa: r2 (sp) ofs 0

00000014 0000000000000010 00000018 FDE cie=00000000 pc=000000000000001c..0000000000000020
  DW_CFA_undefined: r1 (ra)
  DW_CFA_nop
Comment 4 Fangrui Song 2024-07-06 23:28:35 UTC
I created https://github.com/llvm/llvm-project/pull/97922 to support .cfi_label in the LLVM integrated assembler, which will hopefully make it into the upcoming LLVM 19 release.

I believe .cfi_label .Ldummy isn't strictly necessary, since DW_CFA_undefined being part of a CIE should be fine. However, .cfi_label .Ldummy placing the following DW_CFA_undefined into a FDE can usually decrease the number of CIEs as a minor size optimization.