authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-13 10:22:02+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-18 09:13:08+02:00
log387a71fa5bed4782d6f6789b8ca1ce637a31076f
treeddc9b3e093bbd7dd2c574c8f5b12444866a1bcb2
parent84189f9d56f207e92d0a9d1f5145079cc46f8db0

macho: re-enable writing out static archive with ZigObject


3 files changed, 40 insertions(+), 58 deletions(-)

src/link/MachO/ZigObject.zig+6-4
...@@ -313,7 +313,9 @@ pub fn dedupLiterals(self: *ZigObject, lp: MachO.LiteralPool, macho_file: *MachO...@@ -313,7 +313,9 @@ pub fn dedupLiterals(self: *ZigObject, lp: MachO.LiteralPool, macho_file: *MachO
313/// This is just a temporary helper function that allows us to re-read what we wrote to file into a buffer.313/// This is just a temporary helper function that allows us to re-read what we wrote to file into a buffer.
314/// We need this so that we can write to an archive.314/// We need this so that we can write to an archive.
315/// TODO implement writing ZigObject data directly to a buffer instead.315/// TODO implement writing ZigObject data directly to a buffer instead.
316pub fn readFileContents(self: *ZigObject, size: usize, macho_file: *MachO) !void {316pub fn readFileContents(self: *ZigObject, macho_file: *MachO) !void {
317 // Size of the output object file is always the offset + size of the strtab
318 const size = macho_file.symtab_cmd.stroff + macho_file.symtab_cmd.strsize;
317 const gpa = macho_file.base.comp.gpa;319 const gpa = macho_file.base.comp.gpa;
318 try self.data.resize(gpa, size);320 try self.data.resize(gpa, size);
319 const amt = try macho_file.base.file.?.preadAll(self.data.items, 0);321 const amt = try macho_file.base.file.?.preadAll(self.data.items, 0);
...@@ -322,9 +324,9 @@ pub fn readFileContents(self: *ZigObject, size: usize, macho_file: *MachO) !void...@@ -322,9 +324,9 @@ pub fn readFileContents(self: *ZigObject, size: usize, macho_file: *MachO) !void
322324
323pub fn updateArSymtab(self: ZigObject, ar_symtab: *Archive.ArSymtab, macho_file: *MachO) error{OutOfMemory}!void {325pub fn updateArSymtab(self: ZigObject, ar_symtab: *Archive.ArSymtab, macho_file: *MachO) error{OutOfMemory}!void {
324 const gpa = macho_file.base.comp.gpa;326 const gpa = macho_file.base.comp.gpa;
325 for (self.symbols.items) |sym_index| {327 for (self.symbols.items, 0..) |sym, i| {
326 const sym = macho_file.getSymbol(sym_index);328 const ref = self.getSymbolRef(@intCast(i), macho_file);
327 const file = sym.getFile(macho_file).?;329 const file = ref.getFile(macho_file).?;
328 assert(file.getIndex() == self.index);330 assert(file.getIndex() == self.index);
329 if (!sym.flags.@"export") continue;331 if (!sym.flags.@"export") continue;
330 const off = try ar_symtab.strtab.insert(gpa, sym.getName(macho_file));332 const off = try ar_symtab.strtab.insert(gpa, sym.getName(macho_file));
src/link/MachO/file.zig+2-8
...@@ -293,8 +293,6 @@ pub const File = union(enum) {...@@ -293,8 +293,6 @@ pub const File = union(enum) {
293 pub fn updateArSymtab(file: File, ar_symtab: *Archive.ArSymtab, macho_file: *MachO) error{OutOfMemory}!void {293 pub fn updateArSymtab(file: File, ar_symtab: *Archive.ArSymtab, macho_file: *MachO) error{OutOfMemory}!void {
294 return switch (file) {294 return switch (file) {
295 .dylib, .internal => unreachable,295 .dylib, .internal => unreachable,
296 // TODO
297 .zig_object => unreachable,
298 inline else => |x| x.updateArSymtab(ar_symtab, macho_file),296 inline else => |x| x.updateArSymtab(ar_symtab, macho_file),
299 };297 };
300 }298 }
...@@ -302,9 +300,7 @@ pub const File = union(enum) {...@@ -302,9 +300,7 @@ pub const File = union(enum) {
302 pub fn updateArSize(file: File, macho_file: *MachO) !void {300 pub fn updateArSize(file: File, macho_file: *MachO) !void {
303 return switch (file) {301 return switch (file) {
304 .dylib, .internal => unreachable,302 .dylib, .internal => unreachable,
305 // TODO303 .zig_object => |x| x.updateArSize(),
306 .zig_object => unreachable,
307 // .zig_object => |x| x.updateArSize(),
308 .object => |x| x.updateArSize(macho_file),304 .object => |x| x.updateArSize(macho_file),
309 };305 };
310 }306 }
...@@ -312,9 +308,7 @@ pub const File = union(enum) {...@@ -312,9 +308,7 @@ pub const File = union(enum) {
312 pub fn writeAr(file: File, ar_format: Archive.Format, macho_file: *MachO, writer: anytype) !void {308 pub fn writeAr(file: File, ar_format: Archive.Format, macho_file: *MachO, writer: anytype) !void {
313 return switch (file) {309 return switch (file) {
314 .dylib, .internal => unreachable,310 .dylib, .internal => unreachable,
315 // TODO311 .zig_object => |x| x.writeAr(ar_format, writer),
316 .zig_object => unreachable,
317 // .zig_object => |x| x.writeAr(ar_format, writer),
318 .object => |x| x.writeAr(ar_format, macho_file, writer),312 .object => |x| x.writeAr(ar_format, macho_file, writer),
319 };313 };
320 }314 }
src/link/MachO/relocatable.zig+32-46
...@@ -110,56 +110,42 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?...@@ -110,56 +110,42 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?
110110
111 if (comp.link_errors.items.len > 0) return error.FlushFailure;111 if (comp.link_errors.items.len > 0) return error.FlushFailure;
112112
113 // TODO re-enable113 // First, we flush relocatable object file generated with our backends.
114 // // First, we flush relocatable object file generated with our backends.114 if (macho_file.getZigObject()) |zo| {
115 // if (macho_file.getZigObject()) |zo| {115 try zo.resolveSymbols(macho_file);
116 // zo.resolveSymbols(macho_file);116 zo.asFile().markExportsRelocatable(macho_file);
117 // zo.asFile().markExportsRelocatable(macho_file);117 zo.asFile().claimUnresolvedRelocatable(macho_file);
118 // zo.asFile().claimUnresolvedRelocatable(macho_file);118 try macho_file.sortSections();
119 // try macho_file.sortSections();119 try macho_file.addAtomsToSections();
120 // try macho_file.addAtomsToSections();120 try calcSectionSizes(macho_file);
121 // try calcSectionSizes(macho_file);121 try createSegment(macho_file);
122 // try createSegment(macho_file);122 try allocateSections(macho_file);
123 // try allocateSections(macho_file);123 allocateSegment(macho_file);
124 // allocateSegment(macho_file);124
125125 if (build_options.enable_logging) {
126 // var off = off: {126 state_log.debug("{}", .{macho_file.dumpState()});
127 // const seg = macho_file.segments.items[0];127 }
128 // const off = math.cast(u32, seg.fileoff + seg.filesize) orelse return error.Overflow;128
129 // break :off mem.alignForward(u32, off, @alignOf(macho.relocation_info));129 try writeSections(macho_file);
130 // };130 sortRelocs(macho_file);
131 // off = allocateSectionsRelocs(macho_file, off);131 try writeSectionsToFile(macho_file);
132132
133 // if (build_options.enable_logging) {133 // In order to please Apple ld (and possibly other MachO linkers in the wild),
134 // state_log.debug("{}", .{macho_file.dumpState()});134 // we will now sanitize segment names of Zig-specific segments.
135 // }135 sanitizeZigSections(macho_file);
136136
137 // try macho_file.calcSymtabSize();137 const ncmds, const sizeofcmds = try writeLoadCommands(macho_file);
138 // try writeAtoms(macho_file);138 try writeHeader(macho_file, ncmds, sizeofcmds);
139139
140 // off = mem.alignForward(u32, off, @alignOf(u64));140 // TODO we can avoid reading in the file contents we just wrote if we give the linker
141 // off = try macho_file.writeDataInCode(0, off);141 // ability to write directly to a buffer.
142 // off = mem.alignForward(u32, off, @alignOf(u64));142 try zo.readFileContents(macho_file);
143 // off = try macho_file.writeSymtab(off);143 }
144 // off = mem.alignForward(u32, off, @alignOf(u64));
145 // off = try macho_file.writeStrtab(off);
146
147 // // In order to please Apple ld (and possibly other MachO linkers in the wild),
148 // // we will now sanitize segment names of Zig-specific segments.
149 // sanitizeZigSections(macho_file);
150
151 // const ncmds, const sizeofcmds = try writeLoadCommands(macho_file);
152 // try writeHeader(macho_file, ncmds, sizeofcmds);
153
154 // // TODO we can avoid reading in the file contents we just wrote if we give the linker
155 // // ability to write directly to a buffer.
156 // try zo.readFileContents(off, macho_file);
157 // }
158144
159 var files = std.ArrayList(File.Index).init(gpa);145 var files = std.ArrayList(File.Index).init(gpa);
160 defer files.deinit();146 defer files.deinit();
161 try files.ensureTotalCapacityPrecise(macho_file.objects.items.len + 1);147 try files.ensureTotalCapacityPrecise(macho_file.objects.items.len + 1);
162 // if (macho_file.getZigObject()) |zo| files.appendAssumeCapacity(zo.index);148 if (macho_file.getZigObject()) |zo| files.appendAssumeCapacity(zo.index);
163 for (macho_file.objects.items) |index| files.appendAssumeCapacity(index);149 for (macho_file.objects.items) |index| files.appendAssumeCapacity(index);
164150
165 const format: Archive.Format = .p32;151 const format: Archive.Format = .p32;