| ... | ... | @@ -242,6 +242,7 @@ const LazySymbolTable = std.ArrayHashMapUnmanaged( |
| 242 | 242 | const LazySymbolMetadata = struct { |
| 243 | 243 | atom: Atom.Index, |
| 244 | 244 | section: u8, |
| 245 | alignment: u32, |
| 245 | 246 | }; |
| 246 | 247 | |
| 247 | 248 | const DeclMetadata = struct { |
| ... | ... | @@ -1205,7 +1206,6 @@ pub fn createAtom(self: *MachO) !Atom.Index { |
| 1205 | 1206 | .sym_index = sym_index, |
| 1206 | 1207 | .file = null, |
| 1207 | 1208 | .size = 0, |
| 1208 | | .alignment = 0, |
| 1209 | 1209 | .prev_index = null, |
| 1210 | 1210 | .next_index = null, |
| 1211 | 1211 | }; |
| ... | ... | @@ -1217,7 +1217,6 @@ pub fn createGotAtom(self: *MachO, target: SymbolWithLoc) !Atom.Index { |
| 1217 | 1217 | const atom_index = try self.createAtom(); |
| 1218 | 1218 | const atom = self.getAtomPtr(atom_index); |
| 1219 | 1219 | atom.size = @sizeOf(u64); |
| 1220 | | atom.alignment = @alignOf(u64); |
| 1221 | 1220 | |
| 1222 | 1221 | const sym = atom.getSymbolPtr(self); |
| 1223 | 1222 | sym.n_type = macho.N_SECT; |
| ... | ... | @@ -1259,7 +1258,6 @@ pub fn createDyldPrivateAtom(self: *MachO) !void { |
| 1259 | 1258 | const atom_index = try self.createAtom(); |
| 1260 | 1259 | const atom = self.getAtomPtr(atom_index); |
| 1261 | 1260 | atom.size = @sizeOf(u64); |
| 1262 | | atom.alignment = @alignOf(u64); |
| 1263 | 1261 | |
| 1264 | 1262 | const sym = atom.getSymbolPtr(self); |
| 1265 | 1263 | sym.n_type = macho.N_SECT; |
| ... | ... | @@ -1285,7 +1283,8 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { |
| 1285 | 1283 | const atom_index = try self.createAtom(); |
| 1286 | 1284 | const atom = self.getAtomPtr(atom_index); |
| 1287 | 1285 | atom.size = size; |
| 1288 | | atom.alignment = switch (arch) { |
| 1286 | |
| 1287 | const required_alignment: u32 = switch (arch) { |
| 1289 | 1288 | .x86_64 => 1, |
| 1290 | 1289 | .aarch64 => @alignOf(u32), |
| 1291 | 1290 | else => unreachable, |
| ... | ... | @@ -1392,7 +1391,7 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { |
| 1392 | 1391 | } |
| 1393 | 1392 | self.stub_helper_preamble_atom_index = atom_index; |
| 1394 | 1393 | |
| 1395 | | sym.n_value = try self.allocateAtom(atom_index, size, atom.alignment); |
| 1394 | sym.n_value = try self.allocateAtom(atom_index, size, required_alignment); |
| 1396 | 1395 | log.debug("allocated stub preamble atom at 0x{x}", .{sym.n_value}); |
| 1397 | 1396 | try self.writeAtom(atom_index, code); |
| 1398 | 1397 | } |
| ... | ... | @@ -1408,7 +1407,8 @@ pub fn createStubHelperAtom(self: *MachO) !Atom.Index { |
| 1408 | 1407 | const atom_index = try self.createAtom(); |
| 1409 | 1408 | const atom = self.getAtomPtr(atom_index); |
| 1410 | 1409 | atom.size = size; |
| 1411 | | atom.alignment = switch (arch) { |
| 1410 | |
| 1411 | const required_alignment: u32 = switch (arch) { |
| 1412 | 1412 | .x86_64 => 1, |
| 1413 | 1413 | .aarch64 => @alignOf(u32), |
| 1414 | 1414 | else => unreachable, |
| ... | ... | @@ -1470,7 +1470,7 @@ pub fn createStubHelperAtom(self: *MachO) !Atom.Index { |
| 1470 | 1470 | else => unreachable, |
| 1471 | 1471 | } |
| 1472 | 1472 | |
| 1473 | | sym.n_value = try self.allocateAtom(atom_index, size, atom.alignment); |
| 1473 | sym.n_value = try self.allocateAtom(atom_index, size, required_alignment); |
| 1474 | 1474 | log.debug("allocated stub helper atom at 0x{x}", .{sym.n_value}); |
| 1475 | 1475 | try self.writeAtom(atom_index, code); |
| 1476 | 1476 | |
| ... | ... | @@ -1481,7 +1481,6 @@ pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWi |
| 1481 | 1481 | const atom_index = try self.createAtom(); |
| 1482 | 1482 | const atom = self.getAtomPtr(atom_index); |
| 1483 | 1483 | atom.size = @sizeOf(u64); |
| 1484 | | atom.alignment = @alignOf(u64); |
| 1485 | 1484 | |
| 1486 | 1485 | const sym = atom.getSymbolPtr(self); |
| 1487 | 1486 | sym.n_type = macho.N_SECT; |
| ... | ... | @@ -1523,7 +1522,8 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index { |
| 1523 | 1522 | const atom_index = try self.createAtom(); |
| 1524 | 1523 | const atom = self.getAtomPtr(atom_index); |
| 1525 | 1524 | atom.size = size; |
| 1526 | | atom.alignment = switch (arch) { |
| 1525 | |
| 1526 | const required_alignment: u32 = switch (arch) { |
| 1527 | 1527 | .x86_64 => 1, |
| 1528 | 1528 | .aarch64 => @alignOf(u32), |
| 1529 | 1529 | else => unreachable, // unhandled architecture type |
| ... | ... | @@ -1587,7 +1587,7 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index { |
| 1587 | 1587 | else => unreachable, |
| 1588 | 1588 | } |
| 1589 | 1589 | |
| 1590 | | sym.n_value = try self.allocateAtom(atom_index, size, atom.alignment); |
| 1590 | sym.n_value = try self.allocateAtom(atom_index, size, required_alignment); |
| 1591 | 1591 | log.debug("allocated stub atom at 0x{x}", .{sym.n_value}); |
| 1592 | 1592 | try self.writeAtom(atom_index, code); |
| 1593 | 1593 | |
| ... | ... | @@ -2217,7 +2217,6 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu |
| 2217 | 2217 | const required_alignment = typed_value.ty.abiAlignment(self.base.options.target); |
| 2218 | 2218 | const atom = self.getAtomPtr(atom_index); |
| 2219 | 2219 | atom.size = code.len; |
| 2220 | | atom.alignment = required_alignment; |
| 2221 | 2220 | // TODO: work out logic for disambiguating functions from function pointers |
| 2222 | 2221 | // const sect_id = self.getDeclOutputSection(decl_index); |
| 2223 | 2222 | const sect_id = self.data_const_section_index.?; |
| ... | ... | @@ -2355,7 +2354,7 @@ fn updateLazySymbol(self: *MachO, lazy_sym: File.LazySymbol, lazy_metadata: Lazy |
| 2355 | 2354 | }, |
| 2356 | 2355 | }; |
| 2357 | 2356 | |
| 2358 | | const required_alignment = atom.alignment; |
| 2357 | const required_alignment = lazy_metadata.alignment; |
| 2359 | 2358 | const symbol = atom.getSymbolPtr(self); |
| 2360 | 2359 | symbol.n_strx = name_str_index; |
| 2361 | 2360 | symbol.n_type = macho.N_SECT; |
| ... | ... | @@ -2398,8 +2397,8 @@ pub fn getOrCreateAtomForLazySymbol( |
| 2398 | 2397 | .code => self.text_section_index.?, |
| 2399 | 2398 | .const_data => self.data_const_section_index.?, |
| 2400 | 2399 | }, |
| 2400 | .alignment = alignment, |
| 2401 | 2401 | }; |
| 2402 | | self.getAtomPtr(gop.value_ptr.atom).alignment = alignment; |
| 2403 | 2402 | } |
| 2404 | 2403 | return gop.value_ptr.atom; |
| 2405 | 2404 | } |
| ... | ... | @@ -3054,7 +3053,51 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts |
| 3054 | 3053 | return section_id; |
| 3055 | 3054 | } |
| 3056 | 3055 | |
| 3057 | | 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 { |
| 3058 | 3101 | const header = &self.sections.items(.header)[sect_id]; |
| 3059 | 3102 | const segment = self.getSegmentPtr(sect_id); |
| 3060 | 3103 | const increased_size = padToIdeal(needed_size); |
| ... | ... | @@ -3173,45 +3216,9 @@ fn allocateAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignm |
| 3173 | 3216 | else |
| 3174 | 3217 | true; |
| 3175 | 3218 | if (expand_section) { |
| 3176 | | const sect_capacity = self.allocatedSize(header.offset); |
| 3177 | 3219 | const needed_size = (vaddr + new_atom_size) - segment.vmaddr; |
| 3178 | | if (needed_size > sect_capacity) { |
| 3179 | | const new_offset = self.findFreeSpace(needed_size, self.page_size); |
| 3180 | | const current_size = if (maybe_last_atom_index.*) |last_atom_index| blk: { |
| 3181 | | const last_atom = self.getAtom(last_atom_index); |
| 3182 | | const sym = last_atom.getSymbol(self); |
| 3183 | | break :blk (sym.n_value + last_atom.size) - segment.vmaddr; |
| 3184 | | } else 0; |
| 3185 | | |
| 3186 | | log.debug("moving {s},{s} from 0x{x} to 0x{x}", .{ |
| 3187 | | header.segName(), |
| 3188 | | header.sectName(), |
| 3189 | | header.offset, |
| 3190 | | new_offset, |
| 3191 | | }); |
| 3192 | | |
| 3193 | | const amt = try self.base.file.?.copyRangeAll( |
| 3194 | | header.offset, |
| 3195 | | self.base.file.?, |
| 3196 | | new_offset, |
| 3197 | | current_size, |
| 3198 | | ); |
| 3199 | | if (amt != current_size) return error.InputOutput; |
| 3200 | | header.offset = @intCast(u32, new_offset); |
| 3201 | | segment.fileoff = new_offset; |
| 3202 | | } |
| 3203 | | |
| 3204 | | const sect_vm_capacity = self.allocatedVirtualSize(segment.vmaddr); |
| 3205 | | if (needed_size > sect_vm_capacity) { |
| 3206 | | self.markRelocsDirtyByAddress(segment.vmaddr + needed_size); |
| 3207 | | try self.moveSectionInVirtualMemory(sect_id, needed_size); |
| 3208 | | } |
| 3209 | | |
| 3210 | | header.size = needed_size; |
| 3211 | | segment.filesize = mem.alignForwardGeneric(u64, needed_size, self.page_size); |
| 3212 | | segment.vmsize = mem.alignForwardGeneric(u64, needed_size, self.page_size); |
| 3220 | try self.growSection(sect_id, needed_size); |
| 3213 | 3221 | maybe_last_atom_index.* = atom_index; |
| 3214 | | |
| 3215 | 3222 | self.segment_table_dirty = true; |
| 3216 | 3223 | } |
| 3217 | 3224 | |
| ... | ... | @@ -3219,11 +3226,7 @@ fn allocateAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignm |
| 3219 | 3226 | if (header.@"align" < align_pow) { |
| 3220 | 3227 | header.@"align" = align_pow; |
| 3221 | 3228 | } |
| 3222 | | { |
| 3223 | | const atom_ptr = self.getAtomPtr(atom_index); |
| 3224 | | atom_ptr.size = new_atom_size; |
| 3225 | | atom_ptr.alignment = @intCast(u32, alignment); |
| 3226 | | } |
| 3229 | self.getAtomPtr(atom_index).size = new_atom_size; |
| 3227 | 3230 | |
| 3228 | 3231 | if (atom.prev_index) |prev_index| { |
| 3229 | 3232 | const prev = self.getAtomPtr(prev_index); |
| ... | ... | @@ -4510,12 +4513,11 @@ pub fn logAtom(self: *MachO, atom_index: Atom.Index) void { |
| 4510 | 4513 | const atom = self.getAtom(atom_index); |
| 4511 | 4514 | const sym = atom.getSymbol(self); |
| 4512 | 4515 | const sym_name = atom.getName(self); |
| 4513 | | log.debug(" ATOM(%{?d}, '{s}') @ {x} (sizeof({x}), alignof({x})) in object({?d}) in sect({d})", .{ |
| 4516 | log.debug(" ATOM(%{?d}, '{s}') @ {x} sizeof({x}) in object({?d}) in sect({d})", .{ |
| 4514 | 4517 | atom.getSymbolIndex(), |
| 4515 | 4518 | sym_name, |
| 4516 | 4519 | sym.n_value, |
| 4517 | 4520 | atom.size, |
| 4518 | | atom.alignment, |
| 4519 | 4521 | atom.file, |
| 4520 | 4522 | sym.n_sect, |
| 4521 | 4523 | }); |