authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-08-28 17:34:10+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-08-29 11:40:20+02:00
log2473ccc3358a33c0827ec7f4ea2ecfe18a1055ec
tree68f5abf0836c542cbb9f7a18d8a93071813ea9e5
parent1820aed786a2bb61a6526873e7a8ddf47d45e9fd

macho: create an explicit error set for parse functions


4 files changed, 43 insertions(+), 23 deletions(-)

src/link/MachO.zig+32-20
...@@ -419,6 +419,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No...@@ -419,6 +419,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
419 &dependent_libs,419 &dependent_libs,
420 &parse_error_ctx,420 &parse_error_ctx,
421 ) catch |err| switch (err) {421 ) catch |err| switch (err) {
422 error.DylibAlreadyExists => {},
422 error.UnknownFileType => try self.reportParseError(path, "unknown file type", .{}),423 error.UnknownFileType => try self.reportParseError(path, "unknown file type", .{}),
423 error.MissingArchFatLib => try self.reportParseError(424 error.MissingArchFatLib => try self.reportParseError(
424 path,425 path,
...@@ -723,6 +724,22 @@ fn resolveLib(...@@ -723,6 +724,22 @@ fn resolveLib(
723 return full_path;724 return full_path;
724}725}
725726
727const ParseError = error{
728 UnknownFileType,
729 MissingArchFatLib,
730 InvalidArch,
731 DylibAlreadyExists,
732 IncompatibleDylibVersion,
733 OutOfMemory,
734 Overflow,
735 InputOutput,
736 MalformedArchive,
737 NotLibStub,
738 EndOfStream,
739 FileSystem,
740 NotSupported,
741} || std.os.SeekError || std.fs.File.OpenError || std.fs.File.ReadError || tapi.TapiError;
742
726pub fn parsePositional(743pub fn parsePositional(
727 self: *MachO,744 self: *MachO,
728 file: std.fs.File,745 file: std.fs.File,
...@@ -730,7 +747,7 @@ pub fn parsePositional(...@@ -730,7 +747,7 @@ pub fn parsePositional(
730 must_link: bool,747 must_link: bool,
731 dependent_libs: anytype,748 dependent_libs: anytype,
732 error_ctx: anytype,749 error_ctx: anytype,
733) !void {750) ParseError!void {
734 const tracy = trace(@src());751 const tracy = trace(@src());
735 defer tracy.end();752 defer tracy.end();
736753
...@@ -750,7 +767,7 @@ fn parseObject(...@@ -750,7 +767,7 @@ fn parseObject(
750 file: std.fs.File,767 file: std.fs.File,
751 path: []const u8,768 path: []const u8,
752 error_ctx: anytype,769 error_ctx: anytype,
753) !void {770) ParseError!void {
754 const tracy = trace(@src());771 const tracy = trace(@src());
755 defer tracy.end();772 defer tracy.end();
756773
...@@ -793,7 +810,7 @@ pub fn parseLibrary(...@@ -793,7 +810,7 @@ pub fn parseLibrary(
793 must_link: bool,810 must_link: bool,
794 dependent_libs: anytype,811 dependent_libs: anytype,
795 error_ctx: anytype,812 error_ctx: anytype,
796) !void {813) ParseError!void {
797 const tracy = trace(@src());814 const tracy = trace(@src());
798 defer tracy.end();815 defer tracy.end();
799816
...@@ -829,7 +846,7 @@ pub fn parseLibrary(...@@ -829,7 +846,7 @@ pub fn parseLibrary(
829 }846 }
830}847}
831848
832pub fn parseFatLibrary(self: *MachO, file: std.fs.File, cpu_arch: std.Target.Cpu.Arch) !u64 {849pub fn parseFatLibrary(self: *MachO, file: std.fs.File, cpu_arch: std.Target.Cpu.Arch) ParseError!u64 {
833 _ = self;850 _ = self;
834 var buffer: [2]fat.Arch = undefined;851 var buffer: [2]fat.Arch = undefined;
835 const fat_archs = try fat.parseArchs(file, &buffer);852 const fat_archs = try fat.parseArchs(file, &buffer);
...@@ -846,7 +863,7 @@ fn parseArchive(...@@ -846,7 +863,7 @@ fn parseArchive(
846 must_link: bool,863 must_link: bool,
847 cpu_arch: std.Target.Cpu.Arch,864 cpu_arch: std.Target.Cpu.Arch,
848 error_ctx: anytype,865 error_ctx: anytype,
849) !void {866) ParseError!void {
850 const gpa = self.base.allocator;867 const gpa = self.base.allocator;
851868
852 // We take ownership of the file so that we can store it for the duration of symbol resolution.869 // We take ownership of the file so that we can store it for the duration of symbol resolution.
...@@ -915,7 +932,7 @@ fn parseDylib(...@@ -915,7 +932,7 @@ fn parseDylib(
915 dependent_libs: anytype,932 dependent_libs: anytype,
916 dylib_options: DylibOpts,933 dylib_options: DylibOpts,
917 error_ctx: anytype,934 error_ctx: anytype,
918) !void {935) ParseError!void {
919 const gpa = self.base.allocator;936 const gpa = self.base.allocator;
920 const self_cpu_arch = self.base.options.target.cpu.arch;937 const self_cpu_arch = self.base.options.target.cpu.arch;
921938
...@@ -948,13 +965,10 @@ fn parseDylib(...@@ -948,13 +965,10 @@ fn parseDylib(
948965
949 // TODO verify platform966 // TODO verify platform
950967
951 self.addDylib(dylib, .{968 try self.addDylib(dylib, .{
952 .needed = dylib_options.needed,969 .needed = dylib_options.needed,
953 .weak = dylib_options.weak,970 .weak = dylib_options.weak,
954 }) catch |err| switch (err) {971 });
955 error.DylibAlreadyExists => dylib.deinit(gpa),
956 else => |e| return e,
957 };
958}972}
959973
960fn parseLibStub(974fn parseLibStub(
...@@ -963,7 +977,7 @@ fn parseLibStub(...@@ -963,7 +977,7 @@ fn parseLibStub(
963 path: []const u8,977 path: []const u8,
964 dependent_libs: anytype,978 dependent_libs: anytype,
965 dylib_options: DylibOpts,979 dylib_options: DylibOpts,
966) !void {980) ParseError!void {
967 const gpa = self.base.allocator;981 const gpa = self.base.allocator;
968 var lib_stub = try LibStub.loadFromFile(gpa, file);982 var lib_stub = try LibStub.loadFromFile(gpa, file);
969 defer lib_stub.deinit();983 defer lib_stub.deinit();
...@@ -984,16 +998,13 @@ fn parseLibStub(...@@ -984,16 +998,13 @@ fn parseLibStub(
984 path,998 path,
985 );999 );
9861000
987 self.addDylib(dylib, .{1001 try self.addDylib(dylib, .{
988 .needed = dylib_options.needed,1002 .needed = dylib_options.needed,
989 .weak = dylib_options.weak,1003 .weak = dylib_options.weak,
990 }) catch |err| switch (err) {1004 });
991 error.DylibAlreadyExists => dylib.deinit(gpa),
992 else => |e| return e,
993 };
994}1005}
9951006
996fn addDylib(self: *MachO, dylib: Dylib, dylib_options: DylibOpts) !void {1007fn addDylib(self: *MachO, dylib: Dylib, dylib_options: DylibOpts) ParseError!void {
997 if (dylib_options.id) |id| {1008 if (dylib_options.id) |id| {
998 if (dylib.id.?.current_version < id.compatibility_version) {1009 if (dylib.id.?.current_version < id.compatibility_version) {
999 // TODO convert into an error1010 // TODO convert into an error
...@@ -1022,7 +1033,7 @@ fn addDylib(self: *MachO, dylib: Dylib, dylib_options: DylibOpts) !void {...@@ -1022,7 +1033,7 @@ fn addDylib(self: *MachO, dylib: Dylib, dylib_options: DylibOpts) !void {
1022 }1033 }
1023}1034}
10241035
1025pub fn parseDependentLibs(self: *MachO, dependent_libs: anytype, error_ctx: anytype) !void {1036pub fn parseDependentLibs(self: *MachO, dependent_libs: anytype, error_ctx: anytype) ParseError!void {
1026 const tracy = trace(@src());1037 const tracy = trace(@src());
1027 defer tracy.end();1038 defer tracy.end();
10281039
...@@ -5145,6 +5156,7 @@ const link = @import("../link.zig");...@@ -5145,6 +5156,7 @@ const link = @import("../link.zig");
5145const llvm_backend = @import("../codegen/llvm.zig");5156const llvm_backend = @import("../codegen/llvm.zig");
5146const load_commands = @import("MachO/load_commands.zig");5157const load_commands = @import("MachO/load_commands.zig");
5147const stubs = @import("MachO/stubs.zig");5158const stubs = @import("MachO/stubs.zig");
5159const tapi = @import("tapi.zig");
5148const target_util = @import("../target.zig");5160const target_util = @import("../target.zig");
5149const thunks = @import("MachO/thunks.zig");5161const thunks = @import("MachO/thunks.zig");
5150const trace = @import("../tracy.zig").trace;5162const trace = @import("../tracy.zig").trace;
...@@ -5162,7 +5174,7 @@ const DwarfInfo = @import("MachO/DwarfInfo.zig");...@@ -5162,7 +5174,7 @@ const DwarfInfo = @import("MachO/DwarfInfo.zig");
5162const Dylib = @import("MachO/Dylib.zig");5174const Dylib = @import("MachO/Dylib.zig");
5163const File = link.File;5175const File = link.File;
5164const Object = @import("MachO/Object.zig");5176const Object = @import("MachO/Object.zig");
5165const LibStub = @import("tapi.zig").LibStub;5177const LibStub = tapi.LibStub;
5166const Liveness = @import("../Liveness.zig");5178const Liveness = @import("../Liveness.zig");
5167const LlvmObject = @import("../codegen/llvm.zig").Object;5179const LlvmObject = @import("../codegen/llvm.zig").Object;
5168const Md5 = std.crypto.hash.Md5;5180const Md5 = std.crypto.hash.Md5;
src/link/MachO/Dylib.zig+1-1
...@@ -320,7 +320,7 @@ pub fn parseFromStub(...@@ -320,7 +320,7 @@ pub fn parseFromStub(
320 dependent_libs: anytype,320 dependent_libs: anytype,
321 name: []const u8,321 name: []const u8,
322) !void {322) !void {
323 if (lib_stub.inner.len == 0) return error.EmptyStubFile;323 if (lib_stub.inner.len == 0) return error.NotLibStub;
324324
325 log.debug("parsing shared library from stub '{s}'", .{name});325 log.debug("parsing shared library from stub '{s}'", .{name});
326326
src/link/MachO/zld.zig+2
...@@ -361,6 +361,7 @@ pub fn linkWithZld(...@@ -361,6 +361,7 @@ pub fn linkWithZld(
361 &dependent_libs,361 &dependent_libs,
362 &parse_error_ctx,362 &parse_error_ctx,
363 ) catch |err| switch (err) {363 ) catch |err| switch (err) {
364 error.DylibAlreadyExists => {},
364 error.UnknownFileType => try macho_file.reportParseError(obj.path, "unknown file type", .{}),365 error.UnknownFileType => try macho_file.reportParseError(obj.path, "unknown file type", .{}),
365 error.MissingArchFatLib => try macho_file.reportParseError(366 error.MissingArchFatLib => try macho_file.reportParseError(
366 obj.path,367 obj.path,
...@@ -392,6 +393,7 @@ pub fn linkWithZld(...@@ -392,6 +393,7 @@ pub fn linkWithZld(
392 &dependent_libs,393 &dependent_libs,
393 &parse_error_ctx,394 &parse_error_ctx,
394 ) catch |err| switch (err) {395 ) catch |err| switch (err) {
396 error.DylibAlreadyExists => {},
395 error.UnknownFileType => try macho_file.reportParseError(path, "unknown file type", .{}),397 error.UnknownFileType => try macho_file.reportParseError(path, "unknown file type", .{}),
396 error.MissingArchFatLib => try macho_file.reportParseError(398 error.MissingArchFatLib => try macho_file.reportParseError(
397 path,399 path,
src/link/tapi.zig+8-2
...@@ -2,9 +2,10 @@ const std = @import("std");...@@ -2,9 +2,10 @@ const std = @import("std");
2const fs = std.fs;2const fs = std.fs;
3const mem = std.mem;3const mem = std.mem;
4const log = std.log.scoped(.tapi);4const log = std.log.scoped(.tapi);
5const yaml = @import("tapi/yaml.zig");
56
6const Allocator = mem.Allocator;7const Allocator = mem.Allocator;
7const Yaml = @import("tapi/yaml.zig").Yaml;8const Yaml = yaml.Yaml;
89
9const VersionField = union(enum) {10const VersionField = union(enum) {
10 string: []const u8,11 string: []const u8,
...@@ -102,6 +103,11 @@ pub const Tbd = union(enum) {...@@ -102,6 +103,11 @@ pub const Tbd = union(enum) {
102 }103 }
103};104};
104105
106pub const TapiError = error{
107 NotLibStub,
108 FileTooBig,
109} || yaml.YamlError || std.fs.File.ReadError;
110
105pub const LibStub = struct {111pub const LibStub = struct {
106 /// Underlying memory for stub's contents.112 /// Underlying memory for stub's contents.
107 yaml: Yaml,113 yaml: Yaml,
...@@ -109,7 +115,7 @@ pub const LibStub = struct {...@@ -109,7 +115,7 @@ pub const LibStub = struct {
109 /// Typed contents of the tbd file.115 /// Typed contents of the tbd file.
110 inner: []Tbd,116 inner: []Tbd,
111117
112 pub fn loadFromFile(allocator: Allocator, file: fs.File) !LibStub {118 pub fn loadFromFile(allocator: Allocator, file: fs.File) TapiError!LibStub {
113 const source = try file.readToEndAlloc(allocator, std.math.maxInt(u32));119 const source = try file.readToEndAlloc(allocator, std.math.maxInt(u32));
114 defer allocator.free(source);120 defer allocator.free(source);
115121