[DWARFLinker] Fix DW_AT_LLVM_stmt_sequence attributes patched to wrong offsets (#178486)
This fixes a bug where `DW_AT_LLVM_stmt_sequence` attributes in dSYM
files were pointing to invalid offsets in the `.debug_line` section.
These attributes must point to `DW_LNE_set_address` opcodes (which mark
sequence starts), but after dsymutil reorders line table sequences by
address, the original row indices no longer correspond to sequence
starts in the output.
The root cause is that when sequences get reordered or merged, a row
that was originally a sequence start may end up in the middle of a
different sequence in the output. The old code was mapping the original
row index directly to its output position, but that output position
might not have a `DW_LNE_set_address` opcode anymore.
The fix builds a mapping from each output row to its containing
sequence's start row. When patching `DW_AT_LLVM_stmt_sequence`, we now:
1. Find the output row corresponding to the original row
2. Look up which sequence that output row belongs to
3. Use the sequence start's offset (where `DW_LNE_set_address` is
emitted)
This ensures all `DW_AT_LLVM_stmt_sequence` attributes point to valid
`DW_LNE_set_address` opcodes, which is required for debuggers to
correctly locate line table sequences for functions.
**Testing wise:**
Modified `stmt-seq-macho.test` to create a scenario that triggers the
bug:
- Two compilation units (a.o and b.o) with functions at different
addresses
- Linked with b.o first so b's functions get lower addresses than a's
- This forces dsymutil to reorder sequences from a.o after sequences
from b.o
- Test extracts all `DW_AT_LLVM_stmt_sequence` offsets and verifies each
one appears as a `DW_LNE_set_address` offset in the output
Results:
- Without fix: test fails (stmt_sequence offsets point to
non-set_address locations)
- With fix: test passes (all offsets are valid)