diff options
| author | Luuk de Gram <luuk@degram.dev> | 2022-05-08 17:16:58 +0200 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2022-05-09 18:51:46 +0200 |
| commit | 62453496bac17f13e1e129de5cf08accddc02302 (patch) | |
| tree | aa540817a86ae174af39bf1ea4803271fafdc23b /src/link/Dwarf.zig | |
| parent | 2ae2ac33d9ddd1fb181e08a811d97b1bf238bced (diff) | |
| download | zig-62453496bac17f13e1e129de5cf08accddc02302.tar.gz zig-62453496bac17f13e1e129de5cf08accddc02302.zip | |
wasm: Write nops for padding debug info
Diffstat (limited to 'src/link/Dwarf.zig')
| -rw-r--r-- | src/link/Dwarf.zig | 106 |
1 files changed, 101 insertions, 5 deletions
diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index a7d2744491..a204dd91ae 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -851,6 +851,10 @@ pub fn commitDeclState( const file_pos = debug_line_sect.offset + src_fn.off; try pwriteDbgLineNops(d_sym.file, file_pos, 0, &[0]u8{}, src_fn.len); }, + .wasm => { + const wasm_file = file.cast(File.Wasm).?; + writeDbgLineNopsBuffered(wasm_file.debug_line.items, src_fn.off, 0, &.{}, src_fn.len); + }, else => unreachable, } // TODO Look at the free list before appending at the end. @@ -972,9 +976,16 @@ pub fn commitDeclState( mem.set(u8, debug_line.items[segment.size..], 0); } segment.size = needed_size; + debug_line.items.len = needed_size; } const offset = segment.offset + src_fn.off; - mem.copy(u8, debug_line.items[offset..], dbg_line_buffer.items); + writeDbgLineNopsBuffered( + debug_line.items, + offset, + prev_padding_size, + dbg_line_buffer.items, + next_padding_size, + ); }, else => unreachable, } @@ -1114,7 +1125,8 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, file: *File, atom: *Atom, len: u3 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, &[0]u8{}, atom.len, false); }, .wasm => { - log.debug(" todo: updateDeclDebugInfoAllocation for Wasm: {d}", .{atom.len}); + const wasm_file = file.cast(File.Wasm).?; + writeDbgInfoNopsBuffered(wasm_file.debug_info.items, atom.off, 0, &.{0}, atom.len, false); }, else => unreachable, } @@ -1253,9 +1265,17 @@ fn writeDeclDebugInfo(self: *Dwarf, file: *File, atom: *Atom, dbg_info_buf: []co mem.set(u8, debug_info.items[segment.size..], 0); } segment.size = needed_size; + debug_info.items.len = needed_size; } const offset = segment.offset + atom.off; - mem.copy(u8, debug_info.items[offset..], dbg_info_buf); + writeDbgInfoNopsBuffered( + debug_info.items, + offset, + prev_padding_size, + dbg_info_buf, + next_padding_size, + trailing_zero, + ); }, else => unreachable, } @@ -1643,7 +1663,7 @@ pub fn writeDbgInfoHeader(self: *Dwarf, file: *File, module: *Module, low_pc: u6 }, .wasm => { const wasm_file = file.cast(File.Wasm).?; - mem.copy(u8, wasm_file.debug_info.items, di_buf.items); + writeDbgInfoNopsBuffered(wasm_file.debug_info.items, 0, 0, di_buf.items, jmp_amt, false); }, else => unreachable, } @@ -1738,6 +1758,45 @@ fn pwriteDbgLineNops( try file.pwritevAll(vecs[0..vec_index], offset - prev_padding_size); } +fn writeDbgLineNopsBuffered( + buf: []u8, + offset: u32, + prev_padding_size: usize, + content: []const u8, + next_padding_size: usize, +) void { + assert(buf.len >= content.len + prev_padding_size + next_padding_size); + const tracy = trace(@src()); + defer tracy.end(); + + const three_byte_nop = [3]u8{ DW.LNS.advance_pc, 0b1000_0000, 0 }; + { + var padding_left = prev_padding_size; + if (padding_left % 2 != 0) { + buf[offset - padding_left ..][0..3].* = three_byte_nop; + padding_left -= 3; + } + + while (padding_left > 0) : (padding_left -= 1) { + buf[offset - padding_left] = DW.LNS.negate_stmt; + } + } + + mem.copy(u8, buf[offset..], content); + + { + var padding_left = next_padding_size; + if (padding_left % 2 != 0) { + buf[offset + content.len + padding_left ..][0..3].* = three_byte_nop; + padding_left -= 3; + } + + while (padding_left > 0) : (padding_left -= 1) { + buf[offset + content.len + padding_left] = DW.LNS.negate_stmt; + } + } +} + /// Writes to the file a buffer, prefixed and suffixed by the specified number of /// bytes of padding. fn pwriteDbgInfoNops( @@ -1810,6 +1869,38 @@ fn pwriteDbgInfoNops( try file.pwritevAll(vecs[0..vec_index], offset - prev_padding_size); } +fn writeDbgInfoNopsBuffered( + buf: []u8, + offset: u32, + prev_padding_size: usize, + content: []const u8, + next_padding_size: usize, + trailing_zero: bool, +) void { + assert(buf.len >= content.len + prev_padding_size + next_padding_size + @boolToInt(trailing_zero)); + const tracy = trace(@src()); + defer tracy.end(); + + { + var padding_left = prev_padding_size; + while (padding_left > 0) : (padding_left -= 1) { + buf[offset - padding_left] = @enumToInt(AbbrevKind.pad1); + } + } + + mem.copy(u8, buf[offset..], content); + { + var padding_left = next_padding_size; + while (padding_left > 0) : (padding_left -= 1) { + buf[offset + content.len + padding_left] = @enumToInt(AbbrevKind.pad1); + } + } + + if (trailing_zero) { + buf[offset + content.len + next_padding_size] = 0; + } +} + pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void { const target_endian = self.target.cpu.arch.endian(); const init_len_size: usize = if (self.tag == .macho) @@ -1909,6 +2000,11 @@ pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void { const file_pos = debug_aranges_sect.offset; try d_sym.file.pwriteAll(di_buf.items, file_pos); }, + .wasm => { + const wasm_file = file.cast(File.Wasm).?; + try wasm_file.debug_aranges.resize(wasm_file.base.allocator, needed_size); + mem.copy(u8, wasm_file.debug_aranges.items, di_buf.items); + }, else => unreachable, } } @@ -2030,7 +2126,7 @@ pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void { }, .wasm => { const wasm_file = file.cast(File.Wasm).?; - mem.copy(u8, wasm_file.debug_line.items, di_buf.items); + writeDbgLineNopsBuffered(wasm_file.debug_line.items, 0, 0, di_buf.items, jmp_amt); }, else => unreachable, } |
