aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-05-17 07:19:15 -0700
committerGitHub <noreply@github.com>2023-05-17 07:19:15 -0700
commitc1add1e19ea35b4d96fbab317410276f757510ef (patch)
tree9791032b09046f6d5b785cd643439b266737cab4 /src
parent5b06daf52bdeaf18b40909ef878e8b19b3d14019 (diff)
parent728ce2d7c18e23ca6c36d86f4ee1ea4ce3ac81e2 (diff)
downloadzig-c1add1e19ea35b4d96fbab317410276f757510ef.tar.gz
zig-c1add1e19ea35b4d96fbab317410276f757510ef.zip
Merge pull request #15459 from motiejus/build-id-full
stage2: implement `--build-id` styles
Diffstat (limited to 'src')
-rw-r--r--src/Compilation.zig7
-rw-r--r--src/link.zig3
-rw-r--r--src/link/Elf.zig14
-rw-r--r--src/link/Wasm.zig45
-rw-r--r--src/main.zig35
5 files changed, 71 insertions, 33 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig
index 0818eaafdd..0a01e9465c 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -29,6 +29,7 @@ const wasi_libc = @import("wasi_libc.zig");
const fatal = @import("main.zig").fatal;
const clangMain = @import("main.zig").clangMain;
const Module = @import("Module.zig");
+const BuildId = std.Build.CompileStep.BuildId;
const Cache = std.Build.Cache;
const translate_c = @import("translate_c.zig");
const clang = @import("clang.zig");
@@ -563,7 +564,7 @@ pub const InitOptions = struct {
linker_print_map: bool = false,
linker_opt_bisect_limit: i32 = -1,
each_lib_rpath: ?bool = null,
- build_id: ?bool = null,
+ build_id: ?BuildId = null,
disable_c_depfile: bool = false,
linker_z_nodelete: bool = false,
linker_z_notext: bool = false,
@@ -797,7 +798,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
const unwind_tables = options.want_unwind_tables orelse
(link_libunwind or target_util.needUnwindTables(options.target));
const link_eh_frame_hdr = options.link_eh_frame_hdr or unwind_tables;
- const build_id = options.build_id orelse false;
+ const build_id = options.build_id orelse .none;
// Make a decision on whether to use LLD or our own linker.
const use_lld = options.use_lld orelse blk: {
@@ -828,7 +829,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
options.output_mode == .Lib or
options.linker_script != null or options.version_script != null or
options.emit_implib != null or
- build_id or
+ build_id != .none or
options.symbol_wrap_set.count() > 0)
{
break :blk true;
diff --git a/src/link.zig b/src/link.zig
index 74e3ca85fc..79ac33b892 100644
--- a/src/link.zig
+++ b/src/link.zig
@@ -10,6 +10,7 @@ const wasi_libc = @import("wasi_libc.zig");
const Air = @import("Air.zig");
const Allocator = std.mem.Allocator;
+const BuildId = std.Build.CompileStep.BuildId;
const Cache = std.Build.Cache;
const Compilation = @import("Compilation.zig");
const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
@@ -157,7 +158,7 @@ pub const Options = struct {
skip_linker_dependencies: bool,
parent_compilation_link_libc: bool,
each_lib_rpath: bool,
- build_id: bool,
+ build_id: BuildId,
disable_lld_caching: bool,
is_test: bool,
hash_style: HashStyle,
diff --git a/src/link/Elf.zig b/src/link/Elf.zig
index 724ec76500..f90f4ebd46 100644
--- a/src/link/Elf.zig
+++ b/src/link/Elf.zig
@@ -1542,8 +1542,18 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
try argv.append("-z");
try argv.append(try std.fmt.allocPrint(arena, "stack-size={d}", .{stack_size}));
- if (self.base.options.build_id) {
- try argv.append("--build-id");
+ switch (self.base.options.build_id) {
+ .none => {},
+ .fast, .uuid, .sha1, .md5 => {
+ try argv.append(try std.fmt.allocPrint(arena, "--build-id={s}", .{
+ @tagName(self.base.options.build_id),
+ }));
+ },
+ .hexstring => |hs| {
+ try argv.append(try std.fmt.allocPrint(arena, "--build-id=0x{s}", .{
+ std.fmt.fmtSliceHexLower(hs.toSlice()),
+ }));
+ },
}
}
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig
index b6f4a4cc59..cd9c44d656 100644
--- a/src/link/Wasm.zig
+++ b/src/link/Wasm.zig
@@ -3797,8 +3797,29 @@ fn writeToFile(
if (!wasm.base.options.strip) {
// The build id must be computed on the main sections only,
// so we have to do it now, before the debug sections.
- if (wasm.base.options.build_id) {
- try emitBuildIdSection(&binary_bytes);
+ switch (wasm.base.options.build_id) {
+ .none => {},
+ .fast => {
+ var id: [16]u8 = undefined;
+ std.crypto.hash.sha3.TurboShake128(null).hash(binary_bytes.items, &id, .{});
+ var uuid: [36]u8 = undefined;
+ _ = try std.fmt.bufPrint(&uuid, "{s}-{s}-{s}-{s}-{s}", .{
+ std.fmt.fmtSliceHexLower(id[0..4]),
+ std.fmt.fmtSliceHexLower(id[4..6]),
+ std.fmt.fmtSliceHexLower(id[6..8]),
+ std.fmt.fmtSliceHexLower(id[8..10]),
+ std.fmt.fmtSliceHexLower(id[10..]),
+ });
+ try emitBuildIdSection(&binary_bytes, &uuid);
+ },
+ .hexstring => |hs| {
+ var buffer: [32 * 2]u8 = undefined;
+ const str = std.fmt.bufPrint(&buffer, "{s}", .{
+ std.fmt.fmtSliceHexLower(hs.toSlice()),
+ }) catch unreachable;
+ try emitBuildIdSection(&binary_bytes, str);
+ },
+ else => |mode| log.err("build-id '{s}' is not supported for WASM", .{@tagName(mode)}),
}
// if (wasm.dwarf) |*dwarf| {
@@ -3942,25 +3963,17 @@ fn emitProducerSection(binary_bytes: *std.ArrayList(u8)) !void {
);
}
-fn emitBuildIdSection(binary_bytes: *std.ArrayList(u8)) !void {
+fn emitBuildIdSection(binary_bytes: *std.ArrayList(u8), build_id: []const u8) !void {
const header_offset = try reserveCustomSectionHeader(binary_bytes);
const writer = binary_bytes.writer();
- const build_id = "build_id";
- try leb.writeULEB128(writer, @intCast(u32, build_id.len));
- try writer.writeAll(build_id);
-
- var id: [16]u8 = undefined;
- std.crypto.hash.sha3.TurboShake128(null).hash(binary_bytes.items, &id, .{});
- var uuid: [36]u8 = undefined;
- _ = try std.fmt.bufPrint(&uuid, "{s}-{s}-{s}-{s}-{s}", .{
- std.fmt.fmtSliceHexLower(id[0..4]), std.fmt.fmtSliceHexLower(id[4..6]), std.fmt.fmtSliceHexLower(id[6..8]),
- std.fmt.fmtSliceHexLower(id[8..10]), std.fmt.fmtSliceHexLower(id[10..]),
- });
+ const hdr_build_id = "build_id";
+ try leb.writeULEB128(writer, @intCast(u32, hdr_build_id.len));
+ try writer.writeAll(hdr_build_id);
try leb.writeULEB128(writer, @as(u32, 1));
- try leb.writeULEB128(writer, @as(u32, uuid.len));
- try writer.writeAll(&uuid);
+ try leb.writeULEB128(writer, @intCast(u32, build_id.len));
+ try writer.writeAll(build_id);
try writeCustomSectionHeader(
binary_bytes.items,
diff --git a/src/main.zig b/src/main.zig
index 6ac8636c88..4e64c06aa9 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -22,6 +22,7 @@ const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
const wasi_libc = @import("wasi_libc.zig");
const translate_c = @import("translate_c.zig");
const clang = @import("clang.zig");
+const BuildId = std.Build.CompileStep.BuildId;
const Cache = std.Build.Cache;
const target_util = @import("target.zig");
const crash_report = @import("crash_report.zig");
@@ -493,8 +494,10 @@ const usage_build_generic =
\\ -fno-each-lib-rpath Prevent adding rpath for each used dynamic library
\\ -fallow-shlib-undefined Allows undefined symbols in shared libraries
\\ -fno-allow-shlib-undefined Disallows undefined symbols in shared libraries
- \\ -fbuild-id Helps coordinate stripped binaries with debug symbols
- \\ -fno-build-id (default) Saves a bit of time linking
+ \\ --build-id[=style] At a minor link-time expense, coordinates stripped binaries
+ \\ fast, uuid, sha1, md5 with debug symbols via a '.note.gnu.build-id' section
+ \\ 0x[hexstring] Maximum 32 bytes
+ \\ none (default) Disable build-id
\\ --eh-frame-hdr Enable C++ exception handling by passing --eh-frame-hdr to linker
\\ --emit-relocs Enable output of relocation sections for post build tools
\\ -z [arg] Set linker extension flags
@@ -817,7 +820,7 @@ fn buildOutputType(
var link_eh_frame_hdr = false;
var link_emit_relocs = false;
var each_lib_rpath: ?bool = null;
- var build_id: ?bool = null;
+ var build_id: ?BuildId = null;
var sysroot: ?[]const u8 = null;
var libc_paths_file: ?[]const u8 = try optionalStringEnvVar(arena, "ZIG_LIBC");
var machine_code_model: std.builtin.CodeModel = .default;
@@ -1202,10 +1205,6 @@ fn buildOutputType(
each_lib_rpath = true;
} else if (mem.eql(u8, arg, "-fno-each-lib-rpath")) {
each_lib_rpath = false;
- } else if (mem.eql(u8, arg, "-fbuild-id")) {
- build_id = true;
- } else if (mem.eql(u8, arg, "-fno-build-id")) {
- build_id = false;
} else if (mem.eql(u8, arg, "--test-cmd-bin")) {
try test_exec_args.append(null);
} else if (mem.eql(u8, arg, "--test-evented-io")) {
@@ -1446,6 +1445,15 @@ fn buildOutputType(
linker_gc_sections = true;
} else if (mem.eql(u8, arg, "--no-gc-sections")) {
linker_gc_sections = false;
+ } else if (mem.eql(u8, arg, "--build-id")) {
+ build_id = .fast;
+ } else if (mem.startsWith(u8, arg, "--build-id=")) {
+ const style = arg["--build-id=".len..];
+ build_id = BuildId.parse(style) catch |err| {
+ fatal("unable to parse --build-id style '{s}': {s}", .{
+ style, @errorName(err),
+ });
+ };
} else if (mem.eql(u8, arg, "--debug-compile-errors")) {
if (!crash_report.is_enabled) {
std.log.warn("Zig was compiled in a release mode. --debug-compile-errors has no effect.", .{});
@@ -1684,9 +1692,12 @@ fn buildOutputType(
if (mem.indexOfScalar(u8, linker_arg, '=')) |equals_pos| {
const key = linker_arg[0..equals_pos];
const value = linker_arg[equals_pos + 1 ..];
- if (mem.eql(u8, key, "build-id")) {
- build_id = true;
- warn("ignoring build-id style argument: '{s}'", .{value});
+ if (mem.eql(u8, key, "--build-id")) {
+ build_id = BuildId.parse(value) catch |err| {
+ fatal("unable to parse --build-id style '{s}': {s}", .{
+ value, @errorName(err),
+ });
+ };
continue;
} else if (mem.eql(u8, key, "--sort-common")) {
// this ignores --sort=common=<anything>; ignoring plain --sort-common
@@ -1698,7 +1709,9 @@ fn buildOutputType(
continue;
}
}
- if (mem.eql(u8, linker_arg, "--as-needed")) {
+ if (mem.eql(u8, linker_arg, "--build-id")) {
+ build_id = .fast;
+ } else if (mem.eql(u8, linker_arg, "--as-needed")) {
needed = false;
} else if (mem.eql(u8, linker_arg, "--no-as-needed")) {
needed = true;