authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-05-31 13:36:33-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-05-31 13:36:33-07:00
log59219e7e91cbfd785f89ec792d3950b9b9ad9b05
treea146eaef495f41dd8dd63ae259e576c75ce76de9
parentd09d61be979fc97233bd53d9d082a86e4dcd9779

stage2: add support for -fbuild-id,-fno-build-id

closes #3047

6 files changed, 48 insertions(+), 4 deletions(-)

build.zig+1
...@@ -145,6 +145,7 @@ pub fn build(b: *Builder) !void {...@@ -145,6 +145,7 @@ pub fn build(b: *Builder) !void {
145145
146 const exe = b.addExecutable("zig", main_file);146 const exe = b.addExecutable("zig", main_file);
147 exe.strip = strip;147 exe.strip = strip;
148 exe.build_id = !strip;
148 exe.install();149 exe.install();
149 exe.setBuildMode(mode);150 exe.setBuildMode(mode);
150 exe.setTarget(target);151 exe.setTarget(target);
lib/std/build.zig+14
...@@ -1549,6 +1549,12 @@ pub const LibExeObjStep = struct {...@@ -1549,6 +1549,12 @@ pub const LibExeObjStep = struct {
15491549
1550 valgrind_support: ?bool = null,1550 valgrind_support: ?bool = null,
1551 each_lib_rpath: ?bool = null,1551 each_lib_rpath: ?bool = null,
1552 /// On ELF targets, this will emit a link section called ".note.gnu.build-id"
1553 /// which can be used to coordinate a stripped binary with its debug symbols.
1554 /// As an example, the bloaty project refuses to work unless its inputs have
1555 /// build ids, in order to prevent accidental mismatches.
1556 /// The default is to not include this section because it slows down linking.
1557 build_id: ?bool = null,
15521558
1553 /// Create a .eh_frame_hdr section and a PT_GNU_EH_FRAME segment in the ELF1559 /// Create a .eh_frame_hdr section and a PT_GNU_EH_FRAME segment in the ELF
1554 /// file.1560 /// file.
...@@ -2953,6 +2959,14 @@ pub const LibExeObjStep = struct {...@@ -2953,6 +2959,14 @@ pub const LibExeObjStep = struct {
2953 }2959 }
2954 }2960 }
29552961
2962 if (self.build_id) |build_id| {
2963 if (build_id) {
2964 try zig_args.append("-fbuild-id");
2965 } else {
2966 try zig_args.append("-fno-build-id");
2967 }
2968 }
2969
2956 if (self.override_lib_dir) |dir| {2970 if (self.override_lib_dir) |dir| {
2957 try zig_args.append("--zig-lib-dir");2971 try zig_args.append("--zig-lib-dir");
2958 try zig_args.append(builder.pathFromRoot(dir));2972 try zig_args.append(builder.pathFromRoot(dir));
src/Compilation.zig+3
...@@ -756,6 +756,7 @@ pub const InitOptions = struct {...@@ -756,6 +756,7 @@ pub const InitOptions = struct {
756 linker_global_base: ?u64 = null,756 linker_global_base: ?u64 = null,
757 linker_export_symbol_names: []const []const u8 = &.{},757 linker_export_symbol_names: []const []const u8 = &.{},
758 each_lib_rpath: ?bool = null,758 each_lib_rpath: ?bool = null,
759 build_id: ?bool = null,
759 disable_c_depfile: bool = false,760 disable_c_depfile: bool = false,
760 linker_z_nodelete: bool = false,761 linker_z_nodelete: bool = false,
761 linker_z_notext: bool = false,762 linker_z_notext: bool = false,
...@@ -1639,6 +1640,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1639,6 +1640,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1639 .skip_linker_dependencies = options.skip_linker_dependencies,1640 .skip_linker_dependencies = options.skip_linker_dependencies,
1640 .parent_compilation_link_libc = options.parent_compilation_link_libc,1641 .parent_compilation_link_libc = options.parent_compilation_link_libc,
1641 .each_lib_rpath = options.each_lib_rpath orelse options.is_native_os,1642 .each_lib_rpath = options.each_lib_rpath orelse options.is_native_os,
1643 .build_id = options.build_id orelse false,
1642 .cache_mode = cache_mode,1644 .cache_mode = cache_mode,
1643 .disable_lld_caching = options.disable_lld_caching or cache_mode == .whole,1645 .disable_lld_caching = options.disable_lld_caching or cache_mode == .whole,
1644 .subsystem = options.subsystem,1646 .subsystem = options.subsystem,
...@@ -2339,6 +2341,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes...@@ -2339,6 +2341,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
2339 man.hash.addListOfBytes(comp.bin_file.options.lib_dirs);2341 man.hash.addListOfBytes(comp.bin_file.options.lib_dirs);
2340 man.hash.addListOfBytes(comp.bin_file.options.rpath_list);2342 man.hash.addListOfBytes(comp.bin_file.options.rpath_list);
2341 man.hash.add(comp.bin_file.options.each_lib_rpath);2343 man.hash.add(comp.bin_file.options.each_lib_rpath);
2344 man.hash.add(comp.bin_file.options.build_id);
2342 man.hash.add(comp.bin_file.options.skip_linker_dependencies);2345 man.hash.add(comp.bin_file.options.skip_linker_dependencies);
2343 man.hash.add(comp.bin_file.options.z_nodelete);2346 man.hash.add(comp.bin_file.options.z_nodelete);
2344 man.hash.add(comp.bin_file.options.z_notext);2347 man.hash.add(comp.bin_file.options.z_notext);
src/link.zig+1
...@@ -146,6 +146,7 @@ pub const Options = struct {...@@ -146,6 +146,7 @@ pub const Options = struct {
146 skip_linker_dependencies: bool,146 skip_linker_dependencies: bool,
147 parent_compilation_link_libc: bool,147 parent_compilation_link_libc: bool,
148 each_lib_rpath: bool,148 each_lib_rpath: bool,
149 build_id: bool,
149 disable_lld_caching: bool,150 disable_lld_caching: bool,
150 is_test: bool,151 is_test: bool,
151 use_stage1: bool,152 use_stage1: bool,
src/link/Elf.zig+8-1
...@@ -1311,7 +1311,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v...@@ -1311,7 +1311,6 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
1311 // We can skip hashing libc and libc++ components that we are in charge of building from Zig1311 // We can skip hashing libc and libc++ components that we are in charge of building from Zig
1312 // installation sources because they are always a product of the compiler version + target information.1312 // installation sources because they are always a product of the compiler version + target information.
1313 man.hash.addOptionalBytes(self.base.options.entry);1313 man.hash.addOptionalBytes(self.base.options.entry);
1314 man.hash.add(stack_size);
1315 man.hash.addOptional(self.base.options.image_base_override);1314 man.hash.addOptional(self.base.options.image_base_override);
1316 man.hash.add(gc_sections);1315 man.hash.add(gc_sections);
1317 man.hash.add(self.base.options.eh_frame_hdr);1316 man.hash.add(self.base.options.eh_frame_hdr);
...@@ -1320,6 +1319,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v...@@ -1320,6 +1319,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
1320 man.hash.addListOfBytes(self.base.options.lib_dirs);1319 man.hash.addListOfBytes(self.base.options.lib_dirs);
1321 man.hash.addListOfBytes(self.base.options.rpath_list);1320 man.hash.addListOfBytes(self.base.options.rpath_list);
1322 man.hash.add(self.base.options.each_lib_rpath);1321 man.hash.add(self.base.options.each_lib_rpath);
1322 if (self.base.options.output_mode == .Exe) {
1323 man.hash.add(stack_size);
1324 man.hash.add(self.base.options.build_id);
1325 }
1323 man.hash.add(self.base.options.skip_linker_dependencies);1326 man.hash.add(self.base.options.skip_linker_dependencies);
1324 man.hash.add(self.base.options.z_nodelete);1327 man.hash.add(self.base.options.z_nodelete);
1325 man.hash.add(self.base.options.z_notext);1328 man.hash.add(self.base.options.z_notext);
...@@ -1450,6 +1453,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v...@@ -1450,6 +1453,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
1450 if (self.base.options.output_mode == .Exe) {1453 if (self.base.options.output_mode == .Exe) {
1451 try argv.append("-z");1454 try argv.append("-z");
1452 try argv.append(try std.fmt.allocPrint(arena, "stack-size={d}", .{stack_size}));1455 try argv.append(try std.fmt.allocPrint(arena, "stack-size={d}", .{stack_size}));
1456
1457 if (self.base.options.build_id) {
1458 try argv.append("--build-id");
1459 }
1453 }1460 }
14541461
1455 if (self.base.options.image_base_override) |image_base| {1462 if (self.base.options.image_base_override) |image_base| {
src/main.zig+21-3
...@@ -423,6 +423,8 @@ const usage_build_generic =...@@ -423,6 +423,8 @@ const usage_build_generic =
423 \\ -fno-each-lib-rpath Prevent adding rpath for each used dynamic library423 \\ -fno-each-lib-rpath Prevent adding rpath for each used dynamic library
424 \\ -fallow-shlib-undefined Allows undefined symbols in shared libraries424 \\ -fallow-shlib-undefined Allows undefined symbols in shared libraries
425 \\ -fno-allow-shlib-undefined Disallows undefined symbols in shared libraries425 \\ -fno-allow-shlib-undefined Disallows undefined symbols in shared libraries
426 \\ -fbuild-id Helps coordinate stripped binaries with debug symbols
427 \\ -fno-build-id (default) Saves a bit of time linking
426 \\ --eh-frame-hdr Enable C++ exception handling by passing --eh-frame-hdr to linker428 \\ --eh-frame-hdr Enable C++ exception handling by passing --eh-frame-hdr to linker
427 \\ --emit-relocs Enable output of relocation sections for post build tools429 \\ --emit-relocs Enable output of relocation sections for post build tools
428 \\ -z [arg] Set linker extension flags430 \\ -z [arg] Set linker extension flags
...@@ -671,6 +673,7 @@ fn buildOutputType(...@@ -671,6 +673,7 @@ fn buildOutputType(
671 var link_eh_frame_hdr = false;673 var link_eh_frame_hdr = false;
672 var link_emit_relocs = false;674 var link_emit_relocs = false;
673 var each_lib_rpath: ?bool = null;675 var each_lib_rpath: ?bool = null;
676 var build_id: ?bool = null;
674 var sysroot: ?[]const u8 = null;677 var sysroot: ?[]const u8 = null;
675 var libc_paths_file: ?[]const u8 = try optionalStringEnvVar(arena, "ZIG_LIBC");678 var libc_paths_file: ?[]const u8 = try optionalStringEnvVar(arena, "ZIG_LIBC");
676 var machine_code_model: std.builtin.CodeModel = .default;679 var machine_code_model: std.builtin.CodeModel = .default;
...@@ -1030,6 +1033,10 @@ fn buildOutputType(...@@ -1030,6 +1033,10 @@ fn buildOutputType(
1030 each_lib_rpath = true;1033 each_lib_rpath = true;
1031 } else if (mem.eql(u8, arg, "-fno-each-lib-rpath")) {1034 } else if (mem.eql(u8, arg, "-fno-each-lib-rpath")) {
1032 each_lib_rpath = false;1035 each_lib_rpath = false;
1036 } else if (mem.eql(u8, arg, "-fbuild-id")) {
1037 build_id = true;
1038 } else if (mem.eql(u8, arg, "-fno-build-id")) {
1039 build_id = false;
1033 } else if (mem.eql(u8, arg, "--enable-cache")) {1040 } else if (mem.eql(u8, arg, "--enable-cache")) {
1034 enable_cache = true;1041 enable_cache = true;
1035 } else if (mem.eql(u8, arg, "--test-cmd-bin")) {1042 } else if (mem.eql(u8, arg, "--test-cmd-bin")) {
...@@ -1415,10 +1422,20 @@ fn buildOutputType(...@@ -1415,10 +1422,20 @@ fn buildOutputType(
1415 while (split_it.next()) |linker_arg| {1422 while (split_it.next()) |linker_arg| {
1416 // Handle nested-joined args like `-Wl,-rpath=foo`.1423 // Handle nested-joined args like `-Wl,-rpath=foo`.
1417 // Must be prefixed with 1 or 2 dashes.1424 // Must be prefixed with 1 or 2 dashes.
1418 if (linker_arg.len >= 3 and linker_arg[0] == '-' and linker_arg[2] != '-') {1425 if (linker_arg.len >= 3 and
1426 linker_arg[0] == '-' and
1427 linker_arg[2] != '-')
1428 {
1419 if (mem.indexOfScalar(u8, linker_arg, '=')) |equals_pos| {1429 if (mem.indexOfScalar(u8, linker_arg, '=')) |equals_pos| {
1420 try linker_args.append(linker_arg[0..equals_pos]);1430 const key = linker_arg[0..equals_pos];
1421 try linker_args.append(linker_arg[equals_pos + 1 ..]);1431 const value = linker_arg[equals_pos + 1 ..];
1432 if (mem.eql(u8, key, "build-id")) {
1433 build_id = true;
1434 warn("ignoring build-id style argument: '{s}'", .{value});
1435 continue;
1436 }
1437 try linker_args.append(key);
1438 try linker_args.append(value);
1422 continue;1439 continue;
1423 }1440 }
1424 }1441 }
...@@ -2727,6 +2744,7 @@ fn buildOutputType(...@@ -2727,6 +2744,7 @@ fn buildOutputType(
2727 .stack_report = stack_report,2744 .stack_report = stack_report,
2728 .is_test = arg_mode == .zig_test,2745 .is_test = arg_mode == .zig_test,
2729 .each_lib_rpath = each_lib_rpath,2746 .each_lib_rpath = each_lib_rpath,
2747 .build_id = build_id,
2730 .test_evented_io = test_evented_io,2748 .test_evented_io = test_evented_io,
2731 .test_filter = test_filter,2749 .test_filter = test_filter,
2732 .test_name_prefix = test_name_prefix,2750 .test_name_prefix = test_name_prefix,