authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-01 22:28:28+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-07 10:21:02+02:00
log41e9b8b6c84a1787ffa647fc42980dcce4942b7d
treeb50e763ea1b13fb6afd36e1e169991e2ad6592fb
parentdeeaa1bb0cb8a8c7ccebb23cc68be64e4b013ab2

elf: fix compile errors


22 files changed, 649 insertions(+), 521 deletions(-)

src/arch/aarch64/CodeGen.zig+3-2
......@@ -4354,8 +4354,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
43544354 if (try self.air.value(callee, pt)) |func_value| {
43554355 if (func_value.getFunction(mod)) |func| {
43564356 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
4357 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
4358 const sym = elf_file.symbol(sym_index);
4357 const zo = elf_file.zigObjectPtr().?;
4358 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
4359 const sym = zo.symbol(sym_index);
43594360 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
43604361 const got_addr = @as(u32, @intCast(sym.zigGotAddress(elf_file)));
43614362 try self.genSetReg(Type.usize, .x30, .{ .memory = got_addr });
src/arch/arm/CodeGen.zig+3-2
......@@ -4336,8 +4336,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
43364336 if (try self.air.value(callee, pt)) |func_value| {
43374337 if (func_value.getFunction(mod)) |func| {
43384338 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
4339 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
4340 const sym = elf_file.symbol(sym_index);
4339 const zo = elf_file.zigObjectPtr().?;
4340 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
4341 const sym = zo.symbol(sym_index);
43414342 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
43424343 const got_addr: u32 = @intCast(sym.zigGotAddress(elf_file));
43434344 try self.genSetReg(Type.usize, .lr, .{ .memory = got_addr });
src/arch/riscv64/CodeGen.zig+11-7
......@@ -1409,12 +1409,13 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {
14091409 defer func.register_manager.unlockReg(data_lock);
14101410
14111411 const elf_file = func.bin_file.cast(link.File.Elf).?;
1412 const sym_index = elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, pt, .{
1412 const zo = elf_file.zigObjectPtr().?;
1413 const sym_index = zo.getOrCreateMetadataForLazySymbol(elf_file, pt, .{
14131414 .kind = .const_data,
14141415 .ty = enum_ty,
14151416 }) catch |err|
14161417 return func.fail("{s} creating lazy symbol", .{@errorName(err)});
1417 const sym = elf_file.symbol(sym_index);
1418 const sym = zo.symbol(sym_index);
14181419
14191420 try func.genSetReg(Type.u64, data_reg, .{ .lea_symbol = .{ .sym = sym.esym_index } });
14201421
......@@ -4946,8 +4947,9 @@ fn genCall(
49464947 }) {
49474948 .func => |func_val| {
49484949 if (func.bin_file.cast(link.File.Elf)) |elf_file| {
4949 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func_val.owner_decl);
4950 const sym = elf_file.symbol(sym_index);
4950 const zo = elf_file.zigObjectPtr().?;
4951 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, func_val.owner_decl);
4952 const sym = zo.symbol(sym_index);
49514953
49524954 if (func.mod.pic) {
49534955 return func.fail("TODO: genCall pic", .{});
......@@ -7822,9 +7824,10 @@ fn airTagName(func: *Func, inst: Air.Inst.Index) !void {
78227824
78237825 const lazy_sym = link.File.LazySymbol.initDecl(.code, enum_ty.getOwnerDecl(zcu), zcu);
78247826 const elf_file = func.bin_file.cast(link.File.Elf).?;
7825 const sym_index = elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|
7827 const zo = elf_file.zigObjectPtr().?;
7828 const sym_index = zo.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|
78267829 return func.fail("{s} creating lazy symbol", .{@errorName(err)});
7827 const sym = elf_file.symbol(sym_index);
7830 const sym = zo.symbol(sym_index);
78287831
78297832 if (func.mod.pic) {
78307833 return func.fail("TODO: airTagName pic", .{});
......@@ -8049,7 +8052,8 @@ fn genTypedValue(func: *Func, val: Value) InnerError!MCValue {
80498052 switch (lf.tag) {
80508053 .elf => {
80518054 const elf_file = lf.cast(link.File.Elf).?;
8052 const local = elf_file.symbol(local_sym_index);
8055 const zo = elf_file.zigObjectPtr().?;
8056 const local = zo.symbol(local_sym_index);
80538057 return MCValue{ .undef = local.esym_index };
80548058 },
80558059 else => unreachable,
src/arch/riscv64/Emit.zig+8-6
......@@ -50,16 +50,16 @@ pub fn emitMir(emit: *Emit) Error!void {
5050 };
5151
5252 const elf_file = emit.bin_file.cast(link.File.Elf).?;
53 const zo = elf_file.zigObjectPtr().?;
5354
54 const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;
55 const sym_index = elf_file.zigObjectPtr().?.symbol(symbol.sym_index);
56 const sym = elf_file.symbol(sym_index);
55 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;
56 const sym = zo.symbol(symbol.sym_index);
5757
5858 var hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);
5959 var lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I);
6060
6161 if (sym.flags.needs_zig_got and !is_obj_or_static_lib) {
62 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
62 _ = try sym.getOrCreateZigGotEntry(symbol.sym_index, elf_file);
6363
6464 hi_r_type = Elf.R_ZIG_GOT_HI20;
6565 lo_r_type = Elf.R_ZIG_GOT_LO12;
......@@ -82,8 +82,9 @@ pub fn emitMir(emit: *Emit) Error!void {
8282 },
8383 .load_tlv_reloc => |symbol| {
8484 const elf_file = emit.bin_file.cast(link.File.Elf).?;
85 const zo = elf_file.zigObjectPtr().?;
8586
86 const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;
87 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;
8788
8889 const R_RISCV = std.elf.R_RISCV;
8990
......@@ -107,7 +108,8 @@ pub fn emitMir(emit: *Emit) Error!void {
107108 },
108109 .call_extern_fn_reloc => |symbol| {
109110 const elf_file = emit.bin_file.cast(link.File.Elf).?;
110 const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;
111 const zo = elf_file.zigObjectPtr().?;
112 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;
111113
112114 const r_type: u32 = @intFromEnum(std.elf.R_RISCV.CALL_PLT);
113115
src/arch/sparc64/CodeGen.zig+3-2
......@@ -1354,8 +1354,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
13541354 switch (mod.intern_pool.indexToKey(func_value.ip_index)) {
13551355 .func => |func| {
13561356 const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: {
1357 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
1358 const sym = elf_file.symbol(sym_index);
1357 const zo = elf_file.zigObjectPtr().?;
1358 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
1359 const sym = zo.symbol(sym_index);
13591360 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
13601361 break :blk @as(u32, @intCast(sym.zigGotAddress(elf_file)));
13611362 } else unreachable;
src/arch/x86_64/CodeGen.zig+6-4
......@@ -12327,8 +12327,9 @@ fn genCall(self: *Self, info: union(enum) {
1232712327 }) {
1232812328 .func => |func| {
1232912329 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
12330 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
12331 const sym = elf_file.symbol(sym_index);
12330 const zo = elf_file.zigObjectPtr().?;
12331 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
12332 const sym = zo.symbol(sym_index);
1233212333 if (self.mod.pic) {
1233312334 const callee_reg: Register = switch (resolved_cc) {
1233412335 .SysV => callee: {
......@@ -15320,9 +15321,10 @@ fn genLazySymbolRef(
1532015321) InnerError!void {
1532115322 const pt = self.pt;
1532215323 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
15323 const sym_index = elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|
15324 const zo = elf_file.zigObjectPtr().?;
15325 const sym_index = zo.getOrCreateMetadataForLazySymbol(elf_file, pt, lazy_sym) catch |err|
1532415326 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
15325 const sym = elf_file.symbol(sym_index);
15327 const sym = zo.symbol(sym_index);
1532615328 if (self.mod.pic) {
1532715329 switch (tag) {
1532815330 .lea, .call => try self.genSetReg(reg, Type.usize, .{
src/arch/x86_64/Emit.zig+10-7
......@@ -42,7 +42,8 @@ pub fn emitMir(emit: *Emit) Error!void {
4242 }),
4343 .linker_extern_fn => |symbol| if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| {
4444 // Add relocation to the decl.
45 const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;
45 const zo = elf_file.zigObjectPtr().?;
46 const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;
4647 const r_type = @intFromEnum(std.elf.R_X86_64.PLT32);
4748 try atom_ptr.addReloc(elf_file, .{
4849 .r_offset = end_offset - 4,
......@@ -88,7 +89,8 @@ pub fn emitMir(emit: *Emit) Error!void {
8889 }),
8990 .linker_tlsld => |data| {
9091 const elf_file = emit.lower.bin_file.cast(link.File.Elf).?;
91 const atom = elf_file.symbol(data.atom_index).atom(elf_file).?;
92 const zo = elf_file.zigObjectPtr().?;
93 const atom = zo.symbol(data.atom_index).atom(elf_file).?;
9294 const r_type = @intFromEnum(std.elf.R_X86_64.TLSLD);
9395 try atom.addReloc(elf_file, .{
9496 .r_offset = end_offset - 4,
......@@ -98,7 +100,8 @@ pub fn emitMir(emit: *Emit) Error!void {
98100 },
99101 .linker_dtpoff => |data| {
100102 const elf_file = emit.lower.bin_file.cast(link.File.Elf).?;
101 const atom = elf_file.symbol(data.atom_index).atom(elf_file).?;
103 const zo = elf_file.zigObjectPtr().?;
104 const atom = zo.symbol(data.atom_index).atom(elf_file).?;
102105 const r_type = @intFromEnum(std.elf.R_X86_64.DTPOFF32);
103106 try atom.addReloc(elf_file, .{
104107 .r_offset = end_offset - 4,
......@@ -112,11 +115,11 @@ pub fn emitMir(emit: *Emit) Error!void {
112115 .Obj => true,
113116 .Lib => emit.lower.link_mode == .static,
114117 };
115 const atom = elf_file.symbol(data.atom_index).atom(elf_file).?;
116 const sym_index = elf_file.zigObjectPtr().?.symbol(data.sym_index);
117 const sym = elf_file.symbol(sym_index);
118 const zo = elf_file.zigObjectPtr().?;
119 const atom = zo.symbol(data.atom_index).atom(elf_file).?;
120 const sym = zo.symbol(data.sym_index);
118121 if (sym.flags.needs_zig_got and !is_obj_or_static_lib) {
119 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
122 _ = try sym.getOrCreateZigGotEntry(data.sym_index, elf_file);
120123 }
121124 if (emit.lower.pic) {
122125 const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj_or_static_lib)
src/arch/x86_64/Lower.zig+2-2
......@@ -349,8 +349,8 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
349349 assert(mem_op.sib.scale_index.scale == 0);
350350
351351 if (lower.bin_file.cast(link.File.Elf)) |elf_file| {
352 const sym_index = elf_file.zigObjectPtr().?.symbol(sym.sym_index);
353 const elf_sym = elf_file.symbol(sym_index);
352 const zo = elf_file.zigObjectPtr().?;
353 const elf_sym = zo.symbol(sym.sym_index);
354354
355355 if (elf_sym.flags.is_tls) {
356356 // TODO handle extern TLS vars, i.e., emit GD model
src/codegen.zig+6-8
......@@ -906,20 +906,20 @@ fn genDeclRef(
906906 const is_extern = decl.isExtern(zcu);
907907
908908 if (lf.cast(link.File.Elf)) |elf_file| {
909 const zo = elf_file.zigObjectPtr().?;
909910 if (is_extern) {
910911 const name = decl.name.toSlice(ip);
911912 // TODO audit this
912913 const lib_name = if (decl.getOwnedVariable(zcu)) |ov| ov.lib_name.toSlice(ip) else null;
913914 const sym_index = try elf_file.getGlobalSymbol(name, lib_name);
914 elf_file.symbol(elf_file.zigObjectPtr().?.symbol(sym_index)).flags.needs_got = true;
915 zo.symbol(sym_index).flags.needs_got = true;
915916 return GenResult.mcv(.{ .load_symbol = sym_index });
916917 }
917 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index);
918 const sym = elf_file.symbol(sym_index);
918 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, decl_index);
919919 if (is_threadlocal) {
920 return GenResult.mcv(.{ .load_tlv = sym.esym_index });
920 return GenResult.mcv(.{ .load_tlv = sym_index });
921921 }
922 return GenResult.mcv(.{ .load_symbol = sym.esym_index });
922 return GenResult.mcv(.{ .load_symbol = sym_index });
923923 } else if (lf.cast(link.File.MachO)) |macho_file| {
924924 const zo = macho_file.getZigObject().?;
925925 if (is_extern) {
......@@ -971,9 +971,7 @@ fn genUnnamedConst(
971971 };
972972 switch (lf.tag) {
973973 .elf => {
974 const elf_file = lf.cast(link.File.Elf).?;
975 const local = elf_file.symbol(local_sym_index);
976 return GenResult.mcv(.{ .load_symbol = local.esym_index });
974 return GenResult.mcv(.{ .load_symbol = local_sym_index });
977975 },
978976 .macho => {
979977 const macho_file = lf.cast(link.File.MachO).?;
src/link/Elf.zig+50-81
......@@ -2013,11 +2013,10 @@ fn claimUnresolved(self: *Elf) void {
20132013fn scanRelocs(self: *Elf) !void {
20142014 const gpa = self.base.comp.gpa;
20152015
2016 var undefs = std.AutoHashMap(Symbol.Index, std.ArrayList(Ref)).init(gpa);
2016 var undefs = std.AutoArrayHashMap(SymbolResolver.Index, std.ArrayList(Ref)).init(gpa);
20172017 defer {
2018 var it = undefs.iterator();
2019 while (it.next()) |entry| {
2020 entry.value_ptr.deinit();
2018 for (undefs.values()) |*refs| {
2019 refs.deinit();
20212020 }
20222021 undefs.deinit();
20232022 }
......@@ -2028,7 +2027,18 @@ fn scanRelocs(self: *Elf) !void {
20282027 objects.appendSliceAssumeCapacity(self.objects.items);
20292028
20302029 var has_reloc_errors = false;
2031 for (objects.items) |index| {
2030 if (self.zigObjectPtr()) |zo| {
2031 zo.asFile().scanRelocs(self, &undefs) catch |err| switch (err) {
2032 error.RelaxFailure => unreachable,
2033 error.UnsupportedCpuArch => {
2034 try self.reportUnsupportedCpuArch();
2035 return error.FlushFailure;
2036 },
2037 error.RelocFailure => has_reloc_errors = true,
2038 else => |e| return e,
2039 };
2040 }
2041 for (self.objects.items) |index| {
20322042 self.file(index).?.scanRelocs(self, &undefs) catch |err| switch (err) {
20332043 error.RelaxFailure => unreachable,
20342044 error.UnsupportedCpuArch => {
......@@ -2044,47 +2054,12 @@ fn scanRelocs(self: *Elf) !void {
20442054
20452055 if (has_reloc_errors) return error.FlushFailure;
20462056
2047 for (self.symbols.items, 0..) |*sym, i| {
2048 const index = @as(u32, @intCast(i));
2049 if (!sym.isLocal(self) and !sym.flags.has_dynamic) {
2050 log.debug("'{s}' is non-local", .{sym.name(self)});
2051 try self.dynsym.addSymbol(index, self);
2052 }
2053 if (sym.flags.needs_got) {
2054 log.debug("'{s}' needs GOT", .{sym.name(self)});
2055 _ = try self.got.addGotSymbol(index, self);
2056 }
2057 if (sym.flags.needs_plt) {
2058 if (sym.flags.is_canonical) {
2059 log.debug("'{s}' needs CPLT", .{sym.name(self)});
2060 sym.flags.@"export" = true;
2061 try self.plt.addSymbol(index, self);
2062 } else if (sym.flags.needs_got) {
2063 log.debug("'{s}' needs PLTGOT", .{sym.name(self)});
2064 try self.plt_got.addSymbol(index, self);
2065 } else {
2066 log.debug("'{s}' needs PLT", .{sym.name(self)});
2067 try self.plt.addSymbol(index, self);
2068 }
2069 }
2070 if (sym.flags.needs_copy_rel and !sym.flags.has_copy_rel) {
2071 log.debug("'{s}' needs COPYREL", .{sym.name(self)});
2072 try self.copy_rel.addSymbol(index, self);
2073 }
2074 if (sym.flags.needs_tlsgd) {
2075 log.debug("'{s}' needs TLSGD", .{sym.name(self)});
2076 try self.got.addTlsGdSymbol(index, self);
2077 }
2078 if (sym.flags.needs_gottp) {
2079 log.debug("'{s}' needs GOTTP", .{sym.name(self)});
2080 try self.got.addGotTpSymbol(index, self);
2081 }
2082 if (sym.flags.needs_tlsdesc) {
2083 log.debug("'{s}' needs TLSDESC", .{sym.name(self)});
2084 try self.got.addTlsDescSymbol(index, self);
2085 }
2057 if (self.zigObjectPtr()) |zo| {
2058 try zo.asFile().createSymbolIndirection(self);
2059 }
2060 for (self.objects.items) |index| {
2061 try self.file(index).?.createSymbolIndirection(self);
20862062 }
2087
20882063 if (self.got.flags.needs_tlsld) {
20892064 log.debug("program needs TLSLD", .{});
20902065 try self.got.addTlsLdSymbol(self);
......@@ -2861,8 +2836,8 @@ pub fn writeElfHeader(self: *Elf) !void {
28612836 index += 4;
28622837
28632838 const e_entry: u64 = if (self.linkerDefinedPtr()) |obj| blk: {
2864 const entry_index = obj.entry_index orelse break :blk 0;
2865 break :blk @intCast(self.symbol(entry_index).address(.{}, self));
2839 const entry_sym = obj.entrySymbol(self) orelse break :blk 0;
2840 break :blk @intCast(entry_sym.address(.{}, self));
28662841 } else 0;
28672842 const phdr_table_offset = if (self.phdr_table_index) |phndx| self.phdrs.items[phndx].p_offset else 0;
28682843 switch (self.ptr_width) {
......@@ -2993,7 +2968,7 @@ pub fn deleteExport(
29932968fn checkDuplicates(self: *Elf) !void {
29942969 const gpa = self.base.comp.gpa;
29952970
2996 var dupes = std.AutoArrayHashMap(Symbol.Index, std.ArrayListUnmanaged(File.Index)).init(gpa);
2971 var dupes = std.AutoArrayHashMap(SymbolResolver.Index, std.ArrayListUnmanaged(File.Index)).init(gpa);
29972972 defer {
29982973 for (dupes.values()) |*list| {
29992974 list.deinit(gpa);
......@@ -3301,7 +3276,7 @@ fn initSyntheticSections(self: *Elf) !void {
33013276 });
33023277
33033278 const needs_versions = for (self.dynsym.entries.items) |entry| {
3304 const sym = self.symbol(entry.symbol_index);
3279 const sym = self.symbol(entry.ref).?;
33053280 if (sym.flags.import and sym.version_index & elf.VERSYM_VERSION > elf.VER_NDX_GLOBAL) break true;
33063281 } else false;
33073282 if (needs_versions) {
......@@ -3515,7 +3490,7 @@ fn setVersionSymtab(self: *Elf) !void {
35153490 try self.versym.resize(gpa, self.dynsym.count());
35163491 self.versym.items[0] = elf.VER_NDX_LOCAL;
35173492 for (self.dynsym.entries.items, 1..) |entry, i| {
3518 const sym = self.symbol(entry.symbol_index);
3493 const sym = self.symbol(entry.ref).?;
35193494 self.versym.items[i] = sym.version_index;
35203495 }
35213496
......@@ -4307,11 +4282,10 @@ fn allocateSpecialPhdrs(self: *Elf) void {
43074282fn writeAtoms(self: *Elf) !void {
43084283 const gpa = self.base.comp.gpa;
43094284
4310 var undefs = std.AutoHashMap(Symbol.Index, std.ArrayList(Ref)).init(gpa);
4285 var undefs = std.AutoArrayHashMap(SymbolResolver.Index, std.ArrayList(Ref)).init(gpa);
43114286 defer {
4312 var it = undefs.iterator();
4313 while (it.next()) |entry| {
4314 entry.value_ptr.deinit();
4287 for (undefs.values()) |*refs| {
4288 refs.deinit();
43154289 }
43164290 undefs.deinit();
43174291 }
......@@ -5261,7 +5235,7 @@ pub fn calcNumIRelativeRelocs(self: *Elf) usize {
52615235
52625236 for (self.got.entries.items) |entry| {
52635237 if (entry.tag != .got) continue;
5264 const sym = self.symbol(entry.symbol_index);
5238 const sym = self.symbol(entry.ref).?;
52655239 if (sym.isIFunc(self)) count += 1;
52665240 }
52675241
......@@ -5443,36 +5417,34 @@ fn reportUndefinedSymbols(self: *Elf, undefs: anytype) !void {
54435417
54445418 try self.base.comp.link_errors.ensureUnusedCapacity(gpa, undefs.count());
54455419
5446 var it = undefs.iterator();
5447 while (it.next()) |entry| {
5448 const undef_index = entry.key_ptr.*;
5449 const atoms = entry.value_ptr.*.items;
5450 const natoms = @min(atoms.len, max_notes);
5451 const nnotes = natoms + @intFromBool(atoms.len > max_notes);
5420 for (undefs.keys(), undefs.values()) |key, refs| {
5421 const undef_sym = self.resolver.keys.items[key - 1];
5422 const nrefs = @min(refs.items.len, max_notes);
5423 const nnotes = nrefs + @intFromBool(refs.items.len > max_notes);
54525424
54535425 var err = try self.base.addErrorWithNotesAssumeCapacity(nnotes);
5454 try err.addMsg("undefined symbol: {s}", .{self.symbol(undef_index).name(self)});
5426 try err.addMsg("undefined symbol: {s}", .{undef_sym.name(self)});
54555427
5456 for (atoms[0..natoms]) |ref| {
5428 for (refs.items[0..nrefs]) |ref| {
54575429 const atom_ptr = self.atom(ref).?;
5458 const file_ptr = self.file(ref.file).?;
5430 const file_ptr = atom_ptr.file(self).?;
54595431 try err.addNote("referenced by {s}:{s}", .{ file_ptr.fmtPath(), atom_ptr.name(self) });
54605432 }
54615433
5462 if (atoms.len > max_notes) {
5463 const remaining = atoms.len - max_notes;
5434 if (refs.items.len > max_notes) {
5435 const remaining = refs.items.len - max_notes;
54645436 try err.addNote("referenced {d} more times", .{remaining});
54655437 }
54665438 }
54675439}
54685440
54695441fn reportDuplicates(self: *Elf, dupes: anytype) error{ HasDuplicates, OutOfMemory }!void {
5442 if (dupes.keys().len == 0) return; // Nothing to do
5443
54705444 const max_notes = 3;
5471 var has_dupes = false;
5472 var it = dupes.iterator();
5473 while (it.next()) |entry| {
5474 const sym = self.symbol(entry.key_ptr.*);
5475 const notes = entry.value_ptr.*;
5445
5446 for (dupes.keys(), dupes.values()) |key, notes| {
5447 const sym = self.resolver.keys.items[key - 1];
54765448 const nnotes = @min(notes.items.len, max_notes) + @intFromBool(notes.items.len > max_notes);
54775449
54785450 var err = try self.base.addErrorWithNotes(nnotes + 1);
......@@ -5489,11 +5461,9 @@ fn reportDuplicates(self: *Elf, dupes: anytype) error{ HasDuplicates, OutOfMemor
54895461 const remaining = notes.items.len - max_notes;
54905462 try err.addNote("defined {d} more times", .{remaining});
54915463 }
5492
5493 has_dupes = true;
54945464 }
54955465
5496 if (has_dupes) return error.HasDuplicates;
5466 return error.HasDuplicates;
54975467}
54985468
54995469fn reportMissingLibraryError(
......@@ -5918,7 +5888,7 @@ pub const SymbolResolver = struct {
59185888 elf_file: *Elf,
59195889 ) !Result {
59205890 const adapter = Adapter{ .keys = resolver.keys.items, .elf_file = elf_file };
5921 const key = Key{ .index = ref.index, .file = ref.file };
5891 const key = Key{ .index = ref.index, .file_index = ref.file };
59225892 const gop = try resolver.table.getOrPutAdapted(allocator, key, adapter);
59235893 if (!gop.found_existing) {
59245894 try resolver.keys.append(allocator, key);
......@@ -5944,16 +5914,15 @@ pub const SymbolResolver = struct {
59445914
59455915 const Key = struct {
59465916 index: Symbol.Index,
5947 file: File.Index,
5917 file_index: File.Index,
59485918
59495919 fn name(key: Key, elf_file: *Elf) [:0]const u8 {
5950 const ref = Ref{ .index = key.index, .file = key.file };
5951 return ref.symbol(elf_file).?.name(elf_file);
5920 const ref = Ref{ .index = key.index, .file = key.file_index };
5921 return elf_file.symbol(ref).?.name(elf_file);
59525922 }
59535923
5954 pub fn file(key: Key, elf_file: *Elf) ?File {
5955 const ref = Ref{ .index = key.index, .file = key.file };
5956 return ref.file(elf_file);
5924 fn file(key: Key, elf_file: *Elf) ?File {
5925 return elf_file.file(key.file_index);
59575926 }
59585927
59595928 fn eql(key: Key, other: Key, elf_file: *Elf) bool {
src/link/Elf/Atom.zig+48-61
......@@ -326,12 +326,8 @@ pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.El
326326 const cpu_arch = elf_file.getTarget().cpu.arch;
327327 const file_ptr = self.file(elf_file).?;
328328 for (self.relocs(elf_file)) |rel| {
329 const target_index = switch (file_ptr) {
330 .zig_object => |x| x.symbol(rel.r_sym()),
331 .object => |x| x.symbols.items[rel.r_sym()],
332 else => unreachable,
333 };
334 const target = elf_file.symbol(target_index);
329 const target_ref = file_ptr.resolveSymbol(rel.r_sym(), elf_file);
330 const target = elf_file.symbol(target_ref).?;
335331 const r_type = rel.r_type();
336332 const r_offset: u64 = @intCast(self.value + @as(i64, @intCast(rel.r_offset)));
337333 var r_addend = rel.r_addend;
......@@ -422,12 +418,21 @@ pub fn scanRelocs(self: Atom, elf_file: *Elf, code: ?[]const u8, undefs: anytype
422418 const r_kind = relocation.decode(rel.r_type(), cpu_arch);
423419 if (r_kind == .none) continue;
424420
425 const symbol_index = switch (file_ptr) {
426 .zig_object => |x| x.symbol(rel.r_sym()),
427 .object => |x| x.symbols.items[rel.r_sym()],
428 else => unreachable,
421 const symbol_ref = file_ptr.resolveSymbol(rel.r_sym(), elf_file);
422 const symbol = elf_file.symbol(symbol_ref) orelse {
423 const sym_name = switch (file_ptr) {
424 .zig_object => |x| x.symbol(rel.r_sym()).name(elf_file),
425 inline else => |x| x.symbols.items[rel.r_sym()].name(elf_file),
426 };
427 // Violation of One Definition Rule for COMDATs.
428 // TODO convert into an error
429 log.debug("{}: {s}: {s} refers to a discarded COMDAT section", .{
430 file_ptr.fmtPath(),
431 self.name(elf_file),
432 sym_name,
433 });
434 continue;
429435 };
430 const symbol = elf_file.symbol(symbol_index);
431436
432437 const is_synthetic_symbol = switch (file_ptr) {
433438 .zig_object => false, // TODO: implement this once we support merge sections in ZigObject
......@@ -435,19 +440,8 @@ pub fn scanRelocs(self: Atom, elf_file: *Elf, code: ?[]const u8, undefs: anytype
435440 else => unreachable,
436441 };
437442
438 // Check for violation of One Definition Rule for COMDATs.
439 if (symbol.file(elf_file) == null) {
440 // TODO convert into an error
441 log.debug("{}: {s}: {s} refers to a discarded COMDAT section", .{
442 file_ptr.fmtPath(),
443 self.name(elf_file),
444 symbol.name(elf_file),
445 });
446 continue;
447 }
448
449443 // Report an undefined symbol.
450 if (!is_synthetic_symbol and (try self.reportUndefined(elf_file, symbol, symbol_index, rel, undefs)))
444 if (!is_synthetic_symbol and (try self.reportUndefined(elf_file, symbol, rel, undefs)))
451445 continue;
452446
453447 if (symbol.isIFunc(elf_file)) {
......@@ -694,16 +688,15 @@ fn reportUndefined(
694688 self: Atom,
695689 elf_file: *Elf,
696690 sym: *const Symbol,
697 sym_index: Symbol.Index,
698691 rel: elf.Elf64_Rela,
699692 undefs: anytype,
700693) !bool {
701694 const comp = elf_file.base.comp;
702695 const gpa = comp.gpa;
703 const rel_esym = switch (self.file(elf_file).?) {
704 .zig_object => |x| x.elfSym(rel.r_sym()).*,
705 .object => |x| x.symtab.items[rel.r_sym()],
706 else => unreachable,
696 const file_ptr = self.file(elf_file).?;
697 const rel_esym = switch (file_ptr) {
698 .zig_object => |x| x.symbol(rel.r_sym()).elfSym(elf_file),
699 inline else => |x| x.symtab.items[rel.r_sym()],
707700 };
708701 const esym = sym.elfSym(elf_file);
709702 if (rel_esym.st_shndx == elf.SHN_UNDEF and
......@@ -712,7 +705,12 @@ fn reportUndefined(
712705 !sym.flags.import and
713706 esym.st_shndx == elf.SHN_UNDEF)
714707 {
715 const gop = try undefs.getOrPut(sym_index);
708 const idx = switch (file_ptr) {
709 .zig_object => |x| x.symbols_resolver.items[rel.r_sym() & ZigObject.symbol_mask],
710 .object => |x| x.symbols_resolver.items[rel.r_sym() - x.first_global.?],
711 inline else => |x| x.symbols_resolver.items[rel.r_sym()],
712 };
713 const gop = try undefs.getOrPut(idx);
716714 if (!gop.found_existing) {
717715 gop.value_ptr.* = std.ArrayList(Elf.Ref).init(gpa);
718716 }
......@@ -737,11 +735,8 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi
737735 const r_kind = relocation.decode(rel.r_type(), cpu_arch);
738736 if (r_kind == .none) continue;
739737
740 const target = switch (file_ptr) {
741 .zig_object => |x| elf_file.symbol(x.symbol(rel.r_sym())),
742 .object => |x| elf_file.symbol(x.symbols.items[rel.r_sym()]),
743 else => unreachable,
744 };
738 const target_ref = file_ptr.resolveSymbol(rel.r_sym(), elf_file);
739 const target = elf_file.symbol(target_ref).?;
745740 const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow;
746741
747742 // We will use equation format to resolve relocations:
......@@ -923,31 +918,29 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any
923918
924919 const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow;
925920
926 const target_index = switch (file_ptr) {
927 .zig_object => |x| x.symbol(rel.r_sym()),
928 .object => |x| x.symbols.items[rel.r_sym()],
929 else => unreachable,
930 };
931 const target = elf_file.symbol(target_index);
932 const is_synthetic_symbol = switch (file_ptr) {
933 .zig_object => false, // TODO: implement this once we support merge sections in ZigObject
934 .object => |x| rel.r_sym() >= x.symtab.items.len,
935 else => unreachable,
936 };
937
938 // Check for violation of One Definition Rule for COMDATs.
939 if (target.file(elf_file) == null) {
921 const target_ref = file_ptr.resolveSymbol(rel.r_sym(), elf_file);
922 const target = elf_file.symbol(target_ref) orelse {
923 const sym_name = switch (file_ptr) {
924 .zig_object => |x| x.symbol(rel.r_sym()).name(elf_file),
925 inline else => |x| x.symbols.items[rel.r_sym()].name(elf_file),
926 };
927 // Violation of One Definition Rule for COMDATs.
940928 // TODO convert into an error
941929 log.debug("{}: {s}: {s} refers to a discarded COMDAT section", .{
942930 file_ptr.fmtPath(),
943931 self.name(elf_file),
944 target.name(elf_file),
932 sym_name,
945933 });
946934 continue;
947 }
935 };
936 const is_synthetic_symbol = switch (file_ptr) {
937 .zig_object => false, // TODO: implement this once we support merge sections in ZigObject
938 .object => |x| rel.r_sym() >= x.symtab.items.len,
939 else => unreachable,
940 };
948941
949942 // Report an undefined symbol.
950 if (!is_synthetic_symbol and (try self.reportUndefined(elf_file, target, target_index, rel, undefs)))
943 if (!is_synthetic_symbol and (try self.reportUndefined(elf_file, target, rel, undefs)))
951944 continue;
952945
953946 // We will use equation format to resolve relocations:
......@@ -1766,11 +1759,7 @@ const aarch64 = struct {
17661759 => {
17671760 const disp: i28 = math.cast(i28, S + A - P) orelse blk: {
17681761 const th = atom.thunk(elf_file);
1769 const target_index = switch (file_ptr) {
1770 .zig_object => |x| x.symbol(rel.r_sym()),
1771 .object => |x| x.symbols.items[rel.r_sym()],
1772 else => unreachable,
1773 };
1762 const target_index = file_ptr.resolveSymbol(rel.r_sym(), elf_file);
17741763 const S_ = th.targetAddress(target_index, elf_file);
17751764 break :blk math.cast(i28, S_ + A - P) orelse return error.Overflow;
17761765 };
......@@ -2106,11 +2095,8 @@ const riscv = struct {
21062095 return error.RelocFailure;
21072096 };
21082097 it.pos = pos;
2109 const target_ = switch (file_ptr) {
2110 .zig_object => |x| elf_file.symbol(x.symbol(pair.r_sym())),
2111 .object => |x| elf_file.symbol(x.symbols.items[pair.r_sym()]),
2112 else => unreachable,
2113 };
2098 const target_ref_ = file_ptr.resolveSymbol(pair.r_sym(), elf_file);
2099 const target_ = elf_file.symbol(target_ref_).?;
21142100 const S_ = target_.address(.{}, elf_file);
21152101 const A_ = pair.r_addend;
21162102 const P_ = atom_addr + @as(i64, @intCast(pair.r_offset));
......@@ -2313,4 +2299,5 @@ const File = @import("file.zig").File;
23132299const Object = @import("Object.zig");
23142300const Symbol = @import("Symbol.zig");
23152301const Thunk = @import("thunks.zig").Thunk;
2302const ZigObject = @import("ZigObject.zig");
23162303const dev = @import("../../dev.zig");
src/link/Elf/LinkerDefined.zig+46-28
......@@ -44,7 +44,7 @@ pub fn init(self: *LinkerDefined, allocator: Allocator) !void {
4444
4545pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
4646 const newSymbolAssumeCapacity = struct {
47 fn newSymbolAssumeCapacity(ld: *LinkerDefined, name_off: u32) Symbol.Index {
47 fn newSymbolAssumeCapacity(ld: *LinkerDefined, name_off: u32, ef: *Elf) Symbol.Index {
4848 const esym_index: u32 = @intCast(ld.symtab.items.len);
4949 const esym = ld.symtab.addOneAssumeCapacity();
5050 esym.* = .{
......@@ -61,7 +61,8 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
6161 symbol.extra_index = ld.addSymbolExtraAssumeCapacity(.{});
6262 symbol.ref = .{ .index = 0, .file = 0 };
6363 symbol.esym_index = esym_index;
64 symbol.version_index = elf_file.default_sym_version;
64 symbol.version_index = ef.default_sym_version;
65 return index;
6566 }
6667 }.newSymbolAssumeCapacity;
6768
......@@ -111,31 +112,31 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
111112 @memset(self.symbols_resolver.items, 0);
112113
113114 if (elf_file.entry_name) |name| {
114 self.entry_index = newSymbolAssumeCapacity(self, try self.addString(gpa, name));
115 self.entry_index = newSymbolAssumeCapacity(self, try self.addString(gpa, name), elf_file);
115116 }
116117
117 self.dynamic_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_DYNAMIC"));
118 self.ehdr_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__ehdr_start"));
119 self.init_array_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__init_array_start"));
120 self.init_array_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__init_array_end"));
121 self.fini_array_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__fini_array_start"));
122 self.fini_array_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__fini_array_end"));
123 self.preinit_array_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__preinit_array_start"));
124 self.preinit_array_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__preinit_array_end"));
125 self.got_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_GLOBAL_OFFSET_TABLE_"));
126 self.plt_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_PROCEDURE_LINKAGE_TABLE_"));
127 self.end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_end"));
118 self.dynamic_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_DYNAMIC"), elf_file);
119 self.ehdr_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__ehdr_start"), elf_file);
120 self.init_array_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__init_array_start"), elf_file);
121 self.init_array_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__init_array_end"), elf_file);
122 self.fini_array_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__fini_array_start"), elf_file);
123 self.fini_array_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__fini_array_end"), elf_file);
124 self.preinit_array_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__preinit_array_start"), elf_file);
125 self.preinit_array_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__preinit_array_end"), elf_file);
126 self.got_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_GLOBAL_OFFSET_TABLE_"), elf_file);
127 self.plt_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_PROCEDURE_LINKAGE_TABLE_"), elf_file);
128 self.end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_end"), elf_file);
128129
129130 if (elf_file.base.comp.link_eh_frame_hdr) {
130 self.gnu_eh_frame_hdr_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__GNU_EH_FRAME_HDR"));
131 self.gnu_eh_frame_hdr_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__GNU_EH_FRAME_HDR"), elf_file);
131132 }
132133
133 self.dso_handle_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__dso_handle"));
134 self.rela_iplt_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__rela_iplt_start"));
135 self.rela_iplt_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__rela_iplt_end"));
134 self.dso_handle_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__dso_handle"), elf_file);
135 self.rela_iplt_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__rela_iplt_start"), elf_file);
136 self.rela_iplt_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__rela_iplt_end"), elf_file);
136137
137138 if (elf_file.getTarget().cpu.arch.isRISCV() and elf_file.isEffectivelyDynLib()) {
138 self.global_pointer_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__global_pointer$"));
139 self.global_pointer_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__global_pointer$"), elf_file);
139140 }
140141
141142 for (elf_file.objects.items) |index| {
......@@ -145,8 +146,8 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
145146 defer gpa.free(start_name);
146147 const stop_name = try std.fmt.allocPrintZ(gpa, "__stop_{s}", .{name});
147148 defer gpa.free(stop_name);
148 const start = newSymbolAssumeCapacity(self, try self.addString(gpa, start_name));
149 const stop = newSymbolAssumeCapacity(self, try self.addString(gpa, stop_name));
149 const start = newSymbolAssumeCapacity(self, try self.addString(gpa, start_name), elf_file);
150 const stop = newSymbolAssumeCapacity(self, try self.addString(gpa, stop_name), elf_file);
150151 self.start_stop_indexes.appendSliceAssumeCapacity(&.{ start, stop });
151152 }
152153 }
......@@ -268,7 +269,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
268269 for (elf_file.shdrs.items, 0..) |shdr, shndx| {
269270 if (shdr.sh_flags & elf.SHF_ALLOC != 0) {
270271 value = shdr.sh_addr + shdr.sh_size;
271 osec = shndx;
272 osec = @intCast(shndx);
272273 }
273274 }
274275 allocSymbol(self, self.end_index.?, value, osec, elf_file);
......@@ -287,10 +288,10 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
287288 {
288289 var index: usize = 0;
289290 while (index < self.start_stop_indexes.items.len) : (index += 2) {
290 const start_ref = self.resolveSymbol(self.start_stop_indexes.items[index]);
291 const start_ref = self.resolveSymbol(self.start_stop_indexes.items[index], elf_file);
291292 const start = elf_file.symbol(start_ref).?;
292293 const name = start.name(elf_file);
293 const stop_ref = self.resolveSymbol(self.start_stop_indexes.items[index + 1]);
294 const stop_ref = self.resolveSymbol(self.start_stop_indexes.items[index + 1], elf_file);
294295 const stop = elf_file.symbol(stop_ref).?;
295296 const shndx = elf_file.sectionByName(name["__start_".len..]).?;
296297 const shdr = &elf_file.shdrs.items[shndx];
......@@ -334,6 +335,18 @@ pub fn writeSymtab(self: *LinkerDefined, elf_file: *Elf) void {
334335 }
335336}
336337
338pub fn dynamicSymbol(self: LinkerDefined, elf_file: *Elf) ?*Symbol {
339 const index = self.dynamic_index orelse return null;
340 const resolv = self.resolveSymbol(index, elf_file);
341 return elf_file.symbol(resolv);
342}
343
344pub fn entrySymbol(self: LinkerDefined, elf_file: *Elf) ?*Symbol {
345 const index = self.entry_index orelse return null;
346 const resolv = self.resolveSymbol(index, elf_file);
347 return elf_file.symbol(resolv);
348}
349
337350pub fn asFile(self: *LinkerDefined) File {
338351 return .{ .linker_defined = self };
339352}
......@@ -356,8 +369,12 @@ pub fn resolveSymbol(self: LinkerDefined, index: Symbol.Index, elf_file: *Elf) E
356369 return elf_file.resolver.get(resolv).?;
357370}
358371
359pub fn addSymbol(self: *LinkerDefined, allocator: Allocator) !Symbol.Index {
372fn addSymbol(self: *LinkerDefined, allocator: Allocator) !Symbol.Index {
360373 try self.symbols.ensureUnusedCapacity(allocator, 1);
374 return self.addSymbolAssumeCapacity();
375}
376
377fn addSymbolAssumeCapacity(self: *LinkerDefined) Symbol.Index {
361378 const index: Symbol.Index = @intCast(self.symbols.items.len);
362379 self.symbols.appendAssumeCapacity(.{ .file_index = self.index });
363380 return index;
......@@ -425,10 +442,11 @@ fn formatSymtab(
425442) !void {
426443 _ = unused_fmt_string;
427444 _ = options;
445 const self = ctx.self;
446 const elf_file = ctx.elf_file;
428447 try writer.writeAll(" globals\n");
429 for (ctx.self.globals()) |index| {
430 const global = ctx.elf_file.symbol(index);
431 try writer.print(" {}\n", .{global.fmt(ctx.elf_file)});
448 for (self.symbols.items) |sym| {
449 try writer.print(" {}\n", .{sym.fmt(elf_file)});
432450 }
433451}
434452
src/link/Elf/Object.zig+63-16
......@@ -394,10 +394,9 @@ fn initSymbols(self: *Object, allocator: Allocator, elf_file: *Elf) !void {
394394 sym_ptr.value = @intCast(sym.st_value);
395395 sym_ptr.name_offset = sym.st_name;
396396 sym_ptr.esym_index = @intCast(i);
397 sym_ptr.extra_index = self.addSymbolExtraAssumeCapacity(.{
398 .weak = sym.st_bind() == elf.STB_WEAK,
399 });
397 sym_ptr.extra_index = self.addSymbolExtraAssumeCapacity(.{});
400398 sym_ptr.version_index = if (i >= first_global) elf_file.default_sym_version else elf.VER_NDX_LOCAL;
399 sym_ptr.flags.weak = sym.st_bind() == elf.STB_WEAK;
401400 if (sym.st_shndx != elf.SHN_ABS and sym.st_shndx != elf.SHN_COMMON) {
402401 sym_ptr.ref = .{ .index = self.atoms_indexes.items[sym.st_shndx], .file = self.index };
403402 }
......@@ -548,7 +547,7 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void {
548547
549548 for (self.cies.items) |cie| {
550549 for (cie.relocs(elf_file)) |rel| {
551 const sym = elf_file.symbol(self.resolveSymbol(rel.r_sym()));
550 const sym = elf_file.symbol(self.resolveSymbol(rel.r_sym(), elf_file)).?;
552551 if (sym.flags.import) {
553552 if (sym.type(elf_file) != elf.STT_FUNC)
554553 // TODO convert into an error
......@@ -562,6 +561,51 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void {
562561 }
563562}
564563
564pub fn createSymbolIndirection(self: *Object, elf_file: *Elf) !void {
565 for (self.symbols.items, 0..) |*sym, i| {
566 const ref = self.resolveSymbol(@intCast(i), elf_file);
567 const ref_sym = elf_file.symbol(ref) orelse continue;
568 if (ref_sym.file(elf_file).?.index() != self.index) continue;
569 if (!sym.isLocal(elf_file) and !sym.flags.has_dynamic) {
570 log.debug("'{s}' is non-local", .{sym.name(elf_file)});
571 try elf_file.dynsym.addSymbol(ref, elf_file);
572 }
573 if (sym.flags.needs_got) {
574 log.debug("'{s}' needs GOT", .{sym.name(elf_file)});
575 _ = try elf_file.got.addGotSymbol(ref, elf_file);
576 }
577 if (sym.flags.needs_plt) {
578 if (sym.flags.is_canonical) {
579 log.debug("'{s}' needs CPLT", .{sym.name(elf_file)});
580 sym.flags.@"export" = true;
581 try elf_file.plt.addSymbol(ref, elf_file);
582 } else if (sym.flags.needs_got) {
583 log.debug("'{s}' needs PLTGOT", .{sym.name(elf_file)});
584 try elf_file.plt_got.addSymbol(ref, elf_file);
585 } else {
586 log.debug("'{s}' needs PLT", .{sym.name(elf_file)});
587 try elf_file.plt.addSymbol(ref, elf_file);
588 }
589 }
590 if (sym.flags.needs_copy_rel and !sym.flags.has_copy_rel) {
591 log.debug("'{s}' needs COPYREL", .{sym.name(elf_file)});
592 try elf_file.copy_rel.addSymbol(ref, elf_file);
593 }
594 if (sym.flags.needs_tlsgd) {
595 log.debug("'{s}' needs TLSGD", .{sym.name(elf_file)});
596 try elf_file.got.addTlsGdSymbol(ref, elf_file);
597 }
598 if (sym.flags.needs_gottp) {
599 log.debug("'{s}' needs GOTTP", .{sym.name(elf_file)});
600 try elf_file.got.addGotTpSymbol(ref, elf_file);
601 }
602 if (sym.flags.needs_tlsdesc) {
603 log.debug("'{s}' needs TLSDESC", .{sym.name(elf_file)});
604 try elf_file.got.addTlsDescSymbol(ref, elf_file);
605 }
606 }
607}
608
565609pub fn resolveSymbols(self: *Object, elf_file: *Elf) !void {
566610 const gpa = elf_file.base.comp.gpa;
567611
......@@ -643,7 +687,7 @@ pub fn claimUnresolvedObject(self: *Object, elf_file: *Elf) void {
643687 sym.file_index = self.index;
644688
645689 const idx = self.symbols_resolver.items[i];
646 elf_file.resolver.items[idx - 1] = .{ .index = esym_index, .file = self.index };
690 elf_file.resolver.values.items[idx - 1] = .{ .index = esym_index, .file = self.index };
647691 }
648692}
649693
......@@ -1120,7 +1164,7 @@ pub fn updateSymtabSize(self: *Object, elf_file: *Elf) void {
11201164 }
11211165
11221166 for (self.globals(), self.symbols_resolver.items) |*global, resolv| {
1123 const ref = elf_file.resolver.items[resolv];
1167 const ref = elf_file.resolver.values.items[resolv];
11241168 const ref_sym = elf_file.symbol(ref) orelse continue;
11251169 if (ref_sym.file(elf_file).?.index() != self.index) continue;
11261170 if (!isAlive(global, elf_file)) continue;
......@@ -1136,7 +1180,7 @@ pub fn updateSymtabSize(self: *Object, elf_file: *Elf) void {
11361180 }
11371181}
11381182
1139pub fn writeSymtab(self: Object, elf_file: *Elf) void {
1183pub fn writeSymtab(self: *Object, elf_file: *Elf) void {
11401184 for (self.locals()) |local| {
11411185 const idx = local.outputSymtabIndex(elf_file) orelse continue;
11421186 const out_sym = &elf_file.symtab.items[idx];
......@@ -1147,7 +1191,7 @@ pub fn writeSymtab(self: Object, elf_file: *Elf) void {
11471191 }
11481192
11491193 for (self.globals(), self.symbols_resolver.items) |global, resolv| {
1150 const ref = elf_file.resolver.items[resolv];
1194 const ref = elf_file.resolver.values.items[resolv];
11511195 const ref_sym = elf_file.symbol(ref) orelse continue;
11521196 if (ref_sym.file(elf_file).?.index() != self.index) continue;
11531197 const idx = global.outputSymtabIndex(elf_file) orelse continue;
......@@ -1199,7 +1243,7 @@ fn locals(self: *Object) []Symbol {
11991243 return self.symbols.items[0..end];
12001244}
12011245
1202fn globals(self: *Object) []Symbol {
1246pub fn globals(self: *Object) []Symbol {
12031247 if (self.symbols.items.len == 0) return &[0]Symbol{};
12041248 assert(self.symbols.items.len >= self.symtab.items.len);
12051249 const start = self.first_global orelse self.symtab.items.len;
......@@ -1214,8 +1258,12 @@ pub fn resolveSymbol(self: Object, index: Symbol.Index, elf_file: *Elf) Elf.Ref
12141258 return elf_file.resolver.get(resolv).?;
12151259}
12161260
1217pub fn addSymbol(self: *Object, allocator: Allocator) !Symbol.Index {
1261fn addSymbol(self: *Object, allocator: Allocator) !Symbol.Index {
12181262 try self.symbols.ensureUnusedCapacity(allocator, 1);
1263 return self.addSymbolAssumeCapacity();
1264}
1265
1266fn addSymbolAssumeCapacity(self: *Object) Symbol.Index {
12191267 const index: Symbol.Index = @intCast(self.symbols.items.len);
12201268 self.symbols.appendAssumeCapacity(.{ .file_index = self.index });
12211269 return index;
......@@ -1430,15 +1478,14 @@ fn formatSymtab(
14301478 _ = unused_fmt_string;
14311479 _ = options;
14321480 const object = ctx.object;
1481 const elf_file = ctx.elf_file;
14331482 try writer.writeAll(" locals\n");
1434 for (object.locals()) |index| {
1435 const local = ctx.elf_file.symbol(index);
1436 try writer.print(" {}\n", .{local.fmt(ctx.elf_file)});
1483 for (object.locals()) |sym| {
1484 try writer.print(" {}\n", .{sym.fmt(elf_file)});
14371485 }
14381486 try writer.writeAll(" globals\n");
1439 for (object.globals()) |index| {
1440 const global = ctx.elf_file.symbol(index);
1441 try writer.print(" {}\n", .{global.fmt(ctx.elf_file)});
1487 for (object.globals()) |sym| {
1488 try writer.print(" {}\n", .{sym.fmt(elf_file)});
14421489 }
14431490}
14441491
src/link/Elf/SharedObject.zig+22-15
......@@ -286,8 +286,8 @@ pub fn markImportExports(self: *SharedObject, elf_file: *Elf) void {
286286 for (0..self.symbols.items.len) |i| {
287287 const ref = self.resolveSymbol(@intCast(i), elf_file);
288288 const ref_sym = elf_file.symbol(ref) orelse continue;
289 const ref_file = ref_sym.file(self).?;
290 const vis = @as(elf.STV, @enumFromInt(ref_sym.elfSym(self).st_other));
289 const ref_file = ref_sym.file(elf_file).?;
290 const vis = @as(elf.STV, @enumFromInt(ref_sym.elfSym(elf_file).st_other));
291291 if (ref_file != .shared_object and vis != .HIDDEN) ref_sym.flags.@"export" = true;
292292 }
293293}
......@@ -349,9 +349,12 @@ pub fn initSymbolAliases(self: *SharedObject, elf_file: *Elf) !void {
349349 assert(self.aliases == null);
350350
351351 const SortAlias = struct {
352 pub fn lessThan(ctx: *Elf, lhs: Symbol.Index, rhs: Symbol.Index) bool {
353 const lhs_sym = ctx.symbol(lhs).elfSym(ctx);
354 const rhs_sym = ctx.symbol(rhs).elfSym(ctx);
352 so: *SharedObject,
353 ef: *Elf,
354
355 pub fn lessThan(ctx: @This(), lhs: Symbol.Index, rhs: Symbol.Index) bool {
356 const lhs_sym = ctx.so.symbols.items[lhs].elfSym(ctx.ef);
357 const rhs_sym = ctx.so.symbols.items[rhs].elfSym(ctx.ef);
355358 return lhs_sym.st_value < rhs_sym.st_value;
356359 }
357360 };
......@@ -362,14 +365,14 @@ pub fn initSymbolAliases(self: *SharedObject, elf_file: *Elf) !void {
362365 defer aliases.deinit();
363366 try aliases.ensureTotalCapacityPrecise(self.symbols.items.len);
364367
365 for (self.symbols_resolvers.items, 0..) |resolv, index| {
368 for (self.symbols_resolver.items, 0..) |resolv, index| {
366369 const ref = elf_file.resolver.get(resolv).?;
367370 const ref_sym = elf_file.symbol(ref) orelse continue;
368371 if (ref_sym.file(elf_file).?.index() != self.index) continue;
369 aliases.appendAssumeCapacity(index);
372 aliases.appendAssumeCapacity(@intCast(index));
370373 }
371374
372 std.mem.sort(u32, aliases.items, elf_file, SortAlias.lessThan);
375 std.mem.sort(u32, aliases.items, SortAlias{ .so = self, .ef = elf_file }, SortAlias.lessThan);
373376
374377 self.aliases = aliases.moveToUnmanaged();
375378}
......@@ -377,16 +380,16 @@ pub fn initSymbolAliases(self: *SharedObject, elf_file: *Elf) !void {
377380pub fn symbolAliases(self: *SharedObject, index: u32, elf_file: *Elf) []const u32 {
378381 assert(self.aliases != null);
379382
380 const symbol = self.symbol(index).elfSym(elf_file);
383 const symbol = self.symbols.items[index].elfSym(elf_file);
381384 const aliases = self.aliases.?;
382385
383386 const start = for (aliases.items, 0..) |alias, i| {
384 const alias_sym = self.symbol(alias).elfSym(elf_file);
387 const alias_sym = self.symbols.items[alias].elfSym(elf_file);
385388 if (symbol.st_value == alias_sym.st_value) break i;
386389 } else aliases.items.len;
387390
388391 const end = for (aliases.items[start..], 0..) |alias, i| {
389 const alias_sym = self.symbol(alias).elfSym(elf_file);
392 const alias_sym = self.symbols.items[alias].elfSym(elf_file);
390393 if (symbol.st_value < alias_sym.st_value) break i + start;
391394 } else aliases.items.len;
392395
......@@ -403,8 +406,12 @@ pub fn resolveSymbol(self: SharedObject, index: Symbol.Index, elf_file: *Elf) El
403406 return elf_file.resolver.get(resolv).?;
404407}
405408
406pub fn addSymbol(self: *SharedObject, allocator: Allocator) !Symbol.Index {
409fn addSymbol(self: *SharedObject, allocator: Allocator) !Symbol.Index {
407410 try self.symbols.ensureUnusedCapacity(allocator, 1);
411 return self.addSymbolAssumeCapacity();
412}
413
414fn addSymbolAssumeCapacity(self: *SharedObject) Symbol.Index {
408415 const index: Symbol.Index = @intCast(self.symbols.items.len);
409416 self.symbols.appendAssumeCapacity(.{ .file_index = self.index });
410417 return index;
......@@ -486,10 +493,10 @@ fn formatSymtab(
486493 _ = unused_fmt_string;
487494 _ = options;
488495 const shared = ctx.shared;
496 const elf_file = ctx.elf_file;
489497 try writer.writeAll(" globals\n");
490 for (shared.symbols.items) |index| {
491 const global = ctx.elf_file.symbol(index);
492 try writer.print(" {}\n", .{global.fmt(ctx.elf_file)});
498 for (shared.symbols.items) |sym| {
499 try writer.print(" {}\n", .{sym.fmt(elf_file)});
493500 }
494501}
495502
src/link/Elf/Symbol.zig+8-3
......@@ -86,6 +86,7 @@ pub fn file(symbol: Symbol, elf_file: *Elf) ?File {
8686
8787pub fn elfSym(symbol: Symbol, elf_file: *Elf) elf.Elf64_Sym {
8888 return switch (symbol.file(elf_file).?) {
89 .zig_object => |x| x.symtab.items(.elf_sym)[symbol.esym_index],
8990 inline else => |x| x.symtab.items[symbol.esym_index],
9091 };
9192}
......@@ -261,7 +262,7 @@ const AddExtraOpts = struct {
261262 zig_got: ?u32 = null,
262263};
263264
264pub fn addExtra(symbol: *Symbol, opts: AddExtraOpts, elf_file: *Elf) !void {
265pub fn addExtra(symbol: *Symbol, opts: AddExtraOpts, elf_file: *Elf) void {
265266 var extras = symbol.extra(elf_file);
266267 inline for (@typeInfo(@TypeOf(opts)).Struct.fields) |field| {
267268 if (@field(opts, field.name)) |x| {
......@@ -272,11 +273,15 @@ pub fn addExtra(symbol: *Symbol, opts: AddExtraOpts, elf_file: *Elf) !void {
272273}
273274
274275pub fn extra(symbol: Symbol, elf_file: *Elf) Extra {
275 return elf_file.symbolExtra(symbol.extra_index);
276 return switch (symbol.file(elf_file).?) {
277 inline else => |x| x.symbolExtra(symbol.extra_index),
278 };
276279}
277280
278281pub fn setExtra(symbol: Symbol, extras: Extra, elf_file: *Elf) void {
279 elf_file.setSymbolExtra(symbol.extra_index, extras);
282 return switch (symbol.file(elf_file).?) {
283 inline else => |x| x.setSymbolExtra(symbol.extra_index, extras),
284 };
280285}
281286
282287pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {
src/link/Elf/ZigObject.zig+108-53
......@@ -89,19 +89,11 @@ pub fn init(self: *ZigObject, elf_file: *Elf) !void {
8989 try self.strtab.buffer.append(gpa, 0);
9090
9191 const name_off = try self.strtab.insert(gpa, self.path);
92 const symbol_index = try elf_file.addSymbol();
93 try self.local_symbols.append(gpa, symbol_index);
94 const symbol_ptr = elf_file.symbol(symbol_index);
95 symbol_ptr.file_index = self.index;
96 symbol_ptr.name_offset = name_off;
97 symbol_ptr.extra_index = try elf_file.addSymbolExtra(.{});
98
99 const esym_index = try self.addLocalEsym(gpa);
100 const esym = &self.local_esyms.items(.elf_sym)[esym_index];
101 esym.st_name = name_off;
92 const symbol_index = try self.newLocalSymbol(gpa, name_off);
93 const sym = self.symbol(symbol_index);
94 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
10295 esym.st_info = elf.STT_FILE;
10396 esym.st_shndx = elf.SHN_ABS;
104 symbol_ptr.esym_index = esym_index;
10597
10698 switch (comp.config.debug_format) {
10799 .strip => {},
......@@ -275,7 +267,7 @@ fn newSymbol(self: *ZigObject, allocator: Allocator, name_off: u32, st_bind: u4)
275267 const index = self.addSymbolAssumeCapacity();
276268 const sym = &self.symbols.items[index];
277269 sym.name_offset = name_off;
278 sym.extra = self.addSymbolExtraAssumeCapacity(.{});
270 sym.extra_index = self.addSymbolExtraAssumeCapacity(.{});
279271
280272 const esym_idx: u32 = @intCast(self.symtab.addOneAssumeCapacity());
281273 const esym = ElfSym{ .elf_sym = .{
......@@ -377,7 +369,7 @@ pub fn resolveSymbols(self: *ZigObject, elf_file: *Elf) !void {
377369 continue;
378370 }
379371
380 if (self.asFile().symbolRank(esym, !self.alive) < elf_file.symbol(gop.ref.*).?.symbolRank(elf_file)) {
372 if (self.asFile().symbolRank(esym, false) < elf_file.symbol(gop.ref.*).?.symbolRank(elf_file)) {
381373 gop.ref.* = .{ .index = @intCast(i | global_symbol_bit), .file = self.index };
382374 }
383375 }
......@@ -428,7 +420,7 @@ pub fn claimUnresolvedObject(self: ZigObject, elf_file: *Elf) void {
428420 global.file_index = self.index;
429421
430422 const idx = self.symbols_resolver.items[i];
431 elf_file.resolver.items[idx - 1] = .{ .index = @intCast(i | global_symbol_bit), .file = self.index };
423 elf_file.resolver.values.items[idx - 1] = .{ .index = @intCast(i | global_symbol_bit), .file = self.index };
432424 }
433425}
434426
......@@ -450,6 +442,64 @@ pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void {
450442 }
451443}
452444
445pub fn createSymbolIndirection(self: *ZigObject, elf_file: *Elf) !void {
446 const impl = struct {
447 fn impl(sym: *Symbol, ref: Elf.Ref, ef: *Elf) !void {
448 if (!sym.isLocal(ef) and !sym.flags.has_dynamic) {
449 log.debug("'{s}' is non-local", .{sym.name(ef)});
450 try ef.dynsym.addSymbol(ref, ef);
451 }
452 if (sym.flags.needs_got) {
453 log.debug("'{s}' needs GOT", .{sym.name(ef)});
454 _ = try ef.got.addGotSymbol(ref, ef);
455 }
456 if (sym.flags.needs_plt) {
457 if (sym.flags.is_canonical) {
458 log.debug("'{s}' needs CPLT", .{sym.name(ef)});
459 sym.flags.@"export" = true;
460 try ef.plt.addSymbol(ref, ef);
461 } else if (sym.flags.needs_got) {
462 log.debug("'{s}' needs PLTGOT", .{sym.name(ef)});
463 try ef.plt_got.addSymbol(ref, ef);
464 } else {
465 log.debug("'{s}' needs PLT", .{sym.name(ef)});
466 try ef.plt.addSymbol(ref, ef);
467 }
468 }
469 if (sym.flags.needs_copy_rel and !sym.flags.has_copy_rel) {
470 log.debug("'{s}' needs COPYREL", .{sym.name(ef)});
471 try ef.copy_rel.addSymbol(ref, ef);
472 }
473 if (sym.flags.needs_tlsgd) {
474 log.debug("'{s}' needs TLSGD", .{sym.name(ef)});
475 try ef.got.addTlsGdSymbol(ref, ef);
476 }
477 if (sym.flags.needs_gottp) {
478 log.debug("'{s}' needs GOTTP", .{sym.name(ef)});
479 try ef.got.addGotTpSymbol(ref, ef);
480 }
481 if (sym.flags.needs_tlsdesc) {
482 log.debug("'{s}' needs TLSDESC", .{sym.name(ef)});
483 try ef.got.addTlsDescSymbol(ref, ef);
484 }
485 }
486 }.impl;
487 for (self.local_symbols.items, 0..) |index, i| {
488 const sym = &self.symbols.items[index];
489 const ref = self.resolveSymbol(@intCast(i), elf_file);
490 const ref_sym = elf_file.symbol(ref) orelse continue;
491 if (ref_sym.file(elf_file).?.index() != self.index) continue;
492 try impl(sym, ref, elf_file);
493 }
494 for (self.global_symbols.items, 0..) |index, i| {
495 const sym = &self.symbols.items[index];
496 const ref = self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file);
497 const ref_sym = elf_file.symbol(ref) orelse continue;
498 if (ref_sym.file(elf_file).?.index() != self.index) continue;
499 try impl(sym, ref, elf_file);
500 }
501}
502
453503pub fn markLive(self: *ZigObject, elf_file: *Elf) void {
454504 for (self.global_symbols.items, 0..) |index, i| {
455505 const global = self.symbols.items[index];
......@@ -468,7 +518,7 @@ pub fn markLive(self: *ZigObject, elf_file: *Elf) void {
468518 }
469519}
470520
471pub fn markImportsExports(self: *Object, elf_file: *Elf) void {
521pub fn markImportsExports(self: *ZigObject, elf_file: *Elf) void {
472522 for (0..self.global_symbols.items.len) |i| {
473523 const ref = self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file);
474524 const sym = elf_file.symbol(ref) orelse continue;
......@@ -604,7 +654,7 @@ pub fn updateSymtabSize(self: *ZigObject, elf_file: *Elf) !void {
604654
605655 for (self.global_symbols.items, self.symbols_resolver.items) |index, resolv| {
606656 const global = &self.symbols.items[index];
607 const ref = elf_file.resolver.items[resolv];
657 const ref = elf_file.resolver.values.items[resolv];
608658 const ref_sym = elf_file.symbol(ref) orelse continue;
609659 if (ref_sym.file(elf_file).?.index() != self.index) continue;
610660 if (global.atom(elf_file)) |atom_ptr| if (!atom_ptr.alive) continue;
......@@ -633,7 +683,7 @@ pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void {
633683
634684 for (self.global_symbols.items, self.symbols_resolver.items) |index, resolv| {
635685 const global = self.symbols.items[index];
636 const ref = elf_file.resolver.items[resolv];
686 const ref = elf_file.resolver.values.items[resolv];
637687 const ref_sym = elf_file.symbol(ref) orelse continue;
638688 if (ref_sym.file(elf_file).?.index() != self.index) continue;
639689 const idx = global.outputSymtabIndex(elf_file) orelse continue;
......@@ -678,13 +728,13 @@ pub fn getDeclVAddr(
678728 reloc_info: link.File.RelocInfo,
679729) !u64 {
680730 const this_sym_index = try self.getOrCreateMetadataForDecl(elf_file, decl_index);
681 const this_sym = elf_file.symbol(this_sym_index);
731 const this_sym = self.symbol(this_sym_index);
682732 const vaddr = this_sym.address(.{}, elf_file);
683 const parent_atom = elf_file.symbol(reloc_info.parent_atom_index).atom(elf_file).?;
733 const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?;
684734 const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);
685735 try parent_atom.addReloc(elf_file, .{
686736 .r_offset = reloc_info.offset,
687 .r_info = (@as(u64, @intCast(this_sym.esym_index)) << 32) | r_type,
737 .r_info = (@as(u64, @intCast(this_sym_index)) << 32) | r_type,
688738 .r_addend = reloc_info.addend,
689739 });
690740 return @intCast(vaddr);
......@@ -697,13 +747,13 @@ pub fn getAnonDeclVAddr(
697747 reloc_info: link.File.RelocInfo,
698748) !u64 {
699749 const sym_index = self.anon_decls.get(decl_val).?.symbol_index;
700 const sym = elf_file.symbol(sym_index);
750 const sym = self.symbol(sym_index);
701751 const vaddr = sym.address(.{}, elf_file);
702 const parent_atom = elf_file.symbol(reloc_info.parent_atom_index).atom(elf_file).?;
752 const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?;
703753 const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);
704754 try parent_atom.addReloc(elf_file, .{
705755 .r_offset = reloc_info.offset,
706 .r_info = (@as(u64, @intCast(sym.esym_index)) << 32) | r_type,
756 .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
707757 .r_addend = reloc_info.addend,
708758 });
709759 return @intCast(vaddr);
......@@ -725,7 +775,7 @@ pub fn lowerAnonDecl(
725775 else => explicit_alignment,
726776 };
727777 if (self.anon_decls.get(decl_val)) |metadata| {
728 const existing_alignment = elf_file.symbol(metadata.symbol_index).atom(elf_file).?.alignment;
778 const existing_alignment = self.symbol(metadata.symbol_index).atom(elf_file).?.alignment;
729779 if (decl_alignment.order(existing_alignment).compare(.lte))
730780 return .ok;
731781 }
......@@ -811,11 +861,10 @@ fn freeUnnamedConsts(self: *ZigObject, elf_file: *Elf, decl_index: InternPool.De
811861}
812862
813863fn freeDeclMetadata(self: *ZigObject, elf_file: *Elf, sym_index: Symbol.Index) void {
814 _ = self;
815 const sym = elf_file.symbol(sym_index);
864 const sym = self.symbol(sym_index);
816865 sym.atom(elf_file).?.free(elf_file);
817866 log.debug("adding %{d} to local symbols free list", .{sym_index});
818 elf_file.symbols.items[sym_index] = .{};
867 self.symbols.items[sym_index] = .{};
819868 // TODO free GOT entry here
820869}
821870
......@@ -940,8 +989,8 @@ fn updateDeclCode(
940989 target_util.minFunctionAlignment(mod.getTarget()),
941990 );
942991
943 const sym = elf_file.symbol(sym_index);
944 const esym = &self.local_esyms.items(.elf_sym)[sym.esym_index];
992 const sym = self.symbol(sym_index);
993 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
945994 const atom_ptr = sym.atom(elf_file).?;
946995 const name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
947996
......@@ -1038,8 +1087,8 @@ fn updateTlv(
10381087
10391088 const required_alignment = decl.getAlignment(pt);
10401089
1041 const sym = elf_file.symbol(sym_index);
1042 const esym = &self.local_esyms.items(.elf_sym)[sym.esym_index];
1090 const sym = self.symbol(sym_index);
1091 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
10431092 const atom_ptr = sym.atom(elf_file).?;
10441093 const name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
10451094
......@@ -1264,9 +1313,9 @@ fn updateLazySymbol(
12641313 .code => elf_file.zig_text_section_index.?,
12651314 .const_data => elf_file.zig_data_rel_ro_section_index.?,
12661315 };
1267 const local_sym = elf_file.symbol(symbol_index);
1316 const local_sym = self.symbol(symbol_index);
12681317 local_sym.name_offset = name_str_index;
1269 const local_esym = &self.local_esyms.items(.elf_sym)[local_sym.esym_index];
1318 const local_esym = &self.symtab.items(.elf_sym)[local_sym.esym_index];
12701319 local_esym.st_name = name_str_index;
12711320 local_esym.st_info |= elf.STT_OBJECT;
12721321 local_esym.st_size = code.len;
......@@ -1372,7 +1421,7 @@ fn lowerConst(
13721421 };
13731422
13741423 const local_sym = self.symbol(sym_index);
1375 const local_esym = local_sym.elfSym(elf_file);
1424 const local_esym = &self.symtab.items(.elf_sym)[local_sym.esym_index];
13761425 local_esym.st_info |= elf.STT_OBJECT;
13771426 local_esym.st_size = code.len;
13781427 const atom_ptr = local_sym.atom(elf_file).?;
......@@ -1473,9 +1522,9 @@ pub fn updateExports(
14731522 const global_sym = self.symbol(global_sym_index);
14741523 global_sym.value = value;
14751524 global_sym.flags.weak = exp.opts.linkage == .weak;
1476 global_sym.version_index = elf_file.default_version_index;
1525 global_sym.version_index = elf_file.default_sym_version;
14771526 global_sym.ref = .{ .index = esym_shndx, .file = self.index };
1478 const global_esym = global_sym.elfSym(elf_file);
1527 const global_esym = &self.symtab.items(.elf_sym)[global_sym.esym_index];
14791528 global_esym.st_value = @intCast(value);
14801529 global_esym.st_shndx = esym.st_shndx;
14811530 global_esym.st_info = (stb_bits << 4) | stt_bits;
......@@ -1517,16 +1566,16 @@ pub fn deleteExport(
15171566 const exp_name = name.toSlice(&mod.intern_pool);
15181567 const esym_index = metadata.@"export"(self, exp_name) orelse return;
15191568 log.debug("deleting export '{s}'", .{exp_name});
1520 const esym = &self.global_esyms.items(.elf_sym)[esym_index.*];
1569 const esym = &self.symtab.items(.elf_sym)[esym_index.*];
15211570 _ = self.globals_lookup.remove(esym.st_name);
1522 const sym_index = elf_file.resolver.get(esym.st_name).?;
1523 const sym = elf_file.symbol(sym_index);
1524 if (sym.file_index == self.index) {
1525 _ = elf_file.resolver.swapRemove(esym.st_name);
1526 sym.* = .{};
1527 }
1571 // const sym_index = elf_file.resolver.get(esym.st_name).?;
1572 // const sym = elf_file.symbol(sym_index);
1573 // if (sym.file_index == self.index) {
1574 // _ = elf_file.resolver.swapRemove(esym.st_name);
1575 // sym.* = .{};
1576 // }
15281577 esym.* = Elf.null_sym;
1529 self.global_esyms.items(.shndx)[esym_index.*] = elf.SHN_UNDEF;
1578 self.symtab.items(.shndx)[esym_index.*] = elf.SHN_UNDEF;
15301579}
15311580
15321581pub fn getGlobalSymbol(self: *ZigObject, elf_file: *Elf, name: []const u8, lib_name: ?[]const u8) !u32 {
......@@ -1535,7 +1584,7 @@ pub fn getGlobalSymbol(self: *ZigObject, elf_file: *Elf, name: []const u8, lib_n
15351584 const off = try self.strtab.insert(gpa, name);
15361585 const lookup_gop = try self.globals_lookup.getOrPut(gpa, off);
15371586 if (!lookup_gop.found_existing) {
1538 lookup_gop.value_ptr.* = try self.newSymbol(gpa, off);
1587 lookup_gop.value_ptr.* = try self.newGlobalSymbol(gpa, off);
15391588 }
15401589 return lookup_gop.value_ptr.*;
15411590}
......@@ -1636,8 +1685,12 @@ pub fn resolveSymbol(self: ZigObject, index: Symbol.Index, elf_file: *Elf) Elf.R
16361685 return .{ .index = index, .file = self.index };
16371686}
16381687
1639pub fn addSymbol(self: *ZigObject, allocator: Allocator) !Symbol.Index {
1688fn addSymbol(self: *ZigObject, allocator: Allocator) !Symbol.Index {
16401689 try self.symbols.ensureUnusedCapacity(allocator, 1);
1690 return self.addSymbolAssumeCapacity();
1691}
1692
1693fn addSymbolAssumeCapacity(self: *ZigObject) Symbol.Index {
16411694 const index: Symbol.Index = @intCast(self.symbols.items.len);
16421695 self.symbols.appendAssumeCapacity(.{ .file_index = self.index });
16431696 return index;
......@@ -1705,15 +1758,17 @@ fn formatSymtab(
17051758) !void {
17061759 _ = unused_fmt_string;
17071760 _ = options;
1761 const self = ctx.self;
1762 const elf_file = ctx.elf_file;
17081763 try writer.writeAll(" locals\n");
1709 for (ctx.self.locals()) |index| {
1710 const local = ctx.elf_file.symbol(index);
1711 try writer.print(" {}\n", .{local.fmt(ctx.elf_file)});
1764 for (self.local_symbols.items) |index| {
1765 const local = self.symbols.items[index];
1766 try writer.print(" {}\n", .{local.fmt(elf_file)});
17121767 }
17131768 try writer.writeAll(" globals\n");
1714 for (ctx.self.globals()) |index| {
1715 const global = ctx.elf_file.symbol(index);
1716 try writer.print(" {}\n", .{global.fmt(ctx.elf_file)});
1769 for (ctx.self.global_symbols.items) |index| {
1770 const global = self.symbols.items[index];
1771 try writer.print(" {}\n", .{global.fmt(elf_file)});
17171772 }
17181773}
17191774
......@@ -1759,7 +1814,7 @@ const DeclMetadata = struct {
17591814
17601815 fn @"export"(m: DeclMetadata, zo: *ZigObject, name: []const u8) ?*u32 {
17611816 for (m.exports.items) |*exp| {
1762 const exp_name = zo.getString(zo.symbol(exp.*).name_off);
1817 const exp_name = zo.getString(zo.symbol(exp.*).name_offset);
17631818 if (mem.eql(u8, name, exp_name)) return exp;
17641819 }
17651820 return null;
src/link/Elf/eh_frame.zig+10-5
......@@ -339,7 +339,8 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
339339 const contents = cie.data(elf_file);
340340
341341 for (cie.relocs(elf_file)) |rel| {
342 const sym = elf_file.symbol(object.symbols.items[rel.r_sym()]);
342 const ref = object.resolveSymbol(rel.r_sym(), elf_file);
343 const sym = elf_file.symbol(ref).?;
343344 resolveReloc(cie, sym, rel, elf_file, contents) catch |err| switch (err) {
344345 error.RelocFailure => has_reloc_errors = true,
345346 else => |e| return e,
......@@ -366,7 +367,8 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
366367 );
367368
368369 for (fde.relocs(elf_file)) |rel| {
369 const sym = elf_file.symbol(object.symbols.items[rel.r_sym()]);
370 const ref = object.resolveSymbol(rel.r_sym(), elf_file);
371 const sym = elf_file.symbol(ref).?;
370372 resolveReloc(fde, sym, rel, elf_file, contents) catch |err| switch (err) {
371373 error.RelocFailure => has_reloc_errors = true,
372374 else => |e| return e,
......@@ -452,7 +454,8 @@ pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void {
452454 for (object.cies.items) |cie| {
453455 if (!cie.alive) continue;
454456 for (cie.relocs(elf_file)) |rel| {
455 const sym = elf_file.symbol(object.symbols.items[rel.r_sym()]);
457 const ref = object.resolveSymbol(rel.r_sym(), elf_file);
458 const sym = elf_file.symbol(ref).?;
456459 const out_rel = emitReloc(elf_file, cie, sym, rel);
457460 try writer.writeStruct(out_rel);
458461 }
......@@ -461,7 +464,8 @@ pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void {
461464 for (object.fdes.items) |fde| {
462465 if (!fde.alive) continue;
463466 for (fde.relocs(elf_file)) |rel| {
464 const sym = elf_file.symbol(object.symbols.items[rel.r_sym()]);
467 const ref = object.resolveSymbol(rel.r_sym(), elf_file);
468 const sym = elf_file.symbol(ref).?;
465469 const out_rel = emitReloc(elf_file, fde, sym, rel);
466470 try writer.writeStruct(out_rel);
467471 }
......@@ -513,7 +517,8 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void {
513517 const relocs = fde.relocs(elf_file);
514518 assert(relocs.len > 0); // Should this be an error? Things are completely broken anyhow if this trips...
515519 const rel = relocs[0];
516 const sym = elf_file.symbol(object.symbols.items[rel.r_sym()]);
520 const ref = object.resolveSymbol(rel.r_sym(), elf_file);
521 const sym = elf_file.symbol(ref).?;
517522 const P = @as(i64, @intCast(fde.address(elf_file)));
518523 const S = @as(i64, @intCast(sym.address(.{}, elf_file)));
519524 const A = rel.r_addend;
src/link/Elf/file.zig+18-5
......@@ -61,10 +61,10 @@ pub const File = union(enum) {
6161 return (@as(u32, base) << 24) + file.index();
6262 }
6363
64 pub fn resolveSymbols(file: File, elf_file: *Elf) void {
65 switch (file) {
64 pub fn resolveSymbols(file: File, elf_file: *Elf) !void {
65 return switch (file) {
6666 inline else => |x| x.resolveSymbols(elf_file),
67 }
67 };
6868 }
6969
7070 pub fn resetGlobals(file: File, elf_file: *Elf) void {
......@@ -100,6 +100,13 @@ pub const File = union(enum) {
100100 }
101101 }
102102
103 pub fn createSymbolIndirection(file: File, elf_file: *Elf) !void {
104 return switch (file) {
105 .linker_defined, .shared_object => unreachable,
106 inline else => |x| x.createSymbolIndirection(elf_file),
107 };
108 }
109
103110 pub fn atom(file: File, atom_index: Atom.Index) ?*Atom {
104111 return switch (file) {
105112 .shared_object => unreachable,
......@@ -146,10 +153,16 @@ pub const File = union(enum) {
146153 };
147154 }
148155
149 pub fn symbol(file: File, ind: Symbol.Index) Symbol.Index {
156 pub fn resolveSymbol(file: File, ind: Symbol.Index, elf_file: *Elf) Elf.Ref {
157 return switch (file) {
158 inline else => |x| x.resolveSymbol(ind, elf_file),
159 };
160 }
161
162 pub fn symbol(file: File, ind: Symbol.Index) *Symbol {
150163 return switch (file) {
151164 .zig_object => |x| x.symbol(ind),
152 inline else => |x| x.symbols.items[ind],
165 inline else => |x| &x.symbols.items[ind],
153166 };
154167 }
155168
src/link/Elf/gc.zig+81-58
......@@ -1,71 +1,84 @@
11pub fn gcAtoms(elf_file: *Elf) !void {
22 const comp = elf_file.base.comp;
33 const gpa = comp.gpa;
4 const num_files = elf_file.objects.items.len + @intFromBool(elf_file.zig_object_index != null);
5 var files = try std.ArrayList(File.Index).initCapacity(gpa, num_files);
6 defer files.deinit();
7 if (elf_file.zig_object_index) |index| files.appendAssumeCapacity(index);
8 for (elf_file.objects.items) |index| files.appendAssumeCapacity(index);
9
104 var roots = std.ArrayList(*Atom).init(gpa);
115 defer roots.deinit();
12 try collectRoots(&roots, files.items, elf_file);
13
6 try collectRoots(&roots, elf_file);
147 mark(roots, elf_file);
15 prune(files.items, elf_file);
8 prune(elf_file);
169}
1710
18fn collectRoots(roots: *std.ArrayList(*Atom), files: []const File.Index, elf_file: *Elf) !void {
11fn collectRoots(roots: *std.ArrayList(*Atom), elf_file: *Elf) !void {
1912 if (elf_file.linkerDefinedPtr()) |obj| {
20 if (obj.entry_index) |index| {
21 const global = elf_file.symbol(index);
22 try markSymbol(global, roots, elf_file);
13 if (obj.entrySymbol(elf_file)) |sym| {
14 try markSymbol(sym, roots, elf_file);
2315 }
2416 }
2517
26 for (files) |index| {
27 for (elf_file.file(index).?.globals()) |global_index| {
28 const global = elf_file.symbol(global_index);
29 if (global.file(elf_file)) |file| {
30 if (file.index() == index and global.flags.@"export")
31 try markSymbol(global, roots, elf_file);
18 if (elf_file.zigObjectPtr()) |zo| {
19 for (0..zo.global_symbols.items.len) |i| {
20 const ref = zo.resolveSymbol(@intCast(i | ZigObject.global_symbol_bit), elf_file);
21 const sym = elf_file.symbol(ref) orelse continue;
22 if (sym.file(elf_file).?.index() != zo.index) continue;
23 if (sym.flags.@"export") {
24 try markSymbol(sym, roots, elf_file);
3225 }
3326 }
3427 }
3528
36 for (files) |index| {
37 const file = elf_file.file(index).?;
38
39 for (file.atoms()) |atom_index| {
40 const atom = file.atom(atom_index) orelse continue;
41 if (!atom.alive) continue;
42
43 const shdr = atom.inputShdr(elf_file);
44 const name = atom.name(elf_file);
45 const is_gc_root = blk: {
46 if (shdr.sh_flags & elf.SHF_GNU_RETAIN != 0) break :blk true;
47 if (shdr.sh_type == elf.SHT_NOTE) break :blk true;
48 if (shdr.sh_type == elf.SHT_PREINIT_ARRAY) break :blk true;
49 if (shdr.sh_type == elf.SHT_INIT_ARRAY) break :blk true;
50 if (shdr.sh_type == elf.SHT_FINI_ARRAY) break :blk true;
51 if (mem.startsWith(u8, name, ".ctors")) break :blk true;
52 if (mem.startsWith(u8, name, ".dtors")) break :blk true;
53 if (mem.startsWith(u8, name, ".init")) break :blk true;
54 if (mem.startsWith(u8, name, ".fini")) break :blk true;
55 if (Elf.isCIdentifier(name)) break :blk true;
56 break :blk false;
57 };
58 if (is_gc_root and markAtom(atom)) try roots.append(atom);
59 if (shdr.sh_flags & elf.SHF_ALLOC == 0) atom.visited = true;
29 for (elf_file.objects.items) |index| {
30 const object = elf_file.file(index).?.object;
31 for (0..object.globals().len) |i| {
32 const ref = object.resolveSymbol(@intCast(i), elf_file);
33 const sym = elf_file.symbol(ref) orelse continue;
34 if (sym.file(elf_file).?.index() != object.index) continue;
35 if (sym.flags.@"export") {
36 try markSymbol(sym, roots, elf_file);
37 }
6038 }
39 }
6140
62 // Mark every atom referenced by CIE as alive.
63 for (file.cies()) |cie| {
64 for (cie.relocs(elf_file)) |rel| {
65 const sym = elf_file.symbol(file.symbol(rel.r_sym()));
66 try markSymbol(sym, roots, elf_file);
41 const atomRoots = struct {
42 fn atomRoots(file: File, rs: anytype, ef: *Elf) !void {
43 for (file.atoms()) |atom_index| {
44 const atom = file.atom(atom_index) orelse continue;
45 if (!atom.alive) continue;
46
47 const shdr = atom.inputShdr(ef);
48 const name = atom.name(ef);
49 const is_gc_root = blk: {
50 if (shdr.sh_flags & elf.SHF_GNU_RETAIN != 0) break :blk true;
51 if (shdr.sh_type == elf.SHT_NOTE) break :blk true;
52 if (shdr.sh_type == elf.SHT_PREINIT_ARRAY) break :blk true;
53 if (shdr.sh_type == elf.SHT_INIT_ARRAY) break :blk true;
54 if (shdr.sh_type == elf.SHT_FINI_ARRAY) break :blk true;
55 if (mem.startsWith(u8, name, ".ctors")) break :blk true;
56 if (mem.startsWith(u8, name, ".dtors")) break :blk true;
57 if (mem.startsWith(u8, name, ".init")) break :blk true;
58 if (mem.startsWith(u8, name, ".fini")) break :blk true;
59 if (Elf.isCIdentifier(name)) break :blk true;
60 break :blk false;
61 };
62 if (is_gc_root and markAtom(atom)) try rs.append(atom);
63 if (shdr.sh_flags & elf.SHF_ALLOC == 0) atom.visited = true;
64 }
65
66 // Mark every atom referenced by CIE as alive.
67 for (file.cies()) |cie| {
68 for (cie.relocs(ef)) |rel| {
69 const ref = file.resolveSymbol(rel.r_sym(), ef);
70 const sym = ef.symbol(ref) orelse continue;
71 try markSymbol(sym, rs, ef);
72 }
6773 }
6874 }
75 }.atomRoots;
76
77 if (elf_file.zigObjectPtr()) |zo| {
78 try atomRoots(zo.asFile(), roots, elf_file);
79 }
80 for (elf_file.objects.items) |index| {
81 try atomRoots(elf_file.file(index).?, roots, elf_file);
6982 }
7083}
7184
......@@ -92,7 +105,8 @@ fn markLive(atom: *Atom, elf_file: *Elf) void {
92105
93106 for (atom.fdes(elf_file)) |fde| {
94107 for (fde.relocs(elf_file)[1..]) |rel| {
95 const target_sym = elf_file.symbol(file.symbol(rel.r_sym()));
108 const ref = file.resolveSymbol(rel.r_sym(), elf_file);
109 const target_sym = elf_file.symbol(ref) orelse continue;
96110 const target_atom = target_sym.atom(elf_file) orelse continue;
97111 target_atom.alive = true;
98112 gc_track_live_log.debug("{}marking live atom({d})", .{ track_live_level, target_atom.atom_index });
......@@ -101,7 +115,8 @@ fn markLive(atom: *Atom, elf_file: *Elf) void {
101115 }
102116
103117 for (atom.relocs(elf_file)) |rel| {
104 const target_sym = elf_file.symbol(file.symbol(rel.r_sym()));
118 const ref = file.resolveSymbol(rel.r_sym(), elf_file);
119 const target_sym = elf_file.symbol(ref) orelse continue;
105120 if (target_sym.mergeSubsection(elf_file)) |msub| {
106121 msub.alive = true;
107122 continue;
......@@ -120,16 +135,23 @@ fn mark(roots: std.ArrayList(*Atom), elf_file: *Elf) void {
120135 }
121136}
122137
123fn prune(files: []const File.Index, elf_file: *Elf) void {
124 for (files) |index| {
125 const file = elf_file.file(index).?;
126 for (file.atoms()) |atom_index| {
127 const atom = file.atom(atom_index) orelse continue;
128 if (atom.alive and !atom.visited) {
129 atom.alive = false;
130 atom.markFdesDead(elf_file);
138fn prune(elf_file: *Elf) void {
139 const pruneInFile = struct {
140 fn pruneInFile(file: File, ef: *Elf) void {
141 for (file.atoms()) |atom_index| {
142 const atom = file.atom(atom_index) orelse continue;
143 if (atom.alive and !atom.visited) {
144 atom.alive = false;
145 atom.markFdesDead(ef);
146 }
131147 }
132148 }
149 }.pruneInFile;
150 if (elf_file.zigObjectPtr()) |zo| {
151 pruneInFile(zo.asFile(), elf_file);
152 }
153 for (elf_file.objects.items) |index| {
154 pruneInFile(elf_file.file(index).?, elf_file);
133155 }
134156}
135157
......@@ -181,3 +203,4 @@ const Atom = @import("Atom.zig");
181203const Elf = @import("../Elf.zig");
182204const File = @import("file.zig").File;
183205const Symbol = @import("Symbol.zig");
206const ZigObject = @import("ZigObject.zig");
src/link/Elf/relocatable.zig+2-2
......@@ -37,7 +37,7 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation, module_obj_path: ?[]co
3737
3838 // First, we flush relocatable object file generated with our backends.
3939 if (elf_file.zigObjectPtr()) |zig_object| {
40 zig_object.resolveSymbols(elf_file);
40 try zig_object.resolveSymbols(elf_file);
4141 try elf_file.addCommentString();
4242 try elf_file.finalizeMergeSections();
4343 zig_object.claimUnresolvedObject(elf_file);
......@@ -383,7 +383,7 @@ fn updateComdatGroupsSizes(elf_file: *Elf) void {
383383 shdr.sh_size = cg.size(elf_file);
384384 shdr.sh_link = elf_file.symtab_section_index.?;
385385
386 const sym = elf_file.symbol(cg.symbol(elf_file));
386 const sym = cg.symbol(elf_file);
387387 shdr.sh_info = sym.outputSymtabIndex(elf_file) orelse
388388 elf_file.sectionSymbolOutputSymtabIndex(sym.outputShndx(elf_file).?);
389389 }
src/link/Elf/synthetic_sections.zig+125-130
......@@ -251,15 +251,16 @@ pub const ZigGotSection = struct {
251251 pub fn addSymbol(zig_got: *ZigGotSection, sym_index: Symbol.Index, elf_file: *Elf) !Index {
252252 const comp = elf_file.base.comp;
253253 const gpa = comp.gpa;
254 const zo = elf_file.zigObjectPtr().?;
254255 const index = try zig_got.allocateEntry(gpa);
255256 const entry = &zig_got.entries.items[index];
256257 entry.* = sym_index;
257 const symbol = elf_file.symbol(sym_index);
258 const symbol = zo.symbol(sym_index);
258259 symbol.flags.has_zig_got = true;
259260 if (elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) {
260261 zig_got.flags.needs_rela = true;
261262 }
262 try symbol.addExtra(.{ .zig_got = index }, elf_file);
263 symbol.addExtra(.{ .zig_got = index }, elf_file);
263264 return index;
264265 }
265266
......@@ -282,6 +283,7 @@ pub const ZigGotSection = struct {
282283 }
283284
284285 pub fn writeOne(zig_got: *ZigGotSection, elf_file: *Elf, index: Index) !void {
286 const zo = elf_file.zigObjectPtr().?;
285287 if (zig_got.flags.dirty) {
286288 const needed_size = zig_got.size(elf_file);
287289 try elf_file.growAllocSection(elf_file.zig_got_section_index.?, needed_size);
......@@ -293,7 +295,7 @@ pub const ZigGotSection = struct {
293295 const off = zig_got.entryOffset(index, elf_file);
294296 const vaddr: u64 = @intCast(zig_got.entryAddress(index, elf_file));
295297 const entry = zig_got.entries.items[index];
296 const value = elf_file.symbol(entry).address(.{}, elf_file);
298 const value = zo.symbol(entry).address(.{}, elf_file);
297299 switch (entry_size) {
298300 2 => {
299301 var buf: [2]u8 = undefined;
......@@ -336,8 +338,9 @@ pub const ZigGotSection = struct {
336338 }
337339
338340 pub fn writeAll(zig_got: ZigGotSection, elf_file: *Elf, writer: anytype) !void {
341 const zo = elf_file.zigObjectPtr().?;
339342 for (zig_got.entries.items) |entry| {
340 const symbol = elf_file.symbol(entry);
343 const symbol = zo.symbol(entry);
341344 const value = symbol.address(.{ .plt = false }, elf_file);
342345 try writeInt(value, elf_file, writer);
343346 }
......@@ -351,9 +354,10 @@ pub const ZigGotSection = struct {
351354 const comp = elf_file.base.comp;
352355 const gpa = comp.gpa;
353356 const cpu_arch = elf_file.getTarget().cpu.arch;
357 const zo = elf_file.zigObjectPtr().?;
354358 try elf_file.rela_dyn.ensureUnusedCapacity(gpa, zig_got.numRela());
355359 for (zig_got.entries.items) |entry| {
356 const symbol = elf_file.symbol(entry);
360 const symbol = zo.symbol(entry);
357361 const offset = symbol.zigGotAddress(elf_file);
358362 elf_file.addRelaDynAssumeCapacity(.{
359363 .offset = @intCast(offset),
......@@ -364,16 +368,18 @@ pub const ZigGotSection = struct {
364368 }
365369
366370 pub fn updateSymtabSize(zig_got: *ZigGotSection, elf_file: *Elf) void {
371 const zo = elf_file.zigObjectPtr().?;
367372 zig_got.output_symtab_ctx.nlocals = @as(u32, @intCast(zig_got.entries.items.len));
368373 for (zig_got.entries.items) |entry| {
369 const name = elf_file.symbol(entry).name(elf_file);
374 const name = zo.symbol(entry).name(elf_file);
370375 zig_got.output_symtab_ctx.strsize += @as(u32, @intCast(name.len + "$ziggot".len)) + 1;
371376 }
372377 }
373378
374379 pub fn writeSymtab(zig_got: ZigGotSection, elf_file: *Elf) void {
380 const zo = elf_file.zigObjectPtr().?;
375381 for (zig_got.entries.items, zig_got.output_symtab_ctx.ilocal.., 0..) |entry, ilocal, index| {
376 const symbol = elf_file.symbol(entry);
382 const symbol = zo.symbol(entry);
377383 const symbol_name = symbol.name(elf_file);
378384 const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
379385 elf_file.strtab.appendSliceAssumeCapacity(symbol_name);
......@@ -409,15 +415,18 @@ pub const ZigGotSection = struct {
409415 ) !void {
410416 _ = options;
411417 _ = unused_fmt_string;
418 const zig_got = ctx.zig_got;
419 const elf_file = ctx.elf_file;
420 const zo = elf_file.zigObjectPtr().?;
412421 try writer.writeAll(".zig.got\n");
413 for (ctx.zig_got.entries.items, 0..) |entry, index| {
414 const symbol = ctx.elf_file.symbol(entry);
422 for (zig_got.entries.items, 0..) |entry, index| {
423 const symbol = zo.symbol(entry);
415424 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{
416425 index,
417 ctx.zig_got.entryAddress(@intCast(index), ctx.elf_file),
426 zig_got.entryAddress(@intCast(index), elf_file),
418427 entry,
419 symbol.address(.{}, ctx.elf_file),
420 symbol.name(ctx.elf_file),
428 symbol.address(.{}, elf_file),
429 symbol.name(elf_file),
421430 });
422431 }
423432 }
......@@ -446,7 +455,7 @@ pub const GotSection = struct {
446455
447456 const Entry = struct {
448457 tag: Tag,
449 symbol_index: Symbol.Index,
458 ref: Elf.Ref,
450459 cell_index: Index,
451460
452461 /// Returns how many indexes in the GOT this entry uses.
......@@ -477,25 +486,25 @@ pub const GotSection = struct {
477486 const last = got.entries.items[index - 1];
478487 break :blk last.cell_index + @as(Index, @intCast(last.len()));
479488 } else 0;
480 entry.* = .{ .tag = undefined, .symbol_index = undefined, .cell_index = cell_index };
489 entry.* = .{ .tag = undefined, .ref = undefined, .cell_index = cell_index };
481490 return index;
482491 }
483492
484 pub fn addGotSymbol(got: *GotSection, sym_index: Symbol.Index, elf_file: *Elf) !Index {
493 pub fn addGotSymbol(got: *GotSection, ref: Elf.Ref, elf_file: *Elf) !Index {
485494 const comp = elf_file.base.comp;
486495 const gpa = comp.gpa;
487496 const index = try got.allocateEntry(gpa);
488497 const entry = &got.entries.items[index];
489498 entry.tag = .got;
490 entry.symbol_index = sym_index;
491 const symbol = elf_file.symbol(sym_index);
499 entry.ref = ref;
500 const symbol = elf_file.symbol(ref).?;
492501 symbol.flags.has_got = true;
493502 if (symbol.flags.import or symbol.isIFunc(elf_file) or
494503 ((elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) and !symbol.isAbs(elf_file)))
495504 {
496505 got.flags.needs_rela = true;
497506 }
498 try symbol.addExtra(.{ .got = index }, elf_file);
507 symbol.addExtra(.{ .got = index }, elf_file);
499508 return index;
500509 }
501510
......@@ -506,48 +515,48 @@ pub const GotSection = struct {
506515 const index = try got.allocateEntry(gpa);
507516 const entry = &got.entries.items[index];
508517 entry.tag = .tlsld;
509 entry.symbol_index = undefined; // unused
518 entry.ref = .{ .index = 0, .file = 0 }; // unused
510519 got.flags.needs_rela = true;
511520 got.tlsld_index = index;
512521 }
513522
514 pub fn addTlsGdSymbol(got: *GotSection, sym_index: Symbol.Index, elf_file: *Elf) !void {
523 pub fn addTlsGdSymbol(got: *GotSection, ref: Elf.Ref, elf_file: *Elf) !void {
515524 const comp = elf_file.base.comp;
516525 const gpa = comp.gpa;
517526 const index = try got.allocateEntry(gpa);
518527 const entry = &got.entries.items[index];
519528 entry.tag = .tlsgd;
520 entry.symbol_index = sym_index;
521 const symbol = elf_file.symbol(sym_index);
529 entry.ref = ref;
530 const symbol = elf_file.symbol(ref).?;
522531 symbol.flags.has_tlsgd = true;
523532 if (symbol.flags.import or elf_file.isEffectivelyDynLib()) got.flags.needs_rela = true;
524 try symbol.addExtra(.{ .tlsgd = index }, elf_file);
533 symbol.addExtra(.{ .tlsgd = index }, elf_file);
525534 }
526535
527 pub fn addGotTpSymbol(got: *GotSection, sym_index: Symbol.Index, elf_file: *Elf) !void {
536 pub fn addGotTpSymbol(got: *GotSection, ref: Elf.Ref, elf_file: *Elf) !void {
528537 const comp = elf_file.base.comp;
529538 const gpa = comp.gpa;
530539 const index = try got.allocateEntry(gpa);
531540 const entry = &got.entries.items[index];
532541 entry.tag = .gottp;
533 entry.symbol_index = sym_index;
534 const symbol = elf_file.symbol(sym_index);
542 entry.ref = ref;
543 const symbol = elf_file.symbol(ref).?;
535544 symbol.flags.has_gottp = true;
536545 if (symbol.flags.import or elf_file.isEffectivelyDynLib()) got.flags.needs_rela = true;
537 try symbol.addExtra(.{ .gottp = index }, elf_file);
546 symbol.addExtra(.{ .gottp = index }, elf_file);
538547 }
539548
540 pub fn addTlsDescSymbol(got: *GotSection, sym_index: Symbol.Index, elf_file: *Elf) !void {
549 pub fn addTlsDescSymbol(got: *GotSection, ref: Elf.Ref, elf_file: *Elf) !void {
541550 const comp = elf_file.base.comp;
542551 const gpa = comp.gpa;
543552 const index = try got.allocateEntry(gpa);
544553 const entry = &got.entries.items[index];
545554 entry.tag = .tlsdesc;
546 entry.symbol_index = sym_index;
547 const symbol = elf_file.symbol(sym_index);
555 entry.ref = ref;
556 const symbol = elf_file.symbol(ref).?;
548557 symbol.flags.has_tlsdesc = true;
549558 got.flags.needs_rela = true;
550 try symbol.addExtra(.{ .tlsdesc = index }, elf_file);
559 symbol.addExtra(.{ .tlsdesc = index }, elf_file);
551560 }
552561
553562 pub fn size(got: GotSection, elf_file: *Elf) usize {
......@@ -564,10 +573,7 @@ pub const GotSection = struct {
564573 const apply_relocs = true; // TODO add user option for this
565574
566575 for (got.entries.items) |entry| {
567 const symbol = switch (entry.tag) {
568 .tlsld => null,
569 inline else => elf_file.symbol(entry.symbol_index),
570 };
576 const symbol = elf_file.symbol(entry.ref);
571577 switch (entry.tag) {
572578 .got => {
573579 const value = blk: {
......@@ -637,10 +643,7 @@ pub const GotSection = struct {
637643 try elf_file.rela_dyn.ensureUnusedCapacity(gpa, got.numRela(elf_file));
638644
639645 for (got.entries.items) |entry| {
640 const symbol = switch (entry.tag) {
641 .tlsld => null,
642 inline else => elf_file.symbol(entry.symbol_index),
643 };
646 const symbol = elf_file.symbol(entry.ref);
644647 const extra = if (symbol) |s| s.extra(elf_file) else null;
645648
646649 switch (entry.tag) {
......@@ -740,10 +743,7 @@ pub const GotSection = struct {
740743 const is_dyn_lib = elf_file.isEffectivelyDynLib();
741744 var num: usize = 0;
742745 for (got.entries.items) |entry| {
743 const symbol = switch (entry.tag) {
744 .tlsld => null,
745 inline else => elf_file.symbol(entry.symbol_index),
746 };
746 const symbol = elf_file.symbol(entry.ref);
747747 switch (entry.tag) {
748748 .got => if (symbol.?.flags.import or symbol.?.isIFunc(elf_file) or
749749 ((elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) and
......@@ -775,24 +775,15 @@ pub const GotSection = struct {
775775 pub fn updateSymtabSize(got: *GotSection, elf_file: *Elf) void {
776776 got.output_symtab_ctx.nlocals = @as(u32, @intCast(got.entries.items.len));
777777 for (got.entries.items) |entry| {
778 const symbol_name = switch (entry.tag) {
779 .tlsld => "",
780 inline else => elf_file.symbol(entry.symbol_index).name(elf_file),
781 };
778 const symbol_name = if (elf_file.symbol(entry.ref)) |sym| sym.name(elf_file) else "";
782779 got.output_symtab_ctx.strsize += @as(u32, @intCast(symbol_name.len + @tagName(entry.tag).len)) + 1 + 1;
783780 }
784781 }
785782
786783 pub fn writeSymtab(got: GotSection, elf_file: *Elf) void {
787784 for (got.entries.items, got.output_symtab_ctx.ilocal..) |entry, ilocal| {
788 const symbol = switch (entry.tag) {
789 .tlsld => null,
790 inline else => elf_file.symbol(entry.symbol_index),
791 };
792 const symbol_name = switch (entry.tag) {
793 .tlsld => "",
794 inline else => symbol.?.name(elf_file),
795 };
785 const symbol = elf_file.symbol(entry.ref);
786 const symbol_name = if (symbol) |s| s.name(elf_file) else "";
796787 const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
797788 elf_file.strtab.appendSliceAssumeCapacity(symbol_name);
798789 elf_file.strtab.appendAssumeCapacity('$');
......@@ -828,36 +819,38 @@ pub const GotSection = struct {
828819 ) !void {
829820 _ = options;
830821 _ = unused_fmt_string;
822 const got = ctx.got;
823 const elf_file = ctx.elf_file;
831824 try writer.writeAll("GOT\n");
832 for (ctx.got.entries.items) |entry| {
833 const symbol = ctx.elf_file.symbol(entry.symbol_index);
834 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{
825 for (got.entries.items) |entry| {
826 const symbol = elf_file.symbol(entry.ref).?;
827 try writer.print(" {d}@0x{x} => {}@0x{x} ({s})\n", .{
835828 entry.cell_index,
836 entry.address(ctx.elf_file),
837 entry.symbol_index,
838 symbol.address(.{}, ctx.elf_file),
839 symbol.name(ctx.elf_file),
829 entry.address(elf_file),
830 entry.ref,
831 symbol.address(.{}, elf_file),
832 symbol.name(elf_file),
840833 });
841834 }
842835 }
843836};
844837
845838pub const PltSection = struct {
846 symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
839 symbols: std.ArrayListUnmanaged(Elf.Ref) = .{},
847840 output_symtab_ctx: Elf.SymtabCtx = .{},
848841
849842 pub fn deinit(plt: *PltSection, allocator: Allocator) void {
850843 plt.symbols.deinit(allocator);
851844 }
852845
853 pub fn addSymbol(plt: *PltSection, sym_index: Symbol.Index, elf_file: *Elf) !void {
846 pub fn addSymbol(plt: *PltSection, ref: Elf.Ref, elf_file: *Elf) !void {
854847 const comp = elf_file.base.comp;
855848 const gpa = comp.gpa;
856849 const index = @as(u32, @intCast(plt.symbols.items.len));
857 const symbol = elf_file.symbol(sym_index);
850 const symbol = elf_file.symbol(ref).?;
858851 symbol.flags.has_plt = true;
859 try symbol.addExtra(.{ .plt = index }, elf_file);
860 try plt.symbols.append(gpa, sym_index);
852 symbol.addExtra(.{ .plt = index }, elf_file);
853 try plt.symbols.append(gpa, ref);
861854 }
862855
863856 pub fn size(plt: PltSection, elf_file: *Elf) usize {
......@@ -895,8 +888,8 @@ pub const PltSection = struct {
895888 const gpa = comp.gpa;
896889 const cpu_arch = elf_file.getTarget().cpu.arch;
897890 try elf_file.rela_plt.ensureUnusedCapacity(gpa, plt.numRela());
898 for (plt.symbols.items) |sym_index| {
899 const sym = elf_file.symbol(sym_index);
891 for (plt.symbols.items) |ref| {
892 const sym = elf_file.symbol(ref).?;
900893 assert(sym.flags.import);
901894 const extra = sym.extra(elf_file);
902895 const r_offset: u64 = @intCast(sym.gotPltAddress(elf_file));
......@@ -916,16 +909,16 @@ pub const PltSection = struct {
916909
917910 pub fn updateSymtabSize(plt: *PltSection, elf_file: *Elf) void {
918911 plt.output_symtab_ctx.nlocals = @as(u32, @intCast(plt.symbols.items.len));
919 for (plt.symbols.items) |sym_index| {
920 const name = elf_file.symbol(sym_index).name(elf_file);
912 for (plt.symbols.items) |ref| {
913 const name = elf_file.symbol(ref).?.name(elf_file);
921914 plt.output_symtab_ctx.strsize += @as(u32, @intCast(name.len + "$plt".len)) + 1;
922915 }
923916 }
924917
925918 pub fn writeSymtab(plt: PltSection, elf_file: *Elf) void {
926919 const cpu_arch = elf_file.getTarget().cpu.arch;
927 for (plt.symbols.items, plt.output_symtab_ctx.ilocal..) |sym_index, ilocal| {
928 const sym = elf_file.symbol(sym_index);
920 for (plt.symbols.items, plt.output_symtab_ctx.ilocal..) |ref, ilocal| {
921 const sym = elf_file.symbol(ref).?;
929922 const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
930923 elf_file.strtab.appendSliceAssumeCapacity(sym.name(elf_file));
931924 elf_file.strtab.appendSliceAssumeCapacity("$plt");
......@@ -958,15 +951,17 @@ pub const PltSection = struct {
958951 ) !void {
959952 _ = options;
960953 _ = unused_fmt_string;
954 const plt = ctx.plt;
955 const elf_file = ctx.elf_file;
961956 try writer.writeAll("PLT\n");
962 for (ctx.plt.symbols.items, 0..) |symbol_index, i| {
963 const symbol = ctx.elf_file.symbol(symbol_index);
964 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{
957 for (plt.symbols.items, 0..) |ref, i| {
958 const symbol = elf_file.symbol(ref).?;
959 try writer.print(" {d}@0x{x} => {}@0x{x} ({s})\n", .{
965960 i,
966 symbol.pltAddress(ctx.elf_file),
967 symbol_index,
968 symbol.address(.{}, ctx.elf_file),
969 symbol.name(ctx.elf_file),
961 symbol.pltAddress(elf_file),
962 ref,
963 symbol.address(.{}, elf_file),
964 symbol.name(elf_file),
970965 });
971966 }
972967 }
......@@ -988,8 +983,8 @@ pub const PltSection = struct {
988983 try writer.writeAll(&preamble);
989984 try writer.writeByteNTimes(0xcc, preambleSize(.x86_64) - preamble.len);
990985
991 for (plt.symbols.items, 0..) |sym_index, i| {
992 const sym = elf_file.symbol(sym_index);
986 for (plt.symbols.items, 0..) |ref, i| {
987 const sym = elf_file.symbol(ref).?;
993988 const target_addr = sym.gotPltAddress(elf_file);
994989 const source_addr = sym.pltAddress(elf_file);
995990 disp = @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr + 12)) - 4;
......@@ -1037,8 +1032,8 @@ pub const PltSection = struct {
10371032 }
10381033 }
10391034
1040 for (plt.symbols.items) |sym_index| {
1041 const sym = elf_file.symbol(sym_index);
1035 for (plt.symbols.items) |ref| {
1036 const sym = elf_file.symbol(ref).?;
10421037 const target_addr = sym.gotPltAddress(elf_file);
10431038 const source_addr = sym.pltAddress(elf_file);
10441039 const pages = try aarch64_util.calcNumberOfPages(source_addr, target_addr);
......@@ -1075,7 +1070,7 @@ pub const GotPltSection = struct {
10751070 _ = got_plt;
10761071 {
10771072 // [0]: _DYNAMIC
1078 const symbol = elf_file.symbol(elf_file.linkerDefinedPtr().?.dynamic_index.?);
1073 const symbol = elf_file.linkerDefinedPtr().?.dynamicSymbol(elf_file).?;
10791074 try writer.writeInt(u64, @intCast(symbol.address(.{}, elf_file)), .little);
10801075 }
10811076 // [1]: 0x0
......@@ -1093,22 +1088,22 @@ pub const GotPltSection = struct {
10931088};
10941089
10951090pub const PltGotSection = struct {
1096 symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
1091 symbols: std.ArrayListUnmanaged(Elf.Ref) = .{},
10971092 output_symtab_ctx: Elf.SymtabCtx = .{},
10981093
10991094 pub fn deinit(plt_got: *PltGotSection, allocator: Allocator) void {
11001095 plt_got.symbols.deinit(allocator);
11011096 }
11021097
1103 pub fn addSymbol(plt_got: *PltGotSection, sym_index: Symbol.Index, elf_file: *Elf) !void {
1098 pub fn addSymbol(plt_got: *PltGotSection, ref: Elf.Ref, elf_file: *Elf) !void {
11041099 const comp = elf_file.base.comp;
11051100 const gpa = comp.gpa;
11061101 const index = @as(u32, @intCast(plt_got.symbols.items.len));
1107 const symbol = elf_file.symbol(sym_index);
1102 const symbol = elf_file.symbol(ref).?;
11081103 symbol.flags.has_plt = true;
11091104 symbol.flags.has_got = true;
1110 try symbol.addExtra(.{ .plt_got = index }, elf_file);
1111 try plt_got.symbols.append(gpa, sym_index);
1105 symbol.addExtra(.{ .plt_got = index }, elf_file);
1106 try plt_got.symbols.append(gpa, ref);
11121107 }
11131108
11141109 pub fn size(plt_got: PltGotSection, elf_file: *Elf) usize {
......@@ -1134,15 +1129,15 @@ pub const PltGotSection = struct {
11341129
11351130 pub fn updateSymtabSize(plt_got: *PltGotSection, elf_file: *Elf) void {
11361131 plt_got.output_symtab_ctx.nlocals = @as(u32, @intCast(plt_got.symbols.items.len));
1137 for (plt_got.symbols.items) |sym_index| {
1138 const name = elf_file.symbol(sym_index).name(elf_file);
1132 for (plt_got.symbols.items) |ref| {
1133 const name = elf_file.symbol(ref).?.name(elf_file);
11391134 plt_got.output_symtab_ctx.strsize += @as(u32, @intCast(name.len + "$pltgot".len)) + 1;
11401135 }
11411136 }
11421137
11431138 pub fn writeSymtab(plt_got: PltGotSection, elf_file: *Elf) void {
1144 for (plt_got.symbols.items, plt_got.output_symtab_ctx.ilocal..) |sym_index, ilocal| {
1145 const sym = elf_file.symbol(sym_index);
1139 for (plt_got.symbols.items, plt_got.output_symtab_ctx.ilocal..) |ref, ilocal| {
1140 const sym = elf_file.symbol(ref).?;
11461141 const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
11471142 elf_file.strtab.appendSliceAssumeCapacity(sym.name(elf_file));
11481143 elf_file.strtab.appendSliceAssumeCapacity("$pltgot");
......@@ -1160,8 +1155,8 @@ pub const PltGotSection = struct {
11601155
11611156 const x86_64 = struct {
11621157 pub fn write(plt_got: PltGotSection, elf_file: *Elf, writer: anytype) !void {
1163 for (plt_got.symbols.items) |sym_index| {
1164 const sym = elf_file.symbol(sym_index);
1158 for (plt_got.symbols.items) |ref| {
1159 const sym = elf_file.symbol(ref).?;
11651160 const target_addr = sym.gotAddress(elf_file);
11661161 const source_addr = sym.pltGotAddress(elf_file);
11671162 const disp = @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr + 6)) - 4;
......@@ -1178,8 +1173,8 @@ pub const PltGotSection = struct {
11781173
11791174 const aarch64 = struct {
11801175 fn write(plt_got: PltGotSection, elf_file: *Elf, writer: anytype) !void {
1181 for (plt_got.symbols.items) |sym_index| {
1182 const sym = elf_file.symbol(sym_index);
1176 for (plt_got.symbols.items) |ref| {
1177 const sym = elf_file.symbol(ref).?;
11831178 const target_addr = sym.gotAddress(elf_file);
11841179 const source_addr = sym.pltGotAddress(elf_file);
11851180 const pages = try aarch64_util.calcNumberOfPages(source_addr, target_addr);
......@@ -1204,56 +1199,56 @@ pub const PltGotSection = struct {
12041199};
12051200
12061201pub const CopyRelSection = struct {
1207 symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
1202 symbols: std.ArrayListUnmanaged(Elf.Ref) = .{},
12081203
12091204 pub fn deinit(copy_rel: *CopyRelSection, allocator: Allocator) void {
12101205 copy_rel.symbols.deinit(allocator);
12111206 }
12121207
1213 pub fn addSymbol(copy_rel: *CopyRelSection, sym_index: Symbol.Index, elf_file: *Elf) !void {
1208 pub fn addSymbol(copy_rel: *CopyRelSection, ref: Elf.Ref, elf_file: *Elf) !void {
12141209 const comp = elf_file.base.comp;
12151210 const gpa = comp.gpa;
12161211 const index = @as(u32, @intCast(copy_rel.symbols.items.len));
1217 const symbol = elf_file.symbol(sym_index);
1212 const symbol = elf_file.symbol(ref).?;
12181213 symbol.flags.import = true;
12191214 symbol.flags.@"export" = true;
12201215 symbol.flags.has_copy_rel = true;
12211216 symbol.flags.weak = false;
1222 try symbol.addExtra(.{ .copy_rel = index }, elf_file);
1223 try copy_rel.symbols.append(gpa, sym_index);
1217 symbol.addExtra(.{ .copy_rel = index }, elf_file);
1218 try copy_rel.symbols.append(gpa, ref);
12241219
12251220 const shared_object = symbol.file(elf_file).?.shared_object;
12261221 if (shared_object.aliases == null) {
12271222 try shared_object.initSymbolAliases(elf_file);
12281223 }
12291224
1230 const aliases = shared_object.symbolAliases(sym_index, elf_file);
1225 const aliases = shared_object.symbolAliases(ref.index, elf_file);
12311226 for (aliases) |alias| {
1232 if (alias == sym_index) continue;
1233 const alias_sym = elf_file.symbol(alias);
1227 if (alias == ref.index) continue;
1228 const alias_sym = &shared_object.symbols.items[alias];
12341229 alias_sym.flags.import = true;
12351230 alias_sym.flags.@"export" = true;
12361231 alias_sym.flags.has_copy_rel = true;
12371232 alias_sym.flags.needs_copy_rel = true;
12381233 alias_sym.flags.weak = false;
1239 try elf_file.dynsym.addSymbol(alias, elf_file);
1234 try elf_file.dynsym.addSymbol(.{ .index = alias, .file = shared_object.index }, elf_file);
12401235 }
12411236 }
12421237
12431238 pub fn updateSectionSize(copy_rel: CopyRelSection, shndx: u32, elf_file: *Elf) !void {
12441239 const shdr = &elf_file.shdrs.items[shndx];
1245 for (copy_rel.symbols.items) |sym_index| {
1246 const symbol = elf_file.symbol(sym_index);
1240 for (copy_rel.symbols.items) |ref| {
1241 const symbol = elf_file.symbol(ref).?;
12471242 const shared_object = symbol.file(elf_file).?.shared_object;
12481243 const alignment = try symbol.dsoAlignment(elf_file);
12491244 symbol.value = @intCast(mem.alignForward(u64, shdr.sh_size, alignment));
12501245 shdr.sh_addralign = @max(shdr.sh_addralign, alignment);
12511246 shdr.sh_size = @as(u64, @intCast(symbol.value)) + symbol.elfSym(elf_file).st_size;
12521247
1253 const aliases = shared_object.symbolAliases(sym_index, elf_file);
1248 const aliases = shared_object.symbolAliases(ref.index, elf_file);
12541249 for (aliases) |alias| {
1255 if (alias == sym_index) continue;
1256 const alias_sym = elf_file.symbol(alias);
1250 if (alias == ref.index) continue;
1251 const alias_sym = &shared_object.symbols.items[alias];
12571252 alias_sym.value = symbol.value;
12581253 }
12591254 }
......@@ -1264,8 +1259,8 @@ pub const CopyRelSection = struct {
12641259 const gpa = comp.gpa;
12651260 const cpu_arch = elf_file.getTarget().cpu.arch;
12661261 try elf_file.rela_dyn.ensureUnusedCapacity(gpa, copy_rel.numRela());
1267 for (copy_rel.symbols.items) |sym_index| {
1268 const sym = elf_file.symbol(sym_index);
1262 for (copy_rel.symbols.items) |ref| {
1263 const sym = elf_file.symbol(ref).?;
12691264 assert(sym.flags.import and sym.flags.has_copy_rel);
12701265 const extra = sym.extra(elf_file);
12711266 elf_file.addRelaDynAssumeCapacity(.{
......@@ -1285,8 +1280,8 @@ pub const DynsymSection = struct {
12851280 entries: std.ArrayListUnmanaged(Entry) = .{},
12861281
12871282 pub const Entry = struct {
1288 /// Index of the symbol which gets privilege of getting a dynamic treatment
1289 symbol_index: Symbol.Index,
1283 /// Ref of the symbol which gets privilege of getting a dynamic treatment
1284 ref: Elf.Ref,
12901285 /// Offset into .dynstrtab
12911286 off: u32,
12921287 };
......@@ -1295,22 +1290,22 @@ pub const DynsymSection = struct {
12951290 dynsym.entries.deinit(allocator);
12961291 }
12971292
1298 pub fn addSymbol(dynsym: *DynsymSection, sym_index: Symbol.Index, elf_file: *Elf) !void {
1293 pub fn addSymbol(dynsym: *DynsymSection, ref: Elf.Ref, elf_file: *Elf) !void {
12991294 const comp = elf_file.base.comp;
13001295 const gpa = comp.gpa;
13011296 const index = @as(u32, @intCast(dynsym.entries.items.len + 1));
1302 const sym = elf_file.symbol(sym_index);
1297 const sym = elf_file.symbol(ref).?;
13031298 sym.flags.has_dynamic = true;
1304 try sym.addExtra(.{ .dynamic = index }, elf_file);
1299 sym.addExtra(.{ .dynamic = index }, elf_file);
13051300 const off = try elf_file.insertDynString(sym.name(elf_file));
1306 try dynsym.entries.append(gpa, .{ .symbol_index = sym_index, .off = off });
1301 try dynsym.entries.append(gpa, .{ .ref = ref, .off = off });
13071302 }
13081303
13091304 pub fn sort(dynsym: *DynsymSection, elf_file: *Elf) void {
13101305 const Sort = struct {
13111306 pub fn lessThan(ctx: *Elf, lhs: Entry, rhs: Entry) bool {
1312 const lhs_sym = ctx.symbol(lhs.symbol_index);
1313 const rhs_sym = ctx.symbol(rhs.symbol_index);
1307 const lhs_sym = ctx.symbol(lhs.ref).?;
1308 const rhs_sym = ctx.symbol(rhs.ref).?;
13141309
13151310 if (lhs_sym.flags.@"export" != rhs_sym.flags.@"export") {
13161311 return rhs_sym.flags.@"export";
......@@ -1329,7 +1324,7 @@ pub const DynsymSection = struct {
13291324
13301325 var num_exports: u32 = 0;
13311326 for (dynsym.entries.items) |entry| {
1332 const sym = elf_file.symbol(entry.symbol_index);
1327 const sym = elf_file.symbol(entry.ref).?;
13331328 if (sym.flags.@"export") num_exports += 1;
13341329 }
13351330
......@@ -1338,7 +1333,7 @@ pub const DynsymSection = struct {
13381333 std.mem.sort(Entry, dynsym.entries.items, elf_file, Sort.lessThan);
13391334
13401335 for (dynsym.entries.items, 1..) |entry, index| {
1341 const sym = elf_file.symbol(entry.symbol_index);
1336 const sym = elf_file.symbol(entry.ref).?;
13421337 var extra = sym.extra(elf_file);
13431338 extra.dynamic = @as(u32, @intCast(index));
13441339 sym.setExtra(extra, elf_file);
......@@ -1356,7 +1351,7 @@ pub const DynsymSection = struct {
13561351 pub fn write(dynsym: DynsymSection, elf_file: *Elf, writer: anytype) !void {
13571352 try writer.writeStruct(Elf.null_sym);
13581353 for (dynsym.entries.items) |entry| {
1359 const sym = elf_file.symbol(entry.symbol_index);
1354 const sym = elf_file.symbol(entry.ref).?;
13601355 var out_sym: elf.Elf64_Sym = Elf.null_sym;
13611356 sym.setOutputSym(elf_file, &out_sym);
13621357 out_sym.st_name = entry.off;
......@@ -1429,7 +1424,7 @@ pub const GnuHashSection = struct {
14291424
14301425 fn getExports(elf_file: *Elf) []const DynsymSection.Entry {
14311426 const start = for (elf_file.dynsym.entries.items, 0..) |entry, i| {
1432 const sym = elf_file.symbol(entry.symbol_index);
1427 const sym = elf_file.symbol(entry.ref).?;
14331428 if (sym.flags.@"export") break i;
14341429 } else elf_file.dynsym.entries.items.len;
14351430 return elf_file.dynsym.entries.items[start..];
......@@ -1477,7 +1472,7 @@ pub const GnuHashSection = struct {
14771472 @memset(bloom, 0);
14781473
14791474 for (exports, 0..) |entry, i| {
1480 const sym = elf_file.symbol(entry.symbol_index);
1475 const sym = elf_file.symbol(entry.ref).?;
14811476 const h = hasher(sym.name(elf_file));
14821477 hashes[i] = h;
14831478 indices[i] = h % hash.num_buckets;
......@@ -1574,7 +1569,7 @@ pub const VerneedSection = struct {
15741569 try verneed.ensureTotalCapacity(dynsyms.len);
15751570
15761571 for (dynsyms, 1..) |entry, i| {
1577 const symbol = elf_file.symbol(entry.symbol_index);
1572 const symbol = elf_file.symbol(entry.ref).?;
15781573 if (symbol.flags.import and symbol.version_index & elf.VERSYM_VERSION > elf.VER_NDX_GLOBAL) {
15791574 const shared_object = symbol.file(elf_file).?.shared_object;
15801575 verneed.appendAssumeCapacity(.{
......@@ -1677,11 +1672,11 @@ pub const ComdatGroupSection = struct {
16771672 return cg_file.object.comdatGroup(cgs.cg_ref.index);
16781673 }
16791674
1680 pub fn symbol(cgs: ComdatGroupSection, elf_file: *Elf) Symbol.Index {
1675 pub fn symbol(cgs: ComdatGroupSection, elf_file: *Elf) *Symbol {
16811676 const cg = cgs.comdatGroup(elf_file);
16821677 const object = cg.file(elf_file).object;
16831678 const shdr = object.shdrs.items[cg.shndx];
1684 return object.symbols.items[shdr.sh_info];
1679 return &object.symbols.items[shdr.sh_info];
16851680 }
16861681
16871682 pub fn size(cgs: ComdatGroupSection, elf_file: *Elf) usize {
src/link/Elf/thunks.zig+16-24
......@@ -43,11 +43,7 @@ pub fn createThunks(shndx: u32, elf_file: *Elf) !void {
4343 else => @panic("unsupported arch"),
4444 };
4545 if (is_reachable) continue;
46 const target = switch (file) {
47 .zig_object => |x| x.symbol(rel.r_sym()),
48 .object => |x| x.symbols.items[rel.r_sym()],
49 else => unreachable,
50 };
46 const target = file.resolveSymbol(rel.r_sym(), elf_file);
5147 try thunk.symbols.put(gpa, target, {});
5248 }
5349 atom.addExtra(.{ .thunk = thunk_index }, elf_file);
......@@ -80,7 +76,7 @@ fn maxAllowedDistance(cpu_arch: std.Target.Cpu.Arch) u32 {
8076pub const Thunk = struct {
8177 value: i64 = 0,
8278 output_section_index: u32 = 0,
83 symbols: std.AutoArrayHashMapUnmanaged(Symbol.Index, void) = .{},
79 symbols: std.AutoArrayHashMapUnmanaged(Elf.Ref, void) = .{},
8480 output_symtab_ctx: Elf.SymtabCtx = .{},
8581
8682 pub fn deinit(thunk: *Thunk, allocator: Allocator) void {
......@@ -97,9 +93,9 @@ pub const Thunk = struct {
9793 return @as(i64, @intCast(shdr.sh_addr)) + thunk.value;
9894 }
9995
100 pub fn targetAddress(thunk: Thunk, sym_index: Symbol.Index, elf_file: *Elf) i64 {
96 pub fn targetAddress(thunk: Thunk, ref: Elf.Ref, elf_file: *Elf) i64 {
10197 const cpu_arch = elf_file.getTarget().cpu.arch;
102 return thunk.address(elf_file) + @as(i64, @intCast(thunk.symbols.getIndex(sym_index).? * trampolineSize(cpu_arch)));
98 return thunk.address(elf_file) + @as(i64, @intCast(thunk.symbols.getIndex(ref).? * trampolineSize(cpu_arch)));
10399 }
104100
105101 pub fn write(thunk: Thunk, elf_file: *Elf, writer: anytype) !void {
......@@ -112,16 +108,16 @@ pub const Thunk = struct {
112108
113109 pub fn calcSymtabSize(thunk: *Thunk, elf_file: *Elf) void {
114110 thunk.output_symtab_ctx.nlocals = @as(u32, @intCast(thunk.symbols.keys().len));
115 for (thunk.symbols.keys()) |sym_index| {
116 const sym = elf_file.symbol(sym_index);
111 for (thunk.symbols.keys()) |ref| {
112 const sym = elf_file.symbol(ref).?;
117113 thunk.output_symtab_ctx.strsize += @as(u32, @intCast(sym.name(elf_file).len + "$thunk".len + 1));
118114 }
119115 }
120116
121117 pub fn writeSymtab(thunk: Thunk, elf_file: *Elf) void {
122118 const cpu_arch = elf_file.getTarget().cpu.arch;
123 for (thunk.symbols.keys(), thunk.output_symtab_ctx.ilocal..) |sym_index, ilocal| {
124 const sym = elf_file.symbol(sym_index);
119 for (thunk.symbols.keys(), thunk.output_symtab_ctx.ilocal..) |ref, ilocal| {
120 const sym = elf_file.symbol(ref).?;
125121 const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
126122 elf_file.strtab.appendSliceAssumeCapacity(sym.name(elf_file));
127123 elf_file.strtab.appendSliceAssumeCapacity("$thunk");
......@@ -131,7 +127,7 @@ pub const Thunk = struct {
131127 .st_info = elf.STT_FUNC,
132128 .st_other = 0,
133129 .st_shndx = @intCast(thunk.output_section_index),
134 .st_value = @intCast(thunk.targetAddress(sym_index, elf_file)),
130 .st_value = @intCast(thunk.targetAddress(ref, elf_file)),
135131 .st_size = trampolineSize(cpu_arch),
136132 };
137133 }
......@@ -181,9 +177,9 @@ pub const Thunk = struct {
181177 const thunk = ctx.thunk;
182178 const elf_file = ctx.elf_file;
183179 try writer.print("@{x} : size({x})\n", .{ thunk.value, thunk.size(elf_file) });
184 for (thunk.symbols.keys()) |index| {
185 const sym = elf_file.symbol(index);
186 try writer.print(" %{d} : {s} : @{x}\n", .{ index, sym.name(elf_file), sym.value });
180 for (thunk.symbols.keys()) |ref| {
181 const sym = elf_file.symbol(ref).?;
182 try writer.print(" {} : {s} : @{x}\n", .{ ref, sym.name(elf_file), sym.value });
187183 }
188184 }
189185
......@@ -195,12 +191,8 @@ const aarch64 = struct {
195191 const r_type: elf.R_AARCH64 = @enumFromInt(rel.r_type());
196192 if (r_type != .CALL26 and r_type != .JUMP26) return true;
197193 const file = atom.file(elf_file).?;
198 const target_index = switch (file) {
199 .zig_object => |x| x.symbol(rel.r_sym()),
200 .object => |x| x.symbols.items[rel.r_sym()],
201 else => unreachable,
202 };
203 const target = elf_file.symbol(target_index);
194 const target_ref = file.resolveSymbol(rel.r_sym(), elf_file);
195 const target = elf_file.symbol(target_ref).?;
204196 if (target.flags.has_plt) return false;
205197 if (atom.output_section_index != target.output_section_index) return false;
206198 const target_atom = target.atom(elf_file).?;
......@@ -212,8 +204,8 @@ const aarch64 = struct {
212204 }
213205
214206 fn write(thunk: Thunk, elf_file: *Elf, writer: anytype) !void {
215 for (thunk.symbols.keys(), 0..) |sym_index, i| {
216 const sym = elf_file.symbol(sym_index);
207 for (thunk.symbols.keys(), 0..) |ref, i| {
208 const sym = elf_file.symbol(ref).?;
217209 const saddr = thunk.address(elf_file) + @as(i64, @intCast(i * trampoline_size));
218210 const taddr = sym.address(.{}, elf_file);
219211 const pages = try util.calcNumberOfPages(saddr, taddr);