| author | |
| committer | |
| log | 411e5099e5fb8a8e1b39e0bcd0098e7a2c162aec |
| tree | af62de07a424afd191244361f556ea1d9bc8944b |
| parent | c9601664c6914a8bdbf778f494a0a4fe6d84fa53 |
MappedFile: use opts struct for realign
Coff: fixup not reserving enough string capacity in loadObject7 files changed, 40 insertions(+), 38 deletions(-)
build.zig-3| ... | ... | @@ -256,7 +256,6 @@ pub fn build(b: *std.Build) !void { |
| 256 | 256 | const is_debug = optimize == .Debug; |
| 257 | 257 | const enable_debug_extensions = b.option(bool, "debug-extensions", "Enable commands and options useful for debugging the compiler") orelse is_debug; |
| 258 | 258 | const enable_logging = b.option(bool, "log", "Enable debug logging with --debug-log") orelse is_debug; |
| 259 | const enable_link_snapshots = b.option(bool, "link-snapshot", "Whether to enable linker state snapshots") orelse false; | |
| 260 | 259 | |
| 261 | 260 | const opt_version_string = b.option([]const u8, "version-string", "Override Zig version string. Default is to find out with git."); |
| 262 | 261 | const version_slice = if (opt_version_string) |version| version else v: { |
| ... | ... | @@ -372,7 +371,6 @@ pub fn build(b: *std.Build) !void { |
| 372 | 371 | |
| 373 | 372 | exe_options.addOption(bool, "enable_debug_extensions", enable_debug_extensions); |
| 374 | 373 | exe_options.addOption(bool, "enable_logging", enable_logging); |
| 375 | exe_options.addOption(bool, "enable_link_snapshots", enable_link_snapshots); | |
| 376 | 374 | exe_options.addOption(bool, "enable_tracy", tracy != null); |
| 377 | 375 | exe_options.addOption(bool, "enable_tracy_callstack", tracy_callstack); |
| 378 | 376 | exe_options.addOption(bool, "enable_tracy_allocation", tracy_allocation); |
| ... | ... | @@ -733,7 +731,6 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void { |
| 733 | 731 | exe_options.addOption(std.SemanticVersion, "semver", semver); |
| 734 | 732 | exe_options.addOption(bool, "enable_debug_extensions", false); |
| 735 | 733 | exe_options.addOption(bool, "enable_logging", false); |
| 736 | exe_options.addOption(bool, "enable_link_snapshots", false); | |
| 737 | 734 | exe_options.addOption(bool, "enable_tracy", false); |
| 738 | 735 | exe_options.addOption(bool, "enable_tracy_callstack", false); |
| 739 | 736 | exe_options.addOption(bool, "enable_tracy_allocation", false); |
src/crash_report.zig+5-8| ... | ... | @@ -132,14 +132,11 @@ fn dumpCrashContext() Io.Writer.Error!void { |
| 132 | 132 | try dumpCrashContextSema(anal, w, &S.crash_heap); |
| 133 | 133 | } else if (LinkerOp.current) |linker_op| { |
| 134 | 134 | try w.writeAll("Linker snapshot:\n"); |
| 135 | if (build_options.enable_link_snapshots) { | |
| 136 | switch (try linker_op.lf.dump(w, linker_op.tid)) { | |
| 137 | .unsupported => try w.writeAll("(backend does not support link snapshots)"), | |
| 138 | .disabled => try w.writeAll("(run with --debug-link-snapshot to dump linker state)"), | |
| 139 | .enabled => {}, | |
| 140 | } | |
| 141 | } else { | |
| 142 | try w.writeAll("(build with -Dlink-snapshot to dump linker state)"); | |
| 135 | switch (try linker_op.lf.dump(w, linker_op.tid)) { | |
| 136 | .unimplemented => try w.writeAll("(backend does not support link snapshots)"), | |
| 137 | .needs_extensions => try w.writeAll("(build with -Ddebug-extensions to dump linker state)"), | |
| 138 | .disabled => try w.writeAll("(run with --debug-link-snapshot to dump linker state)"), | |
| 139 | .enabled => {}, | |
| 143 | 140 | } |
| 144 | 141 | try w.writeAll("\n\n"); |
| 145 | 142 | } else { |
src/link.zig+4-3| ... | ... | @@ -1091,13 +1091,14 @@ pub const File = struct { |
| 1091 | 1091 | } |
| 1092 | 1092 | |
| 1093 | 1093 | pub const DumpResult = enum { |
| 1094 | unsupported, | |
| 1094 | unimplemented, | |
| 1095 | needs_extensions, | |
| 1095 | 1096 | disabled, |
| 1096 | 1097 | enabled, |
| 1097 | 1098 | }; |
| 1098 | 1099 | |
| 1099 | 1100 | pub fn dump(base: *File, w: *Io.Writer, tid: Zcu.PerThread.Id) !DumpResult { |
| 1100 | if (!build_options.enable_link_snapshots) unreachable; | |
| 1101 | if (!build_options.enable_debug_extensions) return .not_built; | |
| 1101 | 1102 | switch (base.tag) { |
| 1102 | 1103 | .elf, |
| 1103 | 1104 | .macho, |
| ... | ... | @@ -1106,7 +1107,7 @@ pub const File = struct { |
| 1106 | 1107 | .spirv, |
| 1107 | 1108 | .plan9, |
| 1108 | 1109 | .lld, |
| 1109 | => return .unsupported, | |
| 1110 | => return .unimplemented, | |
| 1110 | 1111 | inline else => |tag| { |
| 1111 | 1112 | dev.check(tag.devFeature()); |
| 1112 | 1113 | return @as(*tag.Type(), @fieldParentPtr("base", base)).dump(w, tid); |
src/link/Coff.zig+9-7| ... | ... | @@ -22,6 +22,7 @@ const implib = @import("../libs/mingw/implib.zig"); |
| 22 | 22 | const Path = std.Build.Cache.Path; |
| 23 | 23 | |
| 24 | 24 | base: link.File, |
| 25 | options: link.File.OpenOptions, | |
| 25 | 26 | mf: MappedFile, |
| 26 | 27 | nodes: std.MultiArrayList(Node), |
| 27 | 28 | members: std.ArrayList(Member), |
| ... | ... | @@ -82,7 +83,6 @@ synth_prog_node: std.Progress.Node, |
| 82 | 83 | symbol_prog_node: std.Progress.Node, |
| 83 | 84 | member_prog_node: std.Progress.Node, |
| 84 | 85 | input_prog_node: std.Progress.Node, |
| 85 | dump_snapshot: bool, | |
| 86 | 86 | |
| 87 | 87 | pub const default_file_alignment: u16 = 0x200; |
| 88 | 88 | pub const default_size_of_stack_reserve: u32 = 0x1000000; |
| ... | ... | @@ -1593,6 +1593,7 @@ fn create( |
| 1593 | 1593 | .allow_shlib_undefined = false, |
| 1594 | 1594 | .stack_size = 0, |
| 1595 | 1595 | }, |
| 1596 | .options = options, | |
| 1596 | 1597 | .mf = try .init(file, comp.gpa, io), |
| 1597 | 1598 | .nodes = .empty, |
| 1598 | 1599 | .members = .empty, |
| ... | ... | @@ -1664,7 +1665,6 @@ fn create( |
| 1664 | 1665 | .symbol_prog_node = .none, |
| 1665 | 1666 | .member_prog_node = .none, |
| 1666 | 1667 | .input_prog_node = .none, |
| 1667 | .dump_snapshot = options.enable_link_snapshots, | |
| 1668 | 1668 | }; |
| 1669 | 1669 | errdefer coff.deinit(); |
| 1670 | 1670 | |
| ... | ... | @@ -3579,13 +3579,13 @@ fn objectSectionMapIndex( |
| 3579 | 3579 | const parent_alignment = parent_ni.alignment(&coff.mf); |
| 3580 | 3580 | if (alignment.compare(.gt, parent_alignment)) { |
| 3581 | 3581 | log.debug("realignParent({s}, {d}) {d}->{d}", .{ name.toSlice(coff), parent_ni, parent_alignment, alignment }); |
| 3582 | try parent_ni.realign(&coff.mf, gpa, alignment, true); | |
| 3582 | try parent_ni.realign(&coff.mf, gpa, alignment, .{ .set_alignment = true }); | |
| 3583 | 3583 | } |
| 3584 | 3584 | |
| 3585 | 3585 | const old_alignment = sym.ni.alignment(&coff.mf); |
| 3586 | 3586 | if (alignment.compare(.gt, old_alignment)) { |
| 3587 | 3587 | log.debug("realignObject({s}) {d}->{d}", .{ name.toSlice(coff), old_alignment, alignment }); |
| 3588 | try sym.ni.realign(&coff.mf, gpa, alignment, true); | |
| 3588 | try sym.ni.realign(&coff.mf, gpa, alignment, .{ .set_alignment = true }); | |
| 3589 | 3589 | } |
| 3590 | 3590 | |
| 3591 | 3591 | try coff.verifyParentSectionAttributes( |
| ... | ... | @@ -3980,7 +3980,9 @@ fn loadObject( |
| 3980 | 3980 | |
| 3981 | 3981 | try coff.ensureManyUnusedStringCapacity( |
| 3982 | 3982 | header.number_of_sections + header.number_of_symbols, |
| 3983 | string_table_len - @sizeOf(u32), | |
| 3983 | header.number_of_sections * 9 + | |
| 3984 | header.number_of_symbols * 9 + | |
| 3985 | string_table_len - @sizeOf(u32), | |
| 3984 | 3986 | ); |
| 3985 | 3987 | |
| 3986 | 3988 | const PendingSymbolIndex = enum(u32) { |
| ... | ... | @@ -5886,7 +5888,7 @@ pub fn flush( |
| 5886 | 5888 | else => |e| return comp.link_diags.fail("flush write failed: {t}", .{e}), |
| 5887 | 5889 | }; |
| 5888 | 5890 | |
| 5889 | if (coff.dump_snapshot) | |
| 5891 | if (coff.options.enable_link_snapshots) | |
| 5890 | 5892 | coff.dumpStderr(tid) catch |err| |
| 5891 | 5893 | return comp.link_diags.fail("dumping link snapshot failed: {t}", .{err}); |
| 5892 | 5894 | } |
| ... | ... | @@ -7534,7 +7536,7 @@ fn dumpStderr(coff: *Coff, tid: Zcu.PerThread.Id) !void { |
| 7534 | 7536 | } |
| 7535 | 7537 | |
| 7536 | 7538 | pub fn dump(coff: *Coff, w: *Io.Writer, tid: Zcu.PerThread.Id) !link.File.DumpResult { |
| 7537 | if (coff.dump_snapshot) { | |
| 7539 | if (coff.options.enable_link_snapshots) { | |
| 7538 | 7540 | try coff.printNode(tid, w, .root, 0); |
| 7539 | 7541 | try w.writeAll("Section table:\n"); |
| 7540 | 7542 | for (coff.section_table.keys(), coff.section_table.values()) |name, sec| |
src/link/Elf2.zig+4-6| ... | ... | @@ -161,7 +161,6 @@ textrel_count: u32, |
| 161 | 161 | const_prog_node: std.Progress.Node, |
| 162 | 162 | synth_prog_node: std.Progress.Node, |
| 163 | 163 | input_prog_node: std.Progress.Node, |
| 164 | dump_snapshot: bool, | |
| 165 | 164 | |
| 166 | 165 | const Error = link.Error || error{MappedFileIo}; |
| 167 | 166 | |
| ... | ... | @@ -2625,7 +2624,6 @@ fn create( |
| 2625 | 2624 | .synth_prog_node = .none, |
| 2626 | 2625 | .input_prog_node = .none, |
| 2627 | 2626 | .textrel_count = 0, |
| 2628 | .dump_snapshot = options.enable_link_snapshots, | |
| 2629 | 2627 | }; |
| 2630 | 2628 | errdefer elf.deinit(); |
| 2631 | 2629 | |
| ... | ... | @@ -3787,7 +3785,7 @@ fn mapInputSection(elf: *Elf, opts: struct { |
| 3787 | 3785 | const new_alignment: std.mem.Alignment = .fromByteUnits( |
| 3788 | 3786 | std.math.ceilPowerOfTwoAssert(usize, @intCast(opts.addralign)), |
| 3789 | 3787 | ); |
| 3790 | try existing_shndx.get(elf).ni.realign(&elf.mf, gpa, new_alignment, true); | |
| 3788 | try existing_shndx.get(elf).ni.realign(&elf.mf, gpa, new_alignment, .{ .set_alignment = true }); | |
| 3791 | 3789 | } |
| 3792 | 3790 | // ...and update the shdr as needed. |
| 3793 | 3791 | switch (elf.shdrPtr(existing_shndx)) { |
| ... | ... | @@ -3950,7 +3948,7 @@ fn uavMapIndex( |
| 3950 | 3948 | } else { |
| 3951 | 3949 | const node = uav_gop.value_ptr.lsi.index().ptr(elf).node; |
| 3952 | 3950 | if (resolved_align.toStdMem().order(node.alignment(&elf.mf)).compare(.gt)) { |
| 3953 | try node.realign(&elf.mf, gpa, resolved_align.toStdMem(), true); | |
| 3951 | try node.realign(&elf.mf, gpa, resolved_align.toStdMem(), .{ .set_alignment = true }); | |
| 3954 | 3952 | } |
| 3955 | 3953 | } |
| 3956 | 3954 | return umi; |
| ... | ... | @@ -4679,7 +4677,7 @@ fn loadDso(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) (LoadPars |
| 4679 | 4677 | // We have a copy relocation for this global, but the amount of space we |
| 4680 | 4678 | // reserved for it could be too small or underaligned! |
| 4681 | 4679 | try copied_global.node.resize(&elf.mf, gpa, gop.value_ptr.size); |
| 4682 | try copied_global.node.realign(&elf.mf, gpa, gop.value_ptr.alignment, true); | |
| 4680 | try copied_global.node.realign(&elf.mf, gpa, gop.value_ptr.alignment, .{ .set_alignment = true }); | |
| 4683 | 4681 | const global_ptr = elf.globalByName(name).?; |
| 4684 | 4682 | switch (elf.symPtr(global_ptr.symtab_index)) { |
| 4685 | 4683 | inline else => |sym_ptr| elf.targetStore(&sym_ptr.size, @intCast(gop.value_ptr.size)), |
| ... | ... | @@ -6714,7 +6712,7 @@ pub fn deleteExport(elf: *Elf, exported: Zcu.Exported, name: InternPool.NullTerm |
| 6714 | 6712 | } |
| 6715 | 6713 | |
| 6716 | 6714 | pub fn dump(elf: *Elf, w: *Io.Writer, tid: Zcu.PerThread.Id) !link.File.DumpResult { |
| 6717 | if (elf.dump_snapshot) { | |
| 6715 | if (elf.options.enable_link_snapshots) { | |
| 6718 | 6716 | try elf.printNode(tid, w, .root, 0); |
| 6719 | 6717 | return .enabled; |
| 6720 | 6718 | } |
src/link/MappedFile.zig+16-9| ... | ... | @@ -354,18 +354,23 @@ pub const Node = extern struct { |
| 354 | 354 | } |
| 355 | 355 | } |
| 356 | 356 | |
| 357 | pub const RealignNodeOptions = struct { | |
| 358 | /// Shift the node backwards if possible | |
| 359 | try_backwards: bool = true, | |
| 360 | /// If `set, persists `new_alignment` as the node's alignment for future operations. | |
| 361 | set_alignment: bool = true, | |
| 362 | }; | |
| 363 | ||
| 357 | 364 | /// Moves and expands a node such that its offset and size are aligned to `new_alignment`. |
| 358 | /// If it is possible to move the node backwards, this will be done instead of moving it forward. | |
| 359 | /// If `set_alignment` is set, persists `new_alignment` as the node's alignment for future operations. | |
| 360 | 365 | /// Asserts that `ni` is not `Node.Index.root`. |
| 361 | 366 | pub fn realign( |
| 362 | 367 | ni: Node.Index, |
| 363 | 368 | mf: *MappedFile, |
| 364 | 369 | gpa: std.mem.Allocator, |
| 365 | 370 | new_alignment: std.mem.Alignment, |
| 366 | set_alignment: bool, | |
| 371 | opts: RealignNodeOptions, | |
| 367 | 372 | ) Error!void { |
| 368 | mf.realignNode(gpa, ni, new_alignment, true, set_alignment) catch |err| switch (err) { | |
| 373 | mf.realignNode(gpa, ni, new_alignment, opts) catch |err| switch (err) { | |
| 369 | 374 | error.OutOfMemory, |
| 370 | 375 | error.Canceled, |
| 371 | 376 | => |e| return e, |
| ... | ... | @@ -573,7 +578,10 @@ fn addNode(mf: *MappedFile, gpa: std.mem.Allocator, opts: struct { |
| 573 | 578 | else => |next_ni| { |
| 574 | 579 | const next_offset, _ = next_ni.location(mf).resolve(mf); |
| 575 | 580 | if (new_end > next_offset) |
| 576 | try next_ni.realign(mf, gpa, opts.add_node.alignment, false); | |
| 581 | try next_ni.realign(mf, gpa, opts.add_node.alignment, .{ | |
| 582 | .try_backwards = false, | |
| 583 | .set_alignment = false, | |
| 584 | }); | |
| 577 | 585 | }, |
| 578 | 586 | } |
| 579 | 587 | } |
| ... | ... | @@ -1035,8 +1043,7 @@ fn realignNode( |
| 1035 | 1043 | gpa: std.mem.Allocator, |
| 1036 | 1044 | ni: Node.Index, |
| 1037 | 1045 | new_alignment: std.mem.Alignment, |
| 1038 | try_backward: bool, | |
| 1039 | set_alignment: bool, | |
| 1046 | opts: Node.Index.RealignNodeOptions, | |
| 1040 | 1047 | ) (Allocator.Error || Io.Cancelable || IoError)!void { |
| 1041 | 1048 | assert(ni != Node.Index.root); // currently unsupported |
| 1042 | 1049 | mf.nodes_lock.assertUnlocked(); |
| ... | ... | @@ -1052,7 +1059,7 @@ fn realignNode( |
| 1052 | 1059 | node.flags.alignment = new_alignment; |
| 1053 | 1060 | defer { |
| 1054 | 1061 | // alignment needs to be temporarily set for the resizes below |
| 1055 | if (!set_alignment) node.flags.alignment = prev_alignment; | |
| 1062 | if (!opts.set_alignment) node.flags.alignment = prev_alignment; | |
| 1056 | 1063 | } |
| 1057 | 1064 | |
| 1058 | 1065 | const new_size = node.flags.alignment.forward(@intCast(size)); |
| ... | ... | @@ -1070,7 +1077,7 @@ fn realignNode( |
| 1070 | 1077 | }, |
| 1071 | 1078 | }; |
| 1072 | 1079 | |
| 1073 | if (try_backward) { | |
| 1080 | if (opts.try_backwards) { | |
| 1074 | 1081 | const backward_offset = new_alignment.backward(@intCast(old_offset)); |
| 1075 | 1082 | const prev_end = if (node.prev == .none) 0 else prev: { |
| 1076 | 1083 | const prev_offset, const prev_size = node.prev.location(mf).resolve(mf); |
src/main.zig+2-2| ... | ... | @@ -1440,8 +1440,8 @@ fn buildOutputType( |
| 1440 | 1440 | dev.check(.stdio_listen); |
| 1441 | 1441 | listen = .stdio; |
| 1442 | 1442 | } else if (mem.eql(u8, arg, "--debug-link-snapshot")) { |
| 1443 | if (!build_options.enable_link_snapshots) { | |
| 1444 | warn("Zig was compiled without linker snapshots enabled (-Dlink-snapshot). --debug-link-snapshot has no effect.", .{}); | |
| 1443 | if (!build_options.enable_debug_extensions) { | |
| 1444 | warn("Zig was compiled without debug extensions. --debug-link-snapshot has no effect.", .{}); | |
| 1445 | 1445 | } else { |
| 1446 | 1446 | enable_link_snapshots = true; |
| 1447 | 1447 | } |