authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-09-26 12:24:37+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-09 12:27:30-07:00
log7fead5d6dd078beda041ef2f490fb50ffae4dc82
tree1ce11df56c7ffaaece83a4ce2171313cf31fbc43
parentce5a5c361b5b098c3b7d68f88136a9c91e7bec19

elf: track atoms within AtomList with array hash map


4 files changed, 34 insertions(+), 33 deletions(-)

src/link/Elf.zig+14-14
......@@ -3219,7 +3219,7 @@ fn sortInitFini(self: *Elf) !void {
32193219
32203220 for (slice.items(.shdr), slice.items(.atom_list_2)) |shdr, *atom_list| {
32213221 if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue;
3222 if (atom_list.atoms.items.len == 0) continue;
3222 if (atom_list.atoms.keys().len == 0) continue;
32233223
32243224 var is_init_fini = false;
32253225 var is_ctor_dtor = false;
......@@ -3236,10 +3236,10 @@ fn sortInitFini(self: *Elf) !void {
32363236 if (!is_init_fini and !is_ctor_dtor) continue;
32373237
32383238 var entries = std.ArrayList(Entry).init(gpa);
3239 try entries.ensureTotalCapacityPrecise(atom_list.atoms.items.len);
3239 try entries.ensureTotalCapacityPrecise(atom_list.atoms.keys().len);
32403240 defer entries.deinit();
32413241
3242 for (atom_list.atoms.items) |ref| {
3242 for (atom_list.atoms.keys()) |ref| {
32433243 const atom_ptr = self.atom(ref).?;
32443244 const object = atom_ptr.file(self).?.object;
32453245 const priority = blk: {
......@@ -3260,7 +3260,7 @@ fn sortInitFini(self: *Elf) !void {
32603260
32613261 atom_list.atoms.clearRetainingCapacity();
32623262 for (entries.items) |entry| {
3263 atom_list.atoms.appendAssumeCapacity(entry.atom_ref);
3263 _ = atom_list.atoms.getOrPutAssumeCapacity(entry.atom_ref);
32643264 }
32653265 }
32663266}
......@@ -3506,7 +3506,7 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void {
35063506 const slice = self.sections.slice();
35073507 for (slice.items(.shdr), slice.items(.atom_list_2)) |*shdr, *atom_list| {
35083508 atom_list.output_section_index = backlinks[atom_list.output_section_index];
3509 for (atom_list.atoms.items) |ref| {
3509 for (atom_list.atoms.keys()) |ref| {
35103510 self.atom(ref).?.output_section_index = atom_list.output_section_index;
35113511 }
35123512 if (shdr.sh_type == elf.SHT_RELA) {
......@@ -3585,7 +3585,7 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) void {
35853585fn updateSectionSizes(self: *Elf) !void {
35863586 const slice = self.sections.slice();
35873587 for (slice.items(.shdr), slice.items(.atom_list_2)) |shdr, *atom_list| {
3588 if (atom_list.atoms.items.len == 0) continue;
3588 if (atom_list.atoms.keys().len == 0) continue;
35893589 if (self.requiresThunks() and shdr.sh_flags & elf.SHF_EXECINSTR != 0) continue;
35903590 atom_list.updateSize(self);
35913591 try atom_list.allocate(self);
......@@ -3594,7 +3594,7 @@ fn updateSectionSizes(self: *Elf) !void {
35943594 if (self.requiresThunks()) {
35953595 for (slice.items(.shdr), slice.items(.atom_list_2)) |shdr, *atom_list| {
35963596 if (shdr.sh_flags & elf.SHF_EXECINSTR == 0) continue;
3597 if (atom_list.atoms.items.len == 0) continue;
3597 if (atom_list.atoms.keys().len == 0) continue;
35983598
35993599 // Create jump/branch range extenders if needed.
36003600 try self.createThunks(atom_list);
......@@ -4058,7 +4058,7 @@ fn writeAtoms(self: *Elf) !void {
40584058 var has_reloc_errors = false;
40594059 for (slice.items(.shdr), slice.items(.atom_list_2)) |shdr, atom_list| {
40604060 if (shdr.sh_type == elf.SHT_NOBITS) continue;
4061 if (atom_list.atoms.items.len == 0) continue;
4061 if (atom_list.atoms.keys().len == 0) continue;
40624062 atom_list.write(&buffer, &undefs, self) catch |err| switch (err) {
40634063 error.UnsupportedCpuArch => {
40644064 try self.reportUnsupportedCpuArch();
......@@ -5732,20 +5732,20 @@ fn createThunks(elf_file: *Elf, atom_list: *AtomList) !void {
57325732 }
57335733 }.advance;
57345734
5735 for (atom_list.atoms.items) |ref| {
5735 for (atom_list.atoms.keys()) |ref| {
57365736 elf_file.atom(ref).?.value = -1;
57375737 }
57385738
57395739 var i: usize = 0;
5740 while (i < atom_list.atoms.items.len) {
5740 while (i < atom_list.atoms.keys().len) {
57415741 const start = i;
5742 const start_atom = elf_file.atom(atom_list.atoms.items[start]).?;
5742 const start_atom = elf_file.atom(atom_list.atoms.keys()[start]).?;
57435743 assert(start_atom.alive);
57445744 start_atom.value = try advance(atom_list, start_atom.size, start_atom.alignment);
57455745 i += 1;
57465746
5747 while (i < atom_list.atoms.items.len) : (i += 1) {
5748 const atom_ptr = elf_file.atom(atom_list.atoms.items[i]).?;
5747 while (i < atom_list.atoms.keys().len) : (i += 1) {
5748 const atom_ptr = elf_file.atom(atom_list.atoms.keys()[i]).?;
57495749 assert(atom_ptr.alive);
57505750 if (@as(i64, @intCast(atom_ptr.alignment.forward(atom_list.size))) - start_atom.value >= max_distance)
57515751 break;
......@@ -5758,7 +5758,7 @@ fn createThunks(elf_file: *Elf, atom_list: *AtomList) !void {
57585758 thunk_ptr.output_section_index = atom_list.output_section_index;
57595759
57605760 // Scan relocs in the group and create trampolines for any unreachable callsite
5761 for (atom_list.atoms.items[start..i]) |ref| {
5761 for (atom_list.atoms.keys()[start..i]) |ref| {
57625762 const atom_ptr = elf_file.atom(ref).?;
57635763 const file_ptr = atom_ptr.file(elf_file).?;
57645764 log.debug("atom({}) {s}", .{ ref, atom_ptr.name(elf_file) });
src/link/Elf/AtomList.zig+17-16
......@@ -2,7 +2,8 @@ value: i64 = 0,
22size: u64 = 0,
33alignment: Atom.Alignment = .@"1",
44output_section_index: u32 = 0,
5atoms: std.ArrayListUnmanaged(Elf.Ref) = .empty,
5// atoms: std.ArrayListUnmanaged(Elf.Ref) = .empty,
6atoms: std.AutoArrayHashMapUnmanaged(Elf.Ref, void) = .empty,
67
78pub fn deinit(list: *AtomList, allocator: Allocator) void {
89 list.atoms.deinit(allocator);
......@@ -22,7 +23,7 @@ pub fn updateSize(list: *AtomList, elf_file: *Elf) void {
2223 // TODO perhaps a 'stale' flag would be better here?
2324 list.size = 0;
2425 list.alignment = .@"1";
25 for (list.atoms.items) |ref| {
26 for (list.atoms.keys()) |ref| {
2627 const atom_ptr = elf_file.atom(ref).?;
2728 assert(atom_ptr.alive);
2829 const off = atom_ptr.alignment.forward(list.size);
......@@ -56,13 +57,13 @@ pub fn allocate(list: *AtomList, elf_file: *Elf) !void {
5657 // FIXME:JK this currently ignores Thunks as valid chunks.
5758 {
5859 var idx: usize = 0;
59 while (idx < list.atoms.items.len) : (idx += 1) {
60 const curr_atom_ptr = elf_file.atom(list.atoms.items[idx]).?;
60 while (idx < list.atoms.keys().len) : (idx += 1) {
61 const curr_atom_ptr = elf_file.atom(list.atoms.keys()[idx]).?;
6162 if (idx > 0) {
62 curr_atom_ptr.prev_atom_ref = list.atoms.items[idx - 1];
63 curr_atom_ptr.prev_atom_ref = list.atoms.keys()[idx - 1];
6364 }
64 if (idx + 1 < list.atoms.items.len) {
65 curr_atom_ptr.next_atom_ref = list.atoms.items[idx + 1];
65 if (idx + 1 < list.atoms.keys().len) {
66 curr_atom_ptr.next_atom_ref = list.atoms.keys()[idx + 1];
6667 }
6768 }
6869 }
......@@ -74,7 +75,7 @@ pub fn allocate(list: *AtomList, elf_file: *Elf) !void {
7475 }
7576
7677 // FIXME:JK if we had a link from Atom to parent AtomList we would not need to update Atom's value or osec index
77 for (list.atoms.items) |ref| {
78 for (list.atoms.keys()) |ref| {
7879 const atom_ptr = elf_file.atom(ref).?;
7980 atom_ptr.output_section_index = list.output_section_index;
8081 atom_ptr.value += list.value;
......@@ -92,7 +93,7 @@ pub fn write(list: AtomList, buffer: *std.ArrayList(u8), undefs: anytype, elf_fi
9293 try buffer.ensureUnusedCapacity(list_size);
9394 buffer.appendNTimesAssumeCapacity(0, list_size);
9495
95 for (list.atoms.items) |ref| {
96 for (list.atoms.keys()) |ref| {
9697 const atom_ptr = elf_file.atom(ref).?;
9798 assert(atom_ptr.alive);
9899
......@@ -128,7 +129,7 @@ pub fn writeRelocatable(list: AtomList, buffer: *std.ArrayList(u8), elf_file: *E
128129 try buffer.ensureUnusedCapacity(list_size);
129130 buffer.appendNTimesAssumeCapacity(0, list_size);
130131
131 for (list.atoms.items) |ref| {
132 for (list.atoms.keys()) |ref| {
132133 const atom_ptr = elf_file.atom(ref).?;
133134 assert(atom_ptr.alive);
134135
......@@ -149,13 +150,13 @@ pub fn writeRelocatable(list: AtomList, buffer: *std.ArrayList(u8), elf_file: *E
149150}
150151
151152pub fn firstAtom(list: AtomList, elf_file: *Elf) *Atom {
152 assert(list.atoms.items.len > 0);
153 return elf_file.atom(list.atoms.items[0]).?;
153 assert(list.atoms.keys().len > 0);
154 return elf_file.atom(list.atoms.keys()[0]).?;
154155}
155156
156157pub fn lastAtom(list: AtomList, elf_file: *Elf) *Atom {
157 assert(list.atoms.items.len > 0);
158 return elf_file.atom(list.atoms.items[list.atoms.items.len - 1]).?;
158 assert(list.atoms.keys().len > 0);
159 return elf_file.atom(list.atoms.keys()[list.atoms.keys().len - 1]).?;
159160}
160161
161162pub fn format(
......@@ -191,9 +192,9 @@ fn format2(
191192 list.alignment.toByteUnits() orelse 0, list.size,
192193 });
193194 try writer.writeAll(" : atoms{ ");
194 for (list.atoms.items, 0..) |ref, i| {
195 for (list.atoms.keys(), 0..) |ref, i| {
195196 try writer.print("{}", .{ref});
196 if (i < list.atoms.items.len - 1) try writer.writeAll(", ");
197 if (i < list.atoms.keys().len - 1) try writer.writeAll(", ");
197198 }
198199 try writer.writeAll(" }");
199200}
src/link/Elf/Object.zig+1-1
......@@ -915,7 +915,7 @@ pub fn initOutputSections(self: *Object, elf_file: *Elf) !void {
915915 });
916916 const atom_list = &elf_file.sections.items(.atom_list_2)[osec];
917917 atom_list.output_section_index = osec;
918 try atom_list.atoms.append(elf_file.base.comp.gpa, atom_ptr.ref());
918 _ = try atom_list.atoms.getOrPut(elf_file.base.comp.gpa, atom_ptr.ref());
919919 }
920920}
921921
src/link/Elf/relocatable.zig+2-2
......@@ -335,7 +335,7 @@ fn initComdatGroups(elf_file: *Elf) !void {
335335fn updateSectionSizes(elf_file: *Elf) !void {
336336 const slice = elf_file.sections.slice();
337337 for (slice.items(.atom_list_2)) |*atom_list| {
338 if (atom_list.atoms.items.len == 0) continue;
338 if (atom_list.atoms.keys().len == 0) continue;
339339 atom_list.updateSize(elf_file);
340340 try atom_list.allocate(elf_file);
341341 }
......@@ -434,7 +434,7 @@ fn writeAtoms(elf_file: *Elf) !void {
434434 const slice = elf_file.sections.slice();
435435 for (slice.items(.shdr), slice.items(.atom_list_2)) |shdr, atom_list| {
436436 if (shdr.sh_type == elf.SHT_NOBITS) continue;
437 if (atom_list.atoms.items.len == 0) continue;
437 if (atom_list.atoms.keys().len == 0) continue;
438438 try atom_list.writeRelocatable(&buffer, elf_file);
439439 }
440440}