authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-08-26 08:13:41+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-08-29 11:39:34+02:00
logb2773cd7120f7120410e1635aaeec026c7bbcdd1
treecd7defea6ddbd23930c3e168b066cfbd75febe61
parent180979ee41e7374ee1b8bc941e2281bb44e41dfd

macho: move initSection into MachO from Zld


4 files changed, 85 insertions(+), 67 deletions(-)

src/link/MachO.zig+36-14
......@@ -2739,6 +2739,34 @@ fn calcPagezeroSize(self: *MachO) u64 {
27392739 return aligned_pagezero_vmsize;
27402740}
27412741
2742const InitSectionOpts = struct {
2743 flags: u32 = macho.S_REGULAR,
2744 reserved1: u32 = 0,
2745 reserved2: u32 = 0,
2746};
2747
2748pub 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
27422770fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts: struct {
27432771 size: u64 = 0,
27442772 alignment: u32 = 0,
......@@ -2751,7 +2779,6 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts
27512779 // In incremental context, we create one section per segment pairing. This way,
27522780 // we can move the segment in raw file as we please.
27532781 const segment_id = @as(u8, @intCast(self.segments.items.len));
2754 const section_id = @as(u8, @intCast(self.sections.slice().len));
27552782 const vmaddr = blk: {
27562783 const prev_segment = self.segments.items[segment_id - 1];
27572784 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
27822809 .cmdsize = @sizeOf(macho.segment_command_64) + @sizeOf(macho.section_64),
27832810 };
27842811
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, .{
27922813 .flags = opts.flags,
27932814 .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);
27952821 assert(!section.isZerofill()); // TODO zerofill sections
27962822
2797 try self.sections.append(gpa, .{
2798 .segment_index = segment_id,
2799 .header = section,
2800 });
2801 return section_id;
2823 return sect_id;
28022824}
28032825
28042826fn 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 {
106106}
107107
108108pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
109 const gpa = zld.gpa;
109110 const segname = sect.segName();
110111 const sectname = sect.sectName();
111112 const res: ?u8 = blk: {
......@@ -126,7 +127,9 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
126127
127128 if (sect.isCode()) {
128129 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,
130133 "__TEXT",
131134 "__text",
132135 .{
......@@ -148,7 +151,9 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
148151 macho.S_8BYTE_LITERALS,
149152 macho.S_16BYTE_LITERALS,
150153 => {
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,
152157 "__TEXT",
153158 "__const",
154159 .{},
......@@ -156,13 +161,17 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
156161 },
157162 macho.S_CSTRING_LITERALS => {
158163 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,
160167 segname,
161168 sectname,
162169 .{},
163170 );
164171 }
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,
166175 "__TEXT",
167176 "__cstring",
168177 .{ .flags = macho.S_CSTRING_LITERALS },
......@@ -171,7 +180,9 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
171180 macho.S_MOD_INIT_FUNC_POINTERS,
172181 macho.S_MOD_TERM_FUNC_POINTERS,
173182 => {
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,
175186 "__DATA_CONST",
176187 sectname,
177188 .{ .flags = sect.flags },
......@@ -184,14 +195,19 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
184195 macho.S_THREAD_LOCAL_REGULAR,
185196 macho.S_THREAD_LOCAL_ZEROFILL,
186197 => {
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,
188201 segname,
189202 sectname,
190203 .{ .flags = sect.flags },
191204 );
192205 },
193206 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
195211 segname,
196212 sectname,
197213 .{},
......@@ -205,7 +221,9 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
205221 mem.eql(u8, sectname, "__gosymtab") or
206222 mem.eql(u8, sectname, "__gopclntab"))
207223 {
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,
209227 "__TEXT",
210228 sectname,
211229 .{},
......@@ -218,20 +236,26 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 {
218236 mem.eql(u8, sectname, "__objc_classlist") or
219237 mem.eql(u8, sectname, "__objc_imageinfo"))
220238 {
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,
222242 "__DATA_CONST",
223243 sectname,
224244 .{},
225245 );
226246 } 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,
228250 "__DATA",
229251 "__data",
230252 .{},
231253 );
232254 }
233255 }
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,
235259 segname,
236260 sectname,
237261 .{},
src/link/MachO/Object.zig+7-7
......@@ -685,11 +685,12 @@ fn parseEhFrameSection(self: *Object, zld: *Zld, object_id: u32) !void {
685685
686686 log.debug("parsing __TEXT,__eh_frame section", .{});
687687
688 const gpa = zld.gpa;
689
688690 if (zld.getSectionByName("__TEXT", "__eh_frame") == null) {
689 _ = try zld.initSection("__TEXT", "__eh_frame", .{});
691 _ = try MachO.initSection(gpa, zld, "__TEXT", "__eh_frame", .{});
690692 }
691693
692 const gpa = zld.gpa;
693694 const cpu_arch = zld.options.target.cpu.arch;
694695 try self.parseRelocs(gpa, sect_id);
695696 const relocs = self.getRelocs(sect_id);
......@@ -779,6 +780,8 @@ fn parseEhFrameSection(self: *Object, zld: *Zld, object_id: u32) !void {
779780}
780781
781782fn parseUnwindInfo(self: *Object, zld: *Zld, object_id: u32) !void {
783 const gpa = zld.gpa;
784 const cpu_arch = zld.options.target.cpu.arch;
782785 const sect_id = self.unwind_info_sect_id orelse {
783786 // If it so happens that the object had `__eh_frame` section defined but no `__compact_unwind`,
784787 // 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 {
786789 // we still create the output `__TEXT,__unwind_info` section.
787790 if (self.hasEhFrameRecords()) {
788791 if (zld.getSectionByName("__TEXT", "__unwind_info") == null) {
789 _ = try zld.initSection("__TEXT", "__unwind_info", .{});
792 _ = try MachO.initSection(gpa, zld, "__TEXT", "__unwind_info", .{});
790793 }
791794 }
792795 return;
......@@ -794,11 +797,8 @@ fn parseUnwindInfo(self: *Object, zld: *Zld, object_id: u32) !void {
794797
795798 log.debug("parsing unwind info in {s}", .{self.name});
796799
797 const gpa = zld.gpa;
798 const cpu_arch = zld.options.target.cpu.arch;
799
800800 if (zld.getSectionByName("__TEXT", "__unwind_info") == null) {
801 _ = try zld.initSection("__TEXT", "__unwind_info", .{});
801 _ = try MachO.initSection(gpa, zld, "__TEXT", "__unwind_info", .{});
802802 }
803803
804804 const unwind_records = self.getUnwindRecords();
src/link/MachO/zld.zig+7-35
......@@ -141,7 +141,7 @@ pub const Zld = struct {
141141 sym.n_type = macho.N_SECT;
142142
143143 const sect_id = self.getSectionByName("__DATA", "__data") orelse
144 try self.initSection("__DATA", "__data", .{});
144 try MachO.initSection(self.gpa, self, "__DATA", "__data", .{});
145145 sym.n_sect = sect_id + 1;
146146 self.dyld_private_atom_index = atom_index;
147147
......@@ -165,7 +165,7 @@ pub const Zld = struct {
165165 const size = sym.n_value;
166166 const alignment = (sym.n_desc >> 8) & 0x0f;
167167 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 });
169169
170170 sym.* = .{
171171 .n_strx = sym.n_strx,
......@@ -619,7 +619,7 @@ pub const Zld = struct {
619619 if (self.got_table.lookup.contains(target)) return;
620620 _ = try self.got_table.allocateEntry(self.gpa, target);
621621 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", .{
623623 .flags = macho.S_NON_LAZY_SYMBOL_POINTERS,
624624 });
625625 }
......@@ -629,7 +629,7 @@ pub const Zld = struct {
629629 if (self.tlv_ptr_table.lookup.contains(target)) return;
630630 _ = try self.tlv_ptr_table.allocateEntry(self.gpa, target);
631631 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", .{
633633 .flags = macho.S_THREAD_LOCAL_VARIABLE_POINTERS,
634634 });
635635 }
......@@ -639,18 +639,18 @@ pub const Zld = struct {
639639 if (self.stubs_table.lookup.contains(target)) return;
640640 _ = try self.stubs_table.allocateEntry(self.gpa, target);
641641 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", .{
643643 .flags = macho.S_SYMBOL_STUBS |
644644 macho.S_ATTR_PURE_INSTRUCTIONS |
645645 macho.S_ATTR_SOME_INSTRUCTIONS,
646646 .reserved2 = stubs.stubSize(self.options.target.cpu.arch),
647647 });
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", .{
649649 .flags = macho.S_REGULAR |
650650 macho.S_ATTR_PURE_INSTRUCTIONS |
651651 macho.S_ATTR_SOME_INSTRUCTIONS,
652652 });
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", .{
654654 .flags = macho.S_LAZY_SYMBOL_POINTERS,
655655 });
656656 }
......@@ -1152,34 +1152,6 @@ pub const Zld = struct {
11521152 segment.vmsize = mem.alignForward(u64, segment.vmsize, page_size);
11531153 }
11541154
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
11831155 fn writeSegmentHeaders(self: *Zld, writer: anytype) !void {
11841156 for (self.segments.items, 0..) |seg, i| {
11851157 const indexes = self.getSectionIndexes(@as(u8, @intCast(i)));