authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-15 09:10:46+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-16 19:33:06+02:00
log45197ea7adfa34806b549263c06b988b5e35d48c
tree03ee67cf2eabb83e41864958509823a05f83da54
parentc71a79f618abcc547f327edcdb45f01768200dca

codegen+elf: lower imported data refs


11 files changed, 107 insertions(+), 29 deletions(-)

src/arch/aarch64/CodeGen.zig+5-1
...@@ -4012,6 +4012,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type...@@ -4012,6 +4012,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
4012 .got => .load_memory_ptr_got,4012 .got => .load_memory_ptr_got,
4013 .direct => .load_memory_ptr_direct,4013 .direct => .load_memory_ptr_direct,
4014 .import => unreachable,4014 .import => unreachable,
4015 .actual_got => unreachable,
4015 };4016 };
4016 const atom_index = switch (self.bin_file.tag) {4017 const atom_index = switch (self.bin_file.tag) {
4017 .macho => blk: {4018 .macho => blk: {
...@@ -5531,6 +5532,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -5531,6 +5532,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
5531 .got => .load_memory_ptr_got,5532 .got => .load_memory_ptr_got,
5532 .direct => .load_memory_ptr_direct,5533 .direct => .load_memory_ptr_direct,
5533 .import => unreachable,5534 .import => unreachable,
5535 .actual_got => unreachable,
5534 };5536 };
5535 const atom_index = switch (self.bin_file.tag) {5537 const atom_index = switch (self.bin_file.tag) {
5536 .macho => blk: {5538 .macho => blk: {
...@@ -5652,6 +5654,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5652,6 +5654,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5652 .got => .load_memory_got,5654 .got => .load_memory_got,
5653 .direct => .load_memory_direct,5655 .direct => .load_memory_direct,
5654 .import => .load_memory_import,5656 .import => .load_memory_import,
5657 .actual_got => unreachable,
5655 };5658 };
5656 const atom_index = switch (self.bin_file.tag) {5659 const atom_index = switch (self.bin_file.tag) {
5657 .macho => blk: {5660 .macho => blk: {
...@@ -5849,6 +5852,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I...@@ -5849,6 +5852,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
5849 .got => .load_memory_ptr_got,5852 .got => .load_memory_ptr_got,
5850 .direct => .load_memory_ptr_direct,5853 .direct => .load_memory_ptr_direct,
5851 .import => unreachable,5854 .import => unreachable,
5855 .actual_got => unreachable,
5852 };5856 };
5853 const atom_index = switch (self.bin_file.tag) {5857 const atom_index = switch (self.bin_file.tag) {
5854 .macho => blk: {5858 .macho => blk: {
...@@ -6176,7 +6180,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {...@@ -6176,7 +6180,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
6176 .memory => |addr| .{ .memory = addr },6180 .memory => |addr| .{ .memory = addr },
6177 .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } },6181 .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } },
6178 .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },6182 .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },
6179 .load_tlv => unreachable, // TODO6183 .load_actual_got, .load_tlv => unreachable, // TODO
6180 },6184 },
6181 .fail => |msg| {6185 .fail => |msg| {
6182 self.err_msg = msg;6186 self.err_msg = msg;
src/arch/arm/CodeGen.zig+1-1
...@@ -6135,7 +6135,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {...@@ -6135,7 +6135,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
6135 .mcv => |mcv| switch (mcv) {6135 .mcv => |mcv| switch (mcv) {
6136 .none => .none,6136 .none => .none,
6137 .undef => .undef,6137 .undef => .undef,
6138 .load_got, .load_direct, .load_tlv => unreachable, // TODO6138 .load_got, .load_actual_got, .load_direct, .load_tlv => unreachable, // TODO
6139 .immediate => |imm| .{ .immediate = @as(u32, @truncate(imm)) },6139 .immediate => |imm| .{ .immediate = @as(u32, @truncate(imm)) },
6140 .memory => |addr| .{ .memory = addr },6140 .memory => |addr| .{ .memory = addr },
6141 },6141 },
src/arch/riscv64/CodeGen.zig+1-1
...@@ -2591,7 +2591,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -2591,7 +2591,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
2591 .mcv => |mcv| switch (mcv) {2591 .mcv => |mcv| switch (mcv) {
2592 .none => .none,2592 .none => .none,
2593 .undef => .undef,2593 .undef => .undef,
2594 .load_got, .load_direct, .load_tlv => unreachable, // TODO2594 .load_got, .load_actual_got, .load_direct, .load_tlv => unreachable, // TODO
2595 .immediate => |imm| .{ .immediate = imm },2595 .immediate => |imm| .{ .immediate = imm },
2596 .memory => |addr| .{ .memory = addr },2596 .memory => |addr| .{ .memory = addr },
2597 },2597 },
src/arch/sparc64/CodeGen.zig+1-1
...@@ -4137,7 +4137,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {...@@ -4137,7 +4137,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
4137 .mcv => |mcv| switch (mcv) {4137 .mcv => |mcv| switch (mcv) {
4138 .none => .none,4138 .none => .none,
4139 .undef => .undef,4139 .undef => .undef,
4140 .load_got, .load_direct, .load_tlv => unreachable, // TODO4140 .load_got, .load_actual_got, .load_direct, .load_tlv => unreachable, // TODO
4141 .immediate => |imm| .{ .immediate = imm },4141 .immediate => |imm| .{ .immediate = imm },
4142 .memory => |addr| .{ .memory = addr },4142 .memory => |addr| .{ .memory = addr },
4143 },4143 },
src/arch/x86_64/CodeGen.zig+70-17
...@@ -207,6 +207,10 @@ pub const MCValue = union(enum) {...@@ -207,6 +207,10 @@ pub const MCValue = union(enum) {
207 /// The value is a pointer to a value referenced indirectly via GOT.207 /// The value is a pointer to a value referenced indirectly via GOT.
208 /// Payload is a symbol index.208 /// Payload is a symbol index.
209 lea_got: u32,209 lea_got: u32,
210 /// TODO indirection via actual .got table
211 /// LOL Jakub, the king of naming...
212 load_actual_got: u32,
213 lea_actual_got: u32,
210 /// The value is a threadlocal variable.214 /// The value is a threadlocal variable.
211 /// Payload is a symbol index.215 /// Payload is a symbol index.
212 load_tlv: u32,216 load_tlv: u32,
...@@ -295,6 +299,7 @@ pub const MCValue = union(enum) {...@@ -295,6 +299,7 @@ pub const MCValue = union(enum) {
295 .register_overflow,299 .register_overflow,
296 .lea_direct,300 .lea_direct,
297 .lea_got,301 .lea_got,
302 .lea_actual_got,
298 .lea_tlv,303 .lea_tlv,
299 .lea_frame,304 .lea_frame,
300 .reserved_frame,305 .reserved_frame,
...@@ -308,6 +313,7 @@ pub const MCValue = union(enum) {...@@ -308,6 +313,7 @@ pub const MCValue = union(enum) {
308 .load_direct => |sym_index| .{ .lea_direct = sym_index },313 .load_direct => |sym_index| .{ .lea_direct = sym_index },
309 .load_got => |sym_index| .{ .lea_got = sym_index },314 .load_got => |sym_index| .{ .lea_got = sym_index },
310 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },315 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
316 .load_actual_got => |sym_index| .{ .lea_actual_got = sym_index },
311 .load_frame => |frame_addr| .{ .lea_frame = frame_addr },317 .load_frame => |frame_addr| .{ .lea_frame = frame_addr },
312 };318 };
313 }319 }
...@@ -325,6 +331,7 @@ pub const MCValue = union(enum) {...@@ -325,6 +331,7 @@ pub const MCValue = union(enum) {
325 .indirect,331 .indirect,
326 .load_direct,332 .load_direct,
327 .load_got,333 .load_got,
334 .load_actual_got,
328 .load_tlv,335 .load_tlv,
329 .load_frame,336 .load_frame,
330 .reserved_frame,337 .reserved_frame,
...@@ -335,6 +342,7 @@ pub const MCValue = union(enum) {...@@ -335,6 +342,7 @@ pub const MCValue = union(enum) {
335 .register_offset => |reg_off| .{ .indirect = reg_off },342 .register_offset => |reg_off| .{ .indirect = reg_off },
336 .lea_direct => |sym_index| .{ .load_direct = sym_index },343 .lea_direct => |sym_index| .{ .load_direct = sym_index },
337 .lea_got => |sym_index| .{ .load_got = sym_index },344 .lea_got => |sym_index| .{ .load_got = sym_index },
345 .lea_actual_got => |sym_index| .{ .load_actual_got = sym_index },
338 .lea_tlv => |sym_index| .{ .load_tlv = sym_index },346 .lea_tlv => |sym_index| .{ .load_tlv = sym_index },
339 .lea_frame => |frame_addr| .{ .load_frame = frame_addr },347 .lea_frame => |frame_addr| .{ .load_frame = frame_addr },
340 };348 };
...@@ -358,6 +366,8 @@ pub const MCValue = union(enum) {...@@ -358,6 +366,8 @@ pub const MCValue = union(enum) {
358 .lea_direct,366 .lea_direct,
359 .load_got,367 .load_got,
360 .lea_got,368 .lea_got,
369 .load_actual_got,
370 .lea_actual_got,
361 .load_tlv,371 .load_tlv,
362 .lea_tlv,372 .lea_tlv,
363 .load_frame,373 .load_frame,
...@@ -392,6 +402,8 @@ pub const MCValue = union(enum) {...@@ -392,6 +402,8 @@ pub const MCValue = union(enum) {
392 .lea_direct,402 .lea_direct,
393 .load_got,403 .load_got,
394 .lea_got,404 .lea_got,
405 .load_actual_got,
406 .lea_actual_got,
395 .load_tlv,407 .load_tlv,
396 .lea_tlv,408 .lea_tlv,
397 .lea_frame,409 .lea_frame,
...@@ -434,6 +446,8 @@ pub const MCValue = union(enum) {...@@ -434,6 +446,8 @@ pub const MCValue = union(enum) {
434 .lea_direct => |pl| try writer.print("direct:{d}", .{pl}),446 .lea_direct => |pl| try writer.print("direct:{d}", .{pl}),
435 .load_got => |pl| try writer.print("[got:{d}]", .{pl}),447 .load_got => |pl| try writer.print("[got:{d}]", .{pl}),
436 .lea_got => |pl| try writer.print("got:{d}", .{pl}),448 .lea_got => |pl| try writer.print("got:{d}", .{pl}),
449 .load_actual_got => |pl| try writer.print("[actual_got:{d}]", .{pl}),
450 .lea_actual_got => |pl| try writer.print("actual_got:{d}", .{pl}),
437 .load_tlv => |pl| try writer.print("[tlv:{d}]", .{pl}),451 .load_tlv => |pl| try writer.print("[tlv:{d}]", .{pl}),
438 .lea_tlv => |pl| try writer.print("tlv:{d}", .{pl}),452 .lea_tlv => |pl| try writer.print("tlv:{d}", .{pl}),
439 .load_frame => |pl| try writer.print("[{} + 0x{x}]", .{ pl.index, pl.off }),453 .load_frame => |pl| try writer.print("[{} + 0x{x}]", .{ pl.index, pl.off }),
...@@ -461,6 +475,8 @@ const InstTracking = struct {...@@ -461,6 +475,8 @@ const InstTracking = struct {
461 .lea_direct,475 .lea_direct,
462 .load_got,476 .load_got,
463 .lea_got,477 .lea_got,
478 .load_actual_got,
479 .lea_actual_got,
464 .load_tlv,480 .load_tlv,
465 .lea_tlv,481 .lea_tlv,
466 .load_frame,482 .load_frame,
...@@ -520,6 +536,8 @@ const InstTracking = struct {...@@ -520,6 +536,8 @@ const InstTracking = struct {
520 .lea_direct,536 .lea_direct,
521 .load_got,537 .load_got,
522 .lea_got,538 .lea_got,
539 .load_actual_got,
540 .lea_actual_got,
523 .load_tlv,541 .load_tlv,
524 .lea_tlv,542 .lea_tlv,
525 .load_frame,543 .load_frame,
...@@ -555,6 +573,8 @@ const InstTracking = struct {...@@ -555,6 +573,8 @@ const InstTracking = struct {
555 .lea_direct,573 .lea_direct,
556 .load_got,574 .load_got,
557 .lea_got,575 .lea_got,
576 .load_actual_got,
577 .lea_actual_got,
558 .load_tlv,578 .load_tlv,
559 .lea_tlv,579 .lea_tlv,
560 .lea_frame,580 .lea_frame,
...@@ -4371,6 +4391,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -4371,6 +4391,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
4371 .memory,4391 .memory,
4372 .load_direct,4392 .load_direct,
4373 .load_got,4393 .load_got,
4394 .load_actual_got,
4374 .load_tlv,4395 .load_tlv,
4375 => try self.genSetReg(addr_reg, Type.usize, array.address()),4396 => try self.genSetReg(addr_reg, Type.usize, array.address()),
4376 .lea_direct, .lea_tlv => unreachable,4397 .lea_direct, .lea_tlv => unreachable,
...@@ -5851,6 +5872,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro...@@ -5851,6 +5872,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro
5851 .register_offset,5872 .register_offset,
5852 .lea_direct,5873 .lea_direct,
5853 .lea_got,5874 .lea_got,
5875 .lea_actual_got,
5854 .lea_tlv,5876 .lea_tlv,
5855 .lea_frame,5877 .lea_frame,
5856 => try self.genCopy(dst_ty, dst_mcv, ptr_mcv.deref()),5878 => try self.genCopy(dst_ty, dst_mcv, ptr_mcv.deref()),
...@@ -5858,6 +5880,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro...@@ -5858,6 +5880,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro
5858 .indirect,5880 .indirect,
5859 .load_direct,5881 .load_direct,
5860 .load_got,5882 .load_got,
5883 .load_actual_got,
5861 .load_tlv,5884 .load_tlv,
5862 .load_frame,5885 .load_frame,
5863 => {5886 => {
...@@ -5996,6 +6019,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr...@@ -5996,6 +6019,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr
5996 .register_offset,6019 .register_offset,
5997 .lea_direct,6020 .lea_direct,
5998 .lea_got,6021 .lea_got,
6022 .lea_actual_got,
5999 .lea_tlv,6023 .lea_tlv,
6000 .lea_frame,6024 .lea_frame,
6001 => try self.genCopy(src_ty, ptr_mcv.deref(), src_mcv),6025 => try self.genCopy(src_ty, ptr_mcv.deref(), src_mcv),
...@@ -6003,6 +6027,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr...@@ -6003,6 +6027,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr
6003 .indirect,6027 .indirect,
6004 .load_direct,6028 .load_direct,
6005 .load_got,6029 .load_got,
6030 .load_actual_got,
6006 .load_tlv,6031 .load_tlv,
6007 .load_frame,6032 .load_frame,
6008 => {6033 => {
...@@ -6424,6 +6449,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC...@@ -6424,6 +6449,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC
6424 .register_overflow,6449 .register_overflow,
6425 .lea_direct,6450 .lea_direct,
6426 .lea_got,6451 .lea_got,
6452 .lea_actual_got,
6427 .lea_tlv,6453 .lea_tlv,
6428 .lea_frame,6454 .lea_frame,
6429 .reserved_frame,6455 .reserved_frame,
...@@ -6431,7 +6457,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC...@@ -6431,7 +6457,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC
6431 => unreachable, // unmodifiable destination6457 => unreachable, // unmodifiable destination
6432 .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)),6458 .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)),
6433 .register_pair => unreachable, // unimplemented6459 .register_pair => unreachable, // unimplemented
6434 .memory, .load_got, .load_direct, .load_tlv => {6460 .memory, .load_got, .load_actual_got, .load_direct, .load_tlv => {
6435 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);6461 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
6436 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);6462 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
6437 defer self.register_manager.unlockReg(addr_reg_lock);6463 defer self.register_manager.unlockReg(addr_reg_lock);
...@@ -7389,6 +7415,8 @@ fn genBinOp(...@@ -7389,6 +7415,8 @@ fn genBinOp(
7389 .lea_direct,7415 .lea_direct,
7390 .load_got,7416 .load_got,
7391 .lea_got,7417 .lea_got,
7418 .load_actual_got,
7419 .lea_actual_got,
7392 .load_tlv,7420 .load_tlv,
7393 .lea_tlv,7421 .lea_tlv,
7394 .lea_frame,7422 .lea_frame,
...@@ -7445,6 +7473,8 @@ fn genBinOp(...@@ -7445,6 +7473,8 @@ fn genBinOp(
7445 .lea_direct,7473 .lea_direct,
7446 .load_got,7474 .load_got,
7447 .lea_got,7475 .lea_got,
7476 .load_actual_got,
7477 .lea_actual_got,
7448 .load_tlv,7478 .load_tlv,
7449 .lea_tlv,7479 .lea_tlv,
7450 .lea_frame,7480 .lea_frame,
...@@ -8397,6 +8427,7 @@ fn genBinOpMir(...@@ -8397,6 +8427,7 @@ fn genBinOpMir(
8397 .register_overflow,8427 .register_overflow,
8398 .lea_direct,8428 .lea_direct,
8399 .lea_got,8429 .lea_got,
8430 .lea_actual_got,
8400 .lea_tlv,8431 .lea_tlv,
8401 .lea_frame,8432 .lea_frame,
8402 .reserved_frame,8433 .reserved_frame,
...@@ -8485,6 +8516,8 @@ fn genBinOpMir(...@@ -8485,6 +8516,8 @@ fn genBinOpMir(
8485 .lea_direct,8516 .lea_direct,
8486 .load_got,8517 .load_got,
8487 .lea_got,8518 .lea_got,
8519 .load_actual_got,
8520 .lea_actual_got,
8488 .load_tlv,8521 .load_tlv,
8489 .lea_tlv,8522 .lea_tlv,
8490 .load_frame,8523 .load_frame,
...@@ -8517,6 +8550,7 @@ fn genBinOpMir(...@@ -8517,6 +8550,7 @@ fn genBinOpMir(
8517 .register_offset,8550 .register_offset,
8518 .lea_direct,8551 .lea_direct,
8519 .lea_got,8552 .lea_got,
8553 .lea_actual_got,
8520 .lea_tlv,8554 .lea_tlv,
8521 .lea_frame,8555 .lea_frame,
8522 => {8556 => {
...@@ -8532,6 +8566,7 @@ fn genBinOpMir(...@@ -8532,6 +8566,7 @@ fn genBinOpMir(
8532 .memory,8566 .memory,
8533 .load_direct,8567 .load_direct,
8534 .load_got,8568 .load_got,
8569 .load_actual_got,
8535 .load_tlv,8570 .load_tlv,
8536 => {8571 => {
8537 const ptr_ty = try mod.singleConstPtrType(ty);8572 const ptr_ty = try mod.singleConstPtrType(ty);
...@@ -8552,13 +8587,13 @@ fn genBinOpMir(...@@ -8552,13 +8587,13 @@ fn genBinOpMir(
8552 }8587 }
8553 }8588 }
8554 },8589 },
8555 .memory, .indirect, .load_got, .load_direct, .load_tlv, .load_frame => {8590 .memory, .indirect, .load_got, .load_actual_got, .load_direct, .load_tlv, .load_frame => {
8556 const OpInfo = ?struct { addr_reg: Register, addr_lock: RegisterLock };8591 const OpInfo = ?struct { addr_reg: Register, addr_lock: RegisterLock };
8557 const limb_abi_size: u32 = @min(abi_size, 8);8592 const limb_abi_size: u32 = @min(abi_size, 8);
85588593
8559 const dst_info: OpInfo = switch (dst_mcv) {8594 const dst_info: OpInfo = switch (dst_mcv) {
8560 else => unreachable,8595 else => unreachable,
8561 .memory, .load_got, .load_direct, .load_tlv => dst: {8596 .memory, .load_got, .load_actual_got, .load_direct, .load_tlv => dst: {
8562 const dst_addr_reg =8597 const dst_addr_reg =
8563 (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64();8598 (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64();
8564 const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg);8599 const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg);
...@@ -8592,16 +8627,17 @@ fn genBinOpMir(...@@ -8592,16 +8627,17 @@ fn genBinOpMir(
8592 .indirect,8627 .indirect,
8593 .lea_direct,8628 .lea_direct,
8594 .lea_got,8629 .lea_got,
8630 .lea_actual_got,
8595 .lea_tlv,8631 .lea_tlv,
8596 .load_frame,8632 .load_frame,
8597 .lea_frame,8633 .lea_frame,
8598 => null,8634 => null,
8599 .memory, .load_got, .load_direct, .load_tlv => src: {8635 .memory, .load_got, .load_actual_got, .load_direct, .load_tlv => src: {
8600 switch (resolved_src_mcv) {8636 switch (resolved_src_mcv) {
8601 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr))) != null and8637 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr))) != null and
8602 math.cast(i32, @as(i64, @bitCast(addr)) + abi_size - limb_abi_size) != null)8638 math.cast(i32, @as(i64, @bitCast(addr)) + abi_size - limb_abi_size) != null)
8603 break :src null,8639 break :src null,
8604 .load_got, .load_direct, .load_tlv => {},8640 .load_got, .load_actual_got, .load_direct, .load_tlv => {},
8605 else => unreachable,8641 else => unreachable,
8606 }8642 }
86078643
...@@ -8644,6 +8680,7 @@ fn genBinOpMir(...@@ -8644,6 +8680,7 @@ fn genBinOpMir(
8644 switch (dst_mcv) {8680 switch (dst_mcv) {
8645 .memory,8681 .memory,
8646 .load_got,8682 .load_got,
8683 .load_actual_got,
8647 .load_direct,8684 .load_direct,
8648 .load_tlv,8685 .load_tlv,
8649 => .{ .base = .{ .reg = dst_info.?.addr_reg }, .disp = off },8686 => .{ .base = .{ .reg = dst_info.?.addr_reg }, .disp = off },
...@@ -8728,6 +8765,8 @@ fn genBinOpMir(...@@ -8728,6 +8765,8 @@ fn genBinOpMir(
8728 .lea_direct,8765 .lea_direct,
8729 .load_got,8766 .load_got,
8730 .lea_got,8767 .lea_got,
8768 .load_actual_got,
8769 .lea_actual_got,
8731 .load_tlv,8770 .load_tlv,
8732 .lea_tlv,8771 .lea_tlv,
8733 .load_frame,8772 .load_frame,
...@@ -8743,6 +8782,7 @@ fn genBinOpMir(...@@ -8743,6 +8782,7 @@ fn genBinOpMir(
8743 .register_offset,8782 .register_offset,
8744 .lea_direct,8783 .lea_direct,
8745 .lea_got,8784 .lea_got,
8785 .lea_actual_got,
8746 .lea_tlv,8786 .lea_tlv,
8747 .lea_frame,8787 .lea_frame,
8748 => switch (limb_i) {8788 => switch (limb_i) {
...@@ -8792,6 +8832,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M...@@ -8792,6 +8832,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
8792 .register_overflow,8832 .register_overflow,
8793 .lea_direct,8833 .lea_direct,
8794 .lea_got,8834 .lea_got,
8835 .lea_actual_got,
8795 .lea_tlv,8836 .lea_tlv,
8796 .lea_frame,8837 .lea_frame,
8797 .reserved_frame,8838 .reserved_frame,
...@@ -8840,6 +8881,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M...@@ -8840,6 +8881,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
8840 .lea_direct,8881 .lea_direct,
8841 .load_got,8882 .load_got,
8842 .lea_got,8883 .lea_got,
8884 .load_actual_got,
8885 .lea_actual_got,
8843 .load_tlv,8886 .load_tlv,
8844 .lea_tlv,8887 .lea_tlv,
8845 .lea_frame,8888 .lea_frame,
...@@ -8878,7 +8921,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M...@@ -8878,7 +8921,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
8878 }8921 }
8879 },8922 },
8880 .register_pair => unreachable, // unimplemented8923 .register_pair => unreachable, // unimplemented
8881 .memory, .indirect, .load_direct, .load_got, .load_tlv, .load_frame => {8924 .memory, .indirect, .load_direct, .load_got, .load_actual_got, .load_tlv, .load_frame => {
8882 const tmp_reg = try self.copyToTmpRegister(dst_ty, dst_mcv);8925 const tmp_reg = try self.copyToTmpRegister(dst_ty, dst_mcv);
8883 const tmp_mcv = MCValue{ .register = tmp_reg };8926 const tmp_mcv = MCValue{ .register = tmp_reg };
8884 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);8927 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
...@@ -8971,6 +9014,7 @@ fn genVarDbgInfo(...@@ -8971,6 +9014,7 @@ fn genVarDbgInfo(
8971 //} },9014 //} },
8972 .memory => |address| .{ .memory = address },9015 .memory => |address| .{ .memory = address },
8973 .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } },9016 .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } },
9017 .load_actual_got => |sym_index| .{ .linker_load = .{ .type = .actual_got, .sym_index = sym_index } },
8974 .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },9018 .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },
8975 .immediate => |x| .{ .immediate = x },9019 .immediate => |x| .{ .immediate = x },
8976 .undef => .undef,9020 .undef => .undef,
...@@ -9410,13 +9454,14 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -9410,13 +9454,14 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
9410 .indirect,9454 .indirect,
9411 .lea_direct,9455 .lea_direct,
9412 .lea_got,9456 .lea_got,
9457 .lea_actual_got,
9413 .lea_tlv,9458 .lea_tlv,
9414 .lea_frame,9459 .lea_frame,
9415 .reserved_frame,9460 .reserved_frame,
9416 .air_ref,9461 .air_ref,
9417 => unreachable,9462 => unreachable,
9418 .register_pair, .load_frame => null,9463 .register_pair, .load_frame => null,
9419 .memory, .load_got, .load_direct, .load_tlv => dst: {9464 .memory, .load_got, .load_actual_got, .load_direct, .load_tlv => dst: {
9420 switch (resolved_dst_mcv) {9465 switch (resolved_dst_mcv) {
9421 .memory => |addr| if (math.cast(9466 .memory => |addr| if (math.cast(
9422 i32,9467 i32,
...@@ -9425,7 +9470,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -9425,7 +9470,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
9425 i32,9470 i32,
9426 @as(i64, @bitCast(addr)) + abi_size - 8,9471 @as(i64, @bitCast(addr)) + abi_size - 8,
9427 ) != null) break :dst null,9472 ) != null) break :dst null,
9428 .load_got, .load_direct, .load_tlv => {},9473 .load_got, .load_actual_got, .load_direct, .load_tlv => {},
9429 else => unreachable,9474 else => unreachable,
9430 }9475 }
94319476
...@@ -9468,13 +9513,14 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -9468,13 +9513,14 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
9468 .indirect,9513 .indirect,
9469 .lea_direct,9514 .lea_direct,
9470 .lea_got,9515 .lea_got,
9516 .lea_actual_got,
9471 .lea_tlv,9517 .lea_tlv,
9472 .lea_frame,9518 .lea_frame,
9473 .reserved_frame,9519 .reserved_frame,
9474 .air_ref,9520 .air_ref,
9475 => unreachable,9521 => unreachable,
9476 .register_pair, .load_frame => null,9522 .register_pair, .load_frame => null,
9477 .memory, .load_got, .load_direct, .load_tlv => src: {9523 .memory, .load_got, .load_actual_got, .load_direct, .load_tlv => src: {
9478 switch (resolved_src_mcv) {9524 switch (resolved_src_mcv) {
9479 .memory => |addr| if (math.cast(9525 .memory => |addr| if (math.cast(
9480 i32,9526 i32,
...@@ -9483,7 +9529,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -9483,7 +9529,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
9483 i32,9529 i32,
9484 @as(i64, @bitCast(addr)) + abi_size - 8,9530 @as(i64, @bitCast(addr)) + abi_size - 8,
9485 ) != null) break :src null,9531 ) != null) break :src null,
9486 .load_got, .load_direct, .load_tlv => {},9532 .load_got, .load_actual_got, .load_direct, .load_tlv => {},
9487 else => unreachable,9533 else => unreachable,
9488 }9534 }
94899535
...@@ -9902,6 +9948,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -9902,6 +9948,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
9902 .register_overflow,9948 .register_overflow,
9903 .lea_direct,9949 .lea_direct,
9904 .lea_got,9950 .lea_got,
9951 .lea_actual_got,
9905 .lea_tlv,9952 .lea_tlv,
9906 .lea_frame,9953 .lea_frame,
9907 .reserved_frame,9954 .reserved_frame,
...@@ -9928,6 +9975,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -9928,6 +9975,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
99289975
9929 .memory,9976 .memory,
9930 .load_got,9977 .load_got,
9978 .load_actual_got,
9931 .load_direct,9979 .load_direct,
9932 .load_tlv,9980 .load_tlv,
9933 => {9981 => {
...@@ -10485,7 +10533,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -10485,7 +10533,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
10485 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |_|10533 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |_|
10486 break :arg input_mcv,10534 break :arg input_mcv,
10487 .indirect, .load_frame => break :arg input_mcv,10535 .indirect, .load_frame => break :arg input_mcv,
10488 .load_direct, .load_got, .load_tlv => {},10536 .load_direct, .load_got, .load_actual_got, .load_tlv => {},
10489 else => {10537 else => {
10490 const temp_mcv = try self.allocTempRegOrMem(ty, false);10538 const temp_mcv = try self.allocTempRegOrMem(ty, false);
10491 try self.genCopy(ty, temp_mcv, input_mcv);10539 try self.genCopy(ty, temp_mcv, input_mcv);
...@@ -11146,6 +11194,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError...@@ -11146,6 +11194,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError
11146 .register_overflow,11194 .register_overflow,
11147 .lea_direct,11195 .lea_direct,
11148 .lea_got,11196 .lea_got,
11197 .lea_actual_got,
11149 .lea_tlv,11198 .lea_tlv,
11150 .lea_frame,11199 .lea_frame,
11151 .reserved_frame,11200 .reserved_frame,
...@@ -11197,11 +11246,11 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError...@@ -11197,11 +11246,11 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError
11197 }11246 }
11198 },11247 },
11199 .indirect => |reg_off| try self.genSetMem(.{ .reg = reg_off.reg }, reg_off.off, ty, src_mcv),11248 .indirect => |reg_off| try self.genSetMem(.{ .reg = reg_off.reg }, reg_off.off, ty, src_mcv),
11200 .memory, .load_direct, .load_got, .load_tlv => {11249 .memory, .load_direct, .load_got, .load_actual_got, .load_tlv => {
11201 switch (dst_mcv) {11250 switch (dst_mcv) {
11202 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|11251 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|
11203 return self.genSetMem(.{ .reg = .ds }, small_addr, ty, src_mcv),11252 return self.genSetMem(.{ .reg = .ds }, small_addr, ty, src_mcv),
11204 .load_direct, .load_got, .load_tlv => {},11253 .load_direct, .load_got, .load_actual_got, .load_tlv => {},
11205 else => unreachable,11254 else => unreachable,
11206 }11255 }
1120711256
...@@ -11363,7 +11412,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -11363,7 +11412,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
11363 else => unreachable,11412 else => unreachable,
11364 },11413 },
11365 )),11414 )),
11366 .memory, .load_direct, .load_got, .load_tlv => {11415 .memory, .load_direct, .load_got, .load_actual_got, .load_tlv => {
11367 switch (src_mcv) {11416 switch (src_mcv) {
11368 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|11417 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|
11369 return (try self.moveStrategy(11418 return (try self.moveStrategy(
...@@ -11391,7 +11440,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -11391,7 +11440,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
11391 },11440 },
11392 .Float, .Vector => {},11441 .Float, .Vector => {},
11393 },11442 },
11394 .load_got, .load_tlv => {},11443 .load_got, .load_actual_got, .load_tlv => {},
11395 else => unreachable,11444 else => unreachable,
11396 }11445 }
1139711446
...@@ -11405,17 +11454,18 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -11405,17 +11454,18 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
11405 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .{ .reg = addr_reg } }),11454 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .{ .reg = addr_reg } }),
11406 );11455 );
11407 },11456 },
11408 .lea_direct, .lea_got => |sym_index| {11457 .lea_direct, .lea_got, .lea_actual_got => |sym_index| {
11409 const atom_index = try self.owner.getSymbolIndex(self);11458 const atom_index = try self.owner.getSymbolIndex(self);
11410 _ = try self.addInst(.{11459 _ = try self.addInst(.{
11411 .tag = switch (src_mcv) {11460 .tag = switch (src_mcv) {
11412 .lea_direct => .lea,11461 .lea_direct => .lea,
11413 .lea_got => .mov,11462 .lea_got, .lea_actual_got => .mov,
11414 else => unreachable,11463 else => unreachable,
11415 },11464 },
11416 .ops = switch (src_mcv) {11465 .ops = switch (src_mcv) {
11417 .lea_direct => .direct_reloc,11466 .lea_direct => .direct_reloc,
11418 .lea_got => .got_reloc,11467 .lea_got => .got_reloc,
11468 .lea_actual_got => .actual_got_reloc,
11419 else => unreachable,11469 else => unreachable,
11420 },11470 },
11421 .data = .{ .rx = .{11471 .data = .{ .rx = .{
...@@ -11551,6 +11601,8 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal...@@ -11551,6 +11601,8 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
11551 .lea_direct,11601 .lea_direct,
11552 .load_got,11602 .load_got,
11553 .lea_got,11603 .lea_got,
11604 .load_actual_got,
11605 .lea_actual_got,
11554 .load_tlv,11606 .load_tlv,
11555 .lea_tlv,11607 .lea_tlv,
11556 .load_frame,11608 .load_frame,
...@@ -13556,6 +13608,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {...@@ -13556,6 +13608,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
13556 .memory => |addr| .{ .memory = addr },13608 .memory => |addr| .{ .memory = addr },
13557 .load_direct => |sym_index| .{ .load_direct = sym_index },13609 .load_direct => |sym_index| .{ .load_direct = sym_index },
13558 .load_got => |sym_index| .{ .lea_got = sym_index },13610 .load_got => |sym_index| .{ .lea_got = sym_index },
13611 .load_actual_got => |sym_index| .{ .lea_actual_got = sym_index },
13559 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },13612 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
13560 },13613 },
13561 .fail => |msg| {13614 .fail => |msg| {
src/arch/x86_64/Emit.zig+3-1
...@@ -79,6 +79,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -79,6 +79,7 @@ pub fn emitMir(emit: *Emit) Error!void {
79 @tagName(emit.bin_file.tag),79 @tagName(emit.bin_file.tag),
80 }),80 }),
81 .linker_got,81 .linker_got,
82 .linker_actual_got,
82 .linker_direct,83 .linker_direct,
83 .linker_direct_got,84 .linker_direct_got,
84 .linker_import,85 .linker_import,
...@@ -87,12 +88,13 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -87,12 +88,13 @@ pub fn emitMir(emit: *Emit) Error!void {
87 const r_type: u32 = switch (lowered_relocs[0].target) {88 const r_type: u32 = switch (lowered_relocs[0].target) {
88 .linker_direct_got => link.File.Elf.R_X86_64_ZIG_GOT32,89 .linker_direct_got => link.File.Elf.R_X86_64_ZIG_GOT32,
89 .linker_got => link.File.Elf.R_X86_64_ZIG_GOTPCREL,90 .linker_got => link.File.Elf.R_X86_64_ZIG_GOTPCREL,
91 .linker_actual_got => std.elf.R_X86_64_GOTPCREL,
90 .linker_direct => std.elf.R_X86_64_PC32,92 .linker_direct => std.elf.R_X86_64_PC32,
91 else => unreachable,93 else => unreachable,
92 };94 };
93 const r_addend: i64 = switch (lowered_relocs[0].target) {95 const r_addend: i64 = switch (lowered_relocs[0].target) {
94 .linker_direct_got => 0,96 .linker_direct_got => 0,
95 .linker_got, .linker_direct => -4,97 .linker_got, .linker_actual_got, .linker_direct => -4,
96 else => unreachable,98 else => unreachable,
97 };99 };
98 const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;100 const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;
src/arch/x86_64/Lower.zig+4-2
...@@ -51,6 +51,7 @@ pub const Reloc = struct {...@@ -51,6 +51,7 @@ pub const Reloc = struct {
51 inst: Mir.Inst.Index,51 inst: Mir.Inst.Index,
52 linker_extern_fn: Mir.Reloc,52 linker_extern_fn: Mir.Reloc,
53 linker_got: Mir.Reloc,53 linker_got: Mir.Reloc,
54 linker_actual_got: Mir.Reloc,
54 linker_direct: Mir.Reloc,55 linker_direct: Mir.Reloc,
55 linker_direct_got: Mir.Reloc,56 linker_direct_got: Mir.Reloc,
56 linker_import: Mir.Reloc,57 linker_import: Mir.Reloc,
...@@ -388,7 +389,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {...@@ -388,7 +389,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
388 .rrmi_sib, .rrmi_rip => inst.data.rrix.fixes,389 .rrmi_sib, .rrmi_rip => inst.data.rrix.fixes,
389 .mi_sib_u, .mi_rip_u, .mi_sib_s, .mi_rip_s => inst.data.x.fixes,390 .mi_sib_u, .mi_rip_u, .mi_sib_s, .mi_rip_s => inst.data.x.fixes,
390 .m_sib, .m_rip, .rax_moffs, .moffs_rax => inst.data.x.fixes,391 .m_sib, .m_rip, .rax_moffs, .moffs_rax => inst.data.x.fixes,
391 .extern_fn_reloc, .got_reloc, .direct_reloc, .direct_got_reloc, .import_reloc, .tlv_reloc => ._,392 .extern_fn_reloc, .got_reloc, .actual_got_reloc, .direct_reloc, .direct_got_reloc, .import_reloc, .tlv_reloc => ._,
392 else => return lower.fail("TODO lower .{s}", .{@tagName(inst.ops)}),393 else => return lower.fail("TODO lower .{s}", .{@tagName(inst.ops)}),
393 };394 };
394 try lower.emit(switch (fixes) {395 try lower.emit(switch (fixes) {
...@@ -532,11 +533,12 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {...@@ -532,11 +533,12 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
532 else => unreachable,533 else => unreachable,
533 }534 }
534 },535 },
535 .got_reloc, .direct_reloc, .import_reloc, .tlv_reloc => ops: {536 .got_reloc, .actual_got_reloc, .direct_reloc, .import_reloc, .tlv_reloc => ops: {
536 const reg = inst.data.rx.r1;537 const reg = inst.data.rx.r1;
537 const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;538 const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;
538 _ = lower.reloc(switch (inst.ops) {539 _ = lower.reloc(switch (inst.ops) {
539 .got_reloc => .{ .linker_got = extra },540 .got_reloc => .{ .linker_got = extra },
541 .actual_got_reloc => .{ .linker_actual_got = extra },
540 .direct_reloc => .{ .linker_direct = extra },542 .direct_reloc => .{ .linker_direct = extra },
541 .import_reloc => .{ .linker_import = extra },543 .import_reloc => .{ .linker_import = extra },
542 .tlv_reloc => .{ .linker_tlv = extra },544 .tlv_reloc => .{ .linker_tlv = extra },
src/arch/x86_64/Mir.zig+2
...@@ -783,6 +783,8 @@ pub const Inst = struct {...@@ -783,6 +783,8 @@ pub const Inst = struct {
783 /// Linker relocation - GOT indirection.783 /// Linker relocation - GOT indirection.
784 /// Uses `rx` payload with extra data of type `Reloc`.784 /// Uses `rx` payload with extra data of type `Reloc`.
785 got_reloc,785 got_reloc,
786 /// TODO
787 actual_got_reloc,
786 /// Linker relocation - direct reference.788 /// Linker relocation - direct reference.
787 /// Uses `rx` payload with extra data of type `Reloc`.789 /// Uses `rx` payload with extra data of type `Reloc`.
788 direct_reloc,790 direct_reloc,
src/codegen.zig+10
...@@ -798,6 +798,7 @@ fn lowerDeclRef(...@@ -798,6 +798,7 @@ fn lowerDeclRef(
798pub const LinkerLoad = struct {798pub const LinkerLoad = struct {
799 type: enum {799 type: enum {
800 got,800 got,
801 actual_got,
801 direct,802 direct,
802 import,803 import,
803 },804 },
...@@ -827,6 +828,8 @@ pub const GenResult = union(enum) {...@@ -827,6 +828,8 @@ pub const GenResult = union(enum) {
827 load_got: u32,828 load_got: u32,
828 /// Direct by-address reference to memory location.829 /// Direct by-address reference to memory location.
829 memory: u64,830 memory: u64,
831 /// TODO LOL Jakub, the king of naming...
832 load_actual_got: u32,
830 };833 };
831834
832 fn mcv(val: MCValue) GenResult {835 fn mcv(val: MCValue) GenResult {
...@@ -885,8 +888,15 @@ fn genDeclRef(...@@ -885,8 +888,15 @@ fn genDeclRef(
885 try mod.markDeclAlive(decl);888 try mod.markDeclAlive(decl);
886889
887 const is_threadlocal = tv.val.isPtrToThreadLocal(mod) and !bin_file.options.single_threaded;890 const is_threadlocal = tv.val.isPtrToThreadLocal(mod) and !bin_file.options.single_threaded;
891 const is_extern = decl.isExtern(mod);
888892
889 if (bin_file.cast(link.File.Elf)) |elf_file| {893 if (bin_file.cast(link.File.Elf)) |elf_file| {
894 if (is_extern) {
895 const variable = decl.getOwnedVariable(mod).?;
896 const name = mod.intern_pool.stringToSlice(decl.name);
897 const lib_name = mod.intern_pool.stringToSliceUnwrap(variable.lib_name);
898 return GenResult.mcv(.{ .load_actual_got = try elf_file.getGlobalSymbol(name, lib_name) });
899 }
890 const sym_index = try elf_file.getOrCreateMetadataForDecl(decl_index);900 const sym_index = try elf_file.getOrCreateMetadataForDecl(decl_index);
891 const sym = elf_file.symbol(sym_index);901 const sym = elf_file.symbol(sym_index);
892 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);902 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
src/link/Dwarf.zig+1
...@@ -1389,6 +1389,7 @@ pub fn commitDeclState(...@@ -1389,6 +1389,7 @@ pub fn commitDeclState(
1389 .prev_vaddr = 0,1389 .prev_vaddr = 0,
1390 });1390 });
1391 },1391 },
1392 .elf => {}, // TODO
1392 else => unreachable,1393 else => unreachable,
1393 }1394 }
1394 }1395 }
src/link/Elf.zig+9-5
...@@ -3196,12 +3196,16 @@ pub fn updateDecl(...@@ -3196,12 +3196,16 @@ pub fn updateDecl(
3196 const decl = mod.declPtr(decl_index);3196 const decl = mod.declPtr(decl_index);
31973197
3198 if (decl.val.getExternFunc(mod)) |_| {3198 if (decl.val.getExternFunc(mod)) |_| {
3199 return; // TODO Should we do more when front-end analyzed extern decl?3199 return;
3200 }3200 }
3201 if (decl.val.getVariable(mod)) |variable| {3201
3202 if (variable.is_extern) {3202 if (decl.isExtern(mod)) {
3203 return; // TODO Should we do more when front-end analyzed extern decl?3203 // Extern variable gets a .got entry only.
3204 }3204 const variable = decl.getOwnedVariable(mod).?;
3205 const name = mod.intern_pool.stringToSlice(decl.name);
3206 const lib_name = mod.intern_pool.stringToSliceUnwrap(variable.lib_name);
3207 _ = try self.getGlobalSymbol(name, lib_name);
3208 return;
3205 }3209 }
32063210
3207 const sym_index = try self.getOrCreateMetadataForDecl(decl_index);3211 const sym_index = try self.getOrCreateMetadataForDecl(decl_index);