authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-25 16:49:56+02:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-10-28 03:48:18-04:00
loga6a10d9c2b096e1c5cb7bf29273d64e7285b5f94
tree539fa70985d2508cedd002ea468b3f77eff874c6
parenta440cf6d4454d3febfe07b6235745120d104cfa0

x86_64: do not hardcode memory passed by Elf linker


11 files changed, 221 insertions(+), 171 deletions(-)

src/arch/aarch64/CodeGen.zig+1-5
...@@ -4012,7 +4012,6 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type...@@ -4012,7 +4012,6 @@ 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 .extern_got => unreachable,
4016 };4015 };
4017 const atom_index = switch (self.bin_file.tag) {4016 const atom_index = switch (self.bin_file.tag) {
4018 .macho => blk: {4017 .macho => blk: {
...@@ -5532,7 +5531,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro...@@ -5532,7 +5531,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
5532 .got => .load_memory_ptr_got,5531 .got => .load_memory_ptr_got,
5533 .direct => .load_memory_ptr_direct,5532 .direct => .load_memory_ptr_direct,
5534 .import => unreachable,5533 .import => unreachable,
5535 .extern_got => unreachable,
5536 };5534 };
5537 const atom_index = switch (self.bin_file.tag) {5535 const atom_index = switch (self.bin_file.tag) {
5538 .macho => blk: {5536 .macho => blk: {
...@@ -5654,7 +5652,6 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -5654,7 +5652,6 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
5654 .got => .load_memory_got,5652 .got => .load_memory_got,
5655 .direct => .load_memory_direct,5653 .direct => .load_memory_direct,
5656 .import => .load_memory_import,5654 .import => .load_memory_import,
5657 .extern_got => unreachable,
5658 };5655 };
5659 const atom_index = switch (self.bin_file.tag) {5656 const atom_index = switch (self.bin_file.tag) {
5660 .macho => blk: {5657 .macho => blk: {
...@@ -5852,7 +5849,6 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I...@@ -5852,7 +5849,6 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
5852 .got => .load_memory_ptr_got,5849 .got => .load_memory_ptr_got,
5853 .direct => .load_memory_ptr_direct,5850 .direct => .load_memory_ptr_direct,
5854 .import => unreachable,5851 .import => unreachable,
5855 .extern_got => unreachable,
5856 };5852 };
5857 const atom_index = switch (self.bin_file.tag) {5853 const atom_index = switch (self.bin_file.tag) {
5858 .macho => blk: {5854 .macho => blk: {
...@@ -6180,7 +6176,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {...@@ -6180,7 +6176,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
6180 .memory => |addr| .{ .memory = addr },6176 .memory => |addr| .{ .memory = addr },
6181 .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } },6177 .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } },
6182 .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },6178 .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },
6183 .load_extern_got, .load_tlv => unreachable, // TODO6179 .load_memory, .lea_memory, .load_tlv => unreachable, // TODO
6184 },6180 },
6185 .fail => |msg| {6181 .fail => |msg| {
6186 self.err_msg = msg;6182 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_extern_got, .load_direct, .load_tlv => unreachable, // TODO6138 .load_got, .load_memory, .lea_memory, .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_extern_got, .load_direct, .load_tlv => unreachable, // TODO2594 .load_got, .load_memory, .lea_memory, .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_extern_got, .load_direct, .load_tlv => unreachable, // TODO4140 .load_got, .load_memory, .lea_memory, .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+124-97
...@@ -193,6 +193,11 @@ pub const MCValue = union(enum) {...@@ -193,6 +193,11 @@ pub const MCValue = union(enum) {
193 /// The value is in memory at a hard-coded address.193 /// The value is in memory at a hard-coded address.
194 /// If the type is a pointer, it means the pointer address is stored at this memory location.194 /// If the type is a pointer, it means the pointer address is stored at this memory location.
195 memory: u64,195 memory: u64,
196 /// The value is in memory at an address not-yet-allocated by the linker.
197 /// This traditionally corresponds to a relocation emitted in a relocatable object file.
198 load_memory: u32,
199 /// The address of the memory location not-yet-allocated by the linker.
200 lea_memory: u32,
196 /// The value is in memory at a constant offset from the address in a register.201 /// The value is in memory at a constant offset from the address in a register.
197 indirect: RegisterOffset,202 indirect: RegisterOffset,
198 /// The value is in memory.203 /// The value is in memory.
...@@ -207,12 +212,6 @@ pub const MCValue = union(enum) {...@@ -207,12 +212,6 @@ pub const MCValue = union(enum) {
207 /// The value is a pointer to a value referenced indirectly via GOT.212 /// The value is a pointer to a value referenced indirectly via GOT.
208 /// Payload is a symbol index.213 /// Payload is a symbol index.
209 lea_got: u32,214 lea_got: u32,
210 /// The value is an extern variable referenced via GOT.
211 /// Payload is a symbol index.
212 load_extern_got: u32,
213 /// The value is a pointer to an extern variable referenced via GOT.
214 /// Payload is a symbol index.
215 lea_extern_got: u32,
216 /// The value is a threadlocal variable.215 /// The value is a threadlocal variable.
217 /// Payload is a symbol index.216 /// Payload is a symbol index.
218 load_tlv: u32,217 load_tlv: u32,
...@@ -299,9 +298,9 @@ pub const MCValue = union(enum) {...@@ -299,9 +298,9 @@ pub const MCValue = union(enum) {
299 .register_pair,298 .register_pair,
300 .register_offset,299 .register_offset,
301 .register_overflow,300 .register_overflow,
301 .lea_memory,
302 .lea_direct,302 .lea_direct,
303 .lea_got,303 .lea_got,
304 .lea_extern_got,
305 .lea_tlv,304 .lea_tlv,
306 .lea_frame,305 .lea_frame,
307 .reserved_frame,306 .reserved_frame,
...@@ -315,8 +314,8 @@ pub const MCValue = union(enum) {...@@ -315,8 +314,8 @@ pub const MCValue = union(enum) {
315 .load_direct => |sym_index| .{ .lea_direct = sym_index },314 .load_direct => |sym_index| .{ .lea_direct = sym_index },
316 .load_got => |sym_index| .{ .lea_got = sym_index },315 .load_got => |sym_index| .{ .lea_got = sym_index },
317 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },316 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
318 .load_extern_got => |sym_index| .{ .lea_extern_got = sym_index },
319 .load_frame => |frame_addr| .{ .lea_frame = frame_addr },317 .load_frame => |frame_addr| .{ .lea_frame = frame_addr },
318 .load_memory => |sym_index| .{ .lea_memory = sym_index },
320 };319 };
321 }320 }
322321
...@@ -333,9 +332,9 @@ pub const MCValue = union(enum) {...@@ -333,9 +332,9 @@ pub const MCValue = union(enum) {
333 .indirect,332 .indirect,
334 .load_direct,333 .load_direct,
335 .load_got,334 .load_got,
336 .load_extern_got,
337 .load_tlv,335 .load_tlv,
338 .load_frame,336 .load_frame,
337 .load_memory,
339 .reserved_frame,338 .reserved_frame,
340 .air_ref,339 .air_ref,
341 => unreachable, // not dereferenceable340 => unreachable, // not dereferenceable
...@@ -344,9 +343,9 @@ pub const MCValue = union(enum) {...@@ -344,9 +343,9 @@ pub const MCValue = union(enum) {
344 .register_offset => |reg_off| .{ .indirect = reg_off },343 .register_offset => |reg_off| .{ .indirect = reg_off },
345 .lea_direct => |sym_index| .{ .load_direct = sym_index },344 .lea_direct => |sym_index| .{ .load_direct = sym_index },
346 .lea_got => |sym_index| .{ .load_got = sym_index },345 .lea_got => |sym_index| .{ .load_got = sym_index },
347 .lea_extern_got => |sym_index| .{ .load_extern_got = sym_index },
348 .lea_tlv => |sym_index| .{ .load_tlv = sym_index },346 .lea_tlv => |sym_index| .{ .load_tlv = sym_index },
349 .lea_frame => |frame_addr| .{ .load_frame = frame_addr },347 .lea_frame => |frame_addr| .{ .load_frame = frame_addr },
348 .lea_memory => |sym_index| .{ .load_memory = sym_index },
350 };349 };
351 }350 }
352351
...@@ -368,11 +367,11 @@ pub const MCValue = union(enum) {...@@ -368,11 +367,11 @@ pub const MCValue = union(enum) {
368 .lea_direct,367 .lea_direct,
369 .load_got,368 .load_got,
370 .lea_got,369 .lea_got,
371 .load_extern_got,
372 .lea_extern_got,
373 .load_tlv,370 .load_tlv,
374 .lea_tlv,371 .lea_tlv,
375 .load_frame,372 .load_frame,
373 .load_memory,
374 .lea_memory,
376 => switch (off) {375 => switch (off) {
377 0 => mcv,376 0 => mcv,
378 else => unreachable, // not offsettable377 else => unreachable, // not offsettable
...@@ -404,13 +403,13 @@ pub const MCValue = union(enum) {...@@ -404,13 +403,13 @@ pub const MCValue = union(enum) {
404 .lea_direct,403 .lea_direct,
405 .load_got,404 .load_got,
406 .lea_got,405 .lea_got,
407 .load_extern_got,
408 .lea_extern_got,
409 .load_tlv,406 .load_tlv,
410 .lea_tlv,407 .lea_tlv,
411 .lea_frame,408 .lea_frame,
412 .reserved_frame,409 .reserved_frame,
413 .air_ref,410 .air_ref,
411 .load_memory,
412 .lea_memory,
414 => unreachable,413 => unreachable,
415 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|414 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|
416 Memory.sib(ptr_size, .{ .base = .{ .reg = .ds }, .disp = small_addr })415 Memory.sib(ptr_size, .{ .base = .{ .reg = .ds }, .disp = small_addr })
...@@ -448,14 +447,14 @@ pub const MCValue = union(enum) {...@@ -448,14 +447,14 @@ pub const MCValue = union(enum) {
448 .lea_direct => |pl| try writer.print("direct:{d}", .{pl}),447 .lea_direct => |pl| try writer.print("direct:{d}", .{pl}),
449 .load_got => |pl| try writer.print("[got:{d}]", .{pl}),448 .load_got => |pl| try writer.print("[got:{d}]", .{pl}),
450 .lea_got => |pl| try writer.print("got:{d}", .{pl}),449 .lea_got => |pl| try writer.print("got:{d}", .{pl}),
451 .load_extern_got => |pl| try writer.print("[extern_got:{d}]", .{pl}),
452 .lea_extern_got => |pl| try writer.print("extern_got:{d}", .{pl}),
453 .load_tlv => |pl| try writer.print("[tlv:{d}]", .{pl}),450 .load_tlv => |pl| try writer.print("[tlv:{d}]", .{pl}),
454 .lea_tlv => |pl| try writer.print("tlv:{d}", .{pl}),451 .lea_tlv => |pl| try writer.print("tlv:{d}", .{pl}),
455 .load_frame => |pl| try writer.print("[{} + 0x{x}]", .{ pl.index, pl.off }),452 .load_frame => |pl| try writer.print("[{} + 0x{x}]", .{ pl.index, pl.off }),
456 .lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }),453 .lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }),
457 .reserved_frame => |pl| try writer.print("(dead:{})", .{pl}),454 .reserved_frame => |pl| try writer.print("(dead:{})", .{pl}),
458 .air_ref => |pl| try writer.print("(air:0x{x})", .{@intFromEnum(pl)}),455 .air_ref => |pl| try writer.print("(air:0x{x})", .{@intFromEnum(pl)}),
456 .load_memory => |pl| try writer.print("[mem:{d}]", .{pl}),
457 .lea_memory => |pl| try writer.print("mem:{d}", .{pl}),
459 }458 }
460 }459 }
461};460};
...@@ -477,12 +476,12 @@ const InstTracking = struct {...@@ -477,12 +476,12 @@ const InstTracking = struct {
477 .lea_direct,476 .lea_direct,
478 .load_got,477 .load_got,
479 .lea_got,478 .lea_got,
480 .load_extern_got,
481 .lea_extern_got,
482 .load_tlv,479 .load_tlv,
483 .lea_tlv,480 .lea_tlv,
484 .load_frame,481 .load_frame,
485 .lea_frame,482 .lea_frame,
483 .load_memory,
484 .lea_memory,
486 => result,485 => result,
487 .dead,486 .dead,
488 .reserved_frame,487 .reserved_frame,
...@@ -538,12 +537,12 @@ const InstTracking = struct {...@@ -538,12 +537,12 @@ const InstTracking = struct {
538 .lea_direct,537 .lea_direct,
539 .load_got,538 .load_got,
540 .lea_got,539 .lea_got,
541 .load_extern_got,
542 .lea_extern_got,
543 .load_tlv,540 .load_tlv,
544 .lea_tlv,541 .lea_tlv,
545 .load_frame,542 .load_frame,
546 .lea_frame,543 .lea_frame,
544 .load_memory,
545 .lea_memory,
547 => self.long,546 => self.long,
548 .dead,547 .dead,
549 .eflags,548 .eflags,
...@@ -575,11 +574,11 @@ const InstTracking = struct {...@@ -575,11 +574,11 @@ const InstTracking = struct {
575 .lea_direct,574 .lea_direct,
576 .load_got,575 .load_got,
577 .lea_got,576 .lea_got,
578 .load_extern_got,
579 .lea_extern_got,
580 .load_tlv,577 .load_tlv,
581 .lea_tlv,578 .lea_tlv,
582 .lea_frame,579 .lea_frame,
580 .load_memory,
581 .lea_memory,
583 => assert(std.meta.eql(self.long, target.long)),582 => assert(std.meta.eql(self.long, target.long)),
584 .load_frame,583 .load_frame,
585 .reserved_frame,584 .reserved_frame,
...@@ -883,6 +882,7 @@ pub fn generate(...@@ -883,6 +882,7 @@ pub fn generate(
883882
884 var emit = Emit{883 var emit = Emit{
885 .lower = .{884 .lower = .{
885 .bin_file = bin_file,
886 .allocator = bin_file.allocator,886 .allocator = bin_file.allocator,
887 .mir = mir,887 .mir = mir,
888 .cc = cc,888 .cc = cc,
...@@ -970,6 +970,7 @@ pub fn generateLazy(...@@ -970,6 +970,7 @@ pub fn generateLazy(
970970
971 var emit = Emit{971 var emit = Emit{
972 .lower = .{972 .lower = .{
973 .bin_file = bin_file,
973 .allocator = bin_file.allocator,974 .allocator = bin_file.allocator,
974 .mir = mir,975 .mir = mir,
975 .cc = abi.resolveCallingConvention(.Unspecified, function.target.*),976 .cc = abi.resolveCallingConvention(.Unspecified, function.target.*),
...@@ -1060,6 +1061,7 @@ fn formatWipMir(...@@ -1060,6 +1061,7 @@ fn formatWipMir(
1060 writer: anytype,1061 writer: anytype,
1061) @TypeOf(writer).Error!void {1062) @TypeOf(writer).Error!void {
1062 var lower = Lower{1063 var lower = Lower{
1064 .bin_file = data.self.bin_file,
1063 .allocator = data.self.gpa,1065 .allocator = data.self.gpa,
1064 .mir = .{1066 .mir = .{
1065 .instructions = data.self.mir_instructions.slice(),1067 .instructions = data.self.mir_instructions.slice(),
...@@ -4729,12 +4731,12 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -4729,12 +4731,12 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
4729 Memory.sib(.qword, .{ .base = .{ .frame = frame_addr.index }, .disp = frame_addr.off }),4731 Memory.sib(.qword, .{ .base = .{ .frame = frame_addr.index }, .disp = frame_addr.off }),
4730 ),4732 ),
4731 .memory,4733 .memory,
4734 .load_memory,
4732 .load_direct,4735 .load_direct,
4733 .load_got,4736 .load_got,
4734 .load_extern_got,
4735 .load_tlv,4737 .load_tlv,
4736 => try self.genSetReg(addr_reg, Type.usize, array.address()),4738 => try self.genSetReg(addr_reg, Type.usize, array.address()),
4737 .lea_direct, .lea_tlv => unreachable,4739 .lea_memory, .lea_direct, .lea_tlv => unreachable,
4738 else => return self.fail("TODO implement array_elem_val when array is {}", .{array}),4740 else => return self.fail("TODO implement array_elem_val when array is {}", .{array}),
4739 }4741 }
47404742
...@@ -6327,17 +6329,17 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro...@@ -6327,17 +6329,17 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro
6327 .immediate,6329 .immediate,
6328 .register,6330 .register,
6329 .register_offset,6331 .register_offset,
6332 .lea_memory,
6330 .lea_direct,6333 .lea_direct,
6331 .lea_got,6334 .lea_got,
6332 .lea_extern_got,
6333 .lea_tlv,6335 .lea_tlv,
6334 .lea_frame,6336 .lea_frame,
6335 => try self.genCopy(dst_ty, dst_mcv, ptr_mcv.deref()),6337 => try self.genCopy(dst_ty, dst_mcv, ptr_mcv.deref()),
6336 .memory,6338 .memory,
6337 .indirect,6339 .indirect,
6340 .load_memory,
6338 .load_direct,6341 .load_direct,
6339 .load_got,6342 .load_got,
6340 .load_extern_got,
6341 .load_tlv,6343 .load_tlv,
6342 .load_frame,6344 .load_frame,
6343 => {6345 => {
...@@ -6476,17 +6478,17 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr...@@ -6476,17 +6478,17 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr
6476 .immediate,6478 .immediate,
6477 .register,6479 .register,
6478 .register_offset,6480 .register_offset,
6481 .lea_memory,
6479 .lea_direct,6482 .lea_direct,
6480 .lea_got,6483 .lea_got,
6481 .lea_extern_got,
6482 .lea_tlv,6484 .lea_tlv,
6483 .lea_frame,6485 .lea_frame,
6484 => try self.genCopy(src_ty, ptr_mcv.deref(), src_mcv),6486 => try self.genCopy(src_ty, ptr_mcv.deref(), src_mcv),
6485 .memory,6487 .memory,
6486 .indirect,6488 .indirect,
6489 .load_memory,
6487 .load_direct,6490 .load_direct,
6488 .load_got,6491 .load_got,
6489 .load_extern_got,
6490 .load_tlv,6492 .load_tlv,
6491 .load_frame,6493 .load_frame,
6492 => {6494 => {
...@@ -6913,15 +6915,15 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC...@@ -6913,15 +6915,15 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC
6913 .register_overflow,6915 .register_overflow,
6914 .lea_direct,6916 .lea_direct,
6915 .lea_got,6917 .lea_got,
6916 .lea_extern_got,
6917 .lea_tlv,6918 .lea_tlv,
6918 .lea_frame,6919 .lea_frame,
6919 .reserved_frame,6920 .reserved_frame,
6920 .air_ref,6921 .air_ref,
6922 .lea_memory,
6921 => unreachable, // unmodifiable destination6923 => unreachable, // unmodifiable destination
6922 .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)),6924 .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)),
6923 .register_pair => unreachable, // unimplemented6925 .register_pair => unreachable, // unimplemented
6924 .memory, .load_got, .load_extern_got, .load_direct, .load_tlv => {6926 .memory, .load_memory, .load_got, .load_direct, .load_tlv => {
6925 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);6927 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
6926 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);6928 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
6927 defer self.register_manager.unlockReg(addr_reg_lock);6929 defer self.register_manager.unlockReg(addr_reg_lock);
...@@ -7973,12 +7975,12 @@ fn genBinOp(...@@ -7973,12 +7975,12 @@ fn genBinOp(
7973 .immediate,7975 .immediate,
7974 .eflags,7976 .eflags,
7975 .register_offset,7977 .register_offset,
7978 .load_memory,
7979 .lea_memory,
7976 .load_direct,7980 .load_direct,
7977 .lea_direct,7981 .lea_direct,
7978 .load_got,7982 .load_got,
7979 .lea_got,7983 .lea_got,
7980 .load_extern_got,
7981 .lea_extern_got,
7982 .load_tlv,7984 .load_tlv,
7983 .lea_tlv,7985 .lea_tlv,
7984 .lea_frame,7986 .lea_frame,
...@@ -8031,12 +8033,12 @@ fn genBinOp(...@@ -8031,12 +8033,12 @@ fn genBinOp(
8031 .register_pair,8033 .register_pair,
8032 .register_offset,8034 .register_offset,
8033 .register_overflow,8035 .register_overflow,
8036 .load_memory,
8037 .lea_memory,
8034 .load_direct,8038 .load_direct,
8035 .lea_direct,8039 .lea_direct,
8036 .load_got,8040 .load_got,
8037 .lea_got,8041 .lea_got,
8038 .load_extern_got,
8039 .lea_extern_got,
8040 .load_tlv,8042 .load_tlv,
8041 .lea_tlv,8043 .lea_tlv,
8042 .lea_frame,8044 .lea_frame,
...@@ -9164,9 +9166,9 @@ fn genBinOpMir(...@@ -9164,9 +9166,9 @@ fn genBinOpMir(
9164 .register_overflow,9166 .register_overflow,
9165 .lea_direct,9167 .lea_direct,
9166 .lea_got,9168 .lea_got,
9167 .lea_extern_got,
9168 .lea_tlv,9169 .lea_tlv,
9169 .lea_frame,9170 .lea_frame,
9171 .lea_memory,
9170 .reserved_frame,9172 .reserved_frame,
9171 .air_ref,9173 .air_ref,
9172 => unreachable, // unmodifiable destination9174 => unreachable, // unmodifiable destination
...@@ -9249,12 +9251,12 @@ fn genBinOpMir(...@@ -9249,12 +9251,12 @@ fn genBinOpMir(
9249 .register_offset,9251 .register_offset,
9250 .memory,9252 .memory,
9251 .indirect,9253 .indirect,
9254 .load_memory,
9255 .lea_memory,
9252 .load_direct,9256 .load_direct,
9253 .lea_direct,9257 .lea_direct,
9254 .load_got,9258 .load_got,
9255 .lea_got,9259 .lea_got,
9256 .load_extern_got,
9257 .lea_extern_got,
9258 .load_tlv,9260 .load_tlv,
9259 .lea_tlv,9261 .lea_tlv,
9260 .load_frame,9262 .load_frame,
...@@ -9285,9 +9287,9 @@ fn genBinOpMir(...@@ -9285,9 +9287,9 @@ fn genBinOpMir(
9285 switch (src_mcv) {9287 switch (src_mcv) {
9286 .eflags,9288 .eflags,
9287 .register_offset,9289 .register_offset,
9290 .lea_memory,
9288 .lea_direct,9291 .lea_direct,
9289 .lea_got,9292 .lea_got,
9290 .lea_extern_got,
9291 .lea_tlv,9293 .lea_tlv,
9292 .lea_frame,9294 .lea_frame,
9293 => {9295 => {
...@@ -9301,9 +9303,9 @@ fn genBinOpMir(...@@ -9301,9 +9303,9 @@ fn genBinOpMir(
9301 );9303 );
9302 },9304 },
9303 .memory,9305 .memory,
9306 .load_memory,
9304 .load_direct,9307 .load_direct,
9305 .load_got,9308 .load_got,
9306 .load_extern_got,
9307 .load_tlv,9309 .load_tlv,
9308 => {9310 => {
9309 const ptr_ty = try mod.singleConstPtrType(ty);9311 const ptr_ty = try mod.singleConstPtrType(ty);
...@@ -9324,13 +9326,13 @@ fn genBinOpMir(...@@ -9324,13 +9326,13 @@ fn genBinOpMir(
9324 }9326 }
9325 }9327 }
9326 },9328 },
9327 .memory, .indirect, .load_got, .load_extern_got, .load_direct, .load_tlv, .load_frame => {9329 .memory, .indirect, .load_memory, .load_got, .load_direct, .load_tlv, .load_frame => {
9328 const OpInfo = ?struct { addr_reg: Register, addr_lock: RegisterLock };9330 const OpInfo = ?struct { addr_reg: Register, addr_lock: RegisterLock };
9329 const limb_abi_size: u32 = @min(abi_size, 8);9331 const limb_abi_size: u32 = @min(abi_size, 8);
93309332
9331 const dst_info: OpInfo = switch (dst_mcv) {9333 const dst_info: OpInfo = switch (dst_mcv) {
9332 else => unreachable,9334 else => unreachable,
9333 .memory, .load_got, .load_extern_got, .load_direct, .load_tlv => dst: {9335 .memory, .load_memory, .load_got, .load_direct, .load_tlv => dst: {
9334 const dst_addr_reg =9336 const dst_addr_reg =
9335 (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64();9337 (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64();
9336 const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg);9338 const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg);
...@@ -9364,17 +9366,17 @@ fn genBinOpMir(...@@ -9364,17 +9366,17 @@ fn genBinOpMir(
9364 .indirect,9366 .indirect,
9365 .lea_direct,9367 .lea_direct,
9366 .lea_got,9368 .lea_got,
9367 .lea_extern_got,
9368 .lea_tlv,9369 .lea_tlv,
9369 .load_frame,9370 .load_frame,
9370 .lea_frame,9371 .lea_frame,
9372 .lea_memory,
9371 => null,9373 => null,
9372 .memory, .load_got, .load_extern_got, .load_direct, .load_tlv => src: {9374 .memory, .load_memory, .load_got, .load_direct, .load_tlv => src: {
9373 switch (resolved_src_mcv) {9375 switch (resolved_src_mcv) {
9374 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr))) != null and9376 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr))) != null and
9375 math.cast(i32, @as(i64, @bitCast(addr)) + abi_size - limb_abi_size) != null)9377 math.cast(i32, @as(i64, @bitCast(addr)) + abi_size - limb_abi_size) != null)
9376 break :src null,9378 break :src null,
9377 .load_got, .load_extern_got, .load_direct, .load_tlv => {},9379 .load_memory, .load_got, .load_direct, .load_tlv => {},
9378 else => unreachable,9380 else => unreachable,
9379 }9381 }
93809382
...@@ -9416,8 +9418,8 @@ fn genBinOpMir(...@@ -9416,8 +9418,8 @@ fn genBinOpMir(
9416 Memory.PtrSize.fromSize(limb_abi_size),9418 Memory.PtrSize.fromSize(limb_abi_size),
9417 switch (dst_mcv) {9419 switch (dst_mcv) {
9418 .memory,9420 .memory,
9421 .load_memory,
9419 .load_got,9422 .load_got,
9420 .load_extern_got,
9421 .load_direct,9423 .load_direct,
9422 .load_tlv,9424 .load_tlv,
9423 => .{ .base = .{ .reg = dst_info.?.addr_reg }, .disp = off },9425 => .{ .base = .{ .reg = dst_info.?.addr_reg }, .disp = off },
...@@ -9498,12 +9500,12 @@ fn genBinOpMir(...@@ -9498,12 +9500,12 @@ fn genBinOpMir(
9498 .eflags,9500 .eflags,
9499 .memory,9501 .memory,
9500 .indirect,9502 .indirect,
9503 .load_memory,
9504 .lea_memory,
9501 .load_direct,9505 .load_direct,
9502 .lea_direct,9506 .lea_direct,
9503 .load_got,9507 .load_got,
9504 .lea_got,9508 .lea_got,
9505 .load_extern_got,
9506 .lea_extern_got,
9507 .load_tlv,9509 .load_tlv,
9508 .lea_tlv,9510 .lea_tlv,
9509 .load_frame,9511 .load_frame,
...@@ -9517,9 +9519,9 @@ fn genBinOpMir(...@@ -9517,9 +9519,9 @@ fn genBinOpMir(
9517 },9519 },
9518 .eflags,9520 .eflags,
9519 .register_offset,9521 .register_offset,
9522 .lea_memory,
9520 .lea_direct,9523 .lea_direct,
9521 .lea_got,9524 .lea_got,
9522 .lea_extern_got,
9523 .lea_tlv,9525 .lea_tlv,
9524 .lea_frame,9526 .lea_frame,
9525 => switch (limb_i) {9527 => switch (limb_i) {
...@@ -9568,9 +9570,9 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M...@@ -9568,9 +9570,9 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
9568 .eflags,9570 .eflags,
9569 .register_offset,9571 .register_offset,
9570 .register_overflow,9572 .register_overflow,
9573 .lea_memory,
9571 .lea_direct,9574 .lea_direct,
9572 .lea_got,9575 .lea_got,
9573 .lea_extern_got,
9574 .lea_tlv,9576 .lea_tlv,
9575 .lea_frame,9577 .lea_frame,
9576 .reserved_frame,9578 .reserved_frame,
...@@ -9615,12 +9617,12 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M...@@ -9615,12 +9617,12 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
9615 },9617 },
9616 .register_offset,9618 .register_offset,
9617 .eflags,9619 .eflags,
9620 .load_memory,
9621 .lea_memory,
9618 .load_direct,9622 .load_direct,
9619 .lea_direct,9623 .lea_direct,
9620 .load_got,9624 .load_got,
9621 .lea_got,9625 .lea_got,
9622 .load_extern_got,
9623 .lea_extern_got,
9624 .load_tlv,9626 .load_tlv,
9625 .lea_tlv,9627 .lea_tlv,
9626 .lea_frame,9628 .lea_frame,
...@@ -9659,7 +9661,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M...@@ -9659,7 +9661,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
9659 }9661 }
9660 },9662 },
9661 .register_pair => unreachable, // unimplemented9663 .register_pair => unreachable, // unimplemented
9662 .memory, .indirect, .load_direct, .load_got, .load_extern_got, .load_tlv, .load_frame => {9664 .memory, .indirect, .load_memory, .load_direct, .load_got, .load_tlv, .load_frame => {
9663 const tmp_reg = try self.copyToTmpRegister(dst_ty, dst_mcv);9665 const tmp_reg = try self.copyToTmpRegister(dst_ty, dst_mcv);
9664 const tmp_mcv = MCValue{ .register = tmp_reg };9666 const tmp_mcv = MCValue{ .register = tmp_reg };
9665 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);9667 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
...@@ -9759,8 +9761,8 @@ fn genVarDbgInfo(...@@ -9759,8 +9761,8 @@ fn genVarDbgInfo(
9759 // .offset = -off,9761 // .offset = -off,
9760 //} },9762 //} },
9761 .memory => |address| .{ .memory = address },9763 .memory => |address| .{ .memory = address },
9764 .load_memory => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } }, // TODO
9762 .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } },9765 .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } },
9763 .load_extern_got => |sym_index| .{ .linker_load = .{ .type = .extern_got, .sym_index = sym_index } },
9764 .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },9766 .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },
9765 .immediate => |x| .{ .immediate = x },9767 .immediate => |x| .{ .immediate = x },
9766 .undef => .undef,9768 .undef => .undef,
...@@ -10011,12 +10013,12 @@ fn genCall(self: *Self, info: union(enum) {...@@ -10011,12 +10013,12 @@ fn genCall(self: *Self, info: union(enum) {
10011 const sym = elf_file.symbol(sym_index);10013 const sym = elf_file.symbol(sym_index);
10012 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);10014 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
10013 if (self.bin_file.options.pic) {10015 if (self.bin_file.options.pic) {
10014 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym.esym_index });10016 try self.genSetReg(.rax, Type.usize, .{ .lea_memory = sym.esym_index });
10015 try self.asmRegister(.{ ._, .call }, .rax);10017 try self.asmRegister(.{ ._, .call }, .rax);
10016 } else {10018 } else {
10017 _ = try self.addInst(.{10019 _ = try self.addInst(.{
10018 .tag = .call,10020 .tag = .call,
10019 .ops = .direct_got_reloc,10021 .ops = .linker_reloc,
10020 .data = .{ .reloc = .{10022 .data = .{ .reloc = .{
10021 .atom_index = try self.owner.getSymbolIndex(self),10023 .atom_index = try self.owner.getSymbolIndex(self),
10022 .sym_index = sym.esym_index,10024 .sym_index = sym.esym_index,
...@@ -10241,14 +10243,14 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -10241,14 +10243,14 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
10241 .indirect,10243 .indirect,
10242 .lea_direct,10244 .lea_direct,
10243 .lea_got,10245 .lea_got,
10244 .lea_extern_got,
10245 .lea_tlv,10246 .lea_tlv,
10246 .lea_frame,10247 .lea_frame,
10248 .lea_memory,
10247 .reserved_frame,10249 .reserved_frame,
10248 .air_ref,10250 .air_ref,
10249 => unreachable,10251 => unreachable,
10250 .register_pair, .load_frame => null,10252 .register_pair, .load_frame => null,
10251 .memory, .load_got, .load_extern_got, .load_direct, .load_tlv => dst: {10253 .memory, .load_memory, .load_got, .load_direct, .load_tlv => dst: {
10252 switch (resolved_dst_mcv) {10254 switch (resolved_dst_mcv) {
10253 .memory => |addr| if (math.cast(10255 .memory => |addr| if (math.cast(
10254 i32,10256 i32,
...@@ -10257,7 +10259,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -10257,7 +10259,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
10257 i32,10259 i32,
10258 @as(i64, @bitCast(addr)) + abi_size - 8,10260 @as(i64, @bitCast(addr)) + abi_size - 8,
10259 ) != null) break :dst null,10261 ) != null) break :dst null,
10260 .load_got, .load_extern_got, .load_direct, .load_tlv => {},10262 .load_memory, .load_got, .load_direct, .load_tlv => {},
10261 else => unreachable,10263 else => unreachable,
10262 }10264 }
1026310265
...@@ -10298,16 +10300,16 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -10298,16 +10300,16 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
10298 .register_offset,10300 .register_offset,
10299 .register_overflow,10301 .register_overflow,
10300 .indirect,10302 .indirect,
10303 .lea_memory,
10301 .lea_direct,10304 .lea_direct,
10302 .lea_got,10305 .lea_got,
10303 .lea_extern_got,
10304 .lea_tlv,10306 .lea_tlv,
10305 .lea_frame,10307 .lea_frame,
10306 .reserved_frame,10308 .reserved_frame,
10307 .air_ref,10309 .air_ref,
10308 => unreachable,10310 => unreachable,
10309 .register_pair, .load_frame => null,10311 .register_pair, .load_frame => null,
10310 .memory, .load_got, .load_extern_got, .load_direct, .load_tlv => src: {10312 .memory, .load_memory, .load_got, .load_direct, .load_tlv => src: {
10311 switch (resolved_src_mcv) {10313 switch (resolved_src_mcv) {
10312 .memory => |addr| if (math.cast(10314 .memory => |addr| if (math.cast(
10313 i32,10315 i32,
...@@ -10316,7 +10318,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -10316,7 +10318,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
10316 i32,10318 i32,
10317 @as(i64, @bitCast(addr)) + abi_size - 8,10319 @as(i64, @bitCast(addr)) + abi_size - 8,
10318 ) != null) break :src null,10320 ) != null) break :src null,
10319 .load_got, .load_extern_got, .load_direct, .load_tlv => {},10321 .load_memory, .load_got, .load_direct, .load_tlv => {},
10320 else => unreachable,10322 else => unreachable,
10321 }10323 }
1032210324
...@@ -10739,9 +10741,9 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -10739,9 +10741,9 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
10739 .register_overflow,10741 .register_overflow,
10740 .lea_direct,10742 .lea_direct,
10741 .lea_got,10743 .lea_got,
10742 .lea_extern_got,
10743 .lea_tlv,10744 .lea_tlv,
10744 .lea_frame,10745 .lea_frame,
10746 .lea_memory,
10745 .reserved_frame,10747 .reserved_frame,
10746 .air_ref,10748 .air_ref,
10747 => unreachable,10749 => unreachable,
...@@ -10765,8 +10767,8 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -10765,8 +10767,8 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
10765 },10767 },
1076610768
10767 .memory,10769 .memory,
10770 .load_memory,
10768 .load_got,10771 .load_got,
10769 .load_extern_got,
10770 .load_direct,10772 .load_direct,
10771 .load_tlv,10773 .load_tlv,
10772 => {10774 => {
...@@ -11363,7 +11365,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -11363,7 +11365,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
11363 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |_|11365 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |_|
11364 break :arg input_mcv,11366 break :arg input_mcv,
11365 .indirect, .load_frame => break :arg input_mcv,11367 .indirect, .load_frame => break :arg input_mcv,
11366 .load_direct, .load_got, .load_extern_got, .load_tlv => {},11368 .load_memory, .load_direct, .load_got, .load_tlv => {},
11367 else => {11369 else => {
11368 const temp_mcv = try self.allocTempRegOrMem(ty, false);11370 const temp_mcv = try self.allocTempRegOrMem(ty, false);
11369 try self.genCopy(ty, temp_mcv, input_mcv);11371 try self.genCopy(ty, temp_mcv, input_mcv);
...@@ -11625,6 +11627,10 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -11625,6 +11627,10 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
11625 .{ .reg = try self.copyToTmpRegister(Type.usize, .{ .lea_got = sym_index }) }11627 .{ .reg = try self.copyToTmpRegister(Type.usize, .{ .lea_got = sym_index }) }
11626 else11628 else
11627 return self.fail("invalid modifier: '{s}'", .{modifier}),11629 return self.fail("invalid modifier: '{s}'", .{modifier}),
11630 .lea_memory => |sym_index| if (mem.eql(u8, modifier, "P"))
11631 .{ .reg = try self.copyToTmpRegister(Type.usize, .{ .lea_memory = sym_index }) }
11632 else
11633 return self.fail("invalid modifier: '{s}'", .{modifier}),
11628 else => return self.fail("invalid constraint: '{s}'", .{op_str}),11634 else => return self.fail("invalid constraint: '{s}'", .{op_str}),
11629 };11635 };
11630 } else if (mem.startsWith(u8, op_str, "$")) {11636 } else if (mem.startsWith(u8, op_str, "$")) {
...@@ -12178,9 +12184,9 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError...@@ -12178,9 +12184,9 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError
12178 .register_overflow,12184 .register_overflow,
12179 .lea_direct,12185 .lea_direct,
12180 .lea_got,12186 .lea_got,
12181 .lea_extern_got,
12182 .lea_tlv,12187 .lea_tlv,
12183 .lea_frame,12188 .lea_frame,
12189 .lea_memory,
12184 .reserved_frame,12190 .reserved_frame,
12185 .air_ref,12191 .air_ref,
12186 => unreachable, // unmodifiable destination12192 => unreachable, // unmodifiable destination
...@@ -12236,6 +12242,12 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError...@@ -12236,6 +12242,12 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError
12236 class_ty,12242 class_ty,
12237 .{ .register = src_regs[dst_reg_i] },12243 .{ .register = src_regs[dst_reg_i] },
12238 ),12244 ),
12245 .load_memory => {
12246 const addr_reg = try self.copyToTmpRegister(Type.usize, src_mcv.address());
12247 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
12248 defer self.register_manager.unlockReg(addr_lock);
12249 try self.genCopy(ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg } });
12250 },
12239 .memory, .indirect, .load_frame => try self.genSetReg(12251 .memory, .indirect, .load_frame => try self.genSetReg(
12240 dst_reg,12252 dst_reg,
12241 class_ty,12253 class_ty,
...@@ -12251,11 +12263,11 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError...@@ -12251,11 +12263,11 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError
12251 }12263 }
12252 },12264 },
12253 .indirect => |reg_off| try self.genSetMem(.{ .reg = reg_off.reg }, reg_off.off, ty, src_mcv),12265 .indirect => |reg_off| try self.genSetMem(.{ .reg = reg_off.reg }, reg_off.off, ty, src_mcv),
12254 .memory, .load_direct, .load_got, .load_extern_got, .load_tlv => {12266 .memory, .load_memory, .load_direct, .load_got, .load_tlv => {
12255 switch (dst_mcv) {12267 switch (dst_mcv) {
12256 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|12268 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|
12257 return self.genSetMem(.{ .reg = .ds }, small_addr, ty, src_mcv),12269 return self.genSetMem(.{ .reg = .ds }, small_addr, ty, src_mcv),
12258 .load_direct, .load_got, .load_extern_got, .load_tlv => {},12270 .load_memory, .load_direct, .load_got, .load_tlv => {},
12259 else => unreachable,12271 else => unreachable,
12260 }12272 }
1226112273
...@@ -12431,7 +12443,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -12431,7 +12443,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
12431 else => unreachable,12443 else => unreachable,
12432 },12444 },
12433 )),12445 )),
12434 .memory, .load_direct, .load_got, .load_extern_got, .load_tlv => {12446 .memory, .load_memory, .load_direct, .load_got, .load_tlv => {
12435 switch (src_mcv) {12447 switch (src_mcv) {
12436 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|12448 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|
12437 return (try self.moveStrategy(12449 return (try self.moveStrategy(
...@@ -12461,7 +12473,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -12461,7 +12473,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
12461 .segment, .mmx => unreachable,12473 .segment, .mmx => unreachable,
12462 .x87, .sse => {},12474 .x87, .sse => {},
12463 },12475 },
12464 .load_got, .load_extern_got, .load_tlv => {},12476 .load_memory, .load_got, .load_tlv => {},
12465 else => unreachable,12477 else => unreachable,
12466 }12478 }
1246712479
...@@ -12475,28 +12487,42 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -12475,28 +12487,42 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
12475 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .{ .reg = addr_reg } }),12487 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .{ .reg = addr_reg } }),
12476 );12488 );
12477 },12489 },
12478 .lea_direct, .lea_got, .lea_extern_got => |sym_index| {12490 .lea_memory, .lea_direct, .lea_got => |sym_index| {
12479 const atom_index = try self.owner.getSymbolIndex(self);12491 const atom_index = try self.owner.getSymbolIndex(self);
12480 _ = try self.addInst(.{12492 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
12481 .tag = switch (src_mcv) {12493 const sym = elf_file.symbol(elf_file.zigModulePtr().symbol(sym_index));
12482 .lea_direct => .lea,12494 _ = try self.addInst(.{
12483 .lea_got, .lea_extern_got => .mov,12495 .tag = if (sym.flags.has_zig_got) .mov else .lea,
12484 else => unreachable,12496 .ops = .linker_reloc,
12485 },12497 .data = .{ .rx = .{
12486 .ops = switch (src_mcv) {12498 .r1 = dst_reg.to64(),
12487 .lea_direct => .direct_reloc,12499 .payload = try self.addExtra(Mir.Reloc{
12488 .lea_got => .got_reloc,12500 .atom_index = atom_index,
12489 .lea_extern_got => .extern_got_reloc,12501 .sym_index = sym_index,
12490 else => unreachable,12502 }),
12491 },12503 } },
12492 .data = .{ .rx = .{12504 });
12493 .r1 = dst_reg.to64(),12505 } else {
12494 .payload = try self.addExtra(Mir.Reloc{12506 _ = try self.addInst(.{
12495 .atom_index = atom_index,12507 .tag = switch (src_mcv) {
12496 .sym_index = sym_index,12508 .lea_direct => .lea,
12497 }),12509 .lea_got => .mov,
12498 } },12510 else => unreachable,
12499 });12511 },
12512 .ops = switch (src_mcv) {
12513 .lea_direct => .direct_reloc,
12514 .lea_got => .got_reloc,
12515 else => unreachable,
12516 },
12517 .data = .{ .rx = .{
12518 .r1 = dst_reg.to64(),
12519 .payload = try self.addExtra(Mir.Reloc{
12520 .atom_index = atom_index,
12521 .sym_index = sym_index,
12522 }),
12523 } },
12524 });
12525 }
12500 },12526 },
12501 .lea_tlv => |sym_index| {12527 .lea_tlv => |sym_index| {
12502 const atom_index = try self.owner.getSymbolIndex(self);12528 const atom_index = try self.owner.getSymbolIndex(self);
...@@ -12645,12 +12671,12 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal...@@ -12645,12 +12671,12 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
12645 .lea_direct,12671 .lea_direct,
12646 .load_got,12672 .load_got,
12647 .lea_got,12673 .lea_got,
12648 .load_extern_got,
12649 .lea_extern_got,
12650 .load_tlv,12674 .load_tlv,
12651 .lea_tlv,12675 .lea_tlv,
12652 .load_frame,12676 .load_frame,
12653 .lea_frame,12677 .lea_frame,
12678 .load_memory,
12679 .lea_memory,
12654 => switch (abi_size) {12680 => switch (abi_size) {
12655 0 => {},12681 0 => {},
12656 1, 2, 4, 8 => {12682 1, 2, 4, 8 => {
...@@ -12741,8 +12767,8 @@ fn genLazySymbolRef(...@@ -12741,8 +12767,8 @@ fn genLazySymbolRef(
1274112767
12742 if (self.bin_file.options.pic) {12768 if (self.bin_file.options.pic) {
12743 switch (tag) {12769 switch (tag) {
12744 .lea, .call => try self.genSetReg(reg, Type.usize, .{ .lea_got = sym.esym_index }),12770 .lea, .call => try self.genSetReg(reg, Type.usize, .{ .lea_memory = sym.esym_index }),
12745 .mov => try self.genSetReg(reg, Type.usize, .{ .load_got = sym.esym_index }),12771 .mov => try self.genSetReg(reg, Type.usize, .{ .load_memory = sym.esym_index }),
12746 else => unreachable,12772 else => unreachable,
12747 }12773 }
12748 switch (tag) {12774 switch (tag) {
...@@ -12758,7 +12784,7 @@ fn genLazySymbolRef(...@@ -12758,7 +12784,7 @@ fn genLazySymbolRef(
12758 switch (tag) {12784 switch (tag) {
12759 .lea, .mov => _ = try self.addInst(.{12785 .lea, .mov => _ = try self.addInst(.{
12760 .tag = .mov,12786 .tag = .mov,
12761 .ops = .direct_got_reloc,12787 .ops = .linker_reloc,
12762 .data = .{ .rx = .{12788 .data = .{ .rx = .{
12763 .r1 = reg.to64(),12789 .r1 = reg.to64(),
12764 .payload = try self.addExtra(reloc),12790 .payload = try self.addExtra(reloc),
...@@ -12766,7 +12792,7 @@ fn genLazySymbolRef(...@@ -12766,7 +12792,7 @@ fn genLazySymbolRef(
12766 }),12792 }),
12767 .call => _ = try self.addInst(.{12793 .call => _ = try self.addInst(.{
12768 .tag = .call,12794 .tag = .call,
12769 .ops = .direct_got_reloc,12795 .ops = .linker_reloc,
12770 .data = .{ .reloc = reloc },12796 .data = .{ .reloc = reloc },
12771 }),12797 }),
12772 else => unreachable,12798 else => unreachable,
...@@ -14716,9 +14742,10 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {...@@ -14716,9 +14742,10 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
14716 .undef => .undef,14742 .undef => .undef,
14717 .immediate => |imm| .{ .immediate = imm },14743 .immediate => |imm| .{ .immediate = imm },
14718 .memory => |addr| .{ .memory = addr },14744 .memory => |addr| .{ .memory = addr },
14745 .load_memory => |sym_index| .{ .load_memory = sym_index },
14746 .lea_memory => |sym_index| .{ .lea_memory = sym_index },
14719 .load_direct => |sym_index| .{ .load_direct = sym_index },14747 .load_direct => |sym_index| .{ .load_direct = sym_index },
14720 .load_got => |sym_index| .{ .lea_got = sym_index },14748 .load_got => |sym_index| .{ .lea_got = sym_index },
14721 .load_extern_got => |sym_index| .{ .lea_extern_got = sym_index },
14722 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },14749 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
14723 },14750 },
14724 .fail => |msg| {14751 .fail => |msg| {
src/arch/x86_64/Emit.zig+31-21
...@@ -78,31 +78,41 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -78,31 +78,41 @@ pub fn emitMir(emit: *Emit) Error!void {
78 } else return emit.fail("TODO implement extern reloc for {s}", .{78 } else return emit.fail("TODO implement extern reloc for {s}", .{
79 @tagName(emit.bin_file.tag),79 @tagName(emit.bin_file.tag),
80 }),80 }),
81 .linker_reloc => |data| if (emit.bin_file.cast(link.File.Elf)) |elf_file| {
82 const atom = elf_file.symbol(data.atom_index).atom(elf_file).?;
83 const sym = elf_file.symbol(elf_file.zigModulePtr().symbol(data.sym_index));
84 if (emit.bin_file.options.pic) {
85 const r_type: u32 = if (sym.flags.has_zig_got)
86 link.File.Elf.R_X86_64_ZIG_GOTPCREL
87 else if (sym.flags.has_got)
88 std.elf.R_X86_64_GOTPCREL
89 else
90 std.elf.R_X86_64_PC32;
91 try atom.addReloc(elf_file, .{
92 .r_offset = end_offset - 4,
93 .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type,
94 .r_addend = -4,
95 });
96 } else {
97 const r_type: u32 = if (sym.flags.has_zig_got)
98 link.File.Elf.R_X86_64_ZIG_GOT32
99 else if (sym.flags.has_got)
100 std.elf.R_X86_64_GOT32
101 else
102 std.elf.R_X86_64_32;
103 try atom.addReloc(elf_file, .{
104 .r_offset = end_offset - 4,
105 .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type,
106 .r_addend = 0,
107 });
108 }
109 } else unreachable,
81 .linker_got,110 .linker_got,
82 .linker_extern_got,
83 .linker_direct,111 .linker_direct,
84 .linker_direct_got,
85 .linker_import,112 .linker_import,
86 .linker_tlv,113 .linker_tlv,
87 => |symbol| if (emit.bin_file.cast(link.File.Elf)) |elf_file| {114 => |symbol| if (emit.bin_file.cast(link.File.Elf)) |_| {
88 const r_type: u32 = switch (lowered_relocs[0].target) {115 unreachable;
89 .linker_direct_got => link.File.Elf.R_X86_64_ZIG_GOT32,
90 .linker_got => link.File.Elf.R_X86_64_ZIG_GOTPCREL,
91 .linker_extern_got => std.elf.R_X86_64_GOTPCREL,
92 .linker_direct => std.elf.R_X86_64_PC32,
93 else => unreachable,
94 };
95 const r_addend: i64 = switch (lowered_relocs[0].target) {
96 .linker_direct_got => 0,
97 .linker_got, .linker_extern_got, .linker_direct => -4,
98 else => unreachable,
99 };
100 const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?;
101 try atom_ptr.addReloc(elf_file, .{
102 .r_offset = end_offset - 4,
103 .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | r_type,
104 .r_addend = r_addend,
105 });
106 } else if (emit.bin_file.cast(link.File.MachO)) |macho_file| {116 } else if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
107 const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = symbol.atom_index }).?;117 const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = symbol.atom_index }).?;
108 try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{118 try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
src/arch/x86_64/Lower.zig+42-24
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1//! This file contains the functionality for lowering x86_64 MIR to Instructions1//! This file contains the functionality for lowering x86_64 MIR to Instructions
22
3bin_file: *link.File,
3allocator: Allocator,4allocator: Allocator,
4mir: Mir,5mir: Mir,
5cc: std.builtin.CallingConvention,6cc: std.builtin.CallingConvention,
...@@ -49,11 +50,10 @@ pub const Reloc = struct {...@@ -49,11 +50,10 @@ pub const Reloc = struct {
4950
50 const Target = union(enum) {51 const Target = union(enum) {
51 inst: Mir.Inst.Index,52 inst: Mir.Inst.Index,
53 linker_reloc: Mir.Reloc,
52 linker_extern_fn: Mir.Reloc,54 linker_extern_fn: Mir.Reloc,
53 linker_got: Mir.Reloc,55 linker_got: Mir.Reloc,
54 linker_extern_got: Mir.Reloc,
55 linker_direct: Mir.Reloc,56 linker_direct: Mir.Reloc,
56 linker_direct_got: Mir.Reloc,
57 linker_import: Mir.Reloc,57 linker_import: Mir.Reloc,
58 linker_tlv: Mir.Reloc,58 linker_tlv: Mir.Reloc,
59 };59 };
...@@ -407,10 +407,9 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {...@@ -407,10 +407,9 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
407 .mi_sib_u, .mi_rip_u, .mi_sib_s, .mi_rip_s => inst.data.x.fixes,407 .mi_sib_u, .mi_rip_u, .mi_sib_s, .mi_rip_s => inst.data.x.fixes,
408 .m_sib, .m_rip, .rax_moffs, .moffs_rax => inst.data.x.fixes,408 .m_sib, .m_rip, .rax_moffs, .moffs_rax => inst.data.x.fixes,
409 .extern_fn_reloc,409 .extern_fn_reloc,
410 .linker_reloc,
410 .got_reloc,411 .got_reloc,
411 .extern_got_reloc,
412 .direct_reloc,412 .direct_reloc,
413 .direct_got_reloc,
414 .import_reloc,413 .import_reloc,
415 .tlv_reloc,414 .tlv_reloc,
416 => ._,415 => ._,
...@@ -545,32 +544,50 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {...@@ -545,32 +544,50 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
545 .extern_fn_reloc => &.{544 .extern_fn_reloc => &.{
546 .{ .imm = lower.reloc(.{ .linker_extern_fn = inst.data.reloc }) },545 .{ .imm = lower.reloc(.{ .linker_extern_fn = inst.data.reloc }) },
547 },546 },
548 .direct_got_reloc => ops: {547 .linker_reloc => ops: {
549 switch (inst.tag) {548 if (lower.bin_file.options.pic) {
550 .call => {549 const reg = inst.data.rx.r1;
551 _ = lower.reloc(.{ .linker_direct_got = inst.data.reloc });550 const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;
552 break :ops &.{551 _ = lower.reloc(.{ .linker_reloc = extra });
553 .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) },552 break :ops &.{
554 };553 .{ .reg = reg },
555 },554 .{ .mem = Memory.rip(Memory.PtrSize.fromBitSize(reg.bitSize()), 0) },
556 .mov => {555 };
557 const reg = inst.data.rx.r1;556 } else {
558 const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;557 switch (inst.tag) {
559 _ = lower.reloc(.{ .linker_direct_got = extra });558 .call => {
560 break :ops &.{559 _ = lower.reloc(.{ .linker_reloc = inst.data.reloc });
561 .{ .reg = reg },560 break :ops &.{
562 .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) },561 .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) },
563 };562 };
564 },563 },
565 else => unreachable,564 .mov => {
565 const reg = inst.data.rx.r1;
566 const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;
567 _ = lower.reloc(.{ .linker_reloc = extra });
568 break :ops &.{
569 .{ .reg = reg },
570 .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) },
571 };
572 },
573 .lea => {
574 const reg = inst.data.rx.r1;
575 const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;
576 _ = lower.reloc(.{ .linker_reloc = extra });
577 break :ops &.{
578 .{ .reg = reg },
579 .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) },
580 };
581 },
582 else => return lower.fail("TODO lower {s} {s}", .{ @tagName(inst.tag), @tagName(inst.ops) }),
583 }
566 }584 }
567 },585 },
568 .got_reloc, .extern_got_reloc, .direct_reloc, .import_reloc, .tlv_reloc => ops: {586 .got_reloc, .direct_reloc, .import_reloc, .tlv_reloc => ops: {
569 const reg = inst.data.rx.r1;587 const reg = inst.data.rx.r1;
570 const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;588 const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;
571 _ = lower.reloc(switch (inst.ops) {589 _ = lower.reloc(switch (inst.ops) {
572 .got_reloc => .{ .linker_got = extra },590 .got_reloc => .{ .linker_got = extra },
573 .extern_got_reloc => .{ .linker_extern_got = extra },
574 .direct_reloc => .{ .linker_direct = extra },591 .direct_reloc => .{ .linker_direct = extra },
575 .import_reloc => .{ .linker_import = extra },592 .import_reloc => .{ .linker_import = extra },
576 .tlv_reloc => .{ .linker_tlv = extra },593 .tlv_reloc => .{ .linker_tlv = extra },
...@@ -601,6 +618,7 @@ const abi = @import("abi.zig");...@@ -601,6 +618,7 @@ const abi = @import("abi.zig");
601const assert = std.debug.assert;618const assert = std.debug.assert;
602const bits = @import("bits.zig");619const bits = @import("bits.zig");
603const encoder = @import("encoder.zig");620const encoder = @import("encoder.zig");
621const link = @import("../../link.zig");
604const std = @import("std");622const std = @import("std");
605623
606const Air = @import("../../Air.zig");624const Air = @import("../../Air.zig");
src/arch/x86_64/Mir.zig+3-6
...@@ -854,9 +854,6 @@ pub const Inst = struct {...@@ -854,9 +854,6 @@ pub const Inst = struct {
854 /// Linker relocation - GOT indirection.854 /// Linker relocation - GOT indirection.
855 /// Uses `rx` payload with extra data of type `Reloc`.855 /// Uses `rx` payload with extra data of type `Reloc`.
856 got_reloc,856 got_reloc,
857 /// Linker relocation - reference to an extern variable via GOT.
858 /// Uses `rx` payload with extra data of type `Reloc`.
859 extern_got_reloc,
860 /// Linker relocation - direct reference.857 /// Linker relocation - direct reference.
861 /// Uses `rx` payload with extra data of type `Reloc`.858 /// Uses `rx` payload with extra data of type `Reloc`.
862 direct_reloc,859 direct_reloc,
...@@ -866,9 +863,9 @@ pub const Inst = struct {...@@ -866,9 +863,9 @@ pub const Inst = struct {
866 /// Linker relocation - threadlocal variable via GOT indirection.863 /// Linker relocation - threadlocal variable via GOT indirection.
867 /// Uses `rx` payload with extra data of type `Reloc`.864 /// Uses `rx` payload with extra data of type `Reloc`.
868 tlv_reloc,865 tlv_reloc,
869 /// Linker relocation - non-PIC direct reference to GOT cell.866 /// Linker relocation.
870 /// Uses `reloc` payload if tag is `call`, `rx` otherwise.867 /// Uses `rx` payload with extra data of type `Reloc`.
871 direct_got_reloc,868 linker_reloc,
872869
873 // Pseudo instructions:870 // Pseudo instructions:
874871
src/codegen.zig+8-15
...@@ -791,13 +791,11 @@ fn lowerDeclRef(...@@ -791,13 +791,11 @@ fn lowerDeclRef(
791791
792/// Helper struct to denote that the value is in memory but requires a linker relocation fixup:792/// Helper struct to denote that the value is in memory but requires a linker relocation fixup:
793/// * got - the value is referenced indirectly via GOT entry index (the linker emits a got-type reloc)793/// * got - the value is referenced indirectly via GOT entry index (the linker emits a got-type reloc)
794/// * extern_got - pointer to extern variable referenced via GOT
795/// * direct - the value is referenced directly via symbol index index (the linker emits a displacement reloc)794/// * direct - the value is referenced directly via symbol index index (the linker emits a displacement reloc)
796/// * import - the value is referenced indirectly via import entry index (the linker emits an import-type reloc)795/// * import - the value is referenced indirectly via import entry index (the linker emits an import-type reloc)
797pub const LinkerLoad = struct {796pub const LinkerLoad = struct {
798 type: enum {797 type: enum {
799 got,798 got,
800 extern_got,
801 direct,799 direct,
802 import,800 import,
803 },801 },
...@@ -827,8 +825,10 @@ pub const GenResult = union(enum) {...@@ -827,8 +825,10 @@ pub const GenResult = union(enum) {
827 load_got: u32,825 load_got: u32,
828 /// Direct by-address reference to memory location.826 /// Direct by-address reference to memory location.
829 memory: u64,827 memory: u64,
830 /// Pointer to extern variable via GOT.828 /// Reference to memory location but deferred until linker allocated the Decl in memory.
831 load_extern_got: u32,829 /// Traditionally, this corresponds to emitting a relocation in a relocatable object file.
830 load_memory: u32,
831 lea_memory: u32,
832 };832 };
833833
834 fn mcv(val: MCValue) GenResult {834 fn mcv(val: MCValue) GenResult {
...@@ -903,16 +903,13 @@ fn genDeclRef(...@@ -903,16 +903,13 @@ fn genDeclRef(
903 mod.intern_pool.stringToSliceUnwrap(ov.lib_name)903 mod.intern_pool.stringToSliceUnwrap(ov.lib_name)
904 else904 else
905 null;905 null;
906 return GenResult.mcv(.{ .load_extern_got = try elf_file.getGlobalSymbol(name, lib_name) });906 const sym_index = try elf_file.getGlobalSymbol(name, lib_name);
907 return GenResult.mcv(.{ .lea_memory = sym_index });
907 }908 }
908 const sym_index = try elf_file.getOrCreateMetadataForDecl(decl_index);909 const sym_index = try elf_file.getOrCreateMetadataForDecl(decl_index);
909 const sym = elf_file.symbol(sym_index);910 const sym = elf_file.symbol(sym_index);
910 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);911 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
911 if (bin_file.options.pic) {912 return GenResult.mcv(.{ .lea_memory = sym.esym_index });
912 return GenResult.mcv(.{ .load_got = sym.esym_index });
913 } else {
914 return GenResult.mcv(.{ .memory = sym.zigGotAddress(elf_file) });
915 }
916 } else if (bin_file.cast(link.File.MachO)) |macho_file| {913 } else if (bin_file.cast(link.File.MachO)) |macho_file| {
917 const atom_index = try macho_file.getOrCreateAtomForDecl(decl_index);914 const atom_index = try macho_file.getOrCreateAtomForDecl(decl_index);
918 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;915 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
...@@ -948,11 +945,7 @@ fn genUnnamedConst(...@@ -948,11 +945,7 @@ fn genUnnamedConst(
948 };945 };
949 if (bin_file.cast(link.File.Elf)) |elf_file| {946 if (bin_file.cast(link.File.Elf)) |elf_file| {
950 const local = elf_file.symbol(local_sym_index);947 const local = elf_file.symbol(local_sym_index);
951 if (bin_file.options.pic) {948 return GenResult.mcv(.{ .load_memory = local.esym_index });
952 return GenResult.mcv(.{ .load_direct = local.esym_index });
953 } else {
954 return GenResult.mcv(.{ .memory = local.value });
955 }
956 } else if (bin_file.cast(link.File.MachO)) |_| {949 } else if (bin_file.cast(link.File.MachO)) |_| {
957 return GenResult.mcv(.{ .load_direct = local_sym_index });950 return GenResult.mcv(.{ .load_direct = local_sym_index });
958 } else if (bin_file.cast(link.File.Coff)) |_| {951 } else if (bin_file.cast(link.File.Coff)) |_| {
src/link/Elf.zig+6
...@@ -5955,6 +5955,12 @@ pub fn getGlobalSymbol(self: *Elf, name: []const u8, lib_name: ?[]const u8) !u32...@@ -5955,6 +5955,12 @@ pub fn getGlobalSymbol(self: *Elf, name: []const u8, lib_name: ?[]const u8) !u32
5955 return lookup_gop.value_ptr.*;5955 return lookup_gop.value_ptr.*;
5956}5956}
59575957
5958pub fn zigModulePtr(self: *Elf) *ZigModule {
5959 assert(self.zig_module_index != null);
5960 const file_ptr = self.file(self.zig_module_index.?).?;
5961 return file_ptr.zig_module;
5962}
5963
5958const GetOrCreateComdatGroupOwnerResult = struct {5964const GetOrCreateComdatGroupOwnerResult = struct {
5959 found_existing: bool,5965 found_existing: bool,
5960 index: ComdatGroupOwner.Index,5966 index: ComdatGroupOwner.Index,
src/link/Elf/Atom.zig+3
...@@ -370,6 +370,7 @@ pub fn scanRelocs(self: Atom, elf_file: *Elf, code: ?[]const u8, undefs: anytype...@@ -370,6 +370,7 @@ pub fn scanRelocs(self: Atom, elf_file: *Elf, code: ?[]const u8, undefs: anytype
370 try self.scanReloc(symbol, rel, dynAbsRelocAction(symbol, elf_file), elf_file);370 try self.scanReloc(symbol, rel, dynAbsRelocAction(symbol, elf_file), elf_file);
371 },371 },
372372
373 elf.R_X86_64_GOT32,
373 elf.R_X86_64_GOTPC32,374 elf.R_X86_64_GOTPC32,
374 elf.R_X86_64_GOTPC64,375 elf.R_X86_64_GOTPC64,
375 elf.R_X86_64_GOTPCREL,376 elf.R_X86_64_GOTPCREL,
...@@ -879,6 +880,8 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) !void {...@@ -879,6 +880,8 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) !void {
879 }880 }
880 },881 },
881882
883 elf.R_X86_64_GOT32 => try cwriter.writeIntLittle(i32, @as(i32, @intCast(G + GOT + A))),
884
882 // Zig custom relocations885 // Zig custom relocations
883 Elf.R_X86_64_ZIG_GOT32 => try cwriter.writeIntLittle(u32, @as(u32, @intCast(ZIG_GOT + A))),886 Elf.R_X86_64_ZIG_GOT32 => try cwriter.writeIntLittle(u32, @as(u32, @intCast(ZIG_GOT + A))),
884 Elf.R_X86_64_ZIG_GOTPCREL => try cwriter.writeIntLittle(i32, @as(i32, @intCast(ZIG_GOT + A - P))),887 Elf.R_X86_64_ZIG_GOTPCREL => try cwriter.writeIntLittle(i32, @as(i32, @intCast(ZIG_GOT + A - P))),