diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2023-02-02 01:39:01 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-02-02 01:39:01 +0100 |
| commit | 304420b99ced44e1b7ebd34d7c3917879cb78648 (patch) | |
| tree | f66f23cc66418fa2ac3f7d7f9a080f991de3ec7d /src/arch | |
| parent | 1fba88450db12f184d76f0651f7ca933322c1fc0 (diff) | |
| parent | beb20d29db3fe945746581eba5d2f2cae1403cdb (diff) | |
| download | zig-304420b99ced44e1b7ebd34d7c3917879cb78648.tar.gz zig-304420b99ced44e1b7ebd34d7c3917879cb78648.zip | |
Merge pull request #14502 from ziglang/link-owned-atoms
link: move ownership of linker atom from frontend to the linkers
Diffstat (limited to 'src/arch')
| -rw-r--r-- | src/arch/aarch64/CodeGen.zig | 121 | ||||
| -rw-r--r-- | src/arch/aarch64/Emit.zig | 16 | ||||
| -rw-r--r-- | src/arch/arm/CodeGen.zig | 37 | ||||
| -rw-r--r-- | src/arch/riscv64/CodeGen.zig | 33 | ||||
| -rw-r--r-- | src/arch/sparc64/CodeGen.zig | 22 | ||||
| -rw-r--r-- | src/arch/wasm/CodeGen.zig | 40 | ||||
| -rw-r--r-- | src/arch/wasm/Emit.zig | 29 | ||||
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 71 | ||||
| -rw-r--r-- | src/arch/x86_64/Emit.zig | 16 |
9 files changed, 196 insertions, 189 deletions
diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 0efd34937a..473a62fd83 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -203,13 +203,7 @@ const DbgInfoReloc = struct { else => unreachable, // not a possible argument }; - try dw.genArgDbgInfo( - reloc.name, - reloc.ty, - function.bin_file.tag, - function.mod_fn.owner_decl, - loc, - ); + try dw.genArgDbgInfo(reloc.name, reloc.ty, function.mod_fn.owner_decl, loc); }, .plan9 => {}, .none => {}, @@ -255,14 +249,7 @@ const DbgInfoReloc = struct { break :blk .nop; }, }; - try dw.genVarDbgInfo( - reloc.name, - reloc.ty, - function.bin_file.tag, - function.mod_fn.owner_decl, - is_ptr, - loc, - ); + try dw.genVarDbgInfo(reloc.name, reloc.ty, function.mod_fn.owner_decl, is_ptr, loc); }, .plan9 => {}, .none => {}, @@ -4019,11 +4006,17 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type .direct => .load_memory_ptr_direct, .import => unreachable, }; - const mod = self.bin_file.options.module.?; - const owner_decl = mod.declPtr(self.mod_fn.owner_decl); const atom_index = switch (self.bin_file.tag) { - .macho => owner_decl.link.macho.getSymbolIndex().?, - .coff => owner_decl.link.coff.getSymbolIndex().?, + .macho => blk: { + const macho_file = self.bin_file.cast(link.File.MachO).?; + const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); + break :blk macho_file.getAtom(atom).getSymbolIndex().?; + }, + .coff => blk: { + const coff_file = self.bin_file.cast(link.File.Coff).?; + const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); + break :blk coff_file.getAtom(atom).getSymbolIndex().?; + }, else => unreachable, // unsupported target format }; _ = try self.addInst(.{ @@ -4301,34 +4294,37 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier if (self.air.value(callee)) |func_value| { if (func_value.castTag(.function)) |func_payload| { const func = func_payload.data; - const fn_owner_decl = mod.declPtr(func.owner_decl); if (self.bin_file.cast(link.File.Elf)) |elf_file| { - try fn_owner_decl.link.elf.ensureInitialized(elf_file); - const got_addr = @intCast(u32, fn_owner_decl.link.elf.getOffsetTableAddress(elf_file)); + const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl); + const atom = elf_file.getAtom(atom_index); + const got_addr = @intCast(u32, atom.getOffsetTableAddress(elf_file)); try self.genSetReg(Type.initTag(.usize), .x30, .{ .memory = got_addr }); } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { - try fn_owner_decl.link.macho.ensureInitialized(macho_file); + const atom = try macho_file.getOrCreateAtomForDecl(func.owner_decl); + const sym_index = macho_file.getAtom(atom).getSymbolIndex().?; try self.genSetReg(Type.initTag(.u64), .x30, .{ .linker_load = .{ .type = .got, - .sym_index = fn_owner_decl.link.macho.getSymbolIndex().?, + .sym_index = sym_index, }, }); } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { - try fn_owner_decl.link.coff.ensureInitialized(coff_file); + const atom = try coff_file.getOrCreateAtomForDecl(func.owner_decl); + const sym_index = coff_file.getAtom(atom).getSymbolIndex().?; try self.genSetReg(Type.initTag(.u64), .x30, .{ .linker_load = .{ .type = .got, - .sym_index = fn_owner_decl.link.coff.getSymbolIndex().?, + .sym_index = sym_index, }, }); } else if (self.bin_file.cast(link.File.Plan9)) |p9| { - try p9.seeDecl(func.owner_decl); + const decl_block_index = try p9.seeDecl(func.owner_decl); + const decl_block = p9.getDeclBlock(decl_block_index); const ptr_bits = self.target.cpu.arch.ptrBitWidth(); const ptr_bytes: u64 = @divExact(ptr_bits, 8); const got_addr = p9.bases.data; - const got_index = fn_owner_decl.link.plan9.got_index.?; + const got_index = decl_block.got_index.?; const fn_got_addr = got_addr + got_index * ptr_bytes; try self.genSetReg(Type.initTag(.usize), .x30, .{ .memory = fn_got_addr }); } else unreachable; @@ -4349,11 +4345,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier if (self.bin_file.cast(link.File.MachO)) |macho_file| { const sym_index = try macho_file.getGlobalSymbol(mem.sliceTo(decl_name, 0)); + const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); + const atom_index = macho_file.getAtom(atom).getSymbolIndex().?; _ = try self.addInst(.{ .tag = .call_extern, .data = .{ .relocation = .{ - .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.getSymbolIndex().?, + .atom_index = atom_index, .sym_index = sym_index, }, }, @@ -5488,11 +5486,17 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro .direct => .load_memory_ptr_direct, .import => unreachable, }; - const mod = self.bin_file.options.module.?; - const owner_decl = mod.declPtr(self.mod_fn.owner_decl); const atom_index = switch (self.bin_file.tag) { - .macho => owner_decl.link.macho.getSymbolIndex().?, - .coff => owner_decl.link.coff.getSymbolIndex().?, + .macho => blk: { + const macho_file = self.bin_file.cast(link.File.MachO).?; + const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); + break :blk macho_file.getAtom(atom).getSymbolIndex().?; + }, + .coff => blk: { + const coff_file = self.bin_file.cast(link.File.Coff).?; + const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); + break :blk coff_file.getAtom(atom).getSymbolIndex().?; + }, else => unreachable, // unsupported target format }; _ = try self.addInst(.{ @@ -5602,11 +5606,17 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void .direct => .load_memory_direct, .import => .load_memory_import, }; - const mod = self.bin_file.options.module.?; - const owner_decl = mod.declPtr(self.mod_fn.owner_decl); const atom_index = switch (self.bin_file.tag) { - .macho => owner_decl.link.macho.getSymbolIndex().?, - .coff => owner_decl.link.coff.getSymbolIndex().?, + .macho => blk: { + const macho_file = self.bin_file.cast(link.File.MachO).?; + const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); + break :blk macho_file.getAtom(atom).getSymbolIndex().?; + }, + .coff => blk: { + const coff_file = self.bin_file.cast(link.File.Coff).?; + const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); + break :blk coff_file.getAtom(atom).getSymbolIndex().?; + }, else => unreachable, // unsupported target format }; _ = try self.addInst(.{ @@ -5796,11 +5806,17 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I .direct => .load_memory_ptr_direct, .import => unreachable, }; - const mod = self.bin_file.options.module.?; - const owner_decl = mod.declPtr(self.mod_fn.owner_decl); const atom_index = switch (self.bin_file.tag) { - .macho => owner_decl.link.macho.getSymbolIndex().?, - .coff => owner_decl.link.coff.getSymbolIndex().?, + .macho => blk: { + const macho_file = self.bin_file.cast(link.File.MachO).?; + const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); + break :blk macho_file.getAtom(atom).getSymbolIndex().?; + }, + .coff => blk: { + const coff_file = self.bin_file.cast(link.File.Coff).?; + const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); + break :blk coff_file.getAtom(atom).getSymbolIndex().?; + }, else => unreachable, // unsupported target format }; _ = try self.addInst(.{ @@ -6119,23 +6135,27 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne mod.markDeclAlive(decl); if (self.bin_file.cast(link.File.Elf)) |elf_file| { - try decl.link.elf.ensureInitialized(elf_file); - return MCValue{ .memory = decl.link.elf.getOffsetTableAddress(elf_file) }; + const atom_index = try elf_file.getOrCreateAtomForDecl(decl_index); + const atom = elf_file.getAtom(atom_index); + return MCValue{ .memory = atom.getOffsetTableAddress(elf_file) }; } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { - try decl.link.macho.ensureInitialized(macho_file); + const atom = try macho_file.getOrCreateAtomForDecl(decl_index); + const sym_index = macho_file.getAtom(atom).getSymbolIndex().?; return MCValue{ .linker_load = .{ .type = .got, - .sym_index = decl.link.macho.getSymbolIndex().?, + .sym_index = sym_index, } }; } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { - try decl.link.coff.ensureInitialized(coff_file); + const atom_index = try coff_file.getOrCreateAtomForDecl(decl_index); + const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; return MCValue{ .linker_load = .{ .type = .got, - .sym_index = decl.link.coff.getSymbolIndex().?, + .sym_index = sym_index, } }; } else if (self.bin_file.cast(link.File.Plan9)) |p9| { - try p9.seeDecl(decl_index); - const got_addr = p9.bases.data + decl.link.plan9.got_index.? * ptr_bytes; + const decl_block_index = try p9.seeDecl(decl_index); + const decl_block = p9.getDeclBlock(decl_block_index); + const got_addr = p9.bases.data + decl_block.got_index.? * ptr_bytes; return MCValue{ .memory = got_addr }; } else { return self.fail("TODO codegen non-ELF const Decl pointer", .{}); @@ -6148,8 +6168,7 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue { return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)}); }; if (self.bin_file.cast(link.File.Elf)) |elf_file| { - const vaddr = elf_file.local_symbols.items[local_sym_index].st_value; - return MCValue{ .memory = vaddr }; + return MCValue{ .memory = elf_file.getSymbol(local_sym_index).st_value }; } else if (self.bin_file.cast(link.File.MachO)) |_| { return MCValue{ .linker_load = .{ .type = .direct, diff --git a/src/arch/aarch64/Emit.zig b/src/arch/aarch64/Emit.zig index 3812597789..3c2a81d5d1 100644 --- a/src/arch/aarch64/Emit.zig +++ b/src/arch/aarch64/Emit.zig @@ -670,9 +670,9 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void { if (emit.bin_file.cast(link.File.MachO)) |macho_file| { // Add relocation to the decl. - const atom = macho_file.getAtomForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?; + const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?; const target = macho_file.getGlobalByIndex(relocation.sym_index); - try atom.addRelocation(macho_file, .{ + try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{ .type = @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_BRANCH26), .target = target, .offset = offset, @@ -883,10 +883,10 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void { } if (emit.bin_file.cast(link.File.MachO)) |macho_file| { - const atom = macho_file.getAtomForSymbol(.{ .sym_index = data.atom_index, .file = null }).?; + const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = data.atom_index, .file = null }).?; // TODO this causes segfault in stage1 // try atom.addRelocations(macho_file, 2, .{ - try atom.addRelocation(macho_file, .{ + try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{ .target = .{ .sym_index = data.sym_index, .file = null }, .offset = offset, .addend = 0, @@ -902,7 +902,7 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void { else => unreachable, }, }); - try atom.addRelocation(macho_file, .{ + try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{ .target = .{ .sym_index = data.sym_index, .file = null }, .offset = offset + 4, .addend = 0, @@ -919,7 +919,7 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void { }, }); } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| { - const atom = coff_file.getAtomForSymbol(.{ .sym_index = data.atom_index, .file = null }).?; + const atom_index = coff_file.getAtomIndexForSymbol(.{ .sym_index = data.atom_index, .file = null }).?; const target = switch (tag) { .load_memory_got, .load_memory_ptr_got, @@ -929,7 +929,7 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void { .load_memory_import => coff_file.getGlobalByIndex(data.sym_index), else => unreachable, }; - try atom.addRelocation(coff_file, .{ + try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{ .target = target, .offset = offset, .addend = 0, @@ -946,7 +946,7 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void { else => unreachable, }, }); - try atom.addRelocation(coff_file, .{ + try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{ .target = target, .offset = offset + 4, .addend = 0, diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 49f979624d..57a8aed699 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -282,13 +282,7 @@ const DbgInfoReloc = struct { else => unreachable, // not a possible argument }; - try dw.genArgDbgInfo( - reloc.name, - reloc.ty, - function.bin_file.tag, - function.mod_fn.owner_decl, - loc, - ); + try dw.genArgDbgInfo(reloc.name, reloc.ty, function.mod_fn.owner_decl, loc); }, .plan9 => {}, .none => {}, @@ -331,14 +325,7 @@ const DbgInfoReloc = struct { break :blk .nop; }, }; - try dw.genVarDbgInfo( - reloc.name, - reloc.ty, - function.bin_file.tag, - function.mod_fn.owner_decl, - is_ptr, - loc, - ); + try dw.genVarDbgInfo(reloc.name, reloc.ty, function.mod_fn.owner_decl, is_ptr, loc); }, .plan9 => {}, .none => {}, @@ -4256,12 +4243,11 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier if (self.air.value(callee)) |func_value| { if (func_value.castTag(.function)) |func_payload| { const func = func_payload.data; - const mod = self.bin_file.options.module.?; - const fn_owner_decl = mod.declPtr(func.owner_decl); if (self.bin_file.cast(link.File.Elf)) |elf_file| { - try fn_owner_decl.link.elf.ensureInitialized(elf_file); - const got_addr = @intCast(u32, fn_owner_decl.link.elf.getOffsetTableAddress(elf_file)); + const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl); + const atom = elf_file.getAtom(atom_index); + const got_addr = @intCast(u32, atom.getOffsetTableAddress(elf_file)); try self.genSetReg(Type.initTag(.usize), .lr, .{ .memory = got_addr }); } else if (self.bin_file.cast(link.File.MachO)) |_| { unreachable; // unsupported architecture for MachO @@ -6084,15 +6070,17 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne mod.markDeclAlive(decl); if (self.bin_file.cast(link.File.Elf)) |elf_file| { - try decl.link.elf.ensureInitialized(elf_file); - return MCValue{ .memory = decl.link.elf.getOffsetTableAddress(elf_file) }; + const atom_index = try elf_file.getOrCreateAtomForDecl(decl_index); + const atom = elf_file.getAtom(atom_index); + return MCValue{ .memory = atom.getOffsetTableAddress(elf_file) }; } else if (self.bin_file.cast(link.File.MachO)) |_| { unreachable; // unsupported architecture for MachO } else if (self.bin_file.cast(link.File.Coff)) |_| { return self.fail("TODO codegen COFF const Decl pointer", .{}); } else if (self.bin_file.cast(link.File.Plan9)) |p9| { - try p9.seeDecl(decl_index); - const got_addr = p9.bases.data + decl.link.plan9.got_index.? * ptr_bytes; + const decl_block_index = try p9.seeDecl(decl_index); + const decl_block = p9.getDeclBlock(decl_block_index); + const got_addr = p9.bases.data + decl_block.got_index.? * ptr_bytes; return MCValue{ .memory = got_addr }; } else { return self.fail("TODO codegen non-ELF const Decl pointer", .{}); @@ -6106,8 +6094,7 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue { return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)}); }; if (self.bin_file.cast(link.File.Elf)) |elf_file| { - const vaddr = elf_file.local_symbols.items[local_sym_index].st_value; - return MCValue{ .memory = vaddr }; + return MCValue{ .memory = elf_file.getSymbol(local_sym_index).st_value }; } else if (self.bin_file.cast(link.File.MachO)) |_| { unreachable; } else if (self.bin_file.cast(link.File.Coff)) |_| { diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index d50a614206..8b8fca4859 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/src/arch/riscv64/CodeGen.zig @@ -1615,13 +1615,9 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void { switch (self.debug_output) { .dwarf => |dw| switch (mcv) { - .register => |reg| try dw.genArgDbgInfo( - name, - ty, - self.bin_file.tag, - self.mod_fn.owner_decl, - .{ .register = reg.dwarfLocOp() }, - ), + .register => |reg| try dw.genArgDbgInfo(name, ty, self.mod_fn.owner_decl, .{ + .register = reg.dwarfLocOp(), + }), .stack_offset => {}, else => {}, }, @@ -1721,12 +1717,9 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier if (self.air.value(callee)) |func_value| { if (func_value.castTag(.function)) |func_payload| { const func = func_payload.data; - - const mod = self.bin_file.options.module.?; - const fn_owner_decl = mod.declPtr(func.owner_decl); - try fn_owner_decl.link.elf.ensureInitialized(elf_file); - const got_addr = @intCast(u32, fn_owner_decl.link.elf.getOffsetTableAddress(elf_file)); - + const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl); + const atom = elf_file.getAtom(atom_index); + const got_addr = @intCast(u32, atom.getOffsetTableAddress(elf_file)); try self.genSetReg(Type.initTag(.usize), .ra, .{ .memory = got_addr }); _ = try self.addInst(.{ .tag = .jalr, @@ -2553,17 +2546,17 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne const decl = mod.declPtr(decl_index); mod.markDeclAlive(decl); if (self.bin_file.cast(link.File.Elf)) |elf_file| { - try decl.link.elf.ensureInitialized(elf_file); - return MCValue{ .memory = decl.link.elf.getOffsetTableAddress(elf_file) }; + const atom_index = try elf_file.getOrCreateAtomForDecl(decl_index); + const atom = elf_file.getAtom(atom_index); + return MCValue{ .memory = atom.getOffsetTableAddress(elf_file) }; } else if (self.bin_file.cast(link.File.MachO)) |_| { - // TODO I'm hacking my way through here by repurposing .memory for storing - // index to the GOT target symbol index. - return MCValue{ .memory = decl.link.macho.sym_index }; + unreachable; } else if (self.bin_file.cast(link.File.Coff)) |_| { return self.fail("TODO codegen COFF const Decl pointer", .{}); } else if (self.bin_file.cast(link.File.Plan9)) |p9| { - try p9.seeDecl(decl_index); - const got_addr = p9.bases.data + decl.link.plan9.got_index.? * ptr_bytes; + const decl_block_index = try p9.seeDecl(decl_index); + const decl_block = p9.getDeclBlock(decl_block_index); + const got_addr = p9.bases.data + decl_block.got_index.? * ptr_bytes; return MCValue{ .memory = got_addr }; } else { return self.fail("TODO codegen non-ELF const Decl pointer", .{}); diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig index 5e9326d23b..418c67c580 100644 --- a/src/arch/sparc64/CodeGen.zig +++ b/src/arch/sparc64/CodeGen.zig @@ -1216,11 +1216,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier if (self.bin_file.tag == link.File.Elf.base_tag) { if (func_value.castTag(.function)) |func_payload| { const func = func_payload.data; - const mod = self.bin_file.options.module.?; - const fn_owner_decl = mod.declPtr(func.owner_decl); const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: { - try fn_owner_decl.link.elf.ensureInitialized(elf_file); - break :blk @intCast(u32, fn_owner_decl.link.elf.getOffsetTableAddress(elf_file)); + const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl); + const atom = elf_file.getAtom(atom_index); + break :blk @intCast(u32, atom.getOffsetTableAddress(elf_file)); } else unreachable; try self.genSetReg(Type.initTag(.usize), .o7, .{ .memory = got_addr }); @@ -3413,13 +3412,9 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void { switch (self.debug_output) { .dwarf => |dw| switch (mcv) { - .register => |reg| try dw.genArgDbgInfo( - name, - ty, - self.bin_file.tag, - self.mod_fn.owner_decl, - .{ .register = reg.dwarfLocOp() }, - ), + .register => |reg| try dw.genArgDbgInfo(name, ty, self.mod_fn.owner_decl, .{ + .register = reg.dwarfLocOp(), + }), else => {}, }, else => {}, @@ -4205,8 +4200,9 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne mod.markDeclAlive(decl); if (self.bin_file.cast(link.File.Elf)) |elf_file| { - try decl.link.elf.ensureInitialized(elf_file); - return MCValue{ .memory = decl.link.elf.getOffsetTableAddress(elf_file) }; + const atom_index = try elf_file.getOrCreateAtomForDecl(decl_index); + const atom = elf_file.getAtom(atom_index); + return MCValue{ .memory = atom.getOffsetTableAddress(elf_file) }; } else { return self.fail("TODO codegen non-ELF const Decl pointer", .{}); } diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index c0d0c11b56..ec494b1a57 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -1194,7 +1194,7 @@ fn genFunc(func: *CodeGen) InnerError!void { const fn_info = func.decl.ty.fnInfo(); var func_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types, fn_info.return_type, func.target); defer func_type.deinit(func.gpa); - func.decl.fn_link.wasm.type_index = try func.bin_file.putOrGetFuncType(func_type); + func.decl.fn_link.?.type_index = try func.bin_file.putOrGetFuncType(func_type); var cc_result = try func.resolveCallingConventionValues(func.decl.ty); defer cc_result.deinit(func.gpa); @@ -1269,10 +1269,10 @@ fn genFunc(func: *CodeGen) InnerError!void { var emit: Emit = .{ .mir = mir, - .bin_file = &func.bin_file.base, + .bin_file = func.bin_file, .code = func.code, .locals = func.locals.items, - .decl = func.decl, + .decl_index = func.decl_index, .dbg_output = func.debug_output, .prev_di_line = 0, .prev_di_column = 0, @@ -2117,33 +2117,31 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif const fn_info = fn_ty.fnInfo(); const first_param_sret = firstParamSRet(fn_info.cc, fn_info.return_type, func.target); - const callee: ?*Decl = blk: { + const callee: ?Decl.Index = blk: { const func_val = func.air.value(pl_op.operand) orelse break :blk null; const module = func.bin_file.base.options.module.?; if (func_val.castTag(.function)) |function| { - const decl = module.declPtr(function.data.owner_decl); - try decl.link.wasm.ensureInitialized(func.bin_file); - break :blk decl; + _ = try func.bin_file.getOrCreateAtomForDecl(function.data.owner_decl); + break :blk function.data.owner_decl; } else if (func_val.castTag(.extern_fn)) |extern_fn| { const ext_decl = module.declPtr(extern_fn.data.owner_decl); const ext_info = ext_decl.ty.fnInfo(); var func_type = try genFunctype(func.gpa, ext_info.cc, ext_info.param_types, ext_info.return_type, func.target); defer func_type.deinit(func.gpa); - const atom = &ext_decl.link.wasm; - try atom.ensureInitialized(func.bin_file); - ext_decl.fn_link.wasm.type_index = try func.bin_file.putOrGetFuncType(func_type); + const atom_index = try func.bin_file.getOrCreateAtomForDecl(extern_fn.data.owner_decl); + const atom = func.bin_file.getAtomPtr(atom_index); + ext_decl.fn_link.?.type_index = try func.bin_file.putOrGetFuncType(func_type); try func.bin_file.addOrUpdateImport( mem.sliceTo(ext_decl.name, 0), atom.getSymbolIndex().?, ext_decl.getExternFn().?.lib_name, - ext_decl.fn_link.wasm.type_index, + ext_decl.fn_link.?.type_index, ); - break :blk ext_decl; + break :blk extern_fn.data.owner_decl; } else if (func_val.castTag(.decl_ref)) |decl_ref| { - const decl = module.declPtr(decl_ref.data); - try decl.link.wasm.ensureInitialized(func.bin_file); - break :blk decl; + _ = try func.bin_file.getOrCreateAtomForDecl(decl_ref.data); + break :blk decl_ref.data; } return func.fail("Expected a function, but instead found type '{}'", .{func_val.tag()}); }; @@ -2164,7 +2162,8 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif } if (callee) |direct| { - try func.addLabel(.call, direct.link.wasm.sym_index); + const atom_index = func.bin_file.decls.get(direct).?; + try func.addLabel(.call, func.bin_file.getAtom(atom_index).sym_index); } else { // in this case we call a function pointer // so load its value onto the stack @@ -2477,7 +2476,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { .dwarf => |dwarf| { const src_index = func.air.instructions.items(.data)[inst].arg.src_index; const name = func.mod_fn.getParamName(func.bin_file.base.options.module.?, src_index); - try dwarf.genArgDbgInfo(name, arg_ty, .wasm, func.mod_fn.owner_decl, .{ + try dwarf.genArgDbgInfo(name, arg_ty, func.mod_fn.owner_decl, .{ .wasm_local = arg.local.value, }); }, @@ -2760,9 +2759,10 @@ fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: Module.Decl.Ind } module.markDeclAlive(decl); - try decl.link.wasm.ensureInitialized(func.bin_file); + const atom_index = try func.bin_file.getOrCreateAtomForDecl(decl_index); + const atom = func.bin_file.getAtom(atom_index); - const target_sym_index = decl.link.wasm.sym_index; + const target_sym_index = atom.sym_index; if (decl.ty.zigTypeTag() == .Fn) { try func.bin_file.addTableFunction(target_sym_index); return WValue{ .function_index = target_sym_index }; @@ -5547,7 +5547,7 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) !void { break :blk .nop; }, }; - try func.debug_output.dwarf.genVarDbgInfo(name, ty, .wasm, func.mod_fn.owner_decl, is_ptr, loc); + try func.debug_output.dwarf.genVarDbgInfo(name, ty, func.mod_fn.owner_decl, is_ptr, loc); func.finishAir(inst, .none, &.{}); } diff --git a/src/arch/wasm/Emit.zig b/src/arch/wasm/Emit.zig index 71d21d2797..a340ac5da8 100644 --- a/src/arch/wasm/Emit.zig +++ b/src/arch/wasm/Emit.zig @@ -11,8 +11,8 @@ const leb128 = std.leb; /// Contains our list of instructions mir: Mir, -/// Reference to the file handler -bin_file: *link.File, +/// Reference to the Wasm module linker +bin_file: *link.File.Wasm, /// Possible error message. When set, the value is allocated and /// must be freed manually. error_msg: ?*Module.ErrorMsg = null, @@ -21,7 +21,7 @@ code: *std.ArrayList(u8), /// List of allocated locals. locals: []const u8, /// The declaration that code is being generated for. -decl: *Module.Decl, +decl_index: Module.Decl.Index, // Debug information /// Holds the debug information for this emission @@ -252,8 +252,8 @@ fn offset(self: Emit) u32 { fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError { @setCold(true); std.debug.assert(emit.error_msg == null); - // TODO: Determine the source location. - emit.error_msg = try Module.ErrorMsg.create(emit.bin_file.allocator, emit.decl.srcLoc(), format, args); + const mod = emit.bin_file.base.options.module.?; + emit.error_msg = try Module.ErrorMsg.create(emit.bin_file.base.allocator, mod.declPtr(emit.decl_index).srcLoc(), format, args); return error.EmitFail; } @@ -304,8 +304,9 @@ fn emitGlobal(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) !void { const global_offset = emit.offset(); try emit.code.appendSlice(&buf); - // globals can have index 0 as it represents the stack pointer - try emit.decl.link.wasm.relocs.append(emit.bin_file.allocator, .{ + const atom_index = emit.bin_file.decls.get(emit.decl_index).?; + const atom = emit.bin_file.getAtomPtr(atom_index); + try atom.relocs.append(emit.bin_file.base.allocator, .{ .index = label, .offset = global_offset, .relocation_type = .R_WASM_GLOBAL_INDEX_LEB, @@ -361,7 +362,9 @@ fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void { try emit.code.appendSlice(&buf); if (label != 0) { - try emit.decl.link.wasm.relocs.append(emit.bin_file.allocator, .{ + const atom_index = emit.bin_file.decls.get(emit.decl_index).?; + const atom = emit.bin_file.getAtomPtr(atom_index); + try atom.relocs.append(emit.bin_file.base.allocator, .{ .offset = call_offset, .index = label, .relocation_type = .R_WASM_FUNCTION_INDEX_LEB, @@ -387,7 +390,9 @@ fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void { try emit.code.appendSlice(&buf); if (symbol_index != 0) { - try emit.decl.link.wasm.relocs.append(emit.bin_file.allocator, .{ + const atom_index = emit.bin_file.decls.get(emit.decl_index).?; + const atom = emit.bin_file.getAtomPtr(atom_index); + try atom.relocs.append(emit.bin_file.base.allocator, .{ .offset = index_offset, .index = symbol_index, .relocation_type = .R_WASM_TABLE_INDEX_SLEB, @@ -399,7 +404,7 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void { const extra_index = emit.mir.instructions.items(.data)[inst].payload; const mem = emit.mir.extraData(Mir.Memory, extra_index).data; const mem_offset = emit.offset() + 1; - const is_wasm32 = emit.bin_file.options.target.cpu.arch == .wasm32; + const is_wasm32 = emit.bin_file.base.options.target.cpu.arch == .wasm32; if (is_wasm32) { try emit.code.append(std.wasm.opcode(.i32_const)); var buf: [5]u8 = undefined; @@ -413,7 +418,9 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void { } if (mem.pointer != 0) { - try emit.decl.link.wasm.relocs.append(emit.bin_file.allocator, .{ + const atom_index = emit.bin_file.decls.get(emit.decl_index).?; + const atom = emit.bin_file.getAtomPtr(atom_index); + try atom.relocs.append(emit.bin_file.base.allocator, .{ .offset = mem_offset, .index = mem.pointer, .relocation_type = if (is_wasm32) .R_WASM_MEMORY_ADDR_LEB else .R_WASM_MEMORY_ADDR_LEB64, diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index df24fe5e7d..c11ea4e63e 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -2668,12 +2668,13 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue switch (ptr) { .linker_load => |load_struct| { const abi_size = @intCast(u32, ptr_ty.abiSize(self.target.*)); - const mod = self.bin_file.options.module.?; - const fn_owner_decl = mod.declPtr(self.mod_fn.owner_decl); - const atom_index = if (self.bin_file.tag == link.File.MachO.base_tag) - fn_owner_decl.link.macho.getSymbolIndex().? - else - fn_owner_decl.link.coff.getSymbolIndex().?; + const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: { + const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); + break :blk macho_file.getAtom(atom).getSymbolIndex().?; + } else if (self.bin_file.cast(link.File.Coff)) |coff_file| blk: { + const atom = try coff_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); + break :blk coff_file.getAtom(atom).getSymbolIndex().?; + } else unreachable; const flags: u2 = switch (load_struct.type) { .got => 0b00, .direct => 0b01, @@ -3835,7 +3836,7 @@ fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void { }, else => unreachable, // not a valid function parameter }; - try dw.genArgDbgInfo(name, ty, self.bin_file.tag, self.mod_fn.owner_decl, loc); + try dw.genArgDbgInfo(name, ty, self.mod_fn.owner_decl, loc); }, .plan9 => {}, .none => {}, @@ -3875,7 +3876,7 @@ fn genVarDbgInfo( break :blk .nop; }, }; - try dw.genVarDbgInfo(name, ty, self.bin_file.tag, self.mod_fn.owner_decl, is_ptr, loc); + try dw.genVarDbgInfo(name, ty, self.mod_fn.owner_decl, is_ptr, loc); }, .plan9 => {}, .none => {}, @@ -3995,19 +3996,19 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier if (self.air.value(callee)) |func_value| { if (func_value.castTag(.function)) |func_payload| { const func = func_payload.data; - const fn_owner_decl = mod.declPtr(func.owner_decl); if (self.bin_file.cast(link.File.Elf)) |elf_file| { - try fn_owner_decl.link.elf.ensureInitialized(elf_file); - const got_addr = @intCast(u32, fn_owner_decl.link.elf.getOffsetTableAddress(elf_file)); + const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl); + const atom = elf_file.getAtom(atom_index); + const got_addr = @intCast(u32, atom.getOffsetTableAddress(elf_file)); _ = try self.addInst(.{ .tag = .call, .ops = Mir.Inst.Ops.encode(.{ .flags = 0b01 }), .data = .{ .imm = got_addr }, }); } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { - try fn_owner_decl.link.coff.ensureInitialized(coff_file); - const sym_index = fn_owner_decl.link.coff.getSymbolIndex().?; + const atom_index = try coff_file.getOrCreateAtomForDecl(func.owner_decl); + const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; try self.genSetReg(Type.initTag(.usize), .rax, .{ .linker_load = .{ .type = .got, @@ -4023,8 +4024,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier .data = undefined, }); } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { - try fn_owner_decl.link.macho.ensureInitialized(macho_file); - const sym_index = fn_owner_decl.link.macho.getSymbolIndex().?; + const atom_index = try macho_file.getOrCreateAtomForDecl(func.owner_decl); + const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; try self.genSetReg(Type.initTag(.usize), .rax, .{ .linker_load = .{ .type = .got, @@ -4040,11 +4041,12 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier .data = undefined, }); } else if (self.bin_file.cast(link.File.Plan9)) |p9| { - try p9.seeDecl(func.owner_decl); + const decl_block_index = try p9.seeDecl(func.owner_decl); + const decl_block = p9.getDeclBlock(decl_block_index); const ptr_bits = self.target.cpu.arch.ptrBitWidth(); const ptr_bytes: u64 = @divExact(ptr_bits, 8); const got_addr = p9.bases.data; - const got_index = fn_owner_decl.link.plan9.got_index.?; + const got_index = decl_block.got_index.?; const fn_got_addr = got_addr + got_index * ptr_bytes; _ = try self.addInst(.{ .tag = .call, @@ -4080,15 +4082,15 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier }); } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { const sym_index = try macho_file.getGlobalSymbol(mem.sliceTo(decl_name, 0)); + const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl); + const atom_index = macho_file.getAtom(atom).getSymbolIndex().?; _ = try self.addInst(.{ .tag = .call_extern, .ops = undefined, - .data = .{ - .relocation = .{ - .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.getSymbolIndex().?, - .sym_index = sym_index, - }, - }, + .data = .{ .relocation = .{ + .atom_index = atom_index, + .sym_index = sym_index, + } }, }); } else { return self.fail("TODO implement calling extern functions", .{}); @@ -6719,23 +6721,27 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne module.markDeclAlive(decl); if (self.bin_file.cast(link.File.Elf)) |elf_file| { - try decl.link.elf.ensureInitialized(elf_file); - return MCValue{ .memory = decl.link.elf.getOffsetTableAddress(elf_file) }; + const atom_index = try elf_file.getOrCreateAtomForDecl(decl_index); + const atom = elf_file.getAtom(atom_index); + return MCValue{ .memory = atom.getOffsetTableAddress(elf_file) }; } else if (self.bin_file.cast(link.File.MachO)) |macho_file| { - try decl.link.macho.ensureInitialized(macho_file); + const atom_index = try macho_file.getOrCreateAtomForDecl(decl_index); + const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?; return MCValue{ .linker_load = .{ .type = .got, - .sym_index = decl.link.macho.getSymbolIndex().?, + .sym_index = sym_index, } }; } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { - try decl.link.coff.ensureInitialized(coff_file); + const atom_index = try coff_file.getOrCreateAtomForDecl(decl_index); + const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?; return MCValue{ .linker_load = .{ .type = .got, - .sym_index = decl.link.coff.getSymbolIndex().?, + .sym_index = sym_index, } }; } else if (self.bin_file.cast(link.File.Plan9)) |p9| { - try p9.seeDecl(decl_index); - const got_addr = p9.bases.data + decl.link.plan9.got_index.? * ptr_bytes; + const decl_block_index = try p9.seeDecl(decl_index); + const decl_block = p9.getDeclBlock(decl_block_index); + const got_addr = p9.bases.data + decl_block.got_index.? * ptr_bytes; return MCValue{ .memory = got_addr }; } else { return self.fail("TODO codegen non-ELF const Decl pointer", .{}); @@ -6748,8 +6754,7 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue { return self.fail("lowering unnamed constant failed: {s}", .{@errorName(err)}); }; if (self.bin_file.cast(link.File.Elf)) |elf_file| { - const vaddr = elf_file.local_symbols.items[local_sym_index].st_value; - return MCValue{ .memory = vaddr }; + return MCValue{ .memory = elf_file.getSymbol(local_sym_index).st_value }; } else if (self.bin_file.cast(link.File.MachO)) |_| { return MCValue{ .linker_load = .{ .type = .direct, diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index af3ed5e053..c4f9b4eb42 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -1001,8 +1001,8 @@ fn mirLeaPic(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { 0b01 => @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_SIGNED), else => unreachable, }; - const atom = macho_file.getAtomForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?; - try atom.addRelocation(macho_file, .{ + const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?; + try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{ .type = reloc_type, .target = .{ .sym_index = relocation.sym_index, .file = null }, .offset = @intCast(u32, end_offset - 4), @@ -1011,8 +1011,8 @@ fn mirLeaPic(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { .length = 2, }); } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| { - const atom = coff_file.getAtomForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?; - try atom.addRelocation(coff_file, .{ + const atom_index = coff_file.getAtomIndexForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?; + try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{ .type = switch (ops.flags) { 0b00 => .got, 0b01 => .direct, @@ -1140,9 +1140,9 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { if (emit.bin_file.cast(link.File.MachO)) |macho_file| { // Add relocation to the decl. - const atom = macho_file.getAtomForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?; + const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?; const target = macho_file.getGlobalByIndex(relocation.sym_index); - try atom.addRelocation(macho_file, .{ + try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{ .type = @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_BRANCH), .target = target, .offset = offset, @@ -1152,9 +1152,9 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { }); } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| { // Add relocation to the decl. - const atom = coff_file.getAtomForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?; + const atom_index = coff_file.getAtomIndexForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?; const target = coff_file.getGlobalByIndex(relocation.sym_index); - try atom.addRelocation(coff_file, .{ + try link.File.Coff.Atom.addRelocation(coff_file, atom_index, .{ .type = .direct, .target = target, .offset = offset, |
