Commit cc931660eb
Changed files (15)
lib/std/Io/Writer.zig
@@ -2381,6 +2381,7 @@ pub fn fromArrayList(array_list: *ArrayList(u8)) Writer {
.vtable = &.{
.drain = fixedDrain,
.flush = noopFlush,
+ .rebase = failingRebase,
},
.buffer = array_list.allocatedSlice(),
.end = array_list.items.len,
lib/std/macho.zig
@@ -1883,10 +1883,8 @@ pub const GenericBlob = extern struct {
pub const data_in_code_entry = extern struct {
/// From mach_header to start of data range.
offset: u32,
-
/// Number of bytes in data range.
length: u16,
-
/// A DICE_KIND value.
kind: u16,
};
src/link/MachO/dyld_info/bind.zig
@@ -132,12 +132,14 @@ pub const Bind = struct {
fn finalize(self: *Self, gpa: Allocator, ctx: *MachO) !void {
if (self.entries.items.len == 0) return;
- const writer = self.buffer.writer(gpa);
-
log.debug("bind opcodes", .{});
std.mem.sort(Entry, self.entries.items, ctx, Entry.lessThan);
+ var allocating: std.Io.Writer.Allocating = .fromArrayList(gpa, &self.buffer);
+ defer self.buffer = allocating.toArrayList();
+ const writer = &allocating.writer;
+
var start: usize = 0;
var seg_id: ?u8 = null;
for (self.entries.items, 0..) |entry, i| {
@@ -151,7 +153,7 @@ pub const Bind = struct {
try done(writer);
}
- fn finalizeSegment(entries: []const Entry, ctx: *MachO, writer: anytype) !void {
+ fn finalizeSegment(entries: []const Entry, ctx: *MachO, writer: *std.Io.Writer) !void {
if (entries.len == 0) return;
const seg_id = entries[0].segment_id;
@@ -263,7 +265,7 @@ pub const Bind = struct {
}
}
- pub fn write(self: Self, writer: anytype) !void {
+ pub fn write(self: Self, writer: *std.Io.Writer) !void {
try writer.writeAll(self.buffer.items);
}
};
@@ -385,12 +387,14 @@ pub const WeakBind = struct {
fn finalize(self: *Self, gpa: Allocator, ctx: *MachO) !void {
if (self.entries.items.len == 0) return;
- const writer = self.buffer.writer(gpa);
-
log.debug("weak bind opcodes", .{});
std.mem.sort(Entry, self.entries.items, ctx, Entry.lessThan);
+ var allocating: std.Io.Writer.Allocating = .fromArrayList(gpa, &self.buffer);
+ defer self.buffer = allocating.toArrayList();
+ const writer = &allocating.writer;
+
var start: usize = 0;
var seg_id: ?u8 = null;
for (self.entries.items, 0..) |entry, i| {
@@ -404,7 +408,7 @@ pub const WeakBind = struct {
try done(writer);
}
- fn finalizeSegment(entries: []const Entry, ctx: *MachO, writer: anytype) !void {
+ fn finalizeSegment(entries: []const Entry, ctx: *MachO, writer: *std.Io.Writer) !void {
if (entries.len == 0) return;
const seg_id = entries[0].segment_id;
@@ -505,7 +509,7 @@ pub const WeakBind = struct {
}
}
- pub fn write(self: Self, writer: anytype) !void {
+ pub fn write(self: Self, writer: *std.Io.Writer) !void {
try writer.writeAll(self.buffer.items);
}
};
@@ -555,8 +559,6 @@ pub const LazyBind = struct {
fn finalize(self: *Self, gpa: Allocator, ctx: *MachO) !void {
try self.offsets.ensureTotalCapacityPrecise(gpa, self.entries.items.len);
- const writer = self.buffer.writer(gpa);
-
log.debug("lazy bind opcodes", .{});
var addend: i64 = 0;
@@ -578,6 +580,9 @@ pub const LazyBind = struct {
break :ord macho.BIND_SPECIAL_DYLIB_SELF;
};
+ var allocating: std.Io.Writer.Allocating = .fromArrayList(gpa, &self.buffer);
+ defer self.buffer = allocating.toArrayList();
+ const writer = &allocating.writer;
try setSegmentOffset(entry.segment_id, entry.offset, writer);
try setSymbol(name, flags, writer);
try setDylibOrdinal(ordinal, writer);
@@ -592,30 +597,30 @@ pub const LazyBind = struct {
}
}
- pub fn write(self: Self, writer: anytype) !void {
+ pub fn write(self: Self, writer: *std.Io.Writer) !void {
try writer.writeAll(self.buffer.items);
}
};
-fn setSegmentOffset(segment_id: u8, offset: u64, writer: anytype) !void {
+fn setSegmentOffset(segment_id: u8, offset: u64, writer: *std.Io.Writer) !void {
log.debug(">>> set segment: {d} and offset: {x}", .{ segment_id, offset });
try writer.writeByte(macho.BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | @as(u4, @truncate(segment_id)));
try std.leb.writeUleb128(writer, offset);
}
-fn setSymbol(name: []const u8, flags: u8, writer: anytype) !void {
+fn setSymbol(name: []const u8, flags: u8, writer: *std.Io.Writer) !void {
log.debug(">>> set symbol: {s} with flags: {x}", .{ name, flags });
try writer.writeByte(macho.BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | @as(u4, @truncate(flags)));
try writer.writeAll(name);
try writer.writeByte(0);
}
-fn setTypePointer(writer: anytype) !void {
+fn setTypePointer(writer: *std.Io.Writer) !void {
log.debug(">>> set type: {d}", .{macho.BIND_TYPE_POINTER});
try writer.writeByte(macho.BIND_OPCODE_SET_TYPE_IMM | @as(u4, @truncate(macho.BIND_TYPE_POINTER)));
}
-fn setDylibOrdinal(ordinal: i16, writer: anytype) !void {
+fn setDylibOrdinal(ordinal: i16, writer: *std.Io.Writer) !void {
if (ordinal <= 0) {
switch (ordinal) {
macho.BIND_SPECIAL_DYLIB_SELF,
@@ -639,18 +644,18 @@ fn setDylibOrdinal(ordinal: i16, writer: anytype) !void {
}
}
-fn setAddend(addend: i64, writer: anytype) !void {
+fn setAddend(addend: i64, writer: *std.Io.Writer) !void {
log.debug(">>> set addend: {x}", .{addend});
try writer.writeByte(macho.BIND_OPCODE_SET_ADDEND_SLEB);
try std.leb.writeIleb128(writer, addend);
}
-fn doBind(writer: anytype) !void {
+fn doBind(writer: *std.Io.Writer) !void {
log.debug(">>> bind", .{});
try writer.writeByte(macho.BIND_OPCODE_DO_BIND);
}
-fn doBindAddAddr(addr: u64, writer: anytype) !void {
+fn doBindAddAddr(addr: u64, writer: *std.Io.Writer) !void {
log.debug(">>> bind with add: {x}", .{addr});
if (std.mem.isAlignedGeneric(u64, addr, @sizeOf(u64))) {
const imm = @divExact(addr, @sizeOf(u64));
@@ -665,20 +670,20 @@ fn doBindAddAddr(addr: u64, writer: anytype) !void {
try std.leb.writeUleb128(writer, addr);
}
-fn doBindTimesSkip(count: usize, skip: u64, writer: anytype) !void {
+fn doBindTimesSkip(count: usize, skip: u64, writer: *std.Io.Writer) !void {
log.debug(">>> bind with count: {d} and skip: {x}", .{ count, skip });
try writer.writeByte(macho.BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB);
try std.leb.writeUleb128(writer, count);
try std.leb.writeUleb128(writer, skip);
}
-fn addAddr(addr: u64, writer: anytype) !void {
+fn addAddr(addr: u64, writer: *std.Io.Writer) !void {
log.debug(">>> add: {x}", .{addr});
try writer.writeByte(macho.BIND_OPCODE_ADD_ADDR_ULEB);
try std.leb.writeUleb128(writer, addr);
}
-fn done(writer: anytype) !void {
+fn done(writer: *std.Io.Writer) !void {
log.debug(">>> done", .{});
try writer.writeByte(macho.BIND_OPCODE_DONE);
}
src/link/MachO/dyld_info/Rebase.zig
@@ -110,12 +110,14 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void {
fn finalize(rebase: *Rebase, gpa: Allocator) !void {
if (rebase.entries.items.len == 0) return;
- const writer = rebase.buffer.writer(gpa);
-
log.debug("rebase opcodes", .{});
std.mem.sort(Entry, rebase.entries.items, {}, Entry.lessThan);
+ var allocating: std.Io.Writer.Allocating = .fromArrayList(gpa, &rebase.buffer);
+ defer rebase.buffer = allocating.toArrayList();
+ const writer = &allocating.writer;
+
try setTypePointer(writer);
var start: usize = 0;
src/link/MachO/dyld_info/Trie.zig
@@ -170,8 +170,13 @@ fn finalize(self: *Trie, allocator: Allocator) !void {
}
try self.buffer.ensureTotalCapacityPrecise(allocator, size);
+
+ var allocating: std.Io.Writer.Allocating = .fromArrayList(allocator, &self.buffer);
+ defer self.buffer = allocating.toArrayList();
+ const writer = &allocating.writer;
+
for (ordered_nodes.items) |node_index| {
- try self.writeNode(node_index, self.buffer.writer(allocator));
+ try self.writeNode(node_index, writer);
}
}
@@ -232,7 +237,7 @@ pub fn deinit(self: *Trie, allocator: Allocator) void {
self.buffer.deinit(allocator);
}
-pub fn write(self: Trie, writer: anytype) !void {
+pub fn write(self: Trie, writer: *std.Io.Writer) !void {
if (self.buffer.items.len == 0) return;
try writer.writeAll(self.buffer.items);
}
@@ -243,7 +248,7 @@ pub fn write(self: Trie, writer: anytype) !void {
/// iterate over `Trie.ordered_nodes` and call this method on each node.
/// This is one of the requirements of the MachO.
/// Panics if `finalize` was not called before calling this method.
-fn writeNode(self: *Trie, node_index: Node.Index, writer: anytype) !void {
+fn writeNode(self: *Trie, node_index: Node.Index, writer: *std.Io.Writer) !void {
const slice = self.nodes.slice();
const edges = slice.items(.edges)[node_index];
const is_terminal = slice.items(.is_terminal)[node_index];
@@ -253,21 +258,21 @@ fn writeNode(self: *Trie, node_index: Node.Index, writer: anytype) !void {
if (is_terminal) {
// Terminal node info: encode export flags and vmaddr offset of this symbol.
var info_buf: [@sizeOf(u64) * 2]u8 = undefined;
- var info_stream = std.io.fixedBufferStream(&info_buf);
+ var info_stream: std.Io.Writer = .fixed(&info_buf);
// TODO Implement for special flags.
assert(export_flags & macho.EXPORT_SYMBOL_FLAGS_REEXPORT == 0 and
export_flags & macho.EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER == 0);
- try leb.writeUleb128(info_stream.writer(), export_flags);
- try leb.writeUleb128(info_stream.writer(), vmaddr_offset);
+ try leb.writeUleb128(&info_stream, export_flags);
+ try leb.writeUleb128(&info_stream, vmaddr_offset);
// Encode the size of the terminal node info.
var size_buf: [@sizeOf(u64)]u8 = undefined;
- var size_stream = std.io.fixedBufferStream(&size_buf);
- try leb.writeUleb128(size_stream.writer(), info_stream.pos);
+ var size_stream: std.Io.Writer = .fixed(&size_buf);
+ try leb.writeUleb128(&size_stream, info_stream.end);
// Now, write them to the output stream.
- try writer.writeAll(size_buf[0..size_stream.pos]);
- try writer.writeAll(info_buf[0..info_stream.pos]);
+ try writer.writeAll(size_buf[0..size_stream.end]);
+ try writer.writeAll(info_buf[0..info_stream.end]);
} else {
// Non-terminal node is delimited by 0 byte.
try writer.writeByte(0);
src/link/MachO/Archive.zig
@@ -81,34 +81,20 @@ pub fn writeHeader(
object_name: []const u8,
object_size: usize,
format: Format,
- writer: anytype,
+ writer: *Writer,
) !void {
- var hdr: ar_hdr = .{
- .ar_name = undefined,
- .ar_date = undefined,
- .ar_uid = undefined,
- .ar_gid = undefined,
- .ar_mode = undefined,
- .ar_size = undefined,
- .ar_fmag = undefined,
- };
- @memset(mem.asBytes(&hdr), 0x20);
- inline for (@typeInfo(ar_hdr).@"struct".fields) |field| {
- var stream = std.io.fixedBufferStream(&@field(hdr, field.name));
- stream.writer().print("0", .{}) catch unreachable;
- }
- @memcpy(&hdr.ar_fmag, ARFMAG);
+ var hdr: ar_hdr = .{};
const object_name_len = mem.alignForward(usize, object_name.len + 1, ptrWidth(format));
const total_object_size = object_size + object_name_len;
{
- var stream = std.io.fixedBufferStream(&hdr.ar_name);
- stream.writer().print("#1/{d}", .{object_name_len}) catch unreachable;
+ var stream: Writer = .fixed(&hdr.ar_name);
+ stream.print("#1/{d}", .{object_name_len}) catch unreachable;
}
{
- var stream = std.io.fixedBufferStream(&hdr.ar_size);
- stream.writer().print("{d}", .{total_object_size}) catch unreachable;
+ var stream: Writer = .fixed(&hdr.ar_size);
+ stream.print("{d}", .{total_object_size}) catch unreachable;
}
try writer.writeAll(mem.asBytes(&hdr));
@@ -116,7 +102,7 @@ pub fn writeHeader(
const padding = object_name_len - object_name.len - 1;
if (padding > 0) {
- try writer.writeByteNTimes(0, padding);
+ try writer.splatByteAll(0, padding);
}
}
@@ -138,25 +124,19 @@ pub const SYMDEF64_SORTED = "__.SYMDEF_64 SORTED";
pub const ar_hdr = extern struct {
/// Member file name, sometimes / terminated.
- ar_name: [16]u8,
-
+ ar_name: [16]u8 = "0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20".*,
/// File date, decimal seconds since Epoch.
- ar_date: [12]u8,
-
+ ar_date: [12]u8 = "0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20".*,
/// User ID, in ASCII format.
- ar_uid: [6]u8,
-
+ ar_uid: [6]u8 = "0\x20\x20\x20\x20\x20".*,
/// Group ID, in ASCII format.
- ar_gid: [6]u8,
-
+ ar_gid: [6]u8 = "0\x20\x20\x20\x20\x20".*,
/// File mode, in ASCII octal.
- ar_mode: [8]u8,
-
+ ar_mode: [8]u8 = "0\x20\x20\x20\x20\x20\x20\x20".*,
/// File size, in ASCII decimal.
- ar_size: [10]u8,
-
+ ar_size: [10]u8 = "0\x20\x20\x20\x20\x20\x20\x20\x20\x20".*,
/// Always contains ARFMAG.
- ar_fmag: [2]u8,
+ ar_fmag: [2]u8 = ARFMAG.*,
fn date(self: ar_hdr) !u64 {
const value = mem.trimEnd(u8, &self.ar_date, &[_]u8{@as(u8, 0x20)});
@@ -201,7 +181,7 @@ pub const ArSymtab = struct {
return ptr_width + ar.entries.items.len * 2 * ptr_width + ptr_width + mem.alignForward(usize, ar.strtab.buffer.items.len, ptr_width);
}
- pub fn write(ar: ArSymtab, format: Format, macho_file: *MachO, writer: anytype) !void {
+ pub fn write(ar: ArSymtab, format: Format, macho_file: *MachO, writer: *Writer) !void {
const ptr_width = ptrWidth(format);
// Header
try writeHeader(SYMDEF, ar.size(format), format, writer);
@@ -226,7 +206,7 @@ pub const ArSymtab = struct {
// Strtab
try writer.writeAll(ar.strtab.buffer.items);
if (padding > 0) {
- try writer.writeByteNTimes(0, padding);
+ try writer.splatByteAll(0, padding);
}
}
@@ -275,7 +255,7 @@ pub fn ptrWidth(format: Format) usize {
};
}
-pub fn writeInt(format: Format, value: u64, writer: anytype) !void {
+pub fn writeInt(format: Format, value: u64, writer: *Writer) !void {
switch (format) {
.p32 => try writer.writeInt(u32, std.math.cast(u32, value) orelse return error.Overflow, .little),
.p64 => try writer.writeInt(u64, value, .little),
@@ -299,7 +279,7 @@ const mem = std.mem;
const std = @import("std");
const Allocator = std.mem.Allocator;
const Path = std.Build.Cache.Path;
-const Writer = std.io.Writer;
+const Writer = std.Io.Writer;
const Archive = @This();
const File = @import("file.zig").File;
src/link/MachO/Atom.zig
@@ -581,7 +581,7 @@ pub fn resolveRelocs(self: Atom, macho_file: *MachO, buffer: []u8) !void {
relocs_log.debug("{x}: {s}", .{ self.value, name });
var has_error = false;
- var stream = std.io.fixedBufferStream(buffer);
+ var stream: Writer = .fixed(buffer);
var i: usize = 0;
while (i < relocs.len) : (i += 1) {
const rel = relocs[i];
@@ -592,8 +592,8 @@ pub fn resolveRelocs(self: Atom, macho_file: *MachO, buffer: []u8) !void {
if (rel.getTargetSymbol(self, macho_file).getFile(macho_file) == null) continue;
}
- try stream.seekTo(rel_offset);
- self.resolveRelocInner(rel, subtractor, buffer, macho_file, stream.writer()) catch |err| {
+ stream.end = rel_offset;
+ self.resolveRelocInner(rel, subtractor, buffer, macho_file, &stream) catch |err| {
switch (err) {
error.RelaxFail => {
const target = switch (rel.tag) {
@@ -630,6 +630,7 @@ const ResolveError = error{
UnexpectedRemainder,
Overflow,
OutOfMemory,
+ WriteFailed,
};
fn resolveRelocInner(
@@ -638,7 +639,7 @@ fn resolveRelocInner(
subtractor: ?Relocation,
code: []u8,
macho_file: *MachO,
- writer: anytype,
+ writer: *Writer,
) ResolveError!void {
const t = &macho_file.base.comp.root_mod.resolved_target.result;
const cpu_arch = t.cpu.arch;
@@ -1147,7 +1148,7 @@ const math = std.math;
const mem = std.mem;
const log = std.log.scoped(.link);
const relocs_log = std.log.scoped(.link_relocs);
-const Writer = std.io.Writer;
+const Writer = std.Io.Writer;
const Allocator = mem.Allocator;
const AtomicBool = std.atomic.Value(bool);
src/link/MachO/CodeSignature.zig
@@ -304,10 +304,10 @@ pub fn writeAdhocSignature(
var hash: [hash_size]u8 = undefined;
if (self.requirements) |*req| {
- var buf = std.array_list.Managed(u8).init(allocator);
- defer buf.deinit();
- try req.write(buf.writer());
- Sha256.hash(buf.items, &hash, .{});
+ var a: std.Io.Writer.Allocating = .init(allocator);
+ defer a.deinit();
+ try req.write(&a.writer);
+ Sha256.hash(a.written(), &hash, .{});
self.code_directory.addSpecialHash(req.slotType(), hash);
try blobs.append(.{ .requirements = req });
@@ -316,10 +316,10 @@ pub fn writeAdhocSignature(
}
if (self.entitlements) |*ents| {
- var buf = std.array_list.Managed(u8).init(allocator);
- defer buf.deinit();
- try ents.write(buf.writer());
- Sha256.hash(buf.items, &hash, .{});
+ var a: std.Io.Writer.Allocating = .init(allocator);
+ defer a.deinit();
+ try ents.write(&a.writer);
+ Sha256.hash(a.written(), &hash, .{});
self.code_directory.addSpecialHash(ents.slotType(), hash);
try blobs.append(.{ .entitlements = ents });
src/link/MachO/DebugSymbols.zig
@@ -273,14 +273,13 @@ fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, u
const buffer = try gpa.alloc(u8, needed_size);
defer gpa.free(buffer);
- var stream = std.io.fixedBufferStream(buffer);
- const writer = stream.writer();
+ var writer: Writer = .fixed(buffer);
var ncmds: usize = 0;
// UUID comes first presumably to speed up lookup by the consumer like lldb.
@memcpy(&self.uuid_cmd.uuid, &macho_file.uuid_cmd.uuid);
- try writer.writeStruct(self.uuid_cmd);
+ try writer.writeStruct(self.uuid_cmd, .little);
ncmds += 1;
// Segment and section load commands
@@ -293,11 +292,11 @@ fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, u
var out_seg = seg;
out_seg.fileoff = 0;
out_seg.filesize = 0;
- try writer.writeStruct(out_seg);
+ try writer.writeStruct(out_seg, .little);
for (slice.items(.header)[sect_id..][0..seg.nsects]) |header| {
var out_header = header;
out_header.offset = 0;
- try writer.writeStruct(out_header);
+ try writer.writeStruct(out_header, .little);
}
sect_id += seg.nsects;
}
@@ -306,19 +305,19 @@ fn writeLoadCommands(self: *DebugSymbols, macho_file: *MachO) !struct { usize, u
// Next, commit DSYM's __LINKEDIT and __DWARF segments headers.
sect_id = 0;
for (self.segments.items) |seg| {
- try writer.writeStruct(seg);
+ try writer.writeStruct(seg, .little);
for (self.sections.items[sect_id..][0..seg.nsects]) |header| {
- try writer.writeStruct(header);
+ try writer.writeStruct(header, .little);
}
sect_id += seg.nsects;
}
ncmds += self.segments.items.len;
}
- try writer.writeStruct(self.symtab_cmd);
+ try writer.writeStruct(self.symtab_cmd, .little);
ncmds += 1;
- assert(stream.pos == needed_size);
+ assert(writer.end == needed_size);
try self.file.?.pwriteAll(buffer, @sizeOf(macho.mach_header_64));
@@ -460,7 +459,7 @@ const math = std.math;
const mem = std.mem;
const padToIdeal = MachO.padToIdeal;
const trace = @import("../../tracy.zig").trace;
-const Writer = std.io.Writer;
+const Writer = std.Io.Writer;
const Allocator = mem.Allocator;
const MachO = @import("../MachO.zig");
src/link/MachO/InternalObject.zig
@@ -261,7 +261,7 @@ fn addObjcMethnameSection(self: *InternalObject, methname: []const u8, macho_fil
sect.offset = @intCast(self.objc_methnames.items.len);
try self.objc_methnames.ensureUnusedCapacity(gpa, methname.len + 1);
- self.objc_methnames.writer(gpa).print("{s}\x00", .{methname}) catch unreachable;
+ self.objc_methnames.print(gpa, "{s}\x00", .{methname}) catch unreachable;
const name_str = try self.addString(gpa, "ltmp");
const sym_index = try self.addSymbol(gpa);
src/link/MachO/load_commands.zig
@@ -3,9 +3,9 @@ const assert = std.debug.assert;
const log = std.log.scoped(.link);
const macho = std.macho;
const mem = std.mem;
-const Writer = std.io.Writer;
+const Writer = std.Io.Writer;
+const Allocator = std.mem.Allocator;
-const Allocator = mem.Allocator;
const DebugSymbols = @import("DebugSymbols.zig");
const Dylib = @import("Dylib.zig");
const MachO = @import("../MachO.zig");
@@ -181,22 +181,22 @@ pub fn calcMinHeaderPadSize(macho_file: *MachO) !u32 {
return offset;
}
-pub fn writeDylinkerLC(writer: anytype) !void {
+pub fn writeDylinkerLC(writer: *Writer) !void {
const name_len = mem.sliceTo(default_dyld_path, 0).len;
const cmdsize = @as(u32, @intCast(mem.alignForward(
u64,
@sizeOf(macho.dylinker_command) + name_len,
@sizeOf(u64),
)));
- try writer.writeStruct(macho.dylinker_command{
+ try writer.writeStruct(@as(macho.dylinker_command, .{
.cmd = .LOAD_DYLINKER,
.cmdsize = cmdsize,
.name = @sizeOf(macho.dylinker_command),
- });
+ }), .little);
try writer.writeAll(mem.sliceTo(default_dyld_path, 0));
const padding = cmdsize - @sizeOf(macho.dylinker_command) - name_len;
if (padding > 0) {
- try writer.writeByteNTimes(0, padding);
+ try writer.splatByteAll(0, padding);
}
}
@@ -208,14 +208,14 @@ const WriteDylibLCCtx = struct {
compatibility_version: u32 = 0x10000,
};
-pub fn writeDylibLC(ctx: WriteDylibLCCtx, writer: anytype) !void {
+pub fn writeDylibLC(ctx: WriteDylibLCCtx, writer: *Writer) !void {
const name_len = ctx.name.len + 1;
const cmdsize = @as(u32, @intCast(mem.alignForward(
u64,
@sizeOf(macho.dylib_command) + name_len,
@sizeOf(u64),
)));
- try writer.writeStruct(macho.dylib_command{
+ try writer.writeStruct(@as(macho.dylib_command, .{
.cmd = ctx.cmd,
.cmdsize = cmdsize,
.dylib = .{
@@ -224,16 +224,16 @@ pub fn writeDylibLC(ctx: WriteDylibLCCtx, writer: anytype) !void {
.current_version = ctx.current_version,
.compatibility_version = ctx.compatibility_version,
},
- });
+ }), .little);
try writer.writeAll(ctx.name);
try writer.writeByte(0);
const padding = cmdsize - @sizeOf(macho.dylib_command) - name_len;
if (padding > 0) {
- try writer.writeByteNTimes(0, padding);
+ try writer.splatByteAll(0, padding);
}
}
-pub fn writeDylibIdLC(macho_file: *MachO, writer: anytype) !void {
+pub fn writeDylibIdLC(macho_file: *MachO, writer: *Writer) !void {
const comp = macho_file.base.comp;
const gpa = comp.gpa;
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 {
}, writer);
}
-pub fn writeRpathLC(rpath: []const u8, writer: anytype) !void {
+pub fn writeRpathLC(rpath: []const u8, writer: *Writer) !void {
const rpath_len = rpath.len + 1;
const cmdsize = @as(u32, @intCast(mem.alignForward(
u64,
@sizeOf(macho.rpath_command) + rpath_len,
@sizeOf(u64),
)));
- try writer.writeStruct(macho.rpath_command{
+ try writer.writeStruct(@as(macho.rpath_command, .{
.cmdsize = cmdsize,
.path = @sizeOf(macho.rpath_command),
- });
+ }), .little);
try writer.writeAll(rpath);
try writer.writeByte(0);
const padding = cmdsize - @sizeOf(macho.rpath_command) - rpath_len;
if (padding > 0) {
- try writer.writeByteNTimes(0, padding);
+ try writer.splatByteAll(0, padding);
}
}
-pub fn writeVersionMinLC(platform: MachO.Platform, sdk_version: ?std.SemanticVersion, writer: anytype) !void {
+pub fn writeVersionMinLC(platform: MachO.Platform, sdk_version: ?std.SemanticVersion, writer: *Writer) !void {
const cmd: macho.LC = switch (platform.os_tag) {
.macos => .VERSION_MIN_MACOSX,
.ios => .VERSION_MIN_IPHONEOS,
@@ -296,9 +296,9 @@ pub fn writeVersionMinLC(platform: MachO.Platform, sdk_version: ?std.SemanticVer
}));
}
-pub fn writeBuildVersionLC(platform: MachO.Platform, sdk_version: ?std.SemanticVersion, writer: anytype) !void {
+pub fn writeBuildVersionLC(platform: MachO.Platform, sdk_version: ?std.SemanticVersion, writer: *Writer) !void {
const cmdsize = @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version);
- try writer.writeStruct(macho.build_version_command{
+ try writer.writeStruct(@as(macho.build_version_command, .{
.cmdsize = cmdsize,
.platform = platform.toApplePlatform(),
.minos = platform.toAppleVersion(),
@@ -307,7 +307,7 @@ pub fn writeBuildVersionLC(platform: MachO.Platform, sdk_version: ?std.SemanticV
else
platform.toAppleVersion(),
.ntools = 1,
- });
+ }), .little);
try writer.writeAll(mem.asBytes(&macho.build_tool_version{
.tool = .ZIG,
.version = 0x0,
src/link/MachO/relocatable.zig
@@ -205,35 +205,32 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?
state_log.debug("ar_symtab\n{f}\n", .{ar_symtab.fmt(macho_file)});
}
- var buffer = std.array_list.Managed(u8).init(gpa);
- defer buffer.deinit();
- try buffer.ensureTotalCapacityPrecise(total_size);
- const writer = buffer.writer();
+ const buffer = try gpa.alloc(u8, total_size);
+ defer gpa.free(buffer);
+ var writer: Writer = .fixed(buffer);
// Write magic
- try writer.writeAll(Archive.ARMAG);
+ writer.writeAll(Archive.ARMAG) catch unreachable;
// Write symtab
- ar_symtab.write(format, macho_file, writer) catch |err| switch (err) {
- error.OutOfMemory => return error.OutOfMemory,
- else => |e| return diags.fail("failed to write archive symbol table: {s}", .{@errorName(e)}),
- };
+ ar_symtab.write(format, macho_file, &writer) catch |err|
+ return diags.fail("failed to write archive symbol table: {t}", .{err});
// Write object files
for (files.items) |index| {
- const aligned = mem.alignForward(usize, buffer.items.len, 2);
- const padding = aligned - buffer.items.len;
+ const aligned = mem.alignForward(usize, writer.end, 2);
+ const padding = aligned - writer.end;
if (padding > 0) {
- try writer.writeByteNTimes(0, padding);
+ writer.splatByteAll(0, padding) catch unreachable;
}
- macho_file.getFile(index).?.writeAr(format, macho_file, writer) catch |err|
- return diags.fail("failed to write archive: {s}", .{@errorName(err)});
+ macho_file.getFile(index).?.writeAr(format, macho_file, &writer) catch |err|
+ return diags.fail("failed to write archive: {t}", .{err});
}
- assert(buffer.items.len == total_size);
+ assert(writer.end == total_size);
try macho_file.setEndPos(total_size);
- try macho_file.pwriteAll(buffer.items, 0);
+ try macho_file.pwriteAll(writer.buffered(), 0);
if (diags.hasErrors()) return error.LinkFailure;
}
@@ -693,8 +690,7 @@ fn writeLoadCommands(macho_file: *MachO) error{ LinkFailure, OutOfMemory }!struc
const buffer = try gpa.alloc(u8, needed_size);
defer gpa.free(buffer);
- var stream = std.io.fixedBufferStream(buffer);
- const writer = stream.writer();
+ var writer: Writer = .fixed(buffer);
var ncmds: usize = 0;
@@ -702,43 +698,43 @@ fn writeLoadCommands(macho_file: *MachO) error{ LinkFailure, OutOfMemory }!struc
{
assert(macho_file.segments.items.len == 1);
const seg = macho_file.segments.items[0];
- writer.writeStruct(seg) catch |err| switch (err) {
- error.NoSpaceLeft => unreachable,
+ writer.writeStruct(seg, .little) catch |err| switch (err) {
+ error.WriteFailed => unreachable,
};
for (macho_file.sections.items(.header)) |header| {
- writer.writeStruct(header) catch |err| switch (err) {
- error.NoSpaceLeft => unreachable,
+ writer.writeStruct(header, .little) catch |err| switch (err) {
+ error.WriteFailed => unreachable,
};
}
ncmds += 1;
}
- writer.writeStruct(macho_file.data_in_code_cmd) catch |err| switch (err) {
- error.NoSpaceLeft => unreachable,
+ writer.writeStruct(macho_file.data_in_code_cmd, .little) catch |err| switch (err) {
+ error.WriteFailed => unreachable,
};
ncmds += 1;
- writer.writeStruct(macho_file.symtab_cmd) catch |err| switch (err) {
- error.NoSpaceLeft => unreachable,
+ writer.writeStruct(macho_file.symtab_cmd, .little) catch |err| switch (err) {
+ error.WriteFailed => unreachable,
};
ncmds += 1;
- writer.writeStruct(macho_file.dysymtab_cmd) catch |err| switch (err) {
- error.NoSpaceLeft => unreachable,
+ writer.writeStruct(macho_file.dysymtab_cmd, .little) catch |err| switch (err) {
+ error.WriteFailed => unreachable,
};
ncmds += 1;
if (macho_file.platform.isBuildVersionCompatible()) {
- load_commands.writeBuildVersionLC(macho_file.platform, macho_file.sdk_version, writer) catch |err| switch (err) {
- error.NoSpaceLeft => unreachable,
+ load_commands.writeBuildVersionLC(macho_file.platform, macho_file.sdk_version, &writer) catch |err| switch (err) {
+ error.WriteFailed => unreachable,
};
ncmds += 1;
} else {
- load_commands.writeVersionMinLC(macho_file.platform, macho_file.sdk_version, writer) catch |err| switch (err) {
- error.NoSpaceLeft => unreachable,
+ load_commands.writeVersionMinLC(macho_file.platform, macho_file.sdk_version, &writer) catch |err| switch (err) {
+ error.WriteFailed => unreachable,
};
ncmds += 1;
}
- assert(stream.pos == needed_size);
+ assert(writer.end == needed_size);
try macho_file.pwriteAll(buffer, @sizeOf(macho.mach_header_64));
src/link/MachO/synthetic.zig
@@ -27,7 +27,7 @@ pub const GotSection = struct {
return got.symbols.items.len * @sizeOf(u64);
}
- pub fn write(got: GotSection, macho_file: *MachO, writer: anytype) !void {
+ pub fn write(got: GotSection, macho_file: *MachO, writer: *Writer) !void {
const tracy = trace(@src());
defer tracy.end();
for (got.symbols.items) |ref| {
@@ -89,7 +89,7 @@ pub const StubsSection = struct {
return stubs.symbols.items.len * header.reserved2;
}
- pub fn write(stubs: StubsSection, macho_file: *MachO, writer: anytype) !void {
+ pub fn write(stubs: StubsSection, macho_file: *MachO, writer: *Writer) !void {
const tracy = trace(@src());
defer tracy.end();
const cpu_arch = macho_file.getTarget().cpu.arch;
@@ -174,7 +174,7 @@ pub const StubsHelperSection = struct {
return s;
}
- pub fn write(stubs_helper: StubsHelperSection, macho_file: *MachO, writer: anytype) !void {
+ pub fn write(stubs_helper: StubsHelperSection, macho_file: *MachO, writer: *Writer) !void {
const tracy = trace(@src());
defer tracy.end();
@@ -217,7 +217,7 @@ pub const StubsHelperSection = struct {
}
}
- fn writePreamble(stubs_helper: StubsHelperSection, macho_file: *MachO, writer: anytype) !void {
+ fn writePreamble(stubs_helper: StubsHelperSection, macho_file: *MachO, writer: *Writer) !void {
_ = stubs_helper;
const obj = macho_file.getInternalObject().?;
const cpu_arch = macho_file.getTarget().cpu.arch;
@@ -273,7 +273,7 @@ pub const LaSymbolPtrSection = struct {
return macho_file.stubs.symbols.items.len * @sizeOf(u64);
}
- pub fn write(laptr: LaSymbolPtrSection, macho_file: *MachO, writer: anytype) !void {
+ pub fn write(laptr: LaSymbolPtrSection, macho_file: *MachO, writer: *Writer) !void {
const tracy = trace(@src());
defer tracy.end();
_ = laptr;
@@ -323,7 +323,7 @@ pub const TlvPtrSection = struct {
return tlv.symbols.items.len * @sizeOf(u64);
}
- pub fn write(tlv: TlvPtrSection, macho_file: *MachO, writer: anytype) !void {
+ pub fn write(tlv: TlvPtrSection, macho_file: *MachO, writer: *Writer) !void {
const tracy = trace(@src());
defer tracy.end();
@@ -394,7 +394,7 @@ pub const ObjcStubsSection = struct {
return objc.symbols.items.len * entrySize(macho_file.getTarget().cpu.arch);
}
- pub fn write(objc: ObjcStubsSection, macho_file: *MachO, writer: anytype) !void {
+ pub fn write(objc: ObjcStubsSection, macho_file: *MachO, writer: *Writer) !void {
const tracy = trace(@src());
defer tracy.end();
@@ -487,7 +487,7 @@ pub const Indsymtab = struct {
macho_file.dysymtab_cmd.nindirectsyms = ind.nsyms(macho_file);
}
- pub fn write(ind: Indsymtab, macho_file: *MachO, writer: anytype) !void {
+ pub fn write(ind: Indsymtab, macho_file: *MachO, writer: *Writer) !void {
const tracy = trace(@src());
defer tracy.end();
@@ -564,7 +564,7 @@ pub const DataInCode = struct {
macho_file.data_in_code_cmd.datasize = math.cast(u32, dice.size()) orelse return error.Overflow;
}
- pub fn write(dice: DataInCode, macho_file: *MachO, writer: anytype) !void {
+ pub fn write(dice: DataInCode, macho_file: *MachO, writer: *Writer) !void {
const base_address = if (!macho_file.base.isRelocatable())
macho_file.getTextSegment().vmaddr
else
@@ -572,11 +572,11 @@ pub const DataInCode = struct {
for (dice.entries.items) |entry| {
const atom_address = entry.atom_ref.getAtom(macho_file).?.getAddress(macho_file);
const offset = atom_address + entry.offset - base_address;
- try writer.writeStruct(macho.data_in_code_entry{
+ try writer.writeStruct(@as(macho.data_in_code_entry, .{
.offset = @intCast(offset),
.length = entry.length,
.kind = entry.kind,
- });
+ }), .little);
}
}
@@ -594,7 +594,7 @@ const assert = std.debug.assert;
const macho = std.macho;
const math = std.math;
const Allocator = std.mem.Allocator;
-const Writer = std.io.Writer;
+const Writer = std.Io.Writer;
const trace = @import("../../tracy.zig").trace;
const MachO = @import("../MachO.zig");
src/link/MachO/UnwindInfo.zig
@@ -293,8 +293,7 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void {
const seg = macho_file.getTextSegment();
const header = macho_file.sections.items(.header)[macho_file.unwind_info_sect_index.?];
- var stream = std.io.fixedBufferStream(buffer);
- const writer = stream.writer();
+ var writer: Writer = .fixed(buffer);
const common_encodings_offset: u32 = @sizeOf(macho.unwind_info_section_header);
const common_encodings_count: u32 = info.common_encodings_count;
@@ -303,14 +302,14 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void {
const indexes_offset: u32 = personalities_offset + personalities_count * @sizeOf(u32);
const indexes_count: u32 = @as(u32, @intCast(info.pages.items.len + 1));
- try writer.writeStruct(macho.unwind_info_section_header{
+ try writer.writeStruct(@as(macho.unwind_info_section_header, .{
.commonEncodingsArraySectionOffset = common_encodings_offset,
.commonEncodingsArrayCount = common_encodings_count,
.personalityArraySectionOffset = personalities_offset,
.personalityArrayCount = personalities_count,
.indexSectionOffset = indexes_offset,
.indexCount = indexes_count,
- });
+ }), .little);
try writer.writeAll(mem.sliceAsBytes(info.common_encodings[0..info.common_encodings_count]));
@@ -325,42 +324,42 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void {
for (info.pages.items, 0..) |page, i| {
assert(page.count > 0);
const rec = info.records.items[page.start].getUnwindRecord(macho_file);
- try writer.writeStruct(macho.unwind_info_section_header_index_entry{
+ try writer.writeStruct(@as(macho.unwind_info_section_header_index_entry, .{
.functionOffset = @as(u32, @intCast(rec.getAtomAddress(macho_file) - seg.vmaddr)),
.secondLevelPagesSectionOffset = @as(u32, @intCast(pages_base_offset + i * second_level_page_bytes)),
.lsdaIndexArraySectionOffset = lsda_base_offset +
info.lsdas_lookup.items[page.start] * @sizeOf(macho.unwind_info_section_header_lsda_index_entry),
- });
+ }), .little);
}
const last_rec = info.records.items[info.records.items.len - 1].getUnwindRecord(macho_file);
const sentinel_address = @as(u32, @intCast(last_rec.getAtomAddress(macho_file) + last_rec.length - seg.vmaddr));
- try writer.writeStruct(macho.unwind_info_section_header_index_entry{
+ try writer.writeStruct(@as(macho.unwind_info_section_header_index_entry, .{
.functionOffset = sentinel_address,
.secondLevelPagesSectionOffset = 0,
.lsdaIndexArraySectionOffset = lsda_base_offset +
@as(u32, @intCast(info.lsdas.items.len)) * @sizeOf(macho.unwind_info_section_header_lsda_index_entry),
- });
+ }), .little);
for (info.lsdas.items) |index| {
const rec = info.records.items[index].getUnwindRecord(macho_file);
- try writer.writeStruct(macho.unwind_info_section_header_lsda_index_entry{
+ try writer.writeStruct(@as(macho.unwind_info_section_header_lsda_index_entry, .{
.functionOffset = @as(u32, @intCast(rec.getAtomAddress(macho_file) - seg.vmaddr)),
.lsdaOffset = @as(u32, @intCast(rec.getLsdaAddress(macho_file) - seg.vmaddr)),
- });
+ }), .little);
}
for (info.pages.items) |page| {
- const start = stream.pos;
- try page.write(info, macho_file, writer);
- const nwritten = stream.pos - start;
+ const start = writer.end;
+ try page.write(info, macho_file, &writer);
+ const nwritten = writer.end - start;
if (nwritten < second_level_page_bytes) {
const padding = math.cast(usize, second_level_page_bytes - nwritten) orelse return error.Overflow;
- try writer.writeByteNTimes(0, padding);
+ try writer.splatByteAll(0, padding);
}
}
- @memset(buffer[stream.pos..], 0);
+ @memset(buffer[writer.end..], 0);
}
fn getOrPutPersonalityFunction(info: *UnwindInfo, ref: MachO.Ref) error{TooManyPersonalities}!u2 {
@@ -611,33 +610,33 @@ const Page = struct {
} };
}
- fn write(page: Page, info: UnwindInfo, macho_file: *MachO, writer: anytype) !void {
+ fn write(page: Page, info: UnwindInfo, macho_file: *MachO, writer: *Writer) !void {
const seg = macho_file.getTextSegment();
switch (page.kind) {
.regular => {
- try writer.writeStruct(macho.unwind_info_regular_second_level_page_header{
+ try writer.writeStruct(@as(macho.unwind_info_regular_second_level_page_header, .{
.entryPageOffset = @sizeOf(macho.unwind_info_regular_second_level_page_header),
.entryCount = page.count,
- });
+ }), .little);
for (info.records.items[page.start..][0..page.count]) |ref| {
const rec = ref.getUnwindRecord(macho_file);
- try writer.writeStruct(macho.unwind_info_regular_second_level_entry{
+ try writer.writeStruct(@as(macho.unwind_info_regular_second_level_entry, .{
.functionOffset = @as(u32, @intCast(rec.getAtomAddress(macho_file) - seg.vmaddr)),
.encoding = rec.enc.enc,
- });
+ }), .little);
}
},
.compressed => {
const entry_offset = @sizeOf(macho.unwind_info_compressed_second_level_page_header) +
@as(u16, @intCast(page.page_encodings_count)) * @sizeOf(u32);
- try writer.writeStruct(macho.unwind_info_compressed_second_level_page_header{
+ try writer.writeStruct(@as(macho.unwind_info_compressed_second_level_page_header, .{
.entryPageOffset = entry_offset,
.entryCount = page.count,
.encodingsPageOffset = @sizeOf(macho.unwind_info_compressed_second_level_page_header),
.encodingsCount = page.page_encodings_count,
- });
+ }), .little);
for (page.page_encodings[0..page.page_encodings_count]) |enc| {
try writer.writeInt(u32, enc.enc, .little);
@@ -656,7 +655,7 @@ const Page = struct {
.funcOffset = @as(u24, @intCast(rec.getAtomAddress(macho_file) - first_rec.getAtomAddress(macho_file))),
.encodingIndex = @as(u8, @intCast(enc_index)),
};
- try writer.writeStruct(compressed);
+ try writer.writeStruct(compressed, .little);
}
},
}
@@ -673,7 +672,7 @@ const macho = std.macho;
const math = std.math;
const mem = std.mem;
const trace = @import("../../tracy.zig").trace;
-const Writer = std.io.Writer;
+const Writer = std.Io.Writer;
const Allocator = mem.Allocator;
const Atom = @import("Atom.zig");
src/link/MachO.zig
@@ -589,7 +589,7 @@ pub fn flush(
);
const ncmds, const sizeofcmds, const uuid_cmd_offset = self.writeLoadCommands() catch |err| switch (err) {
- error.NoSpaceLeft => unreachable,
+ error.WriteFailed => unreachable,
error.OutOfMemory => return error.OutOfMemory,
error.LinkFailure => return error.LinkFailure,
};
@@ -1074,7 +1074,7 @@ fn accessLibPath(
for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| {
test_path.clearRetainingCapacity();
- try test_path.writer().print("{s}" ++ sep ++ "lib{s}{s}", .{ search_dir, name, ext });
+ try test_path.print("{s}" ++ sep ++ "lib{s}{s}", .{ search_dir, name, ext });
try checked_paths.append(try arena.dupe(u8, test_path.items));
fs.cwd().access(test_path.items, .{}) catch |err| switch (err) {
error.FileNotFound => continue,
@@ -1097,7 +1097,7 @@ fn accessFrameworkPath(
for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| {
test_path.clearRetainingCapacity();
- try test_path.writer().print("{s}" ++ sep ++ "{s}.framework" ++ sep ++ "{s}{s}", .{
+ try test_path.print("{s}" ++ sep ++ "{s}.framework" ++ sep ++ "{s}{s}", .{
search_dir,
name,
name,
@@ -1178,9 +1178,9 @@ fn parseDependentDylibs(self: *MachO) !void {
for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| {
test_path.clearRetainingCapacity();
if (self.base.comp.sysroot) |root| {
- try test_path.writer().print("{s}" ++ fs.path.sep_str ++ "{s}{s}", .{ root, path, ext });
+ try test_path.print("{s}" ++ fs.path.sep_str ++ "{s}{s}", .{ root, path, ext });
} else {
- try test_path.writer().print("{s}{s}", .{ path, ext });
+ try test_path.print("{s}{s}", .{ path, ext });
}
try checked_paths.append(try arena.dupe(u8, test_path.items));
fs.cwd().access(test_path.items, .{}) catch |err| switch (err) {
@@ -2528,8 +2528,8 @@ fn writeThunkWorker(self: *MachO, thunk: Thunk) void {
fn doWork(th: Thunk, buffer: []u8, macho_file: *MachO) !void {
const off = try macho_file.cast(usize, th.value);
const size = th.size();
- var stream = std.io.fixedBufferStream(buffer[off..][0..size]);
- try th.write(macho_file, stream.writer());
+ var stream: Writer = .fixed(buffer[off..][0..size]);
+ try th.write(macho_file, &stream);
}
}.doWork;
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 {
const doWork = struct {
fn doWork(macho_file: *MachO, tag: Tag, buffer: []u8) !void {
- var stream = std.io.fixedBufferStream(buffer);
+ var stream: Writer = .fixed(buffer);
switch (tag) {
.eh_frame => eh_frame.write(macho_file, buffer),
.unwind_info => try macho_file.unwind_info.write(macho_file, buffer),
- .got => try macho_file.got.write(macho_file, stream.writer()),
- .stubs => try macho_file.stubs.write(macho_file, stream.writer()),
- .la_symbol_ptr => try macho_file.la_symbol_ptr.write(macho_file, stream.writer()),
- .tlv_ptr => try macho_file.tlv_ptr.write(macho_file, stream.writer()),
- .objc_stubs => try macho_file.objc_stubs.write(macho_file, stream.writer()),
+ .got => try macho_file.got.write(macho_file, &stream),
+ .stubs => try macho_file.stubs.write(macho_file, &stream),
+ .la_symbol_ptr => try macho_file.la_symbol_ptr.write(macho_file, &stream),
+ .tlv_ptr => try macho_file.tlv_ptr.write(macho_file, &stream),
+ .objc_stubs => try macho_file.objc_stubs.write(macho_file, &stream),
}
}
}.doWork;
@@ -2605,8 +2605,8 @@ fn updateLazyBindSizeWorker(self: *MachO) void {
try macho_file.lazy_bind_section.updateSize(macho_file);
const sect_id = macho_file.stubs_helper_sect_index.?;
const out = &macho_file.sections.items(.out)[sect_id];
- var stream = std.io.fixedBufferStream(out.items);
- try macho_file.stubs_helper.write(macho_file, stream.writer());
+ var stream: Writer = .fixed(out.items);
+ try macho_file.stubs_helper.write(macho_file, &stream);
}
}.doWork;
doWork(self) catch |err|
@@ -2669,18 +2669,17 @@ fn writeDyldInfo(self: *MachO) !void {
defer gpa.free(buffer);
@memset(buffer, 0);
- var stream = std.io.fixedBufferStream(buffer);
- const writer = stream.writer();
-
- try self.rebase_section.write(writer);
- try stream.seekTo(cmd.bind_off - base_off);
- try self.bind_section.write(writer);
- try stream.seekTo(cmd.weak_bind_off - base_off);
- try self.weak_bind_section.write(writer);
- try stream.seekTo(cmd.lazy_bind_off - base_off);
- try self.lazy_bind_section.write(writer);
- try stream.seekTo(cmd.export_off - base_off);
- try self.export_trie.write(writer);
+ var writer: Writer = .fixed(buffer);
+
+ try self.rebase_section.write(&writer);
+ writer.end = cmd.bind_off - base_off;
+ try self.bind_section.write(&writer);
+ writer.end = cmd.weak_bind_off - base_off;
+ try self.weak_bind_section.write(&writer);
+ writer.end = cmd.lazy_bind_off - base_off;
+ try self.lazy_bind_section.write(&writer);
+ writer.end = cmd.export_off - base_off;
+ try self.export_trie.write(&writer);
try self.pwriteAll(buffer, cmd.rebase_off);
}
@@ -2689,10 +2688,10 @@ pub fn writeDataInCode(self: *MachO) !void {
defer tracy.end();
const gpa = self.base.comp.gpa;
const cmd = self.data_in_code_cmd;
- var buffer = try std.array_list.Managed(u8).initCapacity(gpa, self.data_in_code.size());
+ var buffer = try std.Io.Writer.Allocating.initCapacity(gpa, self.data_in_code.size());
defer buffer.deinit();
- try self.data_in_code.write(self, buffer.writer());
- try self.pwriteAll(buffer.items, cmd.dataoff);
+ self.data_in_code.write(self, &buffer.writer) catch return error.OutOfMemory;
+ try self.pwriteAll(buffer.written(), cmd.dataoff);
}
fn writeIndsymtab(self: *MachO) !void {
@@ -2701,10 +2700,11 @@ fn writeIndsymtab(self: *MachO) !void {
const gpa = self.base.comp.gpa;
const cmd = self.dysymtab_cmd;
const needed_size = cmd.nindirectsyms * @sizeOf(u32);
- var buffer = try std.array_list.Managed(u8).initCapacity(gpa, needed_size);
- defer buffer.deinit();
- try self.indsymtab.write(self, buffer.writer());
- try self.pwriteAll(buffer.items, cmd.indirectsymoff);
+ const buffer = try gpa.alloc(u8, needed_size);
+ defer gpa.free(buffer);
+ var writer: Writer = .fixed(buffer);
+ try self.indsymtab.write(self, &writer);
+ try self.pwriteAll(buffer, cmd.indirectsymoff);
}
pub fn writeSymtabToFile(self: *MachO) !void {
@@ -2821,8 +2821,7 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } {
const buffer = try gpa.alloc(u8, needed_size);
defer gpa.free(buffer);
- var stream = std.io.fixedBufferStream(buffer);
- const writer = stream.writer();
+ var writer: Writer = .fixed(buffer);
var ncmds: usize = 0;
@@ -2831,26 +2830,26 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } {
const slice = self.sections.slice();
var sect_id: usize = 0;
for (self.segments.items) |seg| {
- try writer.writeStruct(seg);
+ try writer.writeStruct(seg, .little);
for (slice.items(.header)[sect_id..][0..seg.nsects]) |header| {
- try writer.writeStruct(header);
+ try writer.writeStruct(header, .little);
}
sect_id += seg.nsects;
}
ncmds += self.segments.items.len;
}
- try writer.writeStruct(self.dyld_info_cmd);
+ try writer.writeStruct(self.dyld_info_cmd, .little);
ncmds += 1;
- try writer.writeStruct(self.function_starts_cmd);
+ try writer.writeStruct(self.function_starts_cmd, .little);
ncmds += 1;
- try writer.writeStruct(self.data_in_code_cmd);
+ try writer.writeStruct(self.data_in_code_cmd, .little);
ncmds += 1;
- try writer.writeStruct(self.symtab_cmd);
+ try writer.writeStruct(self.symtab_cmd, .little);
ncmds += 1;
- try writer.writeStruct(self.dysymtab_cmd);
+ try writer.writeStruct(self.dysymtab_cmd, .little);
ncmds += 1;
- try load_commands.writeDylinkerLC(writer);
+ try load_commands.writeDylinkerLC(&writer);
ncmds += 1;
if (self.getInternalObject()) |obj| {
@@ -2861,44 +2860,44 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } {
0
else
@as(u32, @intCast(sym.getAddress(.{ .stubs = true }, self) - seg.vmaddr));
- try writer.writeStruct(macho.entry_point_command{
+ try writer.writeStruct(@as(macho.entry_point_command, .{
.entryoff = entryoff,
.stacksize = self.base.stack_size,
- });
+ }), .little);
ncmds += 1;
}
}
if (self.base.isDynLib()) {
- try load_commands.writeDylibIdLC(self, writer);
+ try load_commands.writeDylibIdLC(self, &writer);
ncmds += 1;
}
for (self.rpath_list) |rpath| {
- try load_commands.writeRpathLC(rpath, writer);
+ try load_commands.writeRpathLC(rpath, &writer);
ncmds += 1;
}
if (comp.config.any_sanitize_thread) {
const path = try comp.tsan_lib.?.full_object_path.toString(gpa);
defer gpa.free(path);
const rpath = std.fs.path.dirname(path) orelse ".";
- try load_commands.writeRpathLC(rpath, writer);
+ try load_commands.writeRpathLC(rpath, &writer);
ncmds += 1;
}
- try writer.writeStruct(macho.source_version_command{ .version = 0 });
+ try writer.writeStruct(@as(macho.source_version_command, .{ .version = 0 }), .little);
ncmds += 1;
if (self.platform.isBuildVersionCompatible()) {
- try load_commands.writeBuildVersionLC(self.platform, self.sdk_version, writer);
+ try load_commands.writeBuildVersionLC(self.platform, self.sdk_version, &writer);
ncmds += 1;
} else {
- try load_commands.writeVersionMinLC(self.platform, self.sdk_version, writer);
+ try load_commands.writeVersionMinLC(self.platform, self.sdk_version, &writer);
ncmds += 1;
}
- const uuid_cmd_offset = @sizeOf(macho.mach_header_64) + stream.pos;
- try writer.writeStruct(self.uuid_cmd);
+ const uuid_cmd_offset = @sizeOf(macho.mach_header_64) + writer.end;
+ try writer.writeStruct(self.uuid_cmd, .little);
ncmds += 1;
for (self.dylibs.items) |index| {
@@ -2916,16 +2915,16 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } {
.timestamp = dylib_id.timestamp,
.current_version = dylib_id.current_version,
.compatibility_version = dylib_id.compatibility_version,
- }, writer);
+ }, &writer);
ncmds += 1;
}
if (self.requiresCodeSig()) {
- try writer.writeStruct(self.codesig_cmd);
+ try writer.writeStruct(self.codesig_cmd, .little);
ncmds += 1;
}
- assert(stream.pos == needed_size);
+ assert(writer.end == needed_size);
try self.pwriteAll(buffer, @sizeOf(macho.mach_header_64));
@@ -3014,25 +3013,26 @@ pub fn writeCodeSignaturePadding(self: *MachO, code_sig: *CodeSignature) !void {
pub fn writeCodeSignature(self: *MachO, code_sig: *CodeSignature) !void {
const seg = self.getTextSegment();
const offset = self.codesig_cmd.dataoff;
+ const gpa = self.base.comp.gpa;
- var buffer = std.array_list.Managed(u8).init(self.base.comp.gpa);
- defer buffer.deinit();
- try buffer.ensureTotalCapacityPrecise(code_sig.size());
+ const buffer = try gpa.alloc(u8, code_sig.size());
+ defer gpa.free(buffer);
+ var writer: Writer = .fixed(buffer);
try code_sig.writeAdhocSignature(self, .{
.file = self.base.file.?,
.exec_seg_base = seg.fileoff,
.exec_seg_limit = seg.filesize,
.file_size = offset,
.dylib = self.base.isDynLib(),
- }, buffer.writer());
- assert(buffer.items.len == code_sig.size());
+ }, &writer);
+ assert(writer.buffered().len == code_sig.size());
log.debug("writing code signature from 0x{x} to 0x{x}", .{
offset,
- offset + buffer.items.len,
+ offset + writer.buffered().len,
});
- try self.pwriteAll(buffer.items, offset);
+ try self.pwriteAll(writer.buffered(), offset);
}
pub fn updateFunc(
@@ -5372,7 +5372,7 @@ const macho = std.macho;
const math = std.math;
const mem = std.mem;
const meta = std.meta;
-const Writer = std.io.Writer;
+const Writer = std.Io.Writer;
const aarch64 = codegen.aarch64.encoding;
const bind = @import("MachO/dyld_info/bind.zig");