| ... | @@ -286,9 +286,9 @@ const default_dyld_path: [*:0]const u8 = "/usr/lib/dyld"; | ... | @@ -286,9 +286,9 @@ const default_dyld_path: [*:0]const u8 = "/usr/lib/dyld"; |
| 286 | const minimum_text_block_size = 64; | 286 | const minimum_text_block_size = 64; |
| 287 | pub const min_text_capacity = padToIdeal(minimum_text_block_size); | 287 | pub const min_text_capacity = padToIdeal(minimum_text_block_size); |
| 288 | | 288 | |
| 289 | /// Virtual memory offset corresponds to the size of __PAGEZERO segment and | 289 | /// Default virtual memory offset corresponds to the size of __PAGEZERO segment and |
| 290 | /// start of __TEXT segment. | 290 | /// start of __TEXT segment. |
| 291 | const pagezero_vmsize: u64 = 0x100000000; | 291 | const default_pagezero_vmsize: u64 = 0x100000000; |
| 292 | | 292 | |
| 293 | pub const Export = struct { | 293 | pub const Export = struct { |
| 294 | sym_index: ?u32 = null, | 294 | sym_index: ?u32 = null, |
| ... | @@ -549,7 +549,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No | ... | @@ -549,7 +549,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 549 | // We can skip hashing libc and libc++ components that we are in charge of building from Zig | 549 | // We can skip hashing libc and libc++ components that we are in charge of building from Zig |
| 550 | // installation sources because they are always a product of the compiler version + target information. | 550 | // installation sources because they are always a product of the compiler version + target information. |
| 551 | man.hash.add(stack_size); | 551 | man.hash.add(stack_size); |
| 552 | if (self.base.options.pagezero_size) |value| man.hash.add(value); | 552 | man.hash.addOptional(self.base.options.pagezero_size); |
| 553 | man.hash.addListOfBytes(self.base.options.lib_dirs); | 553 | man.hash.addListOfBytes(self.base.options.lib_dirs); |
| 554 | man.hash.addListOfBytes(self.base.options.framework_dirs); | 554 | man.hash.addListOfBytes(self.base.options.framework_dirs); |
| 555 | man.hash.addListOfBytes(self.base.options.frameworks); | 555 | man.hash.addListOfBytes(self.base.options.frameworks); |
| ... | @@ -4366,14 +4366,21 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil | ... | @@ -4366,14 +4366,21 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil |
| 4366 | | 4366 | |
| 4367 | fn populateMissingMetadata(self: *MachO) !void { | 4367 | fn populateMissingMetadata(self: *MachO) !void { |
| 4368 | const cpu_arch = self.base.options.target.cpu.arch; | 4368 | const cpu_arch = self.base.options.target.cpu.arch; |
| 4369 | | 4369 | const pagezero_vmsize = self.base.options.pagezero_size orelse default_pagezero_vmsize; |
| 4370 | if (self.pagezero_segment_cmd_index == null) { | 4370 | const aligned_pagezero_vmsize = mem.alignBackwardGeneric(u64, pagezero_vmsize, self.page_size); |
| | 4371 | |
| | 4372 | if (self.pagezero_segment_cmd_index == null) blk: { |
| | 4373 | if (aligned_pagezero_vmsize == 0) break :blk; |
| | 4374 | if (aligned_pagezero_vmsize != pagezero_vmsize) { |
| | 4375 | log.warn("requested __PAGEZERO size is not page aligned", .{}); |
| | 4376 | log.warn(" rounding down to 0x{x}", .{aligned_pagezero_vmsize}); |
| | 4377 | } |
| 4371 | self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len); | 4378 | self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4372 | try self.load_commands.append(self.base.allocator, .{ | 4379 | try self.load_commands.append(self.base.allocator, .{ |
| 4373 | .segment = .{ | 4380 | .segment = .{ |
| 4374 | .inner = .{ | 4381 | .inner = .{ |
| 4375 | .segname = makeStaticString("__PAGEZERO"), | 4382 | .segname = makeStaticString("__PAGEZERO"), |
| 4376 | .vmsize = self.base.options.pagezero_size orelse pagezero_vmsize, | 4383 | .vmsize = aligned_pagezero_vmsize, |
| 4377 | .cmdsize = @sizeOf(macho.segment_command_64), | 4384 | .cmdsize = @sizeOf(macho.segment_command_64), |
| 4378 | }, | 4385 | }, |
| 4379 | }, | 4386 | }, |
| ... | @@ -4395,7 +4402,7 @@ fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4395,7 +4402,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 4395 | .segment = .{ | 4402 | .segment = .{ |
| 4396 | .inner = .{ | 4403 | .inner = .{ |
| 4397 | .segname = makeStaticString("__TEXT"), | 4404 | .segname = makeStaticString("__TEXT"), |
| 4398 | .vmaddr = self.base.options.pagezero_size orelse pagezero_vmsize, | 4405 | .vmaddr = aligned_pagezero_vmsize, |
| 4399 | .vmsize = needed_size, | 4406 | .vmsize = needed_size, |
| 4400 | .filesize = needed_size, | 4407 | .filesize = needed_size, |
| 4401 | .maxprot = macho.PROT.READ | macho.PROT.EXEC, | 4408 | .maxprot = macho.PROT.READ | macho.PROT.EXEC, |
| ... | @@ -4882,7 +4889,10 @@ fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4882,7 +4889,10 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 4882 | | 4889 | |
| 4883 | fn allocateTextSegment(self: *MachO) !void { | 4890 | fn allocateTextSegment(self: *MachO) !void { |
| 4884 | const seg = &self.load_commands.items[self.text_segment_cmd_index.?].segment; | 4891 | const seg = &self.load_commands.items[self.text_segment_cmd_index.?].segment; |
| 4885 | const base_vmaddr = self.load_commands.items[self.pagezero_segment_cmd_index.?].segment.inner.vmsize; | 4892 | const base_vmaddr = if (self.pagezero_segment_cmd_index) |index| |
| | 4893 | self.load_commands.items[index].segment.inner.vmsize |
| | 4894 | else |
| | 4895 | 0; |
| 4886 | seg.inner.fileoff = 0; | 4896 | seg.inner.fileoff = 0; |
| 4887 | seg.inner.vmaddr = base_vmaddr; | 4897 | seg.inner.vmaddr = base_vmaddr; |
| 4888 | | 4898 | |