[PATCH] fix missing .debug_frame DWARF section if gcc-based toolchain is used

Parshintsev Anatoly anatoly.parshintsev at syntacore.com
Mon Apr 21 05:47:29 PDT 2025


When OpenSBI is built with a relatively new compiler (gcc-13 and greater)
I observed that GDB is unable to produce proper backtraces and some
variable values appear corrupted (even if the associated DWARF
location descriptor is correct).

Turns out that 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 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, the downside of this approach is that
these sections should 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.

Signed-off-by: Parshintsev Anatoly <anatoly.parshintsev at syntacore.com>
---
 Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Makefile b/Makefile
index e90836c..85748bc 100644
--- a/Makefile
+++ b/Makefile
@@ -362,6 +362,7 @@ GENFLAGS	+=	$(firmware-genflags-y)
 
 CFLAGS		=	-g -Wall -Werror -ffreestanding -nostdlib -fno-stack-protector -fno-strict-aliasing -ffunction-sections -fdata-sections
 CFLAGS		+=	-fno-omit-frame-pointer -fno-optimize-sibling-calls
+CFLAGS		+=	-fno-asynchronous-unwind-tables -fno-unwind-tables
 # Optionally supported flags
 ifeq ($(CC_SUPPORT_VECTOR),y)
 CFLAGS		+=	-DOPENSBI_CC_SUPPORT_VECTOR
-- 
2.43.0





More information about the opensbi mailing list