| ... | @@ -386,6 +386,36 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio | ... | @@ -386,6 +386,36 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio |
| 386 | try self.populateMissingMetadata(); | 386 | try self.populateMissingMetadata(); |
| 387 | try self.writeLocalSymbol(0); | 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 | if (self.d_sym) |*ds| { | 419 | if (self.d_sym) |*ds| { |
| 390 | try ds.populateMissingMetadata(allocator); | 420 | try ds.populateMissingMetadata(allocator); |
| 391 | try ds.writeLocalSymbol(0); | 421 | try ds.writeLocalSymbol(0); |
| ... | @@ -556,7 +586,7 @@ pub fn flush(self: *MachO, comp: *Compilation) !void { | ... | @@ -556,7 +586,7 @@ pub fn flush(self: *MachO, comp: *Compilation) !void { |
| 556 | .read = true, | 586 | .read = true, |
| 557 | .mode = link.determineMode(self.base.options), | 587 | .mode = link.determineMode(self.base.options), |
| 558 | }); | 588 | }); |
| 559 | try self.populateMetadata(); | 589 | try self.populateMissingMetadata(); |
| 560 | | 590 | |
| 561 | // TODO mimicking insertion of null symbol from incremental linker. | 591 | // TODO mimicking insertion of null symbol from incremental linker. |
| 562 | // This will need to moved. | 592 | // This will need to moved. |
| ... | @@ -798,6 +828,17 @@ pub fn flush(self: *MachO, comp: *Compilation) !void { | ... | @@ -798,6 +828,17 @@ pub fn flush(self: *MachO, comp: *Compilation) !void { |
| 798 | try self.allocateTextBlocks(); | 828 | try self.allocateTextBlocks(); |
| 799 | try self.flushZld(); | 829 | try self.flushZld(); |
| 800 | } else { | 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 | try self.flushModule(comp); | 842 | try self.flushModule(comp); |
| 802 | } | 843 | } |
| 803 | } | 844 | } |
| ... | @@ -2503,328 +2544,6 @@ fn parseTextBlocks(self: *MachO) !void { | ... | @@ -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 | fn addDataInCodeLC(self: *MachO) !void { | 2547 | fn addDataInCodeLC(self: *MachO) !void { |
| 2829 | if (self.data_in_code_cmd_index == null) { | 2548 | if (self.data_in_code_cmd_index == null) { |
| 2830 | self.data_in_code_cmd_index = @intCast(u16, self.load_commands.items.len); | 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,12 +3723,6 @@ pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl) u64 { |
| 4004 | } | 3723 | } |
| 4005 | | 3724 | |
| 4006 | pub fn populateMissingMetadata(self: *MachO) !void { | 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 | if (self.pagezero_segment_cmd_index == null) { | 3726 | if (self.pagezero_segment_cmd_index == null) { |
| 4014 | self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len); | 3727 | self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4015 | try self.load_commands.append(self.base.allocator, .{ | 3728 | try self.load_commands.append(self.base.allocator, .{ |
| ... | @@ -4019,11 +3732,9 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4019,11 +3732,9 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4019 | }); | 3732 | }); |
| 4020 | self.load_commands_dirty = true; | 3733 | self.load_commands_dirty = true; |
| 4021 | } | 3734 | } |
| | 3735 | |
| 4022 | if (self.text_segment_cmd_index == null) { | 3736 | if (self.text_segment_cmd_index == null) { |
| 4023 | self.text_segment_cmd_index = @intCast(u16, self.load_commands.items.len); | 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 | const program_code_size_hint = self.base.options.program_code_size_hint; | 3738 | const program_code_size_hint = self.base.options.program_code_size_hint; |
| 4028 | const got_size_hint = @sizeOf(u64) * self.base.options.symbol_count_hint; | 3739 | const got_size_hint = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4029 | const ideal_size = self.header_pad + program_code_size_hint + 3 * got_size_hint; | 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,12 +3747,13 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4036 | .vmaddr = 0x100000000, // always starts at 4GB | 3747 | .vmaddr = 0x100000000, // always starts at 4GB |
| 4037 | .vmsize = needed_size, | 3748 | .vmsize = needed_size, |
| 4038 | .filesize = needed_size, | 3749 | .filesize = needed_size, |
| 4039 | .maxprot = maxprot, | 3750 | .maxprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE, |
| 4040 | .initprot = initprot, | 3751 | .initprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE, |
| 4041 | }), | 3752 | }), |
| 4042 | }); | 3753 | }); |
| 4043 | self.load_commands_dirty = true; | 3754 | self.load_commands_dirty = true; |
| 4044 | } | 3755 | } |
| | 3756 | |
| 4045 | if (self.text_section_index == null) { | 3757 | if (self.text_section_index == null) { |
| 4046 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 3758 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 4047 | self.text_section_index = @intCast(u16, text_segment.sections.items.len); | 3759 | self.text_section_index = @intCast(u16, text_segment.sections.items.len); |
| ... | @@ -4051,7 +3763,6 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4051,7 +3763,6 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4051 | .aarch64 => 2, | 3763 | .aarch64 => 2, |
| 4052 | else => unreachable, // unhandled architecture type | 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 | const needed_size = self.base.options.program_code_size_hint; | 3766 | const needed_size = self.base.options.program_code_size_hint; |
| 4056 | const off = text_segment.findFreeSpace(needed_size, @as(u16, 1) << alignment, self.header_pad); | 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,10 +3773,15 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4062 | .size = @intCast(u32, needed_size), | 3773 | .size = @intCast(u32, needed_size), |
| 4063 | .offset = @intCast(u32, off), | 3774 | .offset = @intCast(u32, off), |
| 4064 | .@"align" = alignment, | 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 | self.load_commands_dirty = true; | 3782 | self.load_commands_dirty = true; |
| 4068 | } | 3783 | } |
| | 3784 | |
| 4069 | if (self.stubs_section_index == null) { | 3785 | if (self.stubs_section_index == null) { |
| 4070 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 3786 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 4071 | self.stubs_section_index = @intCast(u16, text_segment.sections.items.len); | 3787 | self.stubs_section_index = @intCast(u16, text_segment.sections.items.len); |
| ... | @@ -4080,7 +3796,6 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4080,7 +3796,6 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4080 | .aarch64 => 3 * @sizeOf(u32), | 3796 | .aarch64 => 3 * @sizeOf(u32), |
| 4081 | else => unreachable, // unhandled architecture type | 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 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; | 3799 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4085 | const off = text_segment.findFreeSpace(needed_size, @alignOf(u64), self.header_pad); | 3800 | const off = text_segment.findFreeSpace(needed_size, @alignOf(u64), self.header_pad); |
| 4086 | assert(off + needed_size <= text_segment.inner.fileoff + text_segment.inner.filesize); // TODO Must expand __TEXT segment. | 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,11 +3807,16 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4092 | .size = needed_size, | 3807 | .size = needed_size, |
| 4093 | .offset = @intCast(u32, off), | 3808 | .offset = @intCast(u32, off), |
| 4094 | .@"align" = alignment, | 3809 | .@"align" = alignment, |
| 4095 | .flags = flags, | 3810 | .flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 4096 | .reserved2 = stub_size, | 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 | self.load_commands_dirty = true; | 3817 | self.load_commands_dirty = true; |
| 4099 | } | 3818 | } |
| | 3819 | |
| 4100 | if (self.stub_helper_section_index == null) { | 3820 | if (self.stub_helper_section_index == null) { |
| 4101 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 3821 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 4102 | self.stub_helper_section_index = @intCast(u16, text_segment.sections.items.len); | 3822 | self.stub_helper_section_index = @intCast(u16, text_segment.sections.items.len); |
| ... | @@ -4106,7 +3826,6 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4106,7 +3826,6 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4106 | .aarch64 => 2, | 3826 | .aarch64 => 2, |
| 4107 | else => unreachable, // unhandled architecture type | 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 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; | 3829 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4111 | const off = text_segment.findFreeSpace(needed_size, @alignOf(u64), self.header_pad); | 3830 | const off = text_segment.findFreeSpace(needed_size, @alignOf(u64), self.header_pad); |
| 4112 | assert(off + needed_size <= text_segment.inner.fileoff + text_segment.inner.filesize); // TODO Must expand __TEXT segment. | 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,16 +3837,18 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4118 | .size = needed_size, | 3837 | .size = needed_size, |
| 4119 | .offset = @intCast(u32, off), | 3838 | .offset = @intCast(u32, off), |
| 4120 | .@"align" = alignment, | 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 | self.load_commands_dirty = true; | 3846 | self.load_commands_dirty = true; |
| 4124 | } | 3847 | } |
| | 3848 | |
| 4125 | if (self.data_const_segment_cmd_index == null) { | 3849 | if (self.data_const_segment_cmd_index == null) { |
| 4126 | self.data_const_segment_cmd_index = @intCast(u16, self.load_commands.items.len); | 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 | const address_and_offset = self.nextSegmentAddressAndOffset(); | 3851 | const address_and_offset = self.nextSegmentAddressAndOffset(); |
| 4130 | | | |
| 4131 | const ideal_size = @sizeOf(u64) * self.base.options.symbol_count_hint; | 3852 | const ideal_size = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4132 | const needed_size = mem.alignForwardGeneric(u64, padToIdeal(ideal_size), self.page_size); | 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,17 +3860,17 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4139 | .vmsize = needed_size, | 3860 | .vmsize = needed_size, |
| 4140 | .fileoff = address_and_offset.offset, | 3861 | .fileoff = address_and_offset.offset, |
| 4141 | .filesize = needed_size, | 3862 | .filesize = needed_size, |
| 4142 | .maxprot = maxprot, | 3863 | .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, |
| 4143 | .initprot = initprot, | 3864 | .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, |
| 4144 | }), | 3865 | }), |
| 4145 | }); | 3866 | }); |
| 4146 | self.load_commands_dirty = true; | 3867 | self.load_commands_dirty = true; |
| 4147 | } | 3868 | } |
| | 3869 | |
| 4148 | if (self.got_section_index == null) { | 3870 | if (self.got_section_index == null) { |
| 4149 | const dc_segment = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; | 3871 | const dc_segment = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 4150 | self.got_section_index = @intCast(u16, dc_segment.sections.items.len); | 3872 | self.got_section_index = @intCast(u16, dc_segment.sections.items.len); |
| 4151 | | 3873 | |
| 4152 | const flags = macho.S_NON_LAZY_SYMBOL_POINTERS; | | |
| 4153 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; | 3874 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4154 | const off = dc_segment.findFreeSpace(needed_size, @alignOf(u64), null); | 3875 | const off = dc_segment.findFreeSpace(needed_size, @alignOf(u64), null); |
| 4155 | assert(off + needed_size <= dc_segment.inner.fileoff + dc_segment.inner.filesize); // TODO Must expand __DATA_CONST segment. | 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,16 +3882,18 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4161 | .size = needed_size, | 3882 | .size = needed_size, |
| 4162 | .offset = @intCast(u32, off), | 3883 | .offset = @intCast(u32, off), |
| 4163 | .@"align" = 3, // 2^3 = @sizeOf(u64) | 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 | self.load_commands_dirty = true; | 3891 | self.load_commands_dirty = true; |
| 4167 | } | 3892 | } |
| | 3893 | |
| 4168 | if (self.data_segment_cmd_index == null) { | 3894 | if (self.data_segment_cmd_index == null) { |
| 4169 | self.data_segment_cmd_index = @intCast(u16, self.load_commands.items.len); | 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 | const address_and_offset = self.nextSegmentAddressAndOffset(); | 3896 | const address_and_offset = self.nextSegmentAddressAndOffset(); |
| 4173 | | | |
| 4174 | const ideal_size = 2 * @sizeOf(u64) * self.base.options.symbol_count_hint; | 3897 | const ideal_size = 2 * @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4175 | const needed_size = mem.alignForwardGeneric(u64, padToIdeal(ideal_size), self.page_size); | 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,17 +3905,17 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4182 | .vmsize = needed_size, | 3905 | .vmsize = needed_size, |
| 4183 | .fileoff = address_and_offset.offset, | 3906 | .fileoff = address_and_offset.offset, |
| 4184 | .filesize = needed_size, | 3907 | .filesize = needed_size, |
| 4185 | .maxprot = maxprot, | 3908 | .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, |
| 4186 | .initprot = initprot, | 3909 | .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, |
| 4187 | }), | 3910 | }), |
| 4188 | }); | 3911 | }); |
| 4189 | self.load_commands_dirty = true; | 3912 | self.load_commands_dirty = true; |
| 4190 | } | 3913 | } |
| | 3914 | |
| 4191 | if (self.la_symbol_ptr_section_index == null) { | 3915 | if (self.la_symbol_ptr_section_index == null) { |
| 4192 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 3916 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 4193 | self.la_symbol_ptr_section_index = @intCast(u16, data_segment.sections.items.len); | 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 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; | 3919 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4197 | const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null); | 3920 | const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null); |
| 4198 | assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment. | 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,10 +3927,15 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4204 | .size = needed_size, | 3927 | .size = needed_size, |
| 4205 | .offset = @intCast(u32, off), | 3928 | .offset = @intCast(u32, off), |
| 4206 | .@"align" = 3, // 2^3 = @sizeOf(u64) | 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 | self.load_commands_dirty = true; | 3936 | self.load_commands_dirty = true; |
| 4210 | } | 3937 | } |
| | 3938 | |
| 4211 | if (self.data_section_index == null) { | 3939 | if (self.data_section_index == null) { |
| 4212 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 3940 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 4213 | self.data_section_index = @intCast(u16, data_segment.sections.items.len); | 3941 | self.data_section_index = @intCast(u16, data_segment.sections.items.len); |
| ... | @@ -4224,13 +3952,15 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4224,13 +3952,15 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4224 | .offset = @intCast(u32, off), | 3952 | .offset = @intCast(u32, off), |
| 4225 | .@"align" = 3, // 2^3 = @sizeOf(u64) | 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 | self.load_commands_dirty = true; | 3959 | self.load_commands_dirty = true; |
| 4228 | } | 3960 | } |
| | 3961 | |
| 4229 | if (self.linkedit_segment_cmd_index == null) { | 3962 | if (self.linkedit_segment_cmd_index == null) { |
| 4230 | self.linkedit_segment_cmd_index = @intCast(u16, self.load_commands.items.len); | 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 | const address_and_offset = self.nextSegmentAddressAndOffset(); | 3964 | const address_and_offset = self.nextSegmentAddressAndOffset(); |
| 4235 | | 3965 | |
| 4236 | log.debug("found __LINKEDIT segment free space at 0x{x}", .{address_and_offset.offset}); | 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,12 +3969,13 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4239 | .Segment = SegmentCommand.empty("__LINKEDIT", .{ | 3969 | .Segment = SegmentCommand.empty("__LINKEDIT", .{ |
| 4240 | .vmaddr = address_and_offset.address, | 3970 | .vmaddr = address_and_offset.address, |
| 4241 | .fileoff = address_and_offset.offset, | 3971 | .fileoff = address_and_offset.offset, |
| 4242 | .maxprot = maxprot, | 3972 | .maxprot = macho.VM_PROT_READ, |
| 4243 | .initprot = initprot, | 3973 | .initprot = macho.VM_PROT_READ, |
| 4244 | }), | 3974 | }), |
| 4245 | }); | 3975 | }); |
| 4246 | self.load_commands_dirty = true; | 3976 | self.load_commands_dirty = true; |
| 4247 | } | 3977 | } |
| | 3978 | |
| 4248 | if (self.dyld_info_cmd_index == null) { | 3979 | if (self.dyld_info_cmd_index == null) { |
| 4249 | self.dyld_info_cmd_index = @intCast(u16, self.load_commands.items.len); | 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,6 +4022,7 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4291 | | 4022 | |
| 4292 | self.load_commands_dirty = true; | 4023 | self.load_commands_dirty = true; |
| 4293 | } | 4024 | } |
| | 4025 | |
| 4294 | if (self.symtab_cmd_index == null) { | 4026 | if (self.symtab_cmd_index == null) { |
| 4295 | self.symtab_cmd_index = @intCast(u16, self.load_commands.items.len); | 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,6 +4055,7 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4323 | self.load_commands_dirty = true; | 4055 | self.load_commands_dirty = true; |
| 4324 | self.strtab_dirty = true; | 4056 | self.strtab_dirty = true; |
| 4325 | } | 4057 | } |
| | 4058 | |
| 4326 | if (self.dysymtab_cmd_index == null) { | 4059 | if (self.dysymtab_cmd_index == null) { |
| 4327 | self.dysymtab_cmd_index = @intCast(u16, self.load_commands.items.len); | 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,6 +4091,7 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4358 | }); | 4091 | }); |
| 4359 | self.load_commands_dirty = true; | 4092 | self.load_commands_dirty = true; |
| 4360 | } | 4093 | } |
| | 4094 | |
| 4361 | if (self.dylinker_cmd_index == null) { | 4095 | if (self.dylinker_cmd_index == null) { |
| 4362 | self.dylinker_cmd_index = @intCast(u16, self.load_commands.items.len); | 4096 | self.dylinker_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4363 | const cmdsize = @intCast(u32, mem.alignForwardGeneric( | 4097 | const cmdsize = @intCast(u32, mem.alignForwardGeneric( |
| ... | @@ -4376,17 +4110,8 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4376,17 +4110,8 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4376 | try self.load_commands.append(self.base.allocator, .{ .Dylinker = dylinker_cmd }); | 4110 | try self.load_commands.append(self.base.allocator, .{ .Dylinker = dylinker_cmd }); |
| 4377 | self.load_commands_dirty = true; | 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; | 4114 | if (self.main_cmd_index == null and self.base.options.output_mode == .Exe) { |
| 4388 | } | | |
| 4389 | if (self.main_cmd_index == null) { | | |
| 4390 | self.main_cmd_index = @intCast(u16, self.load_commands.items.len); | 4115 | self.main_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4391 | try self.load_commands.append(self.base.allocator, .{ | 4116 | try self.load_commands.append(self.base.allocator, .{ |
| 4392 | .Main = .{ | 4117 | .Main = .{ |
| ... | @@ -4398,6 +4123,38 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4398,6 +4123,38 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4398 | }); | 4123 | }); |
| 4399 | self.load_commands_dirty = true; | 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 | if (self.build_version_cmd_index == null) { | 4158 | if (self.build_version_cmd_index == null) { |
| 4402 | self.build_version_cmd_index = @intCast(u16, self.load_commands.items.len); | 4159 | self.build_version_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4403 | const cmdsize = @intCast(u32, mem.alignForwardGeneric( | 4160 | const cmdsize = @intCast(u32, mem.alignForwardGeneric( |
| ... | @@ -4430,18 +4187,9 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4430,18 +4187,9 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4430 | mem.set(u8, cmd.data, 0); | 4187 | mem.set(u8, cmd.data, 0); |
| 4431 | mem.copy(u8, cmd.data, mem.asBytes(&ld_ver)); | 4188 | mem.copy(u8, cmd.data, mem.asBytes(&ld_ver)); |
| 4432 | try self.load_commands.append(self.base.allocator, .{ .BuildVersion = cmd }); | 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 | self.load_commands_dirty = true; | 4190 | self.load_commands_dirty = true; |
| 4444 | } | 4191 | } |
| | 4192 | |
| 4445 | if (self.uuid_cmd_index == null) { | 4193 | if (self.uuid_cmd_index == null) { |
| 4446 | self.uuid_cmd_index = @intCast(u16, self.load_commands.items.len); | 4194 | self.uuid_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4447 | var uuid_cmd: macho.uuid_command = .{ | 4195 | var uuid_cmd: macho.uuid_command = .{ |
| ... | @@ -4453,47 +4201,6 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4453,47 +4201,6 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4453 | try self.load_commands.append(self.base.allocator, .{ .Uuid = uuid_cmd }); | 4201 | try self.load_commands.append(self.base.allocator, .{ .Uuid = uuid_cmd }); |
| 4454 | self.load_commands_dirty = true; | 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 | fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 { | 4206 | fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 { |