| ... | @@ -801,6 +801,16 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { | ... | @@ -801,6 +801,16 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { |
| 801 | mem.copy(u8, dylib_cmd.data, mem.spanZ(LIB_SYSTEM_PATH)); | 801 | mem.copy(u8, dylib_cmd.data, mem.spanZ(LIB_SYSTEM_PATH)); |
| 802 | try self.load_commands.append(self.base.allocator, .{ .Dylib = dylib_cmd }); | 802 | try self.load_commands.append(self.base.allocator, .{ .Dylib = dylib_cmd }); |
| 803 | | 803 | |
| | 804 | if (self.symtab_cmd_index == null or self.dysymtab_cmd_index == null) { |
| | 805 | std.log.err("Incomplete Mach-O binary: no LC_SYMTAB or LC_DYSYMTAB load command found!", .{}); |
| | 806 | std.log.err("Without the symbol table, it is not possible to patch up the binary for cross-compilation.", .{}); |
| | 807 | return error.NoSymbolTable; |
| | 808 | } |
| | 809 | |
| | 810 | // Parse symbol and string tables. |
| | 811 | try self.parseSymbolTable(); |
| | 812 | try self.parseStringTable(); |
| | 813 | |
| 804 | // Parse dyld info | 814 | // Parse dyld info |
| 805 | try self.parseBindingInfo(); | 815 | try self.parseBindingInfo(); |
| 806 | try self.parseLazyBindingInfo(); | 816 | try self.parseLazyBindingInfo(); |
| ... | @@ -2038,8 +2048,6 @@ fn parseFromFile(self: *MachO, file: fs.File) !void { | ... | @@ -2038,8 +2048,6 @@ fn parseFromFile(self: *MachO, file: fs.File) !void { |
| 2038 | self.load_commands.appendAssumeCapacity(cmd); | 2048 | self.load_commands.appendAssumeCapacity(cmd); |
| 2039 | } | 2049 | } |
| 2040 | self.header = header; | 2050 | self.header = header; |
| 2041 | | | |
| 2042 | // TODO Should we parse memory mapped segments here or as needed? | | |
| 2043 | } | 2051 | } |
| 2044 | | 2052 | |
| 2045 | fn parseAndCmpName(name: []const u8, needle: []const u8) bool { | 2053 | fn parseAndCmpName(name: []const u8, needle: []const u8) bool { |
| ... | @@ -2047,6 +2055,37 @@ fn parseAndCmpName(name: []const u8, needle: []const u8) bool { | ... | @@ -2047,6 +2055,37 @@ fn parseAndCmpName(name: []const u8, needle: []const u8) bool { |
| 2047 | return mem.eql(u8, name[0..len], needle); | 2055 | return mem.eql(u8, name[0..len], needle); |
| 2048 | } | 2056 | } |
| 2049 | | 2057 | |
| | 2058 | fn parseSymbolTable(self: *MachO) !void { |
| | 2059 | const symtab = self.load_commands.items[self.symtab_cmd_index.?].Symtab; |
| | 2060 | const dysymtab = self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab; |
| | 2061 | |
| | 2062 | var buffer = try self.base.allocator.alloc(macho.nlist_64, symtab.nsyms); |
| | 2063 | defer self.base.allocator.free(buffer); |
| | 2064 | const nread = try self.base.file.?.preadAll(@ptrCast([*]u8, buffer)[0 .. symtab.nsyms * @sizeOf(macho.nlist_64)], symtab.symoff); |
| | 2065 | assert(@divExact(nread, @sizeOf(macho.nlist_64)) == buffer.len); |
| | 2066 | |
| | 2067 | try self.local_symbols.ensureCapacity(self.base.allocator, dysymtab.nlocalsym); |
| | 2068 | try self.global_symbols.ensureCapacity(self.base.allocator, dysymtab.nextdefsym); |
| | 2069 | try self.undef_symbols.ensureCapacity(self.base.allocator, dysymtab.nundefsym); |
| | 2070 | |
| | 2071 | self.local_symbols.appendSliceAssumeCapacity(buffer[dysymtab.ilocalsym .. dysymtab.ilocalsym + dysymtab.nlocalsym]); |
| | 2072 | self.global_symbols.appendSliceAssumeCapacity(buffer[dysymtab.iextdefsym .. dysymtab.iextdefsym + dysymtab.nextdefsym]); |
| | 2073 | self.undef_symbols.appendSliceAssumeCapacity(buffer[dysymtab.iundefsym .. dysymtab.iundefsym + dysymtab.nundefsym]); |
| | 2074 | } |
| | 2075 | |
| | 2076 | fn parseStringTable(self: *MachO) !void { |
| | 2077 | const symtab = self.load_commands.items[self.symtab_cmd_index.?].Symtab; |
| | 2078 | |
| | 2079 | var buffer = try self.base.allocator.alloc(u8, symtab.strsize); |
| | 2080 | defer self.base.allocator.free(buffer); |
| | 2081 | const nread = try self.base.file.?.preadAll(buffer, symtab.stroff); |
| | 2082 | assert(nread == buffer.len); |
| | 2083 | |
| | 2084 | try self.string_table.ensureCapacity(self.base.allocator, symtab.strsize); |
| | 2085 | |
| | 2086 | self.string_table.appendSliceAssumeCapacity(buffer); |
| | 2087 | } |
| | 2088 | |
| 2050 | fn parseBindingInfo(self: *MachO) !void { | 2089 | fn parseBindingInfo(self: *MachO) !void { |
| 2051 | const dyld_info = self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly; | 2090 | const dyld_info = self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly; |
| 2052 | var buffer = try self.base.allocator.alloc(u8, dyld_info.bind_size); | 2091 | var buffer = try self.base.allocator.alloc(u8, dyld_info.bind_size); |