From 75f4420c2db46cc3d9fe9c75ac035c588bbcf4bf Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 30 Sep 2023 12:09:16 +0200 Subject: [PATCH] elf: increase Atom.Index resolution to u32 --- src/link/Elf.zig | 6 +++--- src/link/Elf/Atom.zig | 14 ++++++-------- src/link/Elf/ZigModule.zig | 17 +++++++++-------- src/link/Elf/file.zig | 2 +- 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 48b29588e4..e278c45086 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -887,7 +887,7 @@ pub fn populateMissingMetadata(self: *Elf) !void { } }); self.zig_module_index = index; const zig_module = self.file(index).?.zig_module; - + try zig_module.atoms.append(gpa, 0); // null input section const name_off = try self.strtab.insert(gpa, std.fs.path.stem(module.main_mod.root_src_path)); const symbol_index = try self.addSymbol(); try zig_module.local_symbols.append(gpa, symbol_index); @@ -1319,7 +1319,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node // the relocations, and commit objects to file. if (self.zig_module_index) |index| { const zig_module = self.file(index).?.zig_module; - for (zig_module.atoms.keys()) |atom_index| { + for (zig_module.atoms.items) |atom_index| { const atom_ptr = self.atom(atom_index).?; if (!atom_ptr.flags.alive) continue; const shdr = &self.shdrs.items[atom_ptr.outputShndx().?]; @@ -3245,7 +3245,7 @@ pub fn updateDeclExports( }; const esym = &zig_module.global_esyms.items[sym_index & 0x0fffffff]; esym.st_value = decl_sym.value; - esym.st_shndx = decl_sym.atom_index; + esym.st_shndx = decl_esym.st_shndx; esym.st_info = (stb_bits << 4) | stt_bits; esym.st_name = name_off; } diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig index 14c10bb244..762c572abc 100644 --- a/src/link/Elf/Atom.zig +++ b/src/link/Elf/Atom.zig @@ -14,13 +14,13 @@ size: u64 = 0, alignment: Alignment = .@"1", /// Index of the input section. -input_section_index: Index = 0, +input_section_index: u16 = 0, /// Index of the output section. output_section_index: u16 = 0, /// Index of the input section containing this atom's relocs. -relocs_section_index: Index = 0, +relocs_section_index: u16 = 0, /// Index of this atom in the linker's atoms table. atom_index: Index = 0, @@ -216,7 +216,6 @@ pub fn free(self: *Atom, elf_file: *Elf) void { log.debug("freeAtom {d} ({s})", .{ self.atom_index, self.name(elf_file) }); const gpa = elf_file.base.allocator; - const zig_module = self.file(elf_file).?.zig_module; const shndx = self.outputShndx().?; const meta = elf_file.last_atom_and_free_list_table.getPtr(shndx).?; const free_list = &meta.free_list; @@ -267,7 +266,9 @@ pub fn free(self: *Atom, elf_file: *Elf) void { // TODO create relocs free list self.freeRelocs(elf_file); - assert(zig_module.atoms.swapRemove(self.atom_index)); + // TODO figure out how to free input section mappind in ZigModule + // const zig_module = self.file(elf_file).?.zig_module; + // assert(zig_module.atoms.swapRemove(self.atom_index)); self.* = .{}; } @@ -698,10 +699,7 @@ fn format2( } } -// TODO this has to be u32 but for now, to avoid redesigning elfSym machinery for -// ZigModule, keep it at u16 with the intention of bumping it to u32 in the near -// future. -pub const Index = u16; +pub const Index = u32; pub const Flags = packed struct { /// Specifies whether this atom is alive or has been garbage collected. diff --git a/src/link/Elf/ZigModule.zig b/src/link/Elf/ZigModule.zig index c79680dbf5..51e2085384 100644 --- a/src/link/Elf/ZigModule.zig +++ b/src/link/Elf/ZigModule.zig @@ -13,7 +13,7 @@ local_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, global_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, globals_lookup: std.AutoHashMapUnmanaged(u32, Symbol.Index) = .{}, -atoms: std.AutoArrayHashMapUnmanaged(Atom.Index, void) = .{}, +atoms: std.ArrayListUnmanaged(Atom.Index) = .{}, relocs: std.ArrayListUnmanaged(std.ArrayListUnmanaged(elf.Elf64_Rela)) = .{}, output_symtab_size: Elf.SymtabSize = .{}, @@ -56,7 +56,8 @@ pub fn addAtom(self: *ZigModule, elf_file: *Elf) !Symbol.Index { const symbol_index = try elf_file.addSymbol(); const esym_index = try self.addLocalEsym(gpa); - try self.atoms.putNoClobber(gpa, atom_index, {}); + const shndx = @as(u16, @intCast(self.atoms.items.len)); + try self.atoms.append(gpa, atom_index); try self.local_symbols.append(gpa, symbol_index); const atom_ptr = elf_file.atom(atom_index).?; @@ -67,10 +68,10 @@ pub fn addAtom(self: *ZigModule, elf_file: *Elf) !Symbol.Index { symbol_ptr.atom_index = atom_index; const esym = &self.local_esyms.items[esym_index]; - esym.st_shndx = atom_index; + esym.st_shndx = shndx; symbol_ptr.esym_index = esym_index; - const relocs_index = @as(Atom.Index, @intCast(self.relocs.items.len)); + const relocs_index = @as(u16, @intCast(self.relocs.items.len)); const relocs = try self.relocs.addOne(gpa); relocs.* = .{}; atom_ptr.relocs_section_index = relocs_index; @@ -86,7 +87,7 @@ pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void { if (esym.st_shndx == elf.SHN_UNDEF) continue; if (esym.st_shndx != elf.SHN_ABS and esym.st_shndx != elf.SHN_COMMON) { - const atom_index = esym.st_shndx; + const atom_index = self.atoms.items[esym.st_shndx]; const atom = elf_file.atom(atom_index) orelse continue; if (!atom.flags.alive) continue; } @@ -95,7 +96,7 @@ pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void { if (self.asFile().symbolRank(esym, false) < global.symbolRank(elf_file)) { const atom_index = switch (esym.st_shndx) { elf.SHN_ABS, elf.SHN_COMMON => 0, - else => esym.st_shndx, + else => self.atoms.items[esym.st_shndx], }; const output_section_index = if (elf_file.atom(atom_index)) |atom| atom.outputShndx().? @@ -141,7 +142,7 @@ pub fn claimUnresolved(self: *ZigModule, elf_file: *Elf) void { } pub fn scanRelocs(self: *ZigModule, elf_file: *Elf, undefs: anytype) !void { - for (self.atoms.keys()) |atom_index| { + for (self.atoms.items) |atom_index| { const atom = elf_file.atom(atom_index) orelse continue; if (!atom.flags.alive) continue; if (try atom.scanRelocsRequiresCode(elf_file)) { @@ -324,7 +325,7 @@ fn formatAtoms( _ = unused_fmt_string; _ = options; try writer.writeAll(" atoms\n"); - for (ctx.self.atoms.keys()) |atom_index| { + for (ctx.self.atoms.items) |atom_index| { const atom = ctx.elf_file.atom(atom_index) orelse continue; try writer.print(" {}\n", .{atom.fmt(ctx.elf_file)}); } diff --git a/src/link/Elf/file.zig b/src/link/Elf/file.zig index a664061fda..937ca6696f 100644 --- a/src/link/Elf/file.zig +++ b/src/link/Elf/file.zig @@ -92,7 +92,7 @@ pub const File = union(enum) { pub fn atoms(file: File) []const Atom.Index { return switch (file) { .linker_defined => unreachable, - .zig_module => |x| x.atoms.keys(), + .zig_module => |x| x.atoms.items, .object => |x| x.atoms.items, }; }