]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/ld: fix off-by-one error in DWARF .debug_line transcription
authorJosh Bleecher Snyder <josharian@gmail.com>
Thu, 20 Feb 2014 17:06:32 +0000 (09:06 -0800)
committerJosh Bleecher Snyder <josharian@gmail.com>
Thu, 20 Feb 2014 17:06:32 +0000 (09:06 -0800)
The liblink refactor changed the DWARF .debug_line flow control. The mapping was off by one pcline entry. The fix here preserves pc until it can be compared to pcline.pc.

Sample dwarfdump .debug_line output for main.main from the program in issue 7351, before liblink (correct):

0x0000003c: 00 Extended: <9> 02 DW_LNE_set_address( 0x0000000000002000 )
0x00000047: 03 DW_LNS_advance_line( 6 )
0x00000049: 01 DW_LNS_copy
            0x0000000000002000      1      7      0 is_stmt

0x0000004a: 8b address += 21,  line += 1
            0x0000000000002021      1      8      0 is_stmt

0x0000004b: 02 DW_LNS_advance_pc( 153 )
0x0000004e: 03 DW_LNS_advance_line( 1 )
0x00000050: 01 DW_LNS_copy
            0x00000000000020ba      1      9      0 is_stmt

After liblink (off by one entry):

0x00001bbf: 00 Extended: <9> 02 DW_LNE_set_address( 0x0000000000002000 )
0x00001bca: 02 DW_LNS_advance_pc( 33 )
0x00001bcc: 03 DW_LNS_advance_line( 6 )
0x00001bce: 01 DW_LNS_copy
            0x0000000000002021      1      7      0 is_stmt

0x00001bcf: 02 DW_LNS_advance_pc( 153 )
0x00001bd2: 03 DW_LNS_advance_line( 1 )
0x00001bd4: 01 DW_LNS_copy
            0x00000000000020ba      1      8      0 is_stmt

0x00001bd5: 02 DW_LNS_advance_pc( 153 )
0x00001bd8: 03 DW_LNS_advance_line( 1 )
0x00001bda: 01 DW_LNS_copy
            0x0000000000002153      1      9      0 is_stmt

After this CL (the line 9 pc offset changed due to intervening compiler changes):

0x00001d07: 00 Extended: <9> 02 DW_LNE_set_address( 0x0000000000002000 )
0x00001d12: 03 DW_LNS_advance_line( 6 )
0x00001d14: 01 DW_LNS_copy
            0x0000000000002000      1      7      0 is_stmt

0x00001d15: 8b address += 21,  line += 1
            0x0000000000002021      1      8      0 is_stmt

0x00001d16: 02 DW_LNS_advance_pc( 189 )
0x00001d19: 03 DW_LNS_advance_line( 1 )
0x00001d1b: 01 DW_LNS_copy
            0x00000000000020de      1      9      0 is_stmt

Fixes #7351.

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/66290043

src/cmd/ld/dwarf.c

index dd8a3d76066ea70b183568777777237552373e5d..4f1847ecb32f04f0e2833d2d40b8ed9ac6b30240 100644 (file)
@@ -1590,29 +1590,30 @@ writelines(void)
 
                pciterinit(&pcfile, &s->pcln->pcfile);
                pciterinit(&pcline, &s->pcln->pcline);
+               epc = pc;
                while(!pcfile.done && !pcline.done) {
-                       if(pc - s->value >= pcfile.nextpc) {
+                       if(epc - s->value >= pcfile.nextpc) {
                                pciternext(&pcfile);
                                continue;
                        }
-                       if(pc - s->value >= pcline.nextpc) {
+                       if(epc - s->value >= pcline.nextpc) {
                                pciternext(&pcline);
                                continue;
                        }
 
-                       if(pcfile.nextpc < pcline.nextpc)
-                               epc = pcfile.nextpc;
-                       else
-                               epc = pcline.nextpc;
-                       epc += s->value;
-
                        if(file != pcfile.value) {
                                cput(DW_LNS_set_file);
                                uleb128put(pcfile.value);
                                file = pcfile.value;
                        }
-                       putpclcdelta(epc - pc, pcline.value - line);
+                       putpclcdelta(s->value + pcline.pc - pc, pcline.value - line);
+
                        pc = epc;
+                       if(pcfile.nextpc < pcline.nextpc)
+                               epc = pcfile.nextpc;
+                       else
+                               epc = pcline.nextpc;
+                       epc += s->value;
                        line = pcline.value;
                }