| ... | @@ -1647,110 +1647,12 @@ pub fn allocateAtom(self: *MachO, atom: *TextBlock, match: MatchingSection) !u64 | ... | @@ -1647,110 +1647,12 @@ pub fn allocateAtom(self: *MachO, atom: *TextBlock, match: MatchingSection) !u64 |
| 1647 | break :blk new_start_vaddr; | 1647 | break :blk new_start_vaddr; |
| 1648 | } else sect.addr; | 1648 | } else sect.addr; |
| 1649 | | 1649 | |
| 1650 | log.debug("allocating atom for symbol {s} at address 0x{x}", .{ self.getString(sym.n_strx), vaddr }); | 1650 | log.warn("allocating atom for symbol {s} at address 0x{x}", .{ self.getString(sym.n_strx), vaddr }); |
| 1651 | | 1651 | |
| 1652 | const expand_section = atom_placement == null or atom_placement.?.next == null; | 1652 | const expand_section = atom_placement == null or atom_placement.?.next == null; |
| 1653 | if (expand_section) { | 1653 | if (expand_section) { |
| 1654 | const needed_size = (vaddr + atom.size) - sect.addr; | 1654 | const needed_size = @intCast(u32, (vaddr + atom.size) - sect.addr); |
| 1655 | const sect_offset = self.getPtrToSectionOffset(match); | 1655 | try self.growSection(match, needed_size); |
| 1656 | const file_offset = sect_offset.* + vaddr - sect.addr; | | |
| 1657 | const max_size = seg.allocatedSize(file_offset); | | |
| 1658 | log.debug(" (section {s},{s} needed size 0x{x}, max available size 0x{x})", .{ | | |
| 1659 | commands.segmentName(sect.*), | | |
| 1660 | commands.sectionName(sect.*), | | |
| 1661 | needed_size, | | |
| 1662 | max_size, | | |
| 1663 | }); | | |
| 1664 | | | |
| 1665 | if (needed_size > max_size) { | | |
| 1666 | const old_base_addr = sect.addr; | | |
| 1667 | sect.size = 0; | | |
| 1668 | const padding: ?u64 = if (match.seg == self.text_segment_cmd_index.?) self.header_pad else null; | | |
| 1669 | const atom_alignment = try math.powi(u64, 2, atom.alignment); | | |
| 1670 | const new_offset = @intCast(u32, seg.findFreeSpace(needed_size, atom_alignment, padding)); | | |
| 1671 | | | |
| 1672 | if (new_offset + needed_size >= seg.inner.fileoff + seg.inner.filesize) { | | |
| 1673 | // Bummer, need to move all segments below down... | | |
| 1674 | // TODO is this the right estimate? | | |
| 1675 | const new_seg_size = mem.alignForwardGeneric( | | |
| 1676 | u64, | | |
| 1677 | padToIdeal(seg.inner.filesize + needed_size), | | |
| 1678 | self.page_size, | | |
| 1679 | ); | | |
| 1680 | // TODO actually, we're always required to move in a number of pages so I guess all we need | | |
| 1681 | // to know here is the number of pages to shift downwards. | | |
| 1682 | const offset_amt = @intCast(u32, @intCast(i64, new_seg_size) - @intCast(i64, seg.inner.filesize)); | | |
| 1683 | seg.inner.filesize = new_seg_size; | | |
| 1684 | seg.inner.vmsize = new_seg_size; | | |
| 1685 | log.debug(" (new {s} segment file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ | | |
| 1686 | seg.inner.segname, | | |
| 1687 | seg.inner.fileoff, | | |
| 1688 | seg.inner.fileoff + seg.inner.filesize, | | |
| 1689 | seg.inner.vmaddr, | | |
| 1690 | seg.inner.vmaddr + seg.inner.vmsize, | | |
| 1691 | }); | | |
| 1692 | // TODO We should probably nop the expanded by distance, or put 0s. | | |
| 1693 | | | |
| 1694 | // TODO copyRangeAll doesn't automatically extend the file on macOS. | | |
| 1695 | const ledit_seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; | | |
| 1696 | const new_filesize = offset_amt + ledit_seg.inner.fileoff + ledit_seg.inner.filesize; | | |
| 1697 | try self.base.file.?.pwriteAll(&[_]u8{0}, new_filesize - 1); | | |
| 1698 | | | |
| 1699 | var next: usize = match.seg + 1; | | |
| 1700 | while (next < self.linkedit_segment_cmd_index.? + 1) : (next += 1) { | | |
| 1701 | const next_seg = &self.load_commands.items[next].Segment; | | |
| 1702 | _ = try self.base.file.?.copyRangeAll( | | |
| 1703 | next_seg.inner.fileoff, | | |
| 1704 | self.base.file.?, | | |
| 1705 | next_seg.inner.fileoff + offset_amt, | | |
| 1706 | next_seg.inner.filesize, | | |
| 1707 | ); | | |
| 1708 | next_seg.inner.fileoff += offset_amt; | | |
| 1709 | next_seg.inner.vmaddr += offset_amt; | | |
| 1710 | log.debug(" (new {s} segment file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ | | |
| 1711 | next_seg.inner.segname, | | |
| 1712 | next_seg.inner.fileoff, | | |
| 1713 | next_seg.inner.fileoff + next_seg.inner.filesize, | | |
| 1714 | next_seg.inner.vmaddr, | | |
| 1715 | next_seg.inner.vmaddr + next_seg.inner.vmsize, | | |
| 1716 | }); | | |
| 1717 | | | |
| 1718 | for (next_seg.sections.items) |*moved_sect, moved_sect_id| { | | |
| 1719 | const moved_match = MatchingSection{ | | |
| 1720 | .seg = @intCast(u16, next), | | |
| 1721 | .sect = @intCast(u16, moved_sect_id), | | |
| 1722 | }; | | |
| 1723 | const ptr_sect_offset = self.getPtrToSectionOffset(moved_match); | | |
| 1724 | ptr_sect_offset.* += offset_amt; | | |
| 1725 | moved_sect.addr += offset_amt; | | |
| 1726 | log.debug(" (new {s},{s} file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ | | |
| 1727 | commands.segmentName(moved_sect.*), | | |
| 1728 | commands.sectionName(moved_sect.*), | | |
| 1729 | ptr_sect_offset.*, | | |
| 1730 | ptr_sect_offset.* + moved_sect.size, | | |
| 1731 | moved_sect.addr, | | |
| 1732 | moved_sect.addr + moved_sect.size, | | |
| 1733 | }); | | |
| 1734 | | | |
| 1735 | try self.allocateLocalSymbols(moved_match, offset_amt); | | |
| 1736 | } | | |
| 1737 | } | | |
| 1738 | } | | |
| 1739 | sect_offset.* = new_offset; | | |
| 1740 | sect.addr = seg.inner.vmaddr + sect_offset.* - seg.inner.fileoff; | | |
| 1741 | log.debug(" (found new {s},{s} free space from 0x{x} to 0x{x})", .{ | | |
| 1742 | commands.segmentName(sect.*), | | |
| 1743 | commands.sectionName(sect.*), | | |
| 1744 | new_offset, | | |
| 1745 | new_offset + needed_size, | | |
| 1746 | }); | | |
| 1747 | const offset_amt = @intCast(i64, sect.addr) - @intCast(i64, old_base_addr); | | |
| 1748 | try self.allocateLocalSymbols(match, offset_amt); | | |
| 1749 | vaddr = @intCast(u64, @intCast(i64, vaddr) + offset_amt); | | |
| 1750 | } | | |
| 1751 | | | |
| 1752 | sect.size = needed_size; | | |
| 1753 | self.load_commands_dirty = true; | | |
| 1754 | } | 1656 | } |
| 1755 | const n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1); | 1657 | const n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1); |
| 1756 | sym.n_value = vaddr; | 1658 | sym.n_value = vaddr; |
| ... | @@ -3373,7 +3275,6 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -3373,7 +3275,6 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 3373 | else => unreachable, // unhandled architecture type | 3275 | else => unreachable, // unhandled architecture type |
| 3374 | }; | 3276 | }; |
| 3375 | const needed_size = self.base.options.program_code_size_hint; | 3277 | const needed_size = self.base.options.program_code_size_hint; |
| 3376 | // const needed_size = 10; | | |
| 3377 | self.text_section_index = try self.allocateSection( | 3278 | self.text_section_index = try self.allocateSection( |
| 3378 | self.text_segment_cmd_index.?, | 3279 | self.text_segment_cmd_index.?, |
| 3379 | "__text", | 3280 | "__text", |
| ... | @@ -3821,9 +3722,9 @@ fn allocateSection( | ... | @@ -3821,9 +3722,9 @@ fn allocateSection( |
| 3821 | | 3722 | |
| 3822 | const alignment_pow_2 = try math.powi(u32, 2, alignment); | 3723 | const alignment_pow_2 = try math.powi(u32, 2, alignment); |
| 3823 | const padding: ?u64 = if (segment_id == self.text_segment_cmd_index.?) self.header_pad else null; | 3724 | const padding: ?u64 = if (segment_id == self.text_segment_cmd_index.?) self.header_pad else null; |
| 3824 | const off = seg.findFreeSpace(size, alignment_pow_2, padding); | 3725 | const off = self.findFreeSpace(segment_id, alignment_pow_2, padding); |
| 3825 | | 3726 | |
| 3826 | log.debug("found {s},{s} section free space 0x{x} to 0x{x}", .{ | 3727 | log.debug("allocating {s},{s} section from 0x{x} to 0x{x}", .{ |
| 3827 | commands.segmentName(sect), | 3728 | commands.segmentName(sect), |
| 3828 | commands.sectionName(sect), | 3729 | commands.sectionName(sect), |
| 3829 | off, | 3730 | off, |
| ... | @@ -3851,6 +3752,170 @@ fn allocateSection( | ... | @@ -3851,6 +3752,170 @@ fn allocateSection( |
| 3851 | return index; | 3752 | return index; |
| 3852 | } | 3753 | } |
| 3853 | | 3754 | |
| | 3755 | fn findFreeSpace(self: MachO, segment_id: u16, alignment: u64, start: ?u64) u64 { |
| | 3756 | const seg = self.load_commands.items[segment_id].Segment; |
| | 3757 | if (seg.sections.items.len == 0) { |
| | 3758 | return if (start) |v| v else seg.inner.fileoff; |
| | 3759 | } |
| | 3760 | const last_sect = seg.sections.items[seg.sections.items.len - 1]; |
| | 3761 | const final_off = last_sect.offset + padToIdeal(last_sect.size); |
| | 3762 | return mem.alignForwardGeneric(u64, final_off, alignment); |
| | 3763 | } |
| | 3764 | |
| | 3765 | fn growSection(self: *MachO, match: MatchingSection, new_size: u32) !void { |
| | 3766 | const seg = &self.load_commands.items[match.seg].Segment; |
| | 3767 | const sect = &seg.sections.items[match.sect]; |
| | 3768 | |
| | 3769 | const alignment = try math.powi(u32, 2, sect.@"align"); |
| | 3770 | const sect_offset = self.getPtrToSectionOffset(match); |
| | 3771 | const max_size = self.allocatedSize(match.seg, sect_offset.*); |
| | 3772 | const ideal_size = padToIdeal(new_size); |
| | 3773 | const needed_size = mem.alignForwardGeneric(u32, ideal_size, alignment); |
| | 3774 | |
| | 3775 | if (needed_size > max_size) blk: { |
| | 3776 | // Need to move all sections below in file and address spaces. |
| | 3777 | const offset_amt = offset: { |
| | 3778 | const max_alignment = try self.getSectionMaxAlignment(match.seg, match.sect + 1); |
| | 3779 | break :offset mem.alignForwardGeneric(u64, needed_size - max_size, max_alignment); |
| | 3780 | }; |
| | 3781 | |
| | 3782 | // Before we commit to this, check if the segment needs to grow too. |
| | 3783 | // We assume that each section header is growing linearly with the increasing |
| | 3784 | // file offset / virtual memory address space. |
| | 3785 | const last_sect = seg.sections.items[seg.sections.items.len - 1]; |
| | 3786 | const last_sect_off = last_sect.offset + last_sect.size; |
| | 3787 | const seg_off = seg.inner.fileoff + seg.inner.filesize; |
| | 3788 | |
| | 3789 | if (last_sect_off + offset_amt > seg_off) { |
| | 3790 | // Need to grow segment first. |
| | 3791 | log.warn(" (need to grow segment first)", .{}); |
| | 3792 | const spill_size = (last_sect_off + offset_amt) - seg_off; |
| | 3793 | const seg_offset_amt = mem.alignForwardGeneric(u64, spill_size, self.page_size); |
| | 3794 | seg.inner.filesize += seg_offset_amt; |
| | 3795 | seg.inner.vmsize += seg_offset_amt; |
| | 3796 | |
| | 3797 | log.warn(" (new {s} segment file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ |
| | 3798 | seg.inner.segname, |
| | 3799 | seg.inner.fileoff, |
| | 3800 | seg.inner.fileoff + seg.inner.filesize, |
| | 3801 | seg.inner.vmaddr, |
| | 3802 | seg.inner.vmaddr + seg.inner.vmsize, |
| | 3803 | }); |
| | 3804 | |
| | 3805 | // TODO We should probably nop the expanded by distance, or put 0s. |
| | 3806 | |
| | 3807 | // TODO copyRangeAll doesn't automatically extend the file on macOS. |
| | 3808 | const ledit_seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| | 3809 | const new_filesize = seg_offset_amt + ledit_seg.inner.fileoff + ledit_seg.inner.filesize; |
| | 3810 | try self.base.file.?.pwriteAll(&[_]u8{0}, new_filesize - 1); |
| | 3811 | |
| | 3812 | var next: usize = match.seg + 1; |
| | 3813 | while (next < self.linkedit_segment_cmd_index.? + 1) : (next += 1) { |
| | 3814 | const next_seg = &self.load_commands.items[next].Segment; |
| | 3815 | _ = try self.base.file.?.copyRangeAll( |
| | 3816 | next_seg.inner.fileoff, |
| | 3817 | self.base.file.?, |
| | 3818 | next_seg.inner.fileoff + seg_offset_amt, |
| | 3819 | next_seg.inner.filesize, |
| | 3820 | ); |
| | 3821 | next_seg.inner.fileoff += seg_offset_amt; |
| | 3822 | next_seg.inner.vmaddr += seg_offset_amt; |
| | 3823 | |
| | 3824 | log.warn(" (new {s} segment file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ |
| | 3825 | next_seg.inner.segname, |
| | 3826 | next_seg.inner.fileoff, |
| | 3827 | next_seg.inner.fileoff + next_seg.inner.filesize, |
| | 3828 | next_seg.inner.vmaddr, |
| | 3829 | next_seg.inner.vmaddr + next_seg.inner.vmsize, |
| | 3830 | }); |
| | 3831 | |
| | 3832 | for (next_seg.sections.items) |*moved_sect, moved_sect_id| { |
| | 3833 | const moved_match = MatchingSection{ |
| | 3834 | .seg = @intCast(u16, next), |
| | 3835 | .sect = @intCast(u16, moved_sect_id), |
| | 3836 | }; |
| | 3837 | const ptr_sect_offset = self.getPtrToSectionOffset(moved_match); |
| | 3838 | ptr_sect_offset.* += @intCast(u32, seg_offset_amt); |
| | 3839 | moved_sect.addr += seg_offset_amt; |
| | 3840 | |
| | 3841 | log.warn(" (new {s},{s} file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ |
| | 3842 | commands.segmentName(moved_sect.*), |
| | 3843 | commands.sectionName(moved_sect.*), |
| | 3844 | ptr_sect_offset.*, |
| | 3845 | ptr_sect_offset.* + moved_sect.size, |
| | 3846 | moved_sect.addr, |
| | 3847 | moved_sect.addr + moved_sect.size, |
| | 3848 | }); |
| | 3849 | |
| | 3850 | try self.allocateLocalSymbols(moved_match, @intCast(i64, seg_offset_amt)); |
| | 3851 | } |
| | 3852 | } |
| | 3853 | } |
| | 3854 | |
| | 3855 | if (match.sect + 1 >= seg.sections.items.len) break :blk; |
| | 3856 | |
| | 3857 | // We have enough space to expand within the segment, so move all sections by |
| | 3858 | // the required amount and update their header offsets. |
| | 3859 | const next_sect = seg.sections.items[match.sect + 1]; |
| | 3860 | const total_size = last_sect_off - next_sect.offset; |
| | 3861 | _ = try self.base.file.?.copyRangeAll( |
| | 3862 | next_sect.offset, |
| | 3863 | self.base.file.?, |
| | 3864 | next_sect.offset + offset_amt, |
| | 3865 | total_size, |
| | 3866 | ); |
| | 3867 | |
| | 3868 | var next = match.sect + 1; |
| | 3869 | while (next < seg.sections.items.len) : (next += 1) { |
| | 3870 | const moved_match = MatchingSection{ |
| | 3871 | .seg = match.seg, |
| | 3872 | .sect = next, |
| | 3873 | }; |
| | 3874 | const moved_sect = &seg.sections.items[next]; |
| | 3875 | const ptr_sect_offset = self.getPtrToSectionOffset(moved_match); |
| | 3876 | ptr_sect_offset.* += @intCast(u32, offset_amt); |
| | 3877 | moved_sect.addr += offset_amt; |
| | 3878 | |
| | 3879 | log.warn(" (new {s},{s} file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ |
| | 3880 | commands.segmentName(moved_sect.*), |
| | 3881 | commands.sectionName(moved_sect.*), |
| | 3882 | ptr_sect_offset.*, |
| | 3883 | ptr_sect_offset.* + moved_sect.size, |
| | 3884 | moved_sect.addr, |
| | 3885 | moved_sect.addr + moved_sect.size, |
| | 3886 | }); |
| | 3887 | |
| | 3888 | try self.allocateLocalSymbols(moved_match, @intCast(i64, offset_amt)); |
| | 3889 | } |
| | 3890 | } |
| | 3891 | |
| | 3892 | sect.size = new_size; |
| | 3893 | self.load_commands_dirty = true; |
| | 3894 | } |
| | 3895 | |
| | 3896 | fn allocatedSize(self: MachO, segment_id: u16, start: u64) u64 { |
| | 3897 | const seg = self.load_commands.items[segment_id].Segment; |
| | 3898 | assert(start >= seg.inner.fileoff); |
| | 3899 | var min_pos: u64 = seg.inner.fileoff + seg.inner.filesize; |
| | 3900 | for (seg.sections.items) |section| { |
| | 3901 | if (section.offset <= start) continue; |
| | 3902 | if (section.offset < min_pos) min_pos = section.offset; |
| | 3903 | } |
| | 3904 | return min_pos - start; |
| | 3905 | } |
| | 3906 | |
| | 3907 | fn getSectionMaxAlignment(self: *MachO, segment_id: u16, start_sect_id: u16) !u32 { |
| | 3908 | const seg = self.load_commands.items[segment_id].Segment; |
| | 3909 | var max_alignment: u32 = 1; |
| | 3910 | var next = start_sect_id; |
| | 3911 | while (next < seg.sections.items.len) : (next += 1) { |
| | 3912 | const sect = seg.sections.items[next]; |
| | 3913 | const alignment = try math.powi(u32, 2, sect.@"align"); |
| | 3914 | max_alignment = math.max(max_alignment, alignment); |
| | 3915 | } |
| | 3916 | return max_alignment; |
| | 3917 | } |
| | 3918 | |
| 3854 | fn getPtrToSectionOffset(self: *MachO, match: MatchingSection) *u32 { | 3919 | fn getPtrToSectionOffset(self: *MachO, match: MatchingSection) *u32 { |
| 3855 | if (self.data_segment_cmd_index.? == match.seg) { | 3920 | if (self.data_segment_cmd_index.? == match.seg) { |
| 3856 | if (self.bss_section_index) |idx| { | 3921 | if (self.bss_section_index) |idx| { |
| ... | @@ -3943,103 +4008,8 @@ fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, | ... | @@ -3943,103 +4008,8 @@ fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, |
| 3943 | | 4008 | |
| 3944 | const expand_text_section = block_placement == null or block_placement.?.next == null; | 4009 | const expand_text_section = block_placement == null or block_placement.?.next == null; |
| 3945 | if (expand_text_section) { | 4010 | if (expand_text_section) { |
| 3946 | const needed_size = (vaddr + new_block_size) - text_section.addr; | 4011 | const needed_size = @intCast(u32, (vaddr + new_block_size) - text_section.addr); |
| 3947 | const max_size = text_segment.allocatedSize(vaddr - pagezero_vmsize); | 4012 | try self.growSection(match, needed_size); |
| 3948 | log.debug(" (section __TEXT,__text needed size 0x{x}, max available size 0x{x})", .{ needed_size, max_size }); | | |
| 3949 | | | |
| 3950 | if (needed_size > max_size) { | | |
| 3951 | const old_base_addr = text_section.addr; | | |
| 3952 | text_section.size = 0; | | |
| 3953 | const new_offset = @intCast(u32, text_segment.findFreeSpace(needed_size, alignment, self.header_pad)); | | |
| 3954 | | | |
| 3955 | if (new_offset + needed_size >= text_segment.inner.fileoff + text_segment.inner.filesize) { | | |
| 3956 | // Bummer, need to move all segments below down... | | |
| 3957 | // TODO is this the right estimate? | | |
| 3958 | const new_seg_size = mem.alignForwardGeneric( | | |
| 3959 | u64, | | |
| 3960 | padToIdeal(text_segment.inner.filesize + needed_size), | | |
| 3961 | self.page_size, | | |
| 3962 | ); | | |
| 3963 | // TODO actually, we're always required to move in a number of pages so I guess all we need | | |
| 3964 | // to know here is the number of pages to shift downwards. | | |
| 3965 | const offset_amt = @intCast( | | |
| 3966 | u32, | | |
| 3967 | @intCast(i64, new_seg_size) - @intCast(i64, text_segment.inner.filesize), | | |
| 3968 | ); | | |
| 3969 | text_segment.inner.filesize = new_seg_size; | | |
| 3970 | text_segment.inner.vmsize = new_seg_size; | | |
| 3971 | log.debug(" (new __TEXT segment file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ | | |
| 3972 | text_segment.inner.fileoff, | | |
| 3973 | text_segment.inner.fileoff + text_segment.inner.filesize, | | |
| 3974 | text_segment.inner.vmaddr, | | |
| 3975 | text_segment.inner.vmaddr + text_segment.inner.vmsize, | | |
| 3976 | }); | | |
| 3977 | // TODO We should probably nop the expanded by distance, or put 0s. | | |
| 3978 | | | |
| 3979 | // TODO copyRangeAll doesn't automatically extend the file on macOS. | | |
| 3980 | const ledit_seg = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; | | |
| 3981 | const new_filesize = offset_amt + ledit_seg.inner.fileoff + ledit_seg.inner.filesize; | | |
| 3982 | try self.base.file.?.pwriteAll(&[_]u8{0}, new_filesize - 1); | | |
| 3983 | | | |
| 3984 | var next: usize = match.seg + 1; | | |
| 3985 | while (next < self.linkedit_segment_cmd_index.? + 1) : (next += 1) { | | |
| 3986 | const next_seg = &self.load_commands.items[next].Segment; | | |
| 3987 | _ = try self.base.file.?.copyRangeAll( | | |
| 3988 | next_seg.inner.fileoff, | | |
| 3989 | self.base.file.?, | | |
| 3990 | next_seg.inner.fileoff + offset_amt, | | |
| 3991 | next_seg.inner.filesize, | | |
| 3992 | ); | | |
| 3993 | next_seg.inner.fileoff += offset_amt; | | |
| 3994 | next_seg.inner.vmaddr += offset_amt; | | |
| 3995 | log.debug(" (new {s} segment file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ | | |
| 3996 | next_seg.inner.segname, | | |
| 3997 | next_seg.inner.fileoff, | | |
| 3998 | next_seg.inner.fileoff + next_seg.inner.filesize, | | |
| 3999 | next_seg.inner.vmaddr, | | |
| 4000 | next_seg.inner.vmaddr + next_seg.inner.vmsize, | | |
| 4001 | }); | | |
| 4002 | | | |
| 4003 | for (next_seg.sections.items) |*moved_sect, moved_sect_id| { | | |
| 4004 | // TODO put below snippet in a function. | | |
| 4005 | const moved_match = MatchingSection{ | | |
| 4006 | .seg = @intCast(u16, next), | | |
| 4007 | .sect = @intCast(u16, moved_sect_id), | | |
| 4008 | }; | | |
| 4009 | const ptr_sect_offset = self.getPtrToSectionOffset(moved_match); | | |
| 4010 | ptr_sect_offset.* += offset_amt; | | |
| 4011 | moved_sect.addr += offset_amt; | | |
| 4012 | log.debug(" (new {s},{s} file offsets from 0x{x} to 0x{x} (in memory 0x{x} to 0x{x}))", .{ | | |
| 4013 | commands.segmentName(moved_sect.*), | | |
| 4014 | commands.sectionName(moved_sect.*), | | |
| 4015 | ptr_sect_offset.*, | | |
| 4016 | ptr_sect_offset.* + moved_sect.size, | | |
| 4017 | moved_sect.addr, | | |
| 4018 | moved_sect.addr + moved_sect.size, | | |
| 4019 | }); | | |
| 4020 | | | |
| 4021 | try self.allocateLocalSymbols(moved_match, offset_amt); | | |
| 4022 | } | | |
| 4023 | } | | |
| 4024 | } | | |
| 4025 | | | |
| 4026 | text_section.offset = new_offset; | | |
| 4027 | text_section.addr = text_segment.inner.vmaddr + text_section.offset - text_segment.inner.fileoff; | | |
| 4028 | log.debug(" (found new __TEXT,__text free space from 0x{x} to 0x{x})", .{ | | |
| 4029 | new_offset, | | |
| 4030 | new_offset + needed_size, | | |
| 4031 | }); | | |
| 4032 | const offset_amt = @intCast(i64, text_section.addr) - @intCast(i64, old_base_addr); | | |
| 4033 | try self.allocateLocalSymbols(.{ | | |
| 4034 | .seg = self.text_segment_cmd_index.?, | | |
| 4035 | .sect = self.text_section_index.?, | | |
| 4036 | }, offset_amt); | | |
| 4037 | vaddr = @intCast(u64, @intCast(i64, vaddr) + offset_amt); | | |
| 4038 | } | | |
| 4039 | | | |
| 4040 | text_section.size = needed_size; | | |
| 4041 | self.load_commands_dirty = true; | | |
| 4042 | | | |
| 4043 | _ = try self.blocks.put(self.base.allocator, match, text_block); | 4013 | _ = try self.blocks.put(self.base.allocator, match, text_block); |
| 4044 | } | 4014 | } |
| 4045 | text_block.size = new_block_size; | 4015 | text_block.size = new_block_size; |