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().
This commit is contained in:
Andrew Kelley
2024-10-08 14:40:12 -07:00
parent e1e151df0d
commit 2c41c453b6
10 changed files with 20 additions and 35 deletions

View File

@@ -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,

View File

@@ -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,
},
};

View File

@@ -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,

View File

@@ -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| {

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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,
};

View File

@@ -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,

View File

@@ -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),
};

View File

@@ -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,