authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-04 22:01:19+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-04 22:01:19+02:00
log6756aaccf14e168132cabe8e0d7933f4fd51e9a9
tree289a76e3f8907d22777a8bfb19d30f814162fb85
parent76c3b6b794ebc9ddb910e369bbf2d121a01e06d8

macho: do not save rpaths globally in the driver


2 files changed, 47 insertions(+), 35 deletions(-)

src/link/MachO.zig+17-15
...@@ -150,7 +150,6 @@ no_implicit_dylibs: bool = false,...@@ -150,7 +150,6 @@ no_implicit_dylibs: bool = false,
150/// Whether the linker should parse and always force load objects containing ObjC in archives.150/// Whether the linker should parse and always force load objects containing ObjC in archives.
151// TODO: in Zig we currently take -ObjC as always on151// TODO: in Zig we currently take -ObjC as always on
152force_load_objc: bool = true,152force_load_objc: bool = true,
153rpaths: std.ArrayListUnmanaged([]const u8) = .{},
154153
155/// Hot-code swapping state.154/// Hot-code swapping state.
156hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{},155hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{},
...@@ -359,8 +358,6 @@ pub fn deinit(self: *MachO) void {...@@ -359,8 +358,6 @@ pub fn deinit(self: *MachO) void {
359 }358 }
360 self.thunks.deinit(gpa);359 self.thunks.deinit(gpa);
361 self.unwind_records.deinit(gpa);360 self.unwind_records.deinit(gpa);
362
363 self.rpaths.deinit(gpa);
364}361}
365362
366pub fn flush(self: *MachO, arena: Allocator, prog_node: std.Progress.Node) link.File.FlushError!void {363pub 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)...@@ -398,9 +395,6 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: std.Progress.Node)
398 if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path);395 if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path);
399 if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path);396 if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path);
400397
401 try self.rpaths.ensureUnusedCapacity(gpa, self.base.rpath_list.len);
402 self.rpaths.appendSliceAssumeCapacity(self.base.rpath_list);
403
404 var positionals = std.ArrayList(Compilation.LinkObject).init(gpa);398 var positionals = std.ArrayList(Compilation.LinkObject).init(gpa);
405 defer positionals.deinit();399 defer positionals.deinit();
406400
...@@ -419,10 +413,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: std.Progress.Node)...@@ -419,10 +413,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: std.Progress.Node)
419413
420 // TSAN414 // TSAN
421 if (comp.config.any_sanitize_thread) {415 if (comp.config.any_sanitize_thread) {
422 const path = comp.tsan_dynamic_lib.?.full_object_path;416 try positionals.append(.{ .path = comp.tsan_dynamic_lib.?.full_object_path });
423 try positionals.append(.{ .path = path });
424 const basename = std.fs.path.dirname(path) orelse ".";
425 try self.rpaths.append(gpa, basename);
426 }417 }
427418
428 for (positionals.items) |obj| {419 for (positionals.items) |obj| {
...@@ -780,7 +771,7 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {...@@ -780,7 +771,7 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {
780 try argv.append(syslibroot);771 try argv.append(syslibroot);
781 }772 }
782773
783 for (self.rpaths.items) |rpath| {774 for (self.base.rpath_list) |rpath| {
784 try argv.append("-rpath");775 try argv.append("-rpath");
785 try argv.append(rpath);776 try argv.append(rpath);
786 }777 }
...@@ -840,7 +831,9 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {...@@ -840,7 +831,9 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {
840 }831 }
841832
842 if (comp.config.any_sanitize_thread) {833 if (comp.config.any_sanitize_thread) {
843 try argv.append(comp.tsan_dynamic_lib.?.full_object_path);834 const path = comp.tsan_dynamic_lib.?.full_object_path;
835 try argv.append(path);
836 try argv.appendSlice(&.{ "-rpath", std.fs.path.dirname(path) orelse "." });
844 }837 }
845838
846 for (self.lib_dirs) |lib_dir| {839 for (self.lib_dirs) |lib_dir| {
...@@ -2968,7 +2961,8 @@ pub fn writeStrtab(self: *MachO, off: u32) !u32 {...@@ -2968,7 +2961,8 @@ pub fn writeStrtab(self: *MachO, off: u32) !u32 {
2968}2961}
29692962
2970fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } {2963fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } {
2971 const gpa = self.base.comp.gpa;2964 const comp = self.base.comp;
2965 const gpa = comp.gpa;
2972 const needed_size = try load_commands.calcLoadCommandsSize(self, false);2966 const needed_size = try load_commands.calcLoadCommandsSize(self, false);
2973 const buffer = try gpa.alloc(u8, needed_size);2967 const buffer = try gpa.alloc(u8, needed_size);
2974 defer gpa.free(buffer);2968 defer gpa.free(buffer);
...@@ -3024,8 +3018,16 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } {...@@ -3024,8 +3018,16 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } {
3024 ncmds += 1;3018 ncmds += 1;
3025 }3019 }
30263020
3027 try load_commands.writeRpathLCs(self.rpaths.items, writer);3021 for (self.base.rpath_list) |rpath| {
3028 ncmds += self.rpaths.items.len;3022 try load_commands.writeRpathLC(rpath, writer);
3023 ncmds += 1;
3024 }
3025 if (comp.config.any_sanitize_thread) {
3026 const path = comp.tsan_dynamic_lib.?.full_object_path;
3027 const rpath = std.fs.path.dirname(path) orelse ".";
3028 try load_commands.writeRpathLC(rpath, writer);
3029 ncmds += 1;
3030 }
30293031
3030 try writer.writeStruct(macho.source_version_command{ .version = 0 });3032 try writer.writeStruct(macho.source_version_command{ .version = 0 });
3031 ncmds += 1;3033 ncmds += 1;
src/link/MachO/load_commands.zig+30-20
...@@ -18,6 +18,9 @@ fn calcInstallNameLen(cmd_size: u64, name: []const u8, assume_max_path_len: bool...@@ -18,6 +18,9 @@ fn calcInstallNameLen(cmd_size: u64, name: []const u8, assume_max_path_len: bool
18}18}
1919
20pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) !u32 {20pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) !u32 {
21 const comp = macho_file.base.comp;
22 const gpa = comp.gpa;
23
21 var sizeofcmds: u64 = 0;24 var sizeofcmds: u64 = 0;
2225
23 // LC_SEGMENT_6426 // LC_SEGMENT_64
...@@ -48,7 +51,6 @@ pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) !u32...@@ -48,7 +51,6 @@ pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) !u32
48 }51 }
49 // LC_ID_DYLIB52 // LC_ID_DYLIB
50 if (macho_file.base.isDynLib()) {53 if (macho_file.base.isDynLib()) {
51 const gpa = macho_file.base.comp.gpa;
52 const emit = macho_file.base.emit;54 const emit = macho_file.base.emit;
53 const install_name = macho_file.install_name orelse55 const install_name = macho_file.install_name orelse
54 try emit.directory.join(gpa, &.{emit.sub_path});56 try emit.directory.join(gpa, &.{emit.sub_path});
...@@ -61,7 +63,17 @@ pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) !u32...@@ -61,7 +63,17 @@ pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) !u32
61 }63 }
62 // LC_RPATH64 // LC_RPATH
63 {65 {
64 for (macho_file.rpaths.items) |rpath| {66 for (macho_file.base.rpath_list) |rpath| {
67 sizeofcmds += calcInstallNameLen(
68 @sizeOf(macho.rpath_command),
69 rpath,
70 assume_max_path_len,
71 );
72 }
73
74 if (comp.config.any_sanitize_thread) {
75 const path = comp.tsan_dynamic_lib.?.full_object_path;
76 const rpath = std.fs.path.dirname(path) orelse ".";
65 sizeofcmds += calcInstallNameLen(77 sizeofcmds += calcInstallNameLen(
66 @sizeOf(macho.rpath_command),78 @sizeOf(macho.rpath_command),
67 rpath,79 rpath,
...@@ -245,24 +257,22 @@ pub fn writeDylibIdLC(macho_file: *MachO, writer: anytype) !void {...@@ -245,24 +257,22 @@ pub fn writeDylibIdLC(macho_file: *MachO, writer: anytype) !void {
245 }, writer);257 }, writer);
246}258}
247259
248pub fn writeRpathLCs(rpaths: []const []const u8, writer: anytype) !void {260pub fn writeRpathLC(rpath: []const u8, writer: anytype) !void {
249 for (rpaths) |rpath| {261 const rpath_len = rpath.len + 1;
250 const rpath_len = rpath.len + 1;262 const cmdsize = @as(u32, @intCast(mem.alignForward(
251 const cmdsize = @as(u32, @intCast(mem.alignForward(263 u64,
252 u64,264 @sizeOf(macho.rpath_command) + rpath_len,
253 @sizeOf(macho.rpath_command) + rpath_len,265 @sizeOf(u64),
254 @sizeOf(u64),266 )));
255 )));267 try writer.writeStruct(macho.rpath_command{
256 try writer.writeStruct(macho.rpath_command{268 .cmdsize = cmdsize,
257 .cmdsize = cmdsize,269 .path = @sizeOf(macho.rpath_command),
258 .path = @sizeOf(macho.rpath_command),270 });
259 });271 try writer.writeAll(rpath);
260 try writer.writeAll(rpath);272 try writer.writeByte(0);
261 try writer.writeByte(0);273 const padding = cmdsize - @sizeOf(macho.rpath_command) - rpath_len;
262 const padding = cmdsize - @sizeOf(macho.rpath_command) - rpath_len;274 if (padding > 0) {
263 if (padding > 0) {275 try writer.writeByteNTimes(0, padding);
264 try writer.writeByteNTimes(0, padding);
265 }
266 }276 }
267}277}
268278