| ... | @@ -23,9 +23,23 @@ load_commands: std.ArrayListUnmanaged(LoadCommand) = .{}, | ... | @@ -23,9 +23,23 @@ load_commands: std.ArrayListUnmanaged(LoadCommand) = .{}, |
| 23 | | 23 | |
| 24 | symtab_cmd_index: ?u16 = null, | 24 | symtab_cmd_index: ?u16 = null, |
| 25 | dysymtab_cmd_index: ?u16 = null, | 25 | dysymtab_cmd_index: ?u16 = null, |
| | 26 | id_cmd_index: ?u16 = null, |
| | 27 | |
| | 28 | id: ?Id = null, |
| 26 | | 29 | |
| 27 | symbols: std.StringArrayHashMapUnmanaged(*Symbol) = .{}, | 30 | symbols: std.StringArrayHashMapUnmanaged(*Symbol) = .{}, |
| 28 | | 31 | |
| | 32 | pub const Id = struct { |
| | 33 | name: []const u8, |
| | 34 | timestamp: u32, |
| | 35 | current_version: u32, |
| | 36 | compatibility_version: u32, |
| | 37 | |
| | 38 | pub fn deinit(id: *Id, allocator: *Allocator) void { |
| | 39 | allocator.free(id.name); |
| | 40 | } |
| | 41 | }; |
| | 42 | |
| 29 | pub fn init(allocator: *Allocator) Dylib { | 43 | pub fn init(allocator: *Allocator) Dylib { |
| 30 | return .{ .allocator = allocator }; | 44 | return .{ .allocator = allocator }; |
| 31 | } | 45 | } |
| ... | @@ -45,6 +59,10 @@ pub fn deinit(self: *Dylib) void { | ... | @@ -45,6 +59,10 @@ pub fn deinit(self: *Dylib) void { |
| 45 | if (self.name) |name| { | 59 | if (self.name) |name| { |
| 46 | self.allocator.free(name); | 60 | self.allocator.free(name); |
| 47 | } | 61 | } |
| | 62 | |
| | 63 | if (self.id) |*id| { |
| | 64 | id.deinit(self.allocator); |
| | 65 | } |
| 48 | } | 66 | } |
| 49 | | 67 | |
| 50 | pub fn closeFile(self: Dylib) void { | 68 | pub fn closeFile(self: Dylib) void { |
| ... | @@ -78,6 +96,7 @@ pub fn parse(self: *Dylib) !void { | ... | @@ -78,6 +96,7 @@ pub fn parse(self: *Dylib) !void { |
| 78 | } | 96 | } |
| 79 | | 97 | |
| 80 | try self.readLoadCommands(reader); | 98 | try self.readLoadCommands(reader); |
| | 99 | try self.parseId(); |
| 81 | try self.parseSymbols(); | 100 | try self.parseSymbols(); |
| 82 | } | 101 | } |
| 83 | | 102 | |
| ... | @@ -94,6 +113,9 @@ pub fn readLoadCommands(self: *Dylib, reader: anytype) !void { | ... | @@ -94,6 +113,9 @@ pub fn readLoadCommands(self: *Dylib, reader: anytype) !void { |
| 94 | macho.LC_DYSYMTAB => { | 113 | macho.LC_DYSYMTAB => { |
| 95 | self.dysymtab_cmd_index = i; | 114 | self.dysymtab_cmd_index = i; |
| 96 | }, | 115 | }, |
| | 116 | macho.LC_ID_DYLIB => { |
| | 117 | self.id_cmd_index = i; |
| | 118 | }, |
| 97 | else => { | 119 | else => { |
| 98 | log.debug("Unknown load command detected: 0x{x}.", .{cmd.cmd()}); | 120 | log.debug("Unknown load command detected: 0x{x}.", .{cmd.cmd()}); |
| 99 | }, | 121 | }, |
| ... | @@ -102,6 +124,32 @@ pub fn readLoadCommands(self: *Dylib, reader: anytype) !void { | ... | @@ -102,6 +124,32 @@ pub fn readLoadCommands(self: *Dylib, reader: anytype) !void { |
| 102 | } | 124 | } |
| 103 | } | 125 | } |
| 104 | | 126 | |
| | 127 | pub fn parseId(self: *Dylib) !void { |
| | 128 | const index = self.id_cmd_index orelse { |
| | 129 | log.debug("no LC_ID_DYLIB load command found; using hard-coded defaults...", .{}); |
| | 130 | self.id = .{ |
| | 131 | .name = try self.allocator.dupe(u8, self.name.?), |
| | 132 | .timestamp = 2, |
| | 133 | .current_version = 0, |
| | 134 | .compatibility_version = 0, |
| | 135 | }; |
| | 136 | return; |
| | 137 | }; |
| | 138 | const id_cmd = self.load_commands.items[index].Dylib; |
| | 139 | const dylib = id_cmd.inner.dylib; |
| | 140 | |
| | 141 | // TODO should we compare the name from the dylib's id with the user-specified one? |
| | 142 | const dylib_name = @ptrCast([*:0]const u8, id_cmd.data[dylib.name - @sizeOf(macho.dylib_command) ..]); |
| | 143 | const name = try self.allocator.dupe(u8, mem.spanZ(dylib_name)); |
| | 144 | |
| | 145 | self.id = .{ |
| | 146 | .name = name, |
| | 147 | .timestamp = dylib.timestamp, |
| | 148 | .current_version = dylib.current_version, |
| | 149 | .compatibility_version = dylib.compatibility_version, |
| | 150 | }; |
| | 151 | } |
| | 152 | |
| 105 | pub fn parseSymbols(self: *Dylib) !void { | 153 | pub fn parseSymbols(self: *Dylib) !void { |
| 106 | const index = self.symtab_cmd_index orelse return; | 154 | const index = self.symtab_cmd_index orelse return; |
| 107 | const symtab_cmd = self.load_commands.items[index].Symtab; | 155 | const symtab_cmd = self.load_commands.items[index].Symtab; |