aboutsummaryrefslogtreecommitdiff
path: root/src/link/MachO/Dylib.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2025-07-01 18:14:45 -0700
committerAndrew Kelley <andrew@ziglang.org>2025-07-07 22:43:52 -0700
commitc8fcd2ff2c032b2de8cc1a57e075552d1cab35df (patch)
tree7155f58049ecd0e948533f6b64cba1553dd33ae2 /src/link/MachO/Dylib.zig
parentf71d97e4cbb0e56213cb76657ad6c9edf6134868 (diff)
downloadzig-c8fcd2ff2c032b2de8cc1a57e075552d1cab35df.tar.gz
zig-c8fcd2ff2c032b2de8cc1a57e075552d1cab35df.zip
MachO: update to new std.io APIs
Diffstat (limited to 'src/link/MachO/Dylib.zig')
-rw-r--r--src/link/MachO/Dylib.zig142
1 files changed, 41 insertions, 101 deletions
diff --git a/src/link/MachO/Dylib.zig b/src/link/MachO/Dylib.zig
index 01dd25fa8c..d950f791ff 100644
--- a/src/link/MachO/Dylib.zig
+++ b/src/link/MachO/Dylib.zig
@@ -61,7 +61,7 @@ fn parseBinary(self: *Dylib, macho_file: *MachO) !void {
const file = macho_file.getFileHandle(self.file_handle);
const offset = self.offset;
- log.debug("parsing dylib from binary: {}", .{@as(Path, self.path)});
+ log.debug("parsing dylib from binary: {f}", .{@as(Path, self.path)});
var header_buffer: [@sizeOf(macho.mach_header_64)]u8 = undefined;
{
@@ -140,7 +140,7 @@ fn parseBinary(self: *Dylib, macho_file: *MachO) !void {
if (self.platform) |platform| {
if (!macho_file.platform.eqlTarget(platform)) {
- try macho_file.reportParseError2(self.index, "invalid platform: {}", .{
+ try macho_file.reportParseError2(self.index, "invalid platform: {f}", .{
platform.fmtTarget(macho_file.getTarget().cpu.arch),
});
return error.InvalidTarget;
@@ -148,7 +148,7 @@ fn parseBinary(self: *Dylib, macho_file: *MachO) !void {
// TODO: this can cause the CI to fail so I'm commenting this check out so that
// I can work out the rest of the changes first
// if (macho_file.platform.version.order(platform.version) == .lt) {
- // try macho_file.reportParseError2(self.index, "object file built for newer platform: {}: {} < {}", .{
+ // try macho_file.reportParseError2(self.index, "object file built for newer platform: {f}: {f} < {f}", .{
// macho_file.platform.fmtTarget(macho_file.getTarget().cpu.arch),
// macho_file.platform.version,
// platform.version,
@@ -158,46 +158,6 @@ fn parseBinary(self: *Dylib, macho_file: *MachO) !void {
}
}
-const TrieIterator = struct {
- data: []const u8,
- pos: usize = 0,
-
- fn getStream(it: *TrieIterator) std.io.FixedBufferStream([]const u8) {
- return std.io.fixedBufferStream(it.data[it.pos..]);
- }
-
- fn readUleb128(it: *TrieIterator) !u64 {
- var stream = it.getStream();
- var creader = std.io.countingReader(stream.reader());
- const reader = creader.reader();
- const value = try std.leb.readUleb128(u64, reader);
- it.pos += math.cast(usize, creader.bytes_read) orelse return error.Overflow;
- return value;
- }
-
- fn readString(it: *TrieIterator) ![:0]const u8 {
- var stream = it.getStream();
- const reader = stream.reader();
-
- var count: usize = 0;
- while (true) : (count += 1) {
- const byte = try reader.readByte();
- if (byte == 0) break;
- }
-
- const str = @as([*:0]const u8, @ptrCast(it.data.ptr + it.pos))[0..count :0];
- it.pos += count + 1;
- return str;
- }
-
- fn readByte(it: *TrieIterator) !u8 {
- var stream = it.getStream();
- const value = try stream.reader().readByte();
- it.pos += 1;
- return value;
- }
-};
-
pub fn addExport(self: *Dylib, allocator: Allocator, name: []const u8, flags: Export.Flags) !void {
try self.exports.append(allocator, .{
.name = try self.addString(allocator, name),
@@ -207,16 +167,16 @@ pub fn addExport(self: *Dylib, allocator: Allocator, name: []const u8, flags: Ex
fn parseTrieNode(
self: *Dylib,
- it: *TrieIterator,
+ br: *std.io.Reader,
allocator: Allocator,
arena: Allocator,
prefix: []const u8,
) !void {
const tracy = trace(@src());
defer tracy.end();
- const size = try it.readUleb128();
+ const size = try br.takeLeb128(u64);
if (size > 0) {
- const flags = try it.readUleb128();
+ const flags = try br.takeLeb128(u8);
const kind = flags & macho.EXPORT_SYMBOL_FLAGS_KIND_MASK;
const out_flags = Export.Flags{
.abs = kind == macho.EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE,
@@ -224,29 +184,28 @@ fn parseTrieNode(
.weak = flags & macho.EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION != 0,
};
if (flags & macho.EXPORT_SYMBOL_FLAGS_REEXPORT != 0) {
- _ = try it.readUleb128(); // dylib ordinal
- const name = try it.readString();
+ _ = try br.takeLeb128(u64); // dylib ordinal
+ const name = try br.takeSentinel(0);
try self.addExport(allocator, if (name.len > 0) name else prefix, out_flags);
} else if (flags & macho.EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER != 0) {
- _ = try it.readUleb128(); // stub offset
- _ = try it.readUleb128(); // resolver offset
+ _ = try br.takeLeb128(u64); // stub offset
+ _ = try br.takeLeb128(u64); // resolver offset
try self.addExport(allocator, prefix, out_flags);
} else {
- _ = try it.readUleb128(); // VM offset
+ _ = try br.takeLeb128(u64); // VM offset
try self.addExport(allocator, prefix, out_flags);
}
}
- const nedges = try it.readByte();
-
+ const nedges = try br.takeByte();
for (0..nedges) |_| {
- const label = try it.readString();
- const off = try it.readUleb128();
+ const label = try br.takeSentinel(0);
+ const off = try br.takeLeb128(usize);
const prefix_label = try std.fmt.allocPrint(arena, "{s}{s}", .{ prefix, label });
- const curr = it.pos;
- it.pos = math.cast(usize, off) orelse return error.Overflow;
- try self.parseTrieNode(it, allocator, arena, prefix_label);
- it.pos = curr;
+ const seek = br.seek;
+ br.seek = off;
+ try self.parseTrieNode(br, allocator, arena, prefix_label);
+ br.seek = seek;
}
}
@@ -257,8 +216,8 @@ fn parseTrie(self: *Dylib, data: []const u8, macho_file: *MachO) !void {
var arena = std.heap.ArenaAllocator.init(gpa);
defer arena.deinit();
- var it: TrieIterator = .{ .data = data };
- try self.parseTrieNode(&it, gpa, arena.allocator(), "");
+ var r: std.io.Reader = .fixed(data);
+ try self.parseTrieNode(&r, gpa, arena.allocator(), "");
}
fn parseTbd(self: *Dylib, macho_file: *MachO) !void {
@@ -267,7 +226,7 @@ fn parseTbd(self: *Dylib, macho_file: *MachO) !void {
const gpa = macho_file.base.comp.gpa;
- log.debug("parsing dylib from stub: {}", .{self.path});
+ log.debug("parsing dylib from stub: {f}", .{self.path});
const file = macho_file.getFileHandle(self.file_handle);
var lib_stub = LibStub.loadFromFile(gpa, file) catch |err| {
@@ -691,52 +650,32 @@ pub fn setSymbolExtra(self: *Dylib, index: u32, extra: Symbol.Extra) void {
}
}
-pub fn format(
- self: *Dylib,
- comptime unused_fmt_string: []const u8,
- options: std.fmt.FormatOptions,
- writer: anytype,
-) !void {
- _ = self;
- _ = unused_fmt_string;
- _ = options;
- _ = writer;
- @compileError("do not format dylib directly");
-}
-
-pub fn fmtSymtab(self: *Dylib, macho_file: *MachO) std.fmt.Formatter(formatSymtab) {
+pub fn fmtSymtab(self: *Dylib, macho_file: *MachO) std.fmt.Formatter(Format, Format.symtab) {
return .{ .data = .{
.dylib = self,
.macho_file = macho_file,
} };
}
-const FormatContext = struct {
+const Format = struct {
dylib: *Dylib,
macho_file: *MachO,
-};
-fn formatSymtab(
- ctx: FormatContext,
- comptime unused_fmt_string: []const u8,
- options: std.fmt.FormatOptions,
- writer: anytype,
-) !void {
- _ = unused_fmt_string;
- _ = options;
- const dylib = ctx.dylib;
- const macho_file = ctx.macho_file;
- try writer.writeAll(" globals\n");
- for (dylib.symbols.items, 0..) |sym, i| {
- const ref = dylib.getSymbolRef(@intCast(i), macho_file);
- if (ref.getFile(macho_file) == null) {
- // TODO any better way of handling this?
- try writer.print(" {s} : unclaimed\n", .{sym.getName(macho_file)});
- } else {
- try writer.print(" {}\n", .{ref.getSymbol(macho_file).?.fmt(macho_file)});
+ fn symtab(f: Format, w: *Writer) Writer.Error!void {
+ const dylib = f.dylib;
+ const macho_file = f.macho_file;
+ try w.writeAll(" globals\n");
+ for (dylib.symbols.items, 0..) |sym, i| {
+ const ref = dylib.getSymbolRef(@intCast(i), macho_file);
+ if (ref.getFile(macho_file) == null) {
+ // TODO any better way of handling this?
+ try w.print(" {s} : unclaimed\n", .{sym.getName(macho_file)});
+ } else {
+ try w.print(" {f}\n", .{ref.getSymbol(macho_file).?.fmt(macho_file)});
+ }
}
}
-}
+};
pub const TargetMatcher = struct {
allocator: Allocator,
@@ -948,19 +887,17 @@ const Export = struct {
};
};
+const std = @import("std");
const assert = std.debug.assert;
-const fat = @import("fat.zig");
const fs = std.fs;
const fmt = std.fmt;
const log = std.log.scoped(.link);
const macho = std.macho;
const math = std.math;
const mem = std.mem;
-const tapi = @import("../tapi.zig");
-const trace = @import("../../tracy.zig").trace;
-const std = @import("std");
const Allocator = mem.Allocator;
const Path = std.Build.Cache.Path;
+const Writer = std.io.Writer;
const Dylib = @This();
const File = @import("file.zig").File;
@@ -969,3 +906,6 @@ const LoadCommandIterator = macho.LoadCommandIterator;
const MachO = @import("../MachO.zig");
const Symbol = @import("Symbol.zig");
const Tbd = tapi.Tbd;
+const fat = @import("fat.zig");
+const tapi = @import("../tapi.zig");
+const trace = @import("../../tracy.zig").trace;