aboutsummaryrefslogtreecommitdiff
path: root/src/link/MachO/Object.zig
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2024-02-07 19:08:15 +0100
committerJakub Konka <kubkon@jakubkonka.com>2024-02-07 19:27:26 +0100
commitf9eb14ddcfdc508fd03f35e9d89a8f55baf7d11b (patch)
tree38319996d8e4f0657253a1177ac40144b3f91ded /src/link/MachO/Object.zig
parent82144a9073aa06f037e248f332608f94caed59b9 (diff)
downloadzig-f9eb14ddcfdc508fd03f35e9d89a8f55baf7d11b.tar.gz
zig-f9eb14ddcfdc508fd03f35e9d89a8f55baf7d11b.zip
macho: parse input object files specifically for incl in archive
Diffstat (limited to 'src/link/MachO/Object.zig')
-rw-r--r--src/link/MachO/Object.zig76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig
index 9d436d0197..8436a8b853 100644
--- a/src/link/MachO/Object.zig
+++ b/src/link/MachO/Object.zig
@@ -1233,6 +1233,82 @@ fn addSection(self: *Object, allocator: Allocator, segname: []const u8, sectname
return n_sect;
}
+pub fn parseAr(self: *Object, macho_file: *MachO) !void {
+ const tracy = trace(@src());
+ defer tracy.end();
+
+ const gpa = macho_file.base.comp.gpa;
+ const offset = if (self.archive) |ar| ar.offset else 0;
+ const handle = macho_file.getFileHandle(self.file_handle);
+
+ var header_buffer: [@sizeOf(macho.mach_header_64)]u8 = undefined;
+ {
+ const amt = try handle.preadAll(&header_buffer, offset);
+ if (amt != @sizeOf(macho.mach_header_64)) return error.InputOutput;
+ }
+ self.header = @as(*align(1) const macho.mach_header_64, @ptrCast(&header_buffer)).*;
+
+ const this_cpu_arch: std.Target.Cpu.Arch = switch (self.header.?.cputype) {
+ macho.CPU_TYPE_ARM64 => .aarch64,
+ macho.CPU_TYPE_X86_64 => .x86_64,
+ else => |x| {
+ try macho_file.reportParseError2(self.index, "unknown cpu architecture: {d}", .{x});
+ return error.InvalidCpuArch;
+ },
+ };
+ if (macho_file.getTarget().cpu.arch != this_cpu_arch) {
+ try macho_file.reportParseError2(self.index, "invalid cpu architecture: {s}", .{@tagName(this_cpu_arch)});
+ return error.InvalidCpuArch;
+ }
+
+ const lc_buffer = try gpa.alloc(u8, self.header.?.sizeofcmds);
+ defer gpa.free(lc_buffer);
+ {
+ const amt = try handle.preadAll(lc_buffer, offset + @sizeOf(macho.mach_header_64));
+ if (amt != self.header.?.sizeofcmds) return error.InputOutput;
+ }
+
+ var it = LoadCommandIterator{
+ .ncmds = self.header.?.ncmds,
+ .buffer = lc_buffer,
+ };
+ while (it.next()) |lc| switch (lc.cmd()) {
+ .SYMTAB => {
+ const cmd = lc.cast(macho.symtab_command).?;
+ try self.strtab.resize(gpa, cmd.strsize);
+ {
+ const amt = try handle.preadAll(self.strtab.items, cmd.stroff + offset);
+ if (amt != self.strtab.items.len) return error.InputOutput;
+ }
+
+ const symtab_buffer = try gpa.alloc(u8, cmd.nsyms * @sizeOf(macho.nlist_64));
+ defer gpa.free(symtab_buffer);
+ {
+ const amt = try handle.preadAll(symtab_buffer, cmd.symoff + offset);
+ if (amt != symtab_buffer.len) return error.InputOutput;
+ }
+ const symtab = @as([*]align(1) const macho.nlist_64, @ptrCast(symtab_buffer.ptr))[0..cmd.nsyms];
+ try self.symtab.ensureUnusedCapacity(gpa, symtab.len);
+ for (symtab) |nlist| {
+ self.symtab.appendAssumeCapacity(.{
+ .nlist = nlist,
+ .atom = 0,
+ .size = 0,
+ });
+ }
+ },
+ .BUILD_VERSION,
+ .VERSION_MIN_MACOSX,
+ .VERSION_MIN_IPHONEOS,
+ .VERSION_MIN_TVOS,
+ .VERSION_MIN_WATCHOS,
+ => if (self.platform == null) {
+ self.platform = MachO.Platform.fromLoadCommand(lc);
+ },
+ else => {},
+ };
+}
+
pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, macho_file: *MachO) error{OutOfMemory}!void {
const gpa = macho_file.base.comp.gpa;
for (self.symtab.items(.nlist)) |nlist| {