elf: mark imports-exports; populate symtab with objects
This commit is contained in:
@@ -1047,6 +1047,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
|
||||
|
||||
// Resolve symbols
|
||||
self.resolveSymbols();
|
||||
self.markImportsExports();
|
||||
|
||||
if (self.unresolved.keys().len > 0) try self.reportUndefined();
|
||||
|
||||
@@ -1336,6 +1337,52 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
@@ -2941,6 +2988,13 @@ fn updateSymtabSize(self: *Elf) !void {
|
||||
sizes.nglobals += zig_module.output_symtab_size.nglobals;
|
||||
}
|
||||
|
||||
for (self.objects.items) |index| {
|
||||
const object = self.file(index).?.object;
|
||||
object.updateSymtabSize(self);
|
||||
sizes.nlocals += object.output_symtab_size.nlocals;
|
||||
sizes.nglobals += object.output_symtab_size.nglobals;
|
||||
}
|
||||
|
||||
if (self.got_section_index) |_| {
|
||||
self.got.updateSymtabSize(self);
|
||||
sizes.nlocals += self.got.output_symtab_size.nlocals;
|
||||
@@ -2996,6 +3050,13 @@ fn writeSymtab(self: *Elf) !void {
|
||||
ctx.iglobal += zig_module.output_symtab_size.nglobals;
|
||||
}
|
||||
|
||||
for (self.objects.items) |index| {
|
||||
const object = self.file(index).?.object;
|
||||
object.writeSymtab(self, ctx);
|
||||
ctx.ilocal += object.output_symtab_size.nlocals;
|
||||
ctx.iglobal += object.output_symtab_size.nglobals;
|
||||
}
|
||||
|
||||
if (self.got_section_index) |_| {
|
||||
try self.got.writeSymtab(self, ctx);
|
||||
ctx.ilocal += self.got.output_symtab_size.nlocals;
|
||||
|
||||
@@ -430,7 +430,7 @@ pub fn markLive(self: *Object, elf_file: *Elf) void {
|
||||
const global = elf_file.symbol(index);
|
||||
const file = global.getFile(elf_file) orelse continue;
|
||||
const should_keep = sym.st_shndx == elf.SHN_UNDEF or
|
||||
(sym.st_shndx == elf.SHN_COMMON and global.sourceSymbol(elf_file).st_shndx != elf.SHN_COMMON);
|
||||
(sym.st_shndx == elf.SHN_COMMON and global.elfSym(elf_file).st_shndx != elf.SHN_COMMON);
|
||||
if (should_keep and !file.isAlive()) {
|
||||
file.setAlive();
|
||||
file.markLive(elf_file);
|
||||
@@ -526,25 +526,22 @@ pub fn convertCommonSymbols(self: *Object, elf_file: *Elf) !void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn calcSymtabSize(self: *Object, elf_file: *Elf) !void {
|
||||
if (elf_file.options.strip_all) return;
|
||||
|
||||
pub fn updateSymtabSize(self: *Object, elf_file: *Elf) void {
|
||||
for (self.locals()) |local_index| {
|
||||
const local = elf_file.symbol(local_index);
|
||||
if (local.atom(elf_file)) |atom| if (!atom.alive) continue;
|
||||
const s_sym = local.getSourceSymbol(elf_file);
|
||||
switch (s_sym.st_type()) {
|
||||
const esym = local.elfSym(elf_file);
|
||||
switch (esym.st_type()) {
|
||||
elf.STT_SECTION, elf.STT_NOTYPE => continue,
|
||||
else => {},
|
||||
}
|
||||
local.flags.output_symtab = true;
|
||||
self.output_symtab_size.nlocals += 1;
|
||||
self.output_symtab_size.strsize += @as(u32, @intCast(local.getName(elf_file).len + 1));
|
||||
}
|
||||
|
||||
for (self.globals()) |global_index| {
|
||||
const global = elf_file.symbol(global_index);
|
||||
if (global.getFile(elf_file)) |file| if (file.getIndex() != self.index) continue;
|
||||
if (global.file(elf_file)) |file| if (file.index() != self.index) continue;
|
||||
if (global.atom(elf_file)) |atom| if (!atom.alive) continue;
|
||||
global.flags.output_symtab = true;
|
||||
if (global.isLocal()) {
|
||||
@@ -552,35 +549,28 @@ pub fn calcSymtabSize(self: *Object, elf_file: *Elf) !void {
|
||||
} else {
|
||||
self.output_symtab_size.nglobals += 1;
|
||||
}
|
||||
self.output_symtab_size.strsize += @as(u32, @intCast(global.getName(elf_file).len + 1));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeSymtab(self: *Object, elf_file: *Elf, ctx: Elf.WriteSymtabCtx) !void {
|
||||
if (elf_file.options.strip_all) return;
|
||||
|
||||
const gpa = elf_file.base.allocator;
|
||||
|
||||
pub fn writeSymtab(self: *Object, elf_file: *Elf, ctx: anytype) void {
|
||||
var ilocal = ctx.ilocal;
|
||||
for (self.locals()) |local_index| {
|
||||
const local = elf_file.symbol(local_index);
|
||||
if (!local.flags.output_symtab) continue;
|
||||
const st_name = try ctx.strtab.insert(gpa, local.getName(elf_file));
|
||||
ctx.symtab[ilocal] = local.asElfSym(st_name, elf_file);
|
||||
local.setOutputSym(elf_file, &ctx.symtab[ilocal]);
|
||||
ilocal += 1;
|
||||
}
|
||||
|
||||
var iglobal = ctx.iglobal;
|
||||
for (self.globals()) |global_index| {
|
||||
const global = elf_file.symbol(global_index);
|
||||
if (global.getFile(elf_file)) |file| if (file.getIndex() != self.index) continue;
|
||||
if (global.file(elf_file)) |file| if (file.index() != self.index) continue;
|
||||
if (!global.flags.output_symtab) continue;
|
||||
const st_name = try ctx.strtab.insert(gpa, global.getName(elf_file));
|
||||
if (global.isLocal()) {
|
||||
ctx.symtab[ilocal] = global.asElfSym(st_name, elf_file);
|
||||
global.setOutputSym(elf_file, &ctx.symtab[ilocal]);
|
||||
ilocal += 1;
|
||||
} else {
|
||||
ctx.symtab[iglobal] = global.asElfSym(st_name, elf_file);
|
||||
global.setOutputSym(elf_file, &ctx.symtab[iglobal]);
|
||||
iglobal += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ atom_index: Atom.Index = 0,
|
||||
output_section_index: u16 = 0,
|
||||
|
||||
/// Index of the source symbol this symbol references.
|
||||
/// Use `sourceSymbol` to pull the source symbol from the relevant file.
|
||||
/// Use `elfSym` to pull the source symbol from the relevant file.
|
||||
esym_index: Index = 0,
|
||||
|
||||
/// Index of the source version symbol this symbol references if any.
|
||||
@@ -48,7 +48,7 @@ pub inline fn isIFunc(symbol: Symbol, elf_file: *Elf) bool {
|
||||
}
|
||||
|
||||
pub fn @"type"(symbol: Symbol, elf_file: *Elf) u4 {
|
||||
const s_sym = symbol.sourceSymbol(elf_file);
|
||||
const s_sym = symbol.elfSym(elf_file);
|
||||
// const file_ptr = symbol.file(elf_file).?;
|
||||
// if (s_sym.st_type() == elf.STT_GNU_IFUNC and file_ptr == .shared) return elf.STT_FUNC;
|
||||
return s_sym.st_type();
|
||||
@@ -66,7 +66,7 @@ pub fn file(symbol: Symbol, elf_file: *Elf) ?File {
|
||||
return elf_file.file(symbol.file_index);
|
||||
}
|
||||
|
||||
pub fn sourceSymbol(symbol: Symbol, elf_file: *Elf) elf.Elf64_Sym {
|
||||
pub fn elfSym(symbol: Symbol, elf_file: *Elf) elf.Elf64_Sym {
|
||||
const file_ptr = symbol.file(elf_file).?;
|
||||
switch (file_ptr) {
|
||||
.zig_module => |x| {
|
||||
@@ -82,7 +82,7 @@ pub fn sourceSymbol(symbol: Symbol, elf_file: *Elf) elf.Elf64_Sym {
|
||||
|
||||
pub fn symbolRank(symbol: Symbol, elf_file: *Elf) u32 {
|
||||
const file_ptr = symbol.file(elf_file) orelse return std.math.maxInt(u32);
|
||||
const sym = symbol.sourceSymbol(elf_file);
|
||||
const sym = symbol.elfSym(elf_file);
|
||||
const in_archive = switch (file_ptr) {
|
||||
.object => |x| !x.alive,
|
||||
else => false,
|
||||
@@ -173,13 +173,13 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {
|
||||
out.* = Elf.null_sym;
|
||||
return;
|
||||
};
|
||||
const s_sym = symbol.sourceSymbol(elf_file);
|
||||
const esym = symbol.elfSym(elf_file);
|
||||
const st_type = symbol.type(elf_file);
|
||||
const st_bind: u8 = blk: {
|
||||
if (symbol.isLocal()) break :blk 0;
|
||||
if (symbol.flags.weak) break :blk elf.STB_WEAK;
|
||||
// if (file_ptr == .shared) break :blk elf.STB_GLOBAL;
|
||||
break :blk s_sym.st_bind();
|
||||
break :blk esym.st_bind();
|
||||
};
|
||||
const st_shndx = blk: {
|
||||
// if (symbol.flags.copy_rel) break :blk elf_file.copy_rel_sect_index.?;
|
||||
@@ -202,10 +202,10 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {
|
||||
out.* = .{
|
||||
.st_name = symbol.name_offset,
|
||||
.st_info = (st_bind << 4) | st_type,
|
||||
.st_other = s_sym.st_other,
|
||||
.st_other = esym.st_other,
|
||||
.st_shndx = st_shndx,
|
||||
.st_value = st_value,
|
||||
.st_size = s_sym.st_size,
|
||||
.st_size = esym.st_size,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ fn format2(
|
||||
try writer.print("%{d} : {s} : @{x}", .{ symbol.index, symbol.fmtName(ctx.elf_file), symbol.value });
|
||||
if (symbol.file(ctx.elf_file)) |file_ptr| {
|
||||
if (symbol.isAbs(ctx.elf_file)) {
|
||||
if (symbol.sourceSymbol(ctx.elf_file).st_shndx == elf.SHN_UNDEF) {
|
||||
if (symbol.elfSym(ctx.elf_file).st_shndx == elf.SHN_UNDEF) {
|
||||
try writer.writeAll(" : undef");
|
||||
} else {
|
||||
try writer.writeAll(" : absolute");
|
||||
|
||||
@@ -105,7 +105,7 @@ pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void {
|
||||
pub fn updateSymtabSize(self: *ZigModule, elf_file: *Elf) void {
|
||||
for (self.locals()) |local_index| {
|
||||
const local = elf_file.symbol(local_index);
|
||||
const esym = local.sourceSymbol(elf_file);
|
||||
const esym = local.elfSym(elf_file);
|
||||
switch (esym.st_type()) {
|
||||
elf.STT_SECTION, elf.STT_NOTYPE => {
|
||||
local.flags.output_symtab = false;
|
||||
|
||||
Reference in New Issue
Block a user