| ... | ... | @@ -386,6 +386,36 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio |
| 386 | 386 | try self.populateMissingMetadata(); |
| 387 | 387 | try self.writeLocalSymbol(0); |
| 388 | 388 | |
| 389 | if (!self.strtab_dir.containsAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{ |
| 390 | .strtab = &self.strtab, |
| 391 | })) { |
| 392 | const import_sym_index = @intCast(u32, self.undefs.items.len); |
| 393 | const n_strx = try self.makeString("dyld_stub_binder"); |
| 394 | try self.undefs.append(self.base.allocator, .{ |
| 395 | .n_strx = n_strx, |
| 396 | .n_type = macho.N_UNDF | macho.N_EXT, |
| 397 | .n_sect = 0, |
| 398 | .n_desc = @intCast(u8, 1) * macho.N_SYMBOL_RESOLVER, |
| 399 | .n_value = 0, |
| 400 | }); |
| 401 | try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{ |
| 402 | .where = .undef, |
| 403 | .where_index = import_sym_index, |
| 404 | }); |
| 405 | const got_key = GotIndirectionKey{ |
| 406 | .where = .undef, |
| 407 | .where_index = import_sym_index, |
| 408 | }; |
| 409 | const got_index = @intCast(u32, self.got_entries.items.len); |
| 410 | try self.got_entries.append(self.base.allocator, got_key); |
| 411 | try self.got_entries_map.putNoClobber(self.base.allocator, got_key, got_index); |
| 412 | try self.writeGotEntry(got_index); |
| 413 | self.binding_info_dirty = true; |
| 414 | } |
| 415 | if (self.stub_helper_stubs_start_off == null) { |
| 416 | try self.writeStubHelperPreamble(); |
| 417 | } |
| 418 | |
| 389 | 419 | if (self.d_sym) |*ds| { |
| 390 | 420 | try ds.populateMissingMetadata(allocator); |
| 391 | 421 | try ds.writeLocalSymbol(0); |
| ... | ... | @@ -556,7 +586,7 @@ pub fn flush(self: *MachO, comp: *Compilation) !void { |
| 556 | 586 | .read = true, |
| 557 | 587 | .mode = link.determineMode(self.base.options), |
| 558 | 588 | }); |
| 559 | | try self.populateMetadata(); |
| 589 | try self.populateMissingMetadata(); |
| 560 | 590 | |
| 561 | 591 | // TODO mimicking insertion of null symbol from incremental linker. |
| 562 | 592 | // This will need to moved. |
| ... | ... | @@ -798,6 +828,17 @@ pub fn flush(self: *MachO, comp: *Compilation) !void { |
| 798 | 828 | try self.allocateTextBlocks(); |
| 799 | 829 | try self.flushZld(); |
| 800 | 830 | } else { |
| 831 | // TODO this is just a temp; libsystem load command will be autoresolved when parsing libSystem from |
| 832 | // the linker line and actually referencing symbols. |
| 833 | if (self.libsystem_cmd_index == null) { |
| 834 | self.libsystem_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 835 | var dylib_cmd = try commands.createLoadDylibCommand(self.base.allocator, mem.spanZ(LIB_SYSTEM_PATH), 2, 0, 0); |
| 836 | errdefer dylib_cmd.deinit(self.base.allocator); |
| 837 | try self.load_commands.append(self.base.allocator, .{ .Dylib = dylib_cmd }); |
| 838 | self.load_commands_dirty = true; |
| 839 | } |
| 840 | try self.addDataInCodeLC(); |
| 841 | try self.addCodeSignatureLC(); |
| 801 | 842 | try self.flushModule(comp); |
| 802 | 843 | } |
| 803 | 844 | } |
| ... | ... | @@ -2503,328 +2544,6 @@ fn parseTextBlocks(self: *MachO) !void { |
| 2503 | 2544 | } |
| 2504 | 2545 | } |
| 2505 | 2546 | |
| 2506 | | fn populateMetadata(self: *MachO) !void { |
| 2507 | | if (self.pagezero_segment_cmd_index == null) { |
| 2508 | | self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2509 | | try self.load_commands.append(self.base.allocator, .{ |
| 2510 | | .Segment = SegmentCommand.empty("__PAGEZERO", .{ |
| 2511 | | .vmsize = 0x100000000, // size always set to 4GB |
| 2512 | | }), |
| 2513 | | }); |
| 2514 | | } |
| 2515 | | |
| 2516 | | if (self.text_segment_cmd_index == null) { |
| 2517 | | self.text_segment_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2518 | | try self.load_commands.append(self.base.allocator, .{ |
| 2519 | | .Segment = SegmentCommand.empty("__TEXT", .{ |
| 2520 | | .vmaddr = 0x100000000, // always starts at 4GB |
| 2521 | | .maxprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE, |
| 2522 | | .initprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE, |
| 2523 | | }), |
| 2524 | | }); |
| 2525 | | } |
| 2526 | | |
| 2527 | | if (self.text_section_index == null) { |
| 2528 | | const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 2529 | | self.text_section_index = @intCast(u16, text_seg.sections.items.len); |
| 2530 | | const alignment: u2 = switch (self.base.options.target.cpu.arch) { |
| 2531 | | .x86_64 => 0, |
| 2532 | | .aarch64 => 2, |
| 2533 | | else => unreachable, // unhandled architecture type |
| 2534 | | }; |
| 2535 | | try text_seg.addSection(self.base.allocator, "__text", .{ |
| 2536 | | .@"align" = alignment, |
| 2537 | | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 2538 | | }); |
| 2539 | | _ = try self.section_ordinals.getOrPut(self.base.allocator, .{ |
| 2540 | | .seg = self.text_segment_cmd_index.?, |
| 2541 | | .sect = self.text_section_index.?, |
| 2542 | | }); |
| 2543 | | } |
| 2544 | | |
| 2545 | | if (self.stubs_section_index == null) { |
| 2546 | | const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 2547 | | self.stubs_section_index = @intCast(u16, text_seg.sections.items.len); |
| 2548 | | const alignment: u2 = switch (self.base.options.target.cpu.arch) { |
| 2549 | | .x86_64 => 0, |
| 2550 | | .aarch64 => 2, |
| 2551 | | else => unreachable, // unhandled architecture type |
| 2552 | | }; |
| 2553 | | const stub_size: u4 = switch (self.base.options.target.cpu.arch) { |
| 2554 | | .x86_64 => 6, |
| 2555 | | .aarch64 => 3 * @sizeOf(u32), |
| 2556 | | else => unreachable, // unhandled architecture type |
| 2557 | | }; |
| 2558 | | try text_seg.addSection(self.base.allocator, "__stubs", .{ |
| 2559 | | .@"align" = alignment, |
| 2560 | | .flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 2561 | | .reserved2 = stub_size, |
| 2562 | | }); |
| 2563 | | _ = try self.section_ordinals.getOrPut(self.base.allocator, .{ |
| 2564 | | .seg = self.text_segment_cmd_index.?, |
| 2565 | | .sect = self.stubs_section_index.?, |
| 2566 | | }); |
| 2567 | | } |
| 2568 | | |
| 2569 | | if (self.stub_helper_section_index == null) { |
| 2570 | | const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 2571 | | self.stub_helper_section_index = @intCast(u16, text_seg.sections.items.len); |
| 2572 | | const alignment: u2 = switch (self.base.options.target.cpu.arch) { |
| 2573 | | .x86_64 => 0, |
| 2574 | | .aarch64 => 2, |
| 2575 | | else => unreachable, // unhandled architecture type |
| 2576 | | }; |
| 2577 | | const stub_helper_size: u6 = switch (self.base.options.target.cpu.arch) { |
| 2578 | | .x86_64 => 15, |
| 2579 | | .aarch64 => 6 * @sizeOf(u32), |
| 2580 | | else => unreachable, |
| 2581 | | }; |
| 2582 | | try text_seg.addSection(self.base.allocator, "__stub_helper", .{ |
| 2583 | | .size = stub_helper_size, |
| 2584 | | .@"align" = alignment, |
| 2585 | | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 2586 | | }); |
| 2587 | | _ = try self.section_ordinals.getOrPut(self.base.allocator, .{ |
| 2588 | | .seg = self.text_segment_cmd_index.?, |
| 2589 | | .sect = self.stub_helper_section_index.?, |
| 2590 | | }); |
| 2591 | | } |
| 2592 | | |
| 2593 | | if (self.data_const_segment_cmd_index == null) { |
| 2594 | | self.data_const_segment_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2595 | | try self.load_commands.append(self.base.allocator, .{ |
| 2596 | | .Segment = SegmentCommand.empty("__DATA_CONST", .{ |
| 2597 | | .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, |
| 2598 | | .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, |
| 2599 | | }), |
| 2600 | | }); |
| 2601 | | } |
| 2602 | | |
| 2603 | | if (self.got_section_index == null) { |
| 2604 | | const data_const_seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 2605 | | self.got_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| 2606 | | try data_const_seg.addSection(self.base.allocator, "__got", .{ |
| 2607 | | .@"align" = 3, // 2^3 = @sizeOf(u64) |
| 2608 | | .flags = macho.S_NON_LAZY_SYMBOL_POINTERS, |
| 2609 | | }); |
| 2610 | | _ = try self.section_ordinals.getOrPut(self.base.allocator, .{ |
| 2611 | | .seg = self.data_const_segment_cmd_index.?, |
| 2612 | | .sect = self.got_section_index.?, |
| 2613 | | }); |
| 2614 | | } |
| 2615 | | |
| 2616 | | if (self.data_segment_cmd_index == null) { |
| 2617 | | self.data_segment_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2618 | | try self.load_commands.append(self.base.allocator, .{ |
| 2619 | | .Segment = SegmentCommand.empty("__DATA", .{ |
| 2620 | | .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, |
| 2621 | | .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, |
| 2622 | | }), |
| 2623 | | }); |
| 2624 | | } |
| 2625 | | |
| 2626 | | if (self.la_symbol_ptr_section_index == null) { |
| 2627 | | const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 2628 | | self.la_symbol_ptr_section_index = @intCast(u16, data_seg.sections.items.len); |
| 2629 | | try data_seg.addSection(self.base.allocator, "__la_symbol_ptr", .{ |
| 2630 | | .@"align" = 3, // 2^3 = @sizeOf(u64) |
| 2631 | | .flags = macho.S_LAZY_SYMBOL_POINTERS, |
| 2632 | | }); |
| 2633 | | _ = try self.section_ordinals.getOrPut(self.base.allocator, .{ |
| 2634 | | .seg = self.data_segment_cmd_index.?, |
| 2635 | | .sect = self.la_symbol_ptr_section_index.?, |
| 2636 | | }); |
| 2637 | | } |
| 2638 | | |
| 2639 | | if (self.data_section_index == null) { |
| 2640 | | const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 2641 | | self.data_section_index = @intCast(u16, data_seg.sections.items.len); |
| 2642 | | try data_seg.addSection(self.base.allocator, "__data", .{ |
| 2643 | | .@"align" = 3, // 2^3 = @sizeOf(u64) |
| 2644 | | }); |
| 2645 | | _ = try self.section_ordinals.getOrPut(self.base.allocator, .{ |
| 2646 | | .seg = self.data_segment_cmd_index.?, |
| 2647 | | .sect = self.data_section_index.?, |
| 2648 | | }); |
| 2649 | | } |
| 2650 | | |
| 2651 | | if (self.linkedit_segment_cmd_index == null) { |
| 2652 | | self.linkedit_segment_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2653 | | try self.load_commands.append(self.base.allocator, .{ |
| 2654 | | .Segment = SegmentCommand.empty("__LINKEDIT", .{ |
| 2655 | | .maxprot = macho.VM_PROT_READ, |
| 2656 | | .initprot = macho.VM_PROT_READ, |
| 2657 | | }), |
| 2658 | | }); |
| 2659 | | } |
| 2660 | | |
| 2661 | | if (self.dyld_info_cmd_index == null) { |
| 2662 | | self.dyld_info_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2663 | | try self.load_commands.append(self.base.allocator, .{ |
| 2664 | | .DyldInfoOnly = .{ |
| 2665 | | .cmd = macho.LC_DYLD_INFO_ONLY, |
| 2666 | | .cmdsize = @sizeOf(macho.dyld_info_command), |
| 2667 | | .rebase_off = 0, |
| 2668 | | .rebase_size = 0, |
| 2669 | | .bind_off = 0, |
| 2670 | | .bind_size = 0, |
| 2671 | | .weak_bind_off = 0, |
| 2672 | | .weak_bind_size = 0, |
| 2673 | | .lazy_bind_off = 0, |
| 2674 | | .lazy_bind_size = 0, |
| 2675 | | .export_off = 0, |
| 2676 | | .export_size = 0, |
| 2677 | | }, |
| 2678 | | }); |
| 2679 | | } |
| 2680 | | |
| 2681 | | if (self.symtab_cmd_index == null) { |
| 2682 | | self.symtab_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2683 | | try self.load_commands.append(self.base.allocator, .{ |
| 2684 | | .Symtab = .{ |
| 2685 | | .cmd = macho.LC_SYMTAB, |
| 2686 | | .cmdsize = @sizeOf(macho.symtab_command), |
| 2687 | | .symoff = 0, |
| 2688 | | .nsyms = 0, |
| 2689 | | .stroff = 0, |
| 2690 | | .strsize = 0, |
| 2691 | | }, |
| 2692 | | }); |
| 2693 | | } |
| 2694 | | |
| 2695 | | if (self.dysymtab_cmd_index == null) { |
| 2696 | | self.dysymtab_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2697 | | try self.load_commands.append(self.base.allocator, .{ |
| 2698 | | .Dysymtab = .{ |
| 2699 | | .cmd = macho.LC_DYSYMTAB, |
| 2700 | | .cmdsize = @sizeOf(macho.dysymtab_command), |
| 2701 | | .ilocalsym = 0, |
| 2702 | | .nlocalsym = 0, |
| 2703 | | .iextdefsym = 0, |
| 2704 | | .nextdefsym = 0, |
| 2705 | | .iundefsym = 0, |
| 2706 | | .nundefsym = 0, |
| 2707 | | .tocoff = 0, |
| 2708 | | .ntoc = 0, |
| 2709 | | .modtaboff = 0, |
| 2710 | | .nmodtab = 0, |
| 2711 | | .extrefsymoff = 0, |
| 2712 | | .nextrefsyms = 0, |
| 2713 | | .indirectsymoff = 0, |
| 2714 | | .nindirectsyms = 0, |
| 2715 | | .extreloff = 0, |
| 2716 | | .nextrel = 0, |
| 2717 | | .locreloff = 0, |
| 2718 | | .nlocrel = 0, |
| 2719 | | }, |
| 2720 | | }); |
| 2721 | | } |
| 2722 | | |
| 2723 | | if (self.dylinker_cmd_index == null) { |
| 2724 | | self.dylinker_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2725 | | const cmdsize = @intCast(u32, mem.alignForwardGeneric( |
| 2726 | | u64, |
| 2727 | | @sizeOf(macho.dylinker_command) + mem.lenZ(DEFAULT_DYLD_PATH), |
| 2728 | | @sizeOf(u64), |
| 2729 | | )); |
| 2730 | | var dylinker_cmd = commands.emptyGenericCommandWithData(macho.dylinker_command{ |
| 2731 | | .cmd = macho.LC_LOAD_DYLINKER, |
| 2732 | | .cmdsize = cmdsize, |
| 2733 | | .name = @sizeOf(macho.dylinker_command), |
| 2734 | | }); |
| 2735 | | dylinker_cmd.data = try self.base.allocator.alloc(u8, cmdsize - dylinker_cmd.inner.name); |
| 2736 | | mem.set(u8, dylinker_cmd.data, 0); |
| 2737 | | mem.copy(u8, dylinker_cmd.data, mem.spanZ(DEFAULT_DYLD_PATH)); |
| 2738 | | try self.load_commands.append(self.base.allocator, .{ .Dylinker = dylinker_cmd }); |
| 2739 | | } |
| 2740 | | |
| 2741 | | if (self.main_cmd_index == null and self.base.options.output_mode == .Exe) { |
| 2742 | | self.main_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2743 | | try self.load_commands.append(self.base.allocator, .{ |
| 2744 | | .Main = .{ |
| 2745 | | .cmd = macho.LC_MAIN, |
| 2746 | | .cmdsize = @sizeOf(macho.entry_point_command), |
| 2747 | | .entryoff = 0x0, |
| 2748 | | .stacksize = 0, |
| 2749 | | }, |
| 2750 | | }); |
| 2751 | | } |
| 2752 | | |
| 2753 | | if (self.dylib_id_cmd_index == null and self.base.options.output_mode == .Lib) { |
| 2754 | | self.dylib_id_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2755 | | const install_name = try std.fmt.allocPrint(self.base.allocator, "@rpath/{s}", .{ |
| 2756 | | self.base.options.emit.?.sub_path, |
| 2757 | | }); |
| 2758 | | defer self.base.allocator.free(install_name); |
| 2759 | | var dylib_cmd = try commands.createLoadDylibCommand( |
| 2760 | | self.base.allocator, |
| 2761 | | install_name, |
| 2762 | | 2, |
| 2763 | | 0x10000, // TODO forward user-provided versions |
| 2764 | | 0x10000, |
| 2765 | | ); |
| 2766 | | errdefer dylib_cmd.deinit(self.base.allocator); |
| 2767 | | dylib_cmd.inner.cmd = macho.LC_ID_DYLIB; |
| 2768 | | try self.load_commands.append(self.base.allocator, .{ .Dylib = dylib_cmd }); |
| 2769 | | } |
| 2770 | | |
| 2771 | | if (self.source_version_cmd_index == null) { |
| 2772 | | self.source_version_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2773 | | try self.load_commands.append(self.base.allocator, .{ |
| 2774 | | .SourceVersion = .{ |
| 2775 | | .cmd = macho.LC_SOURCE_VERSION, |
| 2776 | | .cmdsize = @sizeOf(macho.source_version_command), |
| 2777 | | .version = 0x0, |
| 2778 | | }, |
| 2779 | | }); |
| 2780 | | } |
| 2781 | | |
| 2782 | | if (self.build_version_cmd_index == null) { |
| 2783 | | self.build_version_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2784 | | const cmdsize = @intCast(u32, mem.alignForwardGeneric( |
| 2785 | | u64, |
| 2786 | | @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version), |
| 2787 | | @sizeOf(u64), |
| 2788 | | )); |
| 2789 | | const ver = self.base.options.target.os.version_range.semver.min; |
| 2790 | | const version = ver.major << 16 | ver.minor << 8 | ver.patch; |
| 2791 | | const is_simulator_abi = self.base.options.target.abi == .simulator; |
| 2792 | | var cmd = commands.emptyGenericCommandWithData(macho.build_version_command{ |
| 2793 | | .cmd = macho.LC_BUILD_VERSION, |
| 2794 | | .cmdsize = cmdsize, |
| 2795 | | .platform = switch (self.base.options.target.os.tag) { |
| 2796 | | .macos => macho.PLATFORM_MACOS, |
| 2797 | | .ios => if (is_simulator_abi) macho.PLATFORM_IOSSIMULATOR else macho.PLATFORM_IOS, |
| 2798 | | .watchos => if (is_simulator_abi) macho.PLATFORM_WATCHOSSIMULATOR else macho.PLATFORM_WATCHOS, |
| 2799 | | .tvos => if (is_simulator_abi) macho.PLATFORM_TVOSSIMULATOR else macho.PLATFORM_TVOS, |
| 2800 | | else => unreachable, |
| 2801 | | }, |
| 2802 | | .minos = version, |
| 2803 | | .sdk = version, |
| 2804 | | .ntools = 1, |
| 2805 | | }); |
| 2806 | | const ld_ver = macho.build_tool_version{ |
| 2807 | | .tool = macho.TOOL_LD, |
| 2808 | | .version = 0x0, |
| 2809 | | }; |
| 2810 | | cmd.data = try self.base.allocator.alloc(u8, cmdsize - @sizeOf(macho.build_version_command)); |
| 2811 | | mem.set(u8, cmd.data, 0); |
| 2812 | | mem.copy(u8, cmd.data, mem.asBytes(&ld_ver)); |
| 2813 | | try self.load_commands.append(self.base.allocator, .{ .BuildVersion = cmd }); |
| 2814 | | } |
| 2815 | | |
| 2816 | | if (self.uuid_cmd_index == null) { |
| 2817 | | self.uuid_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 2818 | | var uuid_cmd: macho.uuid_command = .{ |
| 2819 | | .cmd = macho.LC_UUID, |
| 2820 | | .cmdsize = @sizeOf(macho.uuid_command), |
| 2821 | | .uuid = undefined, |
| 2822 | | }; |
| 2823 | | std.crypto.random.bytes(&uuid_cmd.uuid); |
| 2824 | | try self.load_commands.append(self.base.allocator, .{ .Uuid = uuid_cmd }); |
| 2825 | | } |
| 2826 | | } |
| 2827 | | |
| 2828 | 2547 | fn addDataInCodeLC(self: *MachO) !void { |
| 2829 | 2548 | if (self.data_in_code_cmd_index == null) { |
| 2830 | 2549 | self.data_in_code_cmd_index = @intCast(u16, self.load_commands.items.len); |
| ... | ... | @@ -4004,12 +3723,6 @@ pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl) u64 { |
| 4004 | 3723 | } |
| 4005 | 3724 | |
| 4006 | 3725 | pub fn populateMissingMetadata(self: *MachO) !void { |
| 4007 | | switch (self.base.options.output_mode) { |
| 4008 | | .Exe => {}, |
| 4009 | | .Obj => return error.TODOImplementWritingObjFiles, |
| 4010 | | .Lib => return error.TODOImplementWritingLibFiles, |
| 4011 | | } |
| 4012 | | |
| 4013 | 3726 | if (self.pagezero_segment_cmd_index == null) { |
| 4014 | 3727 | self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4015 | 3728 | try self.load_commands.append(self.base.allocator, .{ |
| ... | ... | @@ -4019,11 +3732,9 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4019 | 3732 | }); |
| 4020 | 3733 | self.load_commands_dirty = true; |
| 4021 | 3734 | } |
| 3735 | |
| 4022 | 3736 | if (self.text_segment_cmd_index == null) { |
| 4023 | 3737 | self.text_segment_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4024 | | const maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE | macho.VM_PROT_EXECUTE; |
| 4025 | | const initprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE; |
| 4026 | | |
| 4027 | 3738 | const program_code_size_hint = self.base.options.program_code_size_hint; |
| 4028 | 3739 | const got_size_hint = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4029 | 3740 | const ideal_size = self.header_pad + program_code_size_hint + 3 * got_size_hint; |
| ... | ... | @@ -4036,12 +3747,13 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4036 | 3747 | .vmaddr = 0x100000000, // always starts at 4GB |
| 4037 | 3748 | .vmsize = needed_size, |
| 4038 | 3749 | .filesize = needed_size, |
| 4039 | | .maxprot = maxprot, |
| 4040 | | .initprot = initprot, |
| 3750 | .maxprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE, |
| 3751 | .initprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE, |
| 4041 | 3752 | }), |
| 4042 | 3753 | }); |
| 4043 | 3754 | self.load_commands_dirty = true; |
| 4044 | 3755 | } |
| 3756 | |
| 4045 | 3757 | if (self.text_section_index == null) { |
| 4046 | 3758 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 4047 | 3759 | self.text_section_index = @intCast(u16, text_segment.sections.items.len); |
| ... | ... | @@ -4051,7 +3763,6 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4051 | 3763 | .aarch64 => 2, |
| 4052 | 3764 | else => unreachable, // unhandled architecture type |
| 4053 | 3765 | }; |
| 4054 | | const flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS; |
| 4055 | 3766 | const needed_size = self.base.options.program_code_size_hint; |
| 4056 | 3767 | const off = text_segment.findFreeSpace(needed_size, @as(u16, 1) << alignment, self.header_pad); |
| 4057 | 3768 | |
| ... | ... | @@ -4062,10 +3773,15 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4062 | 3773 | .size = @intCast(u32, needed_size), |
| 4063 | 3774 | .offset = @intCast(u32, off), |
| 4064 | 3775 | .@"align" = alignment, |
| 4065 | | .flags = flags, |
| 3776 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 3777 | }); |
| 3778 | _ = try self.section_ordinals.getOrPut(self.base.allocator, .{ |
| 3779 | .seg = self.text_segment_cmd_index.?, |
| 3780 | .sect = self.text_section_index.?, |
| 4066 | 3781 | }); |
| 4067 | 3782 | self.load_commands_dirty = true; |
| 4068 | 3783 | } |
| 3784 | |
| 4069 | 3785 | if (self.stubs_section_index == null) { |
| 4070 | 3786 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 4071 | 3787 | self.stubs_section_index = @intCast(u16, text_segment.sections.items.len); |
| ... | ... | @@ -4080,7 +3796,6 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4080 | 3796 | .aarch64 => 3 * @sizeOf(u32), |
| 4081 | 3797 | else => unreachable, // unhandled architecture type |
| 4082 | 3798 | }; |
| 4083 | | const flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS; |
| 4084 | 3799 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4085 | 3800 | const off = text_segment.findFreeSpace(needed_size, @alignOf(u64), self.header_pad); |
| 4086 | 3801 | assert(off + needed_size <= text_segment.inner.fileoff + text_segment.inner.filesize); // TODO Must expand __TEXT segment. |
| ... | ... | @@ -4092,11 +3807,16 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4092 | 3807 | .size = needed_size, |
| 4093 | 3808 | .offset = @intCast(u32, off), |
| 4094 | 3809 | .@"align" = alignment, |
| 4095 | | .flags = flags, |
| 3810 | .flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 4096 | 3811 | .reserved2 = stub_size, |
| 4097 | 3812 | }); |
| 3813 | _ = try self.section_ordinals.getOrPut(self.base.allocator, .{ |
| 3814 | .seg = self.text_segment_cmd_index.?, |
| 3815 | .sect = self.stubs_section_index.?, |
| 3816 | }); |
| 4098 | 3817 | self.load_commands_dirty = true; |
| 4099 | 3818 | } |
| 3819 | |
| 4100 | 3820 | if (self.stub_helper_section_index == null) { |
| 4101 | 3821 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 4102 | 3822 | self.stub_helper_section_index = @intCast(u16, text_segment.sections.items.len); |
| ... | ... | @@ -4106,7 +3826,6 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4106 | 3826 | .aarch64 => 2, |
| 4107 | 3827 | else => unreachable, // unhandled architecture type |
| 4108 | 3828 | }; |
| 4109 | | const flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS; |
| 4110 | 3829 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4111 | 3830 | const off = text_segment.findFreeSpace(needed_size, @alignOf(u64), self.header_pad); |
| 4112 | 3831 | assert(off + needed_size <= text_segment.inner.fileoff + text_segment.inner.filesize); // TODO Must expand __TEXT segment. |
| ... | ... | @@ -4118,16 +3837,18 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4118 | 3837 | .size = needed_size, |
| 4119 | 3838 | .offset = @intCast(u32, off), |
| 4120 | 3839 | .@"align" = alignment, |
| 4121 | | .flags = flags, |
| 3840 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 3841 | }); |
| 3842 | _ = try self.section_ordinals.getOrPut(self.base.allocator, .{ |
| 3843 | .seg = self.text_segment_cmd_index.?, |
| 3844 | .sect = self.stub_helper_section_index.?, |
| 4122 | 3845 | }); |
| 4123 | 3846 | self.load_commands_dirty = true; |
| 4124 | 3847 | } |
| 3848 | |
| 4125 | 3849 | if (self.data_const_segment_cmd_index == null) { |
| 4126 | 3850 | self.data_const_segment_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4127 | | const maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE | macho.VM_PROT_EXECUTE; |
| 4128 | | const initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE; |
| 4129 | 3851 | const address_and_offset = self.nextSegmentAddressAndOffset(); |
| 4130 | | |
| 4131 | 3852 | const ideal_size = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4132 | 3853 | const needed_size = mem.alignForwardGeneric(u64, padToIdeal(ideal_size), self.page_size); |
| 4133 | 3854 | |
| ... | ... | @@ -4139,17 +3860,17 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4139 | 3860 | .vmsize = needed_size, |
| 4140 | 3861 | .fileoff = address_and_offset.offset, |
| 4141 | 3862 | .filesize = needed_size, |
| 4142 | | .maxprot = maxprot, |
| 4143 | | .initprot = initprot, |
| 3863 | .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, |
| 3864 | .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, |
| 4144 | 3865 | }), |
| 4145 | 3866 | }); |
| 4146 | 3867 | self.load_commands_dirty = true; |
| 4147 | 3868 | } |
| 3869 | |
| 4148 | 3870 | if (self.got_section_index == null) { |
| 4149 | 3871 | const dc_segment = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 4150 | 3872 | self.got_section_index = @intCast(u16, dc_segment.sections.items.len); |
| 4151 | 3873 | |
| 4152 | | const flags = macho.S_NON_LAZY_SYMBOL_POINTERS; |
| 4153 | 3874 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4154 | 3875 | const off = dc_segment.findFreeSpace(needed_size, @alignOf(u64), null); |
| 4155 | 3876 | assert(off + needed_size <= dc_segment.inner.fileoff + dc_segment.inner.filesize); // TODO Must expand __DATA_CONST segment. |
| ... | ... | @@ -4161,16 +3882,18 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4161 | 3882 | .size = needed_size, |
| 4162 | 3883 | .offset = @intCast(u32, off), |
| 4163 | 3884 | .@"align" = 3, // 2^3 = @sizeOf(u64) |
| 4164 | | .flags = flags, |
| 3885 | .flags = macho.S_NON_LAZY_SYMBOL_POINTERS, |
| 3886 | }); |
| 3887 | _ = try self.section_ordinals.getOrPut(self.base.allocator, .{ |
| 3888 | .seg = self.data_const_segment_cmd_index.?, |
| 3889 | .sect = self.got_section_index.?, |
| 4165 | 3890 | }); |
| 4166 | 3891 | self.load_commands_dirty = true; |
| 4167 | 3892 | } |
| 3893 | |
| 4168 | 3894 | if (self.data_segment_cmd_index == null) { |
| 4169 | 3895 | self.data_segment_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4170 | | const maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE | macho.VM_PROT_EXECUTE; |
| 4171 | | const initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE; |
| 4172 | 3896 | const address_and_offset = self.nextSegmentAddressAndOffset(); |
| 4173 | | |
| 4174 | 3897 | const ideal_size = 2 * @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4175 | 3898 | const needed_size = mem.alignForwardGeneric(u64, padToIdeal(ideal_size), self.page_size); |
| 4176 | 3899 | |
| ... | ... | @@ -4182,17 +3905,17 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4182 | 3905 | .vmsize = needed_size, |
| 4183 | 3906 | .fileoff = address_and_offset.offset, |
| 4184 | 3907 | .filesize = needed_size, |
| 4185 | | .maxprot = maxprot, |
| 4186 | | .initprot = initprot, |
| 3908 | .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, |
| 3909 | .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, |
| 4187 | 3910 | }), |
| 4188 | 3911 | }); |
| 4189 | 3912 | self.load_commands_dirty = true; |
| 4190 | 3913 | } |
| 3914 | |
| 4191 | 3915 | if (self.la_symbol_ptr_section_index == null) { |
| 4192 | 3916 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 4193 | 3917 | self.la_symbol_ptr_section_index = @intCast(u16, data_segment.sections.items.len); |
| 4194 | 3918 | |
| 4195 | | const flags = macho.S_LAZY_SYMBOL_POINTERS; |
| 4196 | 3919 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4197 | 3920 | const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null); |
| 4198 | 3921 | assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment. |
| ... | ... | @@ -4204,10 +3927,15 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4204 | 3927 | .size = needed_size, |
| 4205 | 3928 | .offset = @intCast(u32, off), |
| 4206 | 3929 | .@"align" = 3, // 2^3 = @sizeOf(u64) |
| 4207 | | .flags = flags, |
| 3930 | .flags = macho.S_LAZY_SYMBOL_POINTERS, |
| 3931 | }); |
| 3932 | _ = try self.section_ordinals.getOrPut(self.base.allocator, .{ |
| 3933 | .seg = self.data_segment_cmd_index.?, |
| 3934 | .sect = self.la_symbol_ptr_section_index.?, |
| 4208 | 3935 | }); |
| 4209 | 3936 | self.load_commands_dirty = true; |
| 4210 | 3937 | } |
| 3938 | |
| 4211 | 3939 | if (self.data_section_index == null) { |
| 4212 | 3940 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 4213 | 3941 | self.data_section_index = @intCast(u16, data_segment.sections.items.len); |
| ... | ... | @@ -4224,13 +3952,15 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4224 | 3952 | .offset = @intCast(u32, off), |
| 4225 | 3953 | .@"align" = 3, // 2^3 = @sizeOf(u64) |
| 4226 | 3954 | }); |
| 3955 | _ = try self.section_ordinals.getOrPut(self.base.allocator, .{ |
| 3956 | .seg = self.data_segment_cmd_index.?, |
| 3957 | .sect = self.data_section_index.?, |
| 3958 | }); |
| 4227 | 3959 | self.load_commands_dirty = true; |
| 4228 | 3960 | } |
| 3961 | |
| 4229 | 3962 | if (self.linkedit_segment_cmd_index == null) { |
| 4230 | 3963 | self.linkedit_segment_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4231 | | |
| 4232 | | const maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE | macho.VM_PROT_EXECUTE; |
| 4233 | | const initprot = macho.VM_PROT_READ; |
| 4234 | 3964 | const address_and_offset = self.nextSegmentAddressAndOffset(); |
| 4235 | 3965 | |
| 4236 | 3966 | log.debug("found __LINKEDIT segment free space at 0x{x}", .{address_and_offset.offset}); |
| ... | ... | @@ -4239,12 +3969,13 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4239 | 3969 | .Segment = SegmentCommand.empty("__LINKEDIT", .{ |
| 4240 | 3970 | .vmaddr = address_and_offset.address, |
| 4241 | 3971 | .fileoff = address_and_offset.offset, |
| 4242 | | .maxprot = maxprot, |
| 4243 | | .initprot = initprot, |
| 3972 | .maxprot = macho.VM_PROT_READ, |
| 3973 | .initprot = macho.VM_PROT_READ, |
| 4244 | 3974 | }), |
| 4245 | 3975 | }); |
| 4246 | 3976 | self.load_commands_dirty = true; |
| 4247 | 3977 | } |
| 3978 | |
| 4248 | 3979 | if (self.dyld_info_cmd_index == null) { |
| 4249 | 3980 | self.dyld_info_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4250 | 3981 | |
| ... | ... | @@ -4291,6 +4022,7 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4291 | 4022 | |
| 4292 | 4023 | self.load_commands_dirty = true; |
| 4293 | 4024 | } |
| 4025 | |
| 4294 | 4026 | if (self.symtab_cmd_index == null) { |
| 4295 | 4027 | self.symtab_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4296 | 4028 | |
| ... | ... | @@ -4323,6 +4055,7 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4323 | 4055 | self.load_commands_dirty = true; |
| 4324 | 4056 | self.strtab_dirty = true; |
| 4325 | 4057 | } |
| 4058 | |
| 4326 | 4059 | if (self.dysymtab_cmd_index == null) { |
| 4327 | 4060 | self.dysymtab_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4328 | 4061 | |
| ... | ... | @@ -4358,6 +4091,7 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4358 | 4091 | }); |
| 4359 | 4092 | self.load_commands_dirty = true; |
| 4360 | 4093 | } |
| 4094 | |
| 4361 | 4095 | if (self.dylinker_cmd_index == null) { |
| 4362 | 4096 | self.dylinker_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4363 | 4097 | const cmdsize = @intCast(u32, mem.alignForwardGeneric( |
| ... | ... | @@ -4376,17 +4110,8 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4376 | 4110 | try self.load_commands.append(self.base.allocator, .{ .Dylinker = dylinker_cmd }); |
| 4377 | 4111 | self.load_commands_dirty = true; |
| 4378 | 4112 | } |
| 4379 | | if (self.libsystem_cmd_index == null) { |
| 4380 | | self.libsystem_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4381 | | |
| 4382 | | var dylib_cmd = try commands.createLoadDylibCommand(self.base.allocator, mem.spanZ(LIB_SYSTEM_PATH), 2, 0, 0); |
| 4383 | | errdefer dylib_cmd.deinit(self.base.allocator); |
| 4384 | | |
| 4385 | | try self.load_commands.append(self.base.allocator, .{ .Dylib = dylib_cmd }); |
| 4386 | 4113 | |
| 4387 | | self.load_commands_dirty = true; |
| 4388 | | } |
| 4389 | | if (self.main_cmd_index == null) { |
| 4114 | if (self.main_cmd_index == null and self.base.options.output_mode == .Exe) { |
| 4390 | 4115 | self.main_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4391 | 4116 | try self.load_commands.append(self.base.allocator, .{ |
| 4392 | 4117 | .Main = .{ |
| ... | ... | @@ -4398,6 +4123,38 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4398 | 4123 | }); |
| 4399 | 4124 | self.load_commands_dirty = true; |
| 4400 | 4125 | } |
| 4126 | |
| 4127 | if (self.dylib_id_cmd_index == null and self.base.options.output_mode == .Lib) { |
| 4128 | self.dylib_id_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4129 | const install_name = try std.fmt.allocPrint(self.base.allocator, "@rpath/{s}", .{ |
| 4130 | self.base.options.emit.?.sub_path, |
| 4131 | }); |
| 4132 | defer self.base.allocator.free(install_name); |
| 4133 | var dylib_cmd = try commands.createLoadDylibCommand( |
| 4134 | self.base.allocator, |
| 4135 | install_name, |
| 4136 | 2, |
| 4137 | 0x10000, // TODO forward user-provided versions |
| 4138 | 0x10000, |
| 4139 | ); |
| 4140 | errdefer dylib_cmd.deinit(self.base.allocator); |
| 4141 | dylib_cmd.inner.cmd = macho.LC_ID_DYLIB; |
| 4142 | try self.load_commands.append(self.base.allocator, .{ .Dylib = dylib_cmd }); |
| 4143 | self.load_commands_dirty = true; |
| 4144 | } |
| 4145 | |
| 4146 | if (self.source_version_cmd_index == null) { |
| 4147 | self.source_version_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4148 | try self.load_commands.append(self.base.allocator, .{ |
| 4149 | .SourceVersion = .{ |
| 4150 | .cmd = macho.LC_SOURCE_VERSION, |
| 4151 | .cmdsize = @sizeOf(macho.source_version_command), |
| 4152 | .version = 0x0, |
| 4153 | }, |
| 4154 | }); |
| 4155 | self.load_commands_dirty = true; |
| 4156 | } |
| 4157 | |
| 4401 | 4158 | if (self.build_version_cmd_index == null) { |
| 4402 | 4159 | self.build_version_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4403 | 4160 | const cmdsize = @intCast(u32, mem.alignForwardGeneric( |
| ... | ... | @@ -4430,18 +4187,9 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4430 | 4187 | mem.set(u8, cmd.data, 0); |
| 4431 | 4188 | mem.copy(u8, cmd.data, mem.asBytes(&ld_ver)); |
| 4432 | 4189 | try self.load_commands.append(self.base.allocator, .{ .BuildVersion = cmd }); |
| 4433 | | } |
| 4434 | | if (self.source_version_cmd_index == null) { |
| 4435 | | self.source_version_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4436 | | try self.load_commands.append(self.base.allocator, .{ |
| 4437 | | .SourceVersion = .{ |
| 4438 | | .cmd = macho.LC_SOURCE_VERSION, |
| 4439 | | .cmdsize = @sizeOf(macho.source_version_command), |
| 4440 | | .version = 0x0, |
| 4441 | | }, |
| 4442 | | }); |
| 4443 | 4190 | self.load_commands_dirty = true; |
| 4444 | 4191 | } |
| 4192 | |
| 4445 | 4193 | if (self.uuid_cmd_index == null) { |
| 4446 | 4194 | self.uuid_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4447 | 4195 | var uuid_cmd: macho.uuid_command = .{ |
| ... | ... | @@ -4453,47 +4201,6 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4453 | 4201 | try self.load_commands.append(self.base.allocator, .{ .Uuid = uuid_cmd }); |
| 4454 | 4202 | self.load_commands_dirty = true; |
| 4455 | 4203 | } |
| 4456 | | if (self.code_signature_cmd_index == null and self.requires_adhoc_codesig) { |
| 4457 | | self.code_signature_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4458 | | try self.load_commands.append(self.base.allocator, .{ |
| 4459 | | .LinkeditData = .{ |
| 4460 | | .cmd = macho.LC_CODE_SIGNATURE, |
| 4461 | | .cmdsize = @sizeOf(macho.linkedit_data_command), |
| 4462 | | .dataoff = 0, |
| 4463 | | .datasize = 0, |
| 4464 | | }, |
| 4465 | | }); |
| 4466 | | self.load_commands_dirty = true; |
| 4467 | | } |
| 4468 | | if (!self.strtab_dir.containsAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{ |
| 4469 | | .strtab = &self.strtab, |
| 4470 | | })) { |
| 4471 | | const import_sym_index = @intCast(u32, self.undefs.items.len); |
| 4472 | | const n_strx = try self.makeString("dyld_stub_binder"); |
| 4473 | | try self.undefs.append(self.base.allocator, .{ |
| 4474 | | .n_strx = n_strx, |
| 4475 | | .n_type = macho.N_UNDF | macho.N_EXT, |
| 4476 | | .n_sect = 0, |
| 4477 | | .n_desc = @intCast(u8, 1) * macho.N_SYMBOL_RESOLVER, |
| 4478 | | .n_value = 0, |
| 4479 | | }); |
| 4480 | | try self.symbol_resolver.putNoClobber(self.base.allocator, n_strx, .{ |
| 4481 | | .where = .undef, |
| 4482 | | .where_index = import_sym_index, |
| 4483 | | }); |
| 4484 | | const got_key = GotIndirectionKey{ |
| 4485 | | .where = .undef, |
| 4486 | | .where_index = import_sym_index, |
| 4487 | | }; |
| 4488 | | const got_index = @intCast(u32, self.got_entries.items.len); |
| 4489 | | try self.got_entries.append(self.base.allocator, got_key); |
| 4490 | | try self.got_entries_map.putNoClobber(self.base.allocator, got_key, got_index); |
| 4491 | | try self.writeGotEntry(got_index); |
| 4492 | | self.binding_info_dirty = true; |
| 4493 | | } |
| 4494 | | if (self.stub_helper_stubs_start_off == null) { |
| 4495 | | try self.writeStubHelperPreamble(); |
| 4496 | | } |
| 4497 | 4204 | } |
| 4498 | 4205 | |
| 4499 | 4206 | fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 { |