Skip to content

Incorrect logic for emitting .eh_frame/.debug_frame entries in self-hosted ELF linker #25421

@mlugg

Description

@mlugg

The .debug_frame and .eh_frame sections are both ways to store DWARF CFI (Call Frame Information) which allows for safe virtual stack unwinding. Aside from some minor format differences, the key distinction between the two is that .eh_frame is accessible to the application and may be necessary for correctness (the typical example is C++ exceptions, which use the data in .eh_frame to unwind the call stack), while .debug_frame is considered debug information and so can typically be stripped without impacting the executable's behavior.

When using the self-hosted backend, we should emit CFI (CIEs and FDEs) for generated functions into exactly one of these two sections. The correct logic is as follows:

  • If -fno-unwind-tables was not passed, then emit entries into .eh_frame.
  • Otherwise, if debug info is not stripped (e.g. -fno-strip, or the default behavior in Debug mode), emit entries into .debug_frame.
  • Otherwise, do not emit Call Frame Information.

The backend/linker does not currently follow this logic. -f[no-]unwind-tables is ignored entirely: instead, it emits entries into .eh_frame if debug info is not stripped, and emits no entries otherwise. This is problematic because .eh_frame entries are not debug information, but a potentially necessary part of an executable.

It's likely that we don't end up solving this issue in the current ELF linker, and instead just do it in the new ELF linker (Elf2). Related: #25328

Metadata

Metadata

Assignees

No one assigned

    Labels

    backend-self-hostedbugObserved behavior contradicts documented or intended behaviorlinking

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions