|
|
|
|
@@ -8,9 +8,11 @@ data: std.ArrayListUnmanaged(u8) = .{},
|
|
|
|
|
path: []const u8,
|
|
|
|
|
index: File.Index,
|
|
|
|
|
|
|
|
|
|
local_esyms: std.MultiArrayList(ElfSym) = .{},
|
|
|
|
|
global_esyms: std.MultiArrayList(ElfSym) = .{},
|
|
|
|
|
symtab: std.MultiArrayList(ElfSym) = .{},
|
|
|
|
|
strtab: StringTable = .{},
|
|
|
|
|
symbols: std.ArrayListUnmanaged(Symbol) = .{},
|
|
|
|
|
symbols_extra: std.ArrayListUnmanaged(u32) = .{},
|
|
|
|
|
symbols_resolver: std.ArrayListUnmanaged(Elf.SymbolResolver.Index) = .{},
|
|
|
|
|
local_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
|
|
|
|
|
global_symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
|
|
|
|
|
globals_lookup: std.AutoHashMapUnmanaged(u32, Symbol.Index) = .{},
|
|
|
|
|
@@ -113,9 +115,11 @@ pub fn init(self: *ZigObject, elf_file: *Elf) !void {
|
|
|
|
|
|
|
|
|
|
pub fn deinit(self: *ZigObject, allocator: Allocator) void {
|
|
|
|
|
self.data.deinit(allocator);
|
|
|
|
|
self.local_esyms.deinit(allocator);
|
|
|
|
|
self.global_esyms.deinit(allocator);
|
|
|
|
|
self.symtab.deinit(allocator);
|
|
|
|
|
self.strtab.deinit(allocator);
|
|
|
|
|
self.symbols.deinit(allocator);
|
|
|
|
|
self.symbols_extra.deinit(allocator);
|
|
|
|
|
self.symbols_resolver.deinit(allocator);
|
|
|
|
|
self.local_symbols.deinit(allocator);
|
|
|
|
|
self.global_symbols.deinit(allocator);
|
|
|
|
|
self.globals_lookup.deinit(allocator);
|
|
|
|
|
@@ -263,51 +267,73 @@ fn saveDebugSectionsSizes(self: *ZigObject, elf_file: *Elf) void {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn addLocalEsym(self: *ZigObject, allocator: Allocator) !Symbol.Index {
|
|
|
|
|
try self.local_esyms.ensureUnusedCapacity(allocator, 1);
|
|
|
|
|
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);
|
|
|
|
|
fn newSymbol(self: *ZigObject, allocator: Allocator, name_off: u32, st_bind: u4) !Symbol.Index {
|
|
|
|
|
try self.symtab.ensureUnusedCapacity(allocator, 1);
|
|
|
|
|
try self.symbols.ensureUnusedCapacity(allocator, 1);
|
|
|
|
|
try self.symbols_extra.ensureUnusedCapacity(allocator, @sizeOf(Symbol.Extra));
|
|
|
|
|
|
|
|
|
|
const index = self.addSymbolAssumeCapacity();
|
|
|
|
|
const sym = &self.symbols.items[index];
|
|
|
|
|
sym.name_offset = name_off;
|
|
|
|
|
sym.extra = self.addSymbolExtraAssumeCapacity(.{});
|
|
|
|
|
|
|
|
|
|
const esym_idx: u32 = @intCast(self.symtab.addOneAssumeCapacity());
|
|
|
|
|
const esym = ElfSym{ .elf_sym = .{
|
|
|
|
|
.st_value = 0,
|
|
|
|
|
.st_name = name_off,
|
|
|
|
|
.st_info = @as(u8, @intCast(st_bind)) << 4,
|
|
|
|
|
.st_other = 0,
|
|
|
|
|
.st_size = 0,
|
|
|
|
|
.st_shndx = 0,
|
|
|
|
|
} };
|
|
|
|
|
self.symtab.set(index, esym);
|
|
|
|
|
sym.esym_index = esym_idx;
|
|
|
|
|
|
|
|
|
|
return index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn addGlobalEsym(self: *ZigObject, allocator: Allocator) !Symbol.Index {
|
|
|
|
|
try self.global_esyms.ensureUnusedCapacity(allocator, 1);
|
|
|
|
|
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;
|
|
|
|
|
fn newLocalSymbol(self: *ZigObject, allocator: Allocator, name_off: u32) !Symbol.Index {
|
|
|
|
|
try self.local_symbols.ensureUnusedCapacity(allocator, 1);
|
|
|
|
|
const fake_index: Symbol.Index = @intCast(self.local_symbols.items.len);
|
|
|
|
|
const index = try self.newSymbol(allocator, name_off, elf.STB_LOCAL);
|
|
|
|
|
self.local_symbols.appendAssumeCapacity(index);
|
|
|
|
|
return fake_index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn newAtom(self: *ZigObject, elf_file: *Elf) !Symbol.Index {
|
|
|
|
|
const gpa = elf_file.base.comp.gpa;
|
|
|
|
|
const atom_index = try self.addAtom(gpa);
|
|
|
|
|
const symbol_index = try elf_file.addSymbol();
|
|
|
|
|
const esym_index = try self.addLocalEsym(gpa);
|
|
|
|
|
fn newGlobalSymbol(self: *ZigObject, allocator: Allocator, name_off: u32) !Symbol.Index {
|
|
|
|
|
try self.global_symbols.ensureUnusedCapacity(allocator, 1);
|
|
|
|
|
const fake_index: Symbol.Index = @intCast(self.global_symbols.items.len);
|
|
|
|
|
const index = try self.newSymbol(allocator, name_off, elf.STB_GLOBAL);
|
|
|
|
|
self.global_symbols.appendAssumeCapacity(index);
|
|
|
|
|
return fake_index | global_symbol_bit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try self.atoms_indexes.append(gpa, atom_index);
|
|
|
|
|
try self.local_symbols.append(gpa, symbol_index);
|
|
|
|
|
fn newAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Atom.Index {
|
|
|
|
|
try self.atoms.ensureUnusedCapacity(allocator, 1);
|
|
|
|
|
try self.atoms_extra.ensureUnusedCapacity(allocator, @sizeOf(Atom.Extra));
|
|
|
|
|
try self.atoms_indexes.ensureUnusedCapacity(allocator, 1);
|
|
|
|
|
try self.relocs.ensureUnusedCapacity(allocator, 1);
|
|
|
|
|
|
|
|
|
|
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(.{});
|
|
|
|
|
const index = self.addAtomAssumeCapacity();
|
|
|
|
|
self.atoms_indexes.appendAssumeCapacity(index);
|
|
|
|
|
const atom_ptr = self.atom(index).?;
|
|
|
|
|
atom_ptr.name_offset = name_off;
|
|
|
|
|
|
|
|
|
|
self.local_esyms.items(.shndx)[esym_index] = atom_index;
|
|
|
|
|
self.local_esyms.items(.elf_sym)[esym_index].st_shndx = SHN_ATOM;
|
|
|
|
|
symbol_ptr.esym_index = esym_index;
|
|
|
|
|
|
|
|
|
|
// TODO I'm thinking that maybe we shouldn' set this value unless it's actually needed?
|
|
|
|
|
const relocs_index = @as(u32, @intCast(self.relocs.items.len));
|
|
|
|
|
const relocs = try self.relocs.addOne(gpa);
|
|
|
|
|
relocs.* = .{};
|
|
|
|
|
|
|
|
|
|
const atom_ptr = self.atom(atom_index).?;
|
|
|
|
|
const relocs_index: u32 = @intCast(self.relocs.items.len);
|
|
|
|
|
self.relocs.addOneAssumeCapacity().* = .{};
|
|
|
|
|
atom_ptr.relocs_section_index = relocs_index;
|
|
|
|
|
|
|
|
|
|
return symbol_index;
|
|
|
|
|
return index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn newSymbolWithAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Symbol.Index {
|
|
|
|
|
const atom_index = try self.newAtom(allocator, name_off);
|
|
|
|
|
const sym_index = try self.newLocalSymbol(allocator, name_off);
|
|
|
|
|
const sym = self.symbol(sym_index);
|
|
|
|
|
sym.ref = .{ .index = atom_index, .file = self.index };
|
|
|
|
|
self.symtab.items(.shndx)[sym.esym_index] = atom_index;
|
|
|
|
|
self.symtab.items(.elf_sym)[sym.esym_index].st_shndx = SHN_ATOM;
|
|
|
|
|
return sym_index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// TODO actually create fake input shdrs and return that instead.
|
|
|
|
|
@@ -322,48 +348,47 @@ pub fn inputShdr(self: *ZigObject, atom_index: Atom.Index, elf_file: *Elf) elf.E
|
|
|
|
|
return shdr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn resolveSymbols(self: *ZigObject, elf_file: *Elf) void {
|
|
|
|
|
for (self.globals(), 0..) |index, 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;
|
|
|
|
|
pub fn resolveSymbols(self: *ZigObject, elf_file: *Elf) !void {
|
|
|
|
|
const gpa = elf_file.base.comp.gpa;
|
|
|
|
|
|
|
|
|
|
for (self.global_symbols.items, 0..) |index, i| {
|
|
|
|
|
const global = &self.symbols.items[index];
|
|
|
|
|
const esym = global.elfSym(elf_file);
|
|
|
|
|
const shndx = self.symtab.items(.shndx)[global.esym_index];
|
|
|
|
|
if (esym.st_shndx != elf.SHN_ABS and esym.st_shndx != elf.SHN_COMMON) {
|
|
|
|
|
assert(esym.st_shndx == SHN_ATOM);
|
|
|
|
|
const atom_ptr = self.atom(shndx) orelse continue;
|
|
|
|
|
if (!atom_ptr.alive) continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const global = elf_file.symbol(index);
|
|
|
|
|
if (self.asFile().symbolRank(esym, false) < global.symbolRank(elf_file)) {
|
|
|
|
|
const atom_index = switch (esym.st_shndx) {
|
|
|
|
|
elf.SHN_ABS, elf.SHN_COMMON => 0,
|
|
|
|
|
SHN_ATOM => shndx,
|
|
|
|
|
else => unreachable,
|
|
|
|
|
};
|
|
|
|
|
global.value = @intCast(esym.st_value);
|
|
|
|
|
global.ref = .{ .index = atom_index, .file = self.index };
|
|
|
|
|
global.esym_index = esym_index;
|
|
|
|
|
global.file_index = self.index;
|
|
|
|
|
global.version_index = elf_file.default_sym_version;
|
|
|
|
|
if (esym.st_bind() == elf.STB_WEAK) global.flags.weak = true;
|
|
|
|
|
const resolv = &self.symbols_resolver.items[i];
|
|
|
|
|
const gop = try elf_file.resolver.getOrPut(gpa, .{
|
|
|
|
|
.index = @intCast(i | global_symbol_bit),
|
|
|
|
|
.file = self.index,
|
|
|
|
|
}, elf_file);
|
|
|
|
|
if (!gop.found_existing) {
|
|
|
|
|
gop.ref.* = .{ .index = 0, .file = 0 };
|
|
|
|
|
}
|
|
|
|
|
resolv.* = gop.index;
|
|
|
|
|
|
|
|
|
|
if (esym.st_shndx == elf.SHN_UNDEF) continue;
|
|
|
|
|
if (elf_file.symbol(gop.ref.*) == null) {
|
|
|
|
|
gop.ref.* = .{ .index = @intCast(i | global_symbol_bit), .file = self.index };
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (self.asFile().symbolRank(esym, !self.alive) < elf_file.symbol(gop.ref.*).?.symbolRank(elf_file)) {
|
|
|
|
|
gop.ref.* = .{ .index = @intCast(i | global_symbol_bit), .file = self.index };
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn claimUnresolved(self: ZigObject, elf_file: *Elf) void {
|
|
|
|
|
for (self.globals(), 0..) |index, i| {
|
|
|
|
|
const esym_index = @as(Symbol.Index, @intCast(i)) | global_symbol_bit;
|
|
|
|
|
const esym = self.global_esyms.items(.elf_sym)[i];
|
|
|
|
|
|
|
|
|
|
pub fn claimUnresolved(self: *ZigObject, elf_file: *Elf) void {
|
|
|
|
|
for (self.global_symbols.items, 0..) |index, i| {
|
|
|
|
|
const global = &self.symbols.items[index];
|
|
|
|
|
const esym = self.symtab.items(.elf_sym)[index];
|
|
|
|
|
if (esym.st_shndx != elf.SHN_UNDEF) continue;
|
|
|
|
|
|
|
|
|
|
const global = elf_file.symbol(index);
|
|
|
|
|
if (global.file(elf_file)) |_| {
|
|
|
|
|
if (global.elfSym(elf_file).st_shndx != elf.SHN_UNDEF) continue;
|
|
|
|
|
}
|
|
|
|
|
if (elf_file.symbol(self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file)) != null) continue;
|
|
|
|
|
|
|
|
|
|
const is_import = blk: {
|
|
|
|
|
if (!elf_file.isEffectivelyDynLib()) break :blk false;
|
|
|
|
|
@@ -374,29 +399,36 @@ pub fn claimUnresolved(self: ZigObject, elf_file: *Elf) void {
|
|
|
|
|
|
|
|
|
|
global.value = 0;
|
|
|
|
|
global.ref = .{ .index = 0, .file = 0 };
|
|
|
|
|
global.esym_index = esym_index;
|
|
|
|
|
global.esym_index = @intCast(index);
|
|
|
|
|
global.file_index = self.index;
|
|
|
|
|
global.version_index = if (is_import) elf.VER_NDX_LOCAL else elf_file.default_sym_version;
|
|
|
|
|
global.flags.import = is_import;
|
|
|
|
|
|
|
|
|
|
const idx = self.symbols_resolver.items[i];
|
|
|
|
|
elf_file.resolver.values.items[idx - 1] = .{ .index = @intCast(i | global_symbol_bit), .file = self.index };
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn claimUnresolvedObject(self: ZigObject, elf_file: *Elf) void {
|
|
|
|
|
for (self.globals(), 0..) |index, i| {
|
|
|
|
|
const esym_index = @as(Symbol.Index, @intCast(i)) | global_symbol_bit;
|
|
|
|
|
const esym = self.global_esyms.items(.elf_sym)[i];
|
|
|
|
|
|
|
|
|
|
for (self.global_symbols.items, 0..) |index, i| {
|
|
|
|
|
const global = &self.symbols.items[index];
|
|
|
|
|
const esym = self.symtab.items(.elf_sym)[index];
|
|
|
|
|
if (esym.st_shndx != elf.SHN_UNDEF) continue;
|
|
|
|
|
if (elf_file.symbol(self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file)) != null) continue;
|
|
|
|
|
|
|
|
|
|
const global = elf_file.symbol(index);
|
|
|
|
|
if (global.file(elf_file)) |file| {
|
|
|
|
|
if (global.elfSym(elf_file).st_shndx != elf.SHN_UNDEF or file.index() <= self.index) continue;
|
|
|
|
|
}
|
|
|
|
|
// TODO: audit this
|
|
|
|
|
// const global = elf_file.symbol(index);
|
|
|
|
|
// if (global.file(elf_file)) |file| {
|
|
|
|
|
// if (global.elfSym(elf_file).st_shndx != elf.SHN_UNDEF or file.index() <= self.index) continue;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
global.value = 0;
|
|
|
|
|
global.ref = .{ .index = 0, .file = 0 };
|
|
|
|
|
global.esym_index = esym_index;
|
|
|
|
|
global.esym_index = @intCast(index);
|
|
|
|
|
global.file_index = self.index;
|
|
|
|
|
|
|
|
|
|
const idx = self.symbols_resolver.items[i];
|
|
|
|
|
elf_file.resolver.items[idx - 1] = .{ .index = @intCast(i | global_symbol_bit), .file = self.index };
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -419,12 +451,14 @@ pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn markLive(self: *ZigObject, elf_file: *Elf) void {
|
|
|
|
|
for (self.globals(), 0..) |index, i| {
|
|
|
|
|
const esym = self.global_esyms.items(.elf_sym)[i];
|
|
|
|
|
for (self.global_symbols.items, 0..) |index, i| {
|
|
|
|
|
const global = self.symbols.items[index];
|
|
|
|
|
const esym = self.symtab.items(.elf_sym)[index];
|
|
|
|
|
if (esym.st_bind() == elf.STB_WEAK) continue;
|
|
|
|
|
|
|
|
|
|
const global = elf_file.symbol(index);
|
|
|
|
|
const file = global.file(elf_file) orelse continue;
|
|
|
|
|
const ref = self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file);
|
|
|
|
|
const sym = elf_file.symbol(ref) orelse continue;
|
|
|
|
|
const file = sym.file(elf_file).?;
|
|
|
|
|
const should_keep = esym.st_shndx == elf.SHN_UNDEF or
|
|
|
|
|
(esym.st_shndx == elf.SHN_COMMON and global.elfSym(elf_file).st_shndx != elf.SHN_COMMON);
|
|
|
|
|
if (should_keep and !file.isAlive()) {
|
|
|
|
|
@@ -434,14 +468,36 @@ pub fn markLive(self: *ZigObject, elf_file: *Elf) void {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn checkDuplicates(self: *ZigObject, dupes: anytype, elf_file: *Elf) error{OutOfMemory}!void {
|
|
|
|
|
for (self.globals(), 0..) |index, i| {
|
|
|
|
|
const esym = self.global_esyms.items(.elf_sym)[i];
|
|
|
|
|
const shndx = self.global_esyms.items(.shndx)[i];
|
|
|
|
|
const global = elf_file.symbol(index);
|
|
|
|
|
const global_file = global.file(elf_file) orelse continue;
|
|
|
|
|
pub fn markImportsExports(self: *Object, elf_file: *Elf) void {
|
|
|
|
|
for (0..self.global_symbols.items.len) |i| {
|
|
|
|
|
const ref = self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file);
|
|
|
|
|
const sym = elf_file.symbol(ref) orelse continue;
|
|
|
|
|
const file = sym.file(elf_file).?;
|
|
|
|
|
if (sym.version_index == elf.VER_NDX_LOCAL) continue;
|
|
|
|
|
const vis = @as(elf.STV, @enumFromInt(sym.elfSym(elf_file).st_other));
|
|
|
|
|
if (vis == .HIDDEN) continue;
|
|
|
|
|
if (file == .shared_object and !sym.isAbs(elf_file)) {
|
|
|
|
|
sym.flags.import = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (file.index() == self.index) {
|
|
|
|
|
sym.flags.@"export" = true;
|
|
|
|
|
if (elf_file.isEffectivelyDynLib() and vis != .PROTECTED) {
|
|
|
|
|
sym.flags.import = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (self.index == global_file.index() or
|
|
|
|
|
pub fn checkDuplicates(self: *ZigObject, dupes: anytype, elf_file: *Elf) error{OutOfMemory}!void {
|
|
|
|
|
for (self.global_symbols.items, 0..) |index, i| {
|
|
|
|
|
const esym = self.symtab.items(.elf_sym)[index];
|
|
|
|
|
const shndx = self.symtab.items(.shndx)[index];
|
|
|
|
|
const ref = self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file);
|
|
|
|
|
const ref_sym = elf_file.symbol(ref) orelse continue;
|
|
|
|
|
const ref_file = ref_sym.file(elf_file).?;
|
|
|
|
|
|
|
|
|
|
if (self.index == ref_file.index() or
|
|
|
|
|
esym.st_shndx == elf.SHN_UNDEF or
|
|
|
|
|
esym.st_bind() == elf.STB_WEAK or
|
|
|
|
|
esym.st_shndx == elf.SHN_COMMON) continue;
|
|
|
|
|
@@ -451,7 +507,7 @@ pub fn checkDuplicates(self: *ZigObject, dupes: anytype, elf_file: *Elf) error{O
|
|
|
|
|
if (!atom_ptr.alive) continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const gop = try dupes.getOrPut(index);
|
|
|
|
|
const gop = try dupes.getOrPut(self.symbols_resolver.items[i]);
|
|
|
|
|
if (!gop.found_existing) {
|
|
|
|
|
gop.value_ptr.* = .{};
|
|
|
|
|
}
|
|
|
|
|
@@ -483,12 +539,13 @@ pub fn readFileContents(self: *ZigObject, elf_file: *Elf) !void {
|
|
|
|
|
pub fn updateArSymtab(self: ZigObject, ar_symtab: *Archive.ArSymtab, elf_file: *Elf) error{OutOfMemory}!void {
|
|
|
|
|
const gpa = elf_file.base.comp.gpa;
|
|
|
|
|
|
|
|
|
|
try ar_symtab.symtab.ensureUnusedCapacity(gpa, self.globals().len);
|
|
|
|
|
try ar_symtab.symtab.ensureUnusedCapacity(gpa, self.global_symbols.items.len);
|
|
|
|
|
|
|
|
|
|
for (self.globals()) |global_index| {
|
|
|
|
|
const global = elf_file.symbol(global_index);
|
|
|
|
|
const file_ptr = global.file(elf_file).?;
|
|
|
|
|
assert(file_ptr.index() == self.index);
|
|
|
|
|
for (self.global_symbols.items, 0..) |index, i| {
|
|
|
|
|
const global = self.symbols.items[index];
|
|
|
|
|
const ref = self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file);
|
|
|
|
|
const sym = elf_file.symbol(ref).?;
|
|
|
|
|
assert(sym.file(elf_file).?.index() == self.index);
|
|
|
|
|
if (global.outputShndx(elf_file) == null) continue;
|
|
|
|
|
|
|
|
|
|
const off = try ar_symtab.strtab.insert(gpa, global.name(elf_file));
|
|
|
|
|
@@ -530,33 +587,9 @@ pub fn addAtomsToRelaSections(self: *ZigObject, elf_file: *Elf) !void {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline fn isGlobal(index: Symbol.Index) bool {
|
|
|
|
|
return index & global_symbol_bit != 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn symbol(self: ZigObject, index: Symbol.Index) Symbol.Index {
|
|
|
|
|
const actual_index = index & symbol_mask;
|
|
|
|
|
if (isGlobal(index)) return self.globals()[actual_index];
|
|
|
|
|
return self.locals()[actual_index];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn elfSym(self: *ZigObject, index: Symbol.Index) *elf.Elf64_Sym {
|
|
|
|
|
const actual_index = index & symbol_mask;
|
|
|
|
|
if (isGlobal(index)) return &self.global_esyms.items(.elf_sym)[actual_index];
|
|
|
|
|
return &self.local_esyms.items(.elf_sym)[actual_index];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn locals(self: ZigObject) []const Symbol.Index {
|
|
|
|
|
return self.local_symbols.items;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn globals(self: ZigObject) []const Symbol.Index {
|
|
|
|
|
return self.global_symbols.items;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn updateSymtabSize(self: *ZigObject, elf_file: *Elf) !void {
|
|
|
|
|
for (self.locals()) |local_index| {
|
|
|
|
|
const local = elf_file.symbol(local_index);
|
|
|
|
|
for (self.local_symbols.items) |index| {
|
|
|
|
|
const local = &self.symbols.items[index];
|
|
|
|
|
if (local.atom(elf_file)) |atom_ptr| if (!atom_ptr.alive) continue;
|
|
|
|
|
const esym = local.elfSym(elf_file);
|
|
|
|
|
switch (esym.st_type()) {
|
|
|
|
|
@@ -564,22 +597,23 @@ pub fn updateSymtabSize(self: *ZigObject, elf_file: *Elf) !void {
|
|
|
|
|
else => {},
|
|
|
|
|
}
|
|
|
|
|
local.flags.output_symtab = true;
|
|
|
|
|
try local.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, elf_file);
|
|
|
|
|
local.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, elf_file);
|
|
|
|
|
self.output_symtab_ctx.nlocals += 1;
|
|
|
|
|
self.output_symtab_ctx.strsize += @as(u32, @intCast(local.name(elf_file).len)) + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (self.globals()) |global_index| {
|
|
|
|
|
const global = elf_file.symbol(global_index);
|
|
|
|
|
const file_ptr = global.file(elf_file) orelse continue;
|
|
|
|
|
if (file_ptr.index() != self.index) continue;
|
|
|
|
|
for (self.global_symbols.items, self.symbols_resolver.items) |index, resolv| {
|
|
|
|
|
const global = &self.symbols.items[index];
|
|
|
|
|
const ref = elf_file.resolver.items[resolv];
|
|
|
|
|
const ref_sym = elf_file.symbol(ref) orelse continue;
|
|
|
|
|
if (ref_sym.file(elf_file).?.index() != self.index) continue;
|
|
|
|
|
if (global.atom(elf_file)) |atom_ptr| if (!atom_ptr.alive) continue;
|
|
|
|
|
global.flags.output_symtab = true;
|
|
|
|
|
if (global.isLocal(elf_file)) {
|
|
|
|
|
try global.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, elf_file);
|
|
|
|
|
global.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, elf_file);
|
|
|
|
|
self.output_symtab_ctx.nlocals += 1;
|
|
|
|
|
} else {
|
|
|
|
|
try global.addExtra(.{ .symtab = self.output_symtab_ctx.nglobals }, elf_file);
|
|
|
|
|
global.addExtra(.{ .symtab = self.output_symtab_ctx.nglobals }, elf_file);
|
|
|
|
|
self.output_symtab_ctx.nglobals += 1;
|
|
|
|
|
}
|
|
|
|
|
self.output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1;
|
|
|
|
|
@@ -587,8 +621,8 @@ pub fn updateSymtabSize(self: *ZigObject, elf_file: *Elf) !void {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void {
|
|
|
|
|
for (self.locals()) |local_index| {
|
|
|
|
|
const local = elf_file.symbol(local_index);
|
|
|
|
|
for (self.local_symbols.items) |index| {
|
|
|
|
|
const local = &self.symbols.items[index];
|
|
|
|
|
const idx = local.outputSymtabIndex(elf_file) orelse continue;
|
|
|
|
|
const out_sym = &elf_file.symtab.items[idx];
|
|
|
|
|
out_sym.st_name = @intCast(elf_file.strtab.items.len);
|
|
|
|
|
@@ -597,10 +631,11 @@ pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void {
|
|
|
|
|
local.setOutputSym(elf_file, out_sym);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (self.globals()) |global_index| {
|
|
|
|
|
const global = elf_file.symbol(global_index);
|
|
|
|
|
const file_ptr = global.file(elf_file) orelse continue;
|
|
|
|
|
if (file_ptr.index() != self.index) continue;
|
|
|
|
|
for (self.global_symbols.items, self.symbols_resolver.items) |index, resolv| {
|
|
|
|
|
const global = self.symbols.items[index];
|
|
|
|
|
const ref = elf_file.resolver.items[resolv];
|
|
|
|
|
const ref_sym = elf_file.symbol(ref) orelse continue;
|
|
|
|
|
if (ref_sym.file(elf_file).?.index() != self.index) continue;
|
|
|
|
|
const idx = global.outputSymtabIndex(elf_file) orelse continue;
|
|
|
|
|
const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
|
|
|
|
|
elf_file.strtab.appendSliceAssumeCapacity(global.name(elf_file));
|
|
|
|
|
@@ -611,10 +646,6 @@ pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn asFile(self: *ZigObject) File {
|
|
|
|
|
return .{ .zig_object = self };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns atom's code.
|
|
|
|
|
/// Caller owns the memory.
|
|
|
|
|
pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8 {
|
|
|
|
|
@@ -755,8 +786,8 @@ pub fn getOrCreateMetadataForLazySymbol(
|
|
|
|
|
};
|
|
|
|
|
switch (metadata.state.*) {
|
|
|
|
|
.unused => {
|
|
|
|
|
const symbol_index = try self.newAtom(elf_file);
|
|
|
|
|
const sym = elf_file.symbol(symbol_index);
|
|
|
|
|
const symbol_index = try self.newSymbolWithAtom(gpa, 0);
|
|
|
|
|
const sym = self.symbol(symbol_index);
|
|
|
|
|
sym.flags.needs_zig_got = true;
|
|
|
|
|
metadata.symbol_index.* = symbol_index;
|
|
|
|
|
},
|
|
|
|
|
@@ -817,10 +848,10 @@ pub fn getOrCreateMetadataForDecl(
|
|
|
|
|
const gop = try self.decls.getOrPut(gpa, decl_index);
|
|
|
|
|
if (!gop.found_existing) {
|
|
|
|
|
const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded;
|
|
|
|
|
const symbol_index = try self.newAtom(elf_file);
|
|
|
|
|
const symbol_index = try self.newSymbolWithAtom(gpa, 0);
|
|
|
|
|
const mod = elf_file.base.comp.module.?;
|
|
|
|
|
const decl = mod.declPtr(decl_index);
|
|
|
|
|
const sym = elf_file.symbol(symbol_index);
|
|
|
|
|
const sym = self.symbol(symbol_index);
|
|
|
|
|
if (decl.getOwnedVariable(mod)) |variable| {
|
|
|
|
|
if (variable.is_threadlocal and any_non_single_threaded) {
|
|
|
|
|
sym.flags.is_tls = true;
|
|
|
|
|
@@ -1064,7 +1095,7 @@ pub fn updateFunc(
|
|
|
|
|
|
|
|
|
|
const sym_index = try self.getOrCreateMetadataForDecl(elf_file, decl_index);
|
|
|
|
|
self.freeUnnamedConsts(elf_file, decl_index);
|
|
|
|
|
elf_file.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file);
|
|
|
|
|
self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file);
|
|
|
|
|
|
|
|
|
|
var code_buffer = std.ArrayList(u8).init(gpa);
|
|
|
|
|
defer code_buffer.deinit();
|
|
|
|
|
@@ -1096,7 +1127,7 @@ pub fn updateFunc(
|
|
|
|
|
try self.updateDeclCode(elf_file, pt, decl_index, sym_index, shndx, code, elf.STT_FUNC);
|
|
|
|
|
|
|
|
|
|
if (decl_state) |*ds| {
|
|
|
|
|
const sym = elf_file.symbol(sym_index);
|
|
|
|
|
const sym = self.symbol(sym_index);
|
|
|
|
|
try self.dwarf.?.commitDeclState(
|
|
|
|
|
pt,
|
|
|
|
|
decl_index,
|
|
|
|
|
@@ -1130,13 +1161,13 @@ pub fn updateDecl(
|
|
|
|
|
const variable = decl.getOwnedVariable(mod).?;
|
|
|
|
|
const name = decl.name.toSlice(&mod.intern_pool);
|
|
|
|
|
const lib_name = variable.lib_name.toSlice(&mod.intern_pool);
|
|
|
|
|
const esym_index = try self.getGlobalSymbol(elf_file, name, lib_name);
|
|
|
|
|
elf_file.symbol(self.symbol(esym_index)).flags.needs_got = true;
|
|
|
|
|
const sym_index = try self.getGlobalSymbol(elf_file, name, lib_name);
|
|
|
|
|
self.symbol(sym_index).flags.needs_got = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const sym_index = try self.getOrCreateMetadataForDecl(elf_file, decl_index);
|
|
|
|
|
elf_file.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file);
|
|
|
|
|
self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file);
|
|
|
|
|
|
|
|
|
|
const gpa = elf_file.base.comp.gpa;
|
|
|
|
|
var code_buffer = std.ArrayList(u8).init(gpa);
|
|
|
|
|
@@ -1174,7 +1205,7 @@ pub fn updateDecl(
|
|
|
|
|
try self.updateDeclCode(elf_file, pt, decl_index, sym_index, shndx, code, elf.STT_OBJECT);
|
|
|
|
|
|
|
|
|
|
if (decl_state) |*ds| {
|
|
|
|
|
const sym = elf_file.symbol(sym_index);
|
|
|
|
|
const sym = self.symbol(sym_index);
|
|
|
|
|
try self.dwarf.?.commitDeclState(
|
|
|
|
|
pt,
|
|
|
|
|
decl_index,
|
|
|
|
|
@@ -1323,7 +1354,8 @@ fn lowerConst(
|
|
|
|
|
var code_buffer = std.ArrayList(u8).init(gpa);
|
|
|
|
|
defer code_buffer.deinit();
|
|
|
|
|
|
|
|
|
|
const sym_index = try self.newAtom(elf_file);
|
|
|
|
|
const name_off = try self.addString(gpa, name);
|
|
|
|
|
const sym_index = try self.newSymbolWithAtom(gpa, name_off);
|
|
|
|
|
|
|
|
|
|
const res = try codegen.generateSymbol(
|
|
|
|
|
&elf_file.base,
|
|
|
|
|
@@ -1339,27 +1371,19 @@ fn lowerConst(
|
|
|
|
|
.fail => |em| return .{ .fail = em },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const local_sym = elf_file.symbol(sym_index);
|
|
|
|
|
const name_str_index = try self.strtab.insert(gpa, name);
|
|
|
|
|
local_sym.name_offset = name_str_index;
|
|
|
|
|
const local_esym = &self.local_esyms.items(.elf_sym)[local_sym.esym_index];
|
|
|
|
|
local_esym.st_name = name_str_index;
|
|
|
|
|
const local_sym = self.symbol(sym_index);
|
|
|
|
|
const local_esym = local_sym.elfSym(elf_file);
|
|
|
|
|
local_esym.st_info |= elf.STT_OBJECT;
|
|
|
|
|
local_esym.st_size = code.len;
|
|
|
|
|
const atom_ptr = local_sym.atom(elf_file).?;
|
|
|
|
|
atom_ptr.alive = true;
|
|
|
|
|
atom_ptr.name_offset = name_str_index;
|
|
|
|
|
atom_ptr.alignment = required_alignment;
|
|
|
|
|
atom_ptr.size = code.len;
|
|
|
|
|
atom_ptr.output_section_index = output_section_index;
|
|
|
|
|
|
|
|
|
|
try atom_ptr.allocate(elf_file);
|
|
|
|
|
// TODO rename and re-audit this method
|
|
|
|
|
errdefer self.freeDeclMetadata(elf_file, sym_index);
|
|
|
|
|
|
|
|
|
|
local_sym.value = 0;
|
|
|
|
|
local_esym.st_value = 0;
|
|
|
|
|
|
|
|
|
|
const shdr = elf_file.shdrs.items[output_section_index];
|
|
|
|
|
const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
|
|
|
|
|
try elf_file.base.file.?.pwriteAll(code, file_offset);
|
|
|
|
|
@@ -1401,9 +1425,9 @@ pub fn updateExports(
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
const sym_index = metadata.symbol_index;
|
|
|
|
|
const esym_index = elf_file.symbol(sym_index).esym_index;
|
|
|
|
|
const esym = self.local_esyms.items(.elf_sym)[esym_index];
|
|
|
|
|
const esym_shndx = self.local_esyms.items(.shndx)[esym_index];
|
|
|
|
|
const esym_index = self.symbol(sym_index).esym_index;
|
|
|
|
|
const esym = self.symtab.items(.elf_sym)[esym_index];
|
|
|
|
|
const esym_shndx = self.symtab.items(.shndx)[esym_index];
|
|
|
|
|
|
|
|
|
|
for (export_indices) |export_idx| {
|
|
|
|
|
const exp = mod.all_exports.items[export_idx];
|
|
|
|
|
@@ -1437,22 +1461,27 @@ pub fn updateExports(
|
|
|
|
|
const stt_bits: u8 = @as(u4, @truncate(esym.st_info));
|
|
|
|
|
const exp_name = exp.opts.name.toSlice(&mod.intern_pool);
|
|
|
|
|
const name_off = try self.strtab.insert(gpa, exp_name);
|
|
|
|
|
const global_esym_index = if (metadata.@"export"(self, exp_name)) |exp_index|
|
|
|
|
|
const global_sym_index = if (metadata.@"export"(self, exp_name)) |exp_index|
|
|
|
|
|
exp_index.*
|
|
|
|
|
else blk: {
|
|
|
|
|
const global_esym_index = try self.getGlobalSymbol(elf_file, exp_name, null);
|
|
|
|
|
try metadata.exports.append(gpa, global_esym_index);
|
|
|
|
|
break :blk global_esym_index;
|
|
|
|
|
const global_sym_index = try self.getGlobalSymbol(elf_file, exp_name, null);
|
|
|
|
|
try metadata.exports.append(gpa, global_sym_index);
|
|
|
|
|
break :blk global_sym_index;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const actual_esym_index = global_esym_index & symbol_mask;
|
|
|
|
|
const global_esym = &self.global_esyms.items(.elf_sym)[actual_esym_index];
|
|
|
|
|
global_esym.st_value = @intCast(elf_file.symbol(sym_index).value);
|
|
|
|
|
const value = self.symbol(sym_index).value;
|
|
|
|
|
const global_sym = self.symbol(global_sym_index);
|
|
|
|
|
global_sym.value = value;
|
|
|
|
|
global_sym.flags.weak = exp.opts.linkage == .weak;
|
|
|
|
|
global_sym.version_index = elf_file.default_version_index;
|
|
|
|
|
global_sym.ref = .{ .index = esym_shndx, .file = self.index };
|
|
|
|
|
const global_esym = global_sym.elfSym(elf_file);
|
|
|
|
|
global_esym.st_value = @intCast(value);
|
|
|
|
|
global_esym.st_shndx = esym.st_shndx;
|
|
|
|
|
global_esym.st_info = (stb_bits << 4) | stt_bits;
|
|
|
|
|
global_esym.st_name = name_off;
|
|
|
|
|
global_esym.st_size = esym.st_size;
|
|
|
|
|
self.global_esyms.items(.shndx)[actual_esym_index] = esym_shndx;
|
|
|
|
|
self.symtab.items(.shndx)[global_sym.esym_index] = esym_shndx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1506,16 +1535,19 @@ pub fn getGlobalSymbol(self: *ZigObject, elf_file: *Elf, name: []const u8, lib_n
|
|
|
|
|
const off = try self.strtab.insert(gpa, name);
|
|
|
|
|
const lookup_gop = try self.globals_lookup.getOrPut(gpa, off);
|
|
|
|
|
if (!lookup_gop.found_existing) {
|
|
|
|
|
const esym_index = try self.addGlobalEsym(gpa);
|
|
|
|
|
const esym = self.elfSym(esym_index);
|
|
|
|
|
esym.st_name = off;
|
|
|
|
|
lookup_gop.value_ptr.* = esym_index;
|
|
|
|
|
const gop = try elf_file.getOrPutGlobal(name);
|
|
|
|
|
try self.global_symbols.append(gpa, gop.index);
|
|
|
|
|
lookup_gop.value_ptr.* = try self.newSymbol(gpa, off);
|
|
|
|
|
}
|
|
|
|
|
return lookup_gop.value_ptr.*;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn asFile(self: *ZigObject) File {
|
|
|
|
|
return .{ .zig_object = self };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn addString(self: *ZigObject, allocator: Allocator, string: []const u8) !u32 {
|
|
|
|
|
return self.strtab.insert(allocator, string);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn getString(self: ZigObject, off: u32) [:0]const u8 {
|
|
|
|
|
return self.strtab.getAssumeExists(off);
|
|
|
|
|
}
|
|
|
|
|
@@ -1586,6 +1618,73 @@ pub fn setAtomExtra(self: *ZigObject, index: u32, extra: Atom.Extra) void {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline fn isGlobal(index: Symbol.Index) bool {
|
|
|
|
|
return index & global_symbol_bit != 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn symbol(self: *ZigObject, index: Symbol.Index) *Symbol {
|
|
|
|
|
const actual_index = index & symbol_mask;
|
|
|
|
|
if (isGlobal(index)) return &self.symbols.items[self.global_symbols.items[actual_index]];
|
|
|
|
|
return &self.symbols.items[self.local_symbols.items[actual_index]];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn resolveSymbol(self: ZigObject, index: Symbol.Index, elf_file: *Elf) Elf.Ref {
|
|
|
|
|
if (isGlobal(index)) {
|
|
|
|
|
const resolv = self.symbols_resolver.items[index & symbol_mask];
|
|
|
|
|
return elf_file.resolver.get(resolv).?;
|
|
|
|
|
}
|
|
|
|
|
return .{ .index = index, .file = self.index };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn addSymbol(self: *ZigObject, allocator: Allocator) !Symbol.Index {
|
|
|
|
|
try self.symbols.ensureUnusedCapacity(allocator, 1);
|
|
|
|
|
const index: Symbol.Index = @intCast(self.symbols.items.len);
|
|
|
|
|
self.symbols.appendAssumeCapacity(.{ .file_index = self.index });
|
|
|
|
|
return index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn addSymbolExtra(self: *ZigObject, allocator: Allocator, extra: Symbol.Extra) !u32 {
|
|
|
|
|
const fields = @typeInfo(Symbol.Extra).Struct.fields;
|
|
|
|
|
try self.symbols_extra.ensureUnusedCapacity(allocator, fields.len);
|
|
|
|
|
return self.addSymbolExtraAssumeCapacity(extra);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn addSymbolExtraAssumeCapacity(self: *ZigObject, extra: Symbol.Extra) u32 {
|
|
|
|
|
const index = @as(u32, @intCast(self.symbols_extra.items.len));
|
|
|
|
|
const fields = @typeInfo(Symbol.Extra).Struct.fields;
|
|
|
|
|
inline for (fields) |field| {
|
|
|
|
|
self.symbols_extra.appendAssumeCapacity(switch (field.type) {
|
|
|
|
|
u32 => @field(extra, field.name),
|
|
|
|
|
else => @compileError("bad field type"),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn symbolExtra(self: *ZigObject, index: u32) Symbol.Extra {
|
|
|
|
|
const fields = @typeInfo(Symbol.Extra).Struct.fields;
|
|
|
|
|
var i: usize = index;
|
|
|
|
|
var result: Symbol.Extra = undefined;
|
|
|
|
|
inline for (fields) |field| {
|
|
|
|
|
@field(result, field.name) = switch (field.type) {
|
|
|
|
|
u32 => self.symbols_extra.items[i],
|
|
|
|
|
else => @compileError("bad field type"),
|
|
|
|
|
};
|
|
|
|
|
i += 1;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn setSymbolExtra(self: *ZigObject, index: u32, extra: Symbol.Extra) void {
|
|
|
|
|
const fields = @typeInfo(Symbol.Extra).Struct.fields;
|
|
|
|
|
inline for (fields, 0..) |field, i| {
|
|
|
|
|
self.symbols_extra.items[index + i] = switch (field.type) {
|
|
|
|
|
u32 => @field(extra, field.name),
|
|
|
|
|
else => @compileError("bad field type"),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn fmtSymtab(self: *ZigObject, elf_file: *Elf) std.fmt.Formatter(formatSymtab) {
|
|
|
|
|
return .{ .data = .{
|
|
|
|
|
.self = self,
|
|
|
|
|
@@ -1658,9 +1757,9 @@ const DeclMetadata = struct {
|
|
|
|
|
/// A list of all exports aliases of this Decl.
|
|
|
|
|
exports: std.ArrayListUnmanaged(Symbol.Index) = .{},
|
|
|
|
|
|
|
|
|
|
fn @"export"(m: DeclMetadata, zig_object: *ZigObject, name: []const u8) ?*u32 {
|
|
|
|
|
fn @"export"(m: DeclMetadata, zo: *ZigObject, name: []const u8) ?*u32 {
|
|
|
|
|
for (m.exports.items) |*exp| {
|
|
|
|
|
const exp_name = zig_object.getString(zig_object.elfSym(exp.*).st_name);
|
|
|
|
|
const exp_name = zo.getString(zo.symbol(exp.*).name_off);
|
|
|
|
|
if (mem.eql(u8, name, exp_name)) return exp;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
|