diff --git a/src/link/Elf/LinkerDefined.zig b/src/link/Elf/LinkerDefined.zig index 938f22985f..bc51cfc1f1 100644 --- a/src/link/Elf/LinkerDefined.zig +++ b/src/link/Elf/LinkerDefined.zig @@ -48,10 +48,42 @@ pub fn resolveSymbols(self: *LinkerDefined, elf_file: *Elf) void { } } -pub fn globals(self: *LinkerDefined) []const Symbol.Index { +pub fn globals(self: LinkerDefined) []const Symbol.Index { return self.symbols.items; } +pub fn updateSymtabSize(self: *LinkerDefined, elf_file: *Elf) !void { + for (self.globals()) |global_index| { + const global = elf_file.symbol(global_index); + const file_ptr = global.file(elf_file) orelse continue; + if (file_ptr.index() != self.index) continue; + global.flags.output_symtab = true; + if (global.isLocal(elf_file)) { + try global.setOutputSymtabIndex(self.output_symtab_ctx.nlocals, elf_file); + self.output_symtab_ctx.nlocals += 1; + } else { + try global.setOutputSymtabIndex(self.output_symtab_ctx.nglobals, elf_file); + self.output_symtab_ctx.nglobals += 1; + } + self.output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1; + } +} + +pub fn writeSymtab(self: LinkerDefined, elf_file: *Elf) void { + for (self.globals()) |global_index| { + const global = elf_file.symbol(global_index); + const file_ptr = global.file(elf_file) orelse continue; + if (file_ptr.index() != self.index) continue; + const idx = global.outputSymtabIndex(elf_file) orelse continue; + const st_name = @as(u32, @intCast(elf_file.strtab.items.len)); + elf_file.strtab.appendSliceAssumeCapacity(global.name(elf_file)); + elf_file.strtab.appendAssumeCapacity(0); + const out_sym = &elf_file.symtab.items[idx]; + out_sym.st_name = st_name; + global.setOutputSym(elf_file, out_sym); + } +} + pub fn asFile(self: *LinkerDefined) File { return .{ .linker_defined = self }; } diff --git a/src/link/Elf/Object.zig b/src/link/Elf/Object.zig index f595988e82..2bcc56b038 100644 --- a/src/link/Elf/Object.zig +++ b/src/link/Elf/Object.zig @@ -741,6 +741,63 @@ pub fn writeAr(self: Object, writer: anytype) !void { try writer.writeAll(self.data); } +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.flags.alive) continue; + const esym = local.elfSym(elf_file); + switch (esym.st_type()) { + elf.STT_SECTION, elf.STT_NOTYPE => continue, + else => {}, + } + local.flags.output_symtab = true; + try local.setOutputSymtabIndex(self.output_symtab_ctx.nlocals, elf_file); + self.output_symtab_ctx.nlocals += 1; + self.output_symtab_ctx.strsize += @as(u32, @intCast(local.name(elf_file).len)) + 1; + } + + for (self.globals()) |global_index| { + const global = elf_file.symbol(global_index); + const file_ptr = global.file(elf_file) orelse continue; + if (file_ptr.index() != self.index) continue; + if (global.atom(elf_file)) |atom| if (!atom.flags.alive) continue; + global.flags.output_symtab = true; + if (global.isLocal(elf_file)) { + try global.setOutputSymtabIndex(self.output_symtab_ctx.nlocals, elf_file); + self.output_symtab_ctx.nlocals += 1; + } else { + try global.setOutputSymtabIndex(self.output_symtab_ctx.nglobals, elf_file); + self.output_symtab_ctx.nglobals += 1; + } + self.output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1; + } +} + +pub fn writeSymtab(self: Object, elf_file: *Elf) void { + for (self.locals()) |local_index| { + const local = elf_file.symbol(local_index); + const idx = local.outputSymtabIndex(elf_file) orelse continue; + const out_sym = &elf_file.symtab.items[idx]; + out_sym.st_name = @intCast(elf_file.strtab.items.len); + elf_file.strtab.appendSliceAssumeCapacity(local.name(elf_file)); + elf_file.strtab.appendAssumeCapacity(0); + local.setOutputSym(elf_file, out_sym); + } + + for (self.globals()) |global_index| { + const global = elf_file.symbol(global_index); + const file_ptr = global.file(elf_file) orelse continue; + if (file_ptr.index() != self.index) continue; + const idx = global.outputSymtabIndex(elf_file) orelse continue; + const st_name = @as(u32, @intCast(elf_file.strtab.items.len)); + elf_file.strtab.appendSliceAssumeCapacity(global.name(elf_file)); + elf_file.strtab.appendAssumeCapacity(0); + const out_sym = &elf_file.symtab.items[idx]; + out_sym.st_name = st_name; + global.setOutputSym(elf_file, out_sym); + } +} + pub fn locals(self: Object) []const Symbol.Index { if (self.symbols.items.len == 0) return &[0]Symbol.Index{}; const end = self.first_global orelse self.symbols.items.len; diff --git a/src/link/Elf/SharedObject.zig b/src/link/Elf/SharedObject.zig index 2317719012..b3302b88d4 100644 --- a/src/link/Elf/SharedObject.zig +++ b/src/link/Elf/SharedObject.zig @@ -191,6 +191,34 @@ pub fn globals(self: SharedObject) []const Symbol.Index { return self.symbols.items; } +pub fn updateSymtabSize(self: *SharedObject, elf_file: *Elf) !void { + for (self.globals()) |global_index| { + const global = elf_file.symbol(global_index); + const file_ptr = global.file(elf_file) orelse continue; + if (file_ptr.index() != self.index) continue; + if (global.isLocal(elf_file)) continue; + global.flags.output_symtab = true; + try global.setOutputSymtabIndex(self.output_symtab_ctx.nglobals, elf_file); + self.output_symtab_ctx.nglobals += 1; + self.output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1; + } +} + +pub fn writeSymtab(self: SharedObject, elf_file: *Elf) void { + for (self.globals()) |global_index| { + const global = elf_file.symbol(global_index); + const file_ptr = global.file(elf_file) orelse continue; + if (file_ptr.index() != self.index) continue; + const idx = global.outputSymtabIndex(elf_file) orelse continue; + const st_name = @as(u32, @intCast(elf_file.strtab.items.len)); + elf_file.strtab.appendSliceAssumeCapacity(global.name(elf_file)); + elf_file.strtab.appendAssumeCapacity(0); + const out_sym = &elf_file.symtab.items[idx]; + out_sym.st_name = st_name; + global.setOutputSym(elf_file, out_sym); + } +} + pub fn shdrContents(self: SharedObject, index: u16) []const u8 { const shdr = self.shdrs.items[index]; return self.data[shdr.sh_offset..][0..shdr.sh_size]; diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index 98bc779ee7..7f2a5efee8 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -528,6 +528,63 @@ pub fn globals(self: ZigObject) []const Symbol.Index { return self.global_symbols.items; } +pub fn updateSymtabSize(self: *ZigObject, elf_file: *Elf) !void { + for (self.locals()) |local_index| { + const local = elf_file.symbol(local_index); + if (local.atom(elf_file)) |atom| if (!atom.flags.alive) continue; + const esym = local.elfSym(elf_file); + switch (esym.st_type()) { + elf.STT_SECTION, elf.STT_NOTYPE => continue, + else => {}, + } + local.flags.output_symtab = true; + try local.setOutputSymtabIndex(self.output_symtab_ctx.nlocals, elf_file); + self.output_symtab_ctx.nlocals += 1; + self.output_symtab_ctx.strsize += @as(u32, @intCast(local.name(elf_file).len)) + 1; + } + + for (self.globals()) |global_index| { + const global = elf_file.symbol(global_index); + const file_ptr = global.file(elf_file) orelse continue; + if (file_ptr.index() != self.index) continue; + if (global.atom(elf_file)) |atom| if (!atom.flags.alive) continue; + global.flags.output_symtab = true; + if (global.isLocal(elf_file)) { + try global.setOutputSymtabIndex(self.output_symtab_ctx.nlocals, elf_file); + self.output_symtab_ctx.nlocals += 1; + } else { + try global.setOutputSymtabIndex(self.output_symtab_ctx.nglobals, elf_file); + self.output_symtab_ctx.nglobals += 1; + } + self.output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1; + } +} + +pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void { + for (self.locals()) |local_index| { + const local = elf_file.symbol(local_index); + const idx = local.outputSymtabIndex(elf_file) orelse continue; + const out_sym = &elf_file.symtab.items[idx]; + out_sym.st_name = @intCast(elf_file.strtab.items.len); + elf_file.strtab.appendSliceAssumeCapacity(local.name(elf_file)); + elf_file.strtab.appendAssumeCapacity(0); + local.setOutputSym(elf_file, out_sym); + } + + for (self.globals()) |global_index| { + const global = elf_file.symbol(global_index); + const file_ptr = global.file(elf_file) orelse continue; + if (file_ptr.index() != self.index) continue; + const idx = global.outputSymtabIndex(elf_file) orelse continue; + const st_name = @as(u32, @intCast(elf_file.strtab.items.len)); + elf_file.strtab.appendSliceAssumeCapacity(global.name(elf_file)); + elf_file.strtab.appendAssumeCapacity(0); + const out_sym = &elf_file.symtab.items[idx]; + out_sym.st_name = st_name; + global.setOutputSym(elf_file, out_sym); + } +} + pub fn asFile(self: *ZigObject) File { return .{ .zig_object = self }; } diff --git a/src/link/Elf/file.zig b/src/link/Elf/file.zig index 29a76daad9..cb83e945d7 100644 --- a/src/link/Elf/file.zig +++ b/src/link/Elf/file.zig @@ -128,63 +128,15 @@ pub const File = union(enum) { } pub fn updateSymtabSize(file: File, elf_file: *Elf) !void { - const output_symtab_ctx = switch (file) { - inline else => |x| &x.output_symtab_ctx, + return switch (file) { + inline else => |x| x.updateSymtabSize(elf_file), }; - for (file.locals()) |local_index| { - const local = elf_file.symbol(local_index); - if (local.atom(elf_file)) |atom| if (!atom.flags.alive) continue; - const esym = local.elfSym(elf_file); - switch (esym.st_type()) { - elf.STT_SECTION, elf.STT_NOTYPE => continue, - else => {}, - } - local.flags.output_symtab = true; - try local.setOutputSymtabIndex(output_symtab_ctx.nlocals, elf_file); - output_symtab_ctx.nlocals += 1; - output_symtab_ctx.strsize += @as(u32, @intCast(local.name(elf_file).len)) + 1; - } - - for (file.globals()) |global_index| { - const global = elf_file.symbol(global_index); - const file_ptr = global.file(elf_file) orelse continue; - if (file_ptr.index() != file.index()) continue; - if (global.atom(elf_file)) |atom| if (!atom.flags.alive) continue; - global.flags.output_symtab = true; - if (global.isLocal(elf_file)) { - try global.setOutputSymtabIndex(output_symtab_ctx.nlocals, elf_file); - output_symtab_ctx.nlocals += 1; - } else { - try global.setOutputSymtabIndex(output_symtab_ctx.nglobals, elf_file); - output_symtab_ctx.nglobals += 1; - } - output_symtab_ctx.strsize += @as(u32, @intCast(global.name(elf_file).len)) + 1; - } } pub fn writeSymtab(file: File, elf_file: *Elf) void { - for (file.locals()) |local_index| { - const local = elf_file.symbol(local_index); - const idx = local.outputSymtabIndex(elf_file) orelse continue; - const out_sym = &elf_file.symtab.items[idx]; - out_sym.st_name = @intCast(elf_file.strtab.items.len); - elf_file.strtab.appendSliceAssumeCapacity(local.name(elf_file)); - elf_file.strtab.appendAssumeCapacity(0); - local.setOutputSym(elf_file, out_sym); - } - - for (file.globals()) |global_index| { - const global = elf_file.symbol(global_index); - const file_ptr = global.file(elf_file) orelse continue; - if (file_ptr.index() != file.index()) continue; - const idx = global.outputSymtabIndex(elf_file) orelse continue; - const st_name = @as(u32, @intCast(elf_file.strtab.items.len)); - elf_file.strtab.appendSliceAssumeCapacity(global.name(elf_file)); - elf_file.strtab.appendAssumeCapacity(0); - const out_sym = &elf_file.symtab.items[idx]; - out_sym.st_name = st_name; - global.setOutputSym(elf_file, out_sym); - } + return switch (file) { + inline else => |x| x.writeSymtab(elf_file), + }; } pub fn updateArSymtab(file: File, ar_symtab: *Archive.ArSymtab, elf_file: *Elf) !void {