| ... | @@ -2839,7 +2839,9 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu | ... | @@ -2839,7 +2839,9 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu |
| 2839 | const required_alignment = typed_value.ty.abiAlignment(self.base.options.target); | 2839 | const required_alignment = typed_value.ty.abiAlignment(self.base.options.target); |
| 2840 | atom.size = code.len; | 2840 | atom.size = code.len; |
| 2841 | atom.alignment = required_alignment; | 2841 | atom.alignment = required_alignment; |
| 2842 | const sect_id = self.getDeclOutputSection(decl); | 2842 | // TODO: work out logic for disambiguating functions from function pointers |
| | 2843 | // const sect_id = self.getDeclOutputSection(decl); |
| | 2844 | const sect_id = self.data_const_section_index.?; |
| 2843 | const symbol = atom.getSymbolPtr(self); | 2845 | const symbol = atom.getSymbolPtr(self); |
| 2844 | symbol.n_strx = name_str_index; | 2846 | symbol.n_strx = name_str_index; |
| 2845 | symbol.n_type = macho.N_SECT; | 2847 | symbol.n_type = macho.N_SECT; |
| ... | @@ -2956,6 +2958,7 @@ fn getDeclOutputSection(self: *MachO, decl: *Module.Decl) u8 { | ... | @@ -2956,6 +2958,7 @@ fn getDeclOutputSection(self: *MachO, decl: *Module.Decl) u8 { |
| 2956 | } | 2958 | } |
| 2957 | | 2959 | |
| 2958 | switch (zig_ty) { | 2960 | switch (zig_ty) { |
| | 2961 | // TODO: what if this is a function pointer? |
| 2959 | .Fn => break :blk self.text_section_index.?, | 2962 | .Fn => break :blk self.text_section_index.?, |
| 2960 | else => { | 2963 | else => { |
| 2961 | if (val.castTag(.variable)) |_| { | 2964 | if (val.castTag(.variable)) |_| { |
| ... | @@ -3709,6 +3712,41 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts | ... | @@ -3709,6 +3712,41 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts |
| 3709 | return section_id; | 3712 | return section_id; |
| 3710 | } | 3713 | } |
| 3711 | | 3714 | |
| | 3715 | fn moveSectionInVirtualMemory(self: *MachO, sect_id: u32, needed_size: u64) !void { |
| | 3716 | const header = &self.sections.items(.header)[sect_id]; |
| | 3717 | const segment = &self.segments.items[self.sections.items(.segment_index)[sect_id]]; |
| | 3718 | const increased_size = padToIdeal(needed_size); |
| | 3719 | const old_aligned_end = segment.vmaddr + segment.vmsize; |
| | 3720 | const new_aligned_end = segment.vmaddr + mem.alignForwardGeneric(u64, increased_size, self.page_size); |
| | 3721 | const diff = new_aligned_end - old_aligned_end; |
| | 3722 | log.debug("shifting every segment after {s},{s} in virtual memory by {x}", .{ |
| | 3723 | header.segName(), |
| | 3724 | header.sectName(), |
| | 3725 | diff, |
| | 3726 | }); |
| | 3727 | |
| | 3728 | // TODO: enforce order by increasing VM addresses in self.sections container. |
| | 3729 | for (self.sections.items(.header)[sect_id + 1 ..]) |*next_header, next_sect_id| { |
| | 3730 | const index = sect_id + 1 + next_sect_id; |
| | 3731 | const maybe_last_atom = &self.sections.items(.last_atom)[index]; |
| | 3732 | const next_segment = &self.segments.items[self.sections.items(.segment_index)[index]]; |
| | 3733 | next_header.addr += diff; |
| | 3734 | next_segment.vmaddr += diff; |
| | 3735 | |
| | 3736 | if (maybe_last_atom.*) |last_atom| { |
| | 3737 | var atom = last_atom; |
| | 3738 | while (true) { |
| | 3739 | const sym = atom.getSymbolPtr(self); |
| | 3740 | sym.n_value += diff; |
| | 3741 | |
| | 3742 | if (atom.prev) |prev| { |
| | 3743 | atom = prev; |
| | 3744 | } else break; |
| | 3745 | } |
| | 3746 | } |
| | 3747 | } |
| | 3748 | } |
| | 3749 | |
| 3712 | fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64) !u64 { | 3750 | fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64) !u64 { |
| 3713 | const tracy = trace(@src()); | 3751 | const tracy = trace(@src()); |
| 3714 | defer tracy.end(); | 3752 | defer tracy.end(); |
| ... | @@ -3816,13 +3854,12 @@ fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64) ! | ... | @@ -3816,13 +3854,12 @@ fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64) ! |
| 3816 | const sect_vm_capacity = self.allocatedVirtualSize(segment.vmaddr); | 3854 | const sect_vm_capacity = self.allocatedVirtualSize(segment.vmaddr); |
| 3817 | if (needed_size > sect_vm_capacity) { | 3855 | if (needed_size > sect_vm_capacity) { |
| 3818 | self.markRelocsDirtyByAddress(segment.vmaddr + needed_size); | 3856 | self.markRelocsDirtyByAddress(segment.vmaddr + needed_size); |
| 3819 | @panic("TODO grow section in VM"); | 3857 | try self.moveSectionInVirtualMemory(sect_id, needed_size); |
| 3820 | } | 3858 | } |
| 3821 | | 3859 | |
| 3822 | header.size = needed_size; | 3860 | header.size = needed_size; |
| 3823 | segment.filesize = needed_size; | 3861 | segment.filesize = needed_size; |
| 3824 | segment.vmsize = mem.alignForwardGeneric(u64, needed_size, self.page_size); | 3862 | segment.vmsize = mem.alignForwardGeneric(u64, needed_size, self.page_size); |
| 3825 | log.warn("updating {s},{s}: {x}, {x}", .{ header.segName(), header.sectName(), segment.vmsize, segment.filesize }); | | |
| 3826 | maybe_last_atom.* = atom; | 3863 | maybe_last_atom.* = atom; |
| 3827 | | 3864 | |
| 3828 | self.segment_table_dirty = true; | 3865 | self.segment_table_dirty = true; |