authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-02-06 14:09:51+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-02-07 19:27:25+01:00
log7f01b61679999bcd0ff644632a26e8c35e7541b6
tree78560ee683f038776ec84e2959479e1a67498635
parentbdbb1dbe1535b727e542c80fe1f7d62a78e527fd

macho: move static lib emitting logic to relocatable.zig


3 files changed, 69 insertions(+), 39 deletions(-)

src/link/MachO.zig+2-2
......@@ -417,8 +417,8 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node
417417 if (comp.verbose_link) try self.dumpArgv(comp);
418418
419419 if (self.getZigObject()) |zo| try zo.flushModule(self);
420 if (self.base.isStaticLib()) return Archive.flush(self, comp, module_obj_path);
421 if (self.base.isObject()) return relocatable.flush(self, comp, module_obj_path);
420 if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path);
421 if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path);
422422
423423 var positionals = std.ArrayList(Compilation.LinkObject).init(gpa);
424424 defer positionals.deinit();
src/link/MachO/Archive.zig-36
......@@ -143,51 +143,15 @@ pub fn parse(self: *Archive, macho_file: *MachO, path: []const u8, handle_index:
143143 }
144144}
145145
146pub fn flush(macho_file: *MachO, comp: *Compilation, module_obj_path: ?[]const u8) link.File.FlushError!void {
147 const gpa = comp.gpa;
148
149 var positionals = std.ArrayList(Compilation.LinkObject).init(gpa);
150 defer positionals.deinit();
151
152 try positionals.ensureUnusedCapacity(comp.objects.len);
153 positionals.appendSliceAssumeCapacity(comp.objects);
154
155 for (comp.c_object_table.keys()) |key| {
156 try positionals.append(.{ .path = key.status.success.object_path });
157 }
158
159 if (module_obj_path) |path| try positionals.append(.{ .path = path });
160
161 for (positionals.items) |obj| {
162 // TODO: parse for archive meaning don't unpack objects
163 _ = obj;
164 }
165
166 if (comp.link_errors.items.len > 0) return error.FlushFailure;
167
168 // First, we flush relocatable object file generated with our backends.
169 if (macho_file.getZigObject()) |zo| {
170 zo.resolveSymbols(macho_file);
171 zo.asFile().claimUnresolvedRelocatable(macho_file);
172 }
173
174 var err = try macho_file.addErrorWithNotes(0);
175 try err.addMsg(macho_file, "TODO implement flushStaticLib", .{});
176
177 return error.FlushFailure;
178}
179
180146const fat = @import("fat.zig");
181147const link = @import("../../link.zig");
182148const log = std.log.scoped(.link);
183149const macho = std.macho;
184150const mem = std.mem;
185const relocatable = @import("relocatable.zig");
186151const std = @import("std");
187152
188153const Allocator = mem.Allocator;
189154const Archive = @This();
190const Compilation = @import("../../Compilation.zig");
191155const File = @import("file.zig").File;
192156const MachO = @import("../MachO.zig");
193157const Object = @import("Object.zig");
src/link/MachO/relocatable.zig+67-1
......@@ -1,4 +1,4 @@
1pub fn flush(macho_file: *MachO, comp: *Compilation, module_obj_path: ?[]const u8) link.File.FlushError!void {
1pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?[]const u8) link.File.FlushError!void {
22 const gpa = macho_file.base.comp.gpa;
33
44 var positionals = std.ArrayList(Compilation.LinkObject).init(gpa);
......@@ -86,6 +86,72 @@ pub fn flush(macho_file: *MachO, comp: *Compilation, module_obj_path: ?[]const u
8686 try writeHeader(macho_file, ncmds, sizeofcmds);
8787}
8888
89pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?[]const u8) link.File.FlushError!void {
90 const gpa = comp.gpa;
91
92 var positionals = std.ArrayList(Compilation.LinkObject).init(gpa);
93 defer positionals.deinit();
94
95 try positionals.ensureUnusedCapacity(comp.objects.len);
96 positionals.appendSliceAssumeCapacity(comp.objects);
97
98 for (comp.c_object_table.keys()) |key| {
99 try positionals.append(.{ .path = key.status.success.object_path });
100 }
101
102 if (module_obj_path) |path| try positionals.append(.{ .path = path });
103
104 for (positionals.items) |obj| {
105 // TODO: parse for archive meaning don't unpack objects
106 _ = obj;
107 }
108
109 if (comp.link_errors.items.len > 0) return error.FlushFailure;
110
111 // First, we flush relocatable object file generated with our backends.
112 if (macho_file.getZigObject()) |zo| {
113 zo.resolveSymbols(macho_file);
114 zo.asFile().claimUnresolvedRelocatable(macho_file);
115 try macho_file.sortSections();
116 try macho_file.addAtomsToSections();
117 try calcSectionSizes(macho_file);
118 try createSegment(macho_file);
119 try allocateSections(macho_file);
120 allocateSegment(macho_file);
121
122 var off = off: {
123 const seg = macho_file.segments.items[0];
124 const off = math.cast(u32, seg.fileoff + seg.filesize) orelse return error.Overflow;
125 break :off mem.alignForward(u32, off, @alignOf(macho.relocation_info));
126 };
127 off = allocateSectionsRelocs(macho_file, off);
128
129 state_log.debug("{}", .{macho_file.dumpState()});
130
131 try macho_file.calcSymtabSize();
132 try writeAtoms(macho_file);
133
134 off = mem.alignForward(u32, off, @alignOf(u64));
135 off = try macho_file.writeDataInCode(0, off);
136 off = mem.alignForward(u32, off, @alignOf(u64));
137 off = try macho_file.writeSymtab(off);
138 off = mem.alignForward(u32, off, @alignOf(u64));
139 off = try macho_file.writeStrtab(off);
140
141 // In order to please Apple ld (and possibly other MachO linkers in the wild),
142 // we will now sanitize segment names of Zig-specific segments.
143 sanitizeZigSections(macho_file);
144
145 const ncmds, const sizeofcmds = try writeLoadCommands(macho_file);
146 try writeHeader(macho_file, ncmds, sizeofcmds);
147 }
148
149 var err = try macho_file.addErrorWithNotes(0);
150 try err.addMsg(macho_file, "TODO implement flushStaticLib", .{});
151
152 return error.FlushFailure;
153}
154
89155fn markExports(macho_file: *MachO) void {
90156 if (macho_file.getZigObject()) |zo| {
91157 zo.asFile().markExportsRelocatable(macho_file);