Add skeleton for MachO support in stage2
This commit adds an empty skeleton for MachO format support in stage2.
This commit is contained in:
@@ -1568,6 +1568,9 @@ fn analyzeRootSrcFile(self: *Module, root_scope: *Scope.File) !void {
|
||||
// in `Decl` to notice that the line number did not change.
|
||||
self.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl });
|
||||
},
|
||||
.macho => {
|
||||
// TODO Implement for MachO
|
||||
},
|
||||
.c => {},
|
||||
}
|
||||
}
|
||||
@@ -1776,10 +1779,12 @@ fn allocateNewDecl(
|
||||
.contents_hash = contents_hash,
|
||||
.link = switch (self.bin_file.tag) {
|
||||
.elf => .{ .elf = link.File.Elf.TextBlock.empty },
|
||||
.macho => .{ .macho = link.File.MachO.TextBlock.empty },
|
||||
.c => .{ .c = {} },
|
||||
},
|
||||
.fn_link = switch (self.bin_file.tag) {
|
||||
.elf => .{ .elf = link.File.Elf.SrcFn.empty },
|
||||
.macho => .{ .macho = link.File.MachO.SrcFn.empty },
|
||||
.c => .{ .c = {} },
|
||||
},
|
||||
.generation = 0,
|
||||
|
||||
@@ -44,11 +44,13 @@ pub const Options = struct {
|
||||
pub const File = struct {
|
||||
pub const LinkBlock = union {
|
||||
elf: Elf.TextBlock,
|
||||
macho: MachO.TextBlock,
|
||||
c: void,
|
||||
};
|
||||
|
||||
pub const LinkFn = union {
|
||||
elf: Elf.SrcFn,
|
||||
macho: MachO.SrcFn,
|
||||
c: void,
|
||||
};
|
||||
|
||||
@@ -66,7 +68,7 @@ pub const File = struct {
|
||||
.unknown => unreachable,
|
||||
.coff => return error.TODOImplementCoff,
|
||||
.elf => return Elf.openPath(allocator, dir, sub_path, options),
|
||||
.macho => return error.TODOImplementMacho,
|
||||
.macho => return MachO.openPath(allocator, dir, sub_path, options),
|
||||
.wasm => return error.TODOImplementWasm,
|
||||
.c => return C.openPath(allocator, dir, sub_path, options),
|
||||
.hex => return error.TODOImplementHex,
|
||||
@@ -83,7 +85,7 @@ pub const File = struct {
|
||||
|
||||
pub fn makeWritable(base: *File, dir: fs.Dir, sub_path: []const u8) !void {
|
||||
switch (base.tag) {
|
||||
.elf => {
|
||||
.elf, .macho => {
|
||||
if (base.file != null) return;
|
||||
base.file = try dir.createFile(sub_path, .{
|
||||
.truncate = false,
|
||||
@@ -106,6 +108,7 @@ pub const File = struct {
|
||||
pub fn updateDecl(base: *File, module: *Module, decl: *Module.Decl) !void {
|
||||
switch (base.tag) {
|
||||
.elf => return @fieldParentPtr(Elf, "base", base).updateDecl(module, decl),
|
||||
.macho => return @fieldParentPtr(MachO, "base", base).updateDecl(module, decl),
|
||||
.c => return @fieldParentPtr(C, "base", base).updateDecl(module, decl),
|
||||
}
|
||||
}
|
||||
@@ -113,6 +116,7 @@ pub const File = struct {
|
||||
pub fn updateDeclLineNumber(base: *File, module: *Module, decl: *Module.Decl) !void {
|
||||
switch (base.tag) {
|
||||
.elf => return @fieldParentPtr(Elf, "base", base).updateDeclLineNumber(module, decl),
|
||||
.macho => return @fieldParentPtr(MachO, "base", base).updateDeclLineNumber(module, decl),
|
||||
.c => {},
|
||||
}
|
||||
}
|
||||
@@ -120,6 +124,7 @@ pub const File = struct {
|
||||
pub fn allocateDeclIndexes(base: *File, decl: *Module.Decl) !void {
|
||||
switch (base.tag) {
|
||||
.elf => return @fieldParentPtr(Elf, "base", base).allocateDeclIndexes(decl),
|
||||
.macho => return @fieldParentPtr(MachO, "base", base).allocateDeclIndexes(decl),
|
||||
.c => {},
|
||||
}
|
||||
}
|
||||
@@ -128,6 +133,7 @@ pub const File = struct {
|
||||
if (base.file) |f| f.close();
|
||||
switch (base.tag) {
|
||||
.elf => @fieldParentPtr(Elf, "base", base).deinit(),
|
||||
.macho => @fieldParentPtr(MachO, "base", base).deinit(),
|
||||
.c => @fieldParentPtr(C, "base", base).deinit(),
|
||||
}
|
||||
}
|
||||
@@ -139,6 +145,11 @@ pub const File = struct {
|
||||
parent.deinit();
|
||||
base.allocator.destroy(parent);
|
||||
},
|
||||
.macho => {
|
||||
const parent = @fieldParentPtr(MachO, "base", base);
|
||||
parent.deinit();
|
||||
base.allocator.destroy(parent);
|
||||
},
|
||||
.c => {
|
||||
const parent = @fieldParentPtr(C, "base", base);
|
||||
parent.deinit();
|
||||
@@ -153,6 +164,7 @@ pub const File = struct {
|
||||
|
||||
try switch (base.tag) {
|
||||
.elf => @fieldParentPtr(Elf, "base", base).flush(),
|
||||
.macho => @fieldParentPtr(MachO, "base", base).flush(),
|
||||
.c => @fieldParentPtr(C, "base", base).flush(),
|
||||
};
|
||||
}
|
||||
@@ -160,6 +172,7 @@ pub const File = struct {
|
||||
pub fn freeDecl(base: *File, decl: *Module.Decl) void {
|
||||
switch (base.tag) {
|
||||
.elf => @fieldParentPtr(Elf, "base", base).freeDecl(decl),
|
||||
.macho => @fieldParentPtr(MachO, "base", base).freeDecl(decl),
|
||||
.c => unreachable,
|
||||
}
|
||||
}
|
||||
@@ -167,6 +180,7 @@ pub const File = struct {
|
||||
pub fn errorFlags(base: *File) ErrorFlags {
|
||||
return switch (base.tag) {
|
||||
.elf => @fieldParentPtr(Elf, "base", base).error_flags,
|
||||
.macho => @fieldParentPtr(MachO, "base", base).error_flags,
|
||||
.c => return .{ .no_entry_point_found = false },
|
||||
};
|
||||
}
|
||||
@@ -180,12 +194,14 @@ pub const File = struct {
|
||||
) !void {
|
||||
switch (base.tag) {
|
||||
.elf => return @fieldParentPtr(Elf, "base", base).updateDeclExports(module, decl, exports),
|
||||
.macho => return @fieldParentPtr(MachO, "base", base).updateDeclExports(module, decl, exports),
|
||||
.c => return {},
|
||||
}
|
||||
}
|
||||
|
||||
pub const Tag = enum {
|
||||
elf,
|
||||
macho,
|
||||
c,
|
||||
};
|
||||
|
||||
@@ -2815,6 +2831,100 @@ 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 {}
|
||||
};
|
||||
};
|
||||
|
||||
/// Saturating multiplication
|
||||
|
||||
Reference in New Issue
Block a user