wasm-linker: write magic bytes only on success

By writing them at the very end, we can easily detect
where the writing of the binary went wrong as tools will
indicate the missing of the magic bytes.
This commit is contained in:
Luuk de Gram 2022-09-10 13:49:39 +02:00
parent e323cf1264
commit a01b1448e2
No known key found for this signature in database
GPG Key ID: A8CFE58E4DC7D664

View File

@ -324,8 +324,6 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option
wasm_bin.base.file = file;
wasm_bin.name = sub_path;
try file.writeAll(&(wasm.magic ++ wasm.version));
// As sym_index '0' is reserved, we use it for our stack pointer symbol
const sym_name = try wasm_bin.string_table.put(allocator, "__stack_pointer");
const symbol = try wasm_bin.symbols.addOne(allocator);
@ -363,7 +361,11 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option
};
}
try wasm_bin.initDebugSections();
if (!options.strip and options.module != null) {
wasm_bin.dwarf = Dwarf.init(allocator, .wasm, options.target);
try wasm_bin.initDebugSections();
}
return wasm_bin;
}
@ -380,10 +382,6 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Wasm {
.name = undefined,
};
if (!options.strip and options.module != null) {
self.dwarf = Dwarf.init(gpa, .wasm, options.target);
}
const use_llvm = build_options.have_llvm and options.use_llvm;
const use_stage1 = build_options.have_stage1 and options.use_stage1;
if (use_llvm and !use_stage1) {
@ -2213,7 +2211,8 @@ pub fn flushModule(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
const header_size = 5 + 1;
const is_obj = self.base.options.output_mode == .Obj;
// No need to rewrite the magic/version header
// We write the magic bytes at the end so they will only be written
// if everything succeeded as expected.
try file.setEndPos(@sizeOf(@TypeOf(wasm.magic ++ wasm.version)));
try file.seekTo(@sizeOf(@TypeOf(wasm.magic ++ wasm.version)));
@ -2599,6 +2598,11 @@ pub fn flushModule(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
}
try self.emitNameSection(file, arena);
}
// Only when writing all sections executed properly we write the magic
// bytes. This allows us to easily detect what went wrong while generating
// the final binary.
try file.pwriteAll(&(wasm.magic ++ wasm.version), 0);
}
fn emitDebugSection(file: fs.File, data: []const u8, name: []const u8) !void {