Commit 137d43c0ea
Changed files (5)
src/link/Elf/file.zig
@@ -101,10 +101,74 @@ pub const File = union(enum) {
}
pub fn createSymbolIndirection(file: File, elf_file: *Elf) !void {
- return switch (file) {
- .linker_defined, .shared_object => unreachable,
- inline else => |x| x.createSymbolIndirection(elf_file),
- };
+ const impl = struct {
+ fn impl(sym: *Symbol, ref: Elf.Ref, ef: *Elf) !void {
+ if (!sym.isLocal(ef) and !sym.flags.has_dynamic) {
+ log.debug("'{s}' is non-local", .{sym.name(ef)});
+ try ef.dynsym.addSymbol(ref, ef);
+ }
+ if (sym.flags.needs_got) {
+ log.debug("'{s}' needs GOT", .{sym.name(ef)});
+ _ = try ef.got.addGotSymbol(ref, ef);
+ }
+ if (sym.flags.needs_plt) {
+ if (sym.flags.is_canonical) {
+ log.debug("'{s}' needs CPLT", .{sym.name(ef)});
+ sym.flags.@"export" = true;
+ try ef.plt.addSymbol(ref, ef);
+ } else if (sym.flags.needs_got) {
+ log.debug("'{s}' needs PLTGOT", .{sym.name(ef)});
+ try ef.plt_got.addSymbol(ref, ef);
+ } else {
+ log.debug("'{s}' needs PLT", .{sym.name(ef)});
+ try ef.plt.addSymbol(ref, ef);
+ }
+ }
+ if (sym.flags.needs_copy_rel and !sym.flags.has_copy_rel) {
+ log.debug("'{s}' needs COPYREL", .{sym.name(ef)});
+ try ef.copy_rel.addSymbol(ref, ef);
+ }
+ if (sym.flags.needs_tlsgd) {
+ log.debug("'{s}' needs TLSGD", .{sym.name(ef)});
+ try ef.got.addTlsGdSymbol(ref, ef);
+ }
+ if (sym.flags.needs_gottp) {
+ log.debug("'{s}' needs GOTTP", .{sym.name(ef)});
+ try ef.got.addGotTpSymbol(ref, ef);
+ }
+ if (sym.flags.needs_tlsdesc) {
+ log.debug("'{s}' needs TLSDESC", .{sym.name(ef)});
+ try ef.got.addTlsDescSymbol(ref, ef);
+ }
+ }
+ }.impl;
+
+ switch (file) {
+ .zig_object => |x| {
+ for (x.local_symbols.items, 0..) |idx, i| {
+ const sym = &x.symbols.items[idx];
+ const ref = x.resolveSymbol(@intCast(i), elf_file);
+ const ref_sym = elf_file.symbol(ref) orelse continue;
+ if (ref_sym.file(elf_file).?.index() != x.index) continue;
+ try impl(sym, ref, elf_file);
+ }
+ for (x.global_symbols.items, 0..) |idx, i| {
+ const sym = &x.symbols.items[idx];
+ const ref = x.resolveSymbol(@intCast(i | ZigObject.global_symbol_bit), elf_file);
+ const ref_sym = elf_file.symbol(ref) orelse continue;
+ if (ref_sym.file(elf_file).?.index() != x.index) continue;
+ try impl(sym, ref, elf_file);
+ }
+ },
+ inline else => |x| {
+ for (x.symbols.items, 0..) |*sym, i| {
+ const ref = x.resolveSymbol(@intCast(i), elf_file);
+ const ref_sym = elf_file.symbol(ref) orelse continue;
+ if (ref_sym.file(elf_file).?.index() != x.index) continue;
+ try impl(sym, ref, elf_file);
+ }
+ },
+ }
}
pub fn atom(file: File, atom_index: Atom.Index) ?*Atom {
@@ -239,6 +303,7 @@ pub const File = union(enum) {
const std = @import("std");
const elf = std.elf;
+const log = std.log.scoped(.link);
const Allocator = std.mem.Allocator;
const Archive = @import("Archive.zig");
src/link/Elf/Object.zig
@@ -561,51 +561,6 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void {
}
}
-pub fn createSymbolIndirection(self: *Object, elf_file: *Elf) !void {
- for (self.symbols.items, 0..) |*sym, i| {
- const ref = self.resolveSymbol(@intCast(i), elf_file);
- const ref_sym = elf_file.symbol(ref) orelse continue;
- if (ref_sym.file(elf_file).?.index() != self.index) continue;
- if (!sym.isLocal(elf_file) and !sym.flags.has_dynamic) {
- log.debug("'{s}' is non-local", .{sym.name(elf_file)});
- try elf_file.dynsym.addSymbol(ref, elf_file);
- }
- if (sym.flags.needs_got) {
- log.debug("'{s}' needs GOT", .{sym.name(elf_file)});
- _ = try elf_file.got.addGotSymbol(ref, elf_file);
- }
- if (sym.flags.needs_plt) {
- if (sym.flags.is_canonical) {
- log.debug("'{s}' needs CPLT", .{sym.name(elf_file)});
- sym.flags.@"export" = true;
- try elf_file.plt.addSymbol(ref, elf_file);
- } else if (sym.flags.needs_got) {
- log.debug("'{s}' needs PLTGOT", .{sym.name(elf_file)});
- try elf_file.plt_got.addSymbol(ref, elf_file);
- } else {
- log.debug("'{s}' needs PLT", .{sym.name(elf_file)});
- try elf_file.plt.addSymbol(ref, elf_file);
- }
- }
- if (sym.flags.needs_copy_rel and !sym.flags.has_copy_rel) {
- log.debug("'{s}' needs COPYREL", .{sym.name(elf_file)});
- try elf_file.copy_rel.addSymbol(ref, elf_file);
- }
- if (sym.flags.needs_tlsgd) {
- log.debug("'{s}' needs TLSGD", .{sym.name(elf_file)});
- try elf_file.got.addTlsGdSymbol(ref, elf_file);
- }
- if (sym.flags.needs_gottp) {
- log.debug("'{s}' needs GOTTP", .{sym.name(elf_file)});
- try elf_file.got.addGotTpSymbol(ref, elf_file);
- }
- if (sym.flags.needs_tlsdesc) {
- log.debug("'{s}' needs TLSDESC", .{sym.name(elf_file)});
- try elf_file.got.addTlsDescSymbol(ref, elf_file);
- }
- }
-}
-
pub fn resolveSymbols(self: *Object, elf_file: *Elf) !void {
const gpa = elf_file.base.comp.gpa;
src/link/Elf/ZigObject.zig
@@ -442,64 +442,6 @@ pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void {
}
}
-pub fn createSymbolIndirection(self: *ZigObject, elf_file: *Elf) !void {
- const impl = struct {
- fn impl(sym: *Symbol, ref: Elf.Ref, ef: *Elf) !void {
- if (!sym.isLocal(ef) and !sym.flags.has_dynamic) {
- log.debug("'{s}' is non-local", .{sym.name(ef)});
- try ef.dynsym.addSymbol(ref, ef);
- }
- if (sym.flags.needs_got) {
- log.debug("'{s}' needs GOT", .{sym.name(ef)});
- _ = try ef.got.addGotSymbol(ref, ef);
- }
- if (sym.flags.needs_plt) {
- if (sym.flags.is_canonical) {
- log.debug("'{s}' needs CPLT", .{sym.name(ef)});
- sym.flags.@"export" = true;
- try ef.plt.addSymbol(ref, ef);
- } else if (sym.flags.needs_got) {
- log.debug("'{s}' needs PLTGOT", .{sym.name(ef)});
- try ef.plt_got.addSymbol(ref, ef);
- } else {
- log.debug("'{s}' needs PLT", .{sym.name(ef)});
- try ef.plt.addSymbol(ref, ef);
- }
- }
- if (sym.flags.needs_copy_rel and !sym.flags.has_copy_rel) {
- log.debug("'{s}' needs COPYREL", .{sym.name(ef)});
- try ef.copy_rel.addSymbol(ref, ef);
- }
- if (sym.flags.needs_tlsgd) {
- log.debug("'{s}' needs TLSGD", .{sym.name(ef)});
- try ef.got.addTlsGdSymbol(ref, ef);
- }
- if (sym.flags.needs_gottp) {
- log.debug("'{s}' needs GOTTP", .{sym.name(ef)});
- try ef.got.addGotTpSymbol(ref, ef);
- }
- if (sym.flags.needs_tlsdesc) {
- log.debug("'{s}' needs TLSDESC", .{sym.name(ef)});
- try ef.got.addTlsDescSymbol(ref, ef);
- }
- }
- }.impl;
- for (self.local_symbols.items, 0..) |index, i| {
- const sym = &self.symbols.items[index];
- const ref = self.resolveSymbol(@intCast(i), elf_file);
- const ref_sym = elf_file.symbol(ref) orelse continue;
- if (ref_sym.file(elf_file).?.index() != self.index) continue;
- try impl(sym, ref, elf_file);
- }
- for (self.global_symbols.items, 0..) |index, i| {
- const sym = &self.symbols.items[index];
- const ref = self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file);
- const ref_sym = elf_file.symbol(ref) orelse continue;
- if (ref_sym.file(elf_file).?.index() != self.index) continue;
- try impl(sym, ref, elf_file);
- }
-}
-
pub fn markLive(self: *ZigObject, elf_file: *Elf) void {
for (self.global_symbols.items, 0..) |index, i| {
const global = self.symbols.items[index];
src/link/Elf.zig
@@ -2060,6 +2060,9 @@ fn scanRelocs(self: *Elf) !void {
for (self.objects.items) |index| {
try self.file(index).?.createSymbolIndirection(self);
}
+ for (self.shared_objects.items) |index| {
+ try self.file(index).?.createSymbolIndirection(self);
+ }
if (self.got.flags.needs_tlsld) {
log.debug("program needs TLSLD", .{});
try self.got.addTlsLdSymbol(self);
@@ -4431,11 +4434,13 @@ pub fn updateSymtabSize(self: *Elf) !void {
strsize += ctx.strsize;
}
- if (self.zig_got_section_index) |_| {
- self.zig_got.output_symtab_ctx.ilocal = nlocals + 1;
- self.zig_got.updateSymtabSize(self);
- nlocals += self.zig_got.output_symtab_ctx.nlocals;
- strsize += self.zig_got.output_symtab_ctx.strsize;
+ if (self.zigObjectPtr()) |_| {
+ if (self.zig_got_section_index) |_| {
+ self.zig_got.output_symtab_ctx.ilocal = nlocals + 1;
+ self.zig_got.updateSymtabSize(self);
+ nlocals += self.zig_got.output_symtab_ctx.nlocals;
+ strsize += self.zig_got.output_symtab_ctx.strsize;
+ }
}
if (self.got_section_index) |_| {
@@ -4574,7 +4579,9 @@ fn writeSyntheticSections(self: *Elf) !void {
const shdr = self.shdrs.items[shndx];
try self.got.addRela(self);
try self.copy_rel.addRela(self);
- try self.zig_got.addRela(self);
+ if (self.zigObjectPtr()) |_| {
+ try self.zig_got.addRela(self);
+ }
self.sortRelaDyn();
try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.rela_dyn.items), shdr.sh_offset);
}