Commit 1448d6b77c
Changed files (2)
src
link
src/link/Elf/ZigModule.zig
@@ -7,8 +7,8 @@
path: []const u8,
index: File.Index,
-local_esyms: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{},
-global_esyms: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{},
+local_esyms: std.MultiArrayList(ElfSym) = .{},
+global_esyms: std.MultiArrayList(ElfSym) = .{},
local_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
global_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
globals_lookup: std.AutoHashMapUnmanaged(u32, Symbol.Index) = .{},
@@ -20,6 +20,10 @@ num_dynrelocs: u32 = 0,
output_symtab_size: Elf.SymtabSize = .{},
+pub const global_symbol_bit: u32 = 0x80000000;
+pub const symbol_mask: u32 = 0x7fffffff;
+pub const SHN_ATOM: u16 = 0x100;
+
pub fn deinit(self: *ZigModule, allocator: Allocator) void {
self.local_esyms.deinit(allocator);
self.global_esyms.deinit(allocator);
@@ -35,20 +39,20 @@ pub fn deinit(self: *ZigModule, allocator: Allocator) void {
pub fn addLocalEsym(self: *ZigModule, allocator: Allocator) !Symbol.Index {
try self.local_esyms.ensureUnusedCapacity(allocator, 1);
- const index = @as(Symbol.Index, @intCast(self.local_esyms.items.len));
- const esym = self.local_esyms.addOneAssumeCapacity();
- esym.* = Elf.null_sym;
- esym.st_info = elf.STB_LOCAL << 4;
+ const index = @as(Symbol.Index, @intCast(self.local_esyms.addOneAssumeCapacity()));
+ var esym = ElfSym{ .elf_sym = Elf.null_sym };
+ esym.elf_sym.st_info = elf.STB_LOCAL << 4;
+ self.local_esyms.set(index, esym);
return index;
}
pub fn addGlobalEsym(self: *ZigModule, allocator: Allocator) !Symbol.Index {
try self.global_esyms.ensureUnusedCapacity(allocator, 1);
- const index = @as(Symbol.Index, @intCast(self.global_esyms.items.len));
- const esym = self.global_esyms.addOneAssumeCapacity();
- esym.* = Elf.null_sym;
- esym.st_info = elf.STB_GLOBAL << 4;
- return index | 0x10000000;
+ const index = @as(Symbol.Index, @intCast(self.global_esyms.addOneAssumeCapacity()));
+ var esym = ElfSym{ .elf_sym = Elf.null_sym };
+ esym.elf_sym.st_info = elf.STB_GLOBAL << 4;
+ self.global_esyms.set(index, esym);
+ return index | global_symbol_bit;
}
pub fn addAtom(self: *ZigModule, elf_file: *Elf) !Symbol.Index {
@@ -58,7 +62,7 @@ pub fn addAtom(self: *ZigModule, elf_file: *Elf) !Symbol.Index {
const symbol_index = try elf_file.addSymbol();
const esym_index = try self.addLocalEsym(gpa);
- const shndx = @as(u16, @intCast(self.atoms.items.len));
+ const shndx = @as(u32, @intCast(self.atoms.items.len));
try self.atoms.append(gpa, atom_index);
try self.local_symbols.append(gpa, symbol_index);
@@ -69,8 +73,8 @@ pub fn addAtom(self: *ZigModule, elf_file: *Elf) !Symbol.Index {
symbol_ptr.file_index = self.index;
symbol_ptr.atom_index = atom_index;
- const esym = &self.local_esyms.items[esym_index];
- esym.st_shndx = shndx;
+ self.local_esyms.items(.shndx)[esym_index] = shndx;
+ self.local_esyms.items(.elf_sym)[esym_index].st_shndx = SHN_ATOM;
symbol_ptr.esym_index = esym_index;
const relocs_index = @as(u32, @intCast(self.relocs.items.len));
@@ -99,13 +103,15 @@ pub fn inputShdr(self: ZigModule, atom_index: Atom.Index, elf_file: *Elf) Object
pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void {
for (self.globals(), 0..) |index, i| {
- const esym_index = @as(Symbol.Index, @intCast(i)) | 0x10000000;
- const esym = self.global_esyms.items[i];
+ const esym_index = @as(Symbol.Index, @intCast(i)) | global_symbol_bit;
+ const esym = self.global_esyms.items(.elf_sym)[i];
+ const shndx = self.global_esyms.items(.shndx)[i];
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 = self.atoms.items[esym.st_shndx];
+ assert(esym.st_shndx == SHN_ATOM);
+ const atom_index = self.atoms.items[shndx];
const atom = elf_file.atom(atom_index) orelse continue;
if (!atom.flags.alive) continue;
}
@@ -114,7 +120,8 @@ 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 => self.atoms.items[esym.st_shndx],
+ SHN_ATOM => self.atoms.items[shndx],
+ else => unreachable,
};
const output_section_index = if (elf_file.atom(atom_index)) |atom|
atom.outputShndx().?
@@ -133,8 +140,8 @@ pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void {
pub fn claimUnresolved(self: *ZigModule, elf_file: *Elf) void {
for (self.globals(), 0..) |index, i| {
- const esym_index = @as(Symbol.Index, @intCast(i)) | 0x10000000;
- const esym = self.global_esyms.items[i];
+ const esym_index = @as(Symbol.Index, @intCast(i)) | global_symbol_bit;
+ const esym = self.global_esyms.items(.elf_sym)[i];
if (esym.st_shndx != elf.SHN_UNDEF) continue;
@@ -187,7 +194,7 @@ pub fn resetGlobals(self: *ZigModule, elf_file: *Elf) void {
pub fn markLive(self: *ZigModule, elf_file: *Elf) void {
for (self.globals(), 0..) |index, i| {
- const esym = self.global_esyms.items[i];
+ const esym = self.global_esyms.items(.elf_sym)[i];
if (esym.st_bind() == elf.STB_WEAK) continue;
const global = elf_file.symbol(index);
@@ -256,17 +263,17 @@ pub fn writeSymtab(self: *ZigModule, elf_file: *Elf, ctx: anytype) void {
}
pub fn symbol(self: *ZigModule, index: Symbol.Index) Symbol.Index {
- const is_global = index & 0x10000000 != 0;
- const actual_index = index & 0x0fffffff;
+ const is_global = index & global_symbol_bit != 0;
+ const actual_index = index & symbol_mask;
if (is_global) return self.global_symbols.items[actual_index];
return self.local_symbols.items[actual_index];
}
pub fn elfSym(self: *ZigModule, index: Symbol.Index) *elf.Elf64_Sym {
- const is_global = index & 0x10000000 != 0;
- const actual_index = index & 0x0fffffff;
- if (is_global) return &self.global_esyms.items[actual_index];
- return &self.local_esyms.items[actual_index];
+ const is_global = index & global_symbol_bit != 0;
+ const actual_index = index & symbol_mask;
+ if (is_global) return &self.global_esyms.items(.elf_sym)[actual_index];
+ return &self.local_esyms.items(.elf_sym)[actual_index];
}
pub fn locals(self: *ZigModule) []const Symbol.Index {
@@ -354,6 +361,11 @@ fn formatAtoms(
}
}
+const ElfSym = struct {
+ elf_sym: elf.Elf64_Sym,
+ shndx: u32 = elf.SHN_UNDEF,
+};
+
const assert = std.debug.assert;
const std = @import("std");
const elf = std.elf;
src/link/Elf.zig
@@ -331,7 +331,7 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option
symbol_ptr.name_offset = name_off;
const esym_index = try zig_module.addLocalEsym(allocator);
- const esym = &zig_module.local_esyms.items[esym_index];
+ const esym = &zig_module.local_esyms.items(.elf_sym)[esym_index];
esym.st_name = name_off;
esym.st_info |= elf.STT_FILE;
esym.st_shndx = elf.SHN_ABS;
@@ -3172,7 +3172,7 @@ fn updateDeclCode(
const required_alignment = decl.getAlignment(mod);
const sym = self.symbol(sym_index);
- const esym = &zig_module.local_esyms.items[sym.esym_index];
+ const esym = &zig_module.local_esyms.items(.elf_sym)[sym.esym_index];
const atom_ptr = sym.atom(self).?;
const shdr_index = self.getDeclShdrIndex(decl_index, code);
@@ -3438,7 +3438,7 @@ fn updateLazySymbol(self: *Elf, sym: link.File.LazySymbol, symbol_index: Symbol.
const phdr_index = self.phdr_to_shdr_table.get(output_section_index).?;
local_sym.name_offset = name_str_index;
local_sym.output_section_index = output_section_index;
- const local_esym = &zig_module.local_esyms.items[local_sym.esym_index];
+ const local_esym = &zig_module.local_esyms.items(.elf_sym)[local_sym.esym_index];
local_esym.st_name = name_str_index;
local_esym.st_info |= elf.STT_OBJECT;
local_esym.st_size = code.len;
@@ -3527,7 +3527,7 @@ fn lowerConst(
const name_str_index = try self.strtab.insert(gpa, name);
local_sym.name_offset = name_str_index;
local_sym.output_section_index = output_section_index;
- const local_esym = &zig_module.local_esyms.items[local_sym.esym_index];
+ const local_esym = &zig_module.local_esyms.items(.elf_sym)[local_sym.esym_index];
local_esym.st_name = name_str_index;
local_esym.st_info |= elf.STT_OBJECT;
local_esym.st_size = code.len;
@@ -3573,7 +3573,9 @@ pub fn updateDeclExports(
const zig_module = self.file(self.zig_module_index.?).?.zig_module;
const decl = mod.declPtr(decl_index);
const decl_sym_index = try self.getOrCreateMetadataForDecl(decl_index);
- const decl_esym = zig_module.local_esyms.items[self.symbol(decl_sym_index).esym_index];
+ const decl_esym_index = self.symbol(decl_sym_index).esym_index;
+ const decl_esym = zig_module.local_esyms.items(.elf_sym)[decl_esym_index];
+ const decl_esym_shndx = zig_module.local_esyms.items(.shndx)[decl_esym_index];
const decl_metadata = self.decls.getPtr(decl_index).?;
for (exports) |exp| {
@@ -3615,11 +3617,13 @@ pub fn updateDeclExports(
try zig_module.global_symbols.append(gpa, gop.index);
break :blk sym_index;
};
- const esym = &zig_module.global_esyms.items[sym_index & 0x0fffffff];
- esym.st_value = self.symbol(decl_sym_index).value;
- esym.st_shndx = decl_esym.st_shndx;
- esym.st_info = (stb_bits << 4) | stt_bits;
- esym.st_name = name_off;
+ const global_esym_index = sym_index & ZigModule.symbol_mask;
+ const global_esym = &zig_module.global_esyms.items(.elf_sym)[global_esym_index];
+ global_esym.st_value = self.symbol(decl_sym_index).value;
+ global_esym.st_shndx = decl_esym.st_shndx;
+ global_esym.st_info = (stb_bits << 4) | stt_bits;
+ global_esym.st_name = name_off;
+ zig_module.global_esyms.items(.shndx)[global_esym_index] = decl_esym_shndx;
}
}
@@ -3651,7 +3655,7 @@ pub fn deleteDeclExport(
const exp_name = mod.intern_pool.stringToSlice(name);
const esym_index = metadata.@"export"(self, exp_name) orelse return;
log.debug("deleting export '{s}'", .{exp_name});
- const esym = &zig_module.global_esyms.items[esym_index.*];
+ const esym = &zig_module.global_esyms.items(.elf_sym)[esym_index.*];
_ = zig_module.globals_lookup.remove(esym.st_name);
const sym_index = self.resolver.get(esym.st_name).?;
const sym = self.symbol(sym_index);
@@ -3660,6 +3664,7 @@ pub fn deleteDeclExport(
sym.* = .{};
}
esym.* = null_sym;
+ zig_module.global_esyms.items(.shndx)[esym_index.*] = elf.SHN_UNDEF;
}
fn addLinkerDefinedSymbols(self: *Elf) !void {