| author | |
| committer | |
| log | b2773cd7120f7120410e1635aaeec026c7bbcdd1 |
| tree | cd7defea6ddbd23930c3e168b066cfbd75febe61 |
| parent | 180979ee41e7374ee1b8bc941e2281bb44e41dfd |
4 files changed, 85 insertions(+), 67 deletions(-)
src/link/MachO.zig+36-14| ... | ... | @@ -2739,6 +2739,34 @@ fn calcPagezeroSize(self: *MachO) u64 { |
| 2739 | 2739 | return aligned_pagezero_vmsize; |
| 2740 | 2740 | } |
| 2741 | 2741 | |
| 2742 | const InitSectionOpts = struct { | |
| 2743 | flags: u32 = macho.S_REGULAR, | |
| 2744 | reserved1: u32 = 0, | |
| 2745 | reserved2: u32 = 0, | |
| 2746 | }; | |
| 2747 | ||
| 2748 | pub fn initSection( | |
| 2749 | gpa: Allocator, | |
| 2750 | ctx: anytype, | |
| 2751 | segname: []const u8, | |
| 2752 | sectname: []const u8, | |
| 2753 | opts: InitSectionOpts, | |
| 2754 | ) !u8 { | |
| 2755 | log.debug("creating section '{s},{s}'", .{ segname, sectname }); | |
| 2756 | const index = @as(u8, @intCast(ctx.sections.slice().len)); | |
| 2757 | try ctx.sections.append(gpa, .{ | |
| 2758 | .segment_index = undefined, // Segments will be created automatically later down the pipeline | |
| 2759 | .header = .{ | |
| 2760 | .sectname = makeStaticString(sectname), | |
| 2761 | .segname = makeStaticString(segname), | |
| 2762 | .flags = opts.flags, | |
| 2763 | .reserved1 = opts.reserved1, | |
| 2764 | .reserved2 = opts.reserved2, | |
| 2765 | }, | |
| 2766 | }); | |
| 2767 | return index; | |
| 2768 | } | |
| 2769 | ||
| 2742 | 2770 | fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts: struct { |
| 2743 | 2771 | size: u64 = 0, |
| 2744 | 2772 | alignment: u32 = 0, |
| ... | ... | @@ -2751,7 +2779,6 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts |
| 2751 | 2779 | // In incremental context, we create one section per segment pairing. This way, |
| 2752 | 2780 | // we can move the segment in raw file as we please. |
| 2753 | 2781 | const segment_id = @as(u8, @intCast(self.segments.items.len)); |
| 2754 | const section_id = @as(u8, @intCast(self.sections.slice().len)); | |
| 2755 | 2782 | const vmaddr = blk: { |
| 2756 | 2783 | const prev_segment = self.segments.items[segment_id - 1]; |
| 2757 | 2784 | break :blk mem.alignForward(u64, prev_segment.vmaddr + prev_segment.vmsize, page_size); |
| ... | ... | @@ -2782,23 +2809,18 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts |
| 2782 | 2809 | .cmdsize = @sizeOf(macho.segment_command_64) + @sizeOf(macho.section_64), |
| 2783 | 2810 | }; |
| 2784 | 2811 | |
| 2785 | var section = macho.section_64{ | |
| 2786 | .sectname = makeStaticString(sectname), | |
| 2787 | .segname = makeStaticString(segname), | |
| 2788 | .addr = mem.alignForward(u64, vmaddr, opts.alignment), | |
| 2789 | .offset = mem.alignForward(u32, @as(u32, @intCast(off)), opts.alignment), | |
| 2790 | .size = opts.size, | |
| 2791 | .@"align" = math.log2(opts.alignment), | |
| 2812 | const sect_id = try initSection(gpa, self, sectname, segname, .{ | |
| 2792 | 2813 | .flags = opts.flags, |
| 2793 | 2814 | .reserved2 = opts.reserved2, |
| 2794 | }; | |
| 2815 | }); | |
| 2816 | const section = &self.sections.items(.header)[sect_id]; | |
| 2817 | section.addr = mem.alignForward(u64, vmaddr, opts.alignment); | |
| 2818 | section.offset = mem.alignForward(u32, @as(u32, @intCast(off)), opts.alignment); | |
| 2819 | section.size = opts.size; | |
| 2820 | section.@"align" = math.log2(opts.alignment); | |
| 2795 | 2821 | assert(!section.isZerofill()); // TODO zerofill sections |
| 2796 | 2822 | |
| 2797 | try self.sections.append(gpa, .{ | |
| 2798 | .segment_index = segment_id, | |
| 2799 | .header = section, | |
| 2800 | }); | |
| 2801 | return section_id; | |
| 2823 | return sect_id; | |
| 2802 | 2824 | } |
| 2803 | 2825 | |
| 2804 | 2826 | fn growSection(self: *MachO, sect_id: u8, needed_size: u64) !void { |
src/link/MachO/Atom.zig+35-11| ... | ... | @@ -106,6 +106,7 @@ pub fn freeListEligible(self: Atom, macho_file: *MachO) bool { |
| 106 | 106 | } |
| 107 | 107 | |
| 108 | 108 | pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 { |
| 109 | const gpa = zld.gpa; | |
| 109 | 110 | const segname = sect.segName(); |
| 110 | 111 | const sectname = sect.sectName(); |
| 111 | 112 | const res: ?u8 = blk: { |
| ... | ... | @@ -126,7 +127,9 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 { |
| 126 | 127 | |
| 127 | 128 | if (sect.isCode()) { |
| 128 | 129 | if (zld.text_section_index == null) { |
| 129 | zld.text_section_index = try zld.initSection( | |
| 130 | zld.text_section_index = try MachO.initSection( | |
| 131 | gpa, | |
| 132 | zld, | |
| 130 | 133 | "__TEXT", |
| 131 | 134 | "__text", |
| 132 | 135 | .{ |
| ... | ... | @@ -148,7 +151,9 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 { |
| 148 | 151 | macho.S_8BYTE_LITERALS, |
| 149 | 152 | macho.S_16BYTE_LITERALS, |
| 150 | 153 | => { |
| 151 | break :blk zld.getSectionByName("__TEXT", "__const") orelse try zld.initSection( | |
| 154 | break :blk zld.getSectionByName("__TEXT", "__const") orelse try MachO.initSection( | |
| 155 | gpa, | |
| 156 | zld, | |
| 152 | 157 | "__TEXT", |
| 153 | 158 | "__const", |
| 154 | 159 | .{}, |
| ... | ... | @@ -156,13 +161,17 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 { |
| 156 | 161 | }, |
| 157 | 162 | macho.S_CSTRING_LITERALS => { |
| 158 | 163 | if (mem.startsWith(u8, sectname, "__objc")) { |
| 159 | break :blk zld.getSectionByName(segname, sectname) orelse try zld.initSection( | |
| 164 | break :blk zld.getSectionByName(segname, sectname) orelse try MachO.initSection( | |
| 165 | gpa, | |
| 166 | zld, | |
| 160 | 167 | segname, |
| 161 | 168 | sectname, |
| 162 | 169 | .{}, |
| 163 | 170 | ); |
| 164 | 171 | } |
| 165 | break :blk zld.getSectionByName("__TEXT", "__cstring") orelse try zld.initSection( | |
| 172 | break :blk zld.getSectionByName("__TEXT", "__cstring") orelse try MachO.initSection( | |
| 173 | gpa, | |
| 174 | zld, | |
| 166 | 175 | "__TEXT", |
| 167 | 176 | "__cstring", |
| 168 | 177 | .{ .flags = macho.S_CSTRING_LITERALS }, |
| ... | ... | @@ -171,7 +180,9 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 { |
| 171 | 180 | macho.S_MOD_INIT_FUNC_POINTERS, |
| 172 | 181 | macho.S_MOD_TERM_FUNC_POINTERS, |
| 173 | 182 | => { |
| 174 | break :blk zld.getSectionByName("__DATA_CONST", sectname) orelse try zld.initSection( | |
| 183 | break :blk zld.getSectionByName("__DATA_CONST", sectname) orelse try MachO.initSection( | |
| 184 | gpa, | |
| 185 | zld, | |
| 175 | 186 | "__DATA_CONST", |
| 176 | 187 | sectname, |
| 177 | 188 | .{ .flags = sect.flags }, |
| ... | ... | @@ -184,14 +195,19 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 { |
| 184 | 195 | macho.S_THREAD_LOCAL_REGULAR, |
| 185 | 196 | macho.S_THREAD_LOCAL_ZEROFILL, |
| 186 | 197 | => { |
| 187 | break :blk zld.getSectionByName(segname, sectname) orelse try zld.initSection( | |
| 198 | break :blk zld.getSectionByName(segname, sectname) orelse try MachO.initSection( | |
| 199 | gpa, | |
| 200 | zld, | |
| 188 | 201 | segname, |
| 189 | 202 | sectname, |
| 190 | 203 | .{ .flags = sect.flags }, |
| 191 | 204 | ); |
| 192 | 205 | }, |
| 193 | 206 | macho.S_COALESCED => { |
| 194 | break :blk zld.getSectionByName(segname, sectname) orelse try zld.initSection( | |
| 207 | break :blk zld.getSectionByName(segname, sectname) orelse try MachO.initSection( | |
| 208 | gpa, | |
| 209 | zld, | |
| 210 | ||
| 195 | 211 | segname, |
| 196 | 212 | sectname, |
| 197 | 213 | .{}, |
| ... | ... | @@ -205,7 +221,9 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 { |
| 205 | 221 | mem.eql(u8, sectname, "__gosymtab") or |
| 206 | 222 | mem.eql(u8, sectname, "__gopclntab")) |
| 207 | 223 | { |
| 208 | break :blk zld.getSectionByName("__TEXT", sectname) orelse try zld.initSection( | |
| 224 | break :blk zld.getSectionByName("__TEXT", sectname) orelse try MachO.initSection( | |
| 225 | gpa, | |
| 226 | zld, | |
| 209 | 227 | "__TEXT", |
| 210 | 228 | sectname, |
| 211 | 229 | .{}, |
| ... | ... | @@ -218,20 +236,26 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 { |
| 218 | 236 | mem.eql(u8, sectname, "__objc_classlist") or |
| 219 | 237 | mem.eql(u8, sectname, "__objc_imageinfo")) |
| 220 | 238 | { |
| 221 | break :blk zld.getSectionByName("__DATA_CONST", sectname) orelse try zld.initSection( | |
| 239 | break :blk zld.getSectionByName("__DATA_CONST", sectname) orelse try MachO.initSection( | |
| 240 | gpa, | |
| 241 | zld, | |
| 222 | 242 | "__DATA_CONST", |
| 223 | 243 | sectname, |
| 224 | 244 | .{}, |
| 225 | 245 | ); |
| 226 | 246 | } else if (mem.eql(u8, sectname, "__data")) { |
| 227 | break :blk zld.getSectionByName("__DATA", "__data") orelse try zld.initSection( | |
| 247 | break :blk zld.getSectionByName("__DATA", "__data") orelse try MachO.initSection( | |
| 248 | gpa, | |
| 249 | zld, | |
| 228 | 250 | "__DATA", |
| 229 | 251 | "__data", |
| 230 | 252 | .{}, |
| 231 | 253 | ); |
| 232 | 254 | } |
| 233 | 255 | } |
| 234 | break :blk zld.getSectionByName(segname, sectname) orelse try zld.initSection( | |
| 256 | break :blk zld.getSectionByName(segname, sectname) orelse try MachO.initSection( | |
| 257 | gpa, | |
| 258 | zld, | |
| 235 | 259 | segname, |
| 236 | 260 | sectname, |
| 237 | 261 | .{}, |
src/link/MachO/Object.zig+7-7| ... | ... | @@ -685,11 +685,12 @@ fn parseEhFrameSection(self: *Object, zld: *Zld, object_id: u32) !void { |
| 685 | 685 | |
| 686 | 686 | log.debug("parsing __TEXT,__eh_frame section", .{}); |
| 687 | 687 | |
| 688 | const gpa = zld.gpa; | |
| 689 | ||
| 688 | 690 | if (zld.getSectionByName("__TEXT", "__eh_frame") == null) { |
| 689 | _ = try zld.initSection("__TEXT", "__eh_frame", .{}); | |
| 691 | _ = try MachO.initSection(gpa, zld, "__TEXT", "__eh_frame", .{}); | |
| 690 | 692 | } |
| 691 | 693 | |
| 692 | const gpa = zld.gpa; | |
| 693 | 694 | const cpu_arch = zld.options.target.cpu.arch; |
| 694 | 695 | try self.parseRelocs(gpa, sect_id); |
| 695 | 696 | const relocs = self.getRelocs(sect_id); |
| ... | ... | @@ -779,6 +780,8 @@ fn parseEhFrameSection(self: *Object, zld: *Zld, object_id: u32) !void { |
| 779 | 780 | } |
| 780 | 781 | |
| 781 | 782 | fn parseUnwindInfo(self: *Object, zld: *Zld, object_id: u32) !void { |
| 783 | const gpa = zld.gpa; | |
| 784 | const cpu_arch = zld.options.target.cpu.arch; | |
| 782 | 785 | const sect_id = self.unwind_info_sect_id orelse { |
| 783 | 786 | // If it so happens that the object had `__eh_frame` section defined but no `__compact_unwind`, |
| 784 | 787 | // we will try fully synthesising unwind info records to somewhat match Apple ld's |
| ... | ... | @@ -786,7 +789,7 @@ fn parseUnwindInfo(self: *Object, zld: *Zld, object_id: u32) !void { |
| 786 | 789 | // we still create the output `__TEXT,__unwind_info` section. |
| 787 | 790 | if (self.hasEhFrameRecords()) { |
| 788 | 791 | if (zld.getSectionByName("__TEXT", "__unwind_info") == null) { |
| 789 | _ = try zld.initSection("__TEXT", "__unwind_info", .{}); | |
| 792 | _ = try MachO.initSection(gpa, zld, "__TEXT", "__unwind_info", .{}); | |
| 790 | 793 | } |
| 791 | 794 | } |
| 792 | 795 | return; |
| ... | ... | @@ -794,11 +797,8 @@ fn parseUnwindInfo(self: *Object, zld: *Zld, object_id: u32) !void { |
| 794 | 797 | |
| 795 | 798 | log.debug("parsing unwind info in {s}", .{self.name}); |
| 796 | 799 | |
| 797 | const gpa = zld.gpa; | |
| 798 | const cpu_arch = zld.options.target.cpu.arch; | |
| 799 | ||
| 800 | 800 | if (zld.getSectionByName("__TEXT", "__unwind_info") == null) { |
| 801 | _ = try zld.initSection("__TEXT", "__unwind_info", .{}); | |
| 801 | _ = try MachO.initSection(gpa, zld, "__TEXT", "__unwind_info", .{}); | |
| 802 | 802 | } |
| 803 | 803 | |
| 804 | 804 | const unwind_records = self.getUnwindRecords(); |
src/link/MachO/zld.zig+7-35| ... | ... | @@ -141,7 +141,7 @@ pub const Zld = struct { |
| 141 | 141 | sym.n_type = macho.N_SECT; |
| 142 | 142 | |
| 143 | 143 | const sect_id = self.getSectionByName("__DATA", "__data") orelse |
| 144 | try self.initSection("__DATA", "__data", .{}); | |
| 144 | try MachO.initSection(self.gpa, self, "__DATA", "__data", .{}); | |
| 145 | 145 | sym.n_sect = sect_id + 1; |
| 146 | 146 | self.dyld_private_atom_index = atom_index; |
| 147 | 147 | |
| ... | ... | @@ -165,7 +165,7 @@ pub const Zld = struct { |
| 165 | 165 | const size = sym.n_value; |
| 166 | 166 | const alignment = (sym.n_desc >> 8) & 0x0f; |
| 167 | 167 | const sect_id = self.getSectionByName("__DATA", "__bss") orelse |
| 168 | try self.initSection("__DATA", "__bss", .{ .flags = macho.S_ZEROFILL }); | |
| 168 | try MachO.initSection(gpa, self, "__DATA", "__bss", .{ .flags = macho.S_ZEROFILL }); | |
| 169 | 169 | |
| 170 | 170 | sym.* = .{ |
| 171 | 171 | .n_strx = sym.n_strx, |
| ... | ... | @@ -619,7 +619,7 @@ pub const Zld = struct { |
| 619 | 619 | if (self.got_table.lookup.contains(target)) return; |
| 620 | 620 | _ = try self.got_table.allocateEntry(self.gpa, target); |
| 621 | 621 | if (self.got_section_index == null) { |
| 622 | self.got_section_index = try self.initSection("__DATA_CONST", "__got", .{ | |
| 622 | self.got_section_index = try MachO.initSection(self.gpa, self, "__DATA_CONST", "__got", .{ | |
| 623 | 623 | .flags = macho.S_NON_LAZY_SYMBOL_POINTERS, |
| 624 | 624 | }); |
| 625 | 625 | } |
| ... | ... | @@ -629,7 +629,7 @@ pub const Zld = struct { |
| 629 | 629 | if (self.tlv_ptr_table.lookup.contains(target)) return; |
| 630 | 630 | _ = try self.tlv_ptr_table.allocateEntry(self.gpa, target); |
| 631 | 631 | if (self.tlv_ptr_section_index == null) { |
| 632 | self.tlv_ptr_section_index = try self.initSection("__DATA", "__thread_ptrs", .{ | |
| 632 | self.tlv_ptr_section_index = try MachO.initSection(self.gpa, self, "__DATA", "__thread_ptrs", .{ | |
| 633 | 633 | .flags = macho.S_THREAD_LOCAL_VARIABLE_POINTERS, |
| 634 | 634 | }); |
| 635 | 635 | } |
| ... | ... | @@ -639,18 +639,18 @@ pub const Zld = struct { |
| 639 | 639 | if (self.stubs_table.lookup.contains(target)) return; |
| 640 | 640 | _ = try self.stubs_table.allocateEntry(self.gpa, target); |
| 641 | 641 | if (self.stubs_section_index == null) { |
| 642 | self.stubs_section_index = try self.initSection("__TEXT", "__stubs", .{ | |
| 642 | self.stubs_section_index = try MachO.initSection(self.gpa, self, "__TEXT", "__stubs", .{ | |
| 643 | 643 | .flags = macho.S_SYMBOL_STUBS | |
| 644 | 644 | macho.S_ATTR_PURE_INSTRUCTIONS | |
| 645 | 645 | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 646 | 646 | .reserved2 = stubs.stubSize(self.options.target.cpu.arch), |
| 647 | 647 | }); |
| 648 | self.stub_helper_section_index = try self.initSection("__TEXT", "__stub_helper", .{ | |
| 648 | self.stub_helper_section_index = try MachO.initSection(self.gpa, self, "__TEXT", "__stub_helper", .{ | |
| 649 | 649 | .flags = macho.S_REGULAR | |
| 650 | 650 | macho.S_ATTR_PURE_INSTRUCTIONS | |
| 651 | 651 | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 652 | 652 | }); |
| 653 | self.la_symbol_ptr_section_index = try self.initSection("__DATA", "__la_symbol_ptr", .{ | |
| 653 | self.la_symbol_ptr_section_index = try MachO.initSection(self.gpa, self, "__DATA", "__la_symbol_ptr", .{ | |
| 654 | 654 | .flags = macho.S_LAZY_SYMBOL_POINTERS, |
| 655 | 655 | }); |
| 656 | 656 | } |
| ... | ... | @@ -1152,34 +1152,6 @@ pub const Zld = struct { |
| 1152 | 1152 | segment.vmsize = mem.alignForward(u64, segment.vmsize, page_size); |
| 1153 | 1153 | } |
| 1154 | 1154 | |
| 1155 | const InitSectionOpts = struct { | |
| 1156 | flags: u32 = macho.S_REGULAR, | |
| 1157 | reserved1: u32 = 0, | |
| 1158 | reserved2: u32 = 0, | |
| 1159 | }; | |
| 1160 | ||
| 1161 | pub fn initSection( | |
| 1162 | self: *Zld, | |
| 1163 | segname: []const u8, | |
| 1164 | sectname: []const u8, | |
| 1165 | opts: InitSectionOpts, | |
| 1166 | ) !u8 { | |
| 1167 | const gpa = self.gpa; | |
| 1168 | log.debug("creating section '{s},{s}'", .{ segname, sectname }); | |
| 1169 | const index = @as(u8, @intCast(self.sections.slice().len)); | |
| 1170 | try self.sections.append(gpa, .{ | |
| 1171 | .segment_index = undefined, // Segments will be created automatically later down the pipeline | |
| 1172 | .header = .{ | |
| 1173 | .sectname = makeStaticString(sectname), | |
| 1174 | .segname = makeStaticString(segname), | |
| 1175 | .flags = opts.flags, | |
| 1176 | .reserved1 = opts.reserved1, | |
| 1177 | .reserved2 = opts.reserved2, | |
| 1178 | }, | |
| 1179 | }); | |
| 1180 | return index; | |
| 1181 | } | |
| 1182 | ||
| 1183 | 1155 | fn writeSegmentHeaders(self: *Zld, writer: anytype) !void { |
| 1184 | 1156 | for (self.segments.items, 0..) |seg, i| { |
| 1185 | 1157 | const indexes = self.getSectionIndexes(@as(u8, @intCast(i))); |