| ... | @@ -134,9 +134,7 @@ objc_data_section_index: ?u16 = null, | ... | @@ -134,9 +134,7 @@ objc_data_section_index: ?u16 = null, |
| 134 | | 134 | |
| 135 | locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | 135 | locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 136 | globals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | 136 | globals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 137 | imports: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | | |
| 138 | undefs: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | 137 | undefs: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 139 | tentatives: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | | |
| 140 | symbol_resolver: std.AutoHashMapUnmanaged(u32, SymbolWithLoc) = .{}, | 138 | symbol_resolver: std.AutoHashMapUnmanaged(u32, SymbolWithLoc) = .{}, |
| 141 | | 139 | |
| 142 | locals_free_list: std.ArrayListUnmanaged(u32) = .{}, | 140 | locals_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| ... | @@ -252,9 +250,7 @@ const SymbolWithLoc = struct { | ... | @@ -252,9 +250,7 @@ const SymbolWithLoc = struct { |
| 252 | // Table where the symbol can be found. | 250 | // Table where the symbol can be found. |
| 253 | where: enum { | 251 | where: enum { |
| 254 | global, | 252 | global, |
| 255 | import, | | |
| 256 | undef, | 253 | undef, |
| 257 | tentative, | | |
| 258 | }, | 254 | }, |
| 259 | where_index: u32, | 255 | where_index: u32, |
| 260 | local_sym_index: u32 = 0, | 256 | local_sym_index: u32 = 0, |
| ... | @@ -264,22 +260,11 @@ const SymbolWithLoc = struct { | ... | @@ -264,22 +260,11 @@ const SymbolWithLoc = struct { |
| 264 | pub const GotIndirectionKey = struct { | 260 | pub const GotIndirectionKey = struct { |
| 265 | where: enum { | 261 | where: enum { |
| 266 | local, | 262 | local, |
| 267 | import, | 263 | undef, |
| 268 | }, | 264 | }, |
| 269 | where_index: u32, | 265 | where_index: u32, |
| 270 | }; | 266 | }; |
| 271 | | 267 | |
| 272 | pub const PIEFixup = struct { | | |
| 273 | /// Target VM address of this relocation. | | |
| 274 | target_addr: u64, | | |
| 275 | | | |
| 276 | /// Offset within the byte stream. | | |
| 277 | offset: usize, | | |
| 278 | | | |
| 279 | /// Size of the relocation. | | |
| 280 | size: usize, | | |
| 281 | }; | | |
| 282 | | | |
| 283 | /// When allocating, the ideal_capacity is calculated by | 268 | /// When allocating, the ideal_capacity is calculated by |
| 284 | /// actual_capacity + (actual_capacity / ideal_factor) | 269 | /// actual_capacity + (actual_capacity / ideal_factor) |
| 285 | const ideal_factor = 2; | 270 | const ideal_factor = 2; |
| ... | @@ -960,7 +945,7 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void { | ... | @@ -960,7 +945,7 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void { |
| 960 | const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; | 945 | const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; |
| 961 | const got_index = @intCast(u32, self.got_entries.items.len); | 946 | const got_index = @intCast(u32, self.got_entries.items.len); |
| 962 | const got_entry = GotIndirectionKey{ | 947 | const got_entry = GotIndirectionKey{ |
| 963 | .where = .import, | 948 | .where = .undef, |
| 964 | .where_index = resolv.where_index, | 949 | .where_index = resolv.where_index, |
| 965 | }; | 950 | }; |
| 966 | try self.got_entries.append(self.base.allocator, got_entry); | 951 | try self.got_entries.append(self.base.allocator, got_entry); |
| ... | @@ -1991,7 +1976,7 @@ fn writeStubHelperCommon(self: *MachO) !void { | ... | @@ -1991,7 +1976,7 @@ fn writeStubHelperCommon(self: *MachO) !void { |
| 1991 | }) orelse unreachable; | 1976 | }) orelse unreachable; |
| 1992 | const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; | 1977 | const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; |
| 1993 | const got_index = self.got_entries_map.get(.{ | 1978 | const got_index = self.got_entries_map.get(.{ |
| 1994 | .where = .import, | 1979 | .where = .undef, |
| 1995 | .where_index = resolv.where_index, | 1980 | .where_index = resolv.where_index, |
| 1996 | }) orelse unreachable; | 1981 | }) orelse unreachable; |
| 1997 | const addr = got.addr + got_index * @sizeOf(u64); | 1982 | const addr = got.addr + got_index * @sizeOf(u64); |
| ... | @@ -2042,7 +2027,7 @@ fn writeStubHelperCommon(self: *MachO) !void { | ... | @@ -2042,7 +2027,7 @@ fn writeStubHelperCommon(self: *MachO) !void { |
| 2042 | }) orelse unreachable; | 2027 | }) orelse unreachable; |
| 2043 | const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; | 2028 | const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; |
| 2044 | const got_index = self.got_entries_map.get(.{ | 2029 | const got_index = self.got_entries_map.get(.{ |
| 2045 | .where = .import, | 2030 | .where = .undef, |
| 2046 | .where_index = resolv.where_index, | 2031 | .where_index = resolv.where_index, |
| 2047 | }) orelse unreachable; | 2032 | }) orelse unreachable; |
| 2048 | const this_addr = stub_helper.addr + 3 * @sizeOf(u32); | 2033 | const this_addr = stub_helper.addr + 3 * @sizeOf(u32); |
| ... | @@ -2106,7 +2091,12 @@ fn writeStubHelperCommon(self: *MachO) !void { | ... | @@ -2106,7 +2091,12 @@ fn writeStubHelperCommon(self: *MachO) !void { |
| 2106 | } | 2091 | } |
| 2107 | } | 2092 | } |
| 2108 | | 2093 | |
| 2109 | fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void { | 2094 | fn resolveSymbolsInObject( |
| | 2095 | self: *MachO, |
| | 2096 | object_id: u16, |
| | 2097 | tentatives: *std.ArrayList(u32), |
| | 2098 | unresolved: *std.ArrayList(u32), |
| | 2099 | ) !void { |
| 2110 | const object = &self.objects.items[object_id]; | 2100 | const object = &self.objects.items[object_id]; |
| 2111 | | 2101 | |
| 2112 | log.debug("resolving symbols in '{s}'", .{object.name}); | 2102 | log.debug("resolving symbols in '{s}'", .{object.name}); |
| ... | @@ -2174,7 +2164,6 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void { | ... | @@ -2174,7 +2164,6 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void { |
| 2174 | }; | 2164 | }; |
| 2175 | | 2165 | |
| 2176 | switch (resolv.where) { | 2166 | switch (resolv.where) { |
| 2177 | .import => unreachable, | | |
| 2178 | .global => { | 2167 | .global => { |
| 2179 | const global = &self.globals.items[resolv.where_index]; | 2168 | const global = &self.globals.items[resolv.where_index]; |
| 2180 | | 2169 | |
| ... | @@ -2186,8 +2175,16 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void { | ... | @@ -2186,8 +2175,16 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void { |
| 2186 | log.err(" next definition in '{s}'", .{object.name}); | 2175 | log.err(" next definition in '{s}'", .{object.name}); |
| 2187 | return error.MultipleSymbolDefinitions; | 2176 | return error.MultipleSymbolDefinitions; |
| 2188 | } | 2177 | } |
| 2189 | | | |
| 2190 | if (symbolIsWeakDef(sym) or symbolIsPext(sym)) continue; // Current symbol is weak, so skip it. | 2178 | if (symbolIsWeakDef(sym) or symbolIsPext(sym)) continue; // Current symbol is weak, so skip it. |
| | 2179 | if (symbolIsTentative(global.*)) { |
| | 2180 | var i: usize = 0; |
| | 2181 | while (i < tentatives.items.len) : (i += 1) { |
| | 2182 | if (tentatives.items[i] == resolv.where_index) { |
| | 2183 | _ = tentatives.swapRemove(i); |
| | 2184 | break; |
| | 2185 | } |
| | 2186 | } |
| | 2187 | } |
| 2191 | | 2188 | |
| 2192 | // Otherwise, update the resolver and the global symbol. | 2189 | // Otherwise, update the resolver and the global symbol. |
| 2193 | global.n_type = sym.n_type; | 2190 | global.n_type = sym.n_type; |
| ... | @@ -2205,16 +2202,14 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void { | ... | @@ -2205,16 +2202,14 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void { |
| 2205 | .n_desc = 0, | 2202 | .n_desc = 0, |
| 2206 | .n_value = 0, | 2203 | .n_value = 0, |
| 2207 | }; | 2204 | }; |
| 2208 | }, | 2205 | |
| 2209 | .tentative => { | 2206 | var i: usize = 0; |
| 2210 | const tentative = &self.tentatives.items[resolv.where_index]; | 2207 | while (i < unresolved.items.len) : (i += 1) { |
| 2211 | tentative.* = .{ | 2208 | if (unresolved.items[i] == resolv.where_index) { |
| 2212 | .n_strx = 0, | 2209 | _ = unresolved.swapRemove(i); |
| 2213 | .n_type = macho.N_UNDF, | 2210 | break; |
| 2214 | .n_sect = 0, | 2211 | } |
| 2215 | .n_desc = 0, | 2212 | } |
| 2216 | .n_value = 0, | | |
| 2217 | }; | | |
| 2218 | }, | 2213 | }, |
| 2219 | } | 2214 | } |
| 2220 | | 2215 | |
| ... | @@ -2235,8 +2230,8 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void { | ... | @@ -2235,8 +2230,8 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void { |
| 2235 | } else if (symbolIsTentative(sym)) { | 2230 | } else if (symbolIsTentative(sym)) { |
| 2236 | // Symbol is a tentative definition. | 2231 | // Symbol is a tentative definition. |
| 2237 | const resolv = self.symbol_resolver.getPtr(n_strx) orelse { | 2232 | const resolv = self.symbol_resolver.getPtr(n_strx) orelse { |
| 2238 | const tent_sym_index = @intCast(u32, self.tentatives.items.len); | 2233 | const global_sym_index = @intCast(u32, self.globals.items.len); |
| 2239 | try self.tentatives.append(self.base.allocator, .{ | 2234 | try self.globals.append(self.base.allocator, .{ |
| 2240 | .n_strx = try self.makeString(sym_name), | 2235 | .n_strx = try self.makeString(sym_name), |
| 2241 | .n_type = sym.n_type, | 2236 | .n_type = sym.n_type, |
| 2242 | .n_sect = 0, | 2237 | .n_sect = 0, |
| ... | @@ -2244,29 +2239,38 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void { | ... | @@ -2244,29 +2239,38 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void { |
| 2244 | .n_value = sym.n_value, | 2239 | .n_value = sym.n_value, |
| 2245 | }); | 2240 | }); |
| 2246 | try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{ | 2241 | try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{ |
| 2247 | .where = .tentative, | 2242 | .where = .global, |
| 2248 | .where_index = tent_sym_index, | 2243 | .where_index = global_sym_index, |
| 2249 | .file = object_id, | 2244 | .file = object_id, |
| 2250 | }); | 2245 | }); |
| | 2246 | try tentatives.append(global_sym_index); |
| 2251 | continue; | 2247 | continue; |
| 2252 | }; | 2248 | }; |
| 2253 | | 2249 | |
| 2254 | switch (resolv.where) { | 2250 | switch (resolv.where) { |
| 2255 | .import => unreachable, | 2251 | .global => { |
| 2256 | .global => {}, | 2252 | const global = &self.globals.items[resolv.where_index]; |
| | 2253 | if (!symbolIsTentative(global.*)) continue; |
| | 2254 | if (global.n_value >= sym.n_value) continue; |
| | 2255 | |
| | 2256 | global.n_desc = sym.n_desc; |
| | 2257 | global.n_value = sym.n_value; |
| | 2258 | resolv.file = object_id; |
| | 2259 | }, |
| 2257 | .undef => { | 2260 | .undef => { |
| 2258 | const undef = &self.undefs.items[resolv.where_index]; | 2261 | const undef = &self.undefs.items[resolv.where_index]; |
| 2259 | const tent_sym_index = @intCast(u32, self.tentatives.items.len); | 2262 | const global_sym_index = @intCast(u32, self.globals.items.len); |
| 2260 | try self.tentatives.append(self.base.allocator, .{ | 2263 | try self.globals.append(self.base.allocator, .{ |
| 2261 | .n_strx = undef.n_strx, | 2264 | .n_strx = undef.n_strx, |
| 2262 | .n_type = sym.n_type, | 2265 | .n_type = sym.n_type, |
| 2263 | .n_sect = 0, | 2266 | .n_sect = 0, |
| 2264 | .n_desc = sym.n_desc, | 2267 | .n_desc = sym.n_desc, |
| 2265 | .n_value = sym.n_value, | 2268 | .n_value = sym.n_value, |
| 2266 | }); | 2269 | }); |
| | 2270 | try tentatives.append(global_sym_index); |
| 2267 | resolv.* = .{ | 2271 | resolv.* = .{ |
| 2268 | .where = .tentative, | 2272 | .where = .global, |
| 2269 | .where_index = tent_sym_index, | 2273 | .where_index = global_sym_index, |
| 2270 | .file = object_id, | 2274 | .file = object_id, |
| 2271 | }; | 2275 | }; |
| 2272 | undef.* = .{ | 2276 | undef.* = .{ |
| ... | @@ -2276,14 +2280,13 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void { | ... | @@ -2276,14 +2280,13 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void { |
| 2276 | .n_desc = 0, | 2280 | .n_desc = 0, |
| 2277 | .n_value = 0, | 2281 | .n_value = 0, |
| 2278 | }; | 2282 | }; |
| 2279 | }, | 2283 | var i: usize = 0; |
| 2280 | .tentative => { | 2284 | while (i < unresolved.items.len) : (i += 1) { |
| 2281 | const tentative = &self.tentatives.items[resolv.where_index]; | 2285 | if (unresolved.items[i] == resolv.where_index) { |
| 2282 | if (tentative.n_value >= sym.n_value) continue; | 2286 | _ = unresolved.swapRemove(i); |
| 2283 | | 2287 | break; |
| 2284 | tentative.n_desc = sym.n_desc; | 2288 | } |
| 2285 | tentative.n_value = sym.n_value; | 2289 | } |
| 2286 | resolv.file = object_id; | | |
| 2287 | }, | 2290 | }, |
| 2288 | } | 2291 | } |
| 2289 | } else { | 2292 | } else { |
| ... | @@ -2303,24 +2306,27 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void { | ... | @@ -2303,24 +2306,27 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void { |
| 2303 | .where_index = undef_sym_index, | 2306 | .where_index = undef_sym_index, |
| 2304 | .file = object_id, | 2307 | .file = object_id, |
| 2305 | }); | 2308 | }); |
| | 2309 | try unresolved.append(undef_sym_index); |
| 2306 | } | 2310 | } |
| 2307 | } | 2311 | } |
| 2308 | } | 2312 | } |
| 2309 | | 2313 | |
| 2310 | fn resolveSymbols(self: *MachO) !void { | 2314 | fn resolveSymbols(self: *MachO) !void { |
| | 2315 | var tentatives = std.ArrayList(u32).init(self.base.allocator); |
| | 2316 | defer tentatives.deinit(); |
| | 2317 | |
| | 2318 | var unresolved = std.ArrayList(u32).init(self.base.allocator); |
| | 2319 | defer unresolved.deinit(); |
| | 2320 | |
| 2311 | // First pass, resolve symbols in provided objects. | 2321 | // First pass, resolve symbols in provided objects. |
| 2312 | for (self.objects.items) |_, object_id| { | 2322 | for (self.objects.items) |_, object_id| { |
| 2313 | try self.resolveSymbolsInObject(@intCast(u16, object_id)); | 2323 | try self.resolveSymbolsInObject(@intCast(u16, object_id), &tentatives, &unresolved); |
| 2314 | } | 2324 | } |
| 2315 | | 2325 | |
| 2316 | // Second pass, resolve symbols in static libraries. | 2326 | // Second pass, resolve symbols in static libraries. |
| 2317 | var next_sym: usize = 0; | 2327 | var next_sym: usize = 0; |
| 2318 | loop: while (true) : (next_sym += 1) { | 2328 | loop: while (next_sym < unresolved.items.len) { |
| 2319 | if (next_sym == self.undefs.items.len) break; | 2329 | const sym = self.undefs.items[unresolved.items[next_sym]]; |
| 2320 | | | |
| 2321 | const sym = self.undefs.items[next_sym]; | | |
| 2322 | if (symbolIsNull(sym)) continue; | | |
| 2323 | | | |
| 2324 | const sym_name = self.getString(sym.n_strx); | 2330 | const sym_name = self.getString(sym.n_strx); |
| 2325 | | 2331 | |
| 2326 | for (self.archives.items) |archive| { | 2332 | for (self.archives.items) |archive| { |
| ... | @@ -2334,17 +2340,18 @@ fn resolveSymbols(self: *MachO) !void { | ... | @@ -2334,17 +2340,18 @@ fn resolveSymbols(self: *MachO) !void { |
| 2334 | const object_id = @intCast(u16, self.objects.items.len); | 2340 | const object_id = @intCast(u16, self.objects.items.len); |
| 2335 | const object = try self.objects.addOne(self.base.allocator); | 2341 | const object = try self.objects.addOne(self.base.allocator); |
| 2336 | object.* = try archive.parseObject(self.base.allocator, self.base.options.target, offsets.items[0]); | 2342 | object.* = try archive.parseObject(self.base.allocator, self.base.options.target, offsets.items[0]); |
| 2337 | try self.resolveSymbolsInObject(object_id); | 2343 | try self.resolveSymbolsInObject(object_id, &tentatives, &unresolved); |
| 2338 | | 2344 | |
| 2339 | continue :loop; | 2345 | continue :loop; |
| 2340 | } | 2346 | } |
| | 2347 | |
| | 2348 | next_sym += 1; |
| 2341 | } | 2349 | } |
| 2342 | | 2350 | |
| 2343 | // Convert any tentative definition into a regular symbol and allocate | 2351 | // Convert any tentative definition into a regular symbol and allocate |
| 2344 | // text blocks for each tentative defintion. | 2352 | // text blocks for each tentative defintion. |
| 2345 | for (self.tentatives.items) |sym| { | 2353 | while (tentatives.popOrNull()) |index| { |
| 2346 | if (symbolIsNull(sym)) continue; | 2354 | const sym = &self.globals.items[index]; |
| 2347 | | | |
| 2348 | const match: MatchingSection = blk: { | 2355 | const match: MatchingSection = blk: { |
| 2349 | if (self.common_section_index == null) { | 2356 | if (self.common_section_index == null) { |
| 2350 | const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 2357 | const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| ... | @@ -2366,24 +2373,17 @@ fn resolveSymbols(self: *MachO) !void { | ... | @@ -2366,24 +2373,17 @@ fn resolveSymbols(self: *MachO) !void { |
| 2366 | mem.set(u8, code, 0); | 2373 | mem.set(u8, code, 0); |
| 2367 | const alignment = (sym.n_desc >> 8) & 0x0f; | 2374 | const alignment = (sym.n_desc >> 8) & 0x0f; |
| 2368 | | 2375 | |
| 2369 | const resolv = self.symbol_resolver.getPtr(sym.n_strx) orelse unreachable; | 2376 | sym.n_value = 0; |
| | 2377 | sym.n_desc = 0; |
| | 2378 | sym.n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1); |
| | 2379 | var local_sym = sym.*; |
| | 2380 | local_sym.n_type = macho.N_SECT; |
| | 2381 | |
| 2370 | const local_sym_index = @intCast(u32, self.locals.items.len); | 2382 | const local_sym_index = @intCast(u32, self.locals.items.len); |
| 2371 | var nlist = macho.nlist_64{ | 2383 | try self.locals.append(self.base.allocator, local_sym); |
| 2372 | .n_strx = sym.n_strx, | 2384 | |
| 2373 | .n_type = macho.N_SECT, | 2385 | const resolv = self.symbol_resolver.getPtr(sym.n_strx) orelse unreachable; |
| 2374 | .n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1), | 2386 | resolv.local_sym_index = local_sym_index; |
| 2375 | .n_desc = 0, | | |
| 2376 | .n_value = 0, | | |
| 2377 | }; | | |
| 2378 | try self.locals.append(self.base.allocator, nlist); | | |
| 2379 | const global_sym_index = @intCast(u32, self.globals.items.len); | | |
| 2380 | nlist.n_type |= macho.N_EXT; | | |
| 2381 | try self.globals.append(self.base.allocator, nlist); | | |
| 2382 | resolv.* = .{ | | |
| 2383 | .where = .global, | | |
| 2384 | .where_index = global_sym_index, | | |
| 2385 | .local_sym_index = local_sym_index, | | |
| 2386 | }; | | |
| 2387 | | 2387 | |
| 2388 | const block = try self.base.allocator.create(TextBlock); | 2388 | const block = try self.base.allocator.create(TextBlock); |
| 2389 | block.* = TextBlock.empty; | 2389 | block.* = TextBlock.empty; |
| ... | @@ -2430,13 +2430,15 @@ fn resolveSymbols(self: *MachO) !void { | ... | @@ -2430,13 +2430,15 @@ fn resolveSymbols(self: *MachO) !void { |
| 2430 | .where = .undef, | 2430 | .where = .undef, |
| 2431 | .where_index = undef_sym_index, | 2431 | .where_index = undef_sym_index, |
| 2432 | }); | 2432 | }); |
| | 2433 | try unresolved.append(undef_sym_index); |
| 2433 | } | 2434 | } |
| 2434 | | 2435 | |
| 2435 | loop: for (self.undefs.items) |sym| { | 2436 | next_sym = 0; |
| 2436 | if (symbolIsNull(sym)) continue; | 2437 | loop: while (next_sym < unresolved.items.len) { |
| 2437 | | 2438 | const sym = self.undefs.items[unresolved.items[next_sym]]; |
| 2438 | const sym_name = self.getString(sym.n_strx); | 2439 | const sym_name = self.getString(sym.n_strx); |
| 2439 | for (self.dylibs.items) |*dylib, id| { | 2440 | |
| | 2441 | for (self.dylibs.items) |dylib, id| { |
| 2440 | if (!dylib.symbols.contains(sym_name)) continue; | 2442 | if (!dylib.symbols.contains(sym_name)) continue; |
| 2441 | | 2443 | |
| 2442 | const dylib_id = @intCast(u16, id); | 2444 | const dylib_id = @intCast(u16, id); |
| ... | @@ -2447,28 +2449,15 @@ fn resolveSymbols(self: *MachO) !void { | ... | @@ -2447,28 +2449,15 @@ fn resolveSymbols(self: *MachO) !void { |
| 2447 | const ordinal = self.referenced_dylibs.getIndex(dylib_id) orelse unreachable; | 2449 | const ordinal = self.referenced_dylibs.getIndex(dylib_id) orelse unreachable; |
| 2448 | const resolv = self.symbol_resolver.getPtr(sym.n_strx) orelse unreachable; | 2450 | const resolv = self.symbol_resolver.getPtr(sym.n_strx) orelse unreachable; |
| 2449 | const undef = &self.undefs.items[resolv.where_index]; | 2451 | const undef = &self.undefs.items[resolv.where_index]; |
| 2450 | const import_sym_index = @intCast(u32, self.imports.items.len); | 2452 | undef.n_type |= macho.N_EXT; |
| 2451 | try self.imports.append(self.base.allocator, .{ | 2453 | undef.n_desc = @intCast(u16, ordinal + 1) * macho.N_SYMBOL_RESOLVER; |
| 2452 | .n_strx = undef.n_strx, | 2454 | |
| 2453 | .n_type = macho.N_UNDF | macho.N_EXT, | 2455 | _ = unresolved.swapRemove(next_sym); |
| 2454 | .n_sect = 0, | | |
| 2455 | .n_desc = @intCast(u16, ordinal + 1) * macho.N_SYMBOL_RESOLVER, | | |
| 2456 | .n_value = 0, | | |
| 2457 | }); | | |
| 2458 | resolv.* = .{ | | |
| 2459 | .where = .import, | | |
| 2460 | .where_index = import_sym_index, | | |
| 2461 | }; | | |
| 2462 | undef.* = .{ | | |
| 2463 | .n_strx = 0, | | |
| 2464 | .n_type = macho.N_UNDF, | | |
| 2465 | .n_sect = 0, | | |
| 2466 | .n_desc = 0, | | |
| 2467 | .n_value = 0, | | |
| 2468 | }; | | |
| 2469 | | 2456 | |
| 2470 | continue :loop; | 2457 | continue :loop; |
| 2471 | } | 2458 | } |
| | 2459 | |
| | 2460 | next_sym += 1; |
| 2472 | } | 2461 | } |
| 2473 | | 2462 | |
| 2474 | // Fourth pass, handle synthetic symbols and flag any undefined references. | 2463 | // Fourth pass, handle synthetic symbols and flag any undefined references. |
| ... | @@ -2497,6 +2486,14 @@ fn resolveSymbols(self: *MachO) !void { | ... | @@ -2497,6 +2486,14 @@ fn resolveSymbols(self: *MachO) !void { |
| 2497 | nlist.n_desc = macho.N_WEAK_DEF; | 2486 | nlist.n_desc = macho.N_WEAK_DEF; |
| 2498 | try self.globals.append(self.base.allocator, nlist); | 2487 | try self.globals.append(self.base.allocator, nlist); |
| 2499 | | 2488 | |
| | 2489 | var i: usize = 0; |
| | 2490 | while (i < unresolved.items.len) : (i += 1) { |
| | 2491 | if (unresolved.items[i] == resolv.where_index) { |
| | 2492 | _ = unresolved.swapRemove(i); |
| | 2493 | break; |
| | 2494 | } |
| | 2495 | } |
| | 2496 | |
| 2500 | undef.* = .{ | 2497 | undef.* = .{ |
| 2501 | .n_strx = 0, | 2498 | .n_strx = 0, |
| 2502 | .n_type = macho.N_UNDF, | 2499 | .n_type = macho.N_UNDF, |
| ... | @@ -2529,19 +2526,17 @@ fn resolveSymbols(self: *MachO) !void { | ... | @@ -2529,19 +2526,17 @@ fn resolveSymbols(self: *MachO) !void { |
| 2529 | } | 2526 | } |
| 2530 | } | 2527 | } |
| 2531 | | 2528 | |
| 2532 | var has_undefined = false; | 2529 | for (unresolved.items) |index| { |
| 2533 | for (self.undefs.items) |sym| { | 2530 | const sym = self.undefs.items[index]; |
| 2534 | if (symbolIsNull(sym)) continue; | | |
| 2535 | | | |
| 2536 | const sym_name = self.getString(sym.n_strx); | 2531 | const sym_name = self.getString(sym.n_strx); |
| 2537 | const resolv = self.symbol_resolver.get(sym.n_strx) orelse unreachable; | 2532 | const resolv = self.symbol_resolver.get(sym.n_strx) orelse unreachable; |
| 2538 | | 2533 | |
| 2539 | log.err("undefined reference to symbol '{s}'", .{sym_name}); | 2534 | log.err("undefined reference to symbol '{s}'", .{sym_name}); |
| 2540 | log.err(" first referenced in '{s}'", .{self.objects.items[resolv.file].name}); | 2535 | log.err(" first referenced in '{s}'", .{self.objects.items[resolv.file].name}); |
| 2541 | has_undefined = true; | | |
| 2542 | } | 2536 | } |
| 2543 | | 2537 | |
| 2544 | if (has_undefined) return error.UndefinedSymbolReference; | 2538 | if (unresolved.items.len > 0) |
| | 2539 | return error.UndefinedSymbolReference; |
| 2545 | } | 2540 | } |
| 2546 | | 2541 | |
| 2547 | fn parseTextBlocks(self: *MachO) !void { | 2542 | fn parseTextBlocks(self: *MachO) !void { |
| ... | @@ -3006,7 +3001,7 @@ fn writeGotEntries(self: *MachO) !void { | ... | @@ -3006,7 +3001,7 @@ fn writeGotEntries(self: *MachO) !void { |
| 3006 | for (self.got_entries.items) |key| { | 3001 | for (self.got_entries.items) |key| { |
| 3007 | const address: u64 = switch (key.where) { | 3002 | const address: u64 = switch (key.where) { |
| 3008 | .local => self.locals.items[key.where_index].n_value, | 3003 | .local => self.locals.items[key.where_index].n_value, |
| 3009 | .import => 0, | 3004 | .undef => 0, |
| 3010 | }; | 3005 | }; |
| 3011 | try writer.writeIntLittle(u64, address); | 3006 | try writer.writeIntLittle(u64, address); |
| 3012 | } | 3007 | } |
| ... | @@ -3075,7 +3070,7 @@ fn writeRebaseInfoTableZld(self: *MachO) !void { | ... | @@ -3075,7 +3070,7 @@ fn writeRebaseInfoTableZld(self: *MachO) !void { |
| 3075 | const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?); | 3070 | const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?); |
| 3076 | | 3071 | |
| 3077 | for (self.got_entries.items) |entry, i| { | 3072 | for (self.got_entries.items) |entry, i| { |
| 3078 | if (entry.where == .import) continue; | 3073 | if (entry.where == .undef) continue; |
| 3079 | | 3074 | |
| 3080 | try pointers.append(.{ | 3075 | try pointers.append(.{ |
| 3081 | .offset = base_offset + i * @sizeOf(u64), | 3076 | .offset = base_offset + i * @sizeOf(u64), |
| ... | @@ -3132,7 +3127,7 @@ fn writeBindInfoTableZld(self: *MachO) !void { | ... | @@ -3132,7 +3127,7 @@ fn writeBindInfoTableZld(self: *MachO) !void { |
| 3132 | for (self.got_entries.items) |entry, i| { | 3127 | for (self.got_entries.items) |entry, i| { |
| 3133 | if (entry.where == .local) continue; | 3128 | if (entry.where == .local) continue; |
| 3134 | | 3129 | |
| 3135 | const sym = self.imports.items[entry.where_index]; | 3130 | const sym = self.undefs.items[entry.where_index]; |
| 3136 | try pointers.append(.{ | 3131 | try pointers.append(.{ |
| 3137 | .offset = base_offset + i * @sizeOf(u64), | 3132 | .offset = base_offset + i * @sizeOf(u64), |
| 3138 | .segment_id = segment_id, | 3133 | .segment_id = segment_id, |
| ... | @@ -3157,7 +3152,7 @@ fn writeBindInfoTableZld(self: *MachO) !void { | ... | @@ -3157,7 +3152,7 @@ fn writeBindInfoTableZld(self: *MachO) !void { |
| 3157 | const base_offset = sym.n_value - seg.inner.vmaddr; | 3152 | const base_offset = sym.n_value - seg.inner.vmaddr; |
| 3158 | | 3153 | |
| 3159 | for (block.bindings.items) |binding| { | 3154 | for (block.bindings.items) |binding| { |
| 3160 | const bind_sym = self.imports.items[binding.local_sym_index]; | 3155 | const bind_sym = self.undefs.items[binding.local_sym_index]; |
| 3161 | try pointers.append(.{ | 3156 | try pointers.append(.{ |
| 3162 | .offset = binding.offset + base_offset, | 3157 | .offset = binding.offset + base_offset, |
| 3163 | .segment_id = match.seg, | 3158 | .segment_id = match.seg, |
| ... | @@ -3204,7 +3199,7 @@ fn writeLazyBindInfoTableZld(self: *MachO) !void { | ... | @@ -3204,7 +3199,7 @@ fn writeLazyBindInfoTableZld(self: *MachO) !void { |
| 3204 | try pointers.ensureUnusedCapacity(self.stubs.items.len); | 3199 | try pointers.ensureUnusedCapacity(self.stubs.items.len); |
| 3205 | | 3200 | |
| 3206 | for (self.stubs.items) |import_id, i| { | 3201 | for (self.stubs.items) |import_id, i| { |
| 3207 | const sym = self.imports.items[import_id]; | 3202 | const sym = self.undefs.items[import_id]; |
| 3208 | pointers.appendAssumeCapacity(.{ | 3203 | pointers.appendAssumeCapacity(.{ |
| 3209 | .offset = base_offset + i * @sizeOf(u64), | 3204 | .offset = base_offset + i * @sizeOf(u64), |
| 3210 | .segment_id = segment_id, | 3205 | .segment_id = segment_id, |
| ... | @@ -3338,7 +3333,7 @@ fn writeSymbolTable(self: *MachO) !void { | ... | @@ -3338,7 +3333,7 @@ fn writeSymbolTable(self: *MachO) !void { |
| 3338 | | 3333 | |
| 3339 | const nlocals = locals.items.len; | 3334 | const nlocals = locals.items.len; |
| 3340 | const nexports = self.globals.items.len; | 3335 | const nexports = self.globals.items.len; |
| 3341 | const nundefs = self.imports.items.len; | 3336 | const nundefs = self.undefs.items.len; |
| 3342 | | 3337 | |
| 3343 | const locals_off = symtab.symoff + symtab.nsyms * @sizeOf(macho.nlist_64); | 3338 | const locals_off = symtab.symoff + symtab.nsyms * @sizeOf(macho.nlist_64); |
| 3344 | const locals_size = nlocals * @sizeOf(macho.nlist_64); | 3339 | const locals_size = nlocals * @sizeOf(macho.nlist_64); |
| ... | @@ -3353,7 +3348,7 @@ fn writeSymbolTable(self: *MachO) !void { | ... | @@ -3353,7 +3348,7 @@ fn writeSymbolTable(self: *MachO) !void { |
| 3353 | const undefs_off = exports_off + exports_size; | 3348 | const undefs_off = exports_off + exports_size; |
| 3354 | const undefs_size = nundefs * @sizeOf(macho.nlist_64); | 3349 | const undefs_size = nundefs * @sizeOf(macho.nlist_64); |
| 3355 | log.debug("writing undefined symbols from 0x{x} to 0x{x}", .{ undefs_off, undefs_size + undefs_off }); | 3350 | log.debug("writing undefined symbols from 0x{x} to 0x{x}", .{ undefs_off, undefs_size + undefs_off }); |
| 3356 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.imports.items), undefs_off); | 3351 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.undefs.items), undefs_off); |
| 3357 | | 3352 | |
| 3358 | symtab.nsyms += @intCast(u32, nlocals + nexports + nundefs); | 3353 | symtab.nsyms += @intCast(u32, nlocals + nexports + nundefs); |
| 3359 | seg.inner.filesize += locals_size + exports_size + undefs_size; | 3354 | seg.inner.filesize += locals_size + exports_size + undefs_size; |
| ... | @@ -3401,7 +3396,7 @@ fn writeSymbolTable(self: *MachO) !void { | ... | @@ -3401,7 +3396,7 @@ fn writeSymbolTable(self: *MachO) !void { |
| 3401 | got.reserved1 = nstubs; | 3396 | got.reserved1 = nstubs; |
| 3402 | for (self.got_entries.items) |entry| { | 3397 | for (self.got_entries.items) |entry| { |
| 3403 | switch (entry.where) { | 3398 | switch (entry.where) { |
| 3404 | .import => { | 3399 | .undef => { |
| 3405 | try writer.writeIntLittle(u32, dysymtab.iundefsym + entry.where_index); | 3400 | try writer.writeIntLittle(u32, dysymtab.iundefsym + entry.where_index); |
| 3406 | }, | 3401 | }, |
| 3407 | .local => { | 3402 | .local => { |
| ... | @@ -3437,8 +3432,6 @@ pub fn deinit(self: *MachO) void { | ... | @@ -3437,8 +3432,6 @@ pub fn deinit(self: *MachO) void { |
| 3437 | self.strtab_dir.deinit(self.base.allocator); | 3432 | self.strtab_dir.deinit(self.base.allocator); |
| 3438 | self.strtab.deinit(self.base.allocator); | 3433 | self.strtab.deinit(self.base.allocator); |
| 3439 | self.undefs.deinit(self.base.allocator); | 3434 | self.undefs.deinit(self.base.allocator); |
| 3440 | self.tentatives.deinit(self.base.allocator); | | |
| 3441 | self.imports.deinit(self.base.allocator); | | |
| 3442 | self.globals.deinit(self.base.allocator); | 3435 | self.globals.deinit(self.base.allocator); |
| 3443 | self.globals_free_list.deinit(self.base.allocator); | 3436 | self.globals_free_list.deinit(self.base.allocator); |
| 3444 | self.locals.deinit(self.base.allocator); | 3437 | self.locals.deinit(self.base.allocator); |
| ... | @@ -4517,9 +4510,9 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4517,9 +4510,9 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4517 | if (!self.strtab_dir.containsAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{ | 4510 | if (!self.strtab_dir.containsAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{ |
| 4518 | .strtab = &self.strtab, | 4511 | .strtab = &self.strtab, |
| 4519 | })) { | 4512 | })) { |
| 4520 | const import_sym_index = @intCast(u32, self.imports.items.len); | 4513 | const import_sym_index = @intCast(u32, self.undefs.items.len); |
| 4521 | const n_strx = try self.makeString("dyld_stub_binder"); | 4514 | const n_strx = try self.makeString("dyld_stub_binder"); |
| 4522 | try self.imports.append(self.base.allocator, .{ | 4515 | try self.undefs.append(self.base.allocator, .{ |
| 4523 | .n_strx = n_strx, | 4516 | .n_strx = n_strx, |
| 4524 | .n_type = macho.N_UNDF | macho.N_EXT, | 4517 | .n_type = macho.N_UNDF | macho.N_EXT, |
| 4525 | .n_sect = 0, | 4518 | .n_sect = 0, |
| ... | @@ -4527,11 +4520,11 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4527,11 +4520,11 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4527 | .n_value = 0, | 4520 | .n_value = 0, |
| 4528 | }); | 4521 | }); |
| 4529 | try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{ | 4522 | try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{ |
| 4530 | .where = .import, | 4523 | .where = .undef, |
| 4531 | .where_index = import_sym_index, | 4524 | .where_index = import_sym_index, |
| 4532 | }); | 4525 | }); |
| 4533 | const got_key = GotIndirectionKey{ | 4526 | const got_key = GotIndirectionKey{ |
| 4534 | .where = .import, | 4527 | .where = .undef, |
| 4535 | .where_index = import_sym_index, | 4528 | .where_index = import_sym_index, |
| 4536 | }; | 4529 | }; |
| 4537 | const got_index = @intCast(u32, self.got_entries.items.len); | 4530 | const got_index = @intCast(u32, self.got_entries.items.len); |
| ... | @@ -4663,9 +4656,9 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 { | ... | @@ -4663,9 +4656,9 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 { |
| 4663 | } | 4656 | } |
| 4664 | | 4657 | |
| 4665 | log.debug("adding new extern function '{s}' with dylib ordinal 1", .{sym_name}); | 4658 | log.debug("adding new extern function '{s}' with dylib ordinal 1", .{sym_name}); |
| 4666 | const import_sym_index = @intCast(u32, self.imports.items.len); | 4659 | const import_sym_index = @intCast(u32, self.undefs.items.len); |
| 4667 | const n_strx = try self.makeString(sym_name); | 4660 | const n_strx = try self.makeString(sym_name); |
| 4668 | try self.imports.append(self.base.allocator, .{ | 4661 | try self.undefs.append(self.base.allocator, .{ |
| 4669 | .n_strx = n_strx, | 4662 | .n_strx = n_strx, |
| 4670 | .n_type = macho.N_UNDF | macho.N_EXT, | 4663 | .n_type = macho.N_UNDF | macho.N_EXT, |
| 4671 | .n_sect = 0, | 4664 | .n_sect = 0, |
| ... | @@ -4673,7 +4666,7 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 { | ... | @@ -4673,7 +4666,7 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 { |
| 4673 | .n_value = 0, | 4666 | .n_value = 0, |
| 4674 | }); | 4667 | }); |
| 4675 | try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{ | 4668 | try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{ |
| 4676 | .where = .import, | 4669 | .where = .undef, |
| 4677 | .where_index = import_sym_index, | 4670 | .where_index = import_sym_index, |
| 4678 | }); | 4671 | }); |
| 4679 | | 4672 | |
| ... | @@ -4856,7 +4849,7 @@ fn writeGotEntry(self: *MachO, index: usize) !void { | ... | @@ -4856,7 +4849,7 @@ fn writeGotEntry(self: *MachO, index: usize) !void { |
| 4856 | const got_entry = self.got_entries.items[index]; | 4849 | const got_entry = self.got_entries.items[index]; |
| 4857 | const sym = switch (got_entry.where) { | 4850 | const sym = switch (got_entry.where) { |
| 4858 | .local => self.locals.items[got_entry.where_index], | 4851 | .local => self.locals.items[got_entry.where_index], |
| 4859 | .import => self.imports.items[got_entry.where_index], | 4852 | .undef => self.undefs.items[got_entry.where_index], |
| 4860 | }; | 4853 | }; |
| 4861 | log.debug("writing offset table entry [ 0x{x} => 0x{x} ({s}) ]", .{ | 4854 | log.debug("writing offset table entry [ 0x{x} => 0x{x} ({s}) ]", .{ |
| 4862 | off, | 4855 | off, |
| ... | @@ -5140,7 +5133,7 @@ fn relocateSymbolTable(self: *MachO) !void { | ... | @@ -5140,7 +5133,7 @@ fn relocateSymbolTable(self: *MachO) !void { |
| 5140 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; | 5133 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; |
| 5141 | const nlocals = self.locals.items.len; | 5134 | const nlocals = self.locals.items.len; |
| 5142 | const nglobals = self.globals.items.len; | 5135 | const nglobals = self.globals.items.len; |
| 5143 | const nundefs = self.imports.items.len; | 5136 | const nundefs = self.undefs.items.len; |
| 5144 | const nsyms = nlocals + nglobals + nundefs; | 5137 | const nsyms = nlocals + nglobals + nundefs; |
| 5145 | | 5138 | |
| 5146 | if (symtab.nsyms < nsyms) { | 5139 | if (symtab.nsyms < nsyms) { |
| ... | @@ -5185,7 +5178,7 @@ fn writeAllGlobalAndUndefSymbols(self: *MachO) !void { | ... | @@ -5185,7 +5178,7 @@ fn writeAllGlobalAndUndefSymbols(self: *MachO) !void { |
| 5185 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; | 5178 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; |
| 5186 | const nlocals = self.locals.items.len; | 5179 | const nlocals = self.locals.items.len; |
| 5187 | const nglobals = self.globals.items.len; | 5180 | const nglobals = self.globals.items.len; |
| 5188 | const nundefs = self.imports.items.len; | 5181 | const nundefs = self.undefs.items.len; |
| 5189 | | 5182 | |
| 5190 | const locals_off = symtab.symoff; | 5183 | const locals_off = symtab.symoff; |
| 5191 | const locals_size = nlocals * @sizeOf(macho.nlist_64); | 5184 | const locals_size = nlocals * @sizeOf(macho.nlist_64); |
| ... | @@ -5198,7 +5191,7 @@ fn writeAllGlobalAndUndefSymbols(self: *MachO) !void { | ... | @@ -5198,7 +5191,7 @@ fn writeAllGlobalAndUndefSymbols(self: *MachO) !void { |
| 5198 | const undefs_off = globals_off + globals_size; | 5191 | const undefs_off = globals_off + globals_size; |
| 5199 | const undefs_size = nundefs * @sizeOf(macho.nlist_64); | 5192 | const undefs_size = nundefs * @sizeOf(macho.nlist_64); |
| 5200 | log.debug("writing extern symbols from 0x{x} to 0x{x}", .{ undefs_off, undefs_size + undefs_off }); | 5193 | log.debug("writing extern symbols from 0x{x} to 0x{x}", .{ undefs_off, undefs_size + undefs_off }); |
| 5201 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.imports.items), undefs_off); | 5194 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.undefs.items), undefs_off); |
| 5202 | | 5195 | |
| 5203 | // Update dynamic symbol table. | 5196 | // Update dynamic symbol table. |
| 5204 | const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab; | 5197 | const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab; |
| ... | @@ -5253,7 +5246,7 @@ fn writeIndirectSymbolTable(self: *MachO) !void { | ... | @@ -5253,7 +5246,7 @@ fn writeIndirectSymbolTable(self: *MachO) !void { |
| 5253 | got.reserved1 = nstubs; | 5246 | got.reserved1 = nstubs; |
| 5254 | for (self.got_entries.items) |entry| { | 5247 | for (self.got_entries.items) |entry| { |
| 5255 | switch (entry.where) { | 5248 | switch (entry.where) { |
| 5256 | .import => { | 5249 | .undef => { |
| 5257 | try writer.writeIntLittle(u32, dysymtab.iundefsym + entry.where_index); | 5250 | try writer.writeIntLittle(u32, dysymtab.iundefsym + entry.where_index); |
| 5258 | }, | 5251 | }, |
| 5259 | .local => { | 5252 | .local => { |
| ... | @@ -5478,7 +5471,7 @@ fn writeRebaseInfoTable(self: *MachO) !void { | ... | @@ -5478,7 +5471,7 @@ fn writeRebaseInfoTable(self: *MachO) !void { |
| 5478 | const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?); | 5471 | const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?); |
| 5479 | | 5472 | |
| 5480 | for (self.got_entries.items) |entry, i| { | 5473 | for (self.got_entries.items) |entry, i| { |
| 5481 | if (entry.where == .import) continue; | 5474 | if (entry.where == .undef) continue; |
| 5482 | | 5475 | |
| 5483 | try pointers.append(.{ | 5476 | try pointers.append(.{ |
| 5484 | .offset = base_offset + i * @sizeOf(u64), | 5477 | .offset = base_offset + i * @sizeOf(u64), |
| ... | @@ -5547,7 +5540,7 @@ fn writeBindInfoTable(self: *MachO) !void { | ... | @@ -5547,7 +5540,7 @@ fn writeBindInfoTable(self: *MachO) !void { |
| 5547 | for (self.got_entries.items) |entry, i| { | 5540 | for (self.got_entries.items) |entry, i| { |
| 5548 | if (entry.where == .local) continue; | 5541 | if (entry.where == .local) continue; |
| 5549 | | 5542 | |
| 5550 | const sym = self.imports.items[entry.where_index]; | 5543 | const sym = self.undefs.items[entry.where_index]; |
| 5551 | try pointers.append(.{ | 5544 | try pointers.append(.{ |
| 5552 | .offset = base_offset + i * @sizeOf(u64), | 5545 | .offset = base_offset + i * @sizeOf(u64), |
| 5553 | .segment_id = segment_id, | 5546 | .segment_id = segment_id, |
| ... | @@ -5572,7 +5565,7 @@ fn writeBindInfoTable(self: *MachO) !void { | ... | @@ -5572,7 +5565,7 @@ fn writeBindInfoTable(self: *MachO) !void { |
| 5572 | const base_offset = sym.n_value - seg.inner.vmaddr; | 5565 | const base_offset = sym.n_value - seg.inner.vmaddr; |
| 5573 | | 5566 | |
| 5574 | for (block.bindings.items) |binding| { | 5567 | for (block.bindings.items) |binding| { |
| 5575 | const bind_sym = self.imports.items[binding.local_sym_index]; | 5568 | const bind_sym = self.undefs.items[binding.local_sym_index]; |
| 5576 | try pointers.append(.{ | 5569 | try pointers.append(.{ |
| 5577 | .offset = binding.offset + base_offset, | 5570 | .offset = binding.offset + base_offset, |
| 5578 | .segment_id = match.seg, | 5571 | .segment_id = match.seg, |
| ... | @@ -5631,7 +5624,7 @@ fn writeLazyBindInfoTable(self: *MachO) !void { | ... | @@ -5631,7 +5624,7 @@ fn writeLazyBindInfoTable(self: *MachO) !void { |
| 5631 | try pointers.ensureUnusedCapacity(self.stubs.items.len); | 5624 | try pointers.ensureUnusedCapacity(self.stubs.items.len); |
| 5632 | | 5625 | |
| 5633 | for (self.stubs.items) |import_id, i| { | 5626 | for (self.stubs.items) |import_id, i| { |
| 5634 | const sym = self.imports.items[import_id]; | 5627 | const sym = self.undefs.items[import_id]; |
| 5635 | pointers.appendAssumeCapacity(.{ | 5628 | pointers.appendAssumeCapacity(.{ |
| 5636 | .offset = base_offset + i * @sizeOf(u64), | 5629 | .offset = base_offset + i * @sizeOf(u64), |
| 5637 | .segment_id = segment_id, | 5630 | .segment_id = segment_id, |
| ... | @@ -5967,10 +5960,6 @@ pub fn symbolIsTentative(sym: macho.nlist_64) bool { | ... | @@ -5967,10 +5960,6 @@ pub fn symbolIsTentative(sym: macho.nlist_64) bool { |
| 5967 | return sym.n_value != 0; | 5960 | return sym.n_value != 0; |
| 5968 | } | 5961 | } |
| 5969 | | 5962 | |
| 5970 | pub fn symbolIsNull(sym: macho.nlist_64) bool { | | |
| 5971 | return sym.n_value == 0 and sym.n_desc == 0 and sym.n_type == 0 and sym.n_strx == 0 and sym.n_sect == 0; | | |
| 5972 | } | | |
| 5973 | | | |
| 5974 | pub fn symbolIsTemp(sym: macho.nlist_64, sym_name: []const u8) bool { | 5963 | pub fn symbolIsTemp(sym: macho.nlist_64, sym_name: []const u8) bool { |
| 5975 | if (!symbolIsSect(sym)) return false; | 5964 | if (!symbolIsSect(sym)) return false; |
| 5976 | if (symbolIsExt(sym)) return false; | 5965 | if (symbolIsExt(sym)) return false; |