启动代码置于.text子段后GDB调试符号丢失的解决问询
解决RISC-V Bootloader中.isr_vector段调试符号丢失问题
问题根源
在汇编代码中使用.section .isr_vector但未指定段属性时,GNU汇编器(GAS)默认不会为该段生成完整的调试关联信息,即便编译时添加了-g -O0参数,GDB也无法将行号与该段的代码对应,最终导致调试符号丢失。
解决方案
方法1:为.isr_vector段显式指定段属性
修改汇编代码中的.section指令,添加**可分配(a)、可执行(x)**属性,并标记为程序代码段(@progbits),确保汇编器为该段生成正确的调试元数据。
修改后的startup.s:
.align 2 // 显式指定段属性:可分配、可执行,属于程序代码段 .section .isr_vector,"ax",@progbits .globl _start .globl puts _start: csrr t0, mhartid bnez t0, halt la sp, stack_top j main halt: wfi
方法2:优化链接脚本的调试段处理
原链接脚本中手动指定.debug : { *(.debug) }的逻辑会干扰链接器自动处理调试段的流程,建议移除该行,让链接器默认保留所有调试段。修改后的linker.ld核心部分:
OUTPUT_ARCH( "riscv" ) OUTPUT_FORMAT("elf32-littleriscv") ENTRY(_start) SECTIONS { /* text: test code section */ . = 0x20400000; .text : { _text = .; KEEP(*(.isr_vector)) *(.text) *(.rodata) _etext = .; } /* gnu_build_id: readonly build identifier */ .gnu_build_id : { *(.note.gnu.build-id) } /* data: Initialized data segment */ . = 0x80000000; .data : { _data = .; *(.data) _edata = .; } .sdata : { *(.sdata) } . += 0x1000; stack_top = .; /* End of uninitalized data segement */ _end = .; }
验证步骤
- 重新编译项目:
mkdir build && cd build cmake .. make
- 用GDB加载ELF文件测试断点:
riscv64-unknown-elf-gdb bootloader-test.elf (gdb) b startup.s:10 // 行号对应_start所在代码行 (gdb) run
此时GDB应能正确识别行号并设置断点。
3. 可选:用readelf验证段属性:
riscv64-unknown-elf-readelf -S bootloader-test.elf | grep isr_vector
输出需包含AX(可分配、可执行)属性,确认段属性配置正确。
内容的提问来源于stack exchange,提问作者Martel
相关产品推荐
相关产品推荐

