From 6756aaccf14e168132cabe8e0d7933f4fd51e9a9 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 4 Jul 2024 22:01:19 +0200 Subject: [PATCH] macho: do not save rpaths globally in the driver --- src/link/MachO.zig | 32 ++++++++++---------- src/link/MachO/load_commands.zig | 50 +++++++++++++++++++------------- 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 52b57a2c58e1331271c581a0f6a0e45a095cbee6..76bea817663007cb5630a468f987592a97f50ccf 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -150,7 +150,6 @@ no_implicit_dylibs: bool = false, /// Whether the linker should parse and always force load objects containing ObjC in archives. // TODO: in Zig we currently take -ObjC as always on force_load_objc: bool = true, -rpaths: std.ArrayListUnmanaged([]const u8) = .{}, /// Hot-code swapping state. hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{}, @@ -359,8 +358,6 @@ pub fn deinit(self: *MachO) void { } self.thunks.deinit(gpa); self.unwind_records.deinit(gpa); - - self.rpaths.deinit(gpa); } pub fn flush(self: *MachO, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void { @@ -398,9 +395,6 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: std.Progress.Node) if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path); if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path); - try self.rpaths.ensureUnusedCapacity(gpa, self.base.rpath_list.len); - self.rpaths.appendSliceAssumeCapacity(self.base.rpath_list); - var positionals = std.ArrayList(Compilation.LinkObject).init(gpa); defer positionals.deinit(); @@ -419,10 +413,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: std.Progress.Node) // TSAN if (comp.config.any_sanitize_thread) { - const path = comp.tsan_dynamic_lib.?.full_object_path; - try positionals.append(.{ .path = path }); - const basename = std.fs.path.dirname(path) orelse "."; - try self.rpaths.append(gpa, basename); + try positionals.append(.{ .path = comp.tsan_dynamic_lib.?.full_object_path }); } for (positionals.items) |obj| { @@ -780,7 +771,7 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void { try argv.append(syslibroot); } - for (self.rpaths.items) |rpath| { + for (self.base.rpath_list) |rpath| { try argv.append("-rpath"); try argv.append(rpath); } @@ -840,7 +831,9 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void { } if (comp.config.any_sanitize_thread) { - try argv.append(comp.tsan_dynamic_lib.?.full_object_path); + const path = comp.tsan_dynamic_lib.?.full_object_path; + try argv.append(path); + try argv.appendSlice(&.{ "-rpath", std.fs.path.dirname(path) orelse "." }); } for (self.lib_dirs) |lib_dir| { @@ -2968,7 +2961,8 @@ pub fn writeStrtab(self: *MachO, off: u32) !u32 { } fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { - const gpa = self.base.comp.gpa; + const comp = self.base.comp; + const gpa = comp.gpa; const needed_size = try load_commands.calcLoadCommandsSize(self, false); const buffer = try gpa.alloc(u8, needed_size); defer gpa.free(buffer); @@ -3024,8 +3018,16 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { ncmds += 1; } - try load_commands.writeRpathLCs(self.rpaths.items, writer); - ncmds += self.rpaths.items.len; + for (self.base.rpath_list) |rpath| { + try load_commands.writeRpathLC(rpath, writer); + ncmds += 1; + } + if (comp.config.any_sanitize_thread) { + const path = comp.tsan_dynamic_lib.?.full_object_path; + const rpath = std.fs.path.dirname(path) orelse "."; + try load_commands.writeRpathLC(rpath, writer); + ncmds += 1; + } try writer.writeStruct(macho.source_version_command{ .version = 0 }); ncmds += 1; diff --git a/src/link/MachO/load_commands.zig b/src/link/MachO/load_commands.zig index 8719d92ea868456a9e6110f6a4b746f64c7c53db..003612fa2f808487f1ccb12ddf802b1ffc50b7ae 100644 --- a/src/link/MachO/load_commands.zig +++ b/src/link/MachO/load_commands.zig @@ -18,6 +18,9 @@ fn calcInstallNameLen(cmd_size: u64, name: []const u8, assume_max_path_len: bool } pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) !u32 { + const comp = macho_file.base.comp; + const gpa = comp.gpa; + var sizeofcmds: u64 = 0; // LC_SEGMENT_64 @@ -48,7 +51,6 @@ pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) !u32 } // LC_ID_DYLIB if (macho_file.base.isDynLib()) { - const gpa = macho_file.base.comp.gpa; const emit = macho_file.base.emit; const install_name = macho_file.install_name orelse try emit.directory.join(gpa, &.{emit.sub_path}); @@ -61,7 +63,17 @@ pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) !u32 } // LC_RPATH { - for (macho_file.rpaths.items) |rpath| { + for (macho_file.base.rpath_list) |rpath| { + sizeofcmds += calcInstallNameLen( + @sizeOf(macho.rpath_command), + rpath, + assume_max_path_len, + ); + } + + if (comp.config.any_sanitize_thread) { + const path = comp.tsan_dynamic_lib.?.full_object_path; + const rpath = std.fs.path.dirname(path) orelse "."; sizeofcmds += calcInstallNameLen( @sizeOf(macho.rpath_command), rpath, @@ -245,24 +257,22 @@ pub fn writeDylibIdLC(macho_file: *MachO, writer: anytype) !void { }, writer); } -pub fn writeRpathLCs(rpaths: []const []const u8, writer: anytype) !void { - for (rpaths) |rpath| { - const rpath_len = rpath.len + 1; - const cmdsize = @as(u32, @intCast(mem.alignForward( - u64, - @sizeOf(macho.rpath_command) + rpath_len, - @sizeOf(u64), - ))); - try writer.writeStruct(macho.rpath_command{ - .cmdsize = cmdsize, - .path = @sizeOf(macho.rpath_command), - }); - try writer.writeAll(rpath); - try writer.writeByte(0); - const padding = cmdsize - @sizeOf(macho.rpath_command) - rpath_len; - if (padding > 0) { - try writer.writeByteNTimes(0, padding); - } +pub fn writeRpathLC(rpath: []const u8, writer: anytype) !void { + const rpath_len = rpath.len + 1; + const cmdsize = @as(u32, @intCast(mem.alignForward( + u64, + @sizeOf(macho.rpath_command) + rpath_len, + @sizeOf(u64), + ))); + try writer.writeStruct(macho.rpath_command{ + .cmdsize = cmdsize, + .path = @sizeOf(macho.rpath_command), + }); + try writer.writeAll(rpath); + try writer.writeByte(0); + const padding = cmdsize - @sizeOf(macho.rpath_command) - rpath_len; + if (padding > 0) { + try writer.writeByteNTimes(0, padding); } } -- 2.54.0