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...@@ -4354,8 +4354,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4354 if (try self.air.value(callee, pt)) |func_value| {4354 if (try self.air.value(callee, pt)) |func_value| {
4355 if (func_value.getFunction(mod)) |func| {4355 if (func_value.getFunction(mod)) |func| {
4356 if (self.bin_file.cast(link.File.Elf)) |elf_file| {4356 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
4357 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);4357 const zo = elf_file.zigObjectPtr().?;
4358 const sym = elf_file.symbol(sym_index);4358 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
4359 const sym = zo.symbol(sym_index);
4359 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);4360 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
4360 const got_addr = @as(u32, @intCast(sym.zigGotAddress(elf_file)));4361 const got_addr = @as(u32, @intCast(sym.zigGotAddress(elf_file)));
4361 try self.genSetReg(Type.usize, .x30, .{ .memory = got_addr });4362 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...@@ -4336,8 +4336,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
4336 if (try self.air.value(callee, pt)) |func_value| {4336 if (try self.air.value(callee, pt)) |func_value| {
4337 if (func_value.getFunction(mod)) |func| {4337 if (func_value.getFunction(mod)) |func| {
4338 if (self.bin_file.cast(link.File.Elf)) |elf_file| {4338 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
4339 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);4339 const zo = elf_file.zigObjectPtr().?;
4340 const sym = elf_file.symbol(sym_index);4340 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
4341 const sym = zo.symbol(sym_index);
4341 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);4342 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
4342 const got_addr: u32 = @intCast(sym.zigGotAddress(elf_file));4343 const got_addr: u32 = @intCast(sym.zigGotAddress(elf_file));
4343 try self.genSetReg(Type.usize, .lr, .{ .memory = got_addr });4344 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 {...@@ -1409,12 +1409,13 @@ fn genLazy(func: *Func, lazy_sym: link.File.LazySymbol) InnerError!void {
1409 defer func.register_manager.unlockReg(data_lock);1409 defer func.register_manager.unlockReg(data_lock);
14101410
1411 const elf_file = func.bin_file.cast(link.File.Elf).?;1411 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, .{
1413 .kind = .const_data,1414 .kind = .const_data,
1414 .ty = enum_ty,1415 .ty = enum_ty,
1415 }) catch |err|1416 }) catch |err|
1416 return func.fail("{s} creating lazy symbol", .{@errorName(err)});1417 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
1419 try func.genSetReg(Type.u64, data_reg, .{ .lea_symbol = .{ .sym = sym.esym_index } });1420 try func.genSetReg(Type.u64, data_reg, .{ .lea_symbol = .{ .sym = sym.esym_index } });
14201421
...@@ -4946,8 +4947,9 @@ fn genCall(...@@ -4946,8 +4947,9 @@ fn genCall(
4946 }) {4947 }) {
4947 .func => |func_val| {4948 .func => |func_val| {
4948 if (func.bin_file.cast(link.File.Elf)) |elf_file| {4949 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 zo = elf_file.zigObjectPtr().?;
4950 const sym = elf_file.symbol(sym_index);4951 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, func_val.owner_decl);
4952 const sym = zo.symbol(sym_index);
49514953
4952 if (func.mod.pic) {4954 if (func.mod.pic) {
4953 return func.fail("TODO: genCall pic", .{});4955 return func.fail("TODO: genCall pic", .{});
...@@ -7822,9 +7824,10 @@ fn airTagName(func: *Func, inst: Air.Inst.Index) !void {...@@ -7822,9 +7824,10 @@ fn airTagName(func: *Func, inst: Air.Inst.Index) !void {
78227824
7823 const lazy_sym = link.File.LazySymbol.initDecl(.code, enum_ty.getOwnerDecl(zcu), zcu);7825 const lazy_sym = link.File.LazySymbol.initDecl(.code, enum_ty.getOwnerDecl(zcu), zcu);
7824 const elf_file = func.bin_file.cast(link.File.Elf).?;7826 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|
7826 return func.fail("{s} creating lazy symbol", .{@errorName(err)});7829 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
7829 if (func.mod.pic) {7832 if (func.mod.pic) {
7830 return func.fail("TODO: airTagName pic", .{});7833 return func.fail("TODO: airTagName pic", .{});
...@@ -8049,7 +8052,8 @@ fn genTypedValue(func: *Func, val: Value) InnerError!MCValue {...@@ -8049,7 +8052,8 @@ fn genTypedValue(func: *Func, val: Value) InnerError!MCValue {
8049 switch (lf.tag) {8052 switch (lf.tag) {
8050 .elf => {8053 .elf => {
8051 const elf_file = lf.cast(link.File.Elf).?;8054 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);
8053 return MCValue{ .undef = local.esym_index };8057 return MCValue{ .undef = local.esym_index };
8054 },8058 },
8055 else => unreachable,8059 else => unreachable,
src/arch/riscv64/Emit.zig+8-6
...@@ -50,16 +50,16 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -50,16 +50,16 @@ pub fn emitMir(emit: *Emit) Error!void {
50 };50 };
5151
52 const elf_file = emit.bin_file.cast(link.File.Elf).?;52 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 atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;
55 const sym_index = elf_file.zigObjectPtr().?.symbol(symbol.sym_index);56 const sym = zo.symbol(symbol.sym_index);
56 const sym = elf_file.symbol(sym_index);
5757
58 var hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);58 var hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);
59 var lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I);59 var lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I);
6060
61 if (sym.flags.needs_zig_got and !is_obj_or_static_lib) {61 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
64 hi_r_type = Elf.R_ZIG_GOT_HI20;64 hi_r_type = Elf.R_ZIG_GOT_HI20;
65 lo_r_type = Elf.R_ZIG_GOT_LO12;65 lo_r_type = Elf.R_ZIG_GOT_LO12;
...@@ -82,8 +82,9 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -82,8 +82,9 @@ pub fn emitMir(emit: *Emit) Error!void {
82 },82 },
83 .load_tlv_reloc => |symbol| {83 .load_tlv_reloc => |symbol| {
84 const elf_file = emit.bin_file.cast(link.File.Elf).?;84 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
88 const R_RISCV = std.elf.R_RISCV;89 const R_RISCV = std.elf.R_RISCV;
8990
...@@ -107,7 +108,8 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -107,7 +108,8 @@ pub fn emitMir(emit: *Emit) Error!void {
107 },108 },
108 .call_extern_fn_reloc => |symbol| {109 .call_extern_fn_reloc => |symbol| {
109 const elf_file = emit.bin_file.cast(link.File.Elf).?;110 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
112 const r_type: u32 = @intFromEnum(std.elf.R_RISCV.CALL_PLT);114 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...@@ -1354,8 +1354,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
1354 switch (mod.intern_pool.indexToKey(func_value.ip_index)) {1354 switch (mod.intern_pool.indexToKey(func_value.ip_index)) {
1355 .func => |func| {1355 .func => |func| {
1356 const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: {1356 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);1357 const zo = elf_file.zigObjectPtr().?;
1358 const sym = elf_file.symbol(sym_index);1358 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
1359 const sym = zo.symbol(sym_index);
1359 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);1360 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
1360 break :blk @as(u32, @intCast(sym.zigGotAddress(elf_file)));1361 break :blk @as(u32, @intCast(sym.zigGotAddress(elf_file)));
1361 } else unreachable;1362 } else unreachable;
src/arch/x86_64/CodeGen.zig+6-4
...@@ -12327,8 +12327,9 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12327,8 +12327,9 @@ fn genCall(self: *Self, info: union(enum) {
12327 }) {12327 }) {
12328 .func => |func| {12328 .func => |func| {
12329 if (self.bin_file.cast(link.File.Elf)) |elf_file| {12329 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
12330 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);12330 const zo = elf_file.zigObjectPtr().?;
12331 const sym = elf_file.symbol(sym_index);12331 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
12332 const sym = zo.symbol(sym_index);
12332 if (self.mod.pic) {12333 if (self.mod.pic) {
12333 const callee_reg: Register = switch (resolved_cc) {12334 const callee_reg: Register = switch (resolved_cc) {
12334 .SysV => callee: {12335 .SysV => callee: {
...@@ -15320,9 +15321,10 @@ fn genLazySymbolRef(...@@ -15320,9 +15321,10 @@ fn genLazySymbolRef(
15320) InnerError!void {15321) InnerError!void {
15321 const pt = self.pt;15322 const pt = self.pt;
15322 if (self.bin_file.cast(link.File.Elf)) |elf_file| {15323 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|
15324 return self.fail("{s} creating lazy symbol", .{@errorName(err)});15326 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
15325 const sym = elf_file.symbol(sym_index);15327 const sym = zo.symbol(sym_index);
15326 if (self.mod.pic) {15328 if (self.mod.pic) {
15327 switch (tag) {15329 switch (tag) {
15328 .lea, .call => try self.genSetReg(reg, Type.usize, .{15330 .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 {...@@ -42,7 +42,8 @@ pub fn emitMir(emit: *Emit) Error!void {
42 }),42 }),
43 .linker_extern_fn => |symbol| if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| {43 .linker_extern_fn => |symbol| if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| {
44 // Add relocation to the decl.44 // 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).?;
46 const r_type = @intFromEnum(std.elf.R_X86_64.PLT32);47 const r_type = @intFromEnum(std.elf.R_X86_64.PLT32);
47 try atom_ptr.addReloc(elf_file, .{48 try atom_ptr.addReloc(elf_file, .{
48 .r_offset = end_offset - 4,49 .r_offset = end_offset - 4,
...@@ -88,7 +89,8 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -88,7 +89,8 @@ pub fn emitMir(emit: *Emit) Error!void {
88 }),89 }),
89 .linker_tlsld => |data| {90 .linker_tlsld => |data| {
90 const elf_file = emit.lower.bin_file.cast(link.File.Elf).?;91 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).?;
92 const r_type = @intFromEnum(std.elf.R_X86_64.TLSLD);94 const r_type = @intFromEnum(std.elf.R_X86_64.TLSLD);
93 try atom.addReloc(elf_file, .{95 try atom.addReloc(elf_file, .{
94 .r_offset = end_offset - 4,96 .r_offset = end_offset - 4,
...@@ -98,7 +100,8 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -98,7 +100,8 @@ pub fn emitMir(emit: *Emit) Error!void {
98 },100 },
99 .linker_dtpoff => |data| {101 .linker_dtpoff => |data| {
100 const elf_file = emit.lower.bin_file.cast(link.File.Elf).?;102 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).?;
102 const r_type = @intFromEnum(std.elf.R_X86_64.DTPOFF32);105 const r_type = @intFromEnum(std.elf.R_X86_64.DTPOFF32);
103 try atom.addReloc(elf_file, .{106 try atom.addReloc(elf_file, .{
104 .r_offset = end_offset - 4,107 .r_offset = end_offset - 4,
...@@ -112,11 +115,11 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -112,11 +115,11 @@ pub fn emitMir(emit: *Emit) Error!void {
112 .Obj => true,115 .Obj => true,
113 .Lib => emit.lower.link_mode == .static,116 .Lib => emit.lower.link_mode == .static,
114 };117 };
115 const atom = elf_file.symbol(data.atom_index).atom(elf_file).?;118 const zo = elf_file.zigObjectPtr().?;
116 const sym_index = elf_file.zigObjectPtr().?.symbol(data.sym_index);119 const atom = zo.symbol(data.atom_index).atom(elf_file).?;
117 const sym = elf_file.symbol(sym_index);120 const sym = zo.symbol(data.sym_index);
118 if (sym.flags.needs_zig_got and !is_obj_or_static_lib) {121 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);
120 }123 }
121 if (emit.lower.pic) {124 if (emit.lower.pic) {
122 const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj_or_static_lib)125 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)...@@ -349,8 +349,8 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
349 assert(mem_op.sib.scale_index.scale == 0);349 assert(mem_op.sib.scale_index.scale == 0);
350350
351 if (lower.bin_file.cast(link.File.Elf)) |elf_file| {351 if (lower.bin_file.cast(link.File.Elf)) |elf_file| {
352 const sym_index = elf_file.zigObjectPtr().?.symbol(sym.sym_index);352 const zo = elf_file.zigObjectPtr().?;
353 const elf_sym = elf_file.symbol(sym_index);353 const elf_sym = zo.symbol(sym.sym_index);
354354
355 if (elf_sym.flags.is_tls) {355 if (elf_sym.flags.is_tls) {
356 // TODO handle extern TLS vars, i.e., emit GD model356 // TODO handle extern TLS vars, i.e., emit GD model
src/codegen.zig+6-8
...@@ -906,20 +906,20 @@ fn genDeclRef(...@@ -906,20 +906,20 @@ fn genDeclRef(
906 const is_extern = decl.isExtern(zcu);906 const is_extern = decl.isExtern(zcu);
907907
908 if (lf.cast(link.File.Elf)) |elf_file| {908 if (lf.cast(link.File.Elf)) |elf_file| {
909 const zo = elf_file.zigObjectPtr().?;
909 if (is_extern) {910 if (is_extern) {
910 const name = decl.name.toSlice(ip);911 const name = decl.name.toSlice(ip);
911 // TODO audit this912 // TODO audit this
912 const lib_name = if (decl.getOwnedVariable(zcu)) |ov| ov.lib_name.toSlice(ip) else null;913 const lib_name = if (decl.getOwnedVariable(zcu)) |ov| ov.lib_name.toSlice(ip) else null;
913 const sym_index = try elf_file.getGlobalSymbol(name, lib_name);914 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;
915 return GenResult.mcv(.{ .load_symbol = sym_index });916 return GenResult.mcv(.{ .load_symbol = sym_index });
916 }917 }
917 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index);918 const sym_index = try zo.getOrCreateMetadataForDecl(elf_file, decl_index);
918 const sym = elf_file.symbol(sym_index);
919 if (is_threadlocal) {919 if (is_threadlocal) {
920 return GenResult.mcv(.{ .load_tlv = sym.esym_index });920 return GenResult.mcv(.{ .load_tlv = sym_index });
921 }921 }
922 return GenResult.mcv(.{ .load_symbol = sym.esym_index });922 return GenResult.mcv(.{ .load_symbol = sym_index });
923 } else if (lf.cast(link.File.MachO)) |macho_file| {923 } else if (lf.cast(link.File.MachO)) |macho_file| {
924 const zo = macho_file.getZigObject().?;924 const zo = macho_file.getZigObject().?;
925 if (is_extern) {925 if (is_extern) {
...@@ -971,9 +971,7 @@ fn genUnnamedConst(...@@ -971,9 +971,7 @@ fn genUnnamedConst(
971 };971 };
972 switch (lf.tag) {972 switch (lf.tag) {
973 .elf => {973 .elf => {
974 const elf_file = lf.cast(link.File.Elf).?;974 return GenResult.mcv(.{ .load_symbol = local_sym_index });
975 const local = elf_file.symbol(local_sym_index);
976 return GenResult.mcv(.{ .load_symbol = local.esym_index });
977 },975 },
978 .macho => {976 .macho => {
979 const macho_file = lf.cast(link.File.MachO).?;977 const macho_file = lf.cast(link.File.MachO).?;
src/link/Elf.zig+50-81
...@@ -2013,11 +2013,10 @@ fn claimUnresolved(self: *Elf) void {...@@ -2013,11 +2013,10 @@ fn claimUnresolved(self: *Elf) void {
2013fn scanRelocs(self: *Elf) !void {2013fn scanRelocs(self: *Elf) !void {
2014 const gpa = self.base.comp.gpa;2014 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);
2017 defer {2017 defer {
2018 var it = undefs.iterator();2018 for (undefs.values()) |*refs| {
2019 while (it.next()) |entry| {2019 refs.deinit();
2020 entry.value_ptr.deinit();
2021 }2020 }
2022 undefs.deinit();2021 undefs.deinit();
2023 }2022 }
...@@ -2028,7 +2027,18 @@ fn scanRelocs(self: *Elf) !void {...@@ -2028,7 +2027,18 @@ fn scanRelocs(self: *Elf) !void {
2028 objects.appendSliceAssumeCapacity(self.objects.items);2027 objects.appendSliceAssumeCapacity(self.objects.items);
20292028
2030 var has_reloc_errors = false;2029 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| {
2032 self.file(index).?.scanRelocs(self, &undefs) catch |err| switch (err) {2042 self.file(index).?.scanRelocs(self, &undefs) catch |err| switch (err) {
2033 error.RelaxFailure => unreachable,2043 error.RelaxFailure => unreachable,
2034 error.UnsupportedCpuArch => {2044 error.UnsupportedCpuArch => {
...@@ -2044,47 +2054,12 @@ fn scanRelocs(self: *Elf) !void {...@@ -2044,47 +2054,12 @@ fn scanRelocs(self: *Elf) !void {
20442054
2045 if (has_reloc_errors) return error.FlushFailure;2055 if (has_reloc_errors) return error.FlushFailure;
20462056
2047 for (self.symbols.items, 0..) |*sym, i| {2057 if (self.zigObjectPtr()) |zo| {
2048 const index = @as(u32, @intCast(i));2058 try zo.asFile().createSymbolIndirection(self);
2049 if (!sym.isLocal(self) and !sym.flags.has_dynamic) {2059 }
2050 log.debug("'{s}' is non-local", .{sym.name(self)});2060 for (self.objects.items) |index| {
2051 try self.dynsym.addSymbol(index, self);2061 try self.file(index).?.createSymbolIndirection(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 }
2086 }2062 }
2087
2088 if (self.got.flags.needs_tlsld) {2063 if (self.got.flags.needs_tlsld) {
2089 log.debug("program needs TLSLD", .{});2064 log.debug("program needs TLSLD", .{});
2090 try self.got.addTlsLdSymbol(self);2065 try self.got.addTlsLdSymbol(self);
...@@ -2861,8 +2836,8 @@ pub fn writeElfHeader(self: *Elf) !void {...@@ -2861,8 +2836,8 @@ pub fn writeElfHeader(self: *Elf) !void {
2861 index += 4;2836 index += 4;
28622837
2863 const e_entry: u64 = if (self.linkerDefinedPtr()) |obj| blk: {2838 const e_entry: u64 = if (self.linkerDefinedPtr()) |obj| blk: {
2864 const entry_index = obj.entry_index orelse break :blk 0;2839 const entry_sym = obj.entrySymbol(self) orelse break :blk 0;
2865 break :blk @intCast(self.symbol(entry_index).address(.{}, self));2840 break :blk @intCast(entry_sym.address(.{}, self));
2866 } else 0;2841 } else 0;
2867 const phdr_table_offset = if (self.phdr_table_index) |phndx| self.phdrs.items[phndx].p_offset else 0;2842 const phdr_table_offset = if (self.phdr_table_index) |phndx| self.phdrs.items[phndx].p_offset else 0;
2868 switch (self.ptr_width) {2843 switch (self.ptr_width) {
...@@ -2993,7 +2968,7 @@ pub fn deleteExport(...@@ -2993,7 +2968,7 @@ pub fn deleteExport(
2993fn checkDuplicates(self: *Elf) !void {2968fn checkDuplicates(self: *Elf) !void {
2994 const gpa = self.base.comp.gpa;2969 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);
2997 defer {2972 defer {
2998 for (dupes.values()) |*list| {2973 for (dupes.values()) |*list| {
2999 list.deinit(gpa);2974 list.deinit(gpa);
...@@ -3301,7 +3276,7 @@ fn initSyntheticSections(self: *Elf) !void {...@@ -3301,7 +3276,7 @@ fn initSyntheticSections(self: *Elf) !void {
3301 });3276 });
33023277
3303 const needs_versions = for (self.dynsym.entries.items) |entry| {3278 const needs_versions = for (self.dynsym.entries.items) |entry| {
3304 const sym = self.symbol(entry.symbol_index);3279 const sym = self.symbol(entry.ref).?;
3305 if (sym.flags.import and sym.version_index & elf.VERSYM_VERSION > elf.VER_NDX_GLOBAL) break true;3280 if (sym.flags.import and sym.version_index & elf.VERSYM_VERSION > elf.VER_NDX_GLOBAL) break true;
3306 } else false;3281 } else false;
3307 if (needs_versions) {3282 if (needs_versions) {
...@@ -3515,7 +3490,7 @@ fn setVersionSymtab(self: *Elf) !void {...@@ -3515,7 +3490,7 @@ fn setVersionSymtab(self: *Elf) !void {
3515 try self.versym.resize(gpa, self.dynsym.count());3490 try self.versym.resize(gpa, self.dynsym.count());
3516 self.versym.items[0] = elf.VER_NDX_LOCAL;3491 self.versym.items[0] = elf.VER_NDX_LOCAL;
3517 for (self.dynsym.entries.items, 1..) |entry, i| {3492 for (self.dynsym.entries.items, 1..) |entry, i| {
3518 const sym = self.symbol(entry.symbol_index);3493 const sym = self.symbol(entry.ref).?;
3519 self.versym.items[i] = sym.version_index;3494 self.versym.items[i] = sym.version_index;
3520 }3495 }
35213496
...@@ -4307,11 +4282,10 @@ fn allocateSpecialPhdrs(self: *Elf) void {...@@ -4307,11 +4282,10 @@ fn allocateSpecialPhdrs(self: *Elf) void {
4307fn writeAtoms(self: *Elf) !void {4282fn writeAtoms(self: *Elf) !void {
4308 const gpa = self.base.comp.gpa;4283 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);
4311 defer {4286 defer {
4312 var it = undefs.iterator();4287 for (undefs.values()) |*refs| {
4313 while (it.next()) |entry| {4288 refs.deinit();
4314 entry.value_ptr.deinit();
4315 }4289 }
4316 undefs.deinit();4290 undefs.deinit();
4317 }4291 }
...@@ -5261,7 +5235,7 @@ pub fn calcNumIRelativeRelocs(self: *Elf) usize {...@@ -5261,7 +5235,7 @@ pub fn calcNumIRelativeRelocs(self: *Elf) usize {
52615235
5262 for (self.got.entries.items) |entry| {5236 for (self.got.entries.items) |entry| {
5263 if (entry.tag != .got) continue;5237 if (entry.tag != .got) continue;
5264 const sym = self.symbol(entry.symbol_index);5238 const sym = self.symbol(entry.ref).?;
5265 if (sym.isIFunc(self)) count += 1;5239 if (sym.isIFunc(self)) count += 1;
5266 }5240 }
52675241
...@@ -5443,36 +5417,34 @@ fn reportUndefinedSymbols(self: *Elf, undefs: anytype) !void {...@@ -5443,36 +5417,34 @@ fn reportUndefinedSymbols(self: *Elf, undefs: anytype) !void {
54435417
5444 try self.base.comp.link_errors.ensureUnusedCapacity(gpa, undefs.count());5418 try self.base.comp.link_errors.ensureUnusedCapacity(gpa, undefs.count());
54455419
5446 var it = undefs.iterator();5420 for (undefs.keys(), undefs.values()) |key, refs| {
5447 while (it.next()) |entry| {5421 const undef_sym = self.resolver.keys.items[key - 1];
5448 const undef_index = entry.key_ptr.*;5422 const nrefs = @min(refs.items.len, max_notes);
5449 const atoms = entry.value_ptr.*.items;5423 const nnotes = nrefs + @intFromBool(refs.items.len > max_notes);
5450 const natoms = @min(atoms.len, max_notes);
5451 const nnotes = natoms + @intFromBool(atoms.len > max_notes);
54525424
5453 var err = try self.base.addErrorWithNotesAssumeCapacity(nnotes);5425 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| {
5457 const atom_ptr = self.atom(ref).?;5429 const atom_ptr = self.atom(ref).?;
5458 const file_ptr = self.file(ref.file).?;5430 const file_ptr = atom_ptr.file(self).?;
5459 try err.addNote("referenced by {s}:{s}", .{ file_ptr.fmtPath(), atom_ptr.name(self) });5431 try err.addNote("referenced by {s}:{s}", .{ file_ptr.fmtPath(), atom_ptr.name(self) });
5460 }5432 }
54615433
5462 if (atoms.len > max_notes) {5434 if (refs.items.len > max_notes) {
5463 const remaining = atoms.len - max_notes;5435 const remaining = refs.items.len - max_notes;
5464 try err.addNote("referenced {d} more times", .{remaining});5436 try err.addNote("referenced {d} more times", .{remaining});
5465 }5437 }
5466 }5438 }
5467}5439}
54685440
5469fn reportDuplicates(self: *Elf, dupes: anytype) error{ HasDuplicates, OutOfMemory }!void {5441fn reportDuplicates(self: *Elf, dupes: anytype) error{ HasDuplicates, OutOfMemory }!void {
5442 if (dupes.keys().len == 0) return; // Nothing to do
5443
5470 const max_notes = 3;5444 const max_notes = 3;
5471 var has_dupes = false;5445
5472 var it = dupes.iterator();5446 for (dupes.keys(), dupes.values()) |key, notes| {
5473 while (it.next()) |entry| {5447 const sym = self.resolver.keys.items[key - 1];
5474 const sym = self.symbol(entry.key_ptr.*);
5475 const notes = entry.value_ptr.*;
5476 const nnotes = @min(notes.items.len, max_notes) + @intFromBool(notes.items.len > max_notes);5448 const nnotes = @min(notes.items.len, max_notes) + @intFromBool(notes.items.len > max_notes);
54775449
5478 var err = try self.base.addErrorWithNotes(nnotes + 1);5450 var err = try self.base.addErrorWithNotes(nnotes + 1);
...@@ -5489,11 +5461,9 @@ fn reportDuplicates(self: *Elf, dupes: anytype) error{ HasDuplicates, OutOfMemor...@@ -5489,11 +5461,9 @@ fn reportDuplicates(self: *Elf, dupes: anytype) error{ HasDuplicates, OutOfMemor
5489 const remaining = notes.items.len - max_notes;5461 const remaining = notes.items.len - max_notes;
5490 try err.addNote("defined {d} more times", .{remaining});5462 try err.addNote("defined {d} more times", .{remaining});
5491 }5463 }
5492
5493 has_dupes = true;
5494 }5464 }
54955465
5496 if (has_dupes) return error.HasDuplicates;5466 return error.HasDuplicates;
5497}5467}
54985468
5499fn reportMissingLibraryError(5469fn reportMissingLibraryError(
...@@ -5918,7 +5888,7 @@ pub const SymbolResolver = struct {...@@ -5918,7 +5888,7 @@ pub const SymbolResolver = struct {
5918 elf_file: *Elf,5888 elf_file: *Elf,
5919 ) !Result {5889 ) !Result {
5920 const adapter = Adapter{ .keys = resolver.keys.items, .elf_file = elf_file };5890 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 };
5922 const gop = try resolver.table.getOrPutAdapted(allocator, key, adapter);5892 const gop = try resolver.table.getOrPutAdapted(allocator, key, adapter);
5923 if (!gop.found_existing) {5893 if (!gop.found_existing) {
5924 try resolver.keys.append(allocator, key);5894 try resolver.keys.append(allocator, key);
...@@ -5944,16 +5914,15 @@ pub const SymbolResolver = struct {...@@ -5944,16 +5914,15 @@ pub const SymbolResolver = struct {
59445914
5945 const Key = struct {5915 const Key = struct {
5946 index: Symbol.Index,5916 index: Symbol.Index,
5947 file: File.Index,5917 file_index: File.Index,
59485918
5949 fn name(key: Key, elf_file: *Elf) [:0]const u8 {5919 fn name(key: Key, elf_file: *Elf) [:0]const u8 {
5950 const ref = Ref{ .index = key.index, .file = key.file };5920 const ref = Ref{ .index = key.index, .file = key.file_index };
5951 return ref.symbol(elf_file).?.name(elf_file);5921 return elf_file.symbol(ref).?.name(elf_file);
5952 }5922 }
59535923
5954 pub fn file(key: Key, elf_file: *Elf) ?File {5924 fn file(key: Key, elf_file: *Elf) ?File {
5955 const ref = Ref{ .index = key.index, .file = key.file };5925 return elf_file.file(key.file_index);
5956 return ref.file(elf_file);
5957 }5926 }
59585927
5959 fn eql(key: Key, other: Key, elf_file: *Elf) bool {5928 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...@@ -326,12 +326,8 @@ pub fn writeRelocs(self: Atom, elf_file: *Elf, out_relocs: *std.ArrayList(elf.El
326 const cpu_arch = elf_file.getTarget().cpu.arch;326 const cpu_arch = elf_file.getTarget().cpu.arch;
327 const file_ptr = self.file(elf_file).?;327 const file_ptr = self.file(elf_file).?;
328 for (self.relocs(elf_file)) |rel| {328 for (self.relocs(elf_file)) |rel| {
329 const target_index = switch (file_ptr) {329 const target_ref = file_ptr.resolveSymbol(rel.r_sym(), elf_file);
330 .zig_object => |x| x.symbol(rel.r_sym()),330 const target = elf_file.symbol(target_ref).?;
331 .object => |x| x.symbols.items[rel.r_sym()],
332 else => unreachable,
333 };
334 const target = elf_file.symbol(target_index);
335 const r_type = rel.r_type();331 const r_type = rel.r_type();
336 const r_offset: u64 = @intCast(self.value + @as(i64, @intCast(rel.r_offset)));332 const r_offset: u64 = @intCast(self.value + @as(i64, @intCast(rel.r_offset)));
337 var r_addend = rel.r_addend;333 var r_addend = rel.r_addend;
...@@ -422,12 +418,21 @@ pub fn scanRelocs(self: Atom, elf_file: *Elf, code: ?[]const u8, undefs: anytype...@@ -422,12 +418,21 @@ pub fn scanRelocs(self: Atom, elf_file: *Elf, code: ?[]const u8, undefs: anytype
422 const r_kind = relocation.decode(rel.r_type(), cpu_arch);418 const r_kind = relocation.decode(rel.r_type(), cpu_arch);
423 if (r_kind == .none) continue;419 if (r_kind == .none) continue;
424420
425 const symbol_index = switch (file_ptr) {421 const symbol_ref = file_ptr.resolveSymbol(rel.r_sym(), elf_file);
426 .zig_object => |x| x.symbol(rel.r_sym()),422 const symbol = elf_file.symbol(symbol_ref) orelse {
427 .object => |x| x.symbols.items[rel.r_sym()],423 const sym_name = switch (file_ptr) {
428 else => unreachable,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;
429 };435 };
430 const symbol = elf_file.symbol(symbol_index);
431436
432 const is_synthetic_symbol = switch (file_ptr) {437 const is_synthetic_symbol = switch (file_ptr) {
433 .zig_object => false, // TODO: implement this once we support merge sections in ZigObject438 .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...@@ -435,19 +440,8 @@ pub fn scanRelocs(self: Atom, elf_file: *Elf, code: ?[]const u8, undefs: anytype
435 else => unreachable,440 else => unreachable,
436 };441 };
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
449 // Report an undefined symbol.443 // 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)))
451 continue;445 continue;
452446
453 if (symbol.isIFunc(elf_file)) {447 if (symbol.isIFunc(elf_file)) {
...@@ -694,16 +688,15 @@ fn reportUndefined(...@@ -694,16 +688,15 @@ fn reportUndefined(
694 self: Atom,688 self: Atom,
695 elf_file: *Elf,689 elf_file: *Elf,
696 sym: *const Symbol,690 sym: *const Symbol,
697 sym_index: Symbol.Index,
698 rel: elf.Elf64_Rela,691 rel: elf.Elf64_Rela,
699 undefs: anytype,692 undefs: anytype,
700) !bool {693) !bool {
701 const comp = elf_file.base.comp;694 const comp = elf_file.base.comp;
702 const gpa = comp.gpa;695 const gpa = comp.gpa;
703 const rel_esym = switch (self.file(elf_file).?) {696 const file_ptr = self.file(elf_file).?;
704 .zig_object => |x| x.elfSym(rel.r_sym()).*,697 const rel_esym = switch (file_ptr) {
705 .object => |x| x.symtab.items[rel.r_sym()],698 .zig_object => |x| x.symbol(rel.r_sym()).elfSym(elf_file),
706 else => unreachable,699 inline else => |x| x.symtab.items[rel.r_sym()],
707 };700 };
708 const esym = sym.elfSym(elf_file);701 const esym = sym.elfSym(elf_file);
709 if (rel_esym.st_shndx == elf.SHN_UNDEF and702 if (rel_esym.st_shndx == elf.SHN_UNDEF and
...@@ -712,7 +705,12 @@ fn reportUndefined(...@@ -712,7 +705,12 @@ fn reportUndefined(
712 !sym.flags.import and705 !sym.flags.import and
713 esym.st_shndx == elf.SHN_UNDEF)706 esym.st_shndx == elf.SHN_UNDEF)
714 {707 {
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);
716 if (!gop.found_existing) {714 if (!gop.found_existing) {
717 gop.value_ptr.* = std.ArrayList(Elf.Ref).init(gpa);715 gop.value_ptr.* = std.ArrayList(Elf.Ref).init(gpa);
718 }716 }
...@@ -737,11 +735,8 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi...@@ -737,11 +735,8 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi
737 const r_kind = relocation.decode(rel.r_type(), cpu_arch);735 const r_kind = relocation.decode(rel.r_type(), cpu_arch);
738 if (r_kind == .none) continue;736 if (r_kind == .none) continue;
739737
740 const target = switch (file_ptr) {738 const target_ref = file_ptr.resolveSymbol(rel.r_sym(), elf_file);
741 .zig_object => |x| elf_file.symbol(x.symbol(rel.r_sym())),739 const target = elf_file.symbol(target_ref).?;
742 .object => |x| elf_file.symbol(x.symbols.items[rel.r_sym()]),
743 else => unreachable,
744 };
745 const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow;740 const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow;
746741
747 // We will use equation format to resolve relocations:742 // We will use equation format to resolve relocations:
...@@ -923,31 +918,29 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any...@@ -923,31 +918,29 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any
923918
924 const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow;919 const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow;
925920
926 const target_index = switch (file_ptr) {921 const target_ref = file_ptr.resolveSymbol(rel.r_sym(), elf_file);
927 .zig_object => |x| x.symbol(rel.r_sym()),922 const target = elf_file.symbol(target_ref) orelse {
928 .object => |x| x.symbols.items[rel.r_sym()],923 const sym_name = switch (file_ptr) {
929 else => unreachable,924 .zig_object => |x| x.symbol(rel.r_sym()).name(elf_file),
930 };925 inline else => |x| x.symbols.items[rel.r_sym()].name(elf_file),
931 const target = elf_file.symbol(target_index);926 };
932 const is_synthetic_symbol = switch (file_ptr) {927 // Violation of One Definition Rule for COMDATs.
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) {
940 // TODO convert into an error928 // TODO convert into an error
941 log.debug("{}: {s}: {s} refers to a discarded COMDAT section", .{929 log.debug("{}: {s}: {s} refers to a discarded COMDAT section", .{
942 file_ptr.fmtPath(),930 file_ptr.fmtPath(),
943 self.name(elf_file),931 self.name(elf_file),
944 target.name(elf_file),932 sym_name,
945 });933 });
946 continue;934 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
949 // Report an undefined symbol.942 // 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)))
951 continue;944 continue;
952945
953 // We will use equation format to resolve relocations:946 // We will use equation format to resolve relocations:
...@@ -1766,11 +1759,7 @@ const aarch64 = struct {...@@ -1766,11 +1759,7 @@ const aarch64 = struct {
1766 => {1759 => {
1767 const disp: i28 = math.cast(i28, S + A - P) orelse blk: {1760 const disp: i28 = math.cast(i28, S + A - P) orelse blk: {
1768 const th = atom.thunk(elf_file);1761 const th = atom.thunk(elf_file);
1769 const target_index = switch (file_ptr) {1762 const target_index = file_ptr.resolveSymbol(rel.r_sym(), elf_file);
1770 .zig_object => |x| x.symbol(rel.r_sym()),
1771 .object => |x| x.symbols.items[rel.r_sym()],
1772 else => unreachable,
1773 };
1774 const S_ = th.targetAddress(target_index, elf_file);1763 const S_ = th.targetAddress(target_index, elf_file);
1775 break :blk math.cast(i28, S_ + A - P) orelse return error.Overflow;1764 break :blk math.cast(i28, S_ + A - P) orelse return error.Overflow;
1776 };1765 };
...@@ -2106,11 +2095,8 @@ const riscv = struct {...@@ -2106,11 +2095,8 @@ const riscv = struct {
2106 return error.RelocFailure;2095 return error.RelocFailure;
2107 };2096 };
2108 it.pos = pos;2097 it.pos = pos;
2109 const target_ = switch (file_ptr) {2098 const target_ref_ = file_ptr.resolveSymbol(pair.r_sym(), elf_file);
2110 .zig_object => |x| elf_file.symbol(x.symbol(pair.r_sym())),2099 const target_ = elf_file.symbol(target_ref_).?;
2111 .object => |x| elf_file.symbol(x.symbols.items[pair.r_sym()]),
2112 else => unreachable,
2113 };
2114 const S_ = target_.address(.{}, elf_file);2100 const S_ = target_.address(.{}, elf_file);
2115 const A_ = pair.r_addend;2101 const A_ = pair.r_addend;
2116 const P_ = atom_addr + @as(i64, @intCast(pair.r_offset));2102 const P_ = atom_addr + @as(i64, @intCast(pair.r_offset));
...@@ -2313,4 +2299,5 @@ const File = @import("file.zig").File;...@@ -2313,4 +2299,5 @@ const File = @import("file.zig").File;
2313const Object = @import("Object.zig");2299const Object = @import("Object.zig");
2314const Symbol = @import("Symbol.zig");2300const Symbol = @import("Symbol.zig");
2315const Thunk = @import("thunks.zig").Thunk;2301const Thunk = @import("thunks.zig").Thunk;
2302const ZigObject = @import("ZigObject.zig");
2316const dev = @import("../../dev.zig");2303const dev = @import("../../dev.zig");
src/link/Elf/LinkerDefined.zig+46-28
...@@ -44,7 +44,7 @@ pub fn init(self: *LinkerDefined, allocator: Allocator) !void {...@@ -44,7 +44,7 @@ pub fn init(self: *LinkerDefined, allocator: Allocator) !void {
4444
45pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void {45pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
46 const newSymbolAssumeCapacity = struct {46 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 {
48 const esym_index: u32 = @intCast(ld.symtab.items.len);48 const esym_index: u32 = @intCast(ld.symtab.items.len);
49 const esym = ld.symtab.addOneAssumeCapacity();49 const esym = ld.symtab.addOneAssumeCapacity();
50 esym.* = .{50 esym.* = .{
...@@ -61,7 +61,8 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void {...@@ -61,7 +61,8 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
61 symbol.extra_index = ld.addSymbolExtraAssumeCapacity(.{});61 symbol.extra_index = ld.addSymbolExtraAssumeCapacity(.{});
62 symbol.ref = .{ .index = 0, .file = 0 };62 symbol.ref = .{ .index = 0, .file = 0 };
63 symbol.esym_index = esym_index;63 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;
65 }66 }
66 }.newSymbolAssumeCapacity;67 }.newSymbolAssumeCapacity;
6768
...@@ -111,31 +112,31 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void {...@@ -111,31 +112,31 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
111 @memset(self.symbols_resolver.items, 0);112 @memset(self.symbols_resolver.items, 0);
112113
113 if (elf_file.entry_name) |name| {114 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);
115 }116 }
116117
117 self.dynamic_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_DYNAMIC"));118 self.dynamic_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_DYNAMIC"), elf_file);
118 self.ehdr_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__ehdr_start"));119 self.ehdr_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__ehdr_start"), elf_file);
119 self.init_array_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__init_array_start"));120 self.init_array_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__init_array_start"), elf_file);
120 self.init_array_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__init_array_end"));121 self.init_array_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__init_array_end"), elf_file);
121 self.fini_array_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__fini_array_start"));122 self.fini_array_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__fini_array_start"), elf_file);
122 self.fini_array_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__fini_array_end"));123 self.fini_array_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__fini_array_end"), elf_file);
123 self.preinit_array_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__preinit_array_start"));124 self.preinit_array_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__preinit_array_start"), elf_file);
124 self.preinit_array_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__preinit_array_end"));125 self.preinit_array_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__preinit_array_end"), elf_file);
125 self.got_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_GLOBAL_OFFSET_TABLE_"));126 self.got_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_GLOBAL_OFFSET_TABLE_"), elf_file);
126 self.plt_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_PROCEDURE_LINKAGE_TABLE_"));127 self.plt_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_PROCEDURE_LINKAGE_TABLE_"), elf_file);
127 self.end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_end"));128 self.end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_end"), elf_file);
128129
129 if (elf_file.base.comp.link_eh_frame_hdr) {130 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);
131 }132 }
132133
133 self.dso_handle_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__dso_handle"));134 self.dso_handle_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__dso_handle"), elf_file);
134 self.rela_iplt_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__rela_iplt_start"));135 self.rela_iplt_start_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__rela_iplt_start"), elf_file);
135 self.rela_iplt_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__rela_iplt_end"));136 self.rela_iplt_end_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__rela_iplt_end"), elf_file);
136137
137 if (elf_file.getTarget().cpu.arch.isRISCV() and elf_file.isEffectivelyDynLib()) {138 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);
139 }140 }
140141
141 for (elf_file.objects.items) |index| {142 for (elf_file.objects.items) |index| {
...@@ -145,8 +146,8 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void {...@@ -145,8 +146,8 @@ pub fn initSymbols(self: *LinkerDefined, elf_file: *Elf) !void {
145 defer gpa.free(start_name);146 defer gpa.free(start_name);
146 const stop_name = try std.fmt.allocPrintZ(gpa, "__stop_{s}", .{name});147 const stop_name = try std.fmt.allocPrintZ(gpa, "__stop_{s}", .{name});
147 defer gpa.free(stop_name);148 defer gpa.free(stop_name);
148 const start = newSymbolAssumeCapacity(self, try self.addString(gpa, start_name));149 const start = newSymbolAssumeCapacity(self, try self.addString(gpa, start_name), elf_file);
149 const stop = newSymbolAssumeCapacity(self, try self.addString(gpa, stop_name));150 const stop = newSymbolAssumeCapacity(self, try self.addString(gpa, stop_name), elf_file);
150 self.start_stop_indexes.appendSliceAssumeCapacity(&.{ start, stop });151 self.start_stop_indexes.appendSliceAssumeCapacity(&.{ start, stop });
151 }152 }
152 }153 }
...@@ -268,7 +269,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {...@@ -268,7 +269,7 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
268 for (elf_file.shdrs.items, 0..) |shdr, shndx| {269 for (elf_file.shdrs.items, 0..) |shdr, shndx| {
269 if (shdr.sh_flags & elf.SHF_ALLOC != 0) {270 if (shdr.sh_flags & elf.SHF_ALLOC != 0) {
270 value = shdr.sh_addr + shdr.sh_size;271 value = shdr.sh_addr + shdr.sh_size;
271 osec = shndx;272 osec = @intCast(shndx);
272 }273 }
273 }274 }
274 allocSymbol(self, self.end_index.?, value, osec, elf_file);275 allocSymbol(self, self.end_index.?, value, osec, elf_file);
...@@ -287,10 +288,10 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {...@@ -287,10 +288,10 @@ pub fn allocateSymbols(self: *LinkerDefined, elf_file: *Elf) void {
287 {288 {
288 var index: usize = 0;289 var index: usize = 0;
289 while (index < self.start_stop_indexes.items.len) : (index += 2) {290 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);
291 const start = elf_file.symbol(start_ref).?;292 const start = elf_file.symbol(start_ref).?;
292 const name = start.name(elf_file);293 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);
294 const stop = elf_file.symbol(stop_ref).?;295 const stop = elf_file.symbol(stop_ref).?;
295 const shndx = elf_file.sectionByName(name["__start_".len..]).?;296 const shndx = elf_file.sectionByName(name["__start_".len..]).?;
296 const shdr = &elf_file.shdrs.items[shndx];297 const shdr = &elf_file.shdrs.items[shndx];
...@@ -334,6 +335,18 @@ pub fn writeSymtab(self: *LinkerDefined, elf_file: *Elf) void {...@@ -334,6 +335,18 @@ pub fn writeSymtab(self: *LinkerDefined, elf_file: *Elf) void {
334 }335 }
335}336}
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
337pub fn asFile(self: *LinkerDefined) File {350pub fn asFile(self: *LinkerDefined) File {
338 return .{ .linker_defined = self };351 return .{ .linker_defined = self };
339}352}
...@@ -356,8 +369,12 @@ pub fn resolveSymbol(self: LinkerDefined, index: Symbol.Index, elf_file: *Elf) E...@@ -356,8 +369,12 @@ pub fn resolveSymbol(self: LinkerDefined, index: Symbol.Index, elf_file: *Elf) E
356 return elf_file.resolver.get(resolv).?;369 return elf_file.resolver.get(resolv).?;
357}370}
358371
359pub fn addSymbol(self: *LinkerDefined, allocator: Allocator) !Symbol.Index {372fn addSymbol(self: *LinkerDefined, allocator: Allocator) !Symbol.Index {
360 try self.symbols.ensureUnusedCapacity(allocator, 1);373 try self.symbols.ensureUnusedCapacity(allocator, 1);
374 return self.addSymbolAssumeCapacity();
375}
376
377fn addSymbolAssumeCapacity(self: *LinkerDefined) Symbol.Index {
361 const index: Symbol.Index = @intCast(self.symbols.items.len);378 const index: Symbol.Index = @intCast(self.symbols.items.len);
362 self.symbols.appendAssumeCapacity(.{ .file_index = self.index });379 self.symbols.appendAssumeCapacity(.{ .file_index = self.index });
363 return index;380 return index;
...@@ -425,10 +442,11 @@ fn formatSymtab(...@@ -425,10 +442,11 @@ fn formatSymtab(
425) !void {442) !void {
426 _ = unused_fmt_string;443 _ = unused_fmt_string;
427 _ = options;444 _ = options;
445 const self = ctx.self;
446 const elf_file = ctx.elf_file;
428 try writer.writeAll(" globals\n");447 try writer.writeAll(" globals\n");
429 for (ctx.self.globals()) |index| {448 for (self.symbols.items) |sym| {
430 const global = ctx.elf_file.symbol(index);449 try writer.print(" {}\n", .{sym.fmt(elf_file)});
431 try writer.print(" {}\n", .{global.fmt(ctx.elf_file)});
432 }450 }
433}451}
434452
src/link/Elf/Object.zig+63-16
...@@ -394,10 +394,9 @@ fn initSymbols(self: *Object, allocator: Allocator, elf_file: *Elf) !void {...@@ -394,10 +394,9 @@ fn initSymbols(self: *Object, allocator: Allocator, elf_file: *Elf) !void {
394 sym_ptr.value = @intCast(sym.st_value);394 sym_ptr.value = @intCast(sym.st_value);
395 sym_ptr.name_offset = sym.st_name;395 sym_ptr.name_offset = sym.st_name;
396 sym_ptr.esym_index = @intCast(i);396 sym_ptr.esym_index = @intCast(i);
397 sym_ptr.extra_index = self.addSymbolExtraAssumeCapacity(.{397 sym_ptr.extra_index = self.addSymbolExtraAssumeCapacity(.{});
398 .weak = sym.st_bind() == elf.STB_WEAK,
399 });
400 sym_ptr.version_index = if (i >= first_global) elf_file.default_sym_version else elf.VER_NDX_LOCAL;398 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;
401 if (sym.st_shndx != elf.SHN_ABS and sym.st_shndx != elf.SHN_COMMON) {400 if (sym.st_shndx != elf.SHN_ABS and sym.st_shndx != elf.SHN_COMMON) {
402 sym_ptr.ref = .{ .index = self.atoms_indexes.items[sym.st_shndx], .file = self.index };401 sym_ptr.ref = .{ .index = self.atoms_indexes.items[sym.st_shndx], .file = self.index };
403 }402 }
...@@ -548,7 +547,7 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void {...@@ -548,7 +547,7 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void {
548547
549 for (self.cies.items) |cie| {548 for (self.cies.items) |cie| {
550 for (cie.relocs(elf_file)) |rel| {549 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)).?;
552 if (sym.flags.import) {551 if (sym.flags.import) {
553 if (sym.type(elf_file) != elf.STT_FUNC)552 if (sym.type(elf_file) != elf.STT_FUNC)
554 // TODO convert into an error553 // TODO convert into an error
...@@ -562,6 +561,51 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void {...@@ -562,6 +561,51 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void {
562 }561 }
563}562}
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
565pub fn resolveSymbols(self: *Object, elf_file: *Elf) !void {609pub fn resolveSymbols(self: *Object, elf_file: *Elf) !void {
566 const gpa = elf_file.base.comp.gpa;610 const gpa = elf_file.base.comp.gpa;
567611
...@@ -643,7 +687,7 @@ pub fn claimUnresolvedObject(self: *Object, elf_file: *Elf) void {...@@ -643,7 +687,7 @@ pub fn claimUnresolvedObject(self: *Object, elf_file: *Elf) void {
643 sym.file_index = self.index;687 sym.file_index = self.index;
644688
645 const idx = self.symbols_resolver.items[i];689 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 };
647 }691 }
648}692}
649693
...@@ -1120,7 +1164,7 @@ pub fn updateSymtabSize(self: *Object, elf_file: *Elf) void {...@@ -1120,7 +1164,7 @@ pub fn updateSymtabSize(self: *Object, elf_file: *Elf) void {
1120 }1164 }
11211165
1122 for (self.globals(), self.symbols_resolver.items) |*global, resolv| {1166 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];
1124 const ref_sym = elf_file.symbol(ref) orelse continue;1168 const ref_sym = elf_file.symbol(ref) orelse continue;
1125 if (ref_sym.file(elf_file).?.index() != self.index) continue;1169 if (ref_sym.file(elf_file).?.index() != self.index) continue;
1126 if (!isAlive(global, elf_file)) continue;1170 if (!isAlive(global, elf_file)) continue;
...@@ -1136,7 +1180,7 @@ pub fn updateSymtabSize(self: *Object, elf_file: *Elf) void {...@@ -1136,7 +1180,7 @@ pub fn updateSymtabSize(self: *Object, elf_file: *Elf) void {
1136 }1180 }
1137}1181}
11381182
1139pub fn writeSymtab(self: Object, elf_file: *Elf) void {1183pub fn writeSymtab(self: *Object, elf_file: *Elf) void {
1140 for (self.locals()) |local| {1184 for (self.locals()) |local| {
1141 const idx = local.outputSymtabIndex(elf_file) orelse continue;1185 const idx = local.outputSymtabIndex(elf_file) orelse continue;
1142 const out_sym = &elf_file.symtab.items[idx];1186 const out_sym = &elf_file.symtab.items[idx];
...@@ -1147,7 +1191,7 @@ pub fn writeSymtab(self: Object, elf_file: *Elf) void {...@@ -1147,7 +1191,7 @@ pub fn writeSymtab(self: Object, elf_file: *Elf) void {
1147 }1191 }
11481192
1149 for (self.globals(), self.symbols_resolver.items) |global, resolv| {1193 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];
1151 const ref_sym = elf_file.symbol(ref) orelse continue;1195 const ref_sym = elf_file.symbol(ref) orelse continue;
1152 if (ref_sym.file(elf_file).?.index() != self.index) continue;1196 if (ref_sym.file(elf_file).?.index() != self.index) continue;
1153 const idx = global.outputSymtabIndex(elf_file) orelse continue;1197 const idx = global.outputSymtabIndex(elf_file) orelse continue;
...@@ -1199,7 +1243,7 @@ fn locals(self: *Object) []Symbol {...@@ -1199,7 +1243,7 @@ fn locals(self: *Object) []Symbol {
1199 return self.symbols.items[0..end];1243 return self.symbols.items[0..end];
1200}1244}
12011245
1202fn globals(self: *Object) []Symbol {1246pub fn globals(self: *Object) []Symbol {
1203 if (self.symbols.items.len == 0) return &[0]Symbol{};1247 if (self.symbols.items.len == 0) return &[0]Symbol{};
1204 assert(self.symbols.items.len >= self.symtab.items.len);1248 assert(self.symbols.items.len >= self.symtab.items.len);
1205 const start = self.first_global orelse self.symtab.items.len;1249 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...@@ -1214,8 +1258,12 @@ pub fn resolveSymbol(self: Object, index: Symbol.Index, elf_file: *Elf) Elf.Ref
1214 return elf_file.resolver.get(resolv).?;1258 return elf_file.resolver.get(resolv).?;
1215}1259}
12161260
1217pub fn addSymbol(self: *Object, allocator: Allocator) !Symbol.Index {1261fn addSymbol(self: *Object, allocator: Allocator) !Symbol.Index {
1218 try self.symbols.ensureUnusedCapacity(allocator, 1);1262 try self.symbols.ensureUnusedCapacity(allocator, 1);
1263 return self.addSymbolAssumeCapacity();
1264}
1265
1266fn addSymbolAssumeCapacity(self: *Object) Symbol.Index {
1219 const index: Symbol.Index = @intCast(self.symbols.items.len);1267 const index: Symbol.Index = @intCast(self.symbols.items.len);
1220 self.symbols.appendAssumeCapacity(.{ .file_index = self.index });1268 self.symbols.appendAssumeCapacity(.{ .file_index = self.index });
1221 return index;1269 return index;
...@@ -1430,15 +1478,14 @@ fn formatSymtab(...@@ -1430,15 +1478,14 @@ fn formatSymtab(
1430 _ = unused_fmt_string;1478 _ = unused_fmt_string;
1431 _ = options;1479 _ = options;
1432 const object = ctx.object;1480 const object = ctx.object;
1481 const elf_file = ctx.elf_file;
1433 try writer.writeAll(" locals\n");1482 try writer.writeAll(" locals\n");
1434 for (object.locals()) |index| {1483 for (object.locals()) |sym| {
1435 const local = ctx.elf_file.symbol(index);1484 try writer.print(" {}\n", .{sym.fmt(elf_file)});
1436 try writer.print(" {}\n", .{local.fmt(ctx.elf_file)});
1437 }1485 }
1438 try writer.writeAll(" globals\n");1486 try writer.writeAll(" globals\n");
1439 for (object.globals()) |index| {1487 for (object.globals()) |sym| {
1440 const global = ctx.elf_file.symbol(index);1488 try writer.print(" {}\n", .{sym.fmt(elf_file)});
1441 try writer.print(" {}\n", .{global.fmt(ctx.elf_file)});
1442 }1489 }
1443}1490}
14441491
src/link/Elf/SharedObject.zig+22-15
...@@ -286,8 +286,8 @@ pub fn markImportExports(self: *SharedObject, elf_file: *Elf) void {...@@ -286,8 +286,8 @@ pub fn markImportExports(self: *SharedObject, elf_file: *Elf) void {
286 for (0..self.symbols.items.len) |i| {286 for (0..self.symbols.items.len) |i| {
287 const ref = self.resolveSymbol(@intCast(i), elf_file);287 const ref = self.resolveSymbol(@intCast(i), elf_file);
288 const ref_sym = elf_file.symbol(ref) orelse continue;288 const ref_sym = elf_file.symbol(ref) orelse continue;
289 const ref_file = ref_sym.file(self).?;289 const ref_file = ref_sym.file(elf_file).?;
290 const vis = @as(elf.STV, @enumFromInt(ref_sym.elfSym(self).st_other));290 const vis = @as(elf.STV, @enumFromInt(ref_sym.elfSym(elf_file).st_other));
291 if (ref_file != .shared_object and vis != .HIDDEN) ref_sym.flags.@"export" = true;291 if (ref_file != .shared_object and vis != .HIDDEN) ref_sym.flags.@"export" = true;
292 }292 }
293}293}
...@@ -349,9 +349,12 @@ pub fn initSymbolAliases(self: *SharedObject, elf_file: *Elf) !void {...@@ -349,9 +349,12 @@ pub fn initSymbolAliases(self: *SharedObject, elf_file: *Elf) !void {
349 assert(self.aliases == null);349 assert(self.aliases == null);
350350
351 const SortAlias = struct {351 const SortAlias = struct {
352 pub fn lessThan(ctx: *Elf, lhs: Symbol.Index, rhs: Symbol.Index) bool {352 so: *SharedObject,
353 const lhs_sym = ctx.symbol(lhs).elfSym(ctx);353 ef: *Elf,
354 const rhs_sym = ctx.symbol(rhs).elfSym(ctx);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);
355 return lhs_sym.st_value < rhs_sym.st_value;358 return lhs_sym.st_value < rhs_sym.st_value;
356 }359 }
357 };360 };
...@@ -362,14 +365,14 @@ pub fn initSymbolAliases(self: *SharedObject, elf_file: *Elf) !void {...@@ -362,14 +365,14 @@ pub fn initSymbolAliases(self: *SharedObject, elf_file: *Elf) !void {
362 defer aliases.deinit();365 defer aliases.deinit();
363 try aliases.ensureTotalCapacityPrecise(self.symbols.items.len);366 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| {
366 const ref = elf_file.resolver.get(resolv).?;369 const ref = elf_file.resolver.get(resolv).?;
367 const ref_sym = elf_file.symbol(ref) orelse continue;370 const ref_sym = elf_file.symbol(ref) orelse continue;
368 if (ref_sym.file(elf_file).?.index() != self.index) continue;371 if (ref_sym.file(elf_file).?.index() != self.index) continue;
369 aliases.appendAssumeCapacity(index);372 aliases.appendAssumeCapacity(@intCast(index));
370 }373 }
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
374 self.aliases = aliases.moveToUnmanaged();377 self.aliases = aliases.moveToUnmanaged();
375}378}
...@@ -377,16 +380,16 @@ pub fn initSymbolAliases(self: *SharedObject, elf_file: *Elf) !void {...@@ -377,16 +380,16 @@ pub fn initSymbolAliases(self: *SharedObject, elf_file: *Elf) !void {
377pub fn symbolAliases(self: *SharedObject, index: u32, elf_file: *Elf) []const u32 {380pub fn symbolAliases(self: *SharedObject, index: u32, elf_file: *Elf) []const u32 {
378 assert(self.aliases != null);381 assert(self.aliases != null);
379382
380 const symbol = self.symbol(index).elfSym(elf_file);383 const symbol = self.symbols.items[index].elfSym(elf_file);
381 const aliases = self.aliases.?;384 const aliases = self.aliases.?;
382385
383 const start = for (aliases.items, 0..) |alias, i| {386 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);
385 if (symbol.st_value == alias_sym.st_value) break i;388 if (symbol.st_value == alias_sym.st_value) break i;
386 } else aliases.items.len;389 } else aliases.items.len;
387390
388 const end = for (aliases.items[start..], 0..) |alias, i| {391 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);
390 if (symbol.st_value < alias_sym.st_value) break i + start;393 if (symbol.st_value < alias_sym.st_value) break i + start;
391 } else aliases.items.len;394 } else aliases.items.len;
392395
...@@ -403,8 +406,12 @@ pub fn resolveSymbol(self: SharedObject, index: Symbol.Index, elf_file: *Elf) El...@@ -403,8 +406,12 @@ pub fn resolveSymbol(self: SharedObject, index: Symbol.Index, elf_file: *Elf) El
403 return elf_file.resolver.get(resolv).?;406 return elf_file.resolver.get(resolv).?;
404}407}
405408
406pub fn addSymbol(self: *SharedObject, allocator: Allocator) !Symbol.Index {409fn addSymbol(self: *SharedObject, allocator: Allocator) !Symbol.Index {
407 try self.symbols.ensureUnusedCapacity(allocator, 1);410 try self.symbols.ensureUnusedCapacity(allocator, 1);
411 return self.addSymbolAssumeCapacity();
412}
413
414fn addSymbolAssumeCapacity(self: *SharedObject) Symbol.Index {
408 const index: Symbol.Index = @intCast(self.symbols.items.len);415 const index: Symbol.Index = @intCast(self.symbols.items.len);
409 self.symbols.appendAssumeCapacity(.{ .file_index = self.index });416 self.symbols.appendAssumeCapacity(.{ .file_index = self.index });
410 return index;417 return index;
...@@ -486,10 +493,10 @@ fn formatSymtab(...@@ -486,10 +493,10 @@ fn formatSymtab(
486 _ = unused_fmt_string;493 _ = unused_fmt_string;
487 _ = options;494 _ = options;
488 const shared = ctx.shared;495 const shared = ctx.shared;
496 const elf_file = ctx.elf_file;
489 try writer.writeAll(" globals\n");497 try writer.writeAll(" globals\n");
490 for (shared.symbols.items) |index| {498 for (shared.symbols.items) |sym| {
491 const global = ctx.elf_file.symbol(index);499 try writer.print(" {}\n", .{sym.fmt(elf_file)});
492 try writer.print(" {}\n", .{global.fmt(ctx.elf_file)});
493 }500 }
494}501}
495502
src/link/Elf/Symbol.zig+8-3
...@@ -86,6 +86,7 @@ pub fn file(symbol: Symbol, elf_file: *Elf) ?File {...@@ -86,6 +86,7 @@ pub fn file(symbol: Symbol, elf_file: *Elf) ?File {
8686
87pub fn elfSym(symbol: Symbol, elf_file: *Elf) elf.Elf64_Sym {87pub fn elfSym(symbol: Symbol, elf_file: *Elf) elf.Elf64_Sym {
88 return switch (symbol.file(elf_file).?) {88 return switch (symbol.file(elf_file).?) {
89 .zig_object => |x| x.symtab.items(.elf_sym)[symbol.esym_index],
89 inline else => |x| x.symtab.items[symbol.esym_index],90 inline else => |x| x.symtab.items[symbol.esym_index],
90 };91 };
91}92}
...@@ -261,7 +262,7 @@ const AddExtraOpts = struct {...@@ -261,7 +262,7 @@ const AddExtraOpts = struct {
261 zig_got: ?u32 = null,262 zig_got: ?u32 = null,
262};263};
263264
264pub fn addExtra(symbol: *Symbol, opts: AddExtraOpts, elf_file: *Elf) !void {265pub fn addExtra(symbol: *Symbol, opts: AddExtraOpts, elf_file: *Elf) void {
265 var extras = symbol.extra(elf_file);266 var extras = symbol.extra(elf_file);
266 inline for (@typeInfo(@TypeOf(opts)).Struct.fields) |field| {267 inline for (@typeInfo(@TypeOf(opts)).Struct.fields) |field| {
267 if (@field(opts, field.name)) |x| {268 if (@field(opts, field.name)) |x| {
...@@ -272,11 +273,15 @@ pub fn addExtra(symbol: *Symbol, opts: AddExtraOpts, elf_file: *Elf) !void {...@@ -272,11 +273,15 @@ pub fn addExtra(symbol: *Symbol, opts: AddExtraOpts, elf_file: *Elf) !void {
272}273}
273274
274pub fn extra(symbol: Symbol, elf_file: *Elf) Extra {275pub 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 };
276}279}
277280
278pub fn setExtra(symbol: Symbol, extras: Extra, elf_file: *Elf) void {281pub 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 };
280}285}
281286
282pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {287pub 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 {...@@ -89,19 +89,11 @@ pub fn init(self: *ZigObject, elf_file: *Elf) !void {
89 try self.strtab.buffer.append(gpa, 0);89 try self.strtab.buffer.append(gpa, 0);
9090
91 const name_off = try self.strtab.insert(gpa, self.path);91 const name_off = try self.strtab.insert(gpa, self.path);
92 const symbol_index = try elf_file.addSymbol();92 const symbol_index = try self.newLocalSymbol(gpa, name_off);
93 try self.local_symbols.append(gpa, symbol_index);93 const sym = self.symbol(symbol_index);
94 const symbol_ptr = elf_file.symbol(symbol_index);94 const esym = &self.symtab.items(.elf_sym)[sym.esym_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;
102 esym.st_info = elf.STT_FILE;95 esym.st_info = elf.STT_FILE;
103 esym.st_shndx = elf.SHN_ABS;96 esym.st_shndx = elf.SHN_ABS;
104 symbol_ptr.esym_index = esym_index;
10597
106 switch (comp.config.debug_format) {98 switch (comp.config.debug_format) {
107 .strip => {},99 .strip => {},
...@@ -275,7 +267,7 @@ fn newSymbol(self: *ZigObject, allocator: Allocator, name_off: u32, st_bind: u4)...@@ -275,7 +267,7 @@ fn newSymbol(self: *ZigObject, allocator: Allocator, name_off: u32, st_bind: u4)
275 const index = self.addSymbolAssumeCapacity();267 const index = self.addSymbolAssumeCapacity();
276 const sym = &self.symbols.items[index];268 const sym = &self.symbols.items[index];
277 sym.name_offset = name_off;269 sym.name_offset = name_off;
278 sym.extra = self.addSymbolExtraAssumeCapacity(.{});270 sym.extra_index = self.addSymbolExtraAssumeCapacity(.{});
279271
280 const esym_idx: u32 = @intCast(self.symtab.addOneAssumeCapacity());272 const esym_idx: u32 = @intCast(self.symtab.addOneAssumeCapacity());
281 const esym = ElfSym{ .elf_sym = .{273 const esym = ElfSym{ .elf_sym = .{
...@@ -377,7 +369,7 @@ pub fn resolveSymbols(self: *ZigObject, elf_file: *Elf) !void {...@@ -377,7 +369,7 @@ pub fn resolveSymbols(self: *ZigObject, elf_file: *Elf) !void {
377 continue;369 continue;
378 }370 }
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)) {
381 gop.ref.* = .{ .index = @intCast(i | global_symbol_bit), .file = self.index };373 gop.ref.* = .{ .index = @intCast(i | global_symbol_bit), .file = self.index };
382 }374 }
383 }375 }
...@@ -428,7 +420,7 @@ pub fn claimUnresolvedObject(self: ZigObject, elf_file: *Elf) void {...@@ -428,7 +420,7 @@ pub fn claimUnresolvedObject(self: ZigObject, elf_file: *Elf) void {
428 global.file_index = self.index;420 global.file_index = self.index;
429421
430 const idx = self.symbols_resolver.items[i];422 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 };
432 }424 }
433}425}
434426
...@@ -450,6 +442,64 @@ pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void {...@@ -450,6 +442,64 @@ pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void {
450 }442 }
451}443}
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
453pub fn markLive(self: *ZigObject, elf_file: *Elf) void {503pub fn markLive(self: *ZigObject, elf_file: *Elf) void {
454 for (self.global_symbols.items, 0..) |index, i| {504 for (self.global_symbols.items, 0..) |index, i| {
455 const global = self.symbols.items[index];505 const global = self.symbols.items[index];
...@@ -468,7 +518,7 @@ pub fn markLive(self: *ZigObject, elf_file: *Elf) void {...@@ -468,7 +518,7 @@ pub fn markLive(self: *ZigObject, elf_file: *Elf) void {
468 }518 }
469}519}
470520
471pub fn markImportsExports(self: *Object, elf_file: *Elf) void {521pub fn markImportsExports(self: *ZigObject, elf_file: *Elf) void {
472 for (0..self.global_symbols.items.len) |i| {522 for (0..self.global_symbols.items.len) |i| {
473 const ref = self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file);523 const ref = self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file);
474 const sym = elf_file.symbol(ref) orelse continue;524 const sym = elf_file.symbol(ref) orelse continue;
...@@ -604,7 +654,7 @@ pub fn updateSymtabSize(self: *ZigObject, elf_file: *Elf) !void {...@@ -604,7 +654,7 @@ pub fn updateSymtabSize(self: *ZigObject, elf_file: *Elf) !void {
604654
605 for (self.global_symbols.items, self.symbols_resolver.items) |index, resolv| {655 for (self.global_symbols.items, self.symbols_resolver.items) |index, resolv| {
606 const global = &self.symbols.items[index];656 const global = &self.symbols.items[index];
607 const ref = elf_file.resolver.items[resolv];657 const ref = elf_file.resolver.values.items[resolv];
608 const ref_sym = elf_file.symbol(ref) orelse continue;658 const ref_sym = elf_file.symbol(ref) orelse continue;
609 if (ref_sym.file(elf_file).?.index() != self.index) continue;659 if (ref_sym.file(elf_file).?.index() != self.index) continue;
610 if (global.atom(elf_file)) |atom_ptr| if (!atom_ptr.alive) continue;660 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 {...@@ -633,7 +683,7 @@ pub fn writeSymtab(self: ZigObject, elf_file: *Elf) void {
633683
634 for (self.global_symbols.items, self.symbols_resolver.items) |index, resolv| {684 for (self.global_symbols.items, self.symbols_resolver.items) |index, resolv| {
635 const global = self.symbols.items[index];685 const global = self.symbols.items[index];
636 const ref = elf_file.resolver.items[resolv];686 const ref = elf_file.resolver.values.items[resolv];
637 const ref_sym = elf_file.symbol(ref) orelse continue;687 const ref_sym = elf_file.symbol(ref) orelse continue;
638 if (ref_sym.file(elf_file).?.index() != self.index) continue;688 if (ref_sym.file(elf_file).?.index() != self.index) continue;
639 const idx = global.outputSymtabIndex(elf_file) orelse continue;689 const idx = global.outputSymtabIndex(elf_file) orelse continue;
...@@ -678,13 +728,13 @@ pub fn getDeclVAddr(...@@ -678,13 +728,13 @@ pub fn getDeclVAddr(
678 reloc_info: link.File.RelocInfo,728 reloc_info: link.File.RelocInfo,
679) !u64 {729) !u64 {
680 const this_sym_index = try self.getOrCreateMetadataForDecl(elf_file, decl_index);730 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);
682 const vaddr = this_sym.address(.{}, elf_file);732 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).?;
684 const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);734 const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);
685 try parent_atom.addReloc(elf_file, .{735 try parent_atom.addReloc(elf_file, .{
686 .r_offset = reloc_info.offset,736 .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,
688 .r_addend = reloc_info.addend,738 .r_addend = reloc_info.addend,
689 });739 });
690 return @intCast(vaddr);740 return @intCast(vaddr);
...@@ -697,13 +747,13 @@ pub fn getAnonDeclVAddr(...@@ -697,13 +747,13 @@ pub fn getAnonDeclVAddr(
697 reloc_info: link.File.RelocInfo,747 reloc_info: link.File.RelocInfo,
698) !u64 {748) !u64 {
699 const sym_index = self.anon_decls.get(decl_val).?.symbol_index;749 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);
701 const vaddr = sym.address(.{}, elf_file);751 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).?;
703 const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);753 const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);
704 try parent_atom.addReloc(elf_file, .{754 try parent_atom.addReloc(elf_file, .{
705 .r_offset = reloc_info.offset,755 .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,
707 .r_addend = reloc_info.addend,757 .r_addend = reloc_info.addend,
708 });758 });
709 return @intCast(vaddr);759 return @intCast(vaddr);
...@@ -725,7 +775,7 @@ pub fn lowerAnonDecl(...@@ -725,7 +775,7 @@ pub fn lowerAnonDecl(
725 else => explicit_alignment,775 else => explicit_alignment,
726 };776 };
727 if (self.anon_decls.get(decl_val)) |metadata| {777 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;
729 if (decl_alignment.order(existing_alignment).compare(.lte))779 if (decl_alignment.order(existing_alignment).compare(.lte))
730 return .ok;780 return .ok;
731 }781 }
...@@ -811,11 +861,10 @@ fn freeUnnamedConsts(self: *ZigObject, elf_file: *Elf, decl_index: InternPool.De...@@ -811,11 +861,10 @@ fn freeUnnamedConsts(self: *ZigObject, elf_file: *Elf, decl_index: InternPool.De
811}861}
812862
813fn freeDeclMetadata(self: *ZigObject, elf_file: *Elf, sym_index: Symbol.Index) void {863fn freeDeclMetadata(self: *ZigObject, elf_file: *Elf, sym_index: Symbol.Index) void {
814 _ = self;864 const sym = self.symbol(sym_index);
815 const sym = elf_file.symbol(sym_index);
816 sym.atom(elf_file).?.free(elf_file);865 sym.atom(elf_file).?.free(elf_file);
817 log.debug("adding %{d} to local symbols free list", .{sym_index});866 log.debug("adding %{d} to local symbols free list", .{sym_index});
818 elf_file.symbols.items[sym_index] = .{};867 self.symbols.items[sym_index] = .{};
819 // TODO free GOT entry here868 // TODO free GOT entry here
820}869}
821870
...@@ -940,8 +989,8 @@ fn updateDeclCode(...@@ -940,8 +989,8 @@ fn updateDeclCode(
940 target_util.minFunctionAlignment(mod.getTarget()),989 target_util.minFunctionAlignment(mod.getTarget()),
941 );990 );
942991
943 const sym = elf_file.symbol(sym_index);992 const sym = self.symbol(sym_index);
944 const esym = &self.local_esyms.items(.elf_sym)[sym.esym_index];993 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
945 const atom_ptr = sym.atom(elf_file).?;994 const atom_ptr = sym.atom(elf_file).?;
946 const name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));995 const name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
947996
...@@ -1038,8 +1087,8 @@ fn updateTlv(...@@ -1038,8 +1087,8 @@ fn updateTlv(
10381087
1039 const required_alignment = decl.getAlignment(pt);1088 const required_alignment = decl.getAlignment(pt);
10401089
1041 const sym = elf_file.symbol(sym_index);1090 const sym = self.symbol(sym_index);
1042 const esym = &self.local_esyms.items(.elf_sym)[sym.esym_index];1091 const esym = &self.symtab.items(.elf_sym)[sym.esym_index];
1043 const atom_ptr = sym.atom(elf_file).?;1092 const atom_ptr = sym.atom(elf_file).?;
1044 const name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));1093 const name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
10451094
...@@ -1264,9 +1313,9 @@ fn updateLazySymbol(...@@ -1264,9 +1313,9 @@ fn updateLazySymbol(
1264 .code => elf_file.zig_text_section_index.?,1313 .code => elf_file.zig_text_section_index.?,
1265 .const_data => elf_file.zig_data_rel_ro_section_index.?,1314 .const_data => elf_file.zig_data_rel_ro_section_index.?,
1266 };1315 };
1267 const local_sym = elf_file.symbol(symbol_index);1316 const local_sym = self.symbol(symbol_index);
1268 local_sym.name_offset = name_str_index;1317 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];
1270 local_esym.st_name = name_str_index;1319 local_esym.st_name = name_str_index;
1271 local_esym.st_info |= elf.STT_OBJECT;1320 local_esym.st_info |= elf.STT_OBJECT;
1272 local_esym.st_size = code.len;1321 local_esym.st_size = code.len;
...@@ -1372,7 +1421,7 @@ fn lowerConst(...@@ -1372,7 +1421,7 @@ fn lowerConst(
1372 };1421 };
13731422
1374 const local_sym = self.symbol(sym_index);1423 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];
1376 local_esym.st_info |= elf.STT_OBJECT;1425 local_esym.st_info |= elf.STT_OBJECT;
1377 local_esym.st_size = code.len;1426 local_esym.st_size = code.len;
1378 const atom_ptr = local_sym.atom(elf_file).?;1427 const atom_ptr = local_sym.atom(elf_file).?;
...@@ -1473,9 +1522,9 @@ pub fn updateExports(...@@ -1473,9 +1522,9 @@ pub fn updateExports(
1473 const global_sym = self.symbol(global_sym_index);1522 const global_sym = self.symbol(global_sym_index);
1474 global_sym.value = value;1523 global_sym.value = value;
1475 global_sym.flags.weak = exp.opts.linkage == .weak;1524 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;
1477 global_sym.ref = .{ .index = esym_shndx, .file = self.index };1526 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];
1479 global_esym.st_value = @intCast(value);1528 global_esym.st_value = @intCast(value);
1480 global_esym.st_shndx = esym.st_shndx;1529 global_esym.st_shndx = esym.st_shndx;
1481 global_esym.st_info = (stb_bits << 4) | stt_bits;1530 global_esym.st_info = (stb_bits << 4) | stt_bits;
...@@ -1517,16 +1566,16 @@ pub fn deleteExport(...@@ -1517,16 +1566,16 @@ pub fn deleteExport(
1517 const exp_name = name.toSlice(&mod.intern_pool);1566 const exp_name = name.toSlice(&mod.intern_pool);
1518 const esym_index = metadata.@"export"(self, exp_name) orelse return;1567 const esym_index = metadata.@"export"(self, exp_name) orelse return;
1519 log.debug("deleting export '{s}'", .{exp_name});1568 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.*];
1521 _ = self.globals_lookup.remove(esym.st_name);1570 _ = self.globals_lookup.remove(esym.st_name);
1522 const sym_index = elf_file.resolver.get(esym.st_name).?;1571 // const sym_index = elf_file.resolver.get(esym.st_name).?;
1523 const sym = elf_file.symbol(sym_index);1572 // const sym = elf_file.symbol(sym_index);
1524 if (sym.file_index == self.index) {1573 // if (sym.file_index == self.index) {
1525 _ = elf_file.resolver.swapRemove(esym.st_name);1574 // _ = elf_file.resolver.swapRemove(esym.st_name);
1526 sym.* = .{};1575 // sym.* = .{};
1527 }1576 // }
1528 esym.* = Elf.null_sym;1577 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;
1530}1579}
15311580
1532pub fn getGlobalSymbol(self: *ZigObject, elf_file: *Elf, name: []const u8, lib_name: ?[]const u8) !u32 {1581pub 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...@@ -1535,7 +1584,7 @@ pub fn getGlobalSymbol(self: *ZigObject, elf_file: *Elf, name: []const u8, lib_n
1535 const off = try self.strtab.insert(gpa, name);1584 const off = try self.strtab.insert(gpa, name);
1536 const lookup_gop = try self.globals_lookup.getOrPut(gpa, off);1585 const lookup_gop = try self.globals_lookup.getOrPut(gpa, off);
1537 if (!lookup_gop.found_existing) {1586 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);
1539 }1588 }
1540 return lookup_gop.value_ptr.*;1589 return lookup_gop.value_ptr.*;
1541}1590}
...@@ -1636,8 +1685,12 @@ pub fn resolveSymbol(self: ZigObject, index: Symbol.Index, elf_file: *Elf) Elf.R...@@ -1636,8 +1685,12 @@ pub fn resolveSymbol(self: ZigObject, index: Symbol.Index, elf_file: *Elf) Elf.R
1636 return .{ .index = index, .file = self.index };1685 return .{ .index = index, .file = self.index };
1637}1686}
16381687
1639pub fn addSymbol(self: *ZigObject, allocator: Allocator) !Symbol.Index {1688fn addSymbol(self: *ZigObject, allocator: Allocator) !Symbol.Index {
1640 try self.symbols.ensureUnusedCapacity(allocator, 1);1689 try self.symbols.ensureUnusedCapacity(allocator, 1);
1690 return self.addSymbolAssumeCapacity();
1691}
1692
1693fn addSymbolAssumeCapacity(self: *ZigObject) Symbol.Index {
1641 const index: Symbol.Index = @intCast(self.symbols.items.len);1694 const index: Symbol.Index = @intCast(self.symbols.items.len);
1642 self.symbols.appendAssumeCapacity(.{ .file_index = self.index });1695 self.symbols.appendAssumeCapacity(.{ .file_index = self.index });
1643 return index;1696 return index;
...@@ -1705,15 +1758,17 @@ fn formatSymtab(...@@ -1705,15 +1758,17 @@ fn formatSymtab(
1705) !void {1758) !void {
1706 _ = unused_fmt_string;1759 _ = unused_fmt_string;
1707 _ = options;1760 _ = options;
1761 const self = ctx.self;
1762 const elf_file = ctx.elf_file;
1708 try writer.writeAll(" locals\n");1763 try writer.writeAll(" locals\n");
1709 for (ctx.self.locals()) |index| {1764 for (self.local_symbols.items) |index| {
1710 const local = ctx.elf_file.symbol(index);1765 const local = self.symbols.items[index];
1711 try writer.print(" {}\n", .{local.fmt(ctx.elf_file)});1766 try writer.print(" {}\n", .{local.fmt(elf_file)});
1712 }1767 }
1713 try writer.writeAll(" globals\n");1768 try writer.writeAll(" globals\n");
1714 for (ctx.self.globals()) |index| {1769 for (ctx.self.global_symbols.items) |index| {
1715 const global = ctx.elf_file.symbol(index);1770 const global = self.symbols.items[index];
1716 try writer.print(" {}\n", .{global.fmt(ctx.elf_file)});1771 try writer.print(" {}\n", .{global.fmt(elf_file)});
1717 }1772 }
1718}1773}
17191774
...@@ -1759,7 +1814,7 @@ const DeclMetadata = struct {...@@ -1759,7 +1814,7 @@ const DeclMetadata = struct {
17591814
1760 fn @"export"(m: DeclMetadata, zo: *ZigObject, name: []const u8) ?*u32 {1815 fn @"export"(m: DeclMetadata, zo: *ZigObject, name: []const u8) ?*u32 {
1761 for (m.exports.items) |*exp| {1816 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);
1763 if (mem.eql(u8, name, exp_name)) return exp;1818 if (mem.eql(u8, name, exp_name)) return exp;
1764 }1819 }
1765 return null;1820 return null;
src/link/Elf/eh_frame.zig+10-5
...@@ -339,7 +339,8 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {...@@ -339,7 +339,8 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
339 const contents = cie.data(elf_file);339 const contents = cie.data(elf_file);
340340
341 for (cie.relocs(elf_file)) |rel| {341 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).?;
343 resolveReloc(cie, sym, rel, elf_file, contents) catch |err| switch (err) {344 resolveReloc(cie, sym, rel, elf_file, contents) catch |err| switch (err) {
344 error.RelocFailure => has_reloc_errors = true,345 error.RelocFailure => has_reloc_errors = true,
345 else => |e| return e,346 else => |e| return e,
...@@ -366,7 +367,8 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {...@@ -366,7 +367,8 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
366 );367 );
367368
368 for (fde.relocs(elf_file)) |rel| {369 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).?;
370 resolveReloc(fde, sym, rel, elf_file, contents) catch |err| switch (err) {372 resolveReloc(fde, sym, rel, elf_file, contents) catch |err| switch (err) {
371 error.RelocFailure => has_reloc_errors = true,373 error.RelocFailure => has_reloc_errors = true,
372 else => |e| return e,374 else => |e| return e,
...@@ -452,7 +454,8 @@ pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void {...@@ -452,7 +454,8 @@ pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void {
452 for (object.cies.items) |cie| {454 for (object.cies.items) |cie| {
453 if (!cie.alive) continue;455 if (!cie.alive) continue;
454 for (cie.relocs(elf_file)) |rel| {456 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).?;
456 const out_rel = emitReloc(elf_file, cie, sym, rel);459 const out_rel = emitReloc(elf_file, cie, sym, rel);
457 try writer.writeStruct(out_rel);460 try writer.writeStruct(out_rel);
458 }461 }
...@@ -461,7 +464,8 @@ pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void {...@@ -461,7 +464,8 @@ pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void {
461 for (object.fdes.items) |fde| {464 for (object.fdes.items) |fde| {
462 if (!fde.alive) continue;465 if (!fde.alive) continue;
463 for (fde.relocs(elf_file)) |rel| {466 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).?;
465 const out_rel = emitReloc(elf_file, fde, sym, rel);469 const out_rel = emitReloc(elf_file, fde, sym, rel);
466 try writer.writeStruct(out_rel);470 try writer.writeStruct(out_rel);
467 }471 }
...@@ -513,7 +517,8 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void {...@@ -513,7 +517,8 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void {
513 const relocs = fde.relocs(elf_file);517 const relocs = fde.relocs(elf_file);
514 assert(relocs.len > 0); // Should this be an error? Things are completely broken anyhow if this trips...518 assert(relocs.len > 0); // Should this be an error? Things are completely broken anyhow if this trips...
515 const rel = relocs[0];519 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).?;
517 const P = @as(i64, @intCast(fde.address(elf_file)));522 const P = @as(i64, @intCast(fde.address(elf_file)));
518 const S = @as(i64, @intCast(sym.address(.{}, elf_file)));523 const S = @as(i64, @intCast(sym.address(.{}, elf_file)));
519 const A = rel.r_addend;524 const A = rel.r_addend;
src/link/Elf/file.zig+18-5
...@@ -61,10 +61,10 @@ pub const File = union(enum) {...@@ -61,10 +61,10 @@ pub const File = union(enum) {
61 return (@as(u32, base) << 24) + file.index();61 return (@as(u32, base) << 24) + file.index();
62 }62 }
6363
64 pub fn resolveSymbols(file: File, elf_file: *Elf) void {64 pub fn resolveSymbols(file: File, elf_file: *Elf) !void {
65 switch (file) {65 return switch (file) {
66 inline else => |x| x.resolveSymbols(elf_file),66 inline else => |x| x.resolveSymbols(elf_file),
67 }67 };
68 }68 }
6969
70 pub fn resetGlobals(file: File, elf_file: *Elf) void {70 pub fn resetGlobals(file: File, elf_file: *Elf) void {
...@@ -100,6 +100,13 @@ pub const File = union(enum) {...@@ -100,6 +100,13 @@ pub const File = union(enum) {
100 }100 }
101 }101 }
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
103 pub fn atom(file: File, atom_index: Atom.Index) ?*Atom {110 pub fn atom(file: File, atom_index: Atom.Index) ?*Atom {
104 return switch (file) {111 return switch (file) {
105 .shared_object => unreachable,112 .shared_object => unreachable,
...@@ -146,10 +153,16 @@ pub const File = union(enum) {...@@ -146,10 +153,16 @@ pub const File = union(enum) {
146 };153 };
147 }154 }
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 {
150 return switch (file) {163 return switch (file) {
151 .zig_object => |x| x.symbol(ind),164 .zig_object => |x| x.symbol(ind),
152 inline else => |x| x.symbols.items[ind],165 inline else => |x| &x.symbols.items[ind],
153 };166 };
154 }167 }
155168
src/link/Elf/gc.zig+81-58
...@@ -1,71 +1,84 @@...@@ -1,71 +1,84 @@
1pub fn gcAtoms(elf_file: *Elf) !void {1pub fn gcAtoms(elf_file: *Elf) !void {
2 const comp = elf_file.base.comp;2 const comp = elf_file.base.comp;
3 const gpa = comp.gpa;3 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
10 var roots = std.ArrayList(*Atom).init(gpa);4 var roots = std.ArrayList(*Atom).init(gpa);
11 defer roots.deinit();5 defer roots.deinit();
12 try collectRoots(&roots, files.items, elf_file);6 try collectRoots(&roots, elf_file);
13
14 mark(roots, elf_file);7 mark(roots, elf_file);
15 prune(files.items, elf_file);8 prune(elf_file);
16}9}
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 {
19 if (elf_file.linkerDefinedPtr()) |obj| {12 if (elf_file.linkerDefinedPtr()) |obj| {
20 if (obj.entry_index) |index| {13 if (obj.entrySymbol(elf_file)) |sym| {
21 const global = elf_file.symbol(index);14 try markSymbol(sym, roots, elf_file);
22 try markSymbol(global, roots, elf_file);
23 }15 }
24 }16 }
2517
26 for (files) |index| {18 if (elf_file.zigObjectPtr()) |zo| {
27 for (elf_file.file(index).?.globals()) |global_index| {19 for (0..zo.global_symbols.items.len) |i| {
28 const global = elf_file.symbol(global_index);20 const ref = zo.resolveSymbol(@intCast(i | ZigObject.global_symbol_bit), elf_file);
29 if (global.file(elf_file)) |file| {21 const sym = elf_file.symbol(ref) orelse continue;
30 if (file.index() == index and global.flags.@"export")22 if (sym.file(elf_file).?.index() != zo.index) continue;
31 try markSymbol(global, roots, elf_file);23 if (sym.flags.@"export") {
24 try markSymbol(sym, roots, elf_file);
32 }25 }
33 }26 }
34 }27 }
3528
36 for (files) |index| {29 for (elf_file.objects.items) |index| {
37 const file = elf_file.file(index).?;30 const object = elf_file.file(index).?.object;
3831 for (0..object.globals().len) |i| {
39 for (file.atoms()) |atom_index| {32 const ref = object.resolveSymbol(@intCast(i), elf_file);
40 const atom = file.atom(atom_index) orelse continue;33 const sym = elf_file.symbol(ref) orelse continue;
41 if (!atom.alive) continue;34 if (sym.file(elf_file).?.index() != object.index) continue;
4235 if (sym.flags.@"export") {
43 const shdr = atom.inputShdr(elf_file);36 try markSymbol(sym, roots, elf_file);
44 const name = atom.name(elf_file);37 }
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;
60 }38 }
39 }
6140
62 // Mark every atom referenced by CIE as alive.41 const atomRoots = struct {
63 for (file.cies()) |cie| {42 fn atomRoots(file: File, rs: anytype, ef: *Elf) !void {
64 for (cie.relocs(elf_file)) |rel| {43 for (file.atoms()) |atom_index| {
65 const sym = elf_file.symbol(file.symbol(rel.r_sym()));44 const atom = file.atom(atom_index) orelse continue;
66 try markSymbol(sym, roots, elf_file);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 }
67 }73 }
68 }74 }
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);
69 }82 }
70}83}
7184
...@@ -92,7 +105,8 @@ fn markLive(atom: *Atom, elf_file: *Elf) void {...@@ -92,7 +105,8 @@ fn markLive(atom: *Atom, elf_file: *Elf) void {
92105
93 for (atom.fdes(elf_file)) |fde| {106 for (atom.fdes(elf_file)) |fde| {
94 for (fde.relocs(elf_file)[1..]) |rel| {107 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;
96 const target_atom = target_sym.atom(elf_file) orelse continue;110 const target_atom = target_sym.atom(elf_file) orelse continue;
97 target_atom.alive = true;111 target_atom.alive = true;
98 gc_track_live_log.debug("{}marking live atom({d})", .{ track_live_level, target_atom.atom_index });112 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 {...@@ -101,7 +115,8 @@ fn markLive(atom: *Atom, elf_file: *Elf) void {
101 }115 }
102116
103 for (atom.relocs(elf_file)) |rel| {117 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;
105 if (target_sym.mergeSubsection(elf_file)) |msub| {120 if (target_sym.mergeSubsection(elf_file)) |msub| {
106 msub.alive = true;121 msub.alive = true;
107 continue;122 continue;
...@@ -120,16 +135,23 @@ fn mark(roots: std.ArrayList(*Atom), elf_file: *Elf) void {...@@ -120,16 +135,23 @@ fn mark(roots: std.ArrayList(*Atom), elf_file: *Elf) void {
120 }135 }
121}136}
122137
123fn prune(files: []const File.Index, elf_file: *Elf) void {138fn prune(elf_file: *Elf) void {
124 for (files) |index| {139 const pruneInFile = struct {
125 const file = elf_file.file(index).?;140 fn pruneInFile(file: File, ef: *Elf) void {
126 for (file.atoms()) |atom_index| {141 for (file.atoms()) |atom_index| {
127 const atom = file.atom(atom_index) orelse continue;142 const atom = file.atom(atom_index) orelse continue;
128 if (atom.alive and !atom.visited) {143 if (atom.alive and !atom.visited) {
129 atom.alive = false;144 atom.alive = false;
130 atom.markFdesDead(elf_file);145 atom.markFdesDead(ef);
146 }
131 }147 }
132 }148 }
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);
133 }155 }
134}156}
135157
...@@ -181,3 +203,4 @@ const Atom = @import("Atom.zig");...@@ -181,3 +203,4 @@ const Atom = @import("Atom.zig");
181const Elf = @import("../Elf.zig");203const Elf = @import("../Elf.zig");
182const File = @import("file.zig").File;204const File = @import("file.zig").File;
183const Symbol = @import("Symbol.zig");205const 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...@@ -37,7 +37,7 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation, module_obj_path: ?[]co
3737
38 // First, we flush relocatable object file generated with our backends.38 // First, we flush relocatable object file generated with our backends.
39 if (elf_file.zigObjectPtr()) |zig_object| {39 if (elf_file.zigObjectPtr()) |zig_object| {
40 zig_object.resolveSymbols(elf_file);40 try zig_object.resolveSymbols(elf_file);
41 try elf_file.addCommentString();41 try elf_file.addCommentString();
42 try elf_file.finalizeMergeSections();42 try elf_file.finalizeMergeSections();
43 zig_object.claimUnresolvedObject(elf_file);43 zig_object.claimUnresolvedObject(elf_file);
...@@ -383,7 +383,7 @@ fn updateComdatGroupsSizes(elf_file: *Elf) void {...@@ -383,7 +383,7 @@ fn updateComdatGroupsSizes(elf_file: *Elf) void {
383 shdr.sh_size = cg.size(elf_file);383 shdr.sh_size = cg.size(elf_file);
384 shdr.sh_link = elf_file.symtab_section_index.?;384 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);
387 shdr.sh_info = sym.outputSymtabIndex(elf_file) orelse387 shdr.sh_info = sym.outputSymtabIndex(elf_file) orelse
388 elf_file.sectionSymbolOutputSymtabIndex(sym.outputShndx(elf_file).?);388 elf_file.sectionSymbolOutputSymtabIndex(sym.outputShndx(elf_file).?);
389 }389 }
src/link/Elf/synthetic_sections.zig+125-130
...@@ -251,15 +251,16 @@ pub const ZigGotSection = struct {...@@ -251,15 +251,16 @@ pub const ZigGotSection = struct {
251 pub fn addSymbol(zig_got: *ZigGotSection, sym_index: Symbol.Index, elf_file: *Elf) !Index {251 pub fn addSymbol(zig_got: *ZigGotSection, sym_index: Symbol.Index, elf_file: *Elf) !Index {
252 const comp = elf_file.base.comp;252 const comp = elf_file.base.comp;
253 const gpa = comp.gpa;253 const gpa = comp.gpa;
254 const zo = elf_file.zigObjectPtr().?;
254 const index = try zig_got.allocateEntry(gpa);255 const index = try zig_got.allocateEntry(gpa);
255 const entry = &zig_got.entries.items[index];256 const entry = &zig_got.entries.items[index];
256 entry.* = sym_index;257 entry.* = sym_index;
257 const symbol = elf_file.symbol(sym_index);258 const symbol = zo.symbol(sym_index);
258 symbol.flags.has_zig_got = true;259 symbol.flags.has_zig_got = true;
259 if (elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) {260 if (elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) {
260 zig_got.flags.needs_rela = true;261 zig_got.flags.needs_rela = true;
261 }262 }
262 try symbol.addExtra(.{ .zig_got = index }, elf_file);263 symbol.addExtra(.{ .zig_got = index }, elf_file);
263 return index;264 return index;
264 }265 }
265266
...@@ -282,6 +283,7 @@ pub const ZigGotSection = struct {...@@ -282,6 +283,7 @@ pub const ZigGotSection = struct {
282 }283 }
283284
284 pub fn writeOne(zig_got: *ZigGotSection, elf_file: *Elf, index: Index) !void {285 pub fn writeOne(zig_got: *ZigGotSection, elf_file: *Elf, index: Index) !void {
286 const zo = elf_file.zigObjectPtr().?;
285 if (zig_got.flags.dirty) {287 if (zig_got.flags.dirty) {
286 const needed_size = zig_got.size(elf_file);288 const needed_size = zig_got.size(elf_file);
287 try elf_file.growAllocSection(elf_file.zig_got_section_index.?, needed_size);289 try elf_file.growAllocSection(elf_file.zig_got_section_index.?, needed_size);
...@@ -293,7 +295,7 @@ pub const ZigGotSection = struct {...@@ -293,7 +295,7 @@ pub const ZigGotSection = struct {
293 const off = zig_got.entryOffset(index, elf_file);295 const off = zig_got.entryOffset(index, elf_file);
294 const vaddr: u64 = @intCast(zig_got.entryAddress(index, elf_file));296 const vaddr: u64 = @intCast(zig_got.entryAddress(index, elf_file));
295 const entry = zig_got.entries.items[index];297 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);
297 switch (entry_size) {299 switch (entry_size) {
298 2 => {300 2 => {
299 var buf: [2]u8 = undefined;301 var buf: [2]u8 = undefined;
...@@ -336,8 +338,9 @@ pub const ZigGotSection = struct {...@@ -336,8 +338,9 @@ pub const ZigGotSection = struct {
336 }338 }
337339
338 pub fn writeAll(zig_got: ZigGotSection, elf_file: *Elf, writer: anytype) !void {340 pub fn writeAll(zig_got: ZigGotSection, elf_file: *Elf, writer: anytype) !void {
341 const zo = elf_file.zigObjectPtr().?;
339 for (zig_got.entries.items) |entry| {342 for (zig_got.entries.items) |entry| {
340 const symbol = elf_file.symbol(entry);343 const symbol = zo.symbol(entry);
341 const value = symbol.address(.{ .plt = false }, elf_file);344 const value = symbol.address(.{ .plt = false }, elf_file);
342 try writeInt(value, elf_file, writer);345 try writeInt(value, elf_file, writer);
343 }346 }
...@@ -351,9 +354,10 @@ pub const ZigGotSection = struct {...@@ -351,9 +354,10 @@ pub const ZigGotSection = struct {
351 const comp = elf_file.base.comp;354 const comp = elf_file.base.comp;
352 const gpa = comp.gpa;355 const gpa = comp.gpa;
353 const cpu_arch = elf_file.getTarget().cpu.arch;356 const cpu_arch = elf_file.getTarget().cpu.arch;
357 const zo = elf_file.zigObjectPtr().?;
354 try elf_file.rela_dyn.ensureUnusedCapacity(gpa, zig_got.numRela());358 try elf_file.rela_dyn.ensureUnusedCapacity(gpa, zig_got.numRela());
355 for (zig_got.entries.items) |entry| {359 for (zig_got.entries.items) |entry| {
356 const symbol = elf_file.symbol(entry);360 const symbol = zo.symbol(entry);
357 const offset = symbol.zigGotAddress(elf_file);361 const offset = symbol.zigGotAddress(elf_file);
358 elf_file.addRelaDynAssumeCapacity(.{362 elf_file.addRelaDynAssumeCapacity(.{
359 .offset = @intCast(offset),363 .offset = @intCast(offset),
...@@ -364,16 +368,18 @@ pub const ZigGotSection = struct {...@@ -364,16 +368,18 @@ pub const ZigGotSection = struct {
364 }368 }
365369
366 pub fn updateSymtabSize(zig_got: *ZigGotSection, elf_file: *Elf) void {370 pub fn updateSymtabSize(zig_got: *ZigGotSection, elf_file: *Elf) void {
371 const zo = elf_file.zigObjectPtr().?;
367 zig_got.output_symtab_ctx.nlocals = @as(u32, @intCast(zig_got.entries.items.len));372 zig_got.output_symtab_ctx.nlocals = @as(u32, @intCast(zig_got.entries.items.len));
368 for (zig_got.entries.items) |entry| {373 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);
370 zig_got.output_symtab_ctx.strsize += @as(u32, @intCast(name.len + "$ziggot".len)) + 1;375 zig_got.output_symtab_ctx.strsize += @as(u32, @intCast(name.len + "$ziggot".len)) + 1;
371 }376 }
372 }377 }
373378
374 pub fn writeSymtab(zig_got: ZigGotSection, elf_file: *Elf) void {379 pub fn writeSymtab(zig_got: ZigGotSection, elf_file: *Elf) void {
380 const zo = elf_file.zigObjectPtr().?;
375 for (zig_got.entries.items, zig_got.output_symtab_ctx.ilocal.., 0..) |entry, ilocal, index| {381 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);
377 const symbol_name = symbol.name(elf_file);383 const symbol_name = symbol.name(elf_file);
378 const st_name = @as(u32, @intCast(elf_file.strtab.items.len));384 const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
379 elf_file.strtab.appendSliceAssumeCapacity(symbol_name);385 elf_file.strtab.appendSliceAssumeCapacity(symbol_name);
...@@ -409,15 +415,18 @@ pub const ZigGotSection = struct {...@@ -409,15 +415,18 @@ pub const ZigGotSection = struct {
409 ) !void {415 ) !void {
410 _ = options;416 _ = options;
411 _ = unused_fmt_string;417 _ = unused_fmt_string;
418 const zig_got = ctx.zig_got;
419 const elf_file = ctx.elf_file;
420 const zo = elf_file.zigObjectPtr().?;
412 try writer.writeAll(".zig.got\n");421 try writer.writeAll(".zig.got\n");
413 for (ctx.zig_got.entries.items, 0..) |entry, index| {422 for (zig_got.entries.items, 0..) |entry, index| {
414 const symbol = ctx.elf_file.symbol(entry);423 const symbol = zo.symbol(entry);
415 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{424 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{
416 index,425 index,
417 ctx.zig_got.entryAddress(@intCast(index), ctx.elf_file),426 zig_got.entryAddress(@intCast(index), elf_file),
418 entry,427 entry,
419 symbol.address(.{}, ctx.elf_file),428 symbol.address(.{}, elf_file),
420 symbol.name(ctx.elf_file),429 symbol.name(elf_file),
421 });430 });
422 }431 }
423 }432 }
...@@ -446,7 +455,7 @@ pub const GotSection = struct {...@@ -446,7 +455,7 @@ pub const GotSection = struct {
446455
447 const Entry = struct {456 const Entry = struct {
448 tag: Tag,457 tag: Tag,
449 symbol_index: Symbol.Index,458 ref: Elf.Ref,
450 cell_index: Index,459 cell_index: Index,
451460
452 /// Returns how many indexes in the GOT this entry uses.461 /// Returns how many indexes in the GOT this entry uses.
...@@ -477,25 +486,25 @@ pub const GotSection = struct {...@@ -477,25 +486,25 @@ pub const GotSection = struct {
477 const last = got.entries.items[index - 1];486 const last = got.entries.items[index - 1];
478 break :blk last.cell_index + @as(Index, @intCast(last.len()));487 break :blk last.cell_index + @as(Index, @intCast(last.len()));
479 } else 0;488 } else 0;
480 entry.* = .{ .tag = undefined, .symbol_index = undefined, .cell_index = cell_index };489 entry.* = .{ .tag = undefined, .ref = undefined, .cell_index = cell_index };
481 return index;490 return index;
482 }491 }
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 {
485 const comp = elf_file.base.comp;494 const comp = elf_file.base.comp;
486 const gpa = comp.gpa;495 const gpa = comp.gpa;
487 const index = try got.allocateEntry(gpa);496 const index = try got.allocateEntry(gpa);
488 const entry = &got.entries.items[index];497 const entry = &got.entries.items[index];
489 entry.tag = .got;498 entry.tag = .got;
490 entry.symbol_index = sym_index;499 entry.ref = ref;
491 const symbol = elf_file.symbol(sym_index);500 const symbol = elf_file.symbol(ref).?;
492 symbol.flags.has_got = true;501 symbol.flags.has_got = true;
493 if (symbol.flags.import or symbol.isIFunc(elf_file) or502 if (symbol.flags.import or symbol.isIFunc(elf_file) or
494 ((elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) and !symbol.isAbs(elf_file)))503 ((elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) and !symbol.isAbs(elf_file)))
495 {504 {
496 got.flags.needs_rela = true;505 got.flags.needs_rela = true;
497 }506 }
498 try symbol.addExtra(.{ .got = index }, elf_file);507 symbol.addExtra(.{ .got = index }, elf_file);
499 return index;508 return index;
500 }509 }
501510
...@@ -506,48 +515,48 @@ pub const GotSection = struct {...@@ -506,48 +515,48 @@ pub const GotSection = struct {
506 const index = try got.allocateEntry(gpa);515 const index = try got.allocateEntry(gpa);
507 const entry = &got.entries.items[index];516 const entry = &got.entries.items[index];
508 entry.tag = .tlsld;517 entry.tag = .tlsld;
509 entry.symbol_index = undefined; // unused518 entry.ref = .{ .index = 0, .file = 0 }; // unused
510 got.flags.needs_rela = true;519 got.flags.needs_rela = true;
511 got.tlsld_index = index;520 got.tlsld_index = index;
512 }521 }
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 {
515 const comp = elf_file.base.comp;524 const comp = elf_file.base.comp;
516 const gpa = comp.gpa;525 const gpa = comp.gpa;
517 const index = try got.allocateEntry(gpa);526 const index = try got.allocateEntry(gpa);
518 const entry = &got.entries.items[index];527 const entry = &got.entries.items[index];
519 entry.tag = .tlsgd;528 entry.tag = .tlsgd;
520 entry.symbol_index = sym_index;529 entry.ref = ref;
521 const symbol = elf_file.symbol(sym_index);530 const symbol = elf_file.symbol(ref).?;
522 symbol.flags.has_tlsgd = true;531 symbol.flags.has_tlsgd = true;
523 if (symbol.flags.import or elf_file.isEffectivelyDynLib()) got.flags.needs_rela = true;532 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);
525 }534 }
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 {
528 const comp = elf_file.base.comp;537 const comp = elf_file.base.comp;
529 const gpa = comp.gpa;538 const gpa = comp.gpa;
530 const index = try got.allocateEntry(gpa);539 const index = try got.allocateEntry(gpa);
531 const entry = &got.entries.items[index];540 const entry = &got.entries.items[index];
532 entry.tag = .gottp;541 entry.tag = .gottp;
533 entry.symbol_index = sym_index;542 entry.ref = ref;
534 const symbol = elf_file.symbol(sym_index);543 const symbol = elf_file.symbol(ref).?;
535 symbol.flags.has_gottp = true;544 symbol.flags.has_gottp = true;
536 if (symbol.flags.import or elf_file.isEffectivelyDynLib()) got.flags.needs_rela = true;545 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);
538 }547 }
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 {
541 const comp = elf_file.base.comp;550 const comp = elf_file.base.comp;
542 const gpa = comp.gpa;551 const gpa = comp.gpa;
543 const index = try got.allocateEntry(gpa);552 const index = try got.allocateEntry(gpa);
544 const entry = &got.entries.items[index];553 const entry = &got.entries.items[index];
545 entry.tag = .tlsdesc;554 entry.tag = .tlsdesc;
546 entry.symbol_index = sym_index;555 entry.ref = ref;
547 const symbol = elf_file.symbol(sym_index);556 const symbol = elf_file.symbol(ref).?;
548 symbol.flags.has_tlsdesc = true;557 symbol.flags.has_tlsdesc = true;
549 got.flags.needs_rela = true;558 got.flags.needs_rela = true;
550 try symbol.addExtra(.{ .tlsdesc = index }, elf_file);559 symbol.addExtra(.{ .tlsdesc = index }, elf_file);
551 }560 }
552561
553 pub fn size(got: GotSection, elf_file: *Elf) usize {562 pub fn size(got: GotSection, elf_file: *Elf) usize {
...@@ -564,10 +573,7 @@ pub const GotSection = struct {...@@ -564,10 +573,7 @@ pub const GotSection = struct {
564 const apply_relocs = true; // TODO add user option for this573 const apply_relocs = true; // TODO add user option for this
565574
566 for (got.entries.items) |entry| {575 for (got.entries.items) |entry| {
567 const symbol = switch (entry.tag) {576 const symbol = elf_file.symbol(entry.ref);
568 .tlsld => null,
569 inline else => elf_file.symbol(entry.symbol_index),
570 };
571 switch (entry.tag) {577 switch (entry.tag) {
572 .got => {578 .got => {
573 const value = blk: {579 const value = blk: {
...@@ -637,10 +643,7 @@ pub const GotSection = struct {...@@ -637,10 +643,7 @@ pub const GotSection = struct {
637 try elf_file.rela_dyn.ensureUnusedCapacity(gpa, got.numRela(elf_file));643 try elf_file.rela_dyn.ensureUnusedCapacity(gpa, got.numRela(elf_file));
638644
639 for (got.entries.items) |entry| {645 for (got.entries.items) |entry| {
640 const symbol = switch (entry.tag) {646 const symbol = elf_file.symbol(entry.ref);
641 .tlsld => null,
642 inline else => elf_file.symbol(entry.symbol_index),
643 };
644 const extra = if (symbol) |s| s.extra(elf_file) else null;647 const extra = if (symbol) |s| s.extra(elf_file) else null;
645648
646 switch (entry.tag) {649 switch (entry.tag) {
...@@ -740,10 +743,7 @@ pub const GotSection = struct {...@@ -740,10 +743,7 @@ pub const GotSection = struct {
740 const is_dyn_lib = elf_file.isEffectivelyDynLib();743 const is_dyn_lib = elf_file.isEffectivelyDynLib();
741 var num: usize = 0;744 var num: usize = 0;
742 for (got.entries.items) |entry| {745 for (got.entries.items) |entry| {
743 const symbol = switch (entry.tag) {746 const symbol = elf_file.symbol(entry.ref);
744 .tlsld => null,
745 inline else => elf_file.symbol(entry.symbol_index),
746 };
747 switch (entry.tag) {747 switch (entry.tag) {
748 .got => if (symbol.?.flags.import or symbol.?.isIFunc(elf_file) or748 .got => if (symbol.?.flags.import or symbol.?.isIFunc(elf_file) or
749 ((elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) and749 ((elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) and
...@@ -775,24 +775,15 @@ pub const GotSection = struct {...@@ -775,24 +775,15 @@ pub const GotSection = struct {
775 pub fn updateSymtabSize(got: *GotSection, elf_file: *Elf) void {775 pub fn updateSymtabSize(got: *GotSection, elf_file: *Elf) void {
776 got.output_symtab_ctx.nlocals = @as(u32, @intCast(got.entries.items.len));776 got.output_symtab_ctx.nlocals = @as(u32, @intCast(got.entries.items.len));
777 for (got.entries.items) |entry| {777 for (got.entries.items) |entry| {
778 const symbol_name = switch (entry.tag) {778 const symbol_name = if (elf_file.symbol(entry.ref)) |sym| sym.name(elf_file) else "";
779 .tlsld => "",
780 inline else => elf_file.symbol(entry.symbol_index).name(elf_file),
781 };
782 got.output_symtab_ctx.strsize += @as(u32, @intCast(symbol_name.len + @tagName(entry.tag).len)) + 1 + 1;779 got.output_symtab_ctx.strsize += @as(u32, @intCast(symbol_name.len + @tagName(entry.tag).len)) + 1 + 1;
783 }780 }
784 }781 }
785782
786 pub fn writeSymtab(got: GotSection, elf_file: *Elf) void {783 pub fn writeSymtab(got: GotSection, elf_file: *Elf) void {
787 for (got.entries.items, got.output_symtab_ctx.ilocal..) |entry, ilocal| {784 for (got.entries.items, got.output_symtab_ctx.ilocal..) |entry, ilocal| {
788 const symbol = switch (entry.tag) {785 const symbol = elf_file.symbol(entry.ref);
789 .tlsld => null,786 const symbol_name = if (symbol) |s| s.name(elf_file) else "";
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 };
796 const st_name = @as(u32, @intCast(elf_file.strtab.items.len));787 const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
797 elf_file.strtab.appendSliceAssumeCapacity(symbol_name);788 elf_file.strtab.appendSliceAssumeCapacity(symbol_name);
798 elf_file.strtab.appendAssumeCapacity('$');789 elf_file.strtab.appendAssumeCapacity('$');
...@@ -828,36 +819,38 @@ pub const GotSection = struct {...@@ -828,36 +819,38 @@ pub const GotSection = struct {
828 ) !void {819 ) !void {
829 _ = options;820 _ = options;
830 _ = unused_fmt_string;821 _ = unused_fmt_string;
822 const got = ctx.got;
823 const elf_file = ctx.elf_file;
831 try writer.writeAll("GOT\n");824 try writer.writeAll("GOT\n");
832 for (ctx.got.entries.items) |entry| {825 for (got.entries.items) |entry| {
833 const symbol = ctx.elf_file.symbol(entry.symbol_index);826 const symbol = elf_file.symbol(entry.ref).?;
834 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{827 try writer.print(" {d}@0x{x} => {}@0x{x} ({s})\n", .{
835 entry.cell_index,828 entry.cell_index,
836 entry.address(ctx.elf_file),829 entry.address(elf_file),
837 entry.symbol_index,830 entry.ref,
838 symbol.address(.{}, ctx.elf_file),831 symbol.address(.{}, elf_file),
839 symbol.name(ctx.elf_file),832 symbol.name(elf_file),
840 });833 });
841 }834 }
842 }835 }
843};836};
844837
845pub const PltSection = struct {838pub const PltSection = struct {
846 symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},839 symbols: std.ArrayListUnmanaged(Elf.Ref) = .{},
847 output_symtab_ctx: Elf.SymtabCtx = .{},840 output_symtab_ctx: Elf.SymtabCtx = .{},
848841
849 pub fn deinit(plt: *PltSection, allocator: Allocator) void {842 pub fn deinit(plt: *PltSection, allocator: Allocator) void {
850 plt.symbols.deinit(allocator);843 plt.symbols.deinit(allocator);
851 }844 }
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 {
854 const comp = elf_file.base.comp;847 const comp = elf_file.base.comp;
855 const gpa = comp.gpa;848 const gpa = comp.gpa;
856 const index = @as(u32, @intCast(plt.symbols.items.len));849 const index = @as(u32, @intCast(plt.symbols.items.len));
857 const symbol = elf_file.symbol(sym_index);850 const symbol = elf_file.symbol(ref).?;
858 symbol.flags.has_plt = true;851 symbol.flags.has_plt = true;
859 try symbol.addExtra(.{ .plt = index }, elf_file);852 symbol.addExtra(.{ .plt = index }, elf_file);
860 try plt.symbols.append(gpa, sym_index);853 try plt.symbols.append(gpa, ref);
861 }854 }
862855
863 pub fn size(plt: PltSection, elf_file: *Elf) usize {856 pub fn size(plt: PltSection, elf_file: *Elf) usize {
...@@ -895,8 +888,8 @@ pub const PltSection = struct {...@@ -895,8 +888,8 @@ pub const PltSection = struct {
895 const gpa = comp.gpa;888 const gpa = comp.gpa;
896 const cpu_arch = elf_file.getTarget().cpu.arch;889 const cpu_arch = elf_file.getTarget().cpu.arch;
897 try elf_file.rela_plt.ensureUnusedCapacity(gpa, plt.numRela());890 try elf_file.rela_plt.ensureUnusedCapacity(gpa, plt.numRela());
898 for (plt.symbols.items) |sym_index| {891 for (plt.symbols.items) |ref| {
899 const sym = elf_file.symbol(sym_index);892 const sym = elf_file.symbol(ref).?;
900 assert(sym.flags.import);893 assert(sym.flags.import);
901 const extra = sym.extra(elf_file);894 const extra = sym.extra(elf_file);
902 const r_offset: u64 = @intCast(sym.gotPltAddress(elf_file));895 const r_offset: u64 = @intCast(sym.gotPltAddress(elf_file));
...@@ -916,16 +909,16 @@ pub const PltSection = struct {...@@ -916,16 +909,16 @@ pub const PltSection = struct {
916909
917 pub fn updateSymtabSize(plt: *PltSection, elf_file: *Elf) void {910 pub fn updateSymtabSize(plt: *PltSection, elf_file: *Elf) void {
918 plt.output_symtab_ctx.nlocals = @as(u32, @intCast(plt.symbols.items.len));911 plt.output_symtab_ctx.nlocals = @as(u32, @intCast(plt.symbols.items.len));
919 for (plt.symbols.items) |sym_index| {912 for (plt.symbols.items) |ref| {
920 const name = elf_file.symbol(sym_index).name(elf_file);913 const name = elf_file.symbol(ref).?.name(elf_file);
921 plt.output_symtab_ctx.strsize += @as(u32, @intCast(name.len + "$plt".len)) + 1;914 plt.output_symtab_ctx.strsize += @as(u32, @intCast(name.len + "$plt".len)) + 1;
922 }915 }
923 }916 }
924917
925 pub fn writeSymtab(plt: PltSection, elf_file: *Elf) void {918 pub fn writeSymtab(plt: PltSection, elf_file: *Elf) void {
926 const cpu_arch = elf_file.getTarget().cpu.arch;919 const cpu_arch = elf_file.getTarget().cpu.arch;
927 for (plt.symbols.items, plt.output_symtab_ctx.ilocal..) |sym_index, ilocal| {920 for (plt.symbols.items, plt.output_symtab_ctx.ilocal..) |ref, ilocal| {
928 const sym = elf_file.symbol(sym_index);921 const sym = elf_file.symbol(ref).?;
929 const st_name = @as(u32, @intCast(elf_file.strtab.items.len));922 const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
930 elf_file.strtab.appendSliceAssumeCapacity(sym.name(elf_file));923 elf_file.strtab.appendSliceAssumeCapacity(sym.name(elf_file));
931 elf_file.strtab.appendSliceAssumeCapacity("$plt");924 elf_file.strtab.appendSliceAssumeCapacity("$plt");
...@@ -958,15 +951,17 @@ pub const PltSection = struct {...@@ -958,15 +951,17 @@ pub const PltSection = struct {
958 ) !void {951 ) !void {
959 _ = options;952 _ = options;
960 _ = unused_fmt_string;953 _ = unused_fmt_string;
954 const plt = ctx.plt;
955 const elf_file = ctx.elf_file;
961 try writer.writeAll("PLT\n");956 try writer.writeAll("PLT\n");
962 for (ctx.plt.symbols.items, 0..) |symbol_index, i| {957 for (plt.symbols.items, 0..) |ref, i| {
963 const symbol = ctx.elf_file.symbol(symbol_index);958 const symbol = elf_file.symbol(ref).?;
964 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{959 try writer.print(" {d}@0x{x} => {}@0x{x} ({s})\n", .{
965 i,960 i,
966 symbol.pltAddress(ctx.elf_file),961 symbol.pltAddress(elf_file),
967 symbol_index,962 ref,
968 symbol.address(.{}, ctx.elf_file),963 symbol.address(.{}, elf_file),
969 symbol.name(ctx.elf_file),964 symbol.name(elf_file),
970 });965 });
971 }966 }
972 }967 }
...@@ -988,8 +983,8 @@ pub const PltSection = struct {...@@ -988,8 +983,8 @@ pub const PltSection = struct {
988 try writer.writeAll(&preamble);983 try writer.writeAll(&preamble);
989 try writer.writeByteNTimes(0xcc, preambleSize(.x86_64) - preamble.len);984 try writer.writeByteNTimes(0xcc, preambleSize(.x86_64) - preamble.len);
990985
991 for (plt.symbols.items, 0..) |sym_index, i| {986 for (plt.symbols.items, 0..) |ref, i| {
992 const sym = elf_file.symbol(sym_index);987 const sym = elf_file.symbol(ref).?;
993 const target_addr = sym.gotPltAddress(elf_file);988 const target_addr = sym.gotPltAddress(elf_file);
994 const source_addr = sym.pltAddress(elf_file);989 const source_addr = sym.pltAddress(elf_file);
995 disp = @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr + 12)) - 4;990 disp = @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr + 12)) - 4;
...@@ -1037,8 +1032,8 @@ pub const PltSection = struct {...@@ -1037,8 +1032,8 @@ pub const PltSection = struct {
1037 }1032 }
1038 }1033 }
10391034
1040 for (plt.symbols.items) |sym_index| {1035 for (plt.symbols.items) |ref| {
1041 const sym = elf_file.symbol(sym_index);1036 const sym = elf_file.symbol(ref).?;
1042 const target_addr = sym.gotPltAddress(elf_file);1037 const target_addr = sym.gotPltAddress(elf_file);
1043 const source_addr = sym.pltAddress(elf_file);1038 const source_addr = sym.pltAddress(elf_file);
1044 const pages = try aarch64_util.calcNumberOfPages(source_addr, target_addr);1039 const pages = try aarch64_util.calcNumberOfPages(source_addr, target_addr);
...@@ -1075,7 +1070,7 @@ pub const GotPltSection = struct {...@@ -1075,7 +1070,7 @@ pub const GotPltSection = struct {
1075 _ = got_plt;1070 _ = got_plt;
1076 {1071 {
1077 // [0]: _DYNAMIC1072 // [0]: _DYNAMIC
1078 const symbol = elf_file.symbol(elf_file.linkerDefinedPtr().?.dynamic_index.?);1073 const symbol = elf_file.linkerDefinedPtr().?.dynamicSymbol(elf_file).?;
1079 try writer.writeInt(u64, @intCast(symbol.address(.{}, elf_file)), .little);1074 try writer.writeInt(u64, @intCast(symbol.address(.{}, elf_file)), .little);
1080 }1075 }
1081 // [1]: 0x01076 // [1]: 0x0
...@@ -1093,22 +1088,22 @@ pub const GotPltSection = struct {...@@ -1093,22 +1088,22 @@ pub const GotPltSection = struct {
1093};1088};
10941089
1095pub const PltGotSection = struct {1090pub const PltGotSection = struct {
1096 symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},1091 symbols: std.ArrayListUnmanaged(Elf.Ref) = .{},
1097 output_symtab_ctx: Elf.SymtabCtx = .{},1092 output_symtab_ctx: Elf.SymtabCtx = .{},
10981093
1099 pub fn deinit(plt_got: *PltGotSection, allocator: Allocator) void {1094 pub fn deinit(plt_got: *PltGotSection, allocator: Allocator) void {
1100 plt_got.symbols.deinit(allocator);1095 plt_got.symbols.deinit(allocator);
1101 }1096 }
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 {
1104 const comp = elf_file.base.comp;1099 const comp = elf_file.base.comp;
1105 const gpa = comp.gpa;1100 const gpa = comp.gpa;
1106 const index = @as(u32, @intCast(plt_got.symbols.items.len));1101 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).?;
1108 symbol.flags.has_plt = true;1103 symbol.flags.has_plt = true;
1109 symbol.flags.has_got = true;1104 symbol.flags.has_got = true;
1110 try symbol.addExtra(.{ .plt_got = index }, elf_file);1105 symbol.addExtra(.{ .plt_got = index }, elf_file);
1111 try plt_got.symbols.append(gpa, sym_index);1106 try plt_got.symbols.append(gpa, ref);
1112 }1107 }
11131108
1114 pub fn size(plt_got: PltGotSection, elf_file: *Elf) usize {1109 pub fn size(plt_got: PltGotSection, elf_file: *Elf) usize {
...@@ -1134,15 +1129,15 @@ pub const PltGotSection = struct {...@@ -1134,15 +1129,15 @@ pub const PltGotSection = struct {
11341129
1135 pub fn updateSymtabSize(plt_got: *PltGotSection, elf_file: *Elf) void {1130 pub fn updateSymtabSize(plt_got: *PltGotSection, elf_file: *Elf) void {
1136 plt_got.output_symtab_ctx.nlocals = @as(u32, @intCast(plt_got.symbols.items.len));1131 plt_got.output_symtab_ctx.nlocals = @as(u32, @intCast(plt_got.symbols.items.len));
1137 for (plt_got.symbols.items) |sym_index| {1132 for (plt_got.symbols.items) |ref| {
1138 const name = elf_file.symbol(sym_index).name(elf_file);1133 const name = elf_file.symbol(ref).?.name(elf_file);
1139 plt_got.output_symtab_ctx.strsize += @as(u32, @intCast(name.len + "$pltgot".len)) + 1;1134 plt_got.output_symtab_ctx.strsize += @as(u32, @intCast(name.len + "$pltgot".len)) + 1;
1140 }1135 }
1141 }1136 }
11421137
1143 pub fn writeSymtab(plt_got: PltGotSection, elf_file: *Elf) void {1138 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| {1139 for (plt_got.symbols.items, plt_got.output_symtab_ctx.ilocal..) |ref, ilocal| {
1145 const sym = elf_file.symbol(sym_index);1140 const sym = elf_file.symbol(ref).?;
1146 const st_name = @as(u32, @intCast(elf_file.strtab.items.len));1141 const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
1147 elf_file.strtab.appendSliceAssumeCapacity(sym.name(elf_file));1142 elf_file.strtab.appendSliceAssumeCapacity(sym.name(elf_file));
1148 elf_file.strtab.appendSliceAssumeCapacity("$pltgot");1143 elf_file.strtab.appendSliceAssumeCapacity("$pltgot");
...@@ -1160,8 +1155,8 @@ pub const PltGotSection = struct {...@@ -1160,8 +1155,8 @@ pub const PltGotSection = struct {
11601155
1161 const x86_64 = struct {1156 const x86_64 = struct {
1162 pub fn write(plt_got: PltGotSection, elf_file: *Elf, writer: anytype) !void {1157 pub fn write(plt_got: PltGotSection, elf_file: *Elf, writer: anytype) !void {
1163 for (plt_got.symbols.items) |sym_index| {1158 for (plt_got.symbols.items) |ref| {
1164 const sym = elf_file.symbol(sym_index);1159 const sym = elf_file.symbol(ref).?;
1165 const target_addr = sym.gotAddress(elf_file);1160 const target_addr = sym.gotAddress(elf_file);
1166 const source_addr = sym.pltGotAddress(elf_file);1161 const source_addr = sym.pltGotAddress(elf_file);
1167 const disp = @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr + 6)) - 4;1162 const disp = @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr + 6)) - 4;
...@@ -1178,8 +1173,8 @@ pub const PltGotSection = struct {...@@ -1178,8 +1173,8 @@ pub const PltGotSection = struct {
11781173
1179 const aarch64 = struct {1174 const aarch64 = struct {
1180 fn write(plt_got: PltGotSection, elf_file: *Elf, writer: anytype) !void {1175 fn write(plt_got: PltGotSection, elf_file: *Elf, writer: anytype) !void {
1181 for (plt_got.symbols.items) |sym_index| {1176 for (plt_got.symbols.items) |ref| {
1182 const sym = elf_file.symbol(sym_index);1177 const sym = elf_file.symbol(ref).?;
1183 const target_addr = sym.gotAddress(elf_file);1178 const target_addr = sym.gotAddress(elf_file);
1184 const source_addr = sym.pltGotAddress(elf_file);1179 const source_addr = sym.pltGotAddress(elf_file);
1185 const pages = try aarch64_util.calcNumberOfPages(source_addr, target_addr);1180 const pages = try aarch64_util.calcNumberOfPages(source_addr, target_addr);
...@@ -1204,56 +1199,56 @@ pub const PltGotSection = struct {...@@ -1204,56 +1199,56 @@ pub const PltGotSection = struct {
1204};1199};
12051200
1206pub const CopyRelSection = struct {1201pub const CopyRelSection = struct {
1207 symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},1202 symbols: std.ArrayListUnmanaged(Elf.Ref) = .{},
12081203
1209 pub fn deinit(copy_rel: *CopyRelSection, allocator: Allocator) void {1204 pub fn deinit(copy_rel: *CopyRelSection, allocator: Allocator) void {
1210 copy_rel.symbols.deinit(allocator);1205 copy_rel.symbols.deinit(allocator);
1211 }1206 }
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 {
1214 const comp = elf_file.base.comp;1209 const comp = elf_file.base.comp;
1215 const gpa = comp.gpa;1210 const gpa = comp.gpa;
1216 const index = @as(u32, @intCast(copy_rel.symbols.items.len));1211 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).?;
1218 symbol.flags.import = true;1213 symbol.flags.import = true;
1219 symbol.flags.@"export" = true;1214 symbol.flags.@"export" = true;
1220 symbol.flags.has_copy_rel = true;1215 symbol.flags.has_copy_rel = true;
1221 symbol.flags.weak = false;1216 symbol.flags.weak = false;
1222 try symbol.addExtra(.{ .copy_rel = index }, elf_file);1217 symbol.addExtra(.{ .copy_rel = index }, elf_file);
1223 try copy_rel.symbols.append(gpa, sym_index);1218 try copy_rel.symbols.append(gpa, ref);
12241219
1225 const shared_object = symbol.file(elf_file).?.shared_object;1220 const shared_object = symbol.file(elf_file).?.shared_object;
1226 if (shared_object.aliases == null) {1221 if (shared_object.aliases == null) {
1227 try shared_object.initSymbolAliases(elf_file);1222 try shared_object.initSymbolAliases(elf_file);
1228 }1223 }
12291224
1230 const aliases = shared_object.symbolAliases(sym_index, elf_file);1225 const aliases = shared_object.symbolAliases(ref.index, elf_file);
1231 for (aliases) |alias| {1226 for (aliases) |alias| {
1232 if (alias == sym_index) continue;1227 if (alias == ref.index) continue;
1233 const alias_sym = elf_file.symbol(alias);1228 const alias_sym = &shared_object.symbols.items[alias];
1234 alias_sym.flags.import = true;1229 alias_sym.flags.import = true;
1235 alias_sym.flags.@"export" = true;1230 alias_sym.flags.@"export" = true;
1236 alias_sym.flags.has_copy_rel = true;1231 alias_sym.flags.has_copy_rel = true;
1237 alias_sym.flags.needs_copy_rel = true;1232 alias_sym.flags.needs_copy_rel = true;
1238 alias_sym.flags.weak = false;1233 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);
1240 }1235 }
1241 }1236 }
12421237
1243 pub fn updateSectionSize(copy_rel: CopyRelSection, shndx: u32, elf_file: *Elf) !void {1238 pub fn updateSectionSize(copy_rel: CopyRelSection, shndx: u32, elf_file: *Elf) !void {
1244 const shdr = &elf_file.shdrs.items[shndx];1239 const shdr = &elf_file.shdrs.items[shndx];
1245 for (copy_rel.symbols.items) |sym_index| {1240 for (copy_rel.symbols.items) |ref| {
1246 const symbol = elf_file.symbol(sym_index);1241 const symbol = elf_file.symbol(ref).?;
1247 const shared_object = symbol.file(elf_file).?.shared_object;1242 const shared_object = symbol.file(elf_file).?.shared_object;
1248 const alignment = try symbol.dsoAlignment(elf_file);1243 const alignment = try symbol.dsoAlignment(elf_file);
1249 symbol.value = @intCast(mem.alignForward(u64, shdr.sh_size, alignment));1244 symbol.value = @intCast(mem.alignForward(u64, shdr.sh_size, alignment));
1250 shdr.sh_addralign = @max(shdr.sh_addralign, alignment);1245 shdr.sh_addralign = @max(shdr.sh_addralign, alignment);
1251 shdr.sh_size = @as(u64, @intCast(symbol.value)) + symbol.elfSym(elf_file).st_size;1246 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);
1254 for (aliases) |alias| {1249 for (aliases) |alias| {
1255 if (alias == sym_index) continue;1250 if (alias == ref.index) continue;
1256 const alias_sym = elf_file.symbol(alias);1251 const alias_sym = &shared_object.symbols.items[alias];
1257 alias_sym.value = symbol.value;1252 alias_sym.value = symbol.value;
1258 }1253 }
1259 }1254 }
...@@ -1264,8 +1259,8 @@ pub const CopyRelSection = struct {...@@ -1264,8 +1259,8 @@ pub const CopyRelSection = struct {
1264 const gpa = comp.gpa;1259 const gpa = comp.gpa;
1265 const cpu_arch = elf_file.getTarget().cpu.arch;1260 const cpu_arch = elf_file.getTarget().cpu.arch;
1266 try elf_file.rela_dyn.ensureUnusedCapacity(gpa, copy_rel.numRela());1261 try elf_file.rela_dyn.ensureUnusedCapacity(gpa, copy_rel.numRela());
1267 for (copy_rel.symbols.items) |sym_index| {1262 for (copy_rel.symbols.items) |ref| {
1268 const sym = elf_file.symbol(sym_index);1263 const sym = elf_file.symbol(ref).?;
1269 assert(sym.flags.import and sym.flags.has_copy_rel);1264 assert(sym.flags.import and sym.flags.has_copy_rel);
1270 const extra = sym.extra(elf_file);1265 const extra = sym.extra(elf_file);
1271 elf_file.addRelaDynAssumeCapacity(.{1266 elf_file.addRelaDynAssumeCapacity(.{
...@@ -1285,8 +1280,8 @@ pub const DynsymSection = struct {...@@ -1285,8 +1280,8 @@ pub const DynsymSection = struct {
1285 entries: std.ArrayListUnmanaged(Entry) = .{},1280 entries: std.ArrayListUnmanaged(Entry) = .{},
12861281
1287 pub const Entry = struct {1282 pub const Entry = struct {
1288 /// Index of the symbol which gets privilege of getting a dynamic treatment1283 /// Ref of the symbol which gets privilege of getting a dynamic treatment
1289 symbol_index: Symbol.Index,1284 ref: Elf.Ref,
1290 /// Offset into .dynstrtab1285 /// Offset into .dynstrtab
1291 off: u32,1286 off: u32,
1292 };1287 };
...@@ -1295,22 +1290,22 @@ pub const DynsymSection = struct {...@@ -1295,22 +1290,22 @@ pub const DynsymSection = struct {
1295 dynsym.entries.deinit(allocator);1290 dynsym.entries.deinit(allocator);
1296 }1291 }
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 {
1299 const comp = elf_file.base.comp;1294 const comp = elf_file.base.comp;
1300 const gpa = comp.gpa;1295 const gpa = comp.gpa;
1301 const index = @as(u32, @intCast(dynsym.entries.items.len + 1));1296 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).?;
1303 sym.flags.has_dynamic = true;1298 sym.flags.has_dynamic = true;
1304 try sym.addExtra(.{ .dynamic = index }, elf_file);1299 sym.addExtra(.{ .dynamic = index }, elf_file);
1305 const off = try elf_file.insertDynString(sym.name(elf_file));1300 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 });
1307 }1302 }
13081303
1309 pub fn sort(dynsym: *DynsymSection, elf_file: *Elf) void {1304 pub fn sort(dynsym: *DynsymSection, elf_file: *Elf) void {
1310 const Sort = struct {1305 const Sort = struct {
1311 pub fn lessThan(ctx: *Elf, lhs: Entry, rhs: Entry) bool {1306 pub fn lessThan(ctx: *Elf, lhs: Entry, rhs: Entry) bool {
1312 const lhs_sym = ctx.symbol(lhs.symbol_index);1307 const lhs_sym = ctx.symbol(lhs.ref).?;
1313 const rhs_sym = ctx.symbol(rhs.symbol_index);1308 const rhs_sym = ctx.symbol(rhs.ref).?;
13141309
1315 if (lhs_sym.flags.@"export" != rhs_sym.flags.@"export") {1310 if (lhs_sym.flags.@"export" != rhs_sym.flags.@"export") {
1316 return rhs_sym.flags.@"export";1311 return rhs_sym.flags.@"export";
...@@ -1329,7 +1324,7 @@ pub const DynsymSection = struct {...@@ -1329,7 +1324,7 @@ pub const DynsymSection = struct {
13291324
1330 var num_exports: u32 = 0;1325 var num_exports: u32 = 0;
1331 for (dynsym.entries.items) |entry| {1326 for (dynsym.entries.items) |entry| {
1332 const sym = elf_file.symbol(entry.symbol_index);1327 const sym = elf_file.symbol(entry.ref).?;
1333 if (sym.flags.@"export") num_exports += 1;1328 if (sym.flags.@"export") num_exports += 1;
1334 }1329 }
13351330
...@@ -1338,7 +1333,7 @@ pub const DynsymSection = struct {...@@ -1338,7 +1333,7 @@ pub const DynsymSection = struct {
1338 std.mem.sort(Entry, dynsym.entries.items, elf_file, Sort.lessThan);1333 std.mem.sort(Entry, dynsym.entries.items, elf_file, Sort.lessThan);
13391334
1340 for (dynsym.entries.items, 1..) |entry, index| {1335 for (dynsym.entries.items, 1..) |entry, index| {
1341 const sym = elf_file.symbol(entry.symbol_index);1336 const sym = elf_file.symbol(entry.ref).?;
1342 var extra = sym.extra(elf_file);1337 var extra = sym.extra(elf_file);
1343 extra.dynamic = @as(u32, @intCast(index));1338 extra.dynamic = @as(u32, @intCast(index));
1344 sym.setExtra(extra, elf_file);1339 sym.setExtra(extra, elf_file);
...@@ -1356,7 +1351,7 @@ pub const DynsymSection = struct {...@@ -1356,7 +1351,7 @@ pub const DynsymSection = struct {
1356 pub fn write(dynsym: DynsymSection, elf_file: *Elf, writer: anytype) !void {1351 pub fn write(dynsym: DynsymSection, elf_file: *Elf, writer: anytype) !void {
1357 try writer.writeStruct(Elf.null_sym);1352 try writer.writeStruct(Elf.null_sym);
1358 for (dynsym.entries.items) |entry| {1353 for (dynsym.entries.items) |entry| {
1359 const sym = elf_file.symbol(entry.symbol_index);1354 const sym = elf_file.symbol(entry.ref).?;
1360 var out_sym: elf.Elf64_Sym = Elf.null_sym;1355 var out_sym: elf.Elf64_Sym = Elf.null_sym;
1361 sym.setOutputSym(elf_file, &out_sym);1356 sym.setOutputSym(elf_file, &out_sym);
1362 out_sym.st_name = entry.off;1357 out_sym.st_name = entry.off;
...@@ -1429,7 +1424,7 @@ pub const GnuHashSection = struct {...@@ -1429,7 +1424,7 @@ pub const GnuHashSection = struct {
14291424
1430 fn getExports(elf_file: *Elf) []const DynsymSection.Entry {1425 fn getExports(elf_file: *Elf) []const DynsymSection.Entry {
1431 const start = for (elf_file.dynsym.entries.items, 0..) |entry, i| {1426 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).?;
1433 if (sym.flags.@"export") break i;1428 if (sym.flags.@"export") break i;
1434 } else elf_file.dynsym.entries.items.len;1429 } else elf_file.dynsym.entries.items.len;
1435 return elf_file.dynsym.entries.items[start..];1430 return elf_file.dynsym.entries.items[start..];
...@@ -1477,7 +1472,7 @@ pub const GnuHashSection = struct {...@@ -1477,7 +1472,7 @@ pub const GnuHashSection = struct {
1477 @memset(bloom, 0);1472 @memset(bloom, 0);
14781473
1479 for (exports, 0..) |entry, i| {1474 for (exports, 0..) |entry, i| {
1480 const sym = elf_file.symbol(entry.symbol_index);1475 const sym = elf_file.symbol(entry.ref).?;
1481 const h = hasher(sym.name(elf_file));1476 const h = hasher(sym.name(elf_file));
1482 hashes[i] = h;1477 hashes[i] = h;
1483 indices[i] = h % hash.num_buckets;1478 indices[i] = h % hash.num_buckets;
...@@ -1574,7 +1569,7 @@ pub const VerneedSection = struct {...@@ -1574,7 +1569,7 @@ pub const VerneedSection = struct {
1574 try verneed.ensureTotalCapacity(dynsyms.len);1569 try verneed.ensureTotalCapacity(dynsyms.len);
15751570
1576 for (dynsyms, 1..) |entry, i| {1571 for (dynsyms, 1..) |entry, i| {
1577 const symbol = elf_file.symbol(entry.symbol_index);1572 const symbol = elf_file.symbol(entry.ref).?;
1578 if (symbol.flags.import and symbol.version_index & elf.VERSYM_VERSION > elf.VER_NDX_GLOBAL) {1573 if (symbol.flags.import and symbol.version_index & elf.VERSYM_VERSION > elf.VER_NDX_GLOBAL) {
1579 const shared_object = symbol.file(elf_file).?.shared_object;1574 const shared_object = symbol.file(elf_file).?.shared_object;
1580 verneed.appendAssumeCapacity(.{1575 verneed.appendAssumeCapacity(.{
...@@ -1677,11 +1672,11 @@ pub const ComdatGroupSection = struct {...@@ -1677,11 +1672,11 @@ pub const ComdatGroupSection = struct {
1677 return cg_file.object.comdatGroup(cgs.cg_ref.index);1672 return cg_file.object.comdatGroup(cgs.cg_ref.index);
1678 }1673 }
16791674
1680 pub fn symbol(cgs: ComdatGroupSection, elf_file: *Elf) Symbol.Index {1675 pub fn symbol(cgs: ComdatGroupSection, elf_file: *Elf) *Symbol {
1681 const cg = cgs.comdatGroup(elf_file);1676 const cg = cgs.comdatGroup(elf_file);
1682 const object = cg.file(elf_file).object;1677 const object = cg.file(elf_file).object;
1683 const shdr = object.shdrs.items[cg.shndx];1678 const shdr = object.shdrs.items[cg.shndx];
1684 return object.symbols.items[shdr.sh_info];1679 return &object.symbols.items[shdr.sh_info];
1685 }1680 }
16861681
1687 pub fn size(cgs: ComdatGroupSection, elf_file: *Elf) usize {1682 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 {...@@ -43,11 +43,7 @@ pub fn createThunks(shndx: u32, elf_file: *Elf) !void {
43 else => @panic("unsupported arch"),43 else => @panic("unsupported arch"),
44 };44 };
45 if (is_reachable) continue;45 if (is_reachable) continue;
46 const target = switch (file) {46 const target = file.resolveSymbol(rel.r_sym(), elf_file);
47 .zig_object => |x| x.symbol(rel.r_sym()),
48 .object => |x| x.symbols.items[rel.r_sym()],
49 else => unreachable,
50 };
51 try thunk.symbols.put(gpa, target, {});47 try thunk.symbols.put(gpa, target, {});
52 }48 }
53 atom.addExtra(.{ .thunk = thunk_index }, elf_file);49 atom.addExtra(.{ .thunk = thunk_index }, elf_file);
...@@ -80,7 +76,7 @@ fn maxAllowedDistance(cpu_arch: std.Target.Cpu.Arch) u32 {...@@ -80,7 +76,7 @@ fn maxAllowedDistance(cpu_arch: std.Target.Cpu.Arch) u32 {
80pub const Thunk = struct {76pub const Thunk = struct {
81 value: i64 = 0,77 value: i64 = 0,
82 output_section_index: u32 = 0,78 output_section_index: u32 = 0,
83 symbols: std.AutoArrayHashMapUnmanaged(Symbol.Index, void) = .{},79 symbols: std.AutoArrayHashMapUnmanaged(Elf.Ref, void) = .{},
84 output_symtab_ctx: Elf.SymtabCtx = .{},80 output_symtab_ctx: Elf.SymtabCtx = .{},
8581
86 pub fn deinit(thunk: *Thunk, allocator: Allocator) void {82 pub fn deinit(thunk: *Thunk, allocator: Allocator) void {
...@@ -97,9 +93,9 @@ pub const Thunk = struct {...@@ -97,9 +93,9 @@ pub const Thunk = struct {
97 return @as(i64, @intCast(shdr.sh_addr)) + thunk.value;93 return @as(i64, @intCast(shdr.sh_addr)) + thunk.value;
98 }94 }
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 {
101 const cpu_arch = elf_file.getTarget().cpu.arch;97 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)));
103 }99 }
104100
105 pub fn write(thunk: Thunk, elf_file: *Elf, writer: anytype) !void {101 pub fn write(thunk: Thunk, elf_file: *Elf, writer: anytype) !void {
...@@ -112,16 +108,16 @@ pub const Thunk = struct {...@@ -112,16 +108,16 @@ pub const Thunk = struct {
112108
113 pub fn calcSymtabSize(thunk: *Thunk, elf_file: *Elf) void {109 pub fn calcSymtabSize(thunk: *Thunk, elf_file: *Elf) void {
114 thunk.output_symtab_ctx.nlocals = @as(u32, @intCast(thunk.symbols.keys().len));110 thunk.output_symtab_ctx.nlocals = @as(u32, @intCast(thunk.symbols.keys().len));
115 for (thunk.symbols.keys()) |sym_index| {111 for (thunk.symbols.keys()) |ref| {
116 const sym = elf_file.symbol(sym_index);112 const sym = elf_file.symbol(ref).?;
117 thunk.output_symtab_ctx.strsize += @as(u32, @intCast(sym.name(elf_file).len + "$thunk".len + 1));113 thunk.output_symtab_ctx.strsize += @as(u32, @intCast(sym.name(elf_file).len + "$thunk".len + 1));
118 }114 }
119 }115 }
120116
121 pub fn writeSymtab(thunk: Thunk, elf_file: *Elf) void {117 pub fn writeSymtab(thunk: Thunk, elf_file: *Elf) void {
122 const cpu_arch = elf_file.getTarget().cpu.arch;118 const cpu_arch = elf_file.getTarget().cpu.arch;
123 for (thunk.symbols.keys(), thunk.output_symtab_ctx.ilocal..) |sym_index, ilocal| {119 for (thunk.symbols.keys(), thunk.output_symtab_ctx.ilocal..) |ref, ilocal| {
124 const sym = elf_file.symbol(sym_index);120 const sym = elf_file.symbol(ref).?;
125 const st_name = @as(u32, @intCast(elf_file.strtab.items.len));121 const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
126 elf_file.strtab.appendSliceAssumeCapacity(sym.name(elf_file));122 elf_file.strtab.appendSliceAssumeCapacity(sym.name(elf_file));
127 elf_file.strtab.appendSliceAssumeCapacity("$thunk");123 elf_file.strtab.appendSliceAssumeCapacity("$thunk");
...@@ -131,7 +127,7 @@ pub const Thunk = struct {...@@ -131,7 +127,7 @@ pub const Thunk = struct {
131 .st_info = elf.STT_FUNC,127 .st_info = elf.STT_FUNC,
132 .st_other = 0,128 .st_other = 0,
133 .st_shndx = @intCast(thunk.output_section_index),129 .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)),
135 .st_size = trampolineSize(cpu_arch),131 .st_size = trampolineSize(cpu_arch),
136 };132 };
137 }133 }
...@@ -181,9 +177,9 @@ pub const Thunk = struct {...@@ -181,9 +177,9 @@ pub const Thunk = struct {
181 const thunk = ctx.thunk;177 const thunk = ctx.thunk;
182 const elf_file = ctx.elf_file;178 const elf_file = ctx.elf_file;
183 try writer.print("@{x} : size({x})\n", .{ thunk.value, thunk.size(elf_file) });179 try writer.print("@{x} : size({x})\n", .{ thunk.value, thunk.size(elf_file) });
184 for (thunk.symbols.keys()) |index| {180 for (thunk.symbols.keys()) |ref| {
185 const sym = elf_file.symbol(index);181 const sym = elf_file.symbol(ref).?;
186 try writer.print(" %{d} : {s} : @{x}\n", .{ index, sym.name(elf_file), sym.value });182 try writer.print(" {} : {s} : @{x}\n", .{ ref, sym.name(elf_file), sym.value });
187 }183 }
188 }184 }
189185
...@@ -195,12 +191,8 @@ const aarch64 = struct {...@@ -195,12 +191,8 @@ const aarch64 = struct {
195 const r_type: elf.R_AARCH64 = @enumFromInt(rel.r_type());191 const r_type: elf.R_AARCH64 = @enumFromInt(rel.r_type());
196 if (r_type != .CALL26 and r_type != .JUMP26) return true;192 if (r_type != .CALL26 and r_type != .JUMP26) return true;
197 const file = atom.file(elf_file).?;193 const file = atom.file(elf_file).?;
198 const target_index = switch (file) {194 const target_ref = file.resolveSymbol(rel.r_sym(), elf_file);
199 .zig_object => |x| x.symbol(rel.r_sym()),195 const target = elf_file.symbol(target_ref).?;
200 .object => |x| x.symbols.items[rel.r_sym()],
201 else => unreachable,
202 };
203 const target = elf_file.symbol(target_index);
204 if (target.flags.has_plt) return false;196 if (target.flags.has_plt) return false;
205 if (atom.output_section_index != target.output_section_index) return false;197 if (atom.output_section_index != target.output_section_index) return false;
206 const target_atom = target.atom(elf_file).?;198 const target_atom = target.atom(elf_file).?;
...@@ -212,8 +204,8 @@ const aarch64 = struct {...@@ -212,8 +204,8 @@ const aarch64 = struct {
212 }204 }
213205
214 fn write(thunk: Thunk, elf_file: *Elf, writer: anytype) !void {206 fn write(thunk: Thunk, elf_file: *Elf, writer: anytype) !void {
215 for (thunk.symbols.keys(), 0..) |sym_index, i| {207 for (thunk.symbols.keys(), 0..) |ref, i| {
216 const sym = elf_file.symbol(sym_index);208 const sym = elf_file.symbol(ref).?;
217 const saddr = thunk.address(elf_file) + @as(i64, @intCast(i * trampoline_size));209 const saddr = thunk.address(elf_file) + @as(i64, @intCast(i * trampoline_size));
218 const taddr = sym.address(.{}, elf_file);210 const taddr = sym.address(.{}, elf_file);
219 const pages = try util.calcNumberOfPages(saddr, taddr);211 const pages = try util.calcNumberOfPages(saddr, taddr);