| ... | @@ -3053,7 +3053,51 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts | ... | @@ -3053,7 +3053,51 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts |
| 3053 | return section_id; | 3053 | return section_id; |
| 3054 | } | 3054 | } |
| 3055 | | 3055 | |
| 3056 | fn moveSectionInVirtualMemory(self: *MachO, sect_id: u8, needed_size: u64) !void { | 3056 | fn growSection(self: *MachO, sect_id: u8, needed_size: u64) !void { |
| | 3057 | const header = &self.sections.items(.header)[sect_id]; |
| | 3058 | const segment_index = self.sections.items(.segment_index)[sect_id]; |
| | 3059 | const segment = &self.segments.items[segment_index]; |
| | 3060 | const maybe_last_atom_index = self.sections.items(.last_atom_index)[sect_id]; |
| | 3061 | const sect_capacity = self.allocatedSize(header.offset); |
| | 3062 | |
| | 3063 | if (needed_size > sect_capacity) { |
| | 3064 | const new_offset = self.findFreeSpace(needed_size, self.page_size); |
| | 3065 | const current_size = if (maybe_last_atom_index) |last_atom_index| blk: { |
| | 3066 | const last_atom = self.getAtom(last_atom_index); |
| | 3067 | const sym = last_atom.getSymbol(self); |
| | 3068 | break :blk (sym.n_value + last_atom.size) - segment.vmaddr; |
| | 3069 | } else 0; |
| | 3070 | |
| | 3071 | log.debug("moving {s},{s} from 0x{x} to 0x{x}", .{ |
| | 3072 | header.segName(), |
| | 3073 | header.sectName(), |
| | 3074 | header.offset, |
| | 3075 | new_offset, |
| | 3076 | }); |
| | 3077 | |
| | 3078 | const amt = try self.base.file.?.copyRangeAll( |
| | 3079 | header.offset, |
| | 3080 | self.base.file.?, |
| | 3081 | new_offset, |
| | 3082 | current_size, |
| | 3083 | ); |
| | 3084 | if (amt != current_size) return error.InputOutput; |
| | 3085 | header.offset = @intCast(u32, new_offset); |
| | 3086 | segment.fileoff = new_offset; |
| | 3087 | } |
| | 3088 | |
| | 3089 | const sect_vm_capacity = self.allocatedVirtualSize(segment.vmaddr); |
| | 3090 | if (needed_size > sect_vm_capacity) { |
| | 3091 | self.markRelocsDirtyByAddress(segment.vmaddr + needed_size); |
| | 3092 | try self.growSectionVirtualMemory(sect_id, needed_size); |
| | 3093 | } |
| | 3094 | |
| | 3095 | header.size = needed_size; |
| | 3096 | segment.filesize = mem.alignForwardGeneric(u64, needed_size, self.page_size); |
| | 3097 | segment.vmsize = mem.alignForwardGeneric(u64, needed_size, self.page_size); |
| | 3098 | } |
| | 3099 | |
| | 3100 | fn growSectionVirtualMemory(self: *MachO, sect_id: u8, needed_size: u64) !void { |
| 3057 | const header = &self.sections.items(.header)[sect_id]; | 3101 | const header = &self.sections.items(.header)[sect_id]; |
| 3058 | const segment = self.getSegmentPtr(sect_id); | 3102 | const segment = self.getSegmentPtr(sect_id); |
| 3059 | const increased_size = padToIdeal(needed_size); | 3103 | const increased_size = padToIdeal(needed_size); |
| ... | @@ -3172,45 +3216,9 @@ fn allocateAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignm | ... | @@ -3172,45 +3216,9 @@ fn allocateAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignm |
| 3172 | else | 3216 | else |
| 3173 | true; | 3217 | true; |
| 3174 | if (expand_section) { | 3218 | if (expand_section) { |
| 3175 | const sect_capacity = self.allocatedSize(header.offset); | | |
| 3176 | const needed_size = (vaddr + new_atom_size) - segment.vmaddr; | 3219 | const needed_size = (vaddr + new_atom_size) - segment.vmaddr; |
| 3177 | if (needed_size > sect_capacity) { | 3220 | try self.growSection(sect_id, needed_size); |
| 3178 | const new_offset = self.findFreeSpace(needed_size, self.page_size); | | |
| 3179 | const current_size = if (maybe_last_atom_index.*) |last_atom_index| blk: { | | |
| 3180 | const last_atom = self.getAtom(last_atom_index); | | |
| 3181 | const sym = last_atom.getSymbol(self); | | |
| 3182 | break :blk (sym.n_value + last_atom.size) - segment.vmaddr; | | |
| 3183 | } else 0; | | |
| 3184 | | | |
| 3185 | log.debug("moving {s},{s} from 0x{x} to 0x{x}", .{ | | |
| 3186 | header.segName(), | | |
| 3187 | header.sectName(), | | |
| 3188 | header.offset, | | |
| 3189 | new_offset, | | |
| 3190 | }); | | |
| 3191 | | | |
| 3192 | const amt = try self.base.file.?.copyRangeAll( | | |
| 3193 | header.offset, | | |
| 3194 | self.base.file.?, | | |
| 3195 | new_offset, | | |
| 3196 | current_size, | | |
| 3197 | ); | | |
| 3198 | if (amt != current_size) return error.InputOutput; | | |
| 3199 | header.offset = @intCast(u32, new_offset); | | |
| 3200 | segment.fileoff = new_offset; | | |
| 3201 | } | | |
| 3202 | | | |
| 3203 | const sect_vm_capacity = self.allocatedVirtualSize(segment.vmaddr); | | |
| 3204 | if (needed_size > sect_vm_capacity) { | | |
| 3205 | self.markRelocsDirtyByAddress(segment.vmaddr + needed_size); | | |
| 3206 | try self.moveSectionInVirtualMemory(sect_id, needed_size); | | |
| 3207 | } | | |
| 3208 | | | |
| 3209 | header.size = needed_size; | | |
| 3210 | segment.filesize = mem.alignForwardGeneric(u64, needed_size, self.page_size); | | |
| 3211 | segment.vmsize = mem.alignForwardGeneric(u64, needed_size, self.page_size); | | |
| 3212 | maybe_last_atom_index.* = atom_index; | 3221 | maybe_last_atom_index.* = atom_index; |
| 3213 | | | |
| 3214 | self.segment_table_dirty = true; | 3222 | self.segment_table_dirty = true; |
| 3215 | } | 3223 | } |
| 3216 | | 3224 | |
| ... | @@ -3218,10 +3226,7 @@ fn allocateAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignm | ... | @@ -3218,10 +3226,7 @@ fn allocateAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignm |
| 3218 | if (header.@"align" < align_pow) { | 3226 | if (header.@"align" < align_pow) { |
| 3219 | header.@"align" = align_pow; | 3227 | header.@"align" = align_pow; |
| 3220 | } | 3228 | } |
| 3221 | { | 3229 | self.getAtomPtr(atom_index).size = new_atom_size; |
| 3222 | const atom_ptr = self.getAtomPtr(atom_index); | | |
| 3223 | atom_ptr.size = new_atom_size; | | |
| 3224 | } | | |
| 3225 | | 3230 | |
| 3226 | if (atom.prev_index) |prev_index| { | 3231 | if (atom.prev_index) |prev_index| { |
| 3227 | const prev = self.getAtomPtr(prev_index); | 3232 | const prev = self.getAtomPtr(prev_index); |