authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-13 20:05:41-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-13 20:05:41-07:00
logedab03bc22018fa66125ecff4d22d09770852a8e
tree477c454f4152e06787a1524f2c07589461eeba07
parent78632894dabec3c20ee2ff4348e03cfa565477ef

link/MachO: fixes to debug symbols

commitDeclDebugInfo: stop trying to write length 0 debug info - avoids hitting an error where zig tries to move the debug info section unnecessarily, gets confused, and reports `error.InputOutput`. The 2 pieces of code that looked at the source and tried to compute source line offsets is now improved to match link/Elf - use the line/column data stored in the Decl object to skip the costly scanning of source bytes. No need to load Zig source code, AST, or tokens, when we have the ZIR!

1 files changed, 8 insertions(+), 24 deletions(-)

src/link/MachO/DebugSymbols.zig+8-24
......@@ -909,20 +909,14 @@ pub fn updateDeclLineNumber(self: *DebugSymbols, module: *Module, decl: *const M
909909 const node_datas = tree.nodes.items(.data);
910910 const token_starts = tree.tokens.items(.start);
911911
912 // TODO Look into improving the performance here by adding a token-index-to-line
913 // lookup table. Currently this involves scanning over the source code for newlines.
914 const fn_decl = decl.src_node;
915 assert(node_tags[fn_decl] == .fn_decl);
916 const block = node_datas[fn_decl].rhs;
917 const lbrace = tree.firstToken(block);
918 const line_delta = std.zig.lineDelta(tree.source, 0, token_starts[lbrace]);
919 const casted_line_off = @intCast(u28, line_delta);
912 const func = decl.val.castTag(.function).?.data;
913 const line_off = @intCast(u28, decl.src_line + func.lbrace_line);
920914
921915 const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment;
922916 const shdr = &dwarf_segment.sections.items[self.debug_line_section_index.?];
923917 const file_pos = shdr.offset + decl.fn_link.macho.off + getRelocDbgLineOff();
924918 var data: [4]u8 = undefined;
925 leb.writeUnsignedFixed(4, &data, casted_line_off);
919 leb.writeUnsignedFixed(4, &data, line_off);
926920 try self.file.pwriteAll(&data, file_pos);
927921}
928922
......@@ -952,21 +946,8 @@ pub fn initDeclDebugBuffers(
952946 // For functions we need to add a prologue to the debug line program.
953947 try dbg_line_buffer.ensureCapacity(26);
954948
955 const line_off: u28 = blk: {
956 const tree = decl.namespace.file_scope.tree;
957 const node_tags = tree.nodes.items(.tag);
958 const node_datas = tree.nodes.items(.data);
959 const token_starts = tree.tokens.items(.start);
960
961 // TODO Look into improving the performance here by adding a token-index-to-line
962 // lookup table. Currently this involves scanning over the source code for newlines.
963 const fn_decl = decl.src_node;
964 assert(node_tags[fn_decl] == .fn_decl);
965 const block = node_datas[fn_decl].rhs;
966 const lbrace = tree.firstToken(block);
967 const line_delta = std.zig.lineDelta(tree.source, 0, token_starts[lbrace]);
968 break :blk @intCast(u28, line_delta);
969 };
949 const func = decl.val.castTag(.function).?.data;
950 const line_off = @intCast(u28, decl.src_line + func.lbrace_line);
970951
971952 dbg_line_buffer.appendSliceAssumeCapacity(&[_]u8{
972953 DW.LNS_extended_op,
......@@ -1162,6 +1143,9 @@ pub fn commitDeclDebugInfo(
11621143 else => {},
11631144 }
11641145
1146 if (dbg_info_buffer.items.len == 0)
1147 return;
1148
11651149 // Now we emit the .debug_info types of the Decl. These will count towards the size of
11661150 // the buffer, so we have to do it before computing the offset, and we can't perform the actual
11671151 // relocations yet.