| ... | ... | @@ -34,7 +34,6 @@ const Object = @import("Object.zig"); |
| 34 | 34 | const Section = MachO.Section; |
| 35 | 35 | const StringTable = @import("../strtab.zig").StringTable; |
| 36 | 36 | const SymbolWithLoc = MachO.SymbolWithLoc; |
| 37 | | const SymbolResolver = MachO.SymbolResolver; |
| 38 | 37 | const TableSection = @import("../table_section.zig").TableSection; |
| 39 | 38 | const Trie = @import("Trie.zig"); |
| 40 | 39 | const UnwindInfo = @import("UnwindInfo.zig"); |
| ... | ... | @@ -76,6 +75,8 @@ pub const Zld = struct { |
| 76 | 75 | |
| 77 | 76 | locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 78 | 77 | globals: std.ArrayListUnmanaged(SymbolWithLoc) = .{}, |
| 78 | resolver: std.StringHashMapUnmanaged(u32) = .{}, |
| 79 | unresolved: std.AutoArrayHashMapUnmanaged(u32, void) = .{}, |
| 79 | 80 | |
| 80 | 81 | entry_index: ?u32 = null, |
| 81 | 82 | mh_execute_header_index: ?u32 = null, |
| ... | ... | @@ -327,53 +328,53 @@ pub const Zld = struct { |
| 327 | 328 | } |
| 328 | 329 | } |
| 329 | 330 | |
| 330 | | fn addUndefined(self: *Zld, name: []const u8, resolver: *SymbolResolver) !void { |
| 331 | fn addUndefined(self: *Zld, name: []const u8) !void { |
| 331 | 332 | const sym_index = try self.allocateSymbol(); |
| 332 | 333 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index }; |
| 333 | 334 | const sym = self.getSymbolPtr(sym_loc); |
| 334 | 335 | sym.n_strx = try self.strtab.insert(self.gpa, name); |
| 335 | 336 | sym.n_type = macho.N_UNDF; |
| 336 | 337 | const global_index = try self.addGlobal(sym_loc); |
| 337 | | try resolver.table.putNoClobber(name, global_index); |
| 338 | | try resolver.unresolved.putNoClobber(global_index, {}); |
| 338 | try self.resolver.putNoClobber(self.gpa, name, global_index); |
| 339 | try self.unresolved.putNoClobber(self.gpa, global_index, {}); |
| 339 | 340 | } |
| 340 | 341 | |
| 341 | | fn resolveSymbols(self: *Zld, resolver: *SymbolResolver) !void { |
| 342 | fn resolveSymbols(self: *Zld) !void { |
| 342 | 343 | // We add the specified entrypoint as the first unresolved symbols so that |
| 343 | 344 | // we search for it in libraries should there be no object files specified |
| 344 | 345 | // on the linker line. |
| 345 | 346 | if (self.options.output_mode == .Exe) { |
| 346 | 347 | const entry_name = self.options.entry orelse load_commands.default_entry_point; |
| 347 | | try self.addUndefined(entry_name, resolver); |
| 348 | try self.addUndefined(entry_name); |
| 348 | 349 | } |
| 349 | 350 | |
| 350 | 351 | // Force resolution of any symbols requested by the user. |
| 351 | 352 | for (self.options.force_undefined_symbols.keys()) |sym_name| { |
| 352 | | try self.addUndefined(sym_name, resolver); |
| 353 | try self.addUndefined(sym_name); |
| 353 | 354 | } |
| 354 | 355 | |
| 355 | 356 | for (self.objects.items, 0..) |_, object_id| { |
| 356 | | try self.resolveSymbolsInObject(@as(u32, @intCast(object_id)), resolver); |
| 357 | try self.resolveSymbolsInObject(@as(u32, @intCast(object_id))); |
| 357 | 358 | } |
| 358 | 359 | |
| 359 | | try self.resolveSymbolsInArchives(resolver); |
| 360 | try self.resolveSymbolsInArchives(); |
| 360 | 361 | |
| 361 | 362 | // Finally, force resolution of dyld_stub_binder if there are imports |
| 362 | 363 | // requested. |
| 363 | | if (resolver.unresolved.count() > 0) { |
| 364 | | try self.addUndefined("dyld_stub_binder", resolver); |
| 364 | if (self.unresolved.count() > 0) { |
| 365 | try self.addUndefined("dyld_stub_binder"); |
| 365 | 366 | } |
| 366 | 367 | |
| 367 | | try self.resolveSymbolsInDylibs(resolver); |
| 368 | try self.resolveSymbolsInDylibs(); |
| 368 | 369 | |
| 369 | | self.dyld_stub_binder_index = resolver.table.get("dyld_stub_binder"); |
| 370 | self.dyld_stub_binder_index = self.resolver.get("dyld_stub_binder"); |
| 370 | 371 | |
| 371 | | try self.createMhExecuteHeaderSymbol(resolver); |
| 372 | | try self.createDsoHandleSymbol(resolver); |
| 373 | | try self.resolveSymbolsAtLoading(resolver); |
| 372 | try self.createMhExecuteHeaderSymbol(); |
| 373 | try self.createDsoHandleSymbol(); |
| 374 | try self.resolveSymbolsAtLoading(); |
| 374 | 375 | } |
| 375 | 376 | |
| 376 | | fn resolveSymbolsInObject(self: *Zld, object_id: u32, resolver: *SymbolResolver) !void { |
| 377 | fn resolveSymbolsInObject(self: *Zld, object_id: u32) !void { |
| 377 | 378 | const object = &self.objects.items[object_id]; |
| 378 | 379 | const in_symtab = object.in_symtab orelse return; |
| 379 | 380 | |
| ... | ... | @@ -415,11 +416,11 @@ pub const Zld = struct { |
| 415 | 416 | |
| 416 | 417 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = object_id + 1 }; |
| 417 | 418 | |
| 418 | | const global_index = resolver.table.get(sym_name) orelse { |
| 419 | const global_index = self.resolver.get(sym_name) orelse { |
| 419 | 420 | const global_index = try self.addGlobal(sym_loc); |
| 420 | | try resolver.table.putNoClobber(sym_name, global_index); |
| 421 | try self.resolver.putNoClobber(self.gpa, sym_name, global_index); |
| 421 | 422 | if (sym.undf() and !sym.tentative()) { |
| 422 | | try resolver.unresolved.putNoClobber(global_index, {}); |
| 423 | try self.unresolved.putNoClobber(self.gpa, global_index, {}); |
| 423 | 424 | } |
| 424 | 425 | continue; |
| 425 | 426 | }; |
| ... | ... | @@ -477,7 +478,7 @@ pub const Zld = struct { |
| 477 | 478 | const global_object = &self.objects.items[file]; |
| 478 | 479 | global_object.globals_lookup[global.sym_index] = global_index; |
| 479 | 480 | } |
| 480 | | _ = resolver.unresolved.swapRemove(resolver.table.get(sym_name).?); |
| 481 | _ = self.unresolved.swapRemove(self.resolver.get(sym_name).?); |
| 481 | 482 | global.* = sym_loc; |
| 482 | 483 | } else { |
| 483 | 484 | object.globals_lookup[sym_index] = global_index; |
| ... | ... | @@ -485,14 +486,14 @@ pub const Zld = struct { |
| 485 | 486 | } |
| 486 | 487 | } |
| 487 | 488 | |
| 488 | | fn resolveSymbolsInArchives(self: *Zld, resolver: *SymbolResolver) !void { |
| 489 | fn resolveSymbolsInArchives(self: *Zld) !void { |
| 489 | 490 | if (self.archives.items.len == 0) return; |
| 490 | 491 | |
| 491 | 492 | const gpa = self.gpa; |
| 492 | 493 | |
| 493 | 494 | var next_sym: usize = 0; |
| 494 | | loop: while (next_sym < resolver.unresolved.count()) { |
| 495 | | const global = self.globals.items[resolver.unresolved.keys()[next_sym]]; |
| 495 | loop: while (next_sym < self.unresolved.count()) { |
| 496 | const global = self.globals.items[self.unresolved.keys()[next_sym]]; |
| 496 | 497 | const sym_name = self.getSymbolName(global); |
| 497 | 498 | |
| 498 | 499 | for (self.archives.items) |archive| { |
| ... | ... | @@ -506,7 +507,7 @@ pub const Zld = struct { |
| 506 | 507 | const object_id = @as(u16, @intCast(self.objects.items.len)); |
| 507 | 508 | const object = try archive.parseObject(gpa, offsets.items[0]); |
| 508 | 509 | try self.objects.append(gpa, object); |
| 509 | | try self.resolveSymbolsInObject(object_id, resolver); |
| 510 | try self.resolveSymbolsInObject(object_id); |
| 510 | 511 | |
| 511 | 512 | continue :loop; |
| 512 | 513 | } |
| ... | ... | @@ -515,12 +516,12 @@ pub const Zld = struct { |
| 515 | 516 | } |
| 516 | 517 | } |
| 517 | 518 | |
| 518 | | fn resolveSymbolsInDylibs(self: *Zld, resolver: *SymbolResolver) !void { |
| 519 | fn resolveSymbolsInDylibs(self: *Zld) !void { |
| 519 | 520 | if (self.dylibs.items.len == 0) return; |
| 520 | 521 | |
| 521 | 522 | var next_sym: usize = 0; |
| 522 | | loop: while (next_sym < resolver.unresolved.count()) { |
| 523 | | const global_index = resolver.unresolved.keys()[next_sym]; |
| 523 | loop: while (next_sym < self.unresolved.count()) { |
| 524 | const global_index = self.unresolved.keys()[next_sym]; |
| 524 | 525 | const global = self.globals.items[global_index]; |
| 525 | 526 | const sym = self.getSymbolPtr(global); |
| 526 | 527 | const sym_name = self.getSymbolName(global); |
| ... | ... | @@ -541,7 +542,7 @@ pub const Zld = struct { |
| 541 | 542 | sym.n_desc |= macho.N_WEAK_REF; |
| 542 | 543 | } |
| 543 | 544 | |
| 544 | | assert(resolver.unresolved.swapRemove(global_index)); |
| 545 | assert(self.unresolved.swapRemove(global_index)); |
| 545 | 546 | continue :loop; |
| 546 | 547 | } |
| 547 | 548 | |
| ... | ... | @@ -549,14 +550,14 @@ pub const Zld = struct { |
| 549 | 550 | } |
| 550 | 551 | } |
| 551 | 552 | |
| 552 | | fn resolveSymbolsAtLoading(self: *Zld, resolver: *SymbolResolver) !void { |
| 553 | fn resolveSymbolsAtLoading(self: *Zld) !void { |
| 553 | 554 | const is_lib = self.options.output_mode == .Lib; |
| 554 | 555 | const is_dyn_lib = self.options.link_mode == .Dynamic and is_lib; |
| 555 | 556 | const allow_undef = is_dyn_lib and (self.options.allow_shlib_undefined orelse false); |
| 556 | 557 | |
| 557 | 558 | var next_sym: usize = 0; |
| 558 | | while (next_sym < resolver.unresolved.count()) { |
| 559 | | const global_index = resolver.unresolved.keys()[next_sym]; |
| 559 | while (next_sym < self.unresolved.count()) { |
| 560 | const global_index = self.unresolved.keys()[next_sym]; |
| 560 | 561 | const global = self.globals.items[global_index]; |
| 561 | 562 | const sym = self.getSymbolPtr(global); |
| 562 | 563 | |
| ... | ... | @@ -568,7 +569,7 @@ pub const Zld = struct { |
| 568 | 569 | .n_desc = 0, |
| 569 | 570 | .n_value = 0, |
| 570 | 571 | }; |
| 571 | | _ = resolver.unresolved.swapRemove(global_index); |
| 572 | _ = self.unresolved.swapRemove(global_index); |
| 572 | 573 | continue; |
| 573 | 574 | } else if (allow_undef) { |
| 574 | 575 | const n_desc = @as( |
| ... | ... | @@ -577,7 +578,7 @@ pub const Zld = struct { |
| 577 | 578 | ); |
| 578 | 579 | sym.n_type = macho.N_EXT; |
| 579 | 580 | sym.n_desc = n_desc; |
| 580 | | _ = resolver.unresolved.swapRemove(global_index); |
| 581 | _ = self.unresolved.swapRemove(global_index); |
| 581 | 582 | continue; |
| 582 | 583 | } |
| 583 | 584 | |
| ... | ... | @@ -585,9 +586,9 @@ pub const Zld = struct { |
| 585 | 586 | } |
| 586 | 587 | } |
| 587 | 588 | |
| 588 | | fn createMhExecuteHeaderSymbol(self: *Zld, resolver: *SymbolResolver) !void { |
| 589 | fn createMhExecuteHeaderSymbol(self: *Zld) !void { |
| 589 | 590 | if (self.options.output_mode != .Exe) return; |
| 590 | | if (resolver.table.get("__mh_execute_header")) |global_index| { |
| 591 | if (self.resolver.get("__mh_execute_header")) |global_index| { |
| 591 | 592 | const global = self.globals.items[global_index]; |
| 592 | 593 | const sym = self.getSymbol(global); |
| 593 | 594 | self.mh_execute_header_index = global_index; |
| ... | ... | @@ -602,7 +603,7 @@ pub const Zld = struct { |
| 602 | 603 | sym.n_type = macho.N_SECT | macho.N_EXT; |
| 603 | 604 | sym.n_desc = macho.REFERENCED_DYNAMICALLY; |
| 604 | 605 | |
| 605 | | if (resolver.table.get("__mh_execute_header")) |global_index| { |
| 606 | if (self.resolver.get("__mh_execute_header")) |global_index| { |
| 606 | 607 | const global = &self.globals.items[global_index]; |
| 607 | 608 | const global_object = &self.objects.items[global.getFile().?]; |
| 608 | 609 | global_object.globals_lookup[global.sym_index] = global_index; |
| ... | ... | @@ -613,8 +614,8 @@ pub const Zld = struct { |
| 613 | 614 | } |
| 614 | 615 | } |
| 615 | 616 | |
| 616 | | fn createDsoHandleSymbol(self: *Zld, resolver: *SymbolResolver) !void { |
| 617 | | const global_index = resolver.table.get("___dso_handle") orelse return; |
| 617 | fn createDsoHandleSymbol(self: *Zld) !void { |
| 618 | const global_index = self.resolver.get("___dso_handle") orelse return; |
| 618 | 619 | const global = &self.globals.items[global_index]; |
| 619 | 620 | self.dso_handle_index = global_index; |
| 620 | 621 | if (!self.getSymbol(global.*).undf()) return; |
| ... | ... | @@ -629,7 +630,7 @@ pub const Zld = struct { |
| 629 | 630 | |
| 630 | 631 | const global_object = &self.objects.items[global.getFile().?]; |
| 631 | 632 | global_object.globals_lookup[global.sym_index] = global_index; |
| 632 | | _ = resolver.unresolved.swapRemove(resolver.table.get("___dso_handle").?); |
| 633 | _ = self.unresolved.swapRemove(self.resolver.get("___dso_handle").?); |
| 633 | 634 | global.* = sym_loc; |
| 634 | 635 | } |
| 635 | 636 | |
| ... | ... | @@ -649,6 +650,8 @@ pub const Zld = struct { |
| 649 | 650 | self.strtab.deinit(gpa); |
| 650 | 651 | self.locals.deinit(gpa); |
| 651 | 652 | self.globals.deinit(gpa); |
| 653 | self.resolver.deinit(gpa); |
| 654 | self.unresolved.deinit(gpa); |
| 652 | 655 | |
| 653 | 656 | for (self.objects.items) |*object| { |
| 654 | 657 | object.deinit(gpa); |
| ... | ... | @@ -3066,17 +3069,12 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 3066 | 3069 | log.err("parsing dependent libraries failed with err {s}", .{@errorName(err)}); |
| 3067 | 3070 | }; |
| 3068 | 3071 | |
| 3069 | | var resolver = SymbolResolver{ |
| 3070 | | .arena = arena, |
| 3071 | | .table = std.StringHashMap(u32).init(arena), |
| 3072 | | .unresolved = std.AutoArrayHashMap(u32, void).init(arena), |
| 3073 | | }; |
| 3074 | | try zld.resolveSymbols(&resolver); |
| 3075 | | try macho_file.reportUndefined(&zld, &resolver); |
| 3072 | try zld.resolveSymbols(); |
| 3073 | try macho_file.reportUndefined(&zld); |
| 3076 | 3074 | |
| 3077 | 3075 | if (options.output_mode == .Exe) { |
| 3078 | 3076 | const entry_name = options.entry orelse load_commands.default_entry_point; |
| 3079 | | const global_index = resolver.table.get(entry_name).?; // Error was flagged earlier |
| 3077 | const global_index = zld.resolver.get(entry_name).?; // Error was flagged earlier |
| 3080 | 3078 | zld.entry_index = global_index; |
| 3081 | 3079 | } |
| 3082 | 3080 | |
| ... | ... | @@ -3085,7 +3083,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr |
| 3085 | 3083 | } |
| 3086 | 3084 | |
| 3087 | 3085 | if (gc_sections) { |
| 3088 | | try dead_strip.gcAtoms(&zld, &resolver); |
| 3086 | try dead_strip.gcAtoms(&zld); |
| 3089 | 3087 | } |
| 3090 | 3088 | |
| 3091 | 3089 | try zld.createDyldPrivateAtom(); |