authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-19 01:02:29-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-23 16:27:38-07:00
log2d8ea78249c85552225db8f50b45e2e71ba85a41
treef042ef9da464e39dfb645e4bb42c176c46065011
parentab33d2e7a90346be43693a7dd0e2276e894a67ba

link.Elf: remove ZigObject from files

By making it a field of link.Elf, it is now accessible without a data dependency on `files`, fixing a race condition with the codegen thread and linker thread.

2 files changed, 21 insertions(+), 15 deletions(-)

src/link/Elf.zig+19-13
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1pub const Atom = @import("Elf/Atom.zig");1pub const Atom = @import("Elf/Atom.zig");
22
3base: link.File,3base: link.File,
4zig_object: ?*ZigObject,
4rpath_table: std.StringArrayHashMapUnmanaged(void),5rpath_table: std.StringArrayHashMapUnmanaged(void),
5image_base: u64,6image_base: u64,
6emit_relocs: bool,7emit_relocs: bool,
...@@ -299,6 +300,7 @@ pub fn createEmpty(...@@ -299,6 +300,7 @@ pub fn createEmpty(
299 .disable_lld_caching = options.disable_lld_caching,300 .disable_lld_caching = options.disable_lld_caching,
300 .build_id = options.build_id,301 .build_id = options.build_id,
301 },302 },
303 .zig_object = null,
302 .rpath_table = rpath_table,304 .rpath_table = rpath_table,
303 .ptr_width = ptr_width,305 .ptr_width = ptr_width,
304 .page_size = page_size,306 .page_size = page_size,
...@@ -423,14 +425,17 @@ pub fn createEmpty(...@@ -423,14 +425,17 @@ pub fn createEmpty(
423 if (opt_zcu) |zcu| {425 if (opt_zcu) |zcu| {
424 if (!use_llvm) {426 if (!use_llvm) {
425 const index: File.Index = @intCast(try self.files.addOne(gpa));427 const index: File.Index = @intCast(try self.files.addOne(gpa));
426 self.files.set(index, .{ .zig_object = .{428 self.files.set(index, .zig_object);
429 self.zig_object_index = index;
430 const zig_object = try arena.create(ZigObject);
431 self.zig_object = zig_object;
432 zig_object.* = .{
427 .index = index,433 .index = index,
428 .basename = try std.fmt.allocPrint(arena, "{s}.o", .{434 .basename = try std.fmt.allocPrint(arena, "{s}.o", .{
429 fs.path.stem(zcu.main_mod.root_src_path),435 fs.path.stem(zcu.main_mod.root_src_path),
430 }),436 }),
431 } });437 };
432 self.zig_object_index = index;438 try zig_object.init(self, .{
433 try self.zigObjectPtr().?.init(self, .{
434 .symbol_count_hint = options.symbol_count_hint,439 .symbol_count_hint = options.symbol_count_hint,
435 .program_code_size_hint = options.program_code_size_hint,440 .program_code_size_hint = options.program_code_size_hint,
436 });441 });
...@@ -462,12 +467,14 @@ pub fn deinit(self: *Elf) void {...@@ -462,12 +467,14 @@ pub fn deinit(self: *Elf) void {
462 self.file_handles.deinit(gpa);467 self.file_handles.deinit(gpa);
463468
464 for (self.files.items(.tags), self.files.items(.data)) |tag, *data| switch (tag) {469 for (self.files.items(.tags), self.files.items(.data)) |tag, *data| switch (tag) {
465 .null => {},470 .null, .zig_object => {},
466 .zig_object => data.zig_object.deinit(gpa),
467 .linker_defined => data.linker_defined.deinit(gpa),471 .linker_defined => data.linker_defined.deinit(gpa),
468 .object => data.object.deinit(gpa),472 .object => data.object.deinit(gpa),
469 .shared_object => data.shared_object.deinit(gpa),473 .shared_object => data.shared_object.deinit(gpa),
470 };474 };
475 if (self.zig_object) |zig_object| {
476 zig_object.deinit(gpa);
477 }
471 self.files.deinit(gpa);478 self.files.deinit(gpa);
472 self.objects.deinit(gpa);479 self.objects.deinit(gpa);
473 self.shared_objects.deinit(gpa);480 self.shared_objects.deinit(gpa);
...@@ -1242,7 +1249,7 @@ fn parseDso(...@@ -1242,7 +1249,7 @@ fn parseDso(
1242 .output_symtab_ctx = .{},1249 .output_symtab_ctx = .{},
1243 },1250 },
1244 });1251 });
1245 const so = fileLookup(files.*, index).?.shared_object;1252 const so = fileLookup(files.*, index, null).?.shared_object;
12461253
1247 // TODO: save this work for later1254 // TODO: save this work for later
1248 const nsyms = parsed.symbols.len;1255 const nsyms = parsed.symbols.len;
...@@ -3118,7 +3125,7 @@ pub fn sortShdrs(...@@ -3118,7 +3125,7 @@ pub fn sortShdrs(
3118 for (slice.items(.shdr), slice.items(.atom_list_2)) |*shdr, *atom_list| {3125 for (slice.items(.shdr), slice.items(.atom_list_2)) |*shdr, *atom_list| {
3119 atom_list.output_section_index = backlinks[atom_list.output_section_index];3126 atom_list.output_section_index = backlinks[atom_list.output_section_index];
3120 for (atom_list.atoms.keys()) |ref| {3127 for (atom_list.atoms.keys()) |ref| {
3121 fileLookup(files, ref.file).?.atom(ref.index).?.output_section_index = atom_list.output_section_index;3128 fileLookup(files, ref.file, zig_object_ptr).?.atom(ref.index).?.output_section_index = atom_list.output_section_index;
3122 }3129 }
3123 if (shdr.sh_type == elf.SHT_RELA) {3130 if (shdr.sh_type == elf.SHT_RELA) {
3124 // FIXME:JK we should spin up .symtab potentially earlier, or set all non-dynamic RELA sections3131 // FIXME:JK we should spin up .symtab potentially earlier, or set all non-dynamic RELA sections
...@@ -4348,15 +4355,15 @@ pub fn thunk(self: *Elf, index: Thunk.Index) *Thunk {...@@ -4348,15 +4355,15 @@ pub fn thunk(self: *Elf, index: Thunk.Index) *Thunk {
4348}4355}
43494356
4350pub fn file(self: *Elf, index: File.Index) ?File {4357pub fn file(self: *Elf, index: File.Index) ?File {
4351 return fileLookup(self.files, index);4358 return fileLookup(self.files, index, self.zig_object);
4352}4359}
43534360
4354fn fileLookup(files: std.MultiArrayList(File.Entry), index: File.Index) ?File {4361fn fileLookup(files: std.MultiArrayList(File.Entry), index: File.Index, zig_object: ?*ZigObject) ?File {
4355 const tag = files.items(.tags)[index];4362 const tag = files.items(.tags)[index];
4356 return switch (tag) {4363 return switch (tag) {
4357 .null => null,4364 .null => null,
4358 .linker_defined => .{ .linker_defined = &files.items(.data)[index].linker_defined },4365 .linker_defined => .{ .linker_defined = &files.items(.data)[index].linker_defined },
4359 .zig_object => .{ .zig_object = &files.items(.data)[index].zig_object },4366 .zig_object => .{ .zig_object = zig_object.? },
4360 .object => .{ .object = &files.items(.data)[index].object },4367 .object => .{ .object = &files.items(.data)[index].object },
4361 .shared_object => .{ .shared_object = &files.items(.data)[index].shared_object },4368 .shared_object => .{ .shared_object = &files.items(.data)[index].shared_object },
4362 };4369 };
...@@ -4394,8 +4401,7 @@ pub fn getGlobalSymbol(self: *Elf, name: []const u8, lib_name: ?[]const u8) !u32...@@ -4394,8 +4401,7 @@ pub fn getGlobalSymbol(self: *Elf, name: []const u8, lib_name: ?[]const u8) !u32
4394}4401}
43954402
4396pub fn zigObjectPtr(self: *Elf) ?*ZigObject {4403pub fn zigObjectPtr(self: *Elf) ?*ZigObject {
4397 const index = self.zig_object_index orelse return null;4404 return self.zig_object;
4398 return self.file(index).?.zig_object;
4399}4405}
44004406
4401pub fn linkerDefinedPtr(self: *Elf) ?*LinkerDefined {4407pub fn linkerDefinedPtr(self: *Elf) ?*LinkerDefined {
src/link/Elf/file.zig+2-2
...@@ -279,8 +279,8 @@ pub const File = union(enum) {...@@ -279,8 +279,8 @@ pub const File = union(enum) {
279 pub const Index = u32;279 pub const Index = u32;
280280
281 pub const Entry = union(enum) {281 pub const Entry = union(enum) {
282 null: void,282 null,
283 zig_object: ZigObject,283 zig_object,
284 linker_defined: LinkerDefined,284 linker_defined: LinkerDefined,
285 object: Object,285 object: Object,
286 shared_object: SharedObject,286 shared_object: SharedObject,