authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-02-04 11:23:17+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-02-04 18:05:38+01:00
loga1b607acb5c1e9dd03760efd7078185e7628b29d
tree3397a620cb4c62c507bfac2eed0d50d082808395
parent3c7970dc4ec5529a59a2c6f768a63c6d3b676c91

macho: sanitize Zig sections segment names before emitting a relocatable

As reported by jacobly, the Apple system linker matches sections to segments by name and not by flags causing Zig's executable section ending up in a segment with incorrect permission flags.

1 files changed, 29 insertions(+), 0 deletions(-)

src/link/MachO/relocatable.zig+29
......@@ -78,6 +78,10 @@ pub fn flush(macho_file: *MachO, comp: *Compilation, module_obj_path: ?[]const u
7878 off = mem.alignForward(u32, off, @alignOf(u64));
7979 off = try macho_file.writeStrtab(off);
8080
81 // In order to please Apple ld (and possibly other MachO linkers in the wild),
82 // we will now sanitize segment names of Zig-specific segments.
83 sanitizeZigSections(macho_file);
84
8185 const ncmds, const sizeofcmds = try writeLoadCommands(macho_file);
8286 try writeHeader(macho_file, ncmds, sizeofcmds);
8387}
......@@ -245,6 +249,31 @@ fn allocateSections(macho_file: *MachO) !void {
245249 }
246250}
247251
252/// Renames segment names in Zig sections to standard MachO segment names such as
253/// `__TEXT`, `__DATA_CONST` and `__DATA`.
254/// TODO: I think I may be able to get rid of this if I rework section/segment
255/// allocation mechanism to not rely so much on having `_ZIG` sections always
256/// pushed to the back. For instance, this is not a problem in ELF linker.
257/// Then, we can create sections with the correct name from the start in `MachO.initMetadata`.
258fn sanitizeZigSections(macho_file: *MachO) void {
259 if (macho_file.zig_text_sect_index) |index| {
260 const header = &macho_file.sections.items(.header)[index];
261 header.segname = MachO.makeStaticString("__TEXT");
262 }
263 if (macho_file.zig_const_sect_index) |index| {
264 const header = &macho_file.sections.items(.header)[index];
265 header.segname = MachO.makeStaticString("__DATA_CONST");
266 }
267 if (macho_file.zig_data_sect_index) |index| {
268 const header = &macho_file.sections.items(.header)[index];
269 header.segname = MachO.makeStaticString("__DATA");
270 }
271 if (macho_file.zig_bss_sect_index) |index| {
272 const header = &macho_file.sections.items(.header)[index];
273 header.segname = MachO.makeStaticString("__DATA");
274 }
275}
276
248277fn createSegment(macho_file: *MachO) !void {
249278 const gpa = macho_file.base.comp.gpa;
250279