mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
elf: claim unresolved dangling symbols that can be claimed
This commit is contained in:
parent
b478a0dd1a
commit
c654f3b0ee
@ -1048,6 +1048,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
// Resolve symbols
|
||||
self.resolveSymbols();
|
||||
self.markImportsExports();
|
||||
self.claimUnresolved();
|
||||
|
||||
if (self.unresolved.keys().len > 0) try self.reportUndefined();
|
||||
|
||||
@ -1338,48 +1339,45 @@ fn resolveSymbols(self: *Elf) void {
|
||||
}
|
||||
|
||||
fn markImportsExports(self: *Elf) void {
|
||||
const is_dyn_lib = self.base.options.output_mode == .Lib and self.base.options.link_mode == .Dynamic;
|
||||
|
||||
if (self.zig_module_index) |index| {
|
||||
const zig_module = self.file(index).?.zig_module;
|
||||
for (zig_module.globals()) |global_index| {
|
||||
const global = self.symbol(global_index);
|
||||
if (global.version_index == elf.VER_NDX_LOCAL) continue;
|
||||
const file_ptr = global.file(self) orelse continue;
|
||||
const vis = @as(elf.STV, @enumFromInt(global.elfSym(self).st_other));
|
||||
if (vis == .HIDDEN) continue;
|
||||
// if (file == .shared and !global.isAbs(self)) {
|
||||
// global.flags.import = true;
|
||||
// continue;
|
||||
// }
|
||||
if (file_ptr.index() == index) {
|
||||
global.flags.@"export" = true;
|
||||
if (is_dyn_lib and vis != .PROTECTED) {
|
||||
global.flags.import = true;
|
||||
const mark = struct {
|
||||
fn mark(elf_file: *Elf, file_index: File.Index) void {
|
||||
for (elf_file.file(file_index).?.globals()) |global_index| {
|
||||
const global = elf_file.symbol(global_index);
|
||||
if (global.version_index == elf.VER_NDX_LOCAL) continue;
|
||||
const file_ptr = global.file(elf_file) orelse continue;
|
||||
const vis = @as(elf.STV, @enumFromInt(global.elfSym(elf_file).st_other));
|
||||
if (vis == .HIDDEN) continue;
|
||||
// if (file == .shared and !global.isAbs(self)) {
|
||||
// global.flags.import = true;
|
||||
// continue;
|
||||
// }
|
||||
if (file_ptr.index() == file_index) {
|
||||
global.flags.@"export" = true;
|
||||
if (elf_file.isDynLib() and vis != .PROTECTED) {
|
||||
global.flags.import = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.mark;
|
||||
|
||||
if (self.zig_module_index) |index| {
|
||||
mark(self, index);
|
||||
}
|
||||
|
||||
for (self.objects.items) |index| {
|
||||
mark(self, index);
|
||||
}
|
||||
}
|
||||
|
||||
fn claimUnresolved(self: *Elf) void {
|
||||
if (self.zig_module_index) |index| {
|
||||
const zig_module = self.file(index).?.zig_module;
|
||||
zig_module.claimUnresolved(self);
|
||||
}
|
||||
for (self.objects.items) |index| {
|
||||
const object = self.file(index).?.object;
|
||||
for (object.globals()) |global_index| {
|
||||
const global = self.symbol(global_index);
|
||||
if (global.version_index == elf.VER_NDX_LOCAL) continue;
|
||||
const file_ptr = global.file(self) orelse continue;
|
||||
const vis = @as(elf.STV, @enumFromInt(global.elfSym(self).st_other));
|
||||
if (vis == .HIDDEN) continue;
|
||||
// if (file == .shared and !global.isAbs(self)) {
|
||||
// global.flags.import = true;
|
||||
// continue;
|
||||
// }
|
||||
if (file_ptr.index() == index) {
|
||||
global.flags.@"export" = true;
|
||||
if (is_dyn_lib and vis != .PROTECTED) {
|
||||
global.flags.import = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
object.claimUnresolved(self);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3423,6 +3421,10 @@ pub fn defaultEntryAddress(self: Elf) u64 {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isDynLib(self: Elf) bool {
|
||||
return self.base.options.output_mode == .Lib and self.base.options.link_mode == .Dynamic;
|
||||
}
|
||||
|
||||
pub fn sectionByName(self: *Elf, name: [:0]const u8) ?u16 {
|
||||
for (self.shdrs.items, 0..) |*shdr, i| {
|
||||
const this_name = self.shstrtab.getAssumeExists(shdr.sh_name);
|
||||
|
||||
@ -411,6 +411,34 @@ pub fn resolveSymbols(self: *Object, elf_file: *Elf) void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn claimUnresolved(self: *Object, elf_file: *Elf) void {
|
||||
const first_global = self.first_global orelse return;
|
||||
for (self.globals(), 0..) |index, i| {
|
||||
const esym_index = @as(u32, @intCast(first_global + i));
|
||||
const esym = self.symtab[esym_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;
|
||||
}
|
||||
|
||||
const is_import = blk: {
|
||||
if (!elf_file.isDynLib()) break :blk false;
|
||||
const vis = @as(elf.STV, @enumFromInt(esym.st_other));
|
||||
if (vis == .HIDDEN) break :blk false;
|
||||
break :blk true;
|
||||
};
|
||||
|
||||
global.value = 0;
|
||||
global.atom_index = 0;
|
||||
global.esym_index = esym_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;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resetGlobals(self: *Object, elf_file: *Elf) void {
|
||||
for (self.globals()) |index| {
|
||||
const global = elf_file.symbol(index);
|
||||
@ -576,12 +604,12 @@ pub fn writeSymtab(self: *Object, elf_file: *Elf, ctx: anytype) void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn locals(self: *Object) []const u32 {
|
||||
pub fn locals(self: *Object) []const Symbol.Index {
|
||||
const end = self.first_global orelse self.symbols.items.len;
|
||||
return self.symbols.items[0..end];
|
||||
}
|
||||
|
||||
pub fn globals(self: *Object) []const u32 {
|
||||
pub fn globals(self: *Object) []const Symbol.Index {
|
||||
const start = self.first_global orelse self.symbols.items.len;
|
||||
return self.symbols.items[start..];
|
||||
}
|
||||
|
||||
@ -102,6 +102,34 @@ 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];
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
const is_import = blk: {
|
||||
if (!elf_file.isDynLib()) break :blk false;
|
||||
const vis = @as(elf.STV, @enumFromInt(esym.st_other));
|
||||
if (vis == .HIDDEN) break :blk false;
|
||||
break :blk true;
|
||||
};
|
||||
|
||||
global.value = 0;
|
||||
global.atom_index = 0;
|
||||
global.esym_index = esym_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;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn updateSymtabSize(self: *ZigModule, elf_file: *Elf) void {
|
||||
for (self.locals()) |local_index| {
|
||||
const local = elf_file.symbol(local_index);
|
||||
|
||||
@ -76,6 +76,12 @@ pub const File = union(enum) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn globals(file: File) []const Symbol.Index {
|
||||
return switch (file) {
|
||||
inline else => |x| x.globals(),
|
||||
};
|
||||
}
|
||||
|
||||
pub const Index = u32;
|
||||
|
||||
pub const Entry = union(enum) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user