From 2c41c453b634b3d1f378f6f1b335314f0a4be2de Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 8 Oct 2024 14:40:12 -0700 Subject: [PATCH] link.Elf: avoid converting rpath data in flush() The goal is to minimize as much as possible how much logic is inside flush(). So let's start by moving out obvious stuff. This data can be preformatted before flush(). --- src/link.zig | 1 - src/link/C.zig | 1 - src/link/Coff.zig | 1 - src/link/Elf.zig | 35 ++++++++++++-------------------- src/link/MachO.zig | 11 +++++----- src/link/MachO/load_commands.zig | 2 +- src/link/NvPtx.zig | 1 - src/link/Plan9.zig | 1 - src/link/SpirV.zig | 1 - src/link/Wasm.zig | 1 - 10 files changed, 20 insertions(+), 35 deletions(-) diff --git a/src/link.zig b/src/link.zig index 3f05f0772c..1329d4eec7 100644 --- a/src/link.zig +++ b/src/link.zig @@ -67,7 +67,6 @@ pub const File = struct { gc_sections: bool, print_gc_sections: bool, build_id: std.zig.BuildId, - rpath_list: []const []const u8, allow_shlib_undefined: bool, stack_size: u64, diff --git a/src/link/C.zig b/src/link/C.zig index 7a5bf780b4..d2d4ca9fbc 100644 --- a/src/link/C.zig +++ b/src/link/C.zig @@ -148,7 +148,6 @@ pub fn createEmpty( .file = file, .disable_lld_caching = options.disable_lld_caching, .build_id = options.build_id, - .rpath_list = options.rpath_list, }, }; diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 24040cb2f8..b104cd5840 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -263,7 +263,6 @@ pub fn createEmpty( .file = null, .disable_lld_caching = options.disable_lld_caching, .build_id = options.build_id, - .rpath_list = options.rpath_list, }, .ptr_width = ptr_width, .page_size = page_size, diff --git a/src/link/Elf.zig b/src/link/Elf.zig index f7b0529d8f..2bb2048112 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1,4 +1,5 @@ base: link.File, +rpath_table: std.StringArrayHashMapUnmanaged(void), image_base: u64, emit_relocs: bool, z_nodelete: bool, @@ -239,6 +240,11 @@ pub fn createEmpty( else try std.fmt.allocPrint(arena, "{s}.o", .{emit.sub_path}); + var rpath_table: std.StringArrayHashMapUnmanaged(void) = .empty; + try rpath_table.entries.resize(arena, options.rpath_list.len); + @memcpy(rpath_table.entries.items(.key), options.rpath_list); + try rpath_table.reIndex(arena); + const self = try arena.create(Elf); self.* = .{ .base = .{ @@ -253,8 +259,8 @@ pub fn createEmpty( .file = null, .disable_lld_caching = options.disable_lld_caching, .build_id = options.build_id, - .rpath_list = options.rpath_list, }, + .rpath_table = rpath_table, .ptr_width = ptr_width, .page_size = page_size, .default_sym_version = default_sym_version, @@ -829,14 +835,6 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod if (module_obj_path) |path| try positionals.append(.{ .path = path }); - // rpaths - var rpath_table = std.StringArrayHashMap(void).init(gpa); - defer rpath_table.deinit(); - - for (self.base.rpath_list) |rpath| { - _ = try rpath_table.put(rpath, {}); - } - if (comp.config.any_sanitize_thread) { try positionals.append(.{ .path = comp.tsan_lib.?.full_object_path }); } @@ -1056,7 +1054,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod try self.initSpecialPhdrs(); try self.sortShdrs(); - try self.setDynamicSection(rpath_table.keys()); + try self.setDynamicSection(self.rpath_table.keys()); self.sortDynamicSymtab(); try self.setHashSections(); try self.setVersionSymtab(); @@ -1207,9 +1205,8 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void { try argv.appendSlice(&.{ "--entry", name }); } - for (self.base.rpath_list) |rpath| { - try argv.append("-rpath"); - try argv.append(rpath); + for (self.rpath_table.keys()) |rpath| { + try argv.appendSlice(&.{ "-rpath", rpath }); } try argv.appendSlice(&.{ @@ -1978,7 +1975,7 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s man.hash.add(self.emit_relocs); man.hash.add(comp.config.rdynamic); man.hash.addListOfBytes(self.lib_dirs); - man.hash.addListOfBytes(self.base.rpath_list); + man.hash.addListOfBytes(self.rpath_table.keys()); if (output_mode == .Exe) { man.hash.add(self.base.stack_size); man.hash.add(self.base.build_id); @@ -2263,14 +2260,8 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s if (csu.crti) |v| try argv.append(v); if (csu.crtbegin) |v| try argv.append(v); - // rpaths - var rpath_table = std.StringHashMap(void).init(gpa); - defer rpath_table.deinit(); - for (self.base.rpath_list) |rpath| { - if ((try rpath_table.fetchPut(rpath, {})) == null) { - try argv.append("-rpath"); - try argv.append(rpath); - } + for (self.rpath_table.keys()) |rpath| { + try argv.appendSlice(&.{ "-rpath", rpath }); } for (self.symbol_wrap_set.keys()) |symbol_name| { diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 9e2dbf6007..d78d2f5148 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -1,5 +1,7 @@ base: link.File, +rpath_list: []const []const u8, + /// If this is not null, an object file is created by LLVM and emitted to zcu_object_sub_path. llvm_object: ?LlvmObject.Ptr = null, @@ -192,8 +194,8 @@ pub fn createEmpty( .file = null, .disable_lld_caching = options.disable_lld_caching, .build_id = options.build_id, - .rpath_list = options.rpath_list, }, + .rpath_list = options.rpath_list, .pagezero_size = options.pagezero_size, .headerpad_size = options.headerpad_size, .headerpad_max_install_names = options.headerpad_max_install_names, @@ -662,9 +664,8 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void { try argv.append(syslibroot); } - for (self.base.rpath_list) |rpath| { - try argv.append("-rpath"); - try argv.append(rpath); + for (self.rpath_list) |rpath| { + try argv.appendSlice(&.{ "-rpath", rpath }); } if (self.pagezero_size) |size| { @@ -2842,7 +2843,7 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } { ncmds += 1; } - for (self.base.rpath_list) |rpath| { + for (self.rpath_list) |rpath| { try load_commands.writeRpathLC(rpath, writer); ncmds += 1; } diff --git a/src/link/MachO/load_commands.zig b/src/link/MachO/load_commands.zig index a891bedbd6..b90b090864 100644 --- a/src/link/MachO/load_commands.zig +++ b/src/link/MachO/load_commands.zig @@ -63,7 +63,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.rpath_list) |rpath| { sizeofcmds += calcInstallNameLen( @sizeOf(macho.rpath_command), rpath, diff --git a/src/link/NvPtx.zig b/src/link/NvPtx.zig index 1488f65ff9..199b13a6c6 100644 --- a/src/link/NvPtx.zig +++ b/src/link/NvPtx.zig @@ -60,7 +60,6 @@ pub fn createEmpty( .file = null, .disable_lld_caching = options.disable_lld_caching, .build_id = options.build_id, - .rpath_list = options.rpath_list, }, .llvm_object = llvm_object, }; diff --git a/src/link/Plan9.zig b/src/link/Plan9.zig index 413ab7372a..483f540699 100644 --- a/src/link/Plan9.zig +++ b/src/link/Plan9.zig @@ -304,7 +304,6 @@ pub fn createEmpty( .file = null, .disable_lld_caching = options.disable_lld_caching, .build_id = options.build_id, - .rpath_list = options.rpath_list, }, .sixtyfour_bit = sixtyfour_bit, .bases = undefined, diff --git a/src/link/SpirV.zig b/src/link/SpirV.zig index 7263b6d28d..bbc267cbc5 100644 --- a/src/link/SpirV.zig +++ b/src/link/SpirV.zig @@ -74,7 +74,6 @@ pub fn createEmpty( .file = null, .disable_lld_caching = options.disable_lld_caching, .build_id = options.build_id, - .rpath_list = options.rpath_list, }, .object = codegen.Object.init(gpa), }; diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 7d97fb4c7d..fed44b7331 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -398,7 +398,6 @@ pub fn createEmpty( .file = null, .disable_lld_caching = options.disable_lld_caching, .build_id = options.build_id, - .rpath_list = options.rpath_list, }, .name = undefined, .import_table = options.import_table,