Commit 5cb96681d9
src-self-hosted/link/MachO.zig
@@ -0,0 +1,93 @@
+const MachO = @This();
+
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const assert = std.debug.assert;
+const fs = std.fs;
+
+const Module = @import("../Module.zig");
+const link = @import("../link.zig");
+const File = link.File;
+
+pub const base_tag: Tag = File.Tag.macho;
+
+base: File,
+
+error_flags: File.ErrorFlags = File.ErrorFlags{},
+
+pub const TextBlock = struct {
+ pub const empty = TextBlock{};
+};
+
+pub const SrcFn = struct {
+ pub const empty = SrcFn{};
+};
+
+pub fn openPath(allocator: *Allocator, dir: fs.Dir, sub_path: []const u8, options: link.Options) !*File {
+ assert(options.object_format == .macho);
+
+ const file = try dir.createFile(sub_path, .{ .truncate = false, .read = true, .mode = link.determineMode(options) });
+ errdefer file.close();
+
+ var macho_file = try allocator.create(MachO);
+ errdefer allocator.destroy(macho_file);
+
+ macho_file.* = openFile(allocator, file, options) catch |err| switch (err) {
+ error.IncrFailed => try createFile(allocator, file, options),
+ else => |e| return e,
+ };
+
+ return &macho_file.base;
+}
+
+/// Returns error.IncrFailed if incremental update could not be performed.
+fn openFile(allocator: *Allocator, file: fs.File, options: link.Options) !MachO {
+ switch (options.output_mode) {
+ .Exe => {},
+ .Obj => {},
+ .Lib => return error.IncrFailed,
+ }
+ var self: MachO = .{
+ .base = .{
+ .file = file,
+ .tag = .macho,
+ .options = options,
+ .allocator = allocator,
+ },
+ };
+ errdefer self.deinit();
+
+ // TODO implement reading the macho file
+ return error.IncrFailed;
+ //try self.populateMissingMetadata();
+ //return self;
+}
+
+/// Truncates the existing file contents and overwrites the contents.
+/// Returns an error if `file` is not already open with +read +write +seek abilities.
+fn createFile(allocator: *Allocator, file: fs.File, options: link.Options) !MachO {
+ switch (options.output_mode) {
+ .Exe => return error.TODOImplementWritingMachOExeFiles,
+ .Obj => return error.TODOImplementWritingMachOObjFiles,
+ .Lib => return error.TODOImplementWritingLibFiles,
+ }
+}
+
+pub fn flush(self: *MachO) !void {}
+
+pub fn deinit(self: *MachO) void {}
+
+pub fn allocateDeclIndexes(self: *MachO, decl: *Module.Decl) !void {}
+
+pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {}
+
+pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl: *const Module.Decl) !void {}
+
+pub fn updateDeclExports(
+ self: *MachO,
+ module: *Module,
+ decl: *const Module.Decl,
+ exports: []const *Module.Export,
+) !void {}
+
+pub fn freeDecl(self: *MachO, decl: *Module.Decl) void {}
src-self-hosted/link.zig
@@ -158,6 +158,7 @@ pub const File = struct {
}
}
+ /// Commit pending changes and write headers.
pub fn flush(base: *File) !void {
const tracy = trace(@src());
defer tracy.end();
@@ -1022,7 +1023,6 @@ pub const File = struct {
pub const abbrev_pad1 = 5;
pub const abbrev_parameter = 6;
- /// Commit pending changes and write headers.
pub fn flush(self: *Elf) !void {
const target_endian = self.base.options.target.cpu.arch.endian();
const foreign_endian = target_endian != std.Target.current.cpu.arch.endian();
@@ -2330,7 +2330,6 @@ pub const File = struct {
try self.pwriteDbgInfoNops(prev_padding_size, dbg_info_buf, next_padding_size, trailing_zero, file_pos);
}
- /// Must be called only after a successful call to `updateDecl`.
pub fn updateDeclExports(
self: *Elf,
module: *Module,
@@ -2832,99 +2831,7 @@ pub const File = struct {
};
- pub const MachO = struct {
- pub const base_tag: Tag = .macho;
-
- base: File,
-
- ptr_width: enum { p32, p64 },
-
- error_flags: ErrorFlags = ErrorFlags{},
-
- pub const TextBlock = struct {
- pub const empty = TextBlock{};
- };
-
- pub const SrcFn = struct {
- pub const empty = SrcFn{};
- };
-
- pub fn openPath(allocator: *Allocator, dir: fs.Dir, sub_path: []const u8, options: Options) !*File {
- assert(options.object_format == .macho);
-
- const file = try dir.createFile(sub_path, .{ .truncate = false, .read = true, .mode = determineMode(options) });
- errdefer file.close();
-
- var macho_file = try allocator.create(MachO);
- errdefer allocator.destroy(macho_file);
-
- macho_file.* = openFile(allocator, file, options) catch |err| switch (err) {
- error.IncrFailed => try createFile(allocator, file, options),
- else => |e| return e,
- };
-
- return &macho_file.base;
- }
-
- /// Returns error.IncrFailed if incremental update could not be performed.
- fn openFile(allocator: *Allocator, file: fs.File, options: Options) !MachO {
- switch (options.output_mode) {
- .Exe => {},
- .Obj => {},
- .Lib => return error.IncrFailed,
- }
- var self: MachO = .{
- .base = .{
- .file = file,
- .tag = .macho,
- .options = options,
- .allocator = allocator,
- },
- .ptr_width = switch (options.target.cpu.arch.ptrBitWidth()) {
- 32 => .p32,
- 64 => .p64,
- else => return error.UnsupportedELFArchitecture,
- },
- };
- errdefer self.deinit();
-
- // TODO implement reading the macho file
- return error.IncrFailed;
- //try self.populateMissingMetadata();
- //return self;
- }
-
- /// Truncates the existing file contents and overwrites the contents.
- /// Returns an error if `file` is not already open with +read +write +seek abilities.
- fn createFile(allocator: *Allocator, file: fs.File, options: Options) !MachO {
- switch (options.output_mode) {
- .Exe => return error.TODOImplementWritingMachOExeFiles,
- .Obj => return error.TODOImplementWritingMachOObjFiles,
- .Lib => return error.TODOImplementWritingLibFiles,
- }
- }
-
- /// Commit pending changes and write headers.
- pub fn flush(self: *MachO) !void {}
-
- pub fn deinit(self: *MachO) void {}
-
- pub fn allocateDeclIndexes(self: *MachO, decl: *Module.Decl) !void {}
-
- pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {}
-
- pub fn updateDeclLineNumber(self: *MachO, module: *Module, decl: *const Module.Decl) !void {}
-
- /// Must be called only after a successful call to `updateDecl`.
- pub fn updateDeclExports(
- self: *MachO,
- module: *Module,
- decl: *const Module.Decl,
- exports: []const *Module.Export,
- ) !void {}
-
- pub fn freeDecl(self: *MachO, decl: *Module.Decl) void {}
- };
+ pub const MachO = @import("link/MachO.zig");
};
/// Saturating multiplication
@@ -2965,7 +2872,7 @@ fn sectHeaderTo32(shdr: elf.Elf64_Shdr) elf.Elf32_Shdr {
};
}
-fn determineMode(options: Options) fs.File.Mode {
+pub fn determineMode(options: Options) fs.File.Mode {
// On common systems with a 0o022 umask, 0o777 will still result in a file created
// with 0o755 permissions, but it works appropriately if the system is configured
// more leniently. As another data point, C's fopen seems to open files with the