diff --git a/src/link/Elf.zig b/src/link/Elf.zig index a8590c18d3..69685dc0e9 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -176,7 +176,6 @@ symtab_section_index: ?u32 = null, /// An array of symbols parsed across all input files. symbols: std.ArrayListUnmanaged(Symbol) = .{}, symbols_extra: std.ArrayListUnmanaged(u32) = .{}, -symbols_free_list: std.ArrayListUnmanaged(Symbol.Index) = .{}, resolver: std.AutoArrayHashMapUnmanaged(u32, Symbol.Index) = .{}, @@ -343,8 +342,6 @@ pub fn createEmpty( // Index 0 is always a null symbol. try self.symbols.append(gpa, .{}); - // Index 0 is always a null symbol. - try self.symbols_extra.append(gpa, 0); // Append null file at index 0 try self.files.append(gpa, .null); // Append null byte to string tables @@ -462,7 +459,6 @@ pub fn deinit(self: *Elf) void { self.strtab.deinit(gpa); self.symbols.deinit(gpa); self.symbols_extra.deinit(gpa); - self.symbols_free_list.deinit(gpa); self.resolver.deinit(gpa); for (self.thunks.items) |*th| { @@ -5389,17 +5385,8 @@ pub fn symbol(self: *Elf, sym_index: Symbol.Index) *Symbol { pub fn addSymbol(self: *Elf) !Symbol.Index { const gpa = self.base.comp.gpa; try self.symbols.ensureUnusedCapacity(gpa, 1); - const index = blk: { - if (self.symbols_free_list.popOrNull()) |index| { - log.debug(" (reusing symbol index {d})", .{index}); - break :blk index; - } else { - log.debug(" (allocating symbol index {d})", .{self.symbols.items.len}); - const index: Symbol.Index = @intCast(self.symbols.items.len); - _ = self.symbols.addOneAssumeCapacity(); - break :blk index; - } - }; + const index: Symbol.Index = @intCast(self.symbols.items.len); + _ = self.symbols.addOneAssumeCapacity(); self.symbols.items[index] = .{}; return index; } @@ -5423,8 +5410,7 @@ pub fn addSymbolExtraAssumeCapacity(self: *Elf, extra: Symbol.Extra) u32 { return index; } -pub fn symbolExtra(self: *Elf, index: u32) ?Symbol.Extra { - if (index == 0) return null; +pub fn symbolExtra(self: *Elf, index: u32) Symbol.Extra { const fields = @typeInfo(Symbol.Extra).Struct.fields; var i: usize = index; var result: Symbol.Extra = undefined; @@ -5439,7 +5425,6 @@ pub fn symbolExtra(self: *Elf, index: u32) ?Symbol.Extra { } pub fn setSymbolExtra(self: *Elf, index: u32, extra: Symbol.Extra) void { - assert(index > 0); const fields = @typeInfo(Symbol.Extra).Struct.fields; inline for (fields, 0..) |field, i| { self.symbols_extra.items[index + i] = switch (field.type) { @@ -5464,6 +5449,7 @@ pub fn getOrPutGlobal(self: *Elf, name: []const u8) !GetOrPutGlobalResult { const global = self.symbol(index); global.name_offset = name_off; global.flags.global = true; + global.extra_index = try self.addSymbolExtra(.{}); gop.value_ptr.* = index; } return .{ diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig index b91b546103..0f1ea4b6e3 100644 --- a/src/link/Elf/Atom.zig +++ b/src/link/Elf/Atom.zig @@ -845,7 +845,7 @@ fn resolveDynAbsReloc( if (is_writeable or elf_file.z_nocopyreloc) { elf_file.addRelaDynAssumeCapacity(.{ .offset = P, - .sym = target.extra(elf_file).?.dynamic, + .sym = target.extra(elf_file).dynamic, .type = relocation.encode(.abs, cpu_arch), .addend = A, }); @@ -859,7 +859,7 @@ fn resolveDynAbsReloc( if (is_writeable) { elf_file.addRelaDynAssumeCapacity(.{ .offset = P, - .sym = target.extra(elf_file).?.dynamic, + .sym = target.extra(elf_file).dynamic, .type = relocation.encode(.abs, cpu_arch), .addend = A, }); @@ -872,7 +872,7 @@ fn resolveDynAbsReloc( .dynrel => { elf_file.addRelaDynAssumeCapacity(.{ .offset = P, - .sym = target.extra(elf_file).?.dynamic, + .sym = target.extra(elf_file).dynamic, .type = relocation.encode(.abs, cpu_arch), .addend = A, }); diff --git a/src/link/Elf/Object.zig b/src/link/Elf/Object.zig index 9185ca0ef7..1b3e768c7d 100644 --- a/src/link/Elf/Object.zig +++ b/src/link/Elf/Object.zig @@ -387,6 +387,7 @@ fn initSymtab(self: *Object, allocator: Allocator, elf_file: *Elf) !void { sym_ptr.name_offset = sym.st_name; sym_ptr.esym_index = @as(u32, @intCast(i)); sym_ptr.file_index = self.index; + sym_ptr.extra_index = try elf_file.addSymbolExtra(.{}); if (sym.st_shndx != elf.SHN_ABS) { sym_ptr.ref = .{ .index = self.atoms_indexes.items[sym.st_shndx], .file = self.index }; } @@ -865,6 +866,7 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) !void { .name_offset = try self.addString(gpa, name), .esym_index = rel.r_sym(), .file_index = self.index, + .extra_index = try elf_file.addSymbolExtra(.{}), }; sym.ref = .{ .index = res.msub_index, .file = imsec.merge_section_index }; sym.flags.merge_subsection = true; diff --git a/src/link/Elf/Symbol.zig b/src/link/Elf/Symbol.zig index 68d23cb74d..2c1ce0a104 100644 --- a/src/link/Elf/Symbol.zig +++ b/src/link/Elf/Symbol.zig @@ -159,20 +159,20 @@ pub fn outputSymtabIndex(symbol: Symbol, elf_file: *Elf) ?u32 { const symtab_ctx = switch (file_ptr) { inline else => |x| x.output_symtab_ctx, }; - const idx = symbol.extra(elf_file).?.symtab; + const idx = symbol.extra(elf_file).symtab; return if (symbol.isLocal(elf_file)) idx + symtab_ctx.ilocal else idx + symtab_ctx.iglobal; } pub fn gotAddress(symbol: Symbol, elf_file: *Elf) i64 { if (!symbol.flags.has_got) return 0; - const extras = symbol.extra(elf_file).?; + const extras = symbol.extra(elf_file); const entry = elf_file.got.entries.items[extras.got]; return entry.address(elf_file); } pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 { if (!(symbol.flags.has_plt and symbol.flags.has_got)) return 0; - const extras = symbol.extra(elf_file).?; + const extras = symbol.extra(elf_file); const shdr = elf_file.shdrs.items[elf_file.plt_got_section_index.?]; const cpu_arch = elf_file.getTarget().cpu.arch; return @intCast(shdr.sh_addr + extras.plt_got * PltGotSection.entrySize(cpu_arch)); @@ -180,7 +180,7 @@ pub fn pltGotAddress(symbol: Symbol, elf_file: *Elf) i64 { pub fn pltAddress(symbol: Symbol, elf_file: *Elf) i64 { if (!symbol.flags.has_plt) return 0; - const extras = symbol.extra(elf_file).?; + const extras = symbol.extra(elf_file); const shdr = elf_file.shdrs.items[elf_file.plt_section_index.?]; const cpu_arch = elf_file.getTarget().cpu.arch; return @intCast(shdr.sh_addr + extras.plt * PltSection.entrySize(cpu_arch) + PltSection.preambleSize(cpu_arch)); @@ -188,7 +188,7 @@ pub fn pltAddress(symbol: Symbol, elf_file: *Elf) i64 { pub fn gotPltAddress(symbol: Symbol, elf_file: *Elf) i64 { if (!symbol.flags.has_plt) return 0; - const extras = symbol.extra(elf_file).?; + const extras = symbol.extra(elf_file); const shdr = elf_file.shdrs.items[elf_file.got_plt_section_index.?]; return @intCast(shdr.sh_addr + extras.plt * 8 + GotPltSection.preamble_size); } @@ -201,21 +201,21 @@ pub fn copyRelAddress(symbol: Symbol, elf_file: *Elf) i64 { pub fn tlsGdAddress(symbol: Symbol, elf_file: *Elf) i64 { if (!symbol.flags.has_tlsgd) return 0; - const extras = symbol.extra(elf_file).?; + const extras = symbol.extra(elf_file); const entry = elf_file.got.entries.items[extras.tlsgd]; return entry.address(elf_file); } pub fn gotTpAddress(symbol: Symbol, elf_file: *Elf) i64 { if (!symbol.flags.has_gottp) return 0; - const extras = symbol.extra(elf_file).?; + const extras = symbol.extra(elf_file); const entry = elf_file.got.entries.items[extras.gottp]; return entry.address(elf_file); } pub fn tlsDescAddress(symbol: Symbol, elf_file: *Elf) i64 { if (!symbol.flags.has_tlsdesc) return 0; - const extras = symbol.extra(elf_file).?; + const extras = symbol.extra(elf_file); const entry = elf_file.got.entries.items[extras.tlsdesc]; return entry.address(elf_file); } @@ -228,14 +228,14 @@ const GetOrCreateZigGotEntryResult = struct { pub fn getOrCreateZigGotEntry(symbol: *Symbol, symbol_index: Index, elf_file: *Elf) !GetOrCreateZigGotEntryResult { assert(!elf_file.base.isRelocatable()); assert(symbol.flags.needs_zig_got); - if (symbol.flags.has_zig_got) return .{ .found_existing = true, .index = symbol.extra(elf_file).?.zig_got }; + if (symbol.flags.has_zig_got) return .{ .found_existing = true, .index = symbol.extra(elf_file).zig_got }; const index = try elf_file.zig_got.addSymbol(symbol_index, elf_file); return .{ .found_existing = false, .index = index }; } pub fn zigGotAddress(symbol: Symbol, elf_file: *Elf) i64 { if (!symbol.flags.has_zig_got) return 0; - const extras = symbol.extra(elf_file).?; + const extras = symbol.extra(elf_file); return elf_file.zig_got.entryAddress(extras.zig_got, elf_file); } @@ -266,10 +266,7 @@ const AddExtraOpts = struct { }; pub fn addExtra(symbol: *Symbol, opts: AddExtraOpts, elf_file: *Elf) !void { - if (symbol.extra(elf_file) == null) { - symbol.extra_index = try elf_file.addSymbolExtra(.{}); - } - var extras = symbol.extra(elf_file).?; + var extras = symbol.extra(elf_file); inline for (@typeInfo(@TypeOf(opts)).Struct.fields) |field| { if (@field(opts, field.name)) |x| { @field(extras, field.name) = x; @@ -278,7 +275,7 @@ pub fn addExtra(symbol: *Symbol, opts: AddExtraOpts, elf_file: *Elf) !void { symbol.setExtra(extras, elf_file); } -pub fn extra(symbol: Symbol, elf_file: *Elf) ?Extra { +pub fn extra(symbol: Symbol, elf_file: *Elf) Extra { return elf_file.symbolExtra(symbol.extra_index); } diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index 454646bfeb..554e038d95 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -92,6 +92,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf) !void { const symbol_ptr = elf_file.symbol(symbol_index); symbol_ptr.file_index = self.index; symbol_ptr.name_offset = name_off; + symbol_ptr.extra_index = try elf_file.addSymbolExtra(.{}); const esym_index = try self.addLocalEsym(gpa); const esym = &self.local_esyms.items(.elf_sym)[esym_index]; @@ -292,6 +293,7 @@ pub fn newAtom(self: *ZigObject, elf_file: *Elf) !Symbol.Index { const symbol_ptr = elf_file.symbol(symbol_index); symbol_ptr.file_index = self.index; symbol_ptr.ref = .{ .index = atom_index, .file = self.index }; + symbol_ptr.extra_index = try elf_file.addSymbolExtra(.{}); self.local_esyms.items(.shndx)[esym_index] = atom_index; self.local_esyms.items(.elf_sym)[esym_index].st_shndx = SHN_ATOM; @@ -779,11 +781,9 @@ fn freeUnnamedConsts(self: *ZigObject, elf_file: *Elf, decl_index: InternPool.De fn freeDeclMetadata(self: *ZigObject, elf_file: *Elf, sym_index: Symbol.Index) void { _ = self; - const gpa = elf_file.base.comp.gpa; const sym = elf_file.symbol(sym_index); sym.atom(elf_file).?.free(elf_file); log.debug("adding %{d} to local symbols free list", .{sym_index}); - elf_file.symbols_free_list.append(gpa, sym_index) catch {}; elf_file.symbols.items[sym_index] = .{}; // TODO free GOT entry here } @@ -940,7 +940,7 @@ fn updateDeclCode( if (!elf_file.base.isRelocatable()) { log.debug(" (writing new offset table entry)", .{}); assert(sym.flags.has_zig_got); - const extra = sym.extra(elf_file).?; + const extra = sym.extra(elf_file); try elf_file.zig_got.writeOne(elf_file, extra.zig_got); } } diff --git a/src/link/Elf/file.zig b/src/link/Elf/file.zig index 9d2560e11b..346f83d10b 100644 --- a/src/link/Elf/file.zig +++ b/src/link/Elf/file.zig @@ -71,9 +71,11 @@ pub const File = union(enum) { for (file.globals()) |global_index| { const global = elf_file.symbol(global_index); const name_offset = global.name_offset; + const extra_index = global.extra_index; global.* = .{}; global.name_offset = name_offset; global.flags.global = true; + global.extra_index = extra_index; } } diff --git a/src/link/Elf/synthetic_sections.zig b/src/link/Elf/synthetic_sections.zig index c5c2359890..df98b753b3 100644 --- a/src/link/Elf/synthetic_sections.zig +++ b/src/link/Elf/synthetic_sections.zig @@ -641,7 +641,7 @@ pub const GotSection = struct { .tlsld => null, inline else => elf_file.symbol(entry.symbol_index), }; - const extra = if (symbol) |s| s.extra(elf_file).? else null; + const extra = if (symbol) |s| s.extra(elf_file) else null; switch (entry.tag) { .got => { @@ -898,7 +898,7 @@ pub const PltSection = struct { for (plt.symbols.items) |sym_index| { const sym = elf_file.symbol(sym_index); assert(sym.flags.import); - const extra = sym.extra(elf_file).?; + const extra = sym.extra(elf_file); const r_offset: u64 = @intCast(sym.gotPltAddress(elf_file)); const r_sym: u64 = extra.dynamic; const r_type = relocation.encode(.jump_slot, cpu_arch); @@ -1267,7 +1267,7 @@ pub const CopyRelSection = struct { for (copy_rel.symbols.items) |sym_index| { const sym = elf_file.symbol(sym_index); assert(sym.flags.import and sym.flags.has_copy_rel); - const extra = sym.extra(elf_file).?; + const extra = sym.extra(elf_file); elf_file.addRelaDynAssumeCapacity(.{ .offset = @intCast(sym.address(.{}, elf_file)), .sym = extra.dynamic, @@ -1322,7 +1322,7 @@ pub const DynsymSection = struct { const rhs_hash = GnuHashSection.hasher(rhs_sym.name(ctx)) % nbuckets; if (lhs_hash == rhs_hash) - return lhs_sym.extra(ctx).?.dynamic < rhs_sym.extra(ctx).?.dynamic; + return lhs_sym.extra(ctx).dynamic < rhs_sym.extra(ctx).dynamic; return lhs_hash < rhs_hash; } }; @@ -1339,7 +1339,7 @@ pub const DynsymSection = struct { for (dynsym.entries.items, 1..) |entry, index| { const sym = elf_file.symbol(entry.symbol_index); - var extra = sym.extra(elf_file).?; + var extra = sym.extra(elf_file); extra.dynamic = @as(u32, @intCast(index)); sym.setExtra(extra, elf_file); }