mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 05:20:34 +00:00
macho: don't store allocator in Archive
instead pass it in functions as an arg when required.
This commit is contained in:
parent
c30cc4dbbf
commit
586a19e3db
@ -2228,7 +2228,11 @@ fn resolveSymbols(self: *MachO) !void {
|
||||
};
|
||||
assert(offsets.items.len > 0);
|
||||
|
||||
const object = try archive.parseObject(offsets.items[0]);
|
||||
const object = try archive.parseObject(
|
||||
self.base.allocator,
|
||||
self.base.options.target.cpu.arch,
|
||||
offsets.items[0],
|
||||
);
|
||||
const object_id = @intCast(u16, self.objects.items.len);
|
||||
try self.objects.append(self.base.allocator, object);
|
||||
try self.resolveSymbolsInObject(object_id);
|
||||
@ -3340,7 +3344,7 @@ pub fn deinit(self: *MachO) void {
|
||||
self.objects.deinit(self.base.allocator);
|
||||
|
||||
for (self.archives.items) |archive| {
|
||||
archive.deinit();
|
||||
archive.deinit(self.base.allocator);
|
||||
self.base.allocator.destroy(archive);
|
||||
}
|
||||
self.archives.deinit(self.base.allocator);
|
||||
@ -3375,7 +3379,7 @@ pub fn closeFiles(self: MachO) void {
|
||||
object.file.close();
|
||||
}
|
||||
for (self.archives.items) |archive| {
|
||||
archive.closeFile();
|
||||
archive.file.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -12,13 +12,10 @@ const Allocator = mem.Allocator;
|
||||
const Arch = std.Target.Cpu.Arch;
|
||||
const Object = @import("Object.zig");
|
||||
|
||||
usingnamespace @import("commands.zig");
|
||||
file: fs.File,
|
||||
name: []const u8,
|
||||
|
||||
allocator: *Allocator,
|
||||
arch: ?Arch = null,
|
||||
file: ?fs.File = null,
|
||||
header: ?ar_hdr = null,
|
||||
name: ?[]const u8 = null,
|
||||
|
||||
// The actual contents we care about linking with will be embedded at
|
||||
// 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
|
||||
errdefer allocator.free(name);
|
||||
|
||||
archive.* = .{
|
||||
.allocator = allocator,
|
||||
.arch = arch,
|
||||
.name = name,
|
||||
.file = file,
|
||||
};
|
||||
|
||||
archive.parse() catch |err| switch (err) {
|
||||
archive.parse(allocator, arch) catch |err| switch (err) {
|
||||
error.EndOfStream, error.NotArchive => {
|
||||
archive.deinit();
|
||||
archive.deinit(allocator);
|
||||
allocator.destroy(archive);
|
||||
return null;
|
||||
},
|
||||
@ -128,32 +123,23 @@ pub fn createAndParseFromPath(allocator: *Allocator, arch: Arch, path: []const u
|
||||
return archive;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Archive) void {
|
||||
pub fn deinit(self: *Archive, allocator: *Allocator) void {
|
||||
for (self.toc.keys()) |*key| {
|
||||
self.allocator.free(key.*);
|
||||
allocator.free(key.*);
|
||||
}
|
||||
for (self.toc.values()) |*value| {
|
||||
value.deinit(self.allocator);
|
||||
}
|
||||
self.toc.deinit(self.allocator);
|
||||
|
||||
if (self.name) |n| {
|
||||
self.allocator.free(n);
|
||||
value.deinit(allocator);
|
||||
}
|
||||
self.toc.deinit(allocator);
|
||||
allocator.free(self.name);
|
||||
}
|
||||
|
||||
pub fn closeFile(self: Archive) void {
|
||||
if (self.file) |f| {
|
||||
f.close();
|
||||
}
|
||||
}
|
||||
pub fn parse(self: *Archive, allocator: *Allocator, arch: Arch) !void {
|
||||
self.library_offset = try fat.getLibraryOffset(self.file.reader(), arch);
|
||||
|
||||
pub fn parse(self: *Archive) !void {
|
||||
self.library_offset = try fat.getLibraryOffset(self.file.?.reader(), self.arch.?);
|
||||
try self.file.seekTo(self.library_offset);
|
||||
|
||||
try self.file.?.seekTo(self.library_offset);
|
||||
|
||||
var reader = self.file.?.reader();
|
||||
var reader = self.file.reader();
|
||||
const magic = try reader.readBytesNoEof(SARMAG);
|
||||
|
||||
if (!mem.eql(u8, &magic, ARMAG)) {
|
||||
@ -168,11 +154,11 @@ pub fn parse(self: *Archive) !void {
|
||||
return error.NotArchive;
|
||||
}
|
||||
|
||||
var embedded_name = try parseName(self.allocator, self.header.?, reader);
|
||||
log.debug("parsing archive '{s}' at '{s}'", .{ embedded_name, self.name.? });
|
||||
defer self.allocator.free(embedded_name);
|
||||
var embedded_name = try parseName(allocator, self.header.?, reader);
|
||||
log.debug("parsing archive '{s}' at '{s}'", .{ embedded_name, self.name });
|
||||
defer allocator.free(embedded_name);
|
||||
|
||||
try self.parseTableOfContents(reader);
|
||||
try self.parseTableOfContents(allocator, reader);
|
||||
|
||||
try reader.context.seekTo(0);
|
||||
}
|
||||
@ -195,10 +181,10 @@ fn parseName(allocator: *Allocator, header: ar_hdr, reader: anytype) ![]u8 {
|
||||
return name;
|
||||
}
|
||||
|
||||
fn parseTableOfContents(self: *Archive, reader: anytype) !void {
|
||||
fn parseTableOfContents(self: *Archive, allocator: *Allocator, reader: anytype) !void {
|
||||
const symtab_size = try reader.readIntLittle(u32);
|
||||
var symtab = try self.allocator.alloc(u8, symtab_size);
|
||||
defer self.allocator.free(symtab);
|
||||
var symtab = try allocator.alloc(u8, symtab_size);
|
||||
defer allocator.free(symtab);
|
||||
|
||||
reader.readNoEof(symtab) catch {
|
||||
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 {
|
||||
};
|
||||
|
||||
const strtab_size = try reader.readIntLittle(u32);
|
||||
var strtab = try self.allocator.alloc(u8, strtab_size);
|
||||
defer self.allocator.free(strtab);
|
||||
var strtab = try allocator.alloc(u8, strtab_size);
|
||||
defer allocator.free(strtab);
|
||||
|
||||
reader.readNoEof(strtab) catch {
|
||||
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 {
|
||||
const object_offset = try symtab_reader.readIntLittle(u32);
|
||||
|
||||
const sym_name = mem.spanZ(@ptrCast([*:0]const u8, strtab.ptr + n_strx));
|
||||
const owned_name = try self.allocator.dupe(u8, sym_name);
|
||||
const res = try self.toc.getOrPut(self.allocator, owned_name);
|
||||
defer if (res.found_existing) self.allocator.free(owned_name);
|
||||
const owned_name = try allocator.dupe(u8, sym_name);
|
||||
const res = try self.toc.getOrPut(allocator, owned_name);
|
||||
defer if (res.found_existing) allocator.free(owned_name);
|
||||
|
||||
if (!res.found_existing) {
|
||||
res.value_ptr.* = .{};
|
||||
}
|
||||
|
||||
try res.value_ptr.append(self.allocator, object_offset);
|
||||
try res.value_ptr.append(allocator, object_offset);
|
||||
}
|
||||
}
|
||||
|
||||
/// Caller owns the Object instance.
|
||||
pub fn parseObject(self: Archive, offset: u32) !*Object {
|
||||
var reader = self.file.?.reader();
|
||||
pub fn parseObject(self: Archive, allocator: *Allocator, arch: Arch, offset: u32) !*Object {
|
||||
var reader = self.file.reader();
|
||||
try reader.context.seekTo(offset + self.library_offset);
|
||||
|
||||
const object_header = try reader.readStruct(ar_hdr);
|
||||
@ -249,27 +235,27 @@ pub fn parseObject(self: Archive, offset: u32) !*Object {
|
||||
return error.MalformedArchive;
|
||||
}
|
||||
|
||||
const object_name = try parseName(self.allocator, object_header, reader);
|
||||
defer self.allocator.free(object_name);
|
||||
const object_name = try parseName(allocator, object_header, reader);
|
||||
defer allocator.free(object_name);
|
||||
|
||||
log.debug("extracting object '{s}' from archive '{s}'", .{ object_name, self.name.? });
|
||||
log.debug("extracting object '{s}' from archive '{s}'", .{ object_name, self.name });
|
||||
|
||||
const name = name: {
|
||||
var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
|
||||
const path = try std.os.realpath(self.name.?, &buffer);
|
||||
break :name try std.fmt.allocPrint(self.allocator, "{s}({s})", .{ path, object_name });
|
||||
const path = try std.os.realpath(self.name, &buffer);
|
||||
break :name try std.fmt.allocPrint(allocator, "{s}({s})", .{ path, object_name });
|
||||
};
|
||||
|
||||
var object = try self.allocator.create(Object);
|
||||
errdefer self.allocator.destroy(object);
|
||||
var object = try allocator.create(Object);
|
||||
errdefer allocator.destroy(object);
|
||||
|
||||
object.* = .{
|
||||
.file = try fs.cwd().openFile(self.name.?, .{}),
|
||||
.file = try fs.cwd().openFile(self.name, .{}),
|
||||
.name = name,
|
||||
.file_offset = @intCast(u32, try reader.context.getPos()),
|
||||
.mtime = try self.header.?.date(),
|
||||
};
|
||||
try object.parse(self.allocator, self.arch.?);
|
||||
try object.parse(allocator, arch);
|
||||
try reader.context.seekTo(0);
|
||||
|
||||
return object;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user