| ... | @@ -73,6 +73,10 @@ const LoadCommand = union(enum) { | ... | @@ -73,6 +73,10 @@ const LoadCommand = union(enum) { |
| 73 | | 73 | |
| 74 | base: File, | 74 | base: File, |
| 75 | | 75 | |
| | 76 | /// Page size is dependent on the target cpu architecture. |
| | 77 | /// For x86_64 that's 4KB, whereas for aarch64, that's 16KB. |
| | 78 | page_size: u16, |
| | 79 | |
| 76 | /// Table of all load commands | 80 | /// Table of all load commands |
| 77 | load_commands: std.ArrayListUnmanaged(LoadCommand) = .{}, | 81 | load_commands: std.ArrayListUnmanaged(LoadCommand) = .{}, |
| 78 | /// __PAGEZERO segment | 82 | /// __PAGEZERO segment |
| ... | @@ -301,6 +305,7 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*MachO { | ... | @@ -301,6 +305,7 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*MachO { |
| 301 | .allocator = gpa, | 305 | .allocator = gpa, |
| 302 | .file = null, | 306 | .file = null, |
| 303 | }, | 307 | }, |
| | 308 | .page_size = if (options.target.cpu.arch == .aarch64) 0x4000 else 0x1000, |
| 304 | }; | 309 | }; |
| 305 | return self; | 310 | return self; |
| 306 | } | 311 | } |
| ... | @@ -387,7 +392,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { | ... | @@ -387,7 +392,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 387 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; | 392 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; |
| 388 | const file_size = symtab.stroff + symtab.strsize - linkedit.fileoff; | 393 | const file_size = symtab.stroff + symtab.strsize - linkedit.fileoff; |
| 389 | linkedit.filesize = file_size; | 394 | linkedit.filesize = file_size; |
| 390 | linkedit.vmsize = mem.alignForwardGeneric(u64, file_size, 0x4000); | 395 | linkedit.vmsize = mem.alignForwardGeneric(u64, file_size, self.page_size); |
| 391 | } | 396 | } |
| 392 | | 397 | |
| 393 | if (self.cmd_table_dirty) { | 398 | if (self.cmd_table_dirty) { |
| ... | @@ -1163,8 +1168,8 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -1163,8 +1168,8 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 1163 | | 1168 | |
| 1164 | // const program_code_size_hint = self.base.options.program_code_size_hint; | 1169 | // const program_code_size_hint = self.base.options.program_code_size_hint; |
| 1165 | const program_code_size_hint = 128; | 1170 | const program_code_size_hint = 128; |
| 1166 | const file_size = mem.alignForwardGeneric(u64, program_code_size_hint, 0x4000); | 1171 | const file_size = mem.alignForwardGeneric(u64, program_code_size_hint, self.page_size); |
| 1167 | const off = @intCast(u32, self.findFreeSpace(file_size, 0x4000)); // TODO maybe findFreeSpace should return u32 directly? | 1172 | const off = @intCast(u32, self.findFreeSpace(file_size, self.page_size)); // TODO maybe findFreeSpace should return u32 directly? |
| 1168 | const flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS; | 1173 | const flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS; |
| 1169 | | 1174 | |
| 1170 | log.debug("found __text section free space 0x{x} to 0x{x}\n", .{ off, off + file_size }); | 1175 | log.debug("found __text section free space 0x{x} to 0x{x}\n", .{ off, off + file_size }); |
| ... | @@ -1237,7 +1242,7 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -1237,7 +1242,7 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 1237 | .reserved3 = 0, | 1242 | .reserved3 = 0, |
| 1238 | }); | 1243 | }); |
| 1239 | | 1244 | |
| 1240 | const segment_size = mem.alignForwardGeneric(u64, file_size, 0x4000); | 1245 | const segment_size = mem.alignForwardGeneric(u64, file_size, self.page_size); |
| 1241 | data_segment.vmsize = segment_size; | 1246 | data_segment.vmsize = segment_size; |
| 1242 | data_segment.filesize = segment_size; | 1247 | data_segment.filesize = segment_size; |
| 1243 | data_segment.fileoff = off; | 1248 | data_segment.fileoff = off; |