| author | |
| committer | |
| log | cc931660eb3e5b7251944c727808aa36e72c1e52 |
| tree | c6564aff1d2e77163cfce1cd8e599a187ce9274a |
| parent | 2dc6ddd7e8cfb83f5ffd57b8b40f33dde9de892d |
15 files changed, 236 insertions(+), 250 deletions(-)
lib/std/Io/Writer.zig+1| ... | ... | @@ -2381,6 +2381,7 @@ pub fn fromArrayList(array_list: *ArrayList(u8)) Writer { |
| 2381 | 2381 | .vtable = &.{ |
| 2382 | 2382 | .drain = fixedDrain, |
| 2383 | 2383 | .flush = noopFlush, |
| 2384 | .rebase = failingRebase, | |
| 2384 | 2385 | }, |
| 2385 | 2386 | .buffer = array_list.allocatedSlice(), |
| 2386 | 2387 | .end = array_list.items.len, |
lib/std/macho.zig-2| ... | ... | @@ -1883,10 +1883,8 @@ pub const GenericBlob = extern struct { |
| 1883 | 1883 | pub const data_in_code_entry = extern struct { |
| 1884 | 1884 | /// From mach_header to start of data range. |
| 1885 | 1885 | offset: u32, |
| 1886 | ||
| 1887 | 1886 | /// Number of bytes in data range. |
| 1888 | 1887 | length: u16, |
| 1889 | ||
| 1890 | 1888 | /// A DICE_KIND value. |
| 1891 | 1889 | kind: u16, |
| 1892 | 1890 | }; |
src/link/MachO.zig+65-65| ... | ... | @@ -589,7 +589,7 @@ pub fn flush( |
| 589 | 589 | ); |
| 590 | 590 | |
| 591 | 591 | const ncmds, const sizeofcmds, const uuid_cmd_offset = self.writeLoadCommands() catch |err| switch (err) { |
| 592 | error.NoSpaceLeft => unreachable, | |
| 592 | error.WriteFailed => unreachable, | |
| 593 | 593 | error.OutOfMemory => return error.OutOfMemory, |
| 594 | 594 | error.LinkFailure => return error.LinkFailure, |
| 595 | 595 | }; |
| ... | ... | @@ -1074,7 +1074,7 @@ fn accessLibPath( |
| 1074 | 1074 | |
| 1075 | 1075 | for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| { |
| 1076 | 1076 | test_path.clearRetainingCapacity(); |
| 1077 | try test_path.writer().print("{s}" ++ sep ++ "lib{s}{s}", .{ search_dir, name, ext }); | |
| 1077 | try test_path.print("{s}" ++ sep ++ "lib{s}{s}", .{ search_dir, name, ext }); | |
| 1078 | 1078 | try checked_paths.append(try arena.dupe(u8, test_path.items)); |
| 1079 | 1079 | fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { |
| 1080 | 1080 | error.FileNotFound => continue, |
| ... | ... | @@ -1097,7 +1097,7 @@ fn accessFrameworkPath( |
| 1097 | 1097 | |
| 1098 | 1098 | for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| { |
| 1099 | 1099 | test_path.clearRetainingCapacity(); |
| 1100 | try test_path.writer().print("{s}" ++ sep ++ "{s}.framework" ++ sep ++ "{s}{s}", .{ | |
| 1100 | try test_path.print("{s}" ++ sep ++ "{s}.framework" ++ sep ++ "{s}{s}", .{ | |
| 1101 | 1101 | search_dir, |
| 1102 | 1102 | name, |
| 1103 | 1103 | name, |
| ... | ... | @@ -1178,9 +1178,9 @@ fn parseDependentDylibs(self: *MachO) !void { |
| 1178 | 1178 | for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| { |
| 1179 | 1179 | test_path.clearRetainingCapacity(); |
| 1180 | 1180 | if (self.base.comp.sysroot) |root| { |
| 1181 | try test_path.writer().print("{s}" ++ fs.path.sep_str ++ "{s}{s}", .{ root, path, ext }); | |
| 1181 | try test_path.print("{s}" ++ fs.path.sep_str ++ "{s}{s}", .{ root, path, ext }); | |
| 1182 | 1182 | } else { |
| 1183 | try test_path.writer().print("{s}{s}", .{ path, ext }); | |
| 1183 | try test_path.print("{s}{s}", .{ path, ext }); | |
| 1184 | 1184 | } |
| 1185 | 1185 | try checked_paths.append(try arena.dupe(u8, test_path.items)); |
| 1186 | 1186 | fs.cwd().access(test_path.items, .{}) catch |err| switch (err) { |
| ... | ... | @@ -2528,8 +2528,8 @@ fn writeThunkWorker(self: *MachO, thunk: Thunk) void { |
| 2528 | 2528 | fn doWork(th: Thunk, buffer: []u8, macho_file: *MachO) !void { |
| 2529 | 2529 | const off = try macho_file.cast(usize, th.value); |
| 2530 | 2530 | const size = th.size(); |
| 2531 | var stream = std.io.fixedBufferStream(buffer[off..][0..size]); | |
| 2532 | try th.write(macho_file, stream.writer()); | |
| 2531 | var stream: Writer = .fixed(buffer[off..][0..size]); | |
| 2532 | try th.write(macho_file, &stream); | |
| 2533 | 2533 | } |
| 2534 | 2534 | }.doWork; |
| 2535 | 2535 | const out = self.sections.items(.out)[thunk.out_n_sect].items; |
| ... | ... | @@ -2556,15 +2556,15 @@ fn writeSyntheticSectionWorker(self: *MachO, sect_id: u8, out: []u8) void { |
| 2556 | 2556 | |
| 2557 | 2557 | const doWork = struct { |
| 2558 | 2558 | fn doWork(macho_file: *MachO, tag: Tag, buffer: []u8) !void { |
| 2559 | var stream = std.io.fixedBufferStream(buffer); | |
| 2559 | var stream: Writer = .fixed(buffer); | |
| 2560 | 2560 | switch (tag) { |
| 2561 | 2561 | .eh_frame => eh_frame.write(macho_file, buffer), |
| 2562 | 2562 | .unwind_info => try macho_file.unwind_info.write(macho_file, buffer), |
| 2563 | .got => try macho_file.got.write(macho_file, stream.writer()), | |
| 2564 | .stubs => try macho_file.stubs.write(macho_file, stream.writer()), | |
| 2565 | .la_symbol_ptr => try macho_file.la_symbol_ptr.write(macho_file, stream.writer()), | |
| 2566 | .tlv_ptr => try macho_file.tlv_ptr.write(macho_file, stream.writer()), | |
| 2567 | .objc_stubs => try macho_file.objc_stubs.write(macho_file, stream.writer()), | |
| 2563 | .got => try macho_file.got.write(macho_file, &stream), | |
| 2564 | .stubs => try macho_file.stubs.write(macho_file, &stream), | |
| 2565 | .la_symbol_ptr => try macho_file.la_symbol_ptr.write(macho_file, &stream), | |
| 2566 | .tlv_ptr => try macho_file.tlv_ptr.write(macho_file, &stream), | |
| 2567 | .objc_stubs => try macho_file.objc_stubs.write(macho_file, &stream), | |
| 2568 | 2568 | } |
| 2569 | 2569 | } |
| 2570 | 2570 | }.doWork; |
| ... | ... | @@ -2605,8 +2605,8 @@ fn updateLazyBindSizeWorker(self: *MachO) void { |
| 2605 | 2605 | try macho_file.lazy_bind_section.updateSize(macho_file); |
| 2606 | 2606 | const sect_id = macho_file.stubs_helper_sect_index.?; |
| 2607 | 2607 | const out = &macho_file.sections.items(.out)[sect_id]; |
| 2608 | var stream = std.io.fixedBufferStream(out.items); | |
| 2609 | try macho_file.stubs_helper.write(macho_file, stream.writer()); | |
| 2608 | var stream: Writer = .fixed(out.items); | |
| 2609 | try macho_file.stubs_helper.write(macho_file, &stream); | |
| 2610 | 2610 | } |
| 2611 | 2611 | }.doWork; |
| 2612 | 2612 | doWork(self) catch |err| |
| ... | ... | @@ -2669,18 +2669,17 @@ fn writeDyldInfo(self: *MachO) !void { |
| 2669 | 2669 | defer gpa.free(buffer); |
| 2670 | 2670 | @memset(buffer, 0); |
| 2671 | 2671 | |
| 2672 | var stream = std.io.fixedBufferStream(buffer); | |
| 2673 | const writer = stream.writer(); | |
| 2674 | ||
| 2675 | try self.rebase_section.write(writer); | |
| 2676 | try stream.seekTo(cmd.bind_off - base_off); | |
| 2677 | try self.bind_section.write(writer); | |
| 2678 | try stream.seekTo(cmd.weak_bind_off - base_off); | |
| 2679 | try self.weak_bind_section.write(writer); | |
| 2680 | try stream.seekTo(cmd.lazy_bind_off - base_off); | |
| 2681 | try self.lazy_bind_section.write(writer); | |
| 2682 | try stream.seekTo(cmd.export_off - base_off); | |
| 2683 | try self.export_trie.write(writer); | |
| 2672 | var writer: Writer = .fixed(buffer); | |
| 2673 | ||
| 2674 | try self.rebase_section.write(&writer); | |
| 2675 | writer.end = cmd.bind_off - base_off; | |
| 2676 | try self.bind_section.write(&writer); | |
| 2677 | writer.end = cmd.weak_bind_off - base_off; | |
| 2678 | try self.weak_bind_section.write(&writer); | |
| 2679 | writer.end = cmd.lazy_bind_off - base_off; | |
| 2680 | try self.lazy_bind_section.write(&writer); | |
| 2681 | writer.end = cmd.export_off - base_off; | |
| 2682 | try self.export_trie.write(&writer); | |
| 2684 | 2683 | try self.pwriteAll(buffer, cmd.rebase_off); |
| 2685 | 2684 | } |
| 2686 | 2685 | |
| ... | ... | @@ -2689,10 +2688,10 @@ pub fn writeDataInCode(self: *MachO) !void { |
| 2689 | 2688 | defer tracy.end(); |
| 2690 | 2689 | const gpa = self.base.comp.gpa; |
| 2691 | 2690 | const cmd = self.data_in_code_cmd; |
| 2692 | var buffer = try std.array_list.Managed(u8).initCapacity(gpa, self.data_in_code.size()); | |
| 2691 | var buffer = try std.Io.Writer.Allocating.initCapacity(gpa, self.data_in_code.size()); | |
| 2693 | 2692 | defer buffer.deinit(); |
| 2694 | try self.data_in_code.write(self, buffer.writer()); | |
| 2695 | try self.pwriteAll(buffer.items, cmd.dataoff); | |
| 2693 | self.data_in_code.write(self, &buffer.writer) catch return error.OutOfMemory; | |
| 2694 | try self.pwriteAll(buffer.written(), cmd.dataoff); | |
| 2696 | 2695 | } |
| 2697 | 2696 | |
| 2698 | 2697 | fn writeIndsymtab(self: *MachO) !void { |
| ... | ... | @@ -2701,10 +2700,11 @@ fn writeIndsymtab(self: *MachO) !void { |
| 2701 | 2700 | const gpa = self.base.comp.gpa; |
| 2702 | 2701 | const cmd = self.dysymtab_cmd; |
| 2703 | 2702 | const needed_size = cmd.nindirectsyms * @sizeOf(u32); |
| 2704 | var buffer = try std.array_list.Managed(u8).initCapacity(gpa, needed_size); | |
| 2705 | defer buffer.deinit(); | |
| 2706 | try self.indsymtab.write(self, buffer.writer()); | |
| 2707 | try self.pwriteAll(buffer.items, cmd.indirectsymoff); | |
| 2703 | const buffer = try gpa.alloc(u8, needed_size); | |
| 2704 | defer gpa.free(buffer); | |
| 2705 | var writer: Writer = .fixed(buffer); | |
| 2706 | try self.indsymtab.write(self, &writer); | |
| 2707 | try self.pwriteAll(buffer, cmd.indirectsymoff); | |
| 2708 | 2708 | } |
| 2709 | 2709 | |
| 2710 | 2710 | pub fn writeSymtabToFile(self: *MachO) !void { |
| ... | ... | @@ -2821,8 +2821,7 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { |
| 2821 | 2821 | const buffer = try gpa.alloc(u8, needed_size); |
| 2822 | 2822 | defer gpa.free(buffer); |
| 2823 | 2823 | |
| 2824 | var stream = std.io.fixedBufferStream(buffer); | |
| 2825 | const writer = stream.writer(); | |
| 2824 | var writer: Writer = .fixed(buffer); | |
| 2826 | 2825 | |
| 2827 | 2826 | var ncmds: usize = 0; |
| 2828 | 2827 | |
| ... | ... | @@ -2831,26 +2830,26 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { |
| 2831 | 2830 | const slice = self.sections.slice(); |
| 2832 | 2831 | var sect_id: usize = 0; |
| 2833 | 2832 | for (self.segments.items) |seg| { |
| 2834 | try writer.writeStruct(seg); | |
| 2833 | try writer.writeStruct(seg, .little); | |
| 2835 | 2834 | for (slice.items(.header)[sect_id..][0..seg.nsects]) |header| { |
| 2836 | try writer.writeStruct(header); | |
| 2835 | try writer.writeStruct(header, .little); | |
| 2837 | 2836 | } |
| 2838 | 2837 | sect_id += seg.nsects; |
| 2839 | 2838 | } |
| 2840 | 2839 | ncmds += self.segments.items.len; |
| 2841 | 2840 | } |
| 2842 | 2841 | |
| 2843 | try writer.writeStruct(self.dyld_info_cmd); | |
| 2842 | try writer.writeStruct(self.dyld_info_cmd, .little); | |
| 2844 | 2843 | ncmds += 1; |
| 2845 | try writer.writeStruct(self.function_starts_cmd); | |
| 2844 | try writer.writeStruct(self.function_starts_cmd, .little); | |
| 2846 | 2845 | ncmds += 1; |
| 2847 | try writer.writeStruct(self.data_in_code_cmd); | |
| 2846 | try writer.writeStruct(self.data_in_code_cmd, .little); | |
| 2848 | 2847 | ncmds += 1; |
| 2849 | try writer.writeStruct(self.symtab_cmd); | |
| 2848 | try writer.writeStruct(self.symtab_cmd, .little); | |
| 2850 | 2849 | ncmds += 1; |
| 2851 | try writer.writeStruct(self.dysymtab_cmd); | |
| 2850 | try writer.writeStruct(self.dysymtab_cmd, .little); | |
| 2852 | 2851 | ncmds += 1; |
| 2853 | try load_commands.writeDylinkerLC(writer); | |
| 2852 | try load_commands.writeDylinkerLC(&writer); | |
| 2854 | 2853 | ncmds += 1; |
| 2855 | 2854 | |
| 2856 | 2855 | if (self.getInternalObject()) |obj| { |
| ... | ... | @@ -2861,44 +2860,44 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { |
| 2861 | 2860 | 0 |
| 2862 | 2861 | else |
| 2863 | 2862 | @as(u32, @intCast(sym.getAddress(.{ .stubs = true }, self) - seg.vmaddr)); |
| 2864 | try writer.writeStruct(macho.entry_point_command{ | |
| 2863 | try writer.writeStruct(@as(macho.entry_point_command, .{ | |
| 2865 | 2864 | .entryoff = entryoff, |
| 2866 | 2865 | .stacksize = self.base.stack_size, |
| 2867 | }); | |
| 2866 | }), .little); | |
| 2868 | 2867 | ncmds += 1; |
| 2869 | 2868 | } |
| 2870 | 2869 | } |
| 2871 | 2870 | |
| 2872 | 2871 | if (self.base.isDynLib()) { |
| 2873 | try load_commands.writeDylibIdLC(self, writer); | |
| 2872 | try load_commands.writeDylibIdLC(self, &writer); | |
| 2874 | 2873 | ncmds += 1; |
| 2875 | 2874 | } |
| 2876 | 2875 | |
| 2877 | 2876 | for (self.rpath_list) |rpath| { |
| 2878 | try load_commands.writeRpathLC(rpath, writer); | |
| 2877 | try load_commands.writeRpathLC(rpath, &writer); | |
| 2879 | 2878 | ncmds += 1; |
| 2880 | 2879 | } |
| 2881 | 2880 | if (comp.config.any_sanitize_thread) { |
| 2882 | 2881 | const path = try comp.tsan_lib.?.full_object_path.toString(gpa); |
| 2883 | 2882 | defer gpa.free(path); |
| 2884 | 2883 | const rpath = std.fs.path.dirname(path) orelse "."; |
| 2885 | try load_commands.writeRpathLC(rpath, writer); | |
| 2884 | try load_commands.writeRpathLC(rpath, &writer); | |
| 2886 | 2885 | ncmds += 1; |
| 2887 | 2886 | } |
| 2888 | 2887 | |
| 2889 | try writer.writeStruct(macho.source_version_command{ .version = 0 }); | |
| 2888 | try writer.writeStruct(@as(macho.source_version_command, .{ .version = 0 }), .little); | |
| 2890 | 2889 | ncmds += 1; |
| 2891 | 2890 | |
| 2892 | 2891 | if (self.platform.isBuildVersionCompatible()) { |
| 2893 | try load_commands.writeBuildVersionLC(self.platform, self.sdk_version, writer); | |
| 2892 | try load_commands.writeBuildVersionLC(self.platform, self.sdk_version, &writer); | |
| 2894 | 2893 | ncmds += 1; |
| 2895 | 2894 | } else { |
| 2896 | try load_commands.writeVersionMinLC(self.platform, self.sdk_version, writer); | |
| 2895 | try load_commands.writeVersionMinLC(self.platform, self.sdk_version, &writer); | |
| 2897 | 2896 | ncmds += 1; |
| 2898 | 2897 | } |
| 2899 | 2898 | |
| 2900 | const uuid_cmd_offset = @sizeOf(macho.mach_header_64) + stream.pos; | |
| 2901 | try writer.writeStruct(self.uuid_cmd); | |
| 2899 | const uuid_cmd_offset = @sizeOf(macho.mach_header_64) + writer.end; | |
| 2900 | try writer.writeStruct(self.uuid_cmd, .little); | |
| 2902 | 2901 | ncmds += 1; |
| 2903 | 2902 | |
| 2904 | 2903 | for (self.dylibs.items) |index| { |
| ... | ... | @@ -2916,16 +2915,16 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { |
| 2916 | 2915 | .timestamp = dylib_id.timestamp, |
| 2917 | 2916 | .current_version = dylib_id.current_version, |
| 2918 | 2917 | .compatibility_version = dylib_id.compatibility_version, |
| 2919 | }, writer); | |
| 2918 | }, &writer); | |
| 2920 | 2919 | ncmds += 1; |
| 2921 | 2920 | } |
| 2922 | 2921 | |
| 2923 | 2922 | if (self.requiresCodeSig()) { |
| 2924 | try writer.writeStruct(self.codesig_cmd); | |
| 2923 | try writer.writeStruct(self.codesig_cmd, .little); | |
| 2925 | 2924 | ncmds += 1; |
| 2926 | 2925 | } |
| 2927 | 2926 | |
| 2928 | assert(stream.pos == needed_size); | |
| 2927 | assert(writer.end == needed_size); | |
| 2929 | 2928 | |
| 2930 | 2929 | try self.pwriteAll(buffer, @sizeOf(macho.mach_header_64)); |
| 2931 | 2930 | |
| ... | ... | @@ -3014,25 +3013,26 @@ pub fn writeCodeSignaturePadding(self: *MachO, code_sig: *CodeSignature) !void { |
| 3014 | 3013 | pub fn writeCodeSignature(self: *MachO, code_sig: *CodeSignature) !void { |
| 3015 | 3014 | const seg = self.getTextSegment(); |
| 3016 | 3015 | const offset = self.codesig_cmd.dataoff; |
| 3016 | const gpa = self.base.comp.gpa; | |
| 3017 | 3017 | |
| 3018 | var buffer = std.array_list.Managed(u8).init(self.base.comp.gpa); | |
| 3019 | defer buffer.deinit(); | |
| 3020 | try buffer.ensureTotalCapacityPrecise(code_sig.size()); | |
| 3018 | const buffer = try gpa.alloc(u8, code_sig.size()); | |
| 3019 | defer gpa.free(buffer); | |
| 3020 | var writer: Writer = .fixed(buffer); | |
| 3021 | 3021 | try code_sig.writeAdhocSignature(self, .{ |
| 3022 | 3022 | .file = self.base.file.?, |
| 3023 | 3023 | .exec_seg_base = seg.fileoff, |
| 3024 | 3024 | .exec_seg_limit = seg.filesize, |
| 3025 | 3025 | .file_size = offset, |
| 3026 | 3026 | .dylib = self.base.isDynLib(), |
| 3027 | }, buffer.writer()); | |
| 3028 | assert(buffer.items.len == code_sig.size()); | |
| 3027 | }, &writer); | |
| 3028 | assert(writer.buffered().len == code_sig.size()); | |
| 3029 | 3029 | |
| 3030 | 3030 | log.debug("writing code signature from 0x{x} to 0x{x}", .{ |
| 3031 | 3031 | offset, |
| 3032 | offset + buffer.items.len, | |
| 3032 | offset + writer.buffered().len, | |
| 3033 | 3033 | }); |
| 3034 | 3034 | |
| 3035 | try self.pwriteAll(buffer.items, offset); | |
| 3035 | try self.pwriteAll(writer.buffered(), offset); | |
| 3036 | 3036 | } |
| 3037 | 3037 | |
| 3038 | 3038 | pub fn updateFunc( |
| ... | ... | @@ -5372,7 +5372,7 @@ const macho = std.macho; |
| 5372 | 5372 | const math = std.math; |
| 5373 | 5373 | const mem = std.mem; |
| 5374 | 5374 | const meta = std.meta; |
| 5375 | const Writer = std.io.Writer; | |
| 5375 | const Writer = std.Io.Writer; | |
| 5376 | 5376 | |
| 5377 | 5377 | const aarch64 = codegen.aarch64.encoding; |
| 5378 | 5378 | const bind = @import("MachO/dyld_info/bind.zig"); |
src/link/MachO/Archive.zig+18-38| ... | ... | @@ -81,34 +81,20 @@ pub fn writeHeader( |
| 81 | 81 | object_name: []const u8, |
| 82 | 82 | object_size: usize, |
| 83 | 83 | format: Format, |
| 84 | writer: anytype, | |
| 84 | writer: *Writer, | |
| 85 | 85 | ) !void { |
| 86 | var hdr: ar_hdr = .{ | |
| 87 | .ar_name = undefined, | |
| 88 | .ar_date = undefined, | |
| 89 | .ar_uid = undefined, | |
| 90 | .ar_gid = undefined, | |
| 91 | .ar_mode = undefined, | |
| 92 | .ar_size = undefined, | |
| 93 | .ar_fmag = undefined, | |
| 94 | }; | |
| 95 | @memset(mem.asBytes(&hdr), 0x20); | |
| 96 | inline for (@typeInfo(ar_hdr).@"struct".fields) |field| { | |
| 97 | var stream = std.io.fixedBufferStream(&@field(hdr, field.name)); | |
| 98 | stream.writer().print("0", .{}) catch unreachable; | |
| 99 | } | |
| 100 | @memcpy(&hdr.ar_fmag, ARFMAG); | |
| 86 | var hdr: ar_hdr = .{}; | |
| 101 | 87 | |
| 102 | 88 | const object_name_len = mem.alignForward(usize, object_name.len + 1, ptrWidth(format)); |
| 103 | 89 | const total_object_size = object_size + object_name_len; |
| 104 | 90 | |
| 105 | 91 | { |
| 106 | var stream = std.io.fixedBufferStream(&hdr.ar_name); | |
| 107 | stream.writer().print("#1/{d}", .{object_name_len}) catch unreachable; | |
| 92 | var stream: Writer = .fixed(&hdr.ar_name); | |
| 93 | stream.print("#1/{d}", .{object_name_len}) catch unreachable; | |
| 108 | 94 | } |
| 109 | 95 | { |
| 110 | var stream = std.io.fixedBufferStream(&hdr.ar_size); | |
| 111 | stream.writer().print("{d}", .{total_object_size}) catch unreachable; | |
| 96 | var stream: Writer = .fixed(&hdr.ar_size); | |
| 97 | stream.print("{d}", .{total_object_size}) catch unreachable; | |
| 112 | 98 | } |
| 113 | 99 | |
| 114 | 100 | try writer.writeAll(mem.asBytes(&hdr)); |
| ... | ... | @@ -116,7 +102,7 @@ pub fn writeHeader( |
| 116 | 102 | |
| 117 | 103 | const padding = object_name_len - object_name.len - 1; |
| 118 | 104 | if (padding > 0) { |
| 119 | try writer.writeByteNTimes(0, padding); | |
| 105 | try writer.splatByteAll(0, padding); | |
| 120 | 106 | } |
| 121 | 107 | } |
| 122 | 108 | |
| ... | ... | @@ -138,25 +124,19 @@ pub const SYMDEF64_SORTED = "__.SYMDEF_64 SORTED"; |
| 138 | 124 | |
| 139 | 125 | pub const ar_hdr = extern struct { |
| 140 | 126 | /// Member file name, sometimes / terminated. |
| 141 | ar_name: [16]u8, | |
| 142 | ||
| 127 | ar_name: [16]u8 = "0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20".*, | |
| 143 | 128 | /// File date, decimal seconds since Epoch. |
| 144 | ar_date: [12]u8, | |
| 145 | ||
| 129 | ar_date: [12]u8 = "0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20".*, | |
| 146 | 130 | /// User ID, in ASCII format. |
| 147 | ar_uid: [6]u8, | |
| 148 | ||
| 131 | ar_uid: [6]u8 = "0\x20\x20\x20\x20\x20".*, | |
| 149 | 132 | /// Group ID, in ASCII format. |
| 150 | ar_gid: [6]u8, | |
| 151 | ||
| 133 | ar_gid: [6]u8 = "0\x20\x20\x20\x20\x20".*, | |
| 152 | 134 | /// File mode, in ASCII octal. |
| 153 | ar_mode: [8]u8, | |
| 154 | ||
| 135 | ar_mode: [8]u8 = "0\x20\x20\x20\x20\x20\x20\x20".*, | |
| 155 | 136 | /// File size, in ASCII decimal. |
| 156 | ar_size: [10]u8, | |
| 157 | ||
| 137 | ar_size: [10]u8 = "0\x20\x20\x20\x20\x20\x20\x20\x20\x20".*, | |
| 158 | 138 | /// Always contains ARFMAG. |
| 159 | ar_fmag: [2]u8, | |
| 139 | ar_fmag: [2]u8 = ARFMAG.*, | |
| 160 | 140 | |
| 161 | 141 | fn date(self: ar_hdr) !u64 { |
| 162 | 142 | const value = mem.trimEnd(u8, &self.ar_date, &[_]u8{@as(u8, 0x20)}); |
| ... | ... | @@ -201,7 +181,7 @@ pub const ArSymtab = struct { |
| 201 | 181 | return ptr_width + ar.entries.items.len * 2 * ptr_width + ptr_width + mem.alignForward(usize, ar.strtab.buffer.items.len, ptr_width); |
| 202 | 182 | } |
| 203 | 183 | |
| 204 | pub fn write(ar: ArSymtab, format: Format, macho_file: *MachO, writer: anytype) !void { | |
| 184 | pub fn write(ar: ArSymtab, format: Format, macho_file: *MachO, writer: *Writer) !void { | |
| 205 | 185 | const ptr_width = ptrWidth(format); |
| 206 | 186 | // Header |
| 207 | 187 | try writeHeader(SYMDEF, ar.size(format), format, writer); |
| ... | ... | @@ -226,7 +206,7 @@ pub const ArSymtab = struct { |
| 226 | 206 | // Strtab |
| 227 | 207 | try writer.writeAll(ar.strtab.buffer.items); |
| 228 | 208 | if (padding > 0) { |
| 229 | try writer.writeByteNTimes(0, padding); | |
| 209 | try writer.splatByteAll(0, padding); | |
| 230 | 210 | } |
| 231 | 211 | } |
| 232 | 212 | |
| ... | ... | @@ -275,7 +255,7 @@ pub fn ptrWidth(format: Format) usize { |
| 275 | 255 | }; |
| 276 | 256 | } |
| 277 | 257 | |
| 278 | pub fn writeInt(format: Format, value: u64, writer: anytype) !void { | |
| 258 | pub fn writeInt(format: Format, value: u64, writer: *Writer) !void { | |
| 279 | 259 | switch (format) { |
| 280 | 260 | .p32 => try writer.writeInt(u32, std.math.cast(u32, value) orelse return error.Overflow, .little), |
| 281 | 261 | .p64 => try writer.writeInt(u64, value, .little), |
| ... | ... | @@ -299,7 +279,7 @@ const mem = std.mem; |
| 299 | 279 | const std = @import("std"); |
| 300 | 280 | const Allocator = std.mem.Allocator; |
| 301 | 281 | const Path = std.Build.Cache.Path; |
| 302 | const Writer = std.io.Writer; | |
| 282 | const Writer = std.Io.Writer; | |
| 303 | 283 | |
| 304 | 284 | const Archive = @This(); |
| 305 | 285 | const File = @import("file.zig").File; |
src/link/MachO/Atom.zig+6-5| ... | ... | @@ -581,7 +581,7 @@ pub fn resolveRelocs(self: Atom, macho_file: *MachO, buffer: []u8) !void { |
| 581 | 581 | relocs_log.debug("{x}: {s}", .{ self.value, name }); |
| 582 | 582 | |
| 583 | 583 | var has_error = false; |
| 584 | var stream = std.io.fixedBufferStream(buffer); | |
| 584 | var stream: Writer = .fixed(buffer); | |
| 585 | 585 | var i: usize = 0; |
| 586 | 586 | while (i < relocs.len) : (i += 1) { |
| 587 | 587 | const rel = relocs[i]; |
| ... | ... | @@ -592,8 +592,8 @@ pub fn resolveRelocs(self: Atom, macho_file: *MachO, buffer: []u8) !void { |
| 592 | 592 | if (rel.getTargetSymbol(self, macho_file).getFile(macho_file) == null) continue; |
| 593 | 593 | } |
| 594 | 594 | |
| 595 | try stream.seekTo(rel_offset); | |
| 596 | self.resolveRelocInner(rel, subtractor, buffer, macho_file, stream.writer()) catch |err| { | |
| 595 | stream.end = rel_offset; | |
| 596 | self.resolveRelocInner(rel, subtractor, buffer, macho_file, &stream) catch |err| { | |
| 597 | 597 | switch (err) { |
| 598 | 598 | error.RelaxFail => { |
| 599 | 599 | const target = switch (rel.tag) { |
| ... | ... | @@ -630,6 +630,7 @@ const ResolveError = error{ |
| 630 | 630 | UnexpectedRemainder, |
| 631 | 631 | Overflow, |
| 632 | 632 | OutOfMemory, |
| 633 | WriteFailed, | |
| 633 | 634 | }; |
| 634 | 635 | |
| 635 | 636 | fn resolveRelocInner( |
| ... | ... | @@ -638,7 +639,7 @@ fn resolveRelocInner( |
| 638 | 639 | subtractor: ?Relocation, |
| 639 | 640 | code: []u8, |
| 640 | 641 | macho_file: *MachO, |
| 641 | writer: anytype, | |
| 642 | writer: *Writer, | |
| 642 | 643 | ) ResolveError!void { |
| 643 | 644 | const t = &macho_file.base.comp.root_mod.resolved_target.result; |
| 644 | 645 | const cpu_arch = t.cpu.arch; |
| ... | ... | @@ -1147,7 +1148,7 @@ const math = std.math; |
| 1147 | 1148 | const mem = std.mem; |
| 1148 | 1149 | const log = std.log.scoped(.link); |
| 1149 | 1150 | const relocs_log = std.log.scoped(.link_relocs); |
| 1150 | const Writer = std.io.Writer; | |
| 1151 | const Writer = std.Io.Writer; | |
| 1151 | 1152 | const Allocator = mem.Allocator; |
| 1152 | 1153 | const AtomicBool = std.atomic.Value(bool); |
| 1153 | 1154 |
src/link/MachO/CodeSignature.zig+8-8| ... | ... | @@ -304,10 +304,10 @@ pub fn writeAdhocSignature( |
| 304 | 304 | var hash: [hash_size]u8 = undefined; |
| 305 | 305 | |
| 306 | 306 | if (self.requirements) |*req| { |
| 307 | var buf = std.array_list.Managed(u8).init(allocator); | |
| 308 | defer buf.deinit(); | |
| 309 | try req.write(buf.writer()); | |
| 310 | Sha256.hash(buf.items, &hash, .{}); | |
| 307 | var a: std.Io.Writer.Allocating = .init(allocator); | |
| 308 | defer a.deinit(); | |
| 309 | try req.write(&a.writer); | |
| 310 | Sha256.hash(a.written(), &hash, .{}); | |
| 311 | 311 | self.code_directory.addSpecialHash(req.slotType(), hash); |
| 312 | 312 | |
| 313 | 313 | try blobs.append(.{ .requirements = req }); |
| ... | ... | @@ -316,10 +316,10 @@ pub fn writeAdhocSignature( |
| 316 | 316 | } |
| 317 | 317 | |
| 318 | 318 | if (self.entitlements) |*ents| { |
| 319 | var buf = std.array_list.Managed(u8).init(allocator); | |
| 320 | defer buf.deinit(); | |
| 321 | try ents.write(buf.writer()); | |
| 322 | Sha256.hash(buf.items, &hash, .{}); | |
| 319 | var a: std.Io.Writer.Allocating = .init(allocator); | |
| 320 | defer a.deinit(); | |
| 321 | try ents.write(&a.writer); | |
| 322 | Sha256.hash(a.written(), &hash, .{}); | |
| 323 | 323 | self.code_directory.addSpecialHash(ents.slotType(), hash); |
| 324 | 324 | |
| 325 | 325 | try blobs.append(.{ .entitlements = ents }); |
src/link/MachO/DebugSymbols.zig+9-10| ... | ... | @@ -273,14 +273,13 @@ fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, u |
| 273 | 273 | const buffer = try gpa.alloc(u8, needed_size); |
| 274 | 274 | defer gpa.free(buffer); |
| 275 | 275 | |
| 276 | var stream = std.io.fixedBufferStream(buffer); | |
| 277 | const writer = stream.writer(); | |
| 276 | var writer: Writer = .fixed(buffer); | |
| 278 | 277 | |
| 279 | 278 | var ncmds: usize = 0; |
| 280 | 279 | |
| 281 | 280 | // UUID comes first presumably to speed up lookup by the consumer like lldb. |
| 282 | 281 | @memcpy(&self.uuid_cmd.uuid, &macho_file.uuid_cmd.uuid); |
| 283 | try writer.writeStruct(self.uuid_cmd); | |
| 282 | try writer.writeStruct(self.uuid_cmd, .little); | |
| 284 | 283 | ncmds += 1; |
| 285 | 284 | |
| 286 | 285 | // Segment and section load commands |
| ... | ... | @@ -293,11 +292,11 @@ fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, u |
| 293 | 292 | var out_seg = seg; |
| 294 | 293 | out_seg.fileoff = 0; |
| 295 | 294 | out_seg.filesize = 0; |
| 296 | try writer.writeStruct(out_seg); | |
| 295 | try writer.writeStruct(out_seg, .little); | |
| 297 | 296 | for (slice.items(.header)[sect_id..][0..seg.nsects]) |header| { |
| 298 | 297 | var out_header = header; |
| 299 | 298 | out_header.offset = 0; |
| 300 | try writer.writeStruct(out_header); | |
| 299 | try writer.writeStruct(out_header, .little); | |
| 301 | 300 | } |
| 302 | 301 | sect_id += seg.nsects; |
| 303 | 302 | } |
| ... | ... | @@ -306,19 +305,19 @@ fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, u |
| 306 | 305 | // Next, commit DSYM's __LINKEDIT and __DWARF segments headers. |
| 307 | 306 | sect_id = 0; |
| 308 | 307 | for (self.segments.items) |seg| { |
| 309 | try writer.writeStruct(seg); | |
| 308 | try writer.writeStruct(seg, .little); | |
| 310 | 309 | for (self.sections.items[sect_id..][0..seg.nsects]) |header| { |
| 311 | try writer.writeStruct(header); | |
| 310 | try writer.writeStruct(header, .little); | |
| 312 | 311 | } |
| 313 | 312 | sect_id += seg.nsects; |
| 314 | 313 | } |
| 315 | 314 | ncmds += self.segments.items.len; |
| 316 | 315 | } |
| 317 | 316 | |
| 318 | try writer.writeStruct(self.symtab_cmd); | |
| 317 | try writer.writeStruct(self.symtab_cmd, .little); | |
| 319 | 318 | ncmds += 1; |
| 320 | 319 | |
| 321 | assert(stream.pos == needed_size); | |
| 320 | assert(writer.end == needed_size); | |
| 322 | 321 | |
| 323 | 322 | try self.file.?.pwriteAll(buffer, @sizeOf(macho.mach_header_64)); |
| 324 | 323 | |
| ... | ... | @@ -460,7 +459,7 @@ const math = std.math; |
| 460 | 459 | const mem = std.mem; |
| 461 | 460 | const padToIdeal = MachO.padToIdeal; |
| 462 | 461 | const trace = @import("../../tracy.zig").trace; |
| 463 | const Writer = std.io.Writer; | |
| 462 | const Writer = std.Io.Writer; | |
| 464 | 463 | |
| 465 | 464 | const Allocator = mem.Allocator; |
| 466 | 465 | const MachO = @import("../MachO.zig"); |
src/link/MachO/InternalObject.zig+1-1| ... | ... | @@ -261,7 +261,7 @@ fn addObjcMethnameSection(self: *InternalObject, methname: []const u8, macho_fil |
| 261 | 261 | |
| 262 | 262 | sect.offset = @intCast(self.objc_methnames.items.len); |
| 263 | 263 | try self.objc_methnames.ensureUnusedCapacity(gpa, methname.len + 1); |
| 264 | self.objc_methnames.writer(gpa).print("{s}\x00", .{methname}) catch unreachable; | |
| 264 | self.objc_methnames.print(gpa, "{s}\x00", .{methname}) catch unreachable; | |
| 265 | 265 | |
| 266 | 266 | const name_str = try self.addString(gpa, "ltmp"); |
| 267 | 267 | const sym_index = try self.addSymbol(gpa); |
src/link/MachO/UnwindInfo.zig+23-24| ... | ... | @@ -293,8 +293,7 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void { |
| 293 | 293 | const seg = macho_file.getTextSegment(); |
| 294 | 294 | const header = macho_file.sections.items(.header)[macho_file.unwind_info_sect_index.?]; |
| 295 | 295 | |
| 296 | var stream = std.io.fixedBufferStream(buffer); | |
| 297 | const writer = stream.writer(); | |
| 296 | var writer: Writer = .fixed(buffer); | |
| 298 | 297 | |
| 299 | 298 | const common_encodings_offset: u32 = @sizeOf(macho.unwind_info_section_header); |
| 300 | 299 | const common_encodings_count: u32 = info.common_encodings_count; |
| ... | ... | @@ -303,14 +302,14 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void { |
| 303 | 302 | const indexes_offset: u32 = personalities_offset + personalities_count * @sizeOf(u32); |
| 304 | 303 | const indexes_count: u32 = @as(u32, @intCast(info.pages.items.len + 1)); |
| 305 | 304 | |
| 306 | try writer.writeStruct(macho.unwind_info_section_header{ | |
| 305 | try writer.writeStruct(@as(macho.unwind_info_section_header, .{ | |
| 307 | 306 | .commonEncodingsArraySectionOffset = common_encodings_offset, |
| 308 | 307 | .commonEncodingsArrayCount = common_encodings_count, |
| 309 | 308 | .personalityArraySectionOffset = personalities_offset, |
| 310 | 309 | .personalityArrayCount = personalities_count, |
| 311 | 310 | .indexSectionOffset = indexes_offset, |
| 312 | 311 | .indexCount = indexes_count, |
| 313 | }); | |
| 312 | }), .little); | |
| 314 | 313 | |
| 315 | 314 | try writer.writeAll(mem.sliceAsBytes(info.common_encodings[0..info.common_encodings_count])); |
| 316 | 315 | |
| ... | ... | @@ -325,42 +324,42 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void { |
| 325 | 324 | for (info.pages.items, 0..) |page, i| { |
| 326 | 325 | assert(page.count > 0); |
| 327 | 326 | const rec = info.records.items[page.start].getUnwindRecord(macho_file); |
| 328 | try writer.writeStruct(macho.unwind_info_section_header_index_entry{ | |
| 327 | try writer.writeStruct(@as(macho.unwind_info_section_header_index_entry, .{ | |
| 329 | 328 | .functionOffset = @as(u32, @intCast(rec.getAtomAddress(macho_file) - seg.vmaddr)), |
| 330 | 329 | .secondLevelPagesSectionOffset = @as(u32, @intCast(pages_base_offset + i * second_level_page_bytes)), |
| 331 | 330 | .lsdaIndexArraySectionOffset = lsda_base_offset + |
| 332 | 331 | info.lsdas_lookup.items[page.start] * @sizeOf(macho.unwind_info_section_header_lsda_index_entry), |
| 333 | }); | |
| 332 | }), .little); | |
| 334 | 333 | } |
| 335 | 334 | |
| 336 | 335 | const last_rec = info.records.items[info.records.items.len - 1].getUnwindRecord(macho_file); |
| 337 | 336 | const sentinel_address = @as(u32, @intCast(last_rec.getAtomAddress(macho_file) + last_rec.length - seg.vmaddr)); |
| 338 | try writer.writeStruct(macho.unwind_info_section_header_index_entry{ | |
| 337 | try writer.writeStruct(@as(macho.unwind_info_section_header_index_entry, .{ | |
| 339 | 338 | .functionOffset = sentinel_address, |
| 340 | 339 | .secondLevelPagesSectionOffset = 0, |
| 341 | 340 | .lsdaIndexArraySectionOffset = lsda_base_offset + |
| 342 | 341 | @as(u32, @intCast(info.lsdas.items.len)) * @sizeOf(macho.unwind_info_section_header_lsda_index_entry), |
| 343 | }); | |
| 342 | }), .little); | |
| 344 | 343 | |
| 345 | 344 | for (info.lsdas.items) |index| { |
| 346 | 345 | const rec = info.records.items[index].getUnwindRecord(macho_file); |
| 347 | try writer.writeStruct(macho.unwind_info_section_header_lsda_index_entry{ | |
| 346 | try writer.writeStruct(@as(macho.unwind_info_section_header_lsda_index_entry, .{ | |
| 348 | 347 | .functionOffset = @as(u32, @intCast(rec.getAtomAddress(macho_file) - seg.vmaddr)), |
| 349 | 348 | .lsdaOffset = @as(u32, @intCast(rec.getLsdaAddress(macho_file) - seg.vmaddr)), |
| 350 | }); | |
| 349 | }), .little); | |
| 351 | 350 | } |
| 352 | 351 | |
| 353 | 352 | for (info.pages.items) |page| { |
| 354 | const start = stream.pos; | |
| 355 | try page.write(info, macho_file, writer); | |
| 356 | const nwritten = stream.pos - start; | |
| 353 | const start = writer.end; | |
| 354 | try page.write(info, macho_file, &writer); | |
| 355 | const nwritten = writer.end - start; | |
| 357 | 356 | if (nwritten < second_level_page_bytes) { |
| 358 | 357 | const padding = math.cast(usize, second_level_page_bytes - nwritten) orelse return error.Overflow; |
| 359 | try writer.writeByteNTimes(0, padding); | |
| 358 | try writer.splatByteAll(0, padding); | |
| 360 | 359 | } |
| 361 | 360 | } |
| 362 | 361 | |
| 363 | @memset(buffer[stream.pos..], 0); | |
| 362 | @memset(buffer[writer.end..], 0); | |
| 364 | 363 | } |
| 365 | 364 | |
| 366 | 365 | fn getOrPutPersonalityFunction(info: *UnwindInfo, ref: MachO.Ref) error{TooManyPersonalities}!u2 { |
| ... | ... | @@ -611,33 +610,33 @@ const Page = struct { |
| 611 | 610 | } }; |
| 612 | 611 | } |
| 613 | 612 | |
| 614 | fn write(page: Page, info: UnwindInfo, macho_file: *MachO, writer: anytype) !void { | |
| 613 | fn write(page: Page, info: UnwindInfo, macho_file: *MachO, writer: *Writer) !void { | |
| 615 | 614 | const seg = macho_file.getTextSegment(); |
| 616 | 615 | |
| 617 | 616 | switch (page.kind) { |
| 618 | 617 | .regular => { |
| 619 | try writer.writeStruct(macho.unwind_info_regular_second_level_page_header{ | |
| 618 | try writer.writeStruct(@as(macho.unwind_info_regular_second_level_page_header, .{ | |
| 620 | 619 | .entryPageOffset = @sizeOf(macho.unwind_info_regular_second_level_page_header), |
| 621 | 620 | .entryCount = page.count, |
| 622 | }); | |
| 621 | }), .little); | |
| 623 | 622 | |
| 624 | 623 | for (info.records.items[page.start..][0..page.count]) |ref| { |
| 625 | 624 | const rec = ref.getUnwindRecord(macho_file); |
| 626 | try writer.writeStruct(macho.unwind_info_regular_second_level_entry{ | |
| 625 | try writer.writeStruct(@as(macho.unwind_info_regular_second_level_entry, .{ | |
| 627 | 626 | .functionOffset = @as(u32, @intCast(rec.getAtomAddress(macho_file) - seg.vmaddr)), |
| 628 | 627 | .encoding = rec.enc.enc, |
| 629 | }); | |
| 628 | }), .little); | |
| 630 | 629 | } |
| 631 | 630 | }, |
| 632 | 631 | .compressed => { |
| 633 | 632 | const entry_offset = @sizeOf(macho.unwind_info_compressed_second_level_page_header) + |
| 634 | 633 | @as(u16, @intCast(page.page_encodings_count)) * @sizeOf(u32); |
| 635 | try writer.writeStruct(macho.unwind_info_compressed_second_level_page_header{ | |
| 634 | try writer.writeStruct(@as(macho.unwind_info_compressed_second_level_page_header, .{ | |
| 636 | 635 | .entryPageOffset = entry_offset, |
| 637 | 636 | .entryCount = page.count, |
| 638 | 637 | .encodingsPageOffset = @sizeOf(macho.unwind_info_compressed_second_level_page_header), |
| 639 | 638 | .encodingsCount = page.page_encodings_count, |
| 640 | }); | |
| 639 | }), .little); | |
| 641 | 640 | |
| 642 | 641 | for (page.page_encodings[0..page.page_encodings_count]) |enc| { |
| 643 | 642 | try writer.writeInt(u32, enc.enc, .little); |
| ... | ... | @@ -656,7 +655,7 @@ const Page = struct { |
| 656 | 655 | .funcOffset = @as(u24, @intCast(rec.getAtomAddress(macho_file) - first_rec.getAtomAddress(macho_file))), |
| 657 | 656 | .encodingIndex = @as(u8, @intCast(enc_index)), |
| 658 | 657 | }; |
| 659 | try writer.writeStruct(compressed); | |
| 658 | try writer.writeStruct(compressed, .little); | |
| 660 | 659 | } |
| 661 | 660 | }, |
| 662 | 661 | } |
| ... | ... | @@ -673,7 +672,7 @@ const macho = std.macho; |
| 673 | 672 | const math = std.math; |
| 674 | 673 | const mem = std.mem; |
| 675 | 674 | const trace = @import("../../tracy.zig").trace; |
| 676 | const Writer = std.io.Writer; | |
| 675 | const Writer = std.Io.Writer; | |
| 677 | 676 | |
| 678 | 677 | const Allocator = mem.Allocator; |
| 679 | 678 | const Atom = @import("Atom.zig"); |
src/link/MachO/dyld_info/Rebase.zig+4-2| ... | ... | @@ -110,12 +110,14 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void { |
| 110 | 110 | fn finalize(rebase: *Rebase, gpa: Allocator) !void { |
| 111 | 111 | if (rebase.entries.items.len == 0) return; |
| 112 | 112 | |
| 113 | const writer = rebase.buffer.writer(gpa); | |
| 114 | ||
| 115 | 113 | log.debug("rebase opcodes", .{}); |
| 116 | 114 | |
| 117 | 115 | std.mem.sort(Entry, rebase.entries.items, {}, Entry.lessThan); |
| 118 | 116 | |
| 117 | var allocating: std.Io.Writer.Allocating = .fromArrayList(gpa, &rebase.buffer); | |
| 118 | defer rebase.buffer = allocating.toArrayList(); | |
| 119 | const writer = &allocating.writer; | |
| 120 | ||
| 119 | 121 | try setTypePointer(writer); |
| 120 | 122 | |
| 121 | 123 | var start: usize = 0; |
src/link/MachO/dyld_info/Trie.zig+15-10| ... | ... | @@ -170,8 +170,13 @@ fn finalize(self: *Trie, allocator: Allocator) !void { |
| 170 | 170 | } |
| 171 | 171 | |
| 172 | 172 | try self.buffer.ensureTotalCapacityPrecise(allocator, size); |
| 173 | ||
| 174 | var allocating: std.Io.Writer.Allocating = .fromArrayList(allocator, &self.buffer); | |
| 175 | defer self.buffer = allocating.toArrayList(); | |
| 176 | const writer = &allocating.writer; | |
| 177 | ||
| 173 | 178 | for (ordered_nodes.items) |node_index| { |
| 174 | try self.writeNode(node_index, self.buffer.writer(allocator)); | |
| 179 | try self.writeNode(node_index, writer); | |
| 175 | 180 | } |
| 176 | 181 | } |
| 177 | 182 | |
| ... | ... | @@ -232,7 +237,7 @@ pub fn deinit(self: *Trie, allocator: Allocator) void { |
| 232 | 237 | self.buffer.deinit(allocator); |
| 233 | 238 | } |
| 234 | 239 | |
| 235 | pub fn write(self: Trie, writer: anytype) !void { | |
| 240 | pub fn write(self: Trie, writer: *std.Io.Writer) !void { | |
| 236 | 241 | if (self.buffer.items.len == 0) return; |
| 237 | 242 | try writer.writeAll(self.buffer.items); |
| 238 | 243 | } |
| ... | ... | @@ -243,7 +248,7 @@ pub fn write(self: Trie, writer: anytype) !void { |
| 243 | 248 | /// iterate over `Trie.ordered_nodes` and call this method on each node. |
| 244 | 249 | /// This is one of the requirements of the MachO. |
| 245 | 250 | /// Panics if `finalize` was not called before calling this method. |
| 246 | fn writeNode(self: *Trie, node_index: Node.Index, writer: anytype) !void { | |
| 251 | fn writeNode(self: *Trie, node_index: Node.Index, writer: *std.Io.Writer) !void { | |
| 247 | 252 | const slice = self.nodes.slice(); |
| 248 | 253 | const edges = slice.items(.edges)[node_index]; |
| 249 | 254 | const is_terminal = slice.items(.is_terminal)[node_index]; |
| ... | ... | @@ -253,21 +258,21 @@ fn writeNode(self: *Trie, node_index: Node.Index, writer: anytype) !void { |
| 253 | 258 | if (is_terminal) { |
| 254 | 259 | // Terminal node info: encode export flags and vmaddr offset of this symbol. |
| 255 | 260 | var info_buf: [@sizeOf(u64) * 2]u8 = undefined; |
| 256 | var info_stream = std.io.fixedBufferStream(&info_buf); | |
| 261 | var info_stream: std.Io.Writer = .fixed(&info_buf); | |
| 257 | 262 | // TODO Implement for special flags. |
| 258 | 263 | assert(export_flags & macho.EXPORT_SYMBOL_FLAGS_REEXPORT == 0 and |
| 259 | 264 | export_flags & macho.EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER == 0); |
| 260 | try leb.writeUleb128(info_stream.writer(), export_flags); | |
| 261 | try leb.writeUleb128(info_stream.writer(), vmaddr_offset); | |
| 265 | try leb.writeUleb128(&info_stream, export_flags); | |
| 266 | try leb.writeUleb128(&info_stream, vmaddr_offset); | |
| 262 | 267 | |
| 263 | 268 | // Encode the size of the terminal node info. |
| 264 | 269 | var size_buf: [@sizeOf(u64)]u8 = undefined; |
| 265 | var size_stream = std.io.fixedBufferStream(&size_buf); | |
| 266 | try leb.writeUleb128(size_stream.writer(), info_stream.pos); | |
| 270 | var size_stream: std.Io.Writer = .fixed(&size_buf); | |
| 271 | try leb.writeUleb128(&size_stream, info_stream.end); | |
| 267 | 272 | |
| 268 | 273 | // Now, write them to the output stream. |
| 269 | try writer.writeAll(size_buf[0..size_stream.pos]); | |
| 270 | try writer.writeAll(info_buf[0..info_stream.pos]); | |
| 274 | try writer.writeAll(size_buf[0..size_stream.end]); | |
| 275 | try writer.writeAll(info_buf[0..info_stream.end]); | |
| 271 | 276 | } else { |
| 272 | 277 | // Non-terminal node is delimited by 0 byte. |
| 273 | 278 | try writer.writeByte(0); |
src/link/MachO/dyld_info/bind.zig+26-21| ... | ... | @@ -132,12 +132,14 @@ pub const Bind = struct { |
| 132 | 132 | fn finalize(self: *Self, gpa: Allocator, ctx: *MachO) !void { |
| 133 | 133 | if (self.entries.items.len == 0) return; |
| 134 | 134 | |
| 135 | const writer = self.buffer.writer(gpa); | |
| 136 | ||
| 137 | 135 | log.debug("bind opcodes", .{}); |
| 138 | 136 | |
| 139 | 137 | std.mem.sort(Entry, self.entries.items, ctx, Entry.lessThan); |
| 140 | 138 | |
| 139 | var allocating: std.Io.Writer.Allocating = .fromArrayList(gpa, &self.buffer); | |
| 140 | defer self.buffer = allocating.toArrayList(); | |
| 141 | const writer = &allocating.writer; | |
| 142 | ||
| 141 | 143 | var start: usize = 0; |
| 142 | 144 | var seg_id: ?u8 = null; |
| 143 | 145 | for (self.entries.items, 0..) |entry, i| { |
| ... | ... | @@ -151,7 +153,7 @@ pub const Bind = struct { |
| 151 | 153 | try done(writer); |
| 152 | 154 | } |
| 153 | 155 | |
| 154 | fn finalizeSegment(entries: []const Entry, ctx: *MachO, writer: anytype) !void { | |
| 156 | fn finalizeSegment(entries: []const Entry, ctx: *MachO, writer: *std.Io.Writer) !void { | |
| 155 | 157 | if (entries.len == 0) return; |
| 156 | 158 | |
| 157 | 159 | const seg_id = entries[0].segment_id; |
| ... | ... | @@ -263,7 +265,7 @@ pub const Bind = struct { |
| 263 | 265 | } |
| 264 | 266 | } |
| 265 | 267 | |
| 266 | pub fn write(self: Self, writer: anytype) !void { | |
| 268 | pub fn write(self: Self, writer: *std.Io.Writer) !void { | |
| 267 | 269 | try writer.writeAll(self.buffer.items); |
| 268 | 270 | } |
| 269 | 271 | }; |
| ... | ... | @@ -385,12 +387,14 @@ pub const WeakBind = struct { |
| 385 | 387 | fn finalize(self: *Self, gpa: Allocator, ctx: *MachO) !void { |
| 386 | 388 | if (self.entries.items.len == 0) return; |
| 387 | 389 | |
| 388 | const writer = self.buffer.writer(gpa); | |
| 389 | ||
| 390 | 390 | log.debug("weak bind opcodes", .{}); |
| 391 | 391 | |
| 392 | 392 | std.mem.sort(Entry, self.entries.items, ctx, Entry.lessThan); |
| 393 | 393 | |
| 394 | var allocating: std.Io.Writer.Allocating = .fromArrayList(gpa, &self.buffer); | |
| 395 | defer self.buffer = allocating.toArrayList(); | |
| 396 | const writer = &allocating.writer; | |
| 397 | ||
| 394 | 398 | var start: usize = 0; |
| 395 | 399 | var seg_id: ?u8 = null; |
| 396 | 400 | for (self.entries.items, 0..) |entry, i| { |
| ... | ... | @@ -404,7 +408,7 @@ pub const WeakBind = struct { |
| 404 | 408 | try done(writer); |
| 405 | 409 | } |
| 406 | 410 | |
| 407 | fn finalizeSegment(entries: []const Entry, ctx: *MachO, writer: anytype) !void { | |
| 411 | fn finalizeSegment(entries: []const Entry, ctx: *MachO, writer: *std.Io.Writer) !void { | |
| 408 | 412 | if (entries.len == 0) return; |
| 409 | 413 | |
| 410 | 414 | const seg_id = entries[0].segment_id; |
| ... | ... | @@ -505,7 +509,7 @@ pub const WeakBind = struct { |
| 505 | 509 | } |
| 506 | 510 | } |
| 507 | 511 | |
| 508 | pub fn write(self: Self, writer: anytype) !void { | |
| 512 | pub fn write(self: Self, writer: *std.Io.Writer) !void { | |
| 509 | 513 | try writer.writeAll(self.buffer.items); |
| 510 | 514 | } |
| 511 | 515 | }; |
| ... | ... | @@ -555,8 +559,6 @@ pub const LazyBind = struct { |
| 555 | 559 | fn finalize(self: *Self, gpa: Allocator, ctx: *MachO) !void { |
| 556 | 560 | try self.offsets.ensureTotalCapacityPrecise(gpa, self.entries.items.len); |
| 557 | 561 | |
| 558 | const writer = self.buffer.writer(gpa); | |
| 559 | ||
| 560 | 562 | log.debug("lazy bind opcodes", .{}); |
| 561 | 563 | |
| 562 | 564 | var addend: i64 = 0; |
| ... | ... | @@ -578,6 +580,9 @@ pub const LazyBind = struct { |
| 578 | 580 | break :ord macho.BIND_SPECIAL_DYLIB_SELF; |
| 579 | 581 | }; |
| 580 | 582 | |
| 583 | var allocating: std.Io.Writer.Allocating = .fromArrayList(gpa, &self.buffer); | |
| 584 | defer self.buffer = allocating.toArrayList(); | |
| 585 | const writer = &allocating.writer; | |
| 581 | 586 | try setSegmentOffset(entry.segment_id, entry.offset, writer); |
| 582 | 587 | try setSymbol(name, flags, writer); |
| 583 | 588 | try setDylibOrdinal(ordinal, writer); |
| ... | ... | @@ -592,30 +597,30 @@ pub const LazyBind = struct { |
| 592 | 597 | } |
| 593 | 598 | } |
| 594 | 599 | |
| 595 | pub fn write(self: Self, writer: anytype) !void { | |
| 600 | pub fn write(self: Self, writer: *std.Io.Writer) !void { | |
| 596 | 601 | try writer.writeAll(self.buffer.items); |
| 597 | 602 | } |
| 598 | 603 | }; |
| 599 | 604 | |
| 600 | fn setSegmentOffset(segment_id: u8, offset: u64, writer: anytype) !void { | |
| 605 | fn setSegmentOffset(segment_id: u8, offset: u64, writer: *std.Io.Writer) !void { | |
| 601 | 606 | log.debug(">>> set segment: {d} and offset: {x}", .{ segment_id, offset }); |
| 602 | 607 | try writer.writeByte(macho.BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | @as(u4, @truncate(segment_id))); |
| 603 | 608 | try std.leb.writeUleb128(writer, offset); |
| 604 | 609 | } |
| 605 | 610 | |
| 606 | fn setSymbol(name: []const u8, flags: u8, writer: anytype) !void { | |
| 611 | fn setSymbol(name: []const u8, flags: u8, writer: *std.Io.Writer) !void { | |
| 607 | 612 | log.debug(">>> set symbol: {s} with flags: {x}", .{ name, flags }); |
| 608 | 613 | try writer.writeByte(macho.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | @as(u4, @truncate(flags))); |
| 609 | 614 | try writer.writeAll(name); |
| 610 | 615 | try writer.writeByte(0); |
| 611 | 616 | } |
| 612 | 617 | |
| 613 | fn setTypePointer(writer: anytype) !void { | |
| 618 | fn setTypePointer(writer: *std.Io.Writer) !void { | |
| 614 | 619 | log.debug(">>> set type: {d}", .{macho.BIND_TYPE_POINTER}); |
| 615 | 620 | try writer.writeByte(macho.BIND_OPCODE_SET_TYPE_IMM | @as(u4, @truncate(macho.BIND_TYPE_POINTER))); |
| 616 | 621 | } |
| 617 | 622 | |
| 618 | fn setDylibOrdinal(ordinal: i16, writer: anytype) !void { | |
| 623 | fn setDylibOrdinal(ordinal: i16, writer: *std.Io.Writer) !void { | |
| 619 | 624 | if (ordinal <= 0) { |
| 620 | 625 | switch (ordinal) { |
| 621 | 626 | macho.BIND_SPECIAL_DYLIB_SELF, |
| ... | ... | @@ -639,18 +644,18 @@ fn setDylibOrdinal(ordinal: i16, writer: anytype) !void { |
| 639 | 644 | } |
| 640 | 645 | } |
| 641 | 646 | |
| 642 | fn setAddend(addend: i64, writer: anytype) !void { | |
| 647 | fn setAddend(addend: i64, writer: *std.Io.Writer) !void { | |
| 643 | 648 | log.debug(">>> set addend: {x}", .{addend}); |
| 644 | 649 | try writer.writeByte(macho.BIND_OPCODE_SET_ADDEND_SLEB); |
| 645 | 650 | try std.leb.writeIleb128(writer, addend); |
| 646 | 651 | } |
| 647 | 652 | |
| 648 | fn doBind(writer: anytype) !void { | |
| 653 | fn doBind(writer: *std.Io.Writer) !void { | |
| 649 | 654 | log.debug(">>> bind", .{}); |
| 650 | 655 | try writer.writeByte(macho.BIND_OPCODE_DO_BIND); |
| 651 | 656 | } |
| 652 | 657 | |
| 653 | fn doBindAddAddr(addr: u64, writer: anytype) !void { | |
| 658 | fn doBindAddAddr(addr: u64, writer: *std.Io.Writer) !void { | |
| 654 | 659 | log.debug(">>> bind with add: {x}", .{addr}); |
| 655 | 660 | if (std.mem.isAlignedGeneric(u64, addr, @sizeOf(u64))) { |
| 656 | 661 | const imm = @divExact(addr, @sizeOf(u64)); |
| ... | ... | @@ -665,20 +670,20 @@ fn doBindAddAddr(addr: u64, writer: anytype) !void { |
| 665 | 670 | try std.leb.writeUleb128(writer, addr); |
| 666 | 671 | } |
| 667 | 672 | |
| 668 | fn doBindTimesSkip(count: usize, skip: u64, writer: anytype) !void { | |
| 673 | fn doBindTimesSkip(count: usize, skip: u64, writer: *std.Io.Writer) !void { | |
| 669 | 674 | log.debug(">>> bind with count: {d} and skip: {x}", .{ count, skip }); |
| 670 | 675 | try writer.writeByte(macho.BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB); |
| 671 | 676 | try std.leb.writeUleb128(writer, count); |
| 672 | 677 | try std.leb.writeUleb128(writer, skip); |
| 673 | 678 | } |
| 674 | 679 | |
| 675 | fn addAddr(addr: u64, writer: anytype) !void { | |
| 680 | fn addAddr(addr: u64, writer: *std.Io.Writer) !void { | |
| 676 | 681 | log.debug(">>> add: {x}", .{addr}); |
| 677 | 682 | try writer.writeByte(macho.BIND_OPCODE_ADD_ADDR_ULEB); |
| 678 | 683 | try std.leb.writeUleb128(writer, addr); |
| 679 | 684 | } |
| 680 | 685 | |
| 681 | fn done(writer: anytype) !void { | |
| 686 | fn done(writer: *std.Io.Writer) !void { | |
| 682 | 687 | log.debug(">>> done", .{}); |
| 683 | 688 | try writer.writeByte(macho.BIND_OPCODE_DONE); |
| 684 | 689 | } |
src/link/MachO/load_commands.zig+19-19| ... | ... | @@ -3,9 +3,9 @@ const assert = std.debug.assert; |
| 3 | 3 | const log = std.log.scoped(.link); |
| 4 | 4 | const macho = std.macho; |
| 5 | 5 | const mem = std.mem; |
| 6 | const Writer = std.io.Writer; | |
| 6 | const Writer = std.Io.Writer; | |
| 7 | const Allocator = std.mem.Allocator; | |
| 7 | 8 | |
| 8 | const Allocator = mem.Allocator; | |
| 9 | 9 | const DebugSymbols = @import("DebugSymbols.zig"); |
| 10 | 10 | const Dylib = @import("Dylib.zig"); |
| 11 | 11 | const MachO = @import("../MachO.zig"); |
| ... | ... | @@ -181,22 +181,22 @@ pub fn calcMinHeaderPadSize(macho_file: *MachO) !u32 { |
| 181 | 181 | return offset; |
| 182 | 182 | } |
| 183 | 183 | |
| 184 | pub fn writeDylinkerLC(writer: anytype) !void { | |
| 184 | pub fn writeDylinkerLC(writer: *Writer) !void { | |
| 185 | 185 | const name_len = mem.sliceTo(default_dyld_path, 0).len; |
| 186 | 186 | const cmdsize = @as(u32, @intCast(mem.alignForward( |
| 187 | 187 | u64, |
| 188 | 188 | @sizeOf(macho.dylinker_command) + name_len, |
| 189 | 189 | @sizeOf(u64), |
| 190 | 190 | ))); |
| 191 | try writer.writeStruct(macho.dylinker_command{ | |
| 191 | try writer.writeStruct(@as(macho.dylinker_command, .{ | |
| 192 | 192 | .cmd = .LOAD_DYLINKER, |
| 193 | 193 | .cmdsize = cmdsize, |
| 194 | 194 | .name = @sizeOf(macho.dylinker_command), |
| 195 | }); | |
| 195 | }), .little); | |
| 196 | 196 | try writer.writeAll(mem.sliceTo(default_dyld_path, 0)); |
| 197 | 197 | const padding = cmdsize - @sizeOf(macho.dylinker_command) - name_len; |
| 198 | 198 | if (padding > 0) { |
| 199 | try writer.writeByteNTimes(0, padding); | |
| 199 | try writer.splatByteAll(0, padding); | |
| 200 | 200 | } |
| 201 | 201 | } |
| 202 | 202 | |
| ... | ... | @@ -208,14 +208,14 @@ const WriteDylibLCCtx = struct { |
| 208 | 208 | compatibility_version: u32 = 0x10000, |
| 209 | 209 | }; |
| 210 | 210 | |
| 211 | pub fn writeDylibLC(ctx: WriteDylibLCCtx, writer: anytype) !void { | |
| 211 | pub fn writeDylibLC(ctx: WriteDylibLCCtx, writer: *Writer) !void { | |
| 212 | 212 | const name_len = ctx.name.len + 1; |
| 213 | 213 | const cmdsize = @as(u32, @intCast(mem.alignForward( |
| 214 | 214 | u64, |
| 215 | 215 | @sizeOf(macho.dylib_command) + name_len, |
| 216 | 216 | @sizeOf(u64), |
| 217 | 217 | ))); |
| 218 | try writer.writeStruct(macho.dylib_command{ | |
| 218 | try writer.writeStruct(@as(macho.dylib_command, .{ | |
| 219 | 219 | .cmd = ctx.cmd, |
| 220 | 220 | .cmdsize = cmdsize, |
| 221 | 221 | .dylib = .{ |
| ... | ... | @@ -224,16 +224,16 @@ pub fn writeDylibLC(ctx: WriteDylibLCCtx, writer: anytype) !void { |
| 224 | 224 | .current_version = ctx.current_version, |
| 225 | 225 | .compatibility_version = ctx.compatibility_version, |
| 226 | 226 | }, |
| 227 | }); | |
| 227 | }), .little); | |
| 228 | 228 | try writer.writeAll(ctx.name); |
| 229 | 229 | try writer.writeByte(0); |
| 230 | 230 | const padding = cmdsize - @sizeOf(macho.dylib_command) - name_len; |
| 231 | 231 | if (padding > 0) { |
| 232 | try writer.writeByteNTimes(0, padding); | |
| 232 | try writer.splatByteAll(0, padding); | |
| 233 | 233 | } |
| 234 | 234 | } |
| 235 | 235 | |
| 236 | pub fn writeDylibIdLC(macho_file: *MachO, writer: anytype) !void { | |
| 236 | pub fn writeDylibIdLC(macho_file: *MachO, writer: *Writer) !void { | |
| 237 | 237 | const comp = macho_file.base.comp; |
| 238 | 238 | const gpa = comp.gpa; |
| 239 | 239 | assert(comp.config.output_mode == .Lib and comp.config.link_mode == .dynamic); |
| ... | ... | @@ -259,26 +259,26 @@ pub fn writeDylibIdLC(macho_file: *MachO, writer: anytype) !void { |
| 259 | 259 | }, writer); |
| 260 | 260 | } |
| 261 | 261 | |
| 262 | pub fn writeRpathLC(rpath: []const u8, writer: anytype) !void { | |
| 262 | pub fn writeRpathLC(rpath: []const u8, writer: *Writer) !void { | |
| 263 | 263 | const rpath_len = rpath.len + 1; |
| 264 | 264 | const cmdsize = @as(u32, @intCast(mem.alignForward( |
| 265 | 265 | u64, |
| 266 | 266 | @sizeOf(macho.rpath_command) + rpath_len, |
| 267 | 267 | @sizeOf(u64), |
| 268 | 268 | ))); |
| 269 | try writer.writeStruct(macho.rpath_command{ | |
| 269 | try writer.writeStruct(@as(macho.rpath_command, .{ | |
| 270 | 270 | .cmdsize = cmdsize, |
| 271 | 271 | .path = @sizeOf(macho.rpath_command), |
| 272 | }); | |
| 272 | }), .little); | |
| 273 | 273 | try writer.writeAll(rpath); |
| 274 | 274 | try writer.writeByte(0); |
| 275 | 275 | const padding = cmdsize - @sizeOf(macho.rpath_command) - rpath_len; |
| 276 | 276 | if (padding > 0) { |
| 277 | try writer.writeByteNTimes(0, padding); | |
| 277 | try writer.splatByteAll(0, padding); | |
| 278 | 278 | } |
| 279 | 279 | } |
| 280 | 280 | |
| 281 | pub fn writeVersionMinLC(platform: MachO.Platform, sdk_version: ?std.SemanticVersion, writer: anytype) !void { | |
| 281 | pub fn writeVersionMinLC(platform: MachO.Platform, sdk_version: ?std.SemanticVersion, writer: *Writer) !void { | |
| 282 | 282 | const cmd: macho.LC = switch (platform.os_tag) { |
| 283 | 283 | .macos => .VERSION_MIN_MACOSX, |
| 284 | 284 | .ios => .VERSION_MIN_IPHONEOS, |
| ... | ... | @@ -296,9 +296,9 @@ pub fn writeVersionMinLC(platform: MachO.Platform, sdk_version: ?std.SemanticVer |
| 296 | 296 | })); |
| 297 | 297 | } |
| 298 | 298 | |
| 299 | pub fn writeBuildVersionLC(platform: MachO.Platform, sdk_version: ?std.SemanticVersion, writer: anytype) !void { | |
| 299 | pub fn writeBuildVersionLC(platform: MachO.Platform, sdk_version: ?std.SemanticVersion, writer: *Writer) !void { | |
| 300 | 300 | const cmdsize = @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version); |
| 301 | try writer.writeStruct(macho.build_version_command{ | |
| 301 | try writer.writeStruct(@as(macho.build_version_command, .{ | |
| 302 | 302 | .cmdsize = cmdsize, |
| 303 | 303 | .platform = platform.toApplePlatform(), |
| 304 | 304 | .minos = platform.toAppleVersion(), |
| ... | ... | @@ -307,7 +307,7 @@ pub fn writeBuildVersionLC(platform: MachO.Platform, sdk_version: ?std.SemanticV |
| 307 | 307 | else |
| 308 | 308 | platform.toAppleVersion(), |
| 309 | 309 | .ntools = 1, |
| 310 | }); | |
| 310 | }), .little); | |
| 311 | 311 | try writer.writeAll(mem.asBytes(&macho.build_tool_version{ |
| 312 | 312 | .tool = .ZIG, |
| 313 | 313 | .version = 0x0, |
src/link/MachO/relocatable.zig+29-33| ... | ... | @@ -205,35 +205,32 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ? |
| 205 | 205 | state_log.debug("ar_symtab\n{f}\n", .{ar_symtab.fmt(macho_file)}); |
| 206 | 206 | } |
| 207 | 207 | |
| 208 | var buffer = std.array_list.Managed(u8).init(gpa); | |
| 209 | defer buffer.deinit(); | |
| 210 | try buffer.ensureTotalCapacityPrecise(total_size); | |
| 211 | const writer = buffer.writer(); | |
| 208 | const buffer = try gpa.alloc(u8, total_size); | |
| 209 | defer gpa.free(buffer); | |
| 210 | var writer: Writer = .fixed(buffer); | |
| 212 | 211 | |
| 213 | 212 | // Write magic |
| 214 | try writer.writeAll(Archive.ARMAG); | |
| 213 | writer.writeAll(Archive.ARMAG) catch unreachable; | |
| 215 | 214 | |
| 216 | 215 | // Write symtab |
| 217 | ar_symtab.write(format, macho_file, writer) catch |err| switch (err) { | |
| 218 | error.OutOfMemory => return error.OutOfMemory, | |
| 219 | else => |e| return diags.fail("failed to write archive symbol table: {s}", .{@errorName(e)}), | |
| 220 | }; | |
| 216 | ar_symtab.write(format, macho_file, &writer) catch |err| | |
| 217 | return diags.fail("failed to write archive symbol table: {t}", .{err}); | |
| 221 | 218 | |
| 222 | 219 | // Write object files |
| 223 | 220 | for (files.items) |index| { |
| 224 | const aligned = mem.alignForward(usize, buffer.items.len, 2); | |
| 225 | const padding = aligned - buffer.items.len; | |
| 221 | const aligned = mem.alignForward(usize, writer.end, 2); | |
| 222 | const padding = aligned - writer.end; | |
| 226 | 223 | if (padding > 0) { |
| 227 | try writer.writeByteNTimes(0, padding); | |
| 224 | writer.splatByteAll(0, padding) catch unreachable; | |
| 228 | 225 | } |
| 229 | macho_file.getFile(index).?.writeAr(format, macho_file, writer) catch |err| | |
| 230 | return diags.fail("failed to write archive: {s}", .{@errorName(err)}); | |
| 226 | macho_file.getFile(index).?.writeAr(format, macho_file, &writer) catch |err| | |
| 227 | return diags.fail("failed to write archive: {t}", .{err}); | |
| 231 | 228 | } |
| 232 | 229 | |
| 233 | assert(buffer.items.len == total_size); | |
| 230 | assert(writer.end == total_size); | |
| 234 | 231 | |
| 235 | 232 | try macho_file.setEndPos(total_size); |
| 236 | try macho_file.pwriteAll(buffer.items, 0); | |
| 233 | try macho_file.pwriteAll(writer.buffered(), 0); | |
| 237 | 234 | |
| 238 | 235 | if (diags.hasErrors()) return error.LinkFailure; |
| 239 | 236 | } |
| ... | ... | @@ -693,8 +690,7 @@ fn writeLoadCommands(macho_file: *MachO) error{ LinkFailure, OutOfMemory }!struc |
| 693 | 690 | const buffer = try gpa.alloc(u8, needed_size); |
| 694 | 691 | defer gpa.free(buffer); |
| 695 | 692 | |
| 696 | var stream = std.io.fixedBufferStream(buffer); | |
| 697 | const writer = stream.writer(); | |
| 693 | var writer: Writer = .fixed(buffer); | |
| 698 | 694 | |
| 699 | 695 | var ncmds: usize = 0; |
| 700 | 696 | |
| ... | ... | @@ -702,43 +698,43 @@ fn writeLoadCommands(macho_file: *MachO) error{ LinkFailure, OutOfMemory }!struc |
| 702 | 698 | { |
| 703 | 699 | assert(macho_file.segments.items.len == 1); |
| 704 | 700 | const seg = macho_file.segments.items[0]; |
| 705 | writer.writeStruct(seg) catch |err| switch (err) { | |
| 706 | error.NoSpaceLeft => unreachable, | |
| 701 | writer.writeStruct(seg, .little) catch |err| switch (err) { | |
| 702 | error.WriteFailed => unreachable, | |
| 707 | 703 | }; |
| 708 | 704 | for (macho_file.sections.items(.header)) |header| { |
| 709 | writer.writeStruct(header) catch |err| switch (err) { | |
| 710 | error.NoSpaceLeft => unreachable, | |
| 705 | writer.writeStruct(header, .little) catch |err| switch (err) { | |
| 706 | error.WriteFailed => unreachable, | |
| 711 | 707 | }; |
| 712 | 708 | } |
| 713 | 709 | ncmds += 1; |
| 714 | 710 | } |
| 715 | 711 | |
| 716 | writer.writeStruct(macho_file.data_in_code_cmd) catch |err| switch (err) { | |
| 717 | error.NoSpaceLeft => unreachable, | |
| 712 | writer.writeStruct(macho_file.data_in_code_cmd, .little) catch |err| switch (err) { | |
| 713 | error.WriteFailed => unreachable, | |
| 718 | 714 | }; |
| 719 | 715 | ncmds += 1; |
| 720 | writer.writeStruct(macho_file.symtab_cmd) catch |err| switch (err) { | |
| 721 | error.NoSpaceLeft => unreachable, | |
| 716 | writer.writeStruct(macho_file.symtab_cmd, .little) catch |err| switch (err) { | |
| 717 | error.WriteFailed => unreachable, | |
| 722 | 718 | }; |
| 723 | 719 | ncmds += 1; |
| 724 | writer.writeStruct(macho_file.dysymtab_cmd) catch |err| switch (err) { | |
| 725 | error.NoSpaceLeft => unreachable, | |
| 720 | writer.writeStruct(macho_file.dysymtab_cmd, .little) catch |err| switch (err) { | |
| 721 | error.WriteFailed => unreachable, | |
| 726 | 722 | }; |
| 727 | 723 | ncmds += 1; |
| 728 | 724 | |
| 729 | 725 | if (macho_file.platform.isBuildVersionCompatible()) { |
| 730 | load_commands.writeBuildVersionLC(macho_file.platform, macho_file.sdk_version, writer) catch |err| switch (err) { | |
| 731 | error.NoSpaceLeft => unreachable, | |
| 726 | load_commands.writeBuildVersionLC(macho_file.platform, macho_file.sdk_version, &writer) catch |err| switch (err) { | |
| 727 | error.WriteFailed => unreachable, | |
| 732 | 728 | }; |
| 733 | 729 | ncmds += 1; |
| 734 | 730 | } else { |
| 735 | load_commands.writeVersionMinLC(macho_file.platform, macho_file.sdk_version, writer) catch |err| switch (err) { | |
| 736 | error.NoSpaceLeft => unreachable, | |
| 731 | load_commands.writeVersionMinLC(macho_file.platform, macho_file.sdk_version, &writer) catch |err| switch (err) { | |
| 732 | error.WriteFailed => unreachable, | |
| 737 | 733 | }; |
| 738 | 734 | ncmds += 1; |
| 739 | 735 | } |
| 740 | 736 | |
| 741 | assert(stream.pos == needed_size); | |
| 737 | assert(writer.end == needed_size); | |
| 742 | 738 | |
| 743 | 739 | try macho_file.pwriteAll(buffer, @sizeOf(macho.mach_header_64)); |
| 744 | 740 |
src/link/MachO/synthetic.zig+12-12| ... | ... | @@ -27,7 +27,7 @@ pub const GotSection = struct { |
| 27 | 27 | return got.symbols.items.len * @sizeOf(u64); |
| 28 | 28 | } |
| 29 | 29 | |
| 30 | pub fn write(got: GotSection, macho_file: *MachO, writer: anytype) !void { | |
| 30 | pub fn write(got: GotSection, macho_file: *MachO, writer: *Writer) !void { | |
| 31 | 31 | const tracy = trace(@src()); |
| 32 | 32 | defer tracy.end(); |
| 33 | 33 | for (got.symbols.items) |ref| { |
| ... | ... | @@ -89,7 +89,7 @@ pub const StubsSection = struct { |
| 89 | 89 | return stubs.symbols.items.len * header.reserved2; |
| 90 | 90 | } |
| 91 | 91 | |
| 92 | pub fn write(stubs: StubsSection, macho_file: *MachO, writer: anytype) !void { | |
| 92 | pub fn write(stubs: StubsSection, macho_file: *MachO, writer: *Writer) !void { | |
| 93 | 93 | const tracy = trace(@src()); |
| 94 | 94 | defer tracy.end(); |
| 95 | 95 | const cpu_arch = macho_file.getTarget().cpu.arch; |
| ... | ... | @@ -174,7 +174,7 @@ pub const StubsHelperSection = struct { |
| 174 | 174 | return s; |
| 175 | 175 | } |
| 176 | 176 | |
| 177 | pub fn write(stubs_helper: StubsHelperSection, macho_file: *MachO, writer: anytype) !void { | |
| 177 | pub fn write(stubs_helper: StubsHelperSection, macho_file: *MachO, writer: *Writer) !void { | |
| 178 | 178 | const tracy = trace(@src()); |
| 179 | 179 | defer tracy.end(); |
| 180 | 180 | |
| ... | ... | @@ -217,7 +217,7 @@ pub const StubsHelperSection = struct { |
| 217 | 217 | } |
| 218 | 218 | } |
| 219 | 219 | |
| 220 | fn writePreamble(stubs_helper: StubsHelperSection, macho_file: *MachO, writer: anytype) !void { | |
| 220 | fn writePreamble(stubs_helper: StubsHelperSection, macho_file: *MachO, writer: *Writer) !void { | |
| 221 | 221 | _ = stubs_helper; |
| 222 | 222 | const obj = macho_file.getInternalObject().?; |
| 223 | 223 | const cpu_arch = macho_file.getTarget().cpu.arch; |
| ... | ... | @@ -273,7 +273,7 @@ pub const LaSymbolPtrSection = struct { |
| 273 | 273 | return macho_file.stubs.symbols.items.len * @sizeOf(u64); |
| 274 | 274 | } |
| 275 | 275 | |
| 276 | pub fn write(laptr: LaSymbolPtrSection, macho_file: *MachO, writer: anytype) !void { | |
| 276 | pub fn write(laptr: LaSymbolPtrSection, macho_file: *MachO, writer: *Writer) !void { | |
| 277 | 277 | const tracy = trace(@src()); |
| 278 | 278 | defer tracy.end(); |
| 279 | 279 | _ = laptr; |
| ... | ... | @@ -323,7 +323,7 @@ pub const TlvPtrSection = struct { |
| 323 | 323 | return tlv.symbols.items.len * @sizeOf(u64); |
| 324 | 324 | } |
| 325 | 325 | |
| 326 | pub fn write(tlv: TlvPtrSection, macho_file: *MachO, writer: anytype) !void { | |
| 326 | pub fn write(tlv: TlvPtrSection, macho_file: *MachO, writer: *Writer) !void { | |
| 327 | 327 | const tracy = trace(@src()); |
| 328 | 328 | defer tracy.end(); |
| 329 | 329 | |
| ... | ... | @@ -394,7 +394,7 @@ pub const ObjcStubsSection = struct { |
| 394 | 394 | return objc.symbols.items.len * entrySize(macho_file.getTarget().cpu.arch); |
| 395 | 395 | } |
| 396 | 396 | |
| 397 | pub fn write(objc: ObjcStubsSection, macho_file: *MachO, writer: anytype) !void { | |
| 397 | pub fn write(objc: ObjcStubsSection, macho_file: *MachO, writer: *Writer) !void { | |
| 398 | 398 | const tracy = trace(@src()); |
| 399 | 399 | defer tracy.end(); |
| 400 | 400 | |
| ... | ... | @@ -487,7 +487,7 @@ pub const Indsymtab = struct { |
| 487 | 487 | macho_file.dysymtab_cmd.nindirectsyms = ind.nsyms(macho_file); |
| 488 | 488 | } |
| 489 | 489 | |
| 490 | pub fn write(ind: Indsymtab, macho_file: *MachO, writer: anytype) !void { | |
| 490 | pub fn write(ind: Indsymtab, macho_file: *MachO, writer: *Writer) !void { | |
| 491 | 491 | const tracy = trace(@src()); |
| 492 | 492 | defer tracy.end(); |
| 493 | 493 | |
| ... | ... | @@ -564,7 +564,7 @@ pub const DataInCode = struct { |
| 564 | 564 | macho_file.data_in_code_cmd.datasize = math.cast(u32, dice.size()) orelse return error.Overflow; |
| 565 | 565 | } |
| 566 | 566 | |
| 567 | pub fn write(dice: DataInCode, macho_file: *MachO, writer: anytype) !void { | |
| 567 | pub fn write(dice: DataInCode, macho_file: *MachO, writer: *Writer) !void { | |
| 568 | 568 | const base_address = if (!macho_file.base.isRelocatable()) |
| 569 | 569 | macho_file.getTextSegment().vmaddr |
| 570 | 570 | else |
| ... | ... | @@ -572,11 +572,11 @@ pub const DataInCode = struct { |
| 572 | 572 | for (dice.entries.items) |entry| { |
| 573 | 573 | const atom_address = entry.atom_ref.getAtom(macho_file).?.getAddress(macho_file); |
| 574 | 574 | const offset = atom_address + entry.offset - base_address; |
| 575 | try writer.writeStruct(macho.data_in_code_entry{ | |
| 575 | try writer.writeStruct(@as(macho.data_in_code_entry, .{ | |
| 576 | 576 | .offset = @intCast(offset), |
| 577 | 577 | .length = entry.length, |
| 578 | 578 | .kind = entry.kind, |
| 579 | }); | |
| 579 | }), .little); | |
| 580 | 580 | } |
| 581 | 581 | } |
| 582 | 582 | |
| ... | ... | @@ -594,7 +594,7 @@ const assert = std.debug.assert; |
| 594 | 594 | const macho = std.macho; |
| 595 | 595 | const math = std.math; |
| 596 | 596 | const Allocator = std.mem.Allocator; |
| 597 | const Writer = std.io.Writer; | |
| 597 | const Writer = std.Io.Writer; | |
| 598 | 598 | |
| 599 | 599 | const trace = @import("../../tracy.zig").trace; |
| 600 | 600 | const MachO = @import("../MachO.zig"); |