Skip to content

Conversation

@aap-sc
Copy link

@aap-sc aap-sc commented Apr 21, 2025

To properly work with debug information, debuggers often need to unwind the stack. They generally rely on Call Frame Information (CFI) records provided by the compiler to facilitate this task. Currently, the GCC compiler offers two mechanisms:

  • .debug_frame section (as described in the DWARF specification).
  • .eh_frame sections (as described in the LSB documents).

The latter (.eh_frame) supports stack unwinding at runtime, providing a framework for C++ exceptions or enabling backtrace generation using libraries like libunwind. However, a downside of this approach is that these sections must be part of loadable segments.

The former (.debug_frame) is simply an ordinary debug section.

Starting from GCC 13, Linux targets enable the -fasynchronous-unwind-tables and -funwind-tables flags by default. Relevant commit:

https://github.com/gcc-mirror/gcc/commit/3cd08f7168

When these flags are active, the compiler generates .eh_frame sections instead of .debug_frame. Since OpenSBI is built using the Linux toolchain, this behavior applies to OpenSBI as well.

The problem arises because the SBI build system uses -Wl,--gc-sections, which discards the .eh_frame section.

Possible Fixes:

  1. Enforce .debug_frame generation – Modify compiler flags to generate .debug_frame instead of .eh_frame.
  2. Preserve .eh_frame in the linker script – Add KEEP(*(.eh_frame)) to ensure the section is not discarded.

I chose Option 1 because it avoids any runtime overhead.

To properly work with debug information, debuggers often need to unwind the
stack. They generally rely on Call Frame Information (CFI) records provided by
the compiler to facilitate this task. Currently, the GCC compiler offers two
mechanisms:

- `.debug_frame` section (as described in the DWARF specification).
- `.eh_frame` sections (as described in the LSB documents).

The latter (`.eh_frame`) supports stack unwinding at runtime, providing a
framework for C++ exceptions or enabling backtrace generation using libraries
like libunwind. However, a downside of this approach is that these sections
must be part of loadable segments.

The former (`.debug_frame`) is simply an ordinary debug section.

Starting from GCC 13, Linux targets enable the `-fasynchronous-unwind-tables`
and `-funwind-tables` flags by default. Relevant commit:
```
gcc-mirror/gcc@3cd08f7168
```
When these flags are active, the compiler generates `.eh_frame` sections
instead of `.debug_frame`. Since OpenSBI is built using the
**Linux toolchain**, this behavior applies to OpenSBI as well.

The problem arises because the SBI build system uses `-Wl,--gc-sections`, which
discards the `.eh_frame` section.

Possible Fixes:

1. Enforce `.debug_frame` generation – Modify compiler flags to generate
`.debug_frame` instead of `.eh_frame`.
2. Preserve `.eh_frame` in the linker script – Add `KEEP(*(.eh_frame))` to
ensure the section is not discarded.

I chose Option 1 because it avoids any runtime overhead.

Signed-off-by: Parshintsev Anatoly <[email protected]>
@github-actions
Copy link

We have mailing list based patch review so it would be great if you can send these patchs to OpenSBI mailing list.

You need to join OpenSBI mailing list using following link
http://lists.infradead.org/mailman/listinfo/opensbi

Make sure you use "git send-email" to send the patches.

Thanks for your contribution to OpenSBI project.

@github-actions github-actions bot closed this Apr 21, 2025
@github-actions github-actions bot locked and limited conversation to collaborators Apr 21, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant