aboutsummaryrefslogtreecommitdiff
path: root/src/link/Dwarf.zig
diff options
context:
space:
mode:
authorLuuk de Gram <luuk@degram.dev>2022-05-08 17:16:58 +0200
committerLuuk de Gram <luuk@degram.dev>2022-05-09 18:51:46 +0200
commit62453496bac17f13e1e129de5cf08accddc02302 (patch)
treeaa540817a86ae174af39bf1ea4803271fafdc23b /src/link/Dwarf.zig
parent2ae2ac33d9ddd1fb181e08a811d97b1bf238bced (diff)
downloadzig-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.zig106
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,
}