| ... | ... | @@ -170,6 +170,8 @@ sections_order_dirty: bool = false, |
| 170 | 170 | has_dices: bool = false, |
| 171 | 171 | has_stabs: bool = false, |
| 172 | 172 | |
| 173 | args_digest: [Cache.hex_digest_len]u8 = undefined, |
| 174 | |
| 173 | 175 | section_ordinals: std.AutoArrayHashMapUnmanaged(MatchingSection, void) = .{}, |
| 174 | 176 | |
| 175 | 177 | /// A list of atoms that have surplus capacity. This list can have false |
| ... | ... | @@ -334,31 +336,31 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio |
| 334 | 336 | return self; |
| 335 | 337 | } |
| 336 | 338 | |
| 337 | | if (!options.strip and options.module != null) { |
| 338 | | // Create dSYM bundle. |
| 339 | | const dir = options.module.?.zig_cache_artifact_directory; |
| 340 | | log.debug("creating {s}.dSYM bundle in {s}", .{ sub_path, dir.path }); |
| 339 | // if (!options.strip and options.module != null) { |
| 340 | // // Create dSYM bundle. |
| 341 | // const dir = options.module.?.zig_cache_artifact_directory; |
| 342 | // log.debug("creating {s}.dSYM bundle in {s}", .{ sub_path, dir.path }); |
| 341 | 343 | |
| 342 | | const d_sym_path = try fmt.allocPrint( |
| 343 | | allocator, |
| 344 | | "{s}.dSYM" ++ fs.path.sep_str ++ "Contents" ++ fs.path.sep_str ++ "Resources" ++ fs.path.sep_str ++ "DWARF", |
| 345 | | .{sub_path}, |
| 346 | | ); |
| 347 | | defer allocator.free(d_sym_path); |
| 344 | // const d_sym_path = try fmt.allocPrint( |
| 345 | // allocator, |
| 346 | // "{s}.dSYM" ++ fs.path.sep_str ++ "Contents" ++ fs.path.sep_str ++ "Resources" ++ fs.path.sep_str ++ "DWARF", |
| 347 | // .{sub_path}, |
| 348 | // ); |
| 349 | // defer allocator.free(d_sym_path); |
| 348 | 350 | |
| 349 | | var d_sym_bundle = try dir.handle.makeOpenPath(d_sym_path, .{}); |
| 350 | | defer d_sym_bundle.close(); |
| 351 | // var d_sym_bundle = try dir.handle.makeOpenPath(d_sym_path, .{}); |
| 352 | // defer d_sym_bundle.close(); |
| 351 | 353 | |
| 352 | | const d_sym_file = try d_sym_bundle.createFile(sub_path, .{ |
| 353 | | .truncate = false, |
| 354 | | .read = true, |
| 355 | | }); |
| 354 | // const d_sym_file = try d_sym_bundle.createFile(sub_path, .{ |
| 355 | // .truncate = false, |
| 356 | // .read = true, |
| 357 | // }); |
| 356 | 358 | |
| 357 | | self.d_sym = .{ |
| 358 | | .base = self, |
| 359 | | .file = d_sym_file, |
| 360 | | }; |
| 361 | | } |
| 359 | // self.d_sym = .{ |
| 360 | // .base = self, |
| 361 | // .file = d_sym_file, |
| 362 | // }; |
| 363 | // } |
| 362 | 364 | |
| 363 | 365 | // Index 0 is always a null symbol. |
| 364 | 366 | try self.locals.append(allocator, .{ |
| ... | ... | @@ -555,218 +557,256 @@ pub fn flush(self: *MachO, comp: *Compilation) !void { |
| 555 | 557 | try self.strtab.append(self.base.allocator, 0); |
| 556 | 558 | } |
| 557 | 559 | |
| 558 | | // Positional arguments to the linker such as object files and static archives. |
| 559 | | var positionals = std.ArrayList([]const u8).init(arena); |
| 560 | const needs_full_relink = blk: { |
| 561 | if (use_stage1) break :blk true; |
| 560 | 562 | |
| 561 | | try positionals.appendSlice(self.base.options.objects); |
| 563 | var hh: Cache.HashHelper = .{}; |
| 564 | hh.addListOfBytes(self.base.options.objects); |
| 565 | for (comp.c_object_table.keys()) |key| { |
| 566 | hh.addBytes(key.status.success.object_path); |
| 567 | } |
| 568 | hh.addOptionalBytes(module_obj_path); |
| 569 | if (comp.compiler_rt_static_lib) |lib| { |
| 570 | hh.addBytes(lib.full_object_path); |
| 571 | } |
| 572 | if (self.base.options.link_libcpp) { |
| 573 | hh.addBytes(comp.libcxxabi_static_lib.?.full_object_path); |
| 574 | hh.addBytes(comp.libcxx_static_lib.?.full_object_path); |
| 575 | } |
| 576 | hh.addListOfBytes(self.base.options.lib_dirs); |
| 577 | hh.addListOfBytes(self.base.options.framework_dirs); |
| 578 | hh.addListOfBytes(self.base.options.frameworks); |
| 579 | hh.addListOfBytes(self.base.options.rpath_list); |
| 580 | hh.addStringSet(self.base.options.system_libs); |
| 581 | hh.addOptionalBytes(self.base.options.sysroot); |
| 582 | const new_digest = hh.final(); |
| 583 | const needs_full_relink = !mem.eql(u8, &new_digest, &self.args_digest); |
| 584 | mem.copy(u8, &self.args_digest, &new_digest); |
| 585 | break :blk needs_full_relink; |
| 586 | }; |
| 562 | 587 | |
| 563 | | for (comp.c_object_table.keys()) |key| { |
| 564 | | try positionals.append(key.status.success.object_path); |
| 565 | | } |
| 588 | if (needs_full_relink) { |
| 589 | self.objects.clearRetainingCapacity(); |
| 590 | self.archives.clearRetainingCapacity(); |
| 591 | self.dylibs.clearRetainingCapacity(); |
| 592 | self.dylibs_map.clearRetainingCapacity(); |
| 593 | self.referenced_dylibs.clearRetainingCapacity(); |
| 566 | 594 | |
| 567 | | if (module_obj_path) |p| { |
| 568 | | try positionals.append(p); |
| 569 | | } |
| 595 | // TODO figure out how to clear atoms from objects, etc. |
| 570 | 596 | |
| 571 | | if (comp.compiler_rt_static_lib) |lib| { |
| 572 | | try positionals.append(lib.full_object_path); |
| 573 | | } |
| 597 | // Positional arguments to the linker such as object files and static archives. |
| 598 | var positionals = std.ArrayList([]const u8).init(arena); |
| 574 | 599 | |
| 575 | | // libc++ dep |
| 576 | | if (self.base.options.link_libcpp) { |
| 577 | | try positionals.append(comp.libcxxabi_static_lib.?.full_object_path); |
| 578 | | try positionals.append(comp.libcxx_static_lib.?.full_object_path); |
| 579 | | } |
| 600 | try positionals.appendSlice(self.base.options.objects); |
| 580 | 601 | |
| 581 | | // Shared and static libraries passed via `-l` flag. |
| 582 | | var search_lib_names = std.ArrayList([]const u8).init(arena); |
| 602 | for (comp.c_object_table.keys()) |key| { |
| 603 | try positionals.append(key.status.success.object_path); |
| 604 | } |
| 583 | 605 | |
| 584 | | const system_libs = self.base.options.system_libs.keys(); |
| 585 | | for (system_libs) |link_lib| { |
| 586 | | // By this time, we depend on these libs being dynamically linked libraries and not static libraries |
| 587 | | // (the check for that needs to be earlier), but they could be full paths to .dylib files, in which |
| 588 | | // case we want to avoid prepending "-l". |
| 589 | | if (Compilation.classifyFileExt(link_lib) == .shared_library) { |
| 590 | | try positionals.append(link_lib); |
| 591 | | continue; |
| 606 | if (module_obj_path) |p| { |
| 607 | try positionals.append(p); |
| 592 | 608 | } |
| 593 | 609 | |
| 594 | | try search_lib_names.append(link_lib); |
| 595 | | } |
| 610 | if (comp.compiler_rt_static_lib) |lib| { |
| 611 | try positionals.append(lib.full_object_path); |
| 612 | } |
| 596 | 613 | |
| 597 | | var lib_dirs = std.ArrayList([]const u8).init(arena); |
| 598 | | for (self.base.options.lib_dirs) |dir| { |
| 599 | | if (try resolveSearchDir(arena, dir, self.base.options.sysroot)) |search_dir| { |
| 600 | | try lib_dirs.append(search_dir); |
| 601 | | } else { |
| 602 | | log.warn("directory not found for '-L{s}'", .{dir}); |
| 614 | // libc++ dep |
| 615 | if (self.base.options.link_libcpp) { |
| 616 | try positionals.append(comp.libcxxabi_static_lib.?.full_object_path); |
| 617 | try positionals.append(comp.libcxx_static_lib.?.full_object_path); |
| 603 | 618 | } |
| 604 | | } |
| 605 | 619 | |
| 606 | | var libs = std.ArrayList([]const u8).init(arena); |
| 607 | | var lib_not_found = false; |
| 608 | | for (search_lib_names.items) |lib_name| { |
| 609 | | // Assume ld64 default: -search_paths_first |
| 610 | | // Look in each directory for a dylib (stub first), and then for archive |
| 611 | | // TODO implement alternative: -search_dylibs_first |
| 612 | | for (&[_][]const u8{ ".tbd", ".dylib", ".a" }) |ext| { |
| 613 | | if (try resolveLib(arena, lib_dirs.items, lib_name, ext)) |full_path| { |
| 614 | | try libs.append(full_path); |
| 615 | | break; |
| 620 | // Shared and static libraries passed via `-l` flag. |
| 621 | var search_lib_names = std.ArrayList([]const u8).init(arena); |
| 622 | |
| 623 | const system_libs = self.base.options.system_libs.keys(); |
| 624 | for (system_libs) |link_lib| { |
| 625 | // By this time, we depend on these libs being dynamically linked libraries and not static libraries |
| 626 | // (the check for that needs to be earlier), but they could be full paths to .dylib files, in which |
| 627 | // case we want to avoid prepending "-l". |
| 628 | if (Compilation.classifyFileExt(link_lib) == .shared_library) { |
| 629 | try positionals.append(link_lib); |
| 630 | continue; |
| 616 | 631 | } |
| 617 | | } else { |
| 618 | | log.warn("library not found for '-l{s}'", .{lib_name}); |
| 619 | | lib_not_found = true; |
| 632 | |
| 633 | try search_lib_names.append(link_lib); |
| 620 | 634 | } |
| 621 | | } |
| 622 | 635 | |
| 623 | | if (lib_not_found) { |
| 624 | | log.warn("Library search paths:", .{}); |
| 625 | | for (lib_dirs.items) |dir| { |
| 626 | | log.warn(" {s}", .{dir}); |
| 636 | var lib_dirs = std.ArrayList([]const u8).init(arena); |
| 637 | for (self.base.options.lib_dirs) |dir| { |
| 638 | if (try resolveSearchDir(arena, dir, self.base.options.sysroot)) |search_dir| { |
| 639 | try lib_dirs.append(search_dir); |
| 640 | } else { |
| 641 | log.warn("directory not found for '-L{s}'", .{dir}); |
| 642 | } |
| 627 | 643 | } |
| 628 | | } |
| 629 | 644 | |
| 630 | | // If we were given the sysroot, try to look there first for libSystem.B.{dylib, tbd}. |
| 631 | | var libsystem_available = false; |
| 632 | | if (self.base.options.sysroot != null) blk: { |
| 633 | | // Try stub file first. If we hit it, then we're done as the stub file |
| 634 | | // re-exports every single symbol definition. |
| 635 | | if (try resolveLib(arena, lib_dirs.items, "System", ".tbd")) |full_path| { |
| 636 | | try libs.append(full_path); |
| 637 | | libsystem_available = true; |
| 638 | | break :blk; |
| 645 | var libs = std.ArrayList([]const u8).init(arena); |
| 646 | var lib_not_found = false; |
| 647 | for (search_lib_names.items) |lib_name| { |
| 648 | // Assume ld64 default: -search_paths_first |
| 649 | // Look in each directory for a dylib (stub first), and then for archive |
| 650 | // TODO implement alternative: -search_dylibs_first |
| 651 | for (&[_][]const u8{ ".tbd", ".dylib", ".a" }) |ext| { |
| 652 | if (try resolveLib(arena, lib_dirs.items, lib_name, ext)) |full_path| { |
| 653 | try libs.append(full_path); |
| 654 | break; |
| 655 | } |
| 656 | } else { |
| 657 | log.warn("library not found for '-l{s}'", .{lib_name}); |
| 658 | lib_not_found = true; |
| 659 | } |
| 639 | 660 | } |
| 640 | | // If we didn't hit the stub file, try .dylib next. However, libSystem.dylib |
| 641 | | // doesn't export libc.dylib which we'll need to resolve subsequently also. |
| 642 | | if (try resolveLib(arena, lib_dirs.items, "System", ".dylib")) |libsystem_path| { |
| 643 | | if (try resolveLib(arena, lib_dirs.items, "c", ".dylib")) |libc_path| { |
| 644 | | try libs.append(libsystem_path); |
| 645 | | try libs.append(libc_path); |
| 661 | |
| 662 | if (lib_not_found) { |
| 663 | log.warn("Library search paths:", .{}); |
| 664 | for (lib_dirs.items) |dir| { |
| 665 | log.warn(" {s}", .{dir}); |
| 666 | } |
| 667 | } |
| 668 | |
| 669 | // If we were given the sysroot, try to look there first for libSystem.B.{dylib, tbd}. |
| 670 | var libsystem_available = false; |
| 671 | if (self.base.options.sysroot != null) blk: { |
| 672 | // Try stub file first. If we hit it, then we're done as the stub file |
| 673 | // re-exports every single symbol definition. |
| 674 | if (try resolveLib(arena, lib_dirs.items, "System", ".tbd")) |full_path| { |
| 675 | try libs.append(full_path); |
| 646 | 676 | libsystem_available = true; |
| 647 | 677 | break :blk; |
| 648 | 678 | } |
| 679 | // If we didn't hit the stub file, try .dylib next. However, libSystem.dylib |
| 680 | // doesn't export libc.dylib which we'll need to resolve subsequently also. |
| 681 | if (try resolveLib(arena, lib_dirs.items, "System", ".dylib")) |libsystem_path| { |
| 682 | if (try resolveLib(arena, lib_dirs.items, "c", ".dylib")) |libc_path| { |
| 683 | try libs.append(libsystem_path); |
| 684 | try libs.append(libc_path); |
| 685 | libsystem_available = true; |
| 686 | break :blk; |
| 687 | } |
| 688 | } |
| 689 | } |
| 690 | if (!libsystem_available) { |
| 691 | const full_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ |
| 692 | "libc", "darwin", "libSystem.B.tbd", |
| 693 | }); |
| 694 | try libs.append(full_path); |
| 649 | 695 | } |
| 650 | | } |
| 651 | | if (!libsystem_available) { |
| 652 | | const full_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ |
| 653 | | "libc", "darwin", "libSystem.B.tbd", |
| 654 | | }); |
| 655 | | try libs.append(full_path); |
| 656 | | } |
| 657 | 696 | |
| 658 | | // frameworks |
| 659 | | var framework_dirs = std.ArrayList([]const u8).init(arena); |
| 660 | | for (self.base.options.framework_dirs) |dir| { |
| 661 | | if (try resolveSearchDir(arena, dir, self.base.options.sysroot)) |search_dir| { |
| 662 | | try framework_dirs.append(search_dir); |
| 663 | | } else { |
| 664 | | log.warn("directory not found for '-F{s}'", .{dir}); |
| 697 | // frameworks |
| 698 | var framework_dirs = std.ArrayList([]const u8).init(arena); |
| 699 | for (self.base.options.framework_dirs) |dir| { |
| 700 | if (try resolveSearchDir(arena, dir, self.base.options.sysroot)) |search_dir| { |
| 701 | try framework_dirs.append(search_dir); |
| 702 | } else { |
| 703 | log.warn("directory not found for '-F{s}'", .{dir}); |
| 704 | } |
| 665 | 705 | } |
| 666 | | } |
| 667 | 706 | |
| 668 | | var framework_not_found = false; |
| 669 | | for (self.base.options.frameworks) |framework| { |
| 670 | | for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| { |
| 671 | | if (try resolveFramework(arena, framework_dirs.items, framework, ext)) |full_path| { |
| 672 | | try libs.append(full_path); |
| 673 | | break; |
| 707 | var framework_not_found = false; |
| 708 | for (self.base.options.frameworks) |framework| { |
| 709 | for (&[_][]const u8{ ".tbd", ".dylib", "" }) |ext| { |
| 710 | if (try resolveFramework(arena, framework_dirs.items, framework, ext)) |full_path| { |
| 711 | try libs.append(full_path); |
| 712 | break; |
| 713 | } |
| 714 | } else { |
| 715 | log.warn("framework not found for '-framework {s}'", .{framework}); |
| 716 | framework_not_found = true; |
| 674 | 717 | } |
| 675 | | } else { |
| 676 | | log.warn("framework not found for '-framework {s}'", .{framework}); |
| 677 | | framework_not_found = true; |
| 678 | 718 | } |
| 679 | | } |
| 680 | 719 | |
| 681 | | if (framework_not_found) { |
| 682 | | log.warn("Framework search paths:", .{}); |
| 683 | | for (framework_dirs.items) |dir| { |
| 684 | | log.warn(" {s}", .{dir}); |
| 720 | if (framework_not_found) { |
| 721 | log.warn("Framework search paths:", .{}); |
| 722 | for (framework_dirs.items) |dir| { |
| 723 | log.warn(" {s}", .{dir}); |
| 724 | } |
| 685 | 725 | } |
| 686 | | } |
| 687 | 726 | |
| 688 | | // rpaths |
| 689 | | var rpath_table = std.StringArrayHashMap(void).init(arena); |
| 690 | | for (self.base.options.rpath_list) |rpath| { |
| 691 | | if (rpath_table.contains(rpath)) continue; |
| 692 | | const cmdsize = @intCast(u32, mem.alignForwardGeneric( |
| 693 | | u64, |
| 694 | | @sizeOf(macho.rpath_command) + rpath.len + 1, |
| 695 | | @sizeOf(u64), |
| 696 | | )); |
| 697 | | var rpath_cmd = commands.emptyGenericCommandWithData(macho.rpath_command{ |
| 698 | | .cmd = macho.LC_RPATH, |
| 699 | | .cmdsize = cmdsize, |
| 700 | | .path = @sizeOf(macho.rpath_command), |
| 701 | | }); |
| 702 | | rpath_cmd.data = try self.base.allocator.alloc(u8, cmdsize - rpath_cmd.inner.path); |
| 703 | | mem.set(u8, rpath_cmd.data, 0); |
| 704 | | mem.copy(u8, rpath_cmd.data, rpath); |
| 705 | | try self.load_commands.append(self.base.allocator, .{ .Rpath = rpath_cmd }); |
| 706 | | try rpath_table.putNoClobber(rpath, {}); |
| 707 | | self.load_commands_dirty = true; |
| 708 | | } |
| 727 | // rpaths |
| 728 | var rpath_table = std.StringArrayHashMap(void).init(arena); |
| 729 | for (self.base.options.rpath_list) |rpath| { |
| 730 | if (rpath_table.contains(rpath)) continue; |
| 731 | const cmdsize = @intCast(u32, mem.alignForwardGeneric( |
| 732 | u64, |
| 733 | @sizeOf(macho.rpath_command) + rpath.len + 1, |
| 734 | @sizeOf(u64), |
| 735 | )); |
| 736 | var rpath_cmd = commands.emptyGenericCommandWithData(macho.rpath_command{ |
| 737 | .cmd = macho.LC_RPATH, |
| 738 | .cmdsize = cmdsize, |
| 739 | .path = @sizeOf(macho.rpath_command), |
| 740 | }); |
| 741 | rpath_cmd.data = try self.base.allocator.alloc(u8, cmdsize - rpath_cmd.inner.path); |
| 742 | mem.set(u8, rpath_cmd.data, 0); |
| 743 | mem.copy(u8, rpath_cmd.data, rpath); |
| 744 | try self.load_commands.append(self.base.allocator, .{ .Rpath = rpath_cmd }); |
| 745 | try rpath_table.putNoClobber(rpath, {}); |
| 746 | self.load_commands_dirty = true; |
| 747 | } |
| 709 | 748 | |
| 710 | | if (self.base.options.verbose_link) { |
| 711 | | var argv = std.ArrayList([]const u8).init(arena); |
| 749 | if (self.base.options.verbose_link) { |
| 750 | var argv = std.ArrayList([]const u8).init(arena); |
| 712 | 751 | |
| 713 | | try argv.append("zig"); |
| 714 | | try argv.append("ld"); |
| 752 | try argv.append("zig"); |
| 753 | try argv.append("ld"); |
| 715 | 754 | |
| 716 | | if (is_exe_or_dyn_lib) { |
| 717 | | try argv.append("-dynamic"); |
| 718 | | } |
| 755 | if (is_exe_or_dyn_lib) { |
| 756 | try argv.append("-dynamic"); |
| 757 | } |
| 719 | 758 | |
| 720 | | if (is_dyn_lib) { |
| 721 | | try argv.append("-dylib"); |
| 759 | if (is_dyn_lib) { |
| 760 | try argv.append("-dylib"); |
| 722 | 761 | |
| 723 | | const install_name = try std.fmt.allocPrint(arena, "@rpath/{s}", .{ |
| 724 | | self.base.options.emit.?.sub_path, |
| 725 | | }); |
| 726 | | try argv.append("-install_name"); |
| 727 | | try argv.append(install_name); |
| 728 | | } |
| 762 | const install_name = try std.fmt.allocPrint(arena, "@rpath/{s}", .{ |
| 763 | self.base.options.emit.?.sub_path, |
| 764 | }); |
| 765 | try argv.append("-install_name"); |
| 766 | try argv.append(install_name); |
| 767 | } |
| 729 | 768 | |
| 730 | | if (self.base.options.sysroot) |syslibroot| { |
| 731 | | try argv.append("-syslibroot"); |
| 732 | | try argv.append(syslibroot); |
| 733 | | } |
| 769 | if (self.base.options.sysroot) |syslibroot| { |
| 770 | try argv.append("-syslibroot"); |
| 771 | try argv.append(syslibroot); |
| 772 | } |
| 734 | 773 | |
| 735 | | for (rpath_table.keys()) |rpath| { |
| 736 | | try argv.append("-rpath"); |
| 737 | | try argv.append(rpath); |
| 738 | | } |
| 774 | for (rpath_table.keys()) |rpath| { |
| 775 | try argv.append("-rpath"); |
| 776 | try argv.append(rpath); |
| 777 | } |
| 739 | 778 | |
| 740 | | try argv.appendSlice(positionals.items); |
| 779 | try argv.appendSlice(positionals.items); |
| 741 | 780 | |
| 742 | | try argv.append("-o"); |
| 743 | | try argv.append(full_out_path); |
| 781 | try argv.append("-o"); |
| 782 | try argv.append(full_out_path); |
| 744 | 783 | |
| 745 | | try argv.append("-lSystem"); |
| 746 | | try argv.append("-lc"); |
| 784 | try argv.append("-lSystem"); |
| 785 | try argv.append("-lc"); |
| 747 | 786 | |
| 748 | | for (search_lib_names.items) |l_name| { |
| 749 | | try argv.append(try std.fmt.allocPrint(arena, "-l{s}", .{l_name})); |
| 750 | | } |
| 787 | for (search_lib_names.items) |l_name| { |
| 788 | try argv.append(try std.fmt.allocPrint(arena, "-l{s}", .{l_name})); |
| 789 | } |
| 751 | 790 | |
| 752 | | for (self.base.options.lib_dirs) |lib_dir| { |
| 753 | | try argv.append(try std.fmt.allocPrint(arena, "-L{s}", .{lib_dir})); |
| 754 | | } |
| 791 | for (self.base.options.lib_dirs) |lib_dir| { |
| 792 | try argv.append(try std.fmt.allocPrint(arena, "-L{s}", .{lib_dir})); |
| 793 | } |
| 755 | 794 | |
| 756 | | for (self.base.options.frameworks) |framework| { |
| 757 | | try argv.append(try std.fmt.allocPrint(arena, "-framework {s}", .{framework})); |
| 758 | | } |
| 795 | for (self.base.options.frameworks) |framework| { |
| 796 | try argv.append(try std.fmt.allocPrint(arena, "-framework {s}", .{framework})); |
| 797 | } |
| 759 | 798 | |
| 760 | | for (self.base.options.framework_dirs) |framework_dir| { |
| 761 | | try argv.append(try std.fmt.allocPrint(arena, "-F{s}", .{framework_dir})); |
| 799 | for (self.base.options.framework_dirs) |framework_dir| { |
| 800 | try argv.append(try std.fmt.allocPrint(arena, "-F{s}", .{framework_dir})); |
| 801 | } |
| 802 | |
| 803 | Compilation.dump_argv(argv.items); |
| 762 | 804 | } |
| 763 | 805 | |
| 764 | | Compilation.dump_argv(argv.items); |
| 806 | try self.parseInputFiles(positionals.items, self.base.options.sysroot); |
| 807 | try self.parseLibs(libs.items, self.base.options.sysroot); |
| 765 | 808 | } |
| 766 | 809 | |
| 767 | | try self.parseInputFiles(positionals.items, self.base.options.sysroot); |
| 768 | | try self.parseLibs(libs.items, self.base.options.sysroot); |
| 769 | | |
| 770 | 810 | if (self.bss_section_index) |idx| { |
| 771 | 811 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 772 | 812 | const sect = &seg.sections.items[idx]; |
| ... | ... | @@ -778,7 +818,8 @@ pub fn flush(self: *MachO, comp: *Compilation) !void { |
| 778 | 818 | sect.offset = self.tlv_bss_file_offset; |
| 779 | 819 | } |
| 780 | 820 | |
| 781 | | for (self.objects.items) |_, object_id| { |
| 821 | for (self.objects.items) |*object, object_id| { |
| 822 | if (object.analyzed) continue; |
| 782 | 823 | try self.resolveSymbolsInObject(@intCast(u16, object_id)); |
| 783 | 824 | } |
| 784 | 825 | |
| ... | ... | @@ -2617,6 +2658,8 @@ fn parseObjectsIntoAtoms(self: *MachO) !void { |
| 2617 | 2658 | defer section_metadata.deinit(); |
| 2618 | 2659 | |
| 2619 | 2660 | for (self.objects.items) |*object, object_id| { |
| 2661 | if (object.analyzed) continue; |
| 2662 | |
| 2620 | 2663 | var atoms_in_objects = try object.parseIntoAtoms(self.base.allocator, @intCast(u16, object_id), self); |
| 2621 | 2664 | defer atoms_in_objects.deinit(); |
| 2622 | 2665 | |
| ... | ... | @@ -2663,6 +2706,8 @@ fn parseObjectsIntoAtoms(self: *MachO) !void { |
| 2663 | 2706 | try first_atoms.putNoClobber(match, atom); |
| 2664 | 2707 | } |
| 2665 | 2708 | } |
| 2709 | |
| 2710 | object.analyzed = true; |
| 2666 | 2711 | } |
| 2667 | 2712 | |
| 2668 | 2713 | var it = section_metadata.iterator(); |
| ... | ... | @@ -3003,6 +3048,12 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv |
| 3003 | 3048 | defer tracy.end(); |
| 3004 | 3049 | |
| 3005 | 3050 | const decl = func.owner_decl; |
| 3051 | // TODO clearing the code and relocs buffer should probably be orchestrated |
| 3052 | // in a different, smarter, more automatic way somewhere else, in a more centralised |
| 3053 | // way than this. |
| 3054 | // If we don't clear the buffers here, we are up for some nasty surprises when |
| 3055 | // this atom is reused later on and was not freed by freeAtom(). |
| 3056 | decl.link.macho.clearRetainingCapacity(); |
| 3006 | 3057 | |
| 3007 | 3058 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); |
| 3008 | 3059 | defer code_buffer.deinit(); |
| ... | ... | @@ -3038,12 +3089,6 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv |
| 3038 | 3089 | try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .none); |
| 3039 | 3090 | switch (res) { |
| 3040 | 3091 | .appended => { |
| 3041 | | // TODO clearing the code and relocs buffer should probably be orchestrated |
| 3042 | | // in a different, smarter, more automatic way somewhere else, in a more centralised |
| 3043 | | // way than this. |
| 3044 | | // If we don't clear the buffers here, we are up for some nasty surprises when |
| 3045 | | // this atom is reused later on and was not freed by freeAtom(). |
| 3046 | | decl.link.macho.code.clearAndFree(self.base.allocator); |
| 3047 | 3092 | try decl.link.macho.code.appendSlice(self.base.allocator, code_buffer.items); |
| 3048 | 3093 | }, |
| 3049 | 3094 | .fail => |em| { |
| ... | ... | @@ -3194,6 +3239,7 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64 |
| 3194 | 3239 | }); |
| 3195 | 3240 | } |
| 3196 | 3241 | decl.link.macho.size = code_len; |
| 3242 | decl.link.macho.dirty = true; |
| 3197 | 3243 | |
| 3198 | 3244 | const new_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{mem.spanZ(decl.name)}); |
| 3199 | 3245 | defer self.base.allocator.free(new_name); |