[PATCH] D150004: [RISCV] .debug_line: emit relocations for assembly input files
Fangrui Song via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri May 5 15:29:11 PDT 2023
MaskRay created this revision.
MaskRay added reviewers: asb, compnerd, craig.topper, enh, hiraditya, kito-cheng, jrtc27.
Herald added subscribers: jobnoorman, luke, VincentWu, vkmr, frasercrmck, evandro, luismarques, apazos, sameer.abuasal, pengfei, s.egerton, Jim, benna, psnobl, jocewei, PkmX, the_o, brucehoult, MartinMosbeck, rogfer01, edward-jones, zzheng, shiva0217, niosHD, sabuasal, simoncook, johnrusso, rbar, arichardson, emaste.
Herald added a project: All.
MaskRay requested review of this revision.
Herald added subscribers: llvm-commits, pcwang-thead, eopXD.
Herald added a project: LLVM.
Fix https://github.com/llvm/llvm-project/issues/62535
When assembling `.debug_line` for both explicitly specified and synthesized
`.loc` directives. the integrated assembler may incorrectly omit relocations for
-mrelax.
For an assembly file, we have a `MCAssembler` object and `evaluateAsAbsolute`
will incorrectly fold `AddrDelta` to a constant (which is not true in the
presence of linker relaxation).
`MCDwarfLineAddr::Emit` will emit a special opcode, which does not take into
account of linker relaxation.
The following script demonstrates the bugs.
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 -q
# 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 -q; 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 -q; test $? -eq 1
The `MCDwarfLineAddr::Emit` code path is an old optimization before
commit 57ab708bdd3231b23a8ef4978b11ff07616034a2 (2010) that seems no longer
relevant. It usually don't trigger for non-assembly input files (no
`MCAssembler`). Let's remove it.
Assembling the assembly output of X86ISelLowering.cpp with `-g` may be
1% slower, but I think the cost is fine.
For -mno-relax, in theory we can prefer special opcodes to
DW_LNS_fixed_advance_pc to decrease the size of .debug_line, but such a change
may be overkill and unnecessarily diverge from -mrelax behaviors and GCC.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D150004
Files:
llvm/lib/MC/MCObjectStreamer.cpp
llvm/test/MC/ELF/RISCV/debug-line.s
llvm/test/MC/ELF/RISCV/lit.local.cfg
Index: llvm/test/MC/ELF/RISCV/lit.local.cfg
===================================================================
--- /dev/null
+++ llvm/test/MC/ELF/RISCV/lit.local.cfg
@@ -0,0 +1,2 @@
+if 'RISCV' not in config.root.targets:
+ config.unsupported = True
Index: llvm/test/MC/ELF/RISCV/debug-line.s
===================================================================
--- /dev/null
+++ llvm/test/MC/ELF/RISCV/debug-line.s
@@ -0,0 +1,37 @@
+## When assembling an assembly file with linker relaxation, emit DW_LNS_fixed_advance_pc
+## with ADD16/SUB16 relocations so that .debug_line can be fixed by the linker.
+## Without linker relaxation, we can emit special opcodes to make .debug_line smaller.
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -g -mattr=-relax < %s -o %t.norelax
+# RUN: llvm-dwarfdump -debug-line -v %t.norelax | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -g -mattr=+relax < %s -o %t.relax
+# RUN: llvm-dwarfdump -debug-line -v %t.relax | FileCheck %s
+# RUN: llvm-readobj -r %t.relax | FileCheck %s --check-prefix=RELOC
+
+call foo
+call foo
+call foo
+
+# CHECK: DW_LNE_set_address
+# CHECK-NEXT: DW_LNS_advance_line ([[#]])
+# CHECK-NEXT: DW_LNS_copy
+# CHECK-NEXT: is_stmt
+# CHECK-NEXT: DW_LNS_advance_line
+# CHECK-NEXT: DW_LNS_fixed_advance_pc (0x0008)
+# CHECK-NEXT: DW_LNS_copy
+# CHECK-NEXT: is_stmt
+# CHECK-NEXT: DW_LNS_advance_line
+# CHECK-NEXT: DW_LNS_fixed_advance_pc (0x0008)
+# CHECK-NEXT: DW_LNS_copy
+# CHECK-NEXT: is_stmt
+# CHECK-NEXT: DW_LNS_fixed_advance_pc (0x0008)
+# CHECK-NEXT: DW_LNE_end_sequence
+
+# RELOC: Section ([[#]]) .rela.debug_line {
+# RELOC-NEXT: 0x2C R_RISCV_64 - 0x0
+# RELOC-NEXT: 0x3A R_RISCV_ADD16 - 0x0
+# RELOC-NEXT: 0x3A R_RISCV_SUB16 - 0x0
+# RELOC-NEXT: 0x40 R_RISCV_ADD16 - 0x0
+# RELOC-NEXT: 0x40 R_RISCV_SUB16 - 0x0
+# RELOC-NEXT: 0x44 R_RISCV_ADD16 - 0x0
+# RELOC-NEXT: 0x44 R_RISCV_SUB16 - 0x0
+# RELOC-NEXT: }
Index: llvm/lib/MC/MCObjectStreamer.cpp
===================================================================
--- llvm/lib/MC/MCObjectStreamer.cpp
+++ llvm/lib/MC/MCObjectStreamer.cpp
@@ -541,12 +541,6 @@
return;
}
const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
- int64_t Res;
- if (AddrDelta->evaluateAsAbsolute(Res, getAssemblerPtr())) {
- MCDwarfLineAddr::Emit(this, Assembler->getDWARFLinetableParams(), LineDelta,
- Res);
- return;
- }
insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D150004.519993.patch
Type: text/x-patch
Size: 2571 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230505/28045b1f/attachment.bin>
More information about the llvm-commits
mailing list