diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2022-09-10 00:18:39 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-09-10 00:18:39 +0200 |
| commit | fc5a6e0e327c1b671aa782d24059e27e5aa55c84 (patch) | |
| tree | db51f363314a023bec3c9c5eefc05839971a5c4a /src | |
| parent | d8f210354577eda1b438d692b28bb3a582913b5a (diff) | |
| download | zig-fc5a6e0e327c1b671aa782d24059e27e5aa55c84.tar.gz zig-fc5a6e0e327c1b671aa782d24059e27e5aa55c84.zip | |
x86_64: combine got_load, direct_load and imports_load into linker_load MCV
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 208 | ||||
| -rw-r--r-- | src/arch/x86_64/Emit.zig | 2 | ||||
| -rw-r--r-- | src/link/Coff.zig | 4 |
3 files changed, 70 insertions, 144 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 25e8695e82..05d7f2b73b 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -128,15 +128,11 @@ pub const MCValue = union(enum) { /// The value is in memory at a hard-coded address. /// If the type is a pointer, it means the pointer address is at this memory location. memory: u64, - /// The value is in memory referenced indirectly via a GOT entry index. - /// If the type is a pointer, it means the pointer is referenced indirectly via GOT. - /// When lowered, linker will emit a relocation of type X86_64_RELOC_GOT. - got_load: u32, - imports_load: u32, - /// The value is in memory referenced directly via symbol index. - /// If the type is a pointer, it means the pointer is referenced directly via symbol index. - /// When lowered, linker will emit a relocation of type X86_64_RELOC_SIGNED. - direct_load: u32, + /// The value is in memory but requires a linker relocation fixup: + /// * got - the value is referenced indirectly via GOT entry index (the linker emits a got-type reloc) + /// * direct - the value is referenced directly via symbol index index (the linker emits a displacement reloc) + /// * import - the value is referenced indirectly via import entry index (the linker emits an import-type reloc) + linker_load: struct { @"type": enum { got, direct, import }, sym_index: u32 }, /// The value is one of the stack variables. /// If the type is a pointer, it means the pointer address is in the stack at this offset. stack_offset: i32, @@ -150,9 +146,7 @@ pub const MCValue = union(enum) { .memory, .stack_offset, .ptr_stack_offset, - .direct_load, - .got_load, - .imports_load, + .linker_load, => true, else => false, }; @@ -165,26 +159,6 @@ pub const MCValue = union(enum) { }; } - fn isMutable(mcv: MCValue) bool { - return switch (mcv) { - .none => unreachable, - .unreach => unreachable, - .dead => unreachable, - - .immediate, - .memory, - .eflags, - .ptr_stack_offset, - .undef, - .register_overflow, - => false, - - .register, - .stack_offset, - => true, - }; - } - fn isRegister(mcv: MCValue) bool { return switch (mcv) { .register => true, @@ -2307,11 +2281,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { .data = .{ .imm = @bitCast(u32, -off) }, }); }, - .memory, - .got_load, - .direct_load, - .imports_load, - => { + .memory, .linker_load => { try self.loadMemPtrIntoRegister(addr_reg, Type.usize, array); }, else => return self.fail("TODO implement array_elem_val when array is {}", .{array}), @@ -2652,11 +2622,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo else => return self.fail("TODO implement loading from register into {}", .{dst_mcv}), } }, - .memory, - .got_load, - .direct_load, - .imports_load, - => { + .memory, .linker_load => { const reg = try self.copyToTmpRegister(ptr_ty, ptr); try self.load(dst_mcv, .{ .register = reg }, ptr_ty); }, @@ -2691,10 +2657,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue) InnerError!void { switch (ptr) { - .got_load, - .direct_load, - .imports_load, - => |sym_index| { + .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); @@ -2702,11 +2665,10 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue fn_owner_decl.link.macho.sym_index else fn_owner_decl.link.coff.sym_index; - const flags: u2 = switch (ptr) { - .got_load => 0b00, - .direct_load => 0b01, - .imports_load => 0b10, - else => unreachable, + const flags: u2 = switch (load_struct.@"type") { + .got => 0b00, + .direct => 0b01, + .import => 0b10, }; _ = try self.addInst(.{ .tag = .lea_pic, @@ -2717,7 +2679,7 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue .data = .{ .relocation = .{ .atom_index = atom_index, - .sym_index = sym_index, + .sym_index = load_struct.sym_index, }, }, }); @@ -2801,9 +2763,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type .register => |src_reg| { try self.genInlineMemcpyRegisterRegister(value_ty, reg, src_reg, 0); }, - .got_load, - .direct_load, - .imports_load, + .linker_load, .memory, .stack_offset, => { @@ -2822,11 +2782,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type }, } }, - .got_load, - .direct_load, - .imports_load, - .memory, - => { + .linker_load, .memory => { const value_lock: ?RegisterLock = switch (value) { .register => |reg| self.register_manager.lockReg(reg), else => null, @@ -2894,11 +2850,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type .register => { return self.store(new_ptr, value, ptr_ty, value_ty); }, - .got_load, - .direct_load, - .imports_load, - .memory, - => { + .linker_load, .memory => { if (abi_size <= 8) { const tmp_reg = try self.register_manager.allocReg(null, gp); const tmp_reg_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); @@ -3606,9 +3558,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu }); }, .memory, - .got_load, - .direct_load, - .imports_load, + .linker_load, .eflags, => { assert(abi_size <= 8); @@ -3694,10 +3644,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu => { return self.fail("TODO implement x86 ADD/SUB/CMP source memory", .{}); }, - .got_load, - .direct_load, - .imports_load, - => { + .linker_load => { return self.fail("TODO implement x86 ADD/SUB/CMP source symbol at index in linker", .{}); }, .eflags => { @@ -3708,10 +3655,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu .memory => { return self.fail("TODO implement x86 ADD/SUB/CMP destination memory", .{}); }, - .got_load, - .direct_load, - .imports_load, - => { + .linker_load => { return self.fail("TODO implement x86 ADD/SUB/CMP destination symbol at index", .{}); }, } @@ -3779,10 +3723,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M .memory => { return self.fail("TODO implement x86 multiply source memory", .{}); }, - .got_load, - .direct_load, - .imports_load, - => { + .linker_load => { return self.fail("TODO implement x86 multiply source symbol at index in linker", .{}); }, .eflags => { @@ -3826,10 +3767,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M .memory, .stack_offset => { return self.fail("TODO implement x86 multiply source memory", .{}); }, - .got_load, - .direct_load, - .imports_load, - => { + .linker_load => { return self.fail("TODO implement x86 multiply source symbol at index in linker", .{}); }, .eflags => { @@ -3840,10 +3778,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M .memory => { return self.fail("TODO implement x86 multiply destination memory", .{}); }, - .got_load, - .direct_load, - .imports_load, - => { + .linker_load => { return self.fail("TODO implement x86 multiply destination symbol at index in linker", .{}); }, } @@ -4006,9 +3941,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. .unreach => unreachable, .dead => unreachable, .memory => unreachable, - .got_load => unreachable, - .direct_load => unreachable, - .imports_load => unreachable, + .linker_load => unreachable, .eflags => unreachable, .register_overflow => unreachable, } @@ -4066,7 +3999,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. const func = func_payload.data; const fn_owner_decl = mod.declPtr(func.owner_decl); try self.genSetReg(Type.initTag(.usize), .rax, .{ - .got_load = fn_owner_decl.link.coff.sym_index, + .linker_load = .{ + .@"type" = .got, + .sym_index = fn_owner_decl.link.coff.sym_index, + }, }); _ = try self.addInst(.{ .tag = .call, @@ -4087,7 +4023,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. } const sym_index = try coff_file.getGlobalSymbol(mem.sliceTo(decl_name, 0)); try self.genSetReg(Type.initTag(.usize), .rax, .{ - .imports_load = sym_index, + .linker_load = .{ + .@"type" = .import, + .sym_index = sym_index, + }, }); _ = try self.addInst(.{ .tag = .call, @@ -4119,7 +4058,12 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. const func = func_payload.data; const fn_owner_decl = mod.declPtr(func.owner_decl); const sym_index = fn_owner_decl.link.macho.sym_index; - try self.genSetReg(Type.initTag(.usize), .rax, .{ .got_load = sym_index }); + try self.genSetReg(Type.initTag(.usize), .rax, .{ + .linker_load = .{ + .@"type" = .got, + .sym_index = sym_index, + }, + }); // callq *%rax _ = try self.addInst(.{ .tag = .call, @@ -4505,11 +4449,7 @@ fn genVarDbgInfo( leb128.writeILEB128(dbg_info.writer(), -off) catch unreachable; dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2); }, - .memory, - .got_load, - .direct_load, - .imports_load, - => { + .memory, .linker_load => { const ptr_width = @intCast(u8, @divExact(self.target.cpu.arch.ptrBitWidth(), 8)); const is_ptr = switch (tag) { .dbg_var_ptr => true, @@ -4540,10 +4480,11 @@ fn genVarDbgInfo( try dbg_info.append(DW.OP.deref); } switch (mcv) { - .got_load, - .direct_load, - .imports_load, - => |index| try dw.addExprlocReloc(index, offset, is_ptr), + .linker_load => |load_struct| try dw.addExprlocReloc( + load_struct.sym_index, + offset, + is_ptr, + ), else => {}, } }, @@ -5587,11 +5528,7 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE else => return self.fail("TODO implement inputs on stack for {} with abi size > 8", .{mcv}), } }, - .memory, - .direct_load, - .got_load, - .imports_load, - => { + .memory, .linker_load => { if (abi_size <= 8) { const reg = try self.copyToTmpRegister(ty, mcv); return self.genSetStackArg(ty, stack_offset, MCValue{ .register = reg }); @@ -5835,11 +5772,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl }, } }, - .memory, - .got_load, - .direct_load, - .imports_load, - => { + .memory, .linker_load => { if (abi_size <= 8) { const reg = try self.copyToTmpRegister(ty, mcv); return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts); @@ -5959,11 +5892,7 @@ fn genInlineMemcpy( const tmp_reg = regs[4].to8(); switch (dst_ptr) { - .memory, - .got_load, - .direct_load, - .imports_load, - => { + .memory, .linker_load => { try self.loadMemPtrIntoRegister(dst_addr_reg, Type.usize, dst_ptr); }, .ptr_stack_offset, .stack_offset => |off| { @@ -5992,11 +5921,7 @@ fn genInlineMemcpy( } switch (src_ptr) { - .memory, - .got_load, - .direct_load, - .imports_load, - => { + .memory, .linker_load => { try self.loadMemPtrIntoRegister(src_addr_reg, Type.usize, src_ptr); }, .ptr_stack_offset, .stack_offset => |off| { @@ -6120,11 +6045,7 @@ fn genInlineMemset( const index_reg = regs[1].to64(); switch (dst_ptr) { - .memory, - .got_load, - .direct_load, - .imports_load, - => { + .memory, .linker_load => { try self.loadMemPtrIntoRegister(addr_reg, Type.usize, dst_ptr); }, .ptr_stack_offset, .stack_offset => |off| { @@ -6356,10 +6277,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void .data = undefined, }); }, - .direct_load, - .got_load, - .imports_load, - => { + .linker_load => { switch (ty.zigTypeTag()) { .Float => { const base_reg = try self.register_manager.allocReg(null, gp); @@ -6753,11 +6671,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { // TODO Is this the only condition for pointer dereference for memcpy? const src: MCValue = blk: { switch (src_ptr) { - .got_load, - .direct_load, - .imports_load, - .memory, - => { + .linker_load, .memory => { const reg = try self.register_manager.allocReg(null, gp); try self.loadMemPtrIntoRegister(reg, src_ty, src_ptr); _ = try self.addInst(.{ @@ -6997,10 +6911,16 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne return MCValue{ .memory = got_addr }; } else if (self.bin_file.cast(link.File.MachO)) |_| { assert(decl.link.macho.sym_index != 0); - return MCValue{ .got_load = decl.link.macho.sym_index }; + return MCValue{ .linker_load = .{ + .@"type" = .got, + .sym_index = decl.link.macho.sym_index, + } }; } else if (self.bin_file.cast(link.File.Coff)) |_| { assert(decl.link.coff.sym_index != 0); - return MCValue{ .got_load = decl.link.coff.sym_index }; + return MCValue{ .linker_load = .{ + .@"type" = .got, + .sym_index = decl.link.coff.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; @@ -7019,9 +6939,15 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue { const vaddr = elf_file.local_symbols.items[local_sym_index].st_value; return MCValue{ .memory = vaddr }; } else if (self.bin_file.cast(link.File.MachO)) |_| { - return MCValue{ .direct_load = local_sym_index }; + return MCValue{ .linker_load = .{ + .@"type" = .direct, + .sym_index = local_sym_index, + } }; } else if (self.bin_file.cast(link.File.Coff)) |_| { - return MCValue{ .direct_load = local_sym_index }; + return MCValue{ .linker_load = .{ + .@"type" = .direct, + .sym_index = local_sym_index, + } }; } else if (self.bin_file.cast(link.File.Plan9)) |_| { return self.fail("TODO lower unnamed const in Plan9", .{}); } else { diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index aeb3f4770e..e99f6ff4f5 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -1021,7 +1021,7 @@ fn mirLeaPic(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { .@"type" = switch (ops.flags) { 0b00 => .got, 0b01 => .direct, - 0b10 => .imports, + 0b10 => .import, else => unreachable, }, .target = switch (ops.flags) { diff --git a/src/link/Coff.zig b/src/link/Coff.zig index ea36c8bc91..013a0c0475 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -127,7 +127,7 @@ pub const Reloc = struct { @"type": enum { got, direct, - imports, + import, }, target: SymbolWithLoc, offset: u32, @@ -141,7 +141,7 @@ pub const Reloc = struct { switch (self.@"type") { .got => return coff_file.getGotAtomForSymbol(self.target), .direct => return coff_file.getAtomForSymbol(self.target), - .imports => return coff_file.getImportAtomForSymbol(self.target), + .import => return coff_file.getImportAtomForSymbol(self.target), } } }; |
