Skip to content

Commit fea14c7

Browse files
authored
wasm-linker: emit build_id section (#14820)
The Build ID is a value that uniquely identifies a build. It is intended to capture the "meaning" or inputs of the build, and is usually associated with debug info. Reference: https://github.com/WebAssembly/tool-conventions/blob/main/BuildId.md
1 parent e3cf9d1 commit fea14c7

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

src/link/Wasm.zig

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2635,6 +2635,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l
26352635
try man.addOptionalFile(compiler_rt_path);
26362636
man.hash.addOptionalBytes(options.entry);
26372637
man.hash.addOptional(options.stack_size_override);
2638+
man.hash.add(wasm.base.options.build_id);
26382639
man.hash.add(options.import_memory);
26392640
man.hash.add(options.import_table);
26402641
man.hash.add(options.export_table);
@@ -3225,6 +3226,12 @@ fn writeToFile(
32253226
}
32263227

32273228
if (!wasm.base.options.strip) {
3229+
// The build id must be computed on the main sections only,
3230+
// so we have to do it now, before the debug sections.
3231+
if (wasm.base.options.build_id) {
3232+
try emitBuildIdSection(&binary_bytes);
3233+
}
3234+
32283235
// if (wasm.dwarf) |*dwarf| {
32293236
// const mod = wasm.base.options.module.?;
32303237
// try dwarf.writeDbgAbbrev();
@@ -3363,6 +3370,33 @@ fn emitProducerSection(binary_bytes: *std.ArrayList(u8)) !void {
33633370
);
33643371
}
33653372

3373+
fn emitBuildIdSection(binary_bytes: *std.ArrayList(u8)) !void {
3374+
const header_offset = try reserveCustomSectionHeader(binary_bytes);
3375+
3376+
const writer = binary_bytes.writer();
3377+
const build_id = "build_id";
3378+
try leb.writeULEB128(writer, @intCast(u32, build_id.len));
3379+
try writer.writeAll(build_id);
3380+
3381+
var id: [16]u8 = undefined;
3382+
std.crypto.hash.sha3.TurboShake128(null).hash(binary_bytes.items, &id, .{});
3383+
var uuid: [36]u8 = undefined;
3384+
_ = try std.fmt.bufPrint(&uuid, "{s}-{s}-{s}-{s}-{s}", .{
3385+
std.fmt.fmtSliceHexLower(id[0..4]), std.fmt.fmtSliceHexLower(id[4..6]), std.fmt.fmtSliceHexLower(id[6..8]),
3386+
std.fmt.fmtSliceHexLower(id[8..10]), std.fmt.fmtSliceHexLower(id[10..]),
3387+
});
3388+
3389+
try leb.writeULEB128(writer, @as(u32, 1));
3390+
try leb.writeULEB128(writer, @as(u32, uuid.len));
3391+
try writer.writeAll(&uuid);
3392+
3393+
try writeCustomSectionHeader(
3394+
binary_bytes.items,
3395+
header_offset,
3396+
@intCast(u32, binary_bytes.items.len - header_offset - 6),
3397+
);
3398+
}
3399+
33663400
fn emitFeaturesSection(binary_bytes: *std.ArrayList(u8), enabled_features: []const bool, features_count: u32) !void {
33673401
const header_offset = try reserveCustomSectionHeader(binary_bytes);
33683402

@@ -3594,6 +3628,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
35943628
try man.addOptionalFile(compiler_rt_path);
35953629
man.hash.addOptionalBytes(wasm.base.options.entry);
35963630
man.hash.addOptional(wasm.base.options.stack_size_override);
3631+
man.hash.add(wasm.base.options.build_id);
35973632
man.hash.add(wasm.base.options.import_memory);
35983633
man.hash.add(wasm.base.options.import_table);
35993634
man.hash.add(wasm.base.options.export_table);
@@ -3760,6 +3795,12 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
37603795
if (wasm.base.options.import_symbols) {
37613796
try argv.append("--allow-undefined");
37623797
}
3798+
3799+
// XXX - TODO: add when wasm-ld supports --build-id.
3800+
// if (wasm.base.options.build_id) {
3801+
// try argv.append("--build-id=tree");
3802+
// }
3803+
37633804
try argv.appendSlice(&.{ "-o", full_out_path });
37643805

37653806
if (target.cpu.arch == .wasm64) {

0 commit comments

Comments
 (0)