mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
elf: add simplistic symbol resolution
This commit is contained in:
parent
53c3757c00
commit
962b46148d
@ -1045,6 +1045,9 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
|
||||
try self.addLinkerDefinedSymbols();
|
||||
|
||||
// Resolve symbols
|
||||
self.resolveSymbols();
|
||||
|
||||
if (self.unresolved.keys().len > 0) try self.reportUndefined();
|
||||
|
||||
self.allocateLinkerDefinedSymbols();
|
||||
@ -1321,6 +1324,18 @@ fn parseObject(self: *Elf, in_file: std.fs.File, path: []const u8, ctx: *ParseEr
|
||||
if (ctx.detected_cpu_arch != self.base.options.target.cpu.arch) return error.InvalidCpuArch;
|
||||
}
|
||||
|
||||
fn resolveSymbols(self: *Elf) void {
|
||||
if (self.zig_module_index) |index| {
|
||||
const zig_module = self.file(index).?.zig_module;
|
||||
zig_module.resolveSymbols(self);
|
||||
}
|
||||
|
||||
for (self.objects.items) |index| {
|
||||
const object = self.file(index).?.object;
|
||||
object.resolveSymbols(self);
|
||||
}
|
||||
}
|
||||
|
||||
fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
@ -2697,7 +2712,7 @@ pub fn updateDeclExports(
|
||||
const name_off = try self.strtab.insert(gpa, exp_name);
|
||||
const esym = &zig_module.global_esyms.items[sym_index];
|
||||
esym.st_value = decl_sym.value;
|
||||
esym.st_shndx = decl_sym.output_section_index;
|
||||
esym.st_shndx = decl_sym.atom_index;
|
||||
esym.st_info = (stb_bits << 4) | stt_bits;
|
||||
esym.st_name = name_off;
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ alignment: u8 = 0,
|
||||
input_section_index: Index = 0,
|
||||
|
||||
/// Index of the output section.
|
||||
output_section_index: u16 = 0,
|
||||
output_section_index: Index = 0,
|
||||
|
||||
/// Index of the input section containing this atom's relocs.
|
||||
relocs_section_index: Index = 0,
|
||||
@ -484,7 +484,7 @@ fn format2(
|
||||
}
|
||||
}
|
||||
|
||||
pub const Index = u32;
|
||||
pub const Index = u16;
|
||||
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
@ -245,10 +245,6 @@ fn initSymtab(self: *Object, elf_file: *Elf) !void {
|
||||
const off = try elf_file.strtab.insert(gpa, name);
|
||||
const gop = try elf_file.getOrPutGlobal(off);
|
||||
self.symbols.addOneAssumeCapacity().* = gop.index;
|
||||
|
||||
if (sym.st_shndx == elf.SHN_UNDEF) {
|
||||
try elf_file.unresolved.put(gpa, gop.index, {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -388,34 +384,29 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf) !void {
|
||||
pub fn resolveSymbols(self: *Object, elf_file: *Elf) void {
|
||||
const first_global = self.first_global orelse return;
|
||||
for (self.globals(), 0..) |index, i| {
|
||||
const sym_idx = @as(u32, @intCast(first_global + i));
|
||||
const this_sym = self.symtab[sym_idx];
|
||||
const esym_index = @as(Symbol.Index, @intCast(first_global + i));
|
||||
const esym = self.symtab[esym_index];
|
||||
|
||||
if (this_sym.st_shndx == elf.SHN_UNDEF) continue;
|
||||
if (esym.st_shndx == elf.SHN_UNDEF) continue;
|
||||
|
||||
if (this_sym.st_shndx != elf.SHN_ABS and this_sym.st_shndx != elf.SHN_COMMON) {
|
||||
const atom_index = self.atoms.items[this_sym.st_shndx];
|
||||
if (esym.st_shndx != elf.SHN_ABS and esym.st_shndx != elf.SHN_COMMON) {
|
||||
const atom_index = self.atoms.items[esym.st_shndx];
|
||||
const atom = elf_file.atom(atom_index) orelse continue;
|
||||
if (!atom.alive) continue;
|
||||
}
|
||||
|
||||
_ = elf_file.unresolved.swapRemove(index);
|
||||
|
||||
const global = elf_file.symbol(index);
|
||||
if (self.asFile().symbolRank(this_sym, !self.alive) < global.symbolRank(elf_file)) {
|
||||
const atom = switch (this_sym.st_shndx) {
|
||||
if (self.asFile().symbolRank(esym, !self.alive) < global.symbolRank(elf_file)) {
|
||||
const atom_index = switch (esym.st_shndx) {
|
||||
elf.SHN_ABS, elf.SHN_COMMON => 0,
|
||||
else => self.atoms.items[this_sym.st_shndx],
|
||||
else => self.atoms.items[esym.st_shndx],
|
||||
};
|
||||
global.* = .{
|
||||
.value = this_sym.st_value,
|
||||
.name = global.name,
|
||||
.atom = atom,
|
||||
.sym_idx = sym_idx,
|
||||
.file = self.index,
|
||||
.ver_idx = elf_file.default_sym_version,
|
||||
};
|
||||
if (this_sym.st_bind() == elf.STB_WEAK) global.flags.weak = true;
|
||||
global.value = esym.st_value;
|
||||
global.atom_index = atom_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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,9 +70,10 @@ pub fn sourceSymbol(symbol: Symbol, elf_file: *Elf) elf.Elf64_Sym {
|
||||
const file_ptr = symbol.file(elf_file).?;
|
||||
switch (file_ptr) {
|
||||
.zig_module => |x| {
|
||||
const is_global = x.globals_lookup.contains(symbol.name_offset);
|
||||
if (is_global) return x.global_esyms.items[symbol.esym_index];
|
||||
return x.local_esyms.items[symbol.esym_index];
|
||||
const is_global = symbol.esym_index & 0x10000000 != 0;
|
||||
const esym_index = symbol.esym_index & 0x0fffffff;
|
||||
if (is_global) return x.global_esyms.items[esym_index];
|
||||
return x.local_esyms.items[esym_index];
|
||||
},
|
||||
.linker_defined => |x| return x.symtab.items[symbol.esym_index],
|
||||
.object => |x| return x.symtab[symbol.esym_index],
|
||||
|
||||
@ -62,7 +62,7 @@ pub fn addAtom(self: *ZigModule, output_section_index: u16, elf_file: *Elf) !Sym
|
||||
|
||||
const esym_index = try self.addLocalEsym(gpa);
|
||||
const esym = &self.local_esyms.items[esym_index];
|
||||
esym.st_shndx = output_section_index;
|
||||
esym.st_shndx = atom_index;
|
||||
symbol_ptr.esym_index = esym_index;
|
||||
|
||||
const relocs_index = @as(Atom.Index, @intCast(self.relocs.items.len));
|
||||
@ -74,9 +74,32 @@ pub fn addAtom(self: *ZigModule, output_section_index: u16, elf_file: *Elf) !Sym
|
||||
}
|
||||
|
||||
pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void {
|
||||
_ = self;
|
||||
_ = elf_file;
|
||||
@panic("TODO");
|
||||
for (self.globals(), 0..) |index, i| {
|
||||
const esym_index = @as(Symbol.Index, @intCast(i)) | 0x10000000;
|
||||
const esym = self.global_esyms.items[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.keys()[esym.st_shndx];
|
||||
const atom = elf_file.atom(atom_index) orelse continue;
|
||||
if (!atom.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,
|
||||
else => self.atoms.keys()[esym.st_shndx],
|
||||
};
|
||||
global.value = esym.st_value;
|
||||
global.atom_index = atom_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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn updateSymtabSize(self: *ZigModule, elf_file: *Elf) void {
|
||||
|
||||
@ -30,18 +30,6 @@ pub const File = union(enum) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolveSymbols(file: File, elf_file: *Elf) void {
|
||||
switch (file) {
|
||||
inline else => |x| x.resolveSymbols(elf_file),
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn resetGlobals(file: File, elf_file: *Elf) void {
|
||||
// switch (file) {
|
||||
// inline else => |x| x.resetGlobals(elf_file),
|
||||
// }
|
||||
// }
|
||||
|
||||
pub fn isAlive(file: File) bool {
|
||||
return switch (file) {
|
||||
.zig_module => true,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user