| ... | @@ -16,8 +16,8 @@ const Allocator = mem.Allocator; | ... | @@ -16,8 +16,8 @@ const Allocator = mem.Allocator; |
| 16 | const Archive = @import("Archive.zig"); | 16 | const Archive = @import("Archive.zig"); |
| 17 | const CodeSignature = @import("CodeSignature.zig"); | 17 | const CodeSignature = @import("CodeSignature.zig"); |
| 18 | const Dylib = @import("Dylib.zig"); | 18 | const Dylib = @import("Dylib.zig"); |
| | 19 | const LibStub = @import("../tapi.zig").LibStub; |
| 19 | const Object = @import("Object.zig"); | 20 | const Object = @import("Object.zig"); |
| 20 | const Stub = @import("Stub.zig"); | | |
| 21 | const Symbol = @import("Symbol.zig"); | 21 | const Symbol = @import("Symbol.zig"); |
| 22 | const Trie = @import("Trie.zig"); | 22 | const Trie = @import("Trie.zig"); |
| 23 | | 23 | |
| ... | @@ -38,9 +38,8 @@ stack_size: u64 = 0, | ... | @@ -38,9 +38,8 @@ stack_size: u64 = 0, |
| 38 | objects: std.ArrayListUnmanaged(*Object) = .{}, | 38 | objects: std.ArrayListUnmanaged(*Object) = .{}, |
| 39 | archives: std.ArrayListUnmanaged(*Archive) = .{}, | 39 | archives: std.ArrayListUnmanaged(*Archive) = .{}, |
| 40 | dylibs: std.ArrayListUnmanaged(*Dylib) = .{}, | 40 | dylibs: std.ArrayListUnmanaged(*Dylib) = .{}, |
| 41 | lib_stubs: std.ArrayListUnmanaged(*Stub) = .{}, | | |
| 42 | | 41 | |
| 43 | libsystem_stub_index: ?u16 = null, | 42 | libsystem_dylib_index: ?u16 = null, |
| 44 | next_dylib_ordinal: u16 = 1, | 43 | next_dylib_ordinal: u16 = 1, |
| 45 | | 44 | |
| 46 | load_commands: std.ArrayListUnmanaged(LoadCommand) = .{}, | 45 | load_commands: std.ArrayListUnmanaged(LoadCommand) = .{}, |
| ... | @@ -134,10 +133,6 @@ const TlvOffset = struct { | ... | @@ -134,10 +133,6 @@ const TlvOffset = struct { |
| 134 | /// Default path to dyld | 133 | /// Default path to dyld |
| 135 | const DEFAULT_DYLD_PATH: [*:0]const u8 = "/usr/lib/dyld"; | 134 | const DEFAULT_DYLD_PATH: [*:0]const u8 = "/usr/lib/dyld"; |
| 136 | | 135 | |
| 137 | const LIB_SYSTEM_NAME: [*:0]const u8 = "System"; | | |
| 138 | /// TODO this should be inferred from included libSystem.tbd or similar. | | |
| 139 | const LIB_SYSTEM_PATH: [*:0]const u8 = "/usr/lib/libSystem.B.dylib"; | | |
| 140 | | | |
| 141 | pub fn init(allocator: *Allocator) Zld { | 136 | pub fn init(allocator: *Allocator) Zld { |
| 142 | return .{ .allocator = allocator }; | 137 | return .{ .allocator = allocator }; |
| 143 | } | 138 | } |
| ... | @@ -171,12 +166,6 @@ pub fn deinit(self: *Zld) void { | ... | @@ -171,12 +166,6 @@ pub fn deinit(self: *Zld) void { |
| 171 | } | 166 | } |
| 172 | self.dylibs.deinit(self.allocator); | 167 | self.dylibs.deinit(self.allocator); |
| 173 | | 168 | |
| 174 | for (self.lib_stubs.items) |stub| { | | |
| 175 | stub.deinit(); | | |
| 176 | self.allocator.destroy(stub); | | |
| 177 | } | | |
| 178 | self.lib_stubs.deinit(self.allocator); | | |
| 179 | | | |
| 180 | for (self.imports.values()) |proxy| { | 169 | for (self.imports.values()) |proxy| { |
| 181 | proxy.deinit(self.allocator); | 170 | proxy.deinit(self.allocator); |
| 182 | self.allocator.destroy(proxy); | 171 | self.allocator.destroy(proxy); |
| ... | @@ -269,20 +258,30 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8, args: L | ... | @@ -269,20 +258,30 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8, args: L |
| 269 | | 258 | |
| 270 | fn parseInputFiles(self: *Zld, files: []const []const u8) !void { | 259 | fn parseInputFiles(self: *Zld, files: []const []const u8) !void { |
| 271 | const Input = struct { | 260 | const Input = struct { |
| 272 | kind: enum { | 261 | kind: union(enum) { |
| 273 | object, | 262 | object: fs.File, |
| 274 | archive, | 263 | archive: fs.File, |
| 275 | dylib, | 264 | dylib: fs.File, |
| 276 | stub, | 265 | stub: LibStub, |
| 277 | }, | | |
| 278 | origin: union { | | |
| 279 | file: fs.File, | | |
| 280 | stub: Stub.LibStub, | | |
| 281 | }, | 266 | }, |
| 282 | name: []const u8, | 267 | name: []const u8, |
| | 268 | |
| | 269 | fn deinit(input: *@This()) void { |
| | 270 | switch (input.kind) { |
| | 271 | .stub => |*stub| { |
| | 272 | stub.deinit(); |
| | 273 | }, |
| | 274 | else => {}, |
| | 275 | } |
| | 276 | } |
| 283 | }; | 277 | }; |
| 284 | var classified = std.ArrayList(Input).init(self.allocator); | 278 | var classified = std.ArrayList(Input).init(self.allocator); |
| 285 | defer classified.deinit(); | 279 | defer { |
| | 280 | for (classified.items) |*input| { |
| | 281 | input.deinit(); |
| | 282 | } |
| | 283 | classified.deinit(); |
| | 284 | } |
| 286 | | 285 | |
| 287 | // First, classify input files: object, archive, dylib or stub (tbd). | 286 | // First, classify input files: object, archive, dylib or stub (tbd). |
| 288 | for (files) |file_name| { | 287 | for (files) |file_name| { |
| ... | @@ -296,8 +295,7 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void { | ... | @@ -296,8 +295,7 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void { |
| 296 | try_object: { | 295 | try_object: { |
| 297 | if (!(try Object.isObject(file))) break :try_object; | 296 | if (!(try Object.isObject(file))) break :try_object; |
| 298 | try classified.append(.{ | 297 | try classified.append(.{ |
| 299 | .kind = .object, | 298 | .kind = .{ .object = file }, |
| 300 | .origin = .{ .file = file }, | | |
| 301 | .name = full_path, | 299 | .name = full_path, |
| 302 | }); | 300 | }); |
| 303 | continue; | 301 | continue; |
| ... | @@ -306,8 +304,7 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void { | ... | @@ -306,8 +304,7 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void { |
| 306 | try_archive: { | 304 | try_archive: { |
| 307 | if (!(try Archive.isArchive(file))) break :try_archive; | 305 | if (!(try Archive.isArchive(file))) break :try_archive; |
| 308 | try classified.append(.{ | 306 | try classified.append(.{ |
| 309 | .kind = .archive, | 307 | .kind = .{ .archive = file }, |
| 310 | .origin = .{ .file = file }, | | |
| 311 | .name = full_path, | 308 | .name = full_path, |
| 312 | }); | 309 | }); |
| 313 | continue; | 310 | continue; |
| ... | @@ -316,20 +313,18 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void { | ... | @@ -316,20 +313,18 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void { |
| 316 | try_dylib: { | 313 | try_dylib: { |
| 317 | if (!(try Dylib.isDylib(file))) break :try_dylib; | 314 | if (!(try Dylib.isDylib(file))) break :try_dylib; |
| 318 | try classified.append(.{ | 315 | try classified.append(.{ |
| 319 | .kind = .dylib, | 316 | .kind = .{ .dylib = file }, |
| 320 | .origin = .{ .file = file }, | | |
| 321 | .name = full_path, | 317 | .name = full_path, |
| 322 | }); | 318 | }); |
| 323 | continue; | 319 | continue; |
| 324 | } | 320 | } |
| 325 | | 321 | |
| 326 | try_stub: { | 322 | try_stub: { |
| 327 | var lib_stub = Stub.LibStub.loadFromFile(self.allocator, file) catch { | 323 | var lib_stub = LibStub.loadFromFile(self.allocator, file) catch { |
| 328 | break :try_stub; | 324 | break :try_stub; |
| 329 | }; | 325 | }; |
| 330 | try classified.append(.{ | 326 | try classified.append(.{ |
| 331 | .kind = .stub, | 327 | .kind = .{ .stub = lib_stub }, |
| 332 | .origin = .{ .stub = lib_stub }, | | |
| 333 | .name = full_path, | 328 | .name = full_path, |
| 334 | }); | 329 | }); |
| 335 | file.close(); | 330 | file.close(); |
| ... | @@ -343,53 +338,46 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void { | ... | @@ -343,53 +338,46 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void { |
| 343 | // Based on our classification, proceed with parsing. | 338 | // Based on our classification, proceed with parsing. |
| 344 | for (classified.items) |input| { | 339 | for (classified.items) |input| { |
| 345 | switch (input.kind) { | 340 | switch (input.kind) { |
| 346 | .object => { | 341 | .object => |file| { |
| 347 | const object = try self.allocator.create(Object); | 342 | const object = try self.allocator.create(Object); |
| 348 | errdefer self.allocator.destroy(object); | 343 | errdefer self.allocator.destroy(object); |
| 349 | | 344 | |
| 350 | object.* = Object.init(self.allocator); | 345 | object.* = Object.init(self.allocator); |
| 351 | object.arch = self.arch.?; | 346 | object.arch = self.arch.?; |
| 352 | object.name = input.name; | 347 | object.name = input.name; |
| 353 | object.file = input.origin.file; | 348 | object.file = file; |
| 354 | | 349 | |
| 355 | try object.parse(); | 350 | try object.parse(); |
| 356 | try self.objects.append(self.allocator, object); | 351 | try self.objects.append(self.allocator, object); |
| 357 | }, | 352 | }, |
| 358 | .archive => { | 353 | .archive => |file| { |
| 359 | const archive = try self.allocator.create(Archive); | 354 | const archive = try self.allocator.create(Archive); |
| 360 | errdefer self.allocator.destroy(archive); | 355 | errdefer self.allocator.destroy(archive); |
| 361 | | 356 | |
| 362 | archive.* = Archive.init(self.allocator); | 357 | archive.* = Archive.init(self.allocator); |
| 363 | archive.arch = self.arch.?; | 358 | archive.arch = self.arch.?; |
| 364 | archive.name = input.name; | 359 | archive.name = input.name; |
| 365 | archive.file = input.origin.file; | 360 | archive.file = file; |
| 366 | | 361 | |
| 367 | try archive.parse(); | 362 | try archive.parse(); |
| 368 | try self.archives.append(self.allocator, archive); | 363 | try self.archives.append(self.allocator, archive); |
| 369 | }, | 364 | }, |
| 370 | .dylib => { | 365 | .dylib, .stub => { |
| 371 | const dylib = try self.allocator.create(Dylib); | 366 | const dylib = try self.allocator.create(Dylib); |
| 372 | errdefer self.allocator.destroy(dylib); | 367 | errdefer self.allocator.destroy(dylib); |
| 373 | | 368 | |
| 374 | dylib.* = Dylib.init(self.allocator); | 369 | dylib.* = Dylib.init(self.allocator); |
| 375 | dylib.arch = self.arch.?; | 370 | dylib.arch = self.arch.?; |
| 376 | dylib.name = input.name; | 371 | dylib.name = input.name; |
| 377 | dylib.file = input.origin.file; | | |
| 378 | | 372 | |
| 379 | try dylib.parse(); | 373 | if (input.kind == .dylib) { |
| 380 | try self.dylibs.append(self.allocator, dylib); | 374 | dylib.file = input.kind.dylib; |
| 381 | }, | 375 | try dylib.parse(); |
| 382 | .stub => { | 376 | } else { |
| 383 | const stub = try self.allocator.create(Stub); | 377 | try dylib.parseFromStub(input.kind.stub); |
| 384 | errdefer self.allocator.destroy(stub); | 378 | } |
| 385 | | | |
| 386 | stub.* = Stub.init(self.allocator); | | |
| 387 | stub.arch = self.arch.?; | | |
| 388 | stub.name = input.name; | | |
| 389 | stub.lib_stub = input.origin.stub; | | |
| 390 | | 379 | |
| 391 | try stub.parse(); | 380 | try self.dylibs.append(self.allocator, dylib); |
| 392 | try self.lib_stubs.append(self.allocator, stub); | | |
| 393 | }, | 381 | }, |
| 394 | } | 382 | } |
| 395 | } | 383 | } |
| ... | @@ -399,50 +387,64 @@ fn parseLibs(self: *Zld, libs: []const []const u8) !void { | ... | @@ -399,50 +387,64 @@ fn parseLibs(self: *Zld, libs: []const []const u8) !void { |
| 399 | for (libs) |lib| { | 387 | for (libs) |lib| { |
| 400 | const file = try fs.cwd().openFile(lib, .{}); | 388 | const file = try fs.cwd().openFile(lib, .{}); |
| 401 | | 389 | |
| 402 | if (try Dylib.isDylib(file)) { | 390 | var kind: ?union(enum) { |
| 403 | const dylib = try self.allocator.create(Dylib); | 391 | archive, |
| 404 | errdefer self.allocator.destroy(dylib); | 392 | dylib, |
| | 393 | stub: LibStub, |
| | 394 | } = kind: { |
| | 395 | if (try Archive.isArchive(file)) break :kind .archive; |
| | 396 | if (try Dylib.isDylib(file)) break :kind .dylib; |
| | 397 | var lib_stub = LibStub.loadFromFile(self.allocator, file) catch { |
| | 398 | break :kind null; |
| | 399 | }; |
| | 400 | break :kind .{ .stub = lib_stub }; |
| | 401 | }; |
| | 402 | defer { |
| | 403 | if (kind) |*kk| { |
| | 404 | switch (kk.*) { |
| | 405 | .stub => |*stub| { |
| | 406 | stub.deinit(); |
| | 407 | }, |
| | 408 | else => {}, |
| | 409 | } |
| | 410 | } |
| | 411 | } |
| 405 | | 412 | |
| 406 | dylib.* = Dylib.init(self.allocator); | 413 | const unwrapped = kind orelse { |
| 407 | dylib.arch = self.arch.?; | 414 | file.close(); |
| 408 | dylib.name = try self.allocator.dupe(u8, lib); | 415 | log.warn("unknown filetype for a library: '{s}'", .{lib}); |
| 409 | dylib.file = file; | 416 | continue; |
| | 417 | }; |
| | 418 | switch (unwrapped) { |
| | 419 | .archive => { |
| | 420 | const archive = try self.allocator.create(Archive); |
| | 421 | errdefer self.allocator.destroy(archive); |
| 410 | | 422 | |
| 411 | try dylib.parse(); | 423 | archive.* = Archive.init(self.allocator); |
| 412 | try self.dylibs.append(self.allocator, dylib); | 424 | archive.arch = self.arch.?; |
| 413 | } else { | 425 | archive.name = try self.allocator.dupe(u8, lib); |
| 414 | // Try tbd stub file next. | 426 | archive.file = file; |
| 415 | if (Stub.LibStub.loadFromFile(self.allocator, file)) |lib_stub| { | 427 | |
| 416 | const stub = try self.allocator.create(Stub); | 428 | try archive.parse(); |
| 417 | errdefer self.allocator.destroy(stub); | 429 | try self.archives.append(self.allocator, archive); |
| 418 | | 430 | }, |
| 419 | stub.* = Stub.init(self.allocator); | 431 | .dylib, .stub => { |
| 420 | stub.arch = self.arch.?; | 432 | const dylib = try self.allocator.create(Dylib); |
| 421 | stub.name = try self.allocator.dupe(u8, lib); | 433 | errdefer self.allocator.destroy(dylib); |
| 422 | stub.lib_stub = lib_stub; | 434 | |
| 423 | | 435 | dylib.* = Dylib.init(self.allocator); |
| 424 | try stub.parse(); | 436 | dylib.arch = self.arch.?; |
| 425 | try self.lib_stubs.append(self.allocator, stub); | 437 | dylib.name = try self.allocator.dupe(u8, lib); |
| 426 | } else |_| { | 438 | |
| 427 | // TODO this entire logic has to be cleaned up. | 439 | if (unwrapped == .dylib) { |
| 428 | try file.seekTo(0); | 440 | dylib.file = file; |
| 429 | | 441 | try dylib.parse(); |
| 430 | if (try Archive.isArchive(file)) { | | |
| 431 | const archive = try self.allocator.create(Archive); | | |
| 432 | errdefer self.allocator.destroy(archive); | | |
| 433 | | | |
| 434 | archive.* = Archive.init(self.allocator); | | |
| 435 | archive.arch = self.arch.?; | | |
| 436 | archive.name = try self.allocator.dupe(u8, lib); | | |
| 437 | archive.file = file; | | |
| 438 | | | |
| 439 | try archive.parse(); | | |
| 440 | try self.archives.append(self.allocator, archive); | | |
| 441 | } else { | 442 | } else { |
| 442 | file.close(); | 443 | try dylib.parseFromStub(unwrapped.stub); |
| 443 | log.warn("unknown filetype for a library: '{s}'", .{lib}); | | |
| 444 | } | 444 | } |
| 445 | } | 445 | |
| | 446 | try self.dylibs.append(self.allocator, dylib); |
| | 447 | }, |
| 446 | } | 448 | } |
| 447 | } | 449 | } |
| 448 | } | 450 | } |
| ... | @@ -451,24 +453,24 @@ fn parseLibSystem(self: *Zld, libc_stub_path: []const u8) !void { | ... | @@ -451,24 +453,24 @@ fn parseLibSystem(self: *Zld, libc_stub_path: []const u8) !void { |
| 451 | const file = try fs.cwd().openFile(libc_stub_path, .{}); | 453 | const file = try fs.cwd().openFile(libc_stub_path, .{}); |
| 452 | defer file.close(); | 454 | defer file.close(); |
| 453 | | 455 | |
| 454 | var lib_stub = try Stub.LibStub.loadFromFile(self.allocator, file); | 456 | var lib_stub = try LibStub.loadFromFile(self.allocator, file); |
| | 457 | defer lib_stub.deinit(); |
| 455 | | 458 | |
| 456 | const stub = try self.allocator.create(Stub); | 459 | const dylib = try self.allocator.create(Dylib); |
| 457 | errdefer self.allocator.destroy(stub); | 460 | errdefer self.allocator.destroy(dylib); |
| 458 | | 461 | |
| 459 | stub.* = Stub.init(self.allocator); | 462 | dylib.* = Dylib.init(self.allocator); |
| 460 | stub.arch = self.arch.?; | 463 | dylib.arch = self.arch.?; |
| 461 | stub.name = try self.allocator.dupe(u8, libc_stub_path); | 464 | dylib.name = try self.allocator.dupe(u8, libc_stub_path); |
| 462 | stub.lib_stub = lib_stub; | | |
| 463 | | 465 | |
| 464 | try stub.parse(); | 466 | try dylib.parseFromStub(lib_stub); |
| 465 | | 467 | |
| 466 | self.libsystem_stub_index = @intCast(u16, self.lib_stubs.items.len); | 468 | self.libsystem_dylib_index = @intCast(u16, self.dylibs.items.len); |
| 467 | try self.lib_stubs.append(self.allocator, stub); | 469 | try self.dylibs.append(self.allocator, dylib); |
| 468 | | 470 | |
| 469 | // Add LC_LOAD_DYLIB load command. | 471 | // Add LC_LOAD_DYLIB load command. |
| 470 | stub.ordinal = self.next_dylib_ordinal; | 472 | dylib.ordinal = self.next_dylib_ordinal; |
| 471 | const dylib_id = stub.id orelse unreachable; | 473 | const dylib_id = dylib.id orelse unreachable; |
| 472 | var dylib_cmd = try createLoadDylibCommand( | 474 | var dylib_cmd = try createLoadDylibCommand( |
| 473 | self.allocator, | 475 | self.allocator, |
| 474 | dylib_id.name, | 476 | dylib_id.name, |
| ... | @@ -1778,25 +1780,16 @@ fn resolveSymbols(self: *Zld) !void { | ... | @@ -1778,25 +1780,16 @@ fn resolveSymbols(self: *Zld) !void { |
| 1778 | } | 1780 | } |
| 1779 | self.unresolved.clearRetainingCapacity(); | 1781 | self.unresolved.clearRetainingCapacity(); |
| 1780 | | 1782 | |
| 1781 | var referenced = std.AutoHashMap(union(enum) { | 1783 | var referenced = std.AutoHashMap(*Dylib, void).init(self.allocator); |
| 1782 | dylib: *Dylib, | | |
| 1783 | stub: *Stub, | | |
| 1784 | }, void).init(self.allocator); | | |
| 1785 | defer referenced.deinit(); | 1784 | defer referenced.deinit(); |
| 1786 | | 1785 | |
| 1787 | loop: while (unresolved.popOrNull()) |undef| { | 1786 | loop: while (unresolved.popOrNull()) |undef| { |
| 1788 | const proxy = self.imports.get(undef.name) orelse outer: { | 1787 | const proxy = self.imports.get(undef.name) orelse outer: { |
| 1789 | const proxy = inner: { | 1788 | const proxy = inner: { |
| 1790 | for (self.dylibs.items) |dylib| { | 1789 | for (self.dylibs.items) |dylib, i| { |
| 1791 | const proxy = (try dylib.createProxy(undef.name)) orelse continue; | 1790 | const proxy = (try dylib.createProxy(undef.name)) orelse continue; |
| 1792 | try referenced.put(.{ .dylib = dylib }, {}); | 1791 | if (self.libsystem_dylib_index.? != @intCast(u16, i)) { // LibSystem gets load command seperately. |
| 1793 | break :inner proxy; | 1792 | try referenced.put(dylib, {}); |
| 1794 | } | | |
| 1795 | for (self.lib_stubs.items) |stub, i| { | | |
| 1796 | const proxy = (try stub.createProxy(undef.name)) orelse continue; | | |
| 1797 | if (self.libsystem_stub_index.? != @intCast(u16, i)) { | | |
| 1798 | // LibSystem gets its load command separately. | | |
| 1799 | try referenced.put(.{ .stub = stub }, {}); | | |
| 1800 | } | 1793 | } |
| 1801 | break :inner proxy; | 1794 | break :inner proxy; |
| 1802 | } | 1795 | } |
| ... | @@ -1829,33 +1822,17 @@ fn resolveSymbols(self: *Zld) !void { | ... | @@ -1829,33 +1822,17 @@ fn resolveSymbols(self: *Zld) !void { |
| 1829 | | 1822 | |
| 1830 | // Add LC_LOAD_DYLIB load command for each referenced dylib/stub. | 1823 | // Add LC_LOAD_DYLIB load command for each referenced dylib/stub. |
| 1831 | var it = referenced.iterator(); | 1824 | var it = referenced.iterator(); |
| 1832 | while (it.next()) |key| { | 1825 | while (it.next()) |entry| { |
| 1833 | var dylib_cmd = blk: { | 1826 | const dylib = entry.key_ptr.*; |
| 1834 | switch (key.key_ptr.*) { | 1827 | dylib.ordinal = self.next_dylib_ordinal; |
| 1835 | .dylib => |dylib| { | 1828 | const dylib_id = dylib.id orelse unreachable; |
| 1836 | dylib.ordinal = self.next_dylib_ordinal; | 1829 | var dylib_cmd = try createLoadDylibCommand( |
| 1837 | const dylib_id = dylib.id orelse unreachable; | 1830 | self.allocator, |
| 1838 | break :blk try createLoadDylibCommand( | 1831 | dylib_id.name, |
| 1839 | self.allocator, | 1832 | dylib_id.timestamp, |
| 1840 | dylib_id.name, | 1833 | dylib_id.current_version, |
| 1841 | dylib_id.timestamp, | 1834 | dylib_id.compatibility_version, |
| 1842 | dylib_id.current_version, | 1835 | ); |
| 1843 | dylib_id.compatibility_version, | | |
| 1844 | ); | | |
| 1845 | }, | | |
| 1846 | .stub => |stub| { | | |
| 1847 | stub.ordinal = self.next_dylib_ordinal; | | |
| 1848 | const dylib_id = stub.id orelse unreachable; | | |
| 1849 | break :blk try createLoadDylibCommand( | | |
| 1850 | self.allocator, | | |
| 1851 | dylib_id.name, | | |
| 1852 | dylib_id.timestamp, | | |
| 1853 | dylib_id.current_version, | | |
| 1854 | dylib_id.compatibility_version, | | |
| 1855 | ); | | |
| 1856 | }, | | |
| 1857 | } | | |
| 1858 | }; | | |
| 1859 | errdefer dylib_cmd.deinit(self.allocator); | 1836 | errdefer dylib_cmd.deinit(self.allocator); |
| 1860 | try self.load_commands.append(self.allocator, .{ .Dylib = dylib_cmd }); | 1837 | try self.load_commands.append(self.allocator, .{ .Dylib = dylib_cmd }); |
| 1861 | self.next_dylib_ordinal += 1; | 1838 | self.next_dylib_ordinal += 1; |
| ... | @@ -1873,8 +1850,8 @@ fn resolveSymbols(self: *Zld) !void { | ... | @@ -1873,8 +1850,8 @@ fn resolveSymbols(self: *Zld) !void { |
| 1873 | } | 1850 | } |
| 1874 | | 1851 | |
| 1875 | // Finally put dyld_stub_binder as an Import | 1852 | // Finally put dyld_stub_binder as an Import |
| 1876 | const libsystem_stub = self.lib_stubs.items[self.libsystem_stub_index.?]; | 1853 | const libsystem_dylib = self.dylibs.items[self.libsystem_dylib_index.?]; |
| 1877 | const proxy = (try libsystem_stub.createProxy("dyld_stub_binder")) orelse { | 1854 | const proxy = (try libsystem_dylib.createProxy("dyld_stub_binder")) orelse { |
| 1878 | log.err("undefined reference to symbol 'dyld_stub_binder'", .{}); | 1855 | log.err("undefined reference to symbol 'dyld_stub_binder'", .{}); |
| 1879 | return error.UndefinedSymbolReference; | 1856 | return error.UndefinedSymbolReference; |
| 1880 | }; | 1857 | }; |