authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-07-31 10:41:51+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-01 09:06:56+02:00
log586a19e3db7d462559874ce6ac877608f7e50f10
treea527e724ffc1a0532b69ce2fc255749dbbab9d83
parentc30cc4dbbfe3e1494160ffac18ce6a9f9a5e5224

macho: don't store allocator in Archive

instead pass it in functions as an arg when required.

2 files changed, 44 insertions(+), 54 deletions(-)

src/link/MachO.zig+7-3
...@@ -2228,7 +2228,11 @@ fn resolveSymbols(self: *MachO) !void {...@@ -2228,7 +2228,11 @@ fn resolveSymbols(self: *MachO) !void {
2228 };2228 };
2229 assert(offsets.items.len > 0);2229 assert(offsets.items.len > 0);
22302230
2231 const object = try archive.parseObject(offsets.items[0]);2231 const object = try archive.parseObject(
2232 self.base.allocator,
2233 self.base.options.target.cpu.arch,
2234 offsets.items[0],
2235 );
2232 const object_id = @intCast(u16, self.objects.items.len);2236 const object_id = @intCast(u16, self.objects.items.len);
2233 try self.objects.append(self.base.allocator, object);2237 try self.objects.append(self.base.allocator, object);
2234 try self.resolveSymbolsInObject(object_id);2238 try self.resolveSymbolsInObject(object_id);
...@@ -3340,7 +3344,7 @@ pub fn deinit(self: *MachO) void {...@@ -3340,7 +3344,7 @@ pub fn deinit(self: *MachO) void {
3340 self.objects.deinit(self.base.allocator);3344 self.objects.deinit(self.base.allocator);
33413345
3342 for (self.archives.items) |archive| {3346 for (self.archives.items) |archive| {
3343 archive.deinit();3347 archive.deinit(self.base.allocator);
3344 self.base.allocator.destroy(archive);3348 self.base.allocator.destroy(archive);
3345 }3349 }
3346 self.archives.deinit(self.base.allocator);3350 self.archives.deinit(self.base.allocator);
...@@ -3375,7 +3379,7 @@ pub fn closeFiles(self: MachO) void {...@@ -3375,7 +3379,7 @@ pub fn closeFiles(self: MachO) void {
3375 object.file.close();3379 object.file.close();
3376 }3380 }
3377 for (self.archives.items) |archive| {3381 for (self.archives.items) |archive| {
3378 archive.closeFile();3382 archive.file.close();
3379 }3383 }
3380}3384}
33813385
src/link/MachO/Archive.zig+37-51
...@@ -12,13 +12,10 @@ const Allocator = mem.Allocator;...@@ -12,13 +12,10 @@ const Allocator = mem.Allocator;
12const Arch = std.Target.Cpu.Arch;12const Arch = std.Target.Cpu.Arch;
13const Object = @import("Object.zig");13const Object = @import("Object.zig");
1414
15usingnamespace @import("commands.zig");15file: fs.File,
16name: []const u8,
1617
17allocator: *Allocator,
18arch: ?Arch = null,
19file: ?fs.File = null,
20header: ?ar_hdr = null,18header: ?ar_hdr = null,
21name: ?[]const u8 = null,
2219
23// The actual contents we care about linking with will be embedded at20// The actual contents we care about linking with will be embedded at
24// an offset within a file if we are linking against a fat lib21// an offset within a file if we are linking against a fat lib
...@@ -110,15 +107,13 @@ pub fn createAndParseFromPath(allocator: *Allocator, arch: Arch, path: []const u...@@ -110,15 +107,13 @@ pub fn createAndParseFromPath(allocator: *Allocator, arch: Arch, path: []const u
110 errdefer allocator.free(name);107 errdefer allocator.free(name);
111108
112 archive.* = .{109 archive.* = .{
113 .allocator = allocator,
114 .arch = arch,
115 .name = name,110 .name = name,
116 .file = file,111 .file = file,
117 };112 };
118113
119 archive.parse() catch |err| switch (err) {114 archive.parse(allocator, arch) catch |err| switch (err) {
120 error.EndOfStream, error.NotArchive => {115 error.EndOfStream, error.NotArchive => {
121 archive.deinit();116 archive.deinit(allocator);
122 allocator.destroy(archive);117 allocator.destroy(archive);
123 return null;118 return null;
124 },119 },
...@@ -128,32 +123,23 @@ pub fn createAndParseFromPath(allocator: *Allocator, arch: Arch, path: []const u...@@ -128,32 +123,23 @@ pub fn createAndParseFromPath(allocator: *Allocator, arch: Arch, path: []const u
128 return archive;123 return archive;
129}124}
130125
131pub fn deinit(self: *Archive) void {126pub fn deinit(self: *Archive, allocator: *Allocator) void {
132 for (self.toc.keys()) |*key| {127 for (self.toc.keys()) |*key| {
133 self.allocator.free(key.*);128 allocator.free(key.*);
134 }129 }
135 for (self.toc.values()) |*value| {130 for (self.toc.values()) |*value| {
136 value.deinit(self.allocator);131 value.deinit(allocator);
137 }
138 self.toc.deinit(self.allocator);
139
140 if (self.name) |n| {
141 self.allocator.free(n);
142 }
143}
144
145pub fn closeFile(self: Archive) void {
146 if (self.file) |f| {
147 f.close();
148 }132 }
133 self.toc.deinit(allocator);
134 allocator.free(self.name);
149}135}
150136
151pub fn parse(self: *Archive) !void {137pub fn parse(self: *Archive, allocator: *Allocator, arch: Arch) !void {
152 self.library_offset = try fat.getLibraryOffset(self.file.?.reader(), self.arch.?);138 self.library_offset = try fat.getLibraryOffset(self.file.reader(), arch);
153139
154 try self.file.?.seekTo(self.library_offset);140 try self.file.seekTo(self.library_offset);
155141
156 var reader = self.file.?.reader();142 var reader = self.file.reader();
157 const magic = try reader.readBytesNoEof(SARMAG);143 const magic = try reader.readBytesNoEof(SARMAG);
158144
159 if (!mem.eql(u8, &magic, ARMAG)) {145 if (!mem.eql(u8, &magic, ARMAG)) {
...@@ -168,11 +154,11 @@ pub fn parse(self: *Archive) !void {...@@ -168,11 +154,11 @@ pub fn parse(self: *Archive) !void {
168 return error.NotArchive;154 return error.NotArchive;
169 }155 }
170156
171 var embedded_name = try parseName(self.allocator, self.header.?, reader);157 var embedded_name = try parseName(allocator, self.header.?, reader);
172 log.debug("parsing archive '{s}' at '{s}'", .{ embedded_name, self.name.? });158 log.debug("parsing archive '{s}' at '{s}'", .{ embedded_name, self.name });
173 defer self.allocator.free(embedded_name);159 defer allocator.free(embedded_name);
174160
175 try self.parseTableOfContents(reader);161 try self.parseTableOfContents(allocator, reader);
176162
177 try reader.context.seekTo(0);163 try reader.context.seekTo(0);
178}164}
...@@ -195,10 +181,10 @@ fn parseName(allocator: *Allocator, header: ar_hdr, reader: anytype) ![]u8 {...@@ -195,10 +181,10 @@ fn parseName(allocator: *Allocator, header: ar_hdr, reader: anytype) ![]u8 {
195 return name;181 return name;
196}182}
197183
198fn parseTableOfContents(self: *Archive, reader: anytype) !void {184fn parseTableOfContents(self: *Archive, allocator: *Allocator, reader: anytype) !void {
199 const symtab_size = try reader.readIntLittle(u32);185 const symtab_size = try reader.readIntLittle(u32);
200 var symtab = try self.allocator.alloc(u8, symtab_size);186 var symtab = try allocator.alloc(u8, symtab_size);
201 defer self.allocator.free(symtab);187 defer allocator.free(symtab);
202188
203 reader.readNoEof(symtab) catch {189 reader.readNoEof(symtab) catch {
204 log.err("incomplete symbol table: expected symbol table of length 0x{x}", .{symtab_size});190 log.err("incomplete symbol table: expected symbol table of length 0x{x}", .{symtab_size});
...@@ -206,8 +192,8 @@ fn parseTableOfContents(self: *Archive, reader: anytype) !void {...@@ -206,8 +192,8 @@ fn parseTableOfContents(self: *Archive, reader: anytype) !void {
206 };192 };
207193
208 const strtab_size = try reader.readIntLittle(u32);194 const strtab_size = try reader.readIntLittle(u32);
209 var strtab = try self.allocator.alloc(u8, strtab_size);195 var strtab = try allocator.alloc(u8, strtab_size);
210 defer self.allocator.free(strtab);196 defer allocator.free(strtab);
211197
212 reader.readNoEof(strtab) catch {198 reader.readNoEof(strtab) catch {
213 log.err("incomplete symbol table: expected string table of length 0x{x}", .{strtab_size});199 log.err("incomplete symbol table: expected string table of length 0x{x}", .{strtab_size});
...@@ -225,21 +211,21 @@ fn parseTableOfContents(self: *Archive, reader: anytype) !void {...@@ -225,21 +211,21 @@ fn parseTableOfContents(self: *Archive, reader: anytype) !void {
225 const object_offset = try symtab_reader.readIntLittle(u32);211 const object_offset = try symtab_reader.readIntLittle(u32);
226212
227 const sym_name = mem.spanZ(@ptrCast([*:0]const u8, strtab.ptr + n_strx));213 const sym_name = mem.spanZ(@ptrCast([*:0]const u8, strtab.ptr + n_strx));
228 const owned_name = try self.allocator.dupe(u8, sym_name);214 const owned_name = try allocator.dupe(u8, sym_name);
229 const res = try self.toc.getOrPut(self.allocator, owned_name);215 const res = try self.toc.getOrPut(allocator, owned_name);
230 defer if (res.found_existing) self.allocator.free(owned_name);216 defer if (res.found_existing) allocator.free(owned_name);
231217
232 if (!res.found_existing) {218 if (!res.found_existing) {
233 res.value_ptr.* = .{};219 res.value_ptr.* = .{};
234 }220 }
235221
236 try res.value_ptr.append(self.allocator, object_offset);222 try res.value_ptr.append(allocator, object_offset);
237 }223 }
238}224}
239225
240/// Caller owns the Object instance.226/// Caller owns the Object instance.
241pub fn parseObject(self: Archive, offset: u32) !*Object {227pub fn parseObject(self: Archive, allocator: *Allocator, arch: Arch, offset: u32) !*Object {
242 var reader = self.file.?.reader();228 var reader = self.file.reader();
243 try reader.context.seekTo(offset + self.library_offset);229 try reader.context.seekTo(offset + self.library_offset);
244230
245 const object_header = try reader.readStruct(ar_hdr);231 const object_header = try reader.readStruct(ar_hdr);
...@@ -249,27 +235,27 @@ pub fn parseObject(self: Archive, offset: u32) !*Object {...@@ -249,27 +235,27 @@ pub fn parseObject(self: Archive, offset: u32) !*Object {
249 return error.MalformedArchive;235 return error.MalformedArchive;
250 }236 }
251237
252 const object_name = try parseName(self.allocator, object_header, reader);238 const object_name = try parseName(allocator, object_header, reader);
253 defer self.allocator.free(object_name);239 defer allocator.free(object_name);
254240
255 log.debug("extracting object '{s}' from archive '{s}'", .{ object_name, self.name.? });241 log.debug("extracting object '{s}' from archive '{s}'", .{ object_name, self.name });
256242
257 const name = name: {243 const name = name: {
258 var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;244 var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
259 const path = try std.os.realpath(self.name.?, &buffer);245 const path = try std.os.realpath(self.name, &buffer);
260 break :name try std.fmt.allocPrint(self.allocator, "{s}({s})", .{ path, object_name });246 break :name try std.fmt.allocPrint(allocator, "{s}({s})", .{ path, object_name });
261 };247 };
262248
263 var object = try self.allocator.create(Object);249 var object = try allocator.create(Object);
264 errdefer self.allocator.destroy(object);250 errdefer allocator.destroy(object);
265251
266 object.* = .{252 object.* = .{
267 .file = try fs.cwd().openFile(self.name.?, .{}),253 .file = try fs.cwd().openFile(self.name, .{}),
268 .name = name,254 .name = name,
269 .file_offset = @intCast(u32, try reader.context.getPos()),255 .file_offset = @intCast(u32, try reader.context.getPos()),
270 .mtime = try self.header.?.date(),256 .mtime = try self.header.?.date(),
271 };257 };
272 try object.parse(self.allocator, self.arch.?);258 try object.parse(allocator, arch);
273 try reader.context.seekTo(0);259 try reader.context.seekTo(0);
274260
275 return object;261 return object;