-
Notifications
You must be signed in to change notification settings - Fork 14.8k
Description
The GNU assembler and LLVM integrated assembler both create a .debug_line
section for assembly files that have .file
and .loc
directives.
When -g
is specified for assembly files without these directives, debug information is synthesized, including line number information.
However, the LLVM integrated assembler has a bug that creates issues for -mrelax
with .debug_line
for both explicitly specified and synthesized .loc
directives.
This is due to MCDwarfLineTable::emitOne
calling MCObjectStreamer::emitDwarfAdvanceLineAddr
to emit line table opcodes for a section.
For an assembly file, createRISCVELFStreamer
is used to create a MCObjectStreamer
instance with a MCAssembler
object.
For a C/C++ file, createRISCVObjectTargetStreamer
is used to create a MCObjectStreamer
instance without a MCAssembler
object.
When a MCAssembler
object is used, label differences in the line number information are incorrectly foldable.
The LLVM integrated assembler will emit special opcodes that hard code instruction offsets, which can become incorrect when the instruction offset changes due to linker relaxation.
#!/bin/sh -e
cat > x.c <<eof
void f();
void _start() {
f();
f();
f();
}
eof
# C to object file: correct DW_LNS_fixed_advance_pc
clang --target=riscv64 -g -c x.c
llvm-dwarfdump --debug-line -v x.o | grep \ DW_LNS_fixed_advance_pc
# Assembly to object file with synthesized line number information: incorrect special opcodes
clang --target=riscv64 -S x.c && clang --target=riscv64 -g -c x.s
llvm-dwarfdump --debug-line -v x.o | grep \ DW_LNS_fixed_advance_pc; test $? -eq 1
# Assembly with .loc to object file: incorrect special opcodes
clang --target=riscv64 -S -g x.c && clang --target=riscv64 -c x.s
llvm-dwarfdump --debug-line -v x.o | grep \ DW_LNS_fixed_advance_pc; test $? -eq 1
Using -S
and -c
on one source file is not commonly used to build projects.
However, clang --target=riscv64 -g -c x.s
is somewhat common. My suggestion is to remove -g
for now.
Synthesized debug information is not very useful anyway.
This can be worked around in several places, but that would further complicate the brittle part. I'd like to take some time figuring out the logic and coming up with a patch.