@@ -48,6 +48,28 @@ pub const DebugInfoOutput = union(enum) {
48
48
dbg_info : * std .ArrayList (u8 ),
49
49
dbg_info_type_relocs : * link.File.DbgInfoTypeRelocsTable ,
50
50
},
51
+ /// the plan9 debuginfo output is a bytecode with 4 opcodes
52
+ /// assume all numbers/variables are bytes
53
+ /// 0 w x y z -> interpret w x y z as a big-endian i32, and add it to the line offset
54
+ /// x when x < 65 -> add x to line offset
55
+ /// x when x < 129 -> subtract 64 from x and subtract it from the line offset
56
+ /// x -> subtract 129 from x, multiply it by the quanta of the instruction size
57
+ /// (1 on x86_64), and add it to the pc
58
+ /// after every opcode, add the quanta of the instruction size to the pc
59
+ plan9 : struct {
60
+ /// the actual opcodes
61
+ dbg_line : * std .ArrayList (u8 ),
62
+ /// what line the debuginfo starts on
63
+ /// this helps because the linker might have to insert some opcodes to make sure that the line count starts at the right amount for the next decl
64
+ start_line : * ? u32 ,
65
+ /// what the line count ends on after codegen
66
+ /// this helps because the linker might have to insert some opcodes to make sure that the line count starts at the right amount for the next decl
67
+ end_line : * u32 ,
68
+ /// the last pc change op
69
+ /// This is very useful for adding quanta
70
+ /// to it if its not actually the last one.
71
+ pcop_change_index : * ? u32 ,
72
+ },
51
73
none ,
52
74
};
53
75
@@ -915,6 +937,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
915
937
try dbg_out .dbg_line .append (DW .LNS .set_prologue_end );
916
938
try self .dbgAdvancePCAndLine (self .prev_di_line , self .prev_di_column );
917
939
},
940
+ .plan9 = > {},
918
941
.none = > {},
919
942
}
920
943
}
@@ -925,15 +948,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
925
948
try dbg_out .dbg_line .append (DW .LNS .set_epilogue_begin );
926
949
try self .dbgAdvancePCAndLine (self .prev_di_line , self .prev_di_column );
927
950
},
951
+ .plan9 = > {},
928
952
.none = > {},
929
953
}
930
954
}
931
955
932
956
fn dbgAdvancePCAndLine (self : * Self , line : u32 , column : u32 ) InnerError ! void {
957
+ const delta_line = @intCast (i32 , line ) - @intCast (i32 , self .prev_di_line );
958
+ const delta_pc : usize = self .code .items .len - self .prev_di_pc ;
933
959
switch (self .debug_output ) {
934
960
.dwarf = > | dbg_out | {
935
- const delta_line = @intCast (i32 , line ) - @intCast (i32 , self .prev_di_line );
936
- const delta_pc = self .code .items .len - self .prev_di_pc ;
937
961
// TODO Look into using the DWARF special opcodes to compress this data.
938
962
// It lets you emit single-byte opcodes that add different numbers to
939
963
// both the PC and the line number at the same time.
@@ -945,12 +969,39 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
945
969
leb128 .writeILEB128 (dbg_out .dbg_line .writer (), delta_line ) catch unreachable ;
946
970
}
947
971
dbg_out .dbg_line .appendAssumeCapacity (DW .LNS .copy );
972
+ self .prev_di_pc = self .code .items .len ;
973
+ self .prev_di_line = line ;
974
+ self .prev_di_column = column ;
975
+ self .prev_di_pc = self .code .items .len ;
976
+ },
977
+ .plan9 = > | dbg_out | {
978
+ if (delta_pc <= 0 ) return ; // only do this when the pc changes
979
+ // we have already checked the target in the linker to make sure it is compatable
980
+ const quant = @import ("link/Plan9/aout.zig" ).getPCQuant (self .target .cpu .arch ) catch unreachable ;
981
+
982
+ // increasing the line number
983
+ try @import ("link/Plan9.zig" ).changeLine (dbg_out .dbg_line , delta_line );
984
+ // increasing the pc
985
+ const d_pc_p9 = @intCast (i64 , delta_pc ) - quant ;
986
+ if (d_pc_p9 > 0 ) {
987
+ // minus one becaue if its the last one, we want to leave space to change the line which is one quanta
988
+ try dbg_out .dbg_line .append (@intCast (u8 , @divExact (d_pc_p9 , quant ) + 128 ) - quant );
989
+ if (dbg_out .pcop_change_index .* ) | pci |
990
+ dbg_out .dbg_line .items [pci ] += 1 ;
991
+ dbg_out .pcop_change_index .* = @intCast (u32 , dbg_out .dbg_line .items .len - 1 );
992
+ } else if (d_pc_p9 == 0 ) {
993
+ // we don't need to do anything, because adding the quant does it for us
994
+ } else unreachable ;
995
+ if (dbg_out .start_line .* == null )
996
+ dbg_out .start_line .* = self .prev_di_line ;
997
+ dbg_out .end_line .* = line ;
998
+ // only do this if the pc changed
999
+ self .prev_di_line = line ;
1000
+ self .prev_di_column = column ;
1001
+ self .prev_di_pc = self .code .items .len ;
948
1002
},
949
1003
.none = > {},
950
1004
}
951
- self .prev_di_line = line ;
952
- self .prev_di_column = column ;
953
- self .prev_di_pc = self .code .items .len ;
954
1005
}
955
1006
956
1007
/// Asserts there is already capacity to insert into top branch inst_table.
@@ -1034,6 +1085,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
1034
1085
}
1035
1086
try gop .value_ptr .relocs .append (self .gpa , @intCast (u32 , index ));
1036
1087
},
1088
+ .plan9 = > {},
1037
1089
.none = > {},
1038
1090
}
1039
1091
}
@@ -2459,6 +2511,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2459
2511
try self .addDbgInfoTypeReloc (ty ); // DW.AT.type, DW.FORM.ref4
2460
2512
dbg_out .dbg_info .appendSliceAssumeCapacity (name_with_null ); // DW.AT.name, DW.FORM.string
2461
2513
},
2514
+ .plan9 = > {},
2462
2515
.none = > {},
2463
2516
}
2464
2517
},
@@ -2493,6 +2546,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2493
2546
else = > {},
2494
2547
}
2495
2548
},
2549
+ .plan9 = > {},
2496
2550
.none = > {},
2497
2551
}
2498
2552
},
@@ -2929,6 +2983,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2929
2983
}
2930
2984
if (self .air .value (callee )) | func_value | {
2931
2985
if (func_value .castTag (.function )) | func_payload | {
2986
+ try p9 .seeDecl (func_payload .data .owner_decl );
2932
2987
const ptr_bits = self .target .cpu .arch .ptrBitWidth ();
2933
2988
const ptr_bytes : u64 = @divExact (ptr_bits , 8 );
2934
2989
const got_addr = p9 .bases .data ;
@@ -2976,6 +3031,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2976
3031
}
2977
3032
if (self .air .value (callee )) | func_value | {
2978
3033
if (func_value .castTag (.function )) | func_payload | {
3034
+ try p9 .seeDecl (func_payload .data .owner_decl );
2979
3035
const ptr_bits = self .target .cpu .arch .ptrBitWidth ();
2980
3036
const ptr_bytes : u64 = @divExact (ptr_bits , 8 );
2981
3037
const got_addr = p9 .bases .data ;
@@ -4923,6 +4979,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
4923
4979
const got_addr = coff_file .offset_table_virtual_address + decl .link .coff .offset_table_index * ptr_bytes ;
4924
4980
return MCValue { .memory = got_addr };
4925
4981
} else if (self .bin_file .cast (link .File .Plan9 )) | p9 | {
4982
+ try p9 .seeDecl (decl );
4926
4983
const got_addr = p9 .bases .data + decl .link .plan9 .got_index .? * ptr_bytes ;
4927
4984
return MCValue { .memory = got_addr };
4928
4985
} else {
0 commit comments