aboutsummaryrefslogtreecommitdiff
path: root/src/link/Elf/LinkerDefined.zig
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2023-09-05 15:55:00 +0200
committerJakub Konka <kubkon@jakubkonka.com>2023-09-05 15:55:00 +0200
commitd9fffd431a89ed4104bcc0b2165bfb9917cdd82b (patch)
tree4b17125cfe074a98c32789c6315ca52db2e0234c /src/link/Elf/LinkerDefined.zig
parent02451bdebfe2685c283f6955488d978047e4e9d8 (diff)
downloadzig-d9fffd431a89ed4104bcc0b2165bfb9917cdd82b.tar.gz
zig-d9fffd431a89ed4104bcc0b2165bfb9917cdd82b.zip
elf: start porting abstraction of input file
Diffstat (limited to 'src/link/Elf/LinkerDefined.zig')
-rw-r--r--src/link/Elf/LinkerDefined.zig132
1 files changed, 132 insertions, 0 deletions
diff --git a/src/link/Elf/LinkerDefined.zig b/src/link/Elf/LinkerDefined.zig
new file mode 100644
index 0000000000..e7cb35b769
--- /dev/null
+++ b/src/link/Elf/LinkerDefined.zig
@@ -0,0 +1,132 @@
+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.getOrCreateGlobal(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(u32, @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 asFile(self: *LinkerDefined) File {
+ return .{ .linker_defined = self };
+}
+
+pub inline fn getGlobals(self: *LinkerDefined) []const u32 {
+ return self.symbols.items;
+}
+
+pub fn fmtSymtab(self: *InternalObject, elf_file: *Elf) std.fmt.Formatter(formatSymtab) {
+ return .{ .data = .{
+ .self = self,
+ .elf_file = elf_file,
+ } };
+}
+
+const FormatContext = struct {
+ self: *InternalObject,
+ 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.getGlobals()) |index| {
+ const global = ctx.elf_file.getSymbol(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");