authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-08 23:41:39-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-09 15:40:59-07:00
logc86a334d43c1818ed19eb403f88e61e38bbf20d6
tree2fdfd31e19d6acb4ee3deb4ee873e10b161cdfb1
parent10cb578e4e16bac44055f277cd06baaf99b159b6

link.Elf.Object.initAtoms: reduce state access and indirection

The initAtoms function now only uses the `elf_file` parameter for reporting linker error messages, making it easier to see that the function has no data dependencies other than the Object struct itself, making it easier to parallelize or otherwise move that logic around. Also removed an indirect call via `addExtra` since we already know the atom's file is the current Object instance. All calls to `Atom.addExtra` should be audited for similar reasons. Also removed unjustified use of `inline fn`.

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

src/link/Elf/Atom.zig+11-11
...@@ -868,15 +868,7 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any...@@ -868,15 +868,7 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any
868 if (has_reloc_errors) return error.RelocFailure;868 if (has_reloc_errors) return error.RelocFailure;
869}869}
870870
871const AddExtraOpts = struct {871pub fn addExtra(atom: *Atom, opts: Extra.AsOptionals, elf_file: *Elf) void {
872 thunk: ?u32 = null,
873 fde_start: ?u32 = null,
874 fde_count: ?u32 = null,
875 rel_index: ?u32 = null,
876 rel_count: ?u32 = null,
877};
878
879pub fn addExtra(atom: *Atom, opts: AddExtraOpts, elf_file: *Elf) void {
880 const file_ptr = atom.file(elf_file).?;872 const file_ptr = atom.file(elf_file).?;
881 var extras = file_ptr.atomExtra(atom.extra_index);873 var extras = file_ptr.atomExtra(atom.extra_index);
882 inline for (@typeInfo(@TypeOf(opts)).@"struct".fields) |field| {874 inline for (@typeInfo(@TypeOf(opts)).@"struct".fields) |field| {
...@@ -887,11 +879,11 @@ pub fn addExtra(atom: *Atom, opts: AddExtraOpts, elf_file: *Elf) void {...@@ -887,11 +879,11 @@ pub fn addExtra(atom: *Atom, opts: AddExtraOpts, elf_file: *Elf) void {
887 file_ptr.setAtomExtra(atom.extra_index, extras);879 file_ptr.setAtomExtra(atom.extra_index, extras);
888}880}
889881
890pub inline fn extra(atom: Atom, elf_file: *Elf) Extra {882pub fn extra(atom: Atom, elf_file: *Elf) Extra {
891 return atom.file(elf_file).?.atomExtra(atom.extra_index);883 return atom.file(elf_file).?.atomExtra(atom.extra_index);
892}884}
893885
894pub inline fn setExtra(atom: Atom, extras: Extra, elf_file: *Elf) void {886pub fn setExtra(atom: Atom, extras: Extra, elf_file: *Elf) void {
895 atom.file(elf_file).?.setAtomExtra(atom.extra_index, extras);887 atom.file(elf_file).?.setAtomExtra(atom.extra_index, extras);
896}888}
897889
...@@ -2103,6 +2095,14 @@ pub const Extra = struct {...@@ -2103,6 +2095,14 @@ pub const Extra = struct {
21032095
2104 /// Count of relocations belonging to this atom.2096 /// Count of relocations belonging to this atom.
2105 rel_count: u32 = 0,2097 rel_count: u32 = 0,
2098
2099 pub const AsOptionals = struct {
2100 thunk: ?u32 = null,
2101 fde_start: ?u32 = null,
2102 fde_count: ?u32 = null,
2103 rel_index: ?u32 = null,
2104 rel_count: ?u32 = null,
2105 };
2106};2106};
21072107
2108const std = @import("std");2108const std = @import("std");
src/link/Elf/Object.zig+21-10
...@@ -166,6 +166,9 @@ fn parseCommon(self: *Object, allocator: Allocator, handle: std.fs.File, elf_fil...@@ -166,6 +166,9 @@ fn parseCommon(self: *Object, allocator: Allocator, handle: std.fs.File, elf_fil
166}166}
167167
168fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file: *Elf) !void {168fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file: *Elf) !void {
169 const comp = elf_file.base.comp;
170 const debug_fmt_strip = comp.config.debug_format == .strip;
171 const target = comp.root_mod.resolved_target.result;
169 const shdrs = self.shdrs.items;172 const shdrs = self.shdrs.items;
170 try self.atoms.ensureTotalCapacityPrecise(allocator, shdrs.len);173 try self.atoms.ensureTotalCapacityPrecise(allocator, shdrs.len);
171 try self.atoms_extra.ensureTotalCapacityPrecise(allocator, shdrs.len * @sizeOf(Atom.Extra));174 try self.atoms_extra.ensureTotalCapacityPrecise(allocator, shdrs.len * @sizeOf(Atom.Extra));
...@@ -194,7 +197,7 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:...@@ -194,7 +197,7 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:
194 break :blk group_info_sym.st_name;197 break :blk group_info_sym.st_name;
195 };198 };
196199
197 const shndx = @as(u32, @intCast(i));200 const shndx: u32 = @intCast(i);
198 const group_raw_data = try self.preadShdrContentsAlloc(allocator, handle, shndx);201 const group_raw_data = try self.preadShdrContentsAlloc(allocator, handle, shndx);
199 defer allocator.free(group_raw_data);202 defer allocator.free(group_raw_data);
200 const group_nmembers = math.divExact(usize, group_raw_data.len, @sizeOf(u32)) catch {203 const group_nmembers = math.divExact(usize, group_raw_data.len, @sizeOf(u32)) catch {
...@@ -209,7 +212,7 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:...@@ -209,7 +212,7 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:
209 return elf_file.failFile(self.index, "corrupt section group: unknown SHT_GROUP format", .{});212 return elf_file.failFile(self.index, "corrupt section group: unknown SHT_GROUP format", .{});
210 }213 }
211214
212 const group_start = @as(u32, @intCast(self.comdat_group_data.items.len));215 const group_start: u32 = @intCast(self.comdat_group_data.items.len);
213 try self.comdat_group_data.appendUnalignedSlice(allocator, group_members[1..]);216 try self.comdat_group_data.appendUnalignedSlice(allocator, group_members[1..]);
214217
215 const comdat_group_index = try self.addComdatGroup(allocator);218 const comdat_group_index = try self.addComdatGroup(allocator);
...@@ -233,8 +236,8 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:...@@ -233,8 +236,8 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:
233 => {},236 => {},
234237
235 else => {238 else => {
236 const shndx = @as(u32, @intCast(i));239 const shndx: u32 = @intCast(i);
237 if (self.skipShdr(shndx, elf_file)) continue;240 if (self.skipShdr(shndx, debug_fmt_strip)) continue;
238 const size, const alignment = if (shdr.sh_flags & elf.SHF_COMPRESSED != 0) blk: {241 const size, const alignment = if (shdr.sh_flags & elf.SHF_COMPRESSED != 0) blk: {
239 const data = try self.preadShdrContentsAlloc(allocator, handle, shndx);242 const data = try self.preadShdrContentsAlloc(allocator, handle, shndx);
240 defer allocator.free(data);243 defer allocator.free(data);
...@@ -262,9 +265,9 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:...@@ -262,9 +265,9 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:
262 atom_ptr.relocs_section_index = @intCast(i);265 atom_ptr.relocs_section_index = @intCast(i);
263 const rel_index: u32 = @intCast(self.relocs.items.len);266 const rel_index: u32 = @intCast(self.relocs.items.len);
264 const rel_count: u32 = @intCast(relocs.len);267 const rel_count: u32 = @intCast(relocs.len);
265 atom_ptr.addExtra(.{ .rel_index = rel_index, .rel_count = rel_count }, elf_file);268 self.setAtomFields(atom_ptr, .{ .rel_index = rel_index, .rel_count = rel_count });
266 try self.relocs.appendUnalignedSlice(allocator, relocs);269 try self.relocs.appendUnalignedSlice(allocator, relocs);
267 if (elf_file.getTarget().cpu.arch == .riscv64) {270 if (target.cpu.arch == .riscv64) {
268 sortRelocs(self.relocs.items[rel_index..][0..rel_count]);271 sortRelocs(self.relocs.items[rel_index..][0..rel_count]);
269 }272 }
270 }273 }
...@@ -273,15 +276,14 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:...@@ -273,15 +276,14 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:
273 };276 };
274}277}
275278
276fn skipShdr(self: *Object, index: u32, elf_file: *Elf) bool {279fn skipShdr(self: *Object, index: u32, debug_fmt_strip: bool) bool {
277 const comp = elf_file.base.comp;
278 const shdr = self.shdrs.items[index];280 const shdr = self.shdrs.items[index];
279 const name = self.getString(shdr.sh_name);281 const name = self.getString(shdr.sh_name);
280 const ignore = blk: {282 const ignore = blk: {
281 if (mem.startsWith(u8, name, ".note")) break :blk true;283 if (mem.startsWith(u8, name, ".note")) break :blk true;
282 if (mem.startsWith(u8, name, ".llvm_addrsig")) break :blk true;284 if (mem.startsWith(u8, name, ".llvm_addrsig")) break :blk true;
283 if (mem.startsWith(u8, name, ".riscv.attributes")) break :blk true; // TODO: riscv attributes285 if (mem.startsWith(u8, name, ".riscv.attributes")) break :blk true; // TODO: riscv attributes
284 if (comp.config.debug_format == .strip and shdr.sh_flags & elf.SHF_ALLOC == 0 and286 if (debug_fmt_strip and shdr.sh_flags & elf.SHF_ALLOC == 0 and
285 mem.startsWith(u8, name, ".debug")) break :blk true;287 mem.startsWith(u8, name, ".debug")) break :blk true;
286 break :blk false;288 break :blk false;
287 };289 };
...@@ -1257,7 +1259,7 @@ pub fn addAtomExtra(self: *Object, allocator: Allocator, extra: Atom.Extra) !u32...@@ -1257,7 +1259,7 @@ pub fn addAtomExtra(self: *Object, allocator: Allocator, extra: Atom.Extra) !u32
1257}1259}
12581260
1259pub fn addAtomExtraAssumeCapacity(self: *Object, extra: Atom.Extra) u32 {1261pub fn addAtomExtraAssumeCapacity(self: *Object, extra: Atom.Extra) u32 {
1260 const index = @as(u32, @intCast(self.atoms_extra.items.len));1262 const index: u32 = @intCast(self.atoms_extra.items.len);
1261 const fields = @typeInfo(Atom.Extra).@"struct".fields;1263 const fields = @typeInfo(Atom.Extra).@"struct".fields;
1262 inline for (fields) |field| {1264 inline for (fields) |field| {
1263 self.atoms_extra.appendAssumeCapacity(switch (field.type) {1265 self.atoms_extra.appendAssumeCapacity(switch (field.type) {
...@@ -1292,6 +1294,15 @@ pub fn setAtomExtra(self: *Object, index: u32, extra: Atom.Extra) void {...@@ -1292,6 +1294,15 @@ pub fn setAtomExtra(self: *Object, index: u32, extra: Atom.Extra) void {
1292 }1294 }
1293}1295}
12941296
1297fn setAtomFields(o: *Object, atom_ptr: *Atom, opts: Atom.Extra.AsOptionals) void {
1298 assert(o.index == atom_ptr.file_index);
1299 var extras = o.atomExtra(atom_ptr.extra_index);
1300 inline for (@typeInfo(@TypeOf(opts)).@"struct".fields) |field| {
1301 if (@field(opts, field.name)) |x| @field(extras, field.name) = x;
1302 }
1303 o.setAtomExtra(atom_ptr.extra_index, extras);
1304}
1305
1295fn addInputMergeSection(self: *Object, allocator: Allocator) !InputMergeSection.Index {1306fn addInputMergeSection(self: *Object, allocator: Allocator) !InputMergeSection.Index {
1296 const index: InputMergeSection.Index = @intCast(self.input_merge_sections.items.len);1307 const index: InputMergeSection.Index = @intCast(self.input_merge_sections.items.len);
1297 const msec = try self.input_merge_sections.addOne(allocator);1308 const msec = try self.input_merge_sections.addOne(allocator);