wasm: Fix unreachable paths

When the last instruction is a debug instruction, the type of it is void.
Similarly for 'noreturn' emit an 'unreachable' instruction to tell the wasm-validator
the path cannot be reached.

Also respect the '--strip' flag in the self-hosted wasm linker and not emit a 'name' section
when the flag is set to `true`.
This commit is contained in:
Luuk de Gram 2022-04-17 19:41:05 +02:00
parent 2193f7c4a2
commit be08d2bdbd
No known key found for this signature in database
GPG Key ID: A8CFE58E4DC7D664
3 changed files with 37 additions and 4 deletions

View File

@ -113,11 +113,14 @@ pub fn detectTTYConfig() TTY.Config {
/// TODO multithreaded awareness
pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
nosuspend {
const stderr = io.getStdErr().writer();
if (comptime builtin.target.isWasm()) {
stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return;
if (native_os == .wasi) {
const stderr = io.getStdErr().writer();
stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return;
}
return;
}
const stderr = io.getStdErr().writer();
if (builtin.strip_debug_info) {
stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return;
return;
@ -138,6 +141,13 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
/// TODO multithreaded awareness
pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void {
nosuspend {
if (comptime builtin.target.isWasm()) {
if (native_os == .wasi) {
const stderr = io.getStdErr().writer();
stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return;
}
return;
}
const stderr = io.getStdErr().writer();
if (builtin.strip_debug_info) {
stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return;
@ -208,6 +218,13 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *std.builtin.StackT
/// TODO multithreaded awareness
pub fn dumpStackTrace(stack_trace: std.builtin.StackTrace) void {
nosuspend {
if (comptime builtin.target.isWasm()) {
if (native_os == .wasi) {
const stderr = io.getStdErr().writer();
stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return;
}
return;
}
const stderr = io.getStdErr().writer();
if (builtin.strip_debug_info) {
stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return;
@ -1138,6 +1155,8 @@ pub const DebugInfo = struct {
return self.lookupModuleWin32(address);
} else if (native_os == .haiku) {
return self.lookupModuleHaiku(address);
} else if (comptime builtin.target.isWasm()) {
return self.lookupModuleWasm(address);
} else {
return self.lookupModuleDl(address);
}
@ -1353,6 +1372,12 @@ pub const DebugInfo = struct {
_ = address;
@panic("TODO implement lookup module for Haiku");
}
fn lookupModuleWasm(self: *DebugInfo, address: usize) !*ModuleDebugInfo {
_ = self;
_ = address;
@panic("TODO implement lookup module for Wasm");
}
};
pub const ModuleDebugInfo = switch (native_os) {
@ -1632,6 +1657,13 @@ pub const ModuleDebugInfo = switch (native_os) {
return getSymbolFromDwarf(relocated_address, &self.dwarf);
}
},
.wasi => struct {
pub fn getSymbolAtAddress(self: *@This(), address: usize) !SymbolInfo {
_ = self;
_ = address;
return SymbolInfo{};
}
},
else => DW.DwarfInfo,
};

View File

@ -871,7 +871,8 @@ fn genFunc(self: *Self) InnerError!void {
// we emit an unreachable instruction to tell the stack validator that part will never be reached.
if (func_type.returns.len != 0 and self.air.instructions.len > 0) {
const inst = @intCast(u32, self.air.instructions.len - 1);
if (self.air.typeOfIndex(inst).isNoReturn()) {
const last_inst_ty = self.air.typeOfIndex(inst);
if (!last_inst_ty.hasRuntimeBitsIgnoreComptime() or last_inst_ty.isNoReturn()) {
try self.addTag(.@"unreachable");
}
}

View File

@ -1897,7 +1897,7 @@ pub fn flushModule(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
if (data_section_index) |data_index| {
try self.emitDataRelocations(file, arena, data_index, symbol_table);
}
} else {
} else if (!self.base.options.strip) {
try self.emitNameSection(file, arena);
}
}