Files
zig/src/link/Elf/LinkerDefined.zig

137 lines
4.3 KiB
Zig

index: File.Index,
symtab: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{},
symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
alive: bool = true,
// output_symtab_size: Elf.SymtabSize = .{},
pub fn deinit(self: *LinkerDefined, allocator: Allocator) void {
self.symtab.deinit(allocator);
self.symbols.deinit(allocator);
}
pub fn addGlobal(self: *LinkerDefined, name: [:0]const u8, elf_file: *Elf) !u32 {
const gpa = elf_file.base.allocator;
try self.symtab.ensureUnusedCapacity(gpa, 1);
try self.symbols.ensureUnusedCapacity(gpa, 1);
self.symtab.appendAssumeCapacity(.{
.st_name = try elf_file.strtab.insert(gpa, name),
.st_info = elf.STB_GLOBAL << 4,
.st_other = @intFromEnum(elf.STV.HIDDEN),
.st_shndx = elf.SHN_ABS,
.st_value = 0,
.st_size = 0,
});
const off = try elf_file.internString("{s}", .{name});
const gop = try elf_file.getOrPutGlobal(off);
self.symbols.addOneAssumeCapacity().* = gop.index;
return gop.index;
}
pub fn resolveSymbols(self: *LinkerDefined, elf_file: *Elf) void {
for (self.symbols.items, 0..) |index, i| {
const sym_idx = @as(Symbol.Index, @intCast(i));
const this_sym = self.symtab.items[sym_idx];
if (this_sym.st_shndx == elf.SHN_UNDEF) continue;
const global = elf_file.symbol(index);
if (self.asFile().symbolRank(this_sym, false) < global.symbolRank(elf_file)) {
global.* = .{
.value = 0,
.name = global.name,
.atom = 0,
.file = self.index,
.sym_idx = sym_idx,
.ver_idx = elf_file.default_sym_version,
};
}
}
}
// pub fn resetGlobals(self: *LinkerDefined, elf_file: *Elf) void {
// for (self.symbols.items) |index| {
// const global = elf_file.getSymbol(index);
// const name = global.name;
// global.* = .{};
// global.name = name;
// }
// }
// pub fn calcSymtabSize(self: *InternalObject, elf_file: *Elf) !void {
// if (elf_file.options.strip_all) return;
// for (self.getGlobals()) |global_index| {
// const global = elf_file.getSymbol(global_index);
// if (global.getFile(elf_file)) |file| if (file.getIndex() != self.index) continue;
// global.flags.output_symtab = true;
// self.output_symtab_size.nlocals += 1;
// self.output_symtab_size.strsize += @as(u32, @intCast(global.getName(elf_file).len + 1));
// }
// }
// pub fn writeSymtab(self: *LinkerDefined, elf_file: *Elf, ctx: Elf.WriteSymtabCtx) !void {
// if (elf_file.options.strip_all) return;
// const gpa = elf_file.base.allocator;
// var ilocal = ctx.ilocal;
// for (self.getGlobals()) |global_index| {
// const global = elf_file.getSymbol(global_index);
// if (global.getFile(elf_file)) |file| if (file.getIndex() != self.index) continue;
// if (!global.flags.output_symtab) continue;
// const st_name = try ctx.strtab.insert(gpa, global.getName(elf_file));
// ctx.symtab[ilocal] = global.asElfSym(st_name, elf_file);
// ilocal += 1;
// }
// }
pub fn sourceSymbol(self: *LinkerDefined, symbol_index: Symbol.Index) *elf.Elf64_Sym {
return &self.symtab.items[symbol_index];
}
pub fn globals(self: *LinkerDefined) []const Symbol.Index {
return self.symbols.items;
}
pub fn asFile(self: *LinkerDefined) File {
return .{ .linker_defined = self };
}
pub fn fmtSymtab(self: *LinkerDefined, elf_file: *Elf) std.fmt.Formatter(formatSymtab) {
return .{ .data = .{
.self = self,
.elf_file = elf_file,
} };
}
const FormatContext = struct {
self: *LinkerDefined,
elf_file: *Elf,
};
fn formatSymtab(
ctx: FormatContext,
comptime unused_fmt_string: []const u8,
options: std.fmt.FormatOptions,
writer: anytype,
) !void {
_ = unused_fmt_string;
_ = options;
try writer.writeAll(" globals\n");
for (ctx.self.globals()) |index| {
const global = ctx.elf_file.symbol(index);
try writer.print(" {}\n", .{global.fmt(ctx.elf_file)});
}
}
const std = @import("std");
const elf = std.elf;
const Allocator = std.mem.Allocator;
const Elf = @import("../Elf.zig");
const File = @import("file.zig").File;
const LinkerDefined = @This();
// const Object = @import("Object.zig");
const Symbol = @import("Symbol.zig");