diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2021-07-31 15:01:37 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2021-08-01 09:06:56 +0200 |
| commit | 06396ddd7d632704681bbd6278f18dcc2b6bf20c (patch) | |
| tree | 068f069096fe341c19a63e0de66e52c19e22ad5b /src/link/MachO/Object.zig | |
| parent | e73777333dd66570ddacdb7de56a390de01b33c5 (diff) | |
| download | zig-06396ddd7d632704681bbd6278f18dcc2b6bf20c.tar.gz zig-06396ddd7d632704681bbd6278f18dcc2b6bf20c.zip | |
macho: don't allocate Objects on the heap
instead, ownership is transferred to MachO. This makes Object
management align closer with data-oriented design.
Diffstat (limited to 'src/link/MachO/Object.zig')
| -rw-r--r-- | src/link/MachO/Object.zig | 60 |
1 files changed, 26 insertions, 34 deletions
diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index 1250f015ed..6a1bf8fd57 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -127,36 +127,6 @@ const DebugInfo = struct { } }; -pub fn createAndParseFromPath(allocator: *Allocator, arch: Arch, path: []const u8) !?*Object { - const file = fs.cwd().openFile(path, .{}) catch |err| switch (err) { - error.FileNotFound => return null, - else => |e| return e, - }; - errdefer file.close(); - - const object = try allocator.create(Object); - errdefer allocator.destroy(object); - - const name = try allocator.dupe(u8, path); - errdefer allocator.free(name); - - object.* = .{ - .name = name, - .file = file, - }; - - object.parse(allocator, arch) catch |err| switch (err) { - error.EndOfStream, error.NotObject => { - object.deinit(allocator); - allocator.destroy(object); - return null; - }, - else => |e| return e, - }; - - return object; -} - pub fn deinit(self: *Object, allocator: *Allocator) void { for (self.load_commands.items) |*lc| { lc.deinit(allocator); @@ -184,6 +154,22 @@ pub fn deinit(self: *Object, allocator: *Allocator) void { } } +pub fn isObject(file: fs.File) !bool { + const reader = file.reader(); + const is_object = blk: { + if (reader.readStruct(macho.mach_header_64)) |header| { + break :blk header.filetype == macho.MH_OBJECT; + } else |err| { + switch (err) { + error.EndOfStream => break :blk false, + else => |e| return e, + } + } + }; + try file.seekTo(0); + return is_object; +} + pub fn parse(self: *Object, allocator: *Allocator, arch: Arch) !void { var reader = self.file.reader(); if (self.file_offset) |offset| { @@ -481,7 +467,12 @@ const TextBlockParser = struct { } }; -pub fn parseTextBlocks(self: *Object, allocator: *Allocator, macho_file: *MachO) !void { +pub fn parseTextBlocks( + self: *Object, + allocator: *Allocator, + object_id: u16, + macho_file: *MachO, +) !void { const seg = self.load_commands.items[self.segment_cmd_index.?].Segment; log.debug("analysing {s}", .{self.name}); @@ -668,13 +659,14 @@ pub fn parseTextBlocks(self: *Object, allocator: *Allocator, macho_file: *MachO) if (is_ext) { if (macho_file.symbol_resolver.get(sym.n_strx)) |resolv| { assert(resolv.where == .global); - const global_object = macho_file.objects.items[resolv.file]; - if (global_object != self) { + if (resolv.file != object_id) { log.debug("deduping definition of {s} in {s}", .{ macho_file.getString(sym.n_strx), self.name, }); - log.debug(" already defined in {s}", .{global_object.name}); + log.debug(" already defined in {s}", .{ + macho_file.objects.items[resolv.file].name, + }); continue; } } |
