Commit c9d19ebb7a

Jakub Konka <kubkon@jakubkonka.com>
2024-07-04 07:21:01
macho: link dynamic TSAN lib
1 parent 1cfc364
Changed files (2)
src/link/MachO/load_commands.zig
@@ -61,7 +61,7 @@ pub fn calcLoadCommandsSize(macho_file: *MachO, assume_max_path_len: bool) !u32
     }
     // LC_RPATH
     {
-        for (macho_file.base.rpath_list) |rpath| {
+        for (macho_file.rpaths.items) |rpath| {
             sizeofcmds += calcInstallNameLen(
                 @sizeOf(macho.rpath_command),
                 rpath,
src/link/MachO.zig
@@ -150,6 +150,7 @@ 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 {} = .{},
@@ -192,7 +193,7 @@ pub fn createEmpty(
         null
     else
         try std.fmt.allocPrint(arena, "{s}.o", .{emit.sub_path});
-    const allow_shlib_undefined = options.allow_shlib_undefined orelse comp.config.any_sanitize_thread;
+    const allow_shlib_undefined = options.allow_shlib_undefined orelse false;
 
     const self = try arena.create(MachO);
     self.* = .{
@@ -358,6 +359,8 @@ 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 {
@@ -395,6 +398,9 @@ 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();
 
@@ -413,7 +419,10 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: std.Progress.Node)
 
     // TSAN
     if (comp.config.any_sanitize_thread) {
-        try positionals.append(.{ .path = comp.tsan_static_lib.?.full_object_path });
+        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);
     }
 
     for (positionals.items) |obj| {
@@ -771,7 +780,7 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {
             try argv.append(syslibroot);
         }
 
-        for (self.base.rpath_list) |rpath| {
+        for (self.rpaths.items) |rpath| {
             try argv.append("-rpath");
             try argv.append(rpath);
         }
@@ -831,7 +840,7 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {
         }
 
         if (comp.config.any_sanitize_thread) {
-            try argv.append(comp.tsan_static_lib.?.full_object_path);
+            try argv.append(comp.tsan_dynamic_lib.?.full_object_path);
         }
 
         for (self.lib_dirs) |lib_dir| {
@@ -3015,8 +3024,8 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } {
         ncmds += 1;
     }
 
-    try load_commands.writeRpathLCs(self.base.rpath_list, writer);
-    ncmds += self.base.rpath_list.len;
+    try load_commands.writeRpathLCs(self.rpaths.items, writer);
+    ncmds += self.rpaths.items.len;
 
     try writer.writeStruct(macho.source_version_command{ .version = 0 });
     ncmds += 1;