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
40124012 .got => .load_memory_ptr_got,
40134013 .direct => .load_memory_ptr_direct,
40144014 .import => unreachable,
4015 .actual_got => unreachable,
40154016 };
40164017 const atom_index = switch (self.bin_file.tag) {
40174018 .macho => blk: {
......@@ -5531,6 +5532,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
55315532 .got => .load_memory_ptr_got,
55325533 .direct => .load_memory_ptr_direct,
55335534 .import => unreachable,
5535 .actual_got => unreachable,
55345536 };
55355537 const atom_index = switch (self.bin_file.tag) {
55365538 .macho => blk: {
......@@ -5652,6 +5654,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
56525654 .got => .load_memory_got,
56535655 .direct => .load_memory_direct,
56545656 .import => .load_memory_import,
5657 .actual_got => unreachable,
56555658 };
56565659 const atom_index = switch (self.bin_file.tag) {
56575660 .macho => blk: {
......@@ -5849,6 +5852,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
58495852 .got => .load_memory_ptr_got,
58505853 .direct => .load_memory_ptr_direct,
58515854 .import => unreachable,
5855 .actual_got => unreachable,
58525856 };
58535857 const atom_index = switch (self.bin_file.tag) {
58545858 .macho => blk: {
......@@ -6176,7 +6180,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
61766180 .memory => |addr| .{ .memory = addr },
61776181 .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } },
61786182 .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },
6179 .load_tlv => unreachable, // TODO
6183 .load_actual_got, .load_tlv => unreachable, // TODO
61806184 },
61816185 .fail => |msg| {
61826186 self.err_msg = msg;
src/arch/arm/CodeGen.zig+1-1
......@@ -6135,7 +6135,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
61356135 .mcv => |mcv| switch (mcv) {
61366136 .none => .none,
61376137 .undef => .undef,
6138 .load_got, .load_direct, .load_tlv => unreachable, // TODO
6138 .load_got, .load_actual_got, .load_direct, .load_tlv => unreachable, // TODO
61396139 .immediate => |imm| .{ .immediate = @as(u32, @truncate(imm)) },
61406140 .memory => |addr| .{ .memory = addr },
61416141 },
src/arch/riscv64/CodeGen.zig+1-1
......@@ -2591,7 +2591,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
25912591 .mcv => |mcv| switch (mcv) {
25922592 .none => .none,
25932593 .undef => .undef,
2594 .load_got, .load_direct, .load_tlv => unreachable, // TODO
2594 .load_got, .load_actual_got, .load_direct, .load_tlv => unreachable, // TODO
25952595 .immediate => |imm| .{ .immediate = imm },
25962596 .memory => |addr| .{ .memory = addr },
25972597 },
src/arch/sparc64/CodeGen.zig+1-1
......@@ -4137,7 +4137,7 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
41374137 .mcv => |mcv| switch (mcv) {
41384138 .none => .none,
41394139 .undef => .undef,
4140 .load_got, .load_direct, .load_tlv => unreachable, // TODO
4140 .load_got, .load_actual_got, .load_direct, .load_tlv => unreachable, // TODO
41414141 .immediate => |imm| .{ .immediate = imm },
41424142 .memory => |addr| .{ .memory = addr },
41434143 },
src/arch/x86_64/CodeGen.zig+70-17
......@@ -207,6 +207,10 @@ pub const MCValue = union(enum) {
207207 /// The value is a pointer to a value referenced indirectly via GOT.
208208 /// Payload is a symbol index.
209209 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,
210214 /// The value is a threadlocal variable.
211215 /// Payload is a symbol index.
212216 load_tlv: u32,
......@@ -295,6 +299,7 @@ pub const MCValue = union(enum) {
295299 .register_overflow,
296300 .lea_direct,
297301 .lea_got,
302 .lea_actual_got,
298303 .lea_tlv,
299304 .lea_frame,
300305 .reserved_frame,
......@@ -308,6 +313,7 @@ pub const MCValue = union(enum) {
308313 .load_direct => |sym_index| .{ .lea_direct = sym_index },
309314 .load_got => |sym_index| .{ .lea_got = sym_index },
310315 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
316 .load_actual_got => |sym_index| .{ .lea_actual_got = sym_index },
311317 .load_frame => |frame_addr| .{ .lea_frame = frame_addr },
312318 };
313319 }
......@@ -325,6 +331,7 @@ pub const MCValue = union(enum) {
325331 .indirect,
326332 .load_direct,
327333 .load_got,
334 .load_actual_got,
328335 .load_tlv,
329336 .load_frame,
330337 .reserved_frame,
......@@ -335,6 +342,7 @@ pub const MCValue = union(enum) {
335342 .register_offset => |reg_off| .{ .indirect = reg_off },
336343 .lea_direct => |sym_index| .{ .load_direct = sym_index },
337344 .lea_got => |sym_index| .{ .load_got = sym_index },
345 .lea_actual_got => |sym_index| .{ .load_actual_got = sym_index },
338346 .lea_tlv => |sym_index| .{ .load_tlv = sym_index },
339347 .lea_frame => |frame_addr| .{ .load_frame = frame_addr },
340348 };
......@@ -358,6 +366,8 @@ pub const MCValue = union(enum) {
358366 .lea_direct,
359367 .load_got,
360368 .lea_got,
369 .load_actual_got,
370 .lea_actual_got,
361371 .load_tlv,
362372 .lea_tlv,
363373 .load_frame,
......@@ -392,6 +402,8 @@ pub const MCValue = union(enum) {
392402 .lea_direct,
393403 .load_got,
394404 .lea_got,
405 .load_actual_got,
406 .lea_actual_got,
395407 .load_tlv,
396408 .lea_tlv,
397409 .lea_frame,
......@@ -434,6 +446,8 @@ pub const MCValue = union(enum) {
434446 .lea_direct => |pl| try writer.print("direct:{d}", .{pl}),
435447 .load_got => |pl| try writer.print("[got:{d}]", .{pl}),
436448 .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}),
437451 .load_tlv => |pl| try writer.print("[tlv:{d}]", .{pl}),
438452 .lea_tlv => |pl| try writer.print("tlv:{d}", .{pl}),
439453 .load_frame => |pl| try writer.print("[{} + 0x{x}]", .{ pl.index, pl.off }),
......@@ -461,6 +475,8 @@ const InstTracking = struct {
461475 .lea_direct,
462476 .load_got,
463477 .lea_got,
478 .load_actual_got,
479 .lea_actual_got,
464480 .load_tlv,
465481 .lea_tlv,
466482 .load_frame,
......@@ -520,6 +536,8 @@ const InstTracking = struct {
520536 .lea_direct,
521537 .load_got,
522538 .lea_got,
539 .load_actual_got,
540 .lea_actual_got,
523541 .load_tlv,
524542 .lea_tlv,
525543 .load_frame,
......@@ -555,6 +573,8 @@ const InstTracking = struct {
555573 .lea_direct,
556574 .load_got,
557575 .lea_got,
576 .load_actual_got,
577 .lea_actual_got,
558578 .load_tlv,
559579 .lea_tlv,
560580 .lea_frame,
......@@ -4371,6 +4391,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
43714391 .memory,
43724392 .load_direct,
43734393 .load_got,
4394 .load_actual_got,
43744395 .load_tlv,
43754396 => try self.genSetReg(addr_reg, Type.usize, array.address()),
43764397 .lea_direct, .lea_tlv => unreachable,
......@@ -5851,6 +5872,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro
58515872 .register_offset,
58525873 .lea_direct,
58535874 .lea_got,
5875 .lea_actual_got,
58545876 .lea_tlv,
58555877 .lea_frame,
58565878 => 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
58585880 .indirect,
58595881 .load_direct,
58605882 .load_got,
5883 .load_actual_got,
58615884 .load_tlv,
58625885 .load_frame,
58635886 => {
......@@ -5996,6 +6019,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr
59966019 .register_offset,
59976020 .lea_direct,
59986021 .lea_got,
6022 .lea_actual_got,
59996023 .lea_tlv,
60006024 .lea_frame,
60016025 => 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
60036027 .indirect,
60046028 .load_direct,
60056029 .load_got,
6030 .load_actual_got,
60066031 .load_tlv,
60076032 .load_frame,
60086033 => {
......@@ -6424,6 +6449,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC
64246449 .register_overflow,
64256450 .lea_direct,
64266451 .lea_got,
6452 .lea_actual_got,
64276453 .lea_tlv,
64286454 .lea_frame,
64296455 .reserved_frame,
......@@ -6431,7 +6457,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC
64316457 => unreachable, // unmodifiable destination
64326458 .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)),
64336459 .register_pair => unreachable, // unimplemented
6434 .memory, .load_got, .load_direct, .load_tlv => {
6460 .memory, .load_got, .load_actual_got, .load_direct, .load_tlv => {
64356461 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
64366462 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
64376463 defer self.register_manager.unlockReg(addr_reg_lock);
......@@ -7389,6 +7415,8 @@ fn genBinOp(
73897415 .lea_direct,
73907416 .load_got,
73917417 .lea_got,
7418 .load_actual_got,
7419 .lea_actual_got,
73927420 .load_tlv,
73937421 .lea_tlv,
73947422 .lea_frame,
......@@ -7445,6 +7473,8 @@ fn genBinOp(
74457473 .lea_direct,
74467474 .load_got,
74477475 .lea_got,
7476 .load_actual_got,
7477 .lea_actual_got,
74487478 .load_tlv,
74497479 .lea_tlv,
74507480 .lea_frame,
......@@ -8397,6 +8427,7 @@ fn genBinOpMir(
83978427 .register_overflow,
83988428 .lea_direct,
83998429 .lea_got,
8430 .lea_actual_got,
84008431 .lea_tlv,
84018432 .lea_frame,
84028433 .reserved_frame,
......@@ -8485,6 +8516,8 @@ fn genBinOpMir(
84858516 .lea_direct,
84868517 .load_got,
84878518 .lea_got,
8519 .load_actual_got,
8520 .lea_actual_got,
84888521 .load_tlv,
84898522 .lea_tlv,
84908523 .load_frame,
......@@ -8517,6 +8550,7 @@ fn genBinOpMir(
85178550 .register_offset,
85188551 .lea_direct,
85198552 .lea_got,
8553 .lea_actual_got,
85208554 .lea_tlv,
85218555 .lea_frame,
85228556 => {
......@@ -8532,6 +8566,7 @@ fn genBinOpMir(
85328566 .memory,
85338567 .load_direct,
85348568 .load_got,
8569 .load_actual_got,
85358570 .load_tlv,
85368571 => {
85378572 const ptr_ty = try mod.singleConstPtrType(ty);
......@@ -8552,13 +8587,13 @@ fn genBinOpMir(
85528587 }
85538588 }
85548589 },
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 => {
85568591 const OpInfo = ?struct { addr_reg: Register, addr_lock: RegisterLock };
85578592 const limb_abi_size: u32 = @min(abi_size, 8);
85588593
85598594 const dst_info: OpInfo = switch (dst_mcv) {
85608595 else => unreachable,
8561 .memory, .load_got, .load_direct, .load_tlv => dst: {
8596 .memory, .load_got, .load_actual_got, .load_direct, .load_tlv => dst: {
85628597 const dst_addr_reg =
85638598 (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64();
85648599 const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg);
......@@ -8592,16 +8627,17 @@ fn genBinOpMir(
85928627 .indirect,
85938628 .lea_direct,
85948629 .lea_got,
8630 .lea_actual_got,
85958631 .lea_tlv,
85968632 .load_frame,
85978633 .lea_frame,
85988634 => null,
8599 .memory, .load_got, .load_direct, .load_tlv => src: {
8635 .memory, .load_got, .load_actual_got, .load_direct, .load_tlv => src: {
86008636 switch (resolved_src_mcv) {
86018637 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr))) != null and
86028638 math.cast(i32, @as(i64, @bitCast(addr)) + abi_size - limb_abi_size) != null)
86038639 break :src null,
8604 .load_got, .load_direct, .load_tlv => {},
8640 .load_got, .load_actual_got, .load_direct, .load_tlv => {},
86058641 else => unreachable,
86068642 }
86078643
......@@ -8644,6 +8680,7 @@ fn genBinOpMir(
86448680 switch (dst_mcv) {
86458681 .memory,
86468682 .load_got,
8683 .load_actual_got,
86478684 .load_direct,
86488685 .load_tlv,
86498686 => .{ .base = .{ .reg = dst_info.?.addr_reg }, .disp = off },
......@@ -8728,6 +8765,8 @@ fn genBinOpMir(
87288765 .lea_direct,
87298766 .load_got,
87308767 .lea_got,
8768 .load_actual_got,
8769 .lea_actual_got,
87318770 .load_tlv,
87328771 .lea_tlv,
87338772 .load_frame,
......@@ -8743,6 +8782,7 @@ fn genBinOpMir(
87438782 .register_offset,
87448783 .lea_direct,
87458784 .lea_got,
8785 .lea_actual_got,
87468786 .lea_tlv,
87478787 .lea_frame,
87488788 => switch (limb_i) {
......@@ -8792,6 +8832,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
87928832 .register_overflow,
87938833 .lea_direct,
87948834 .lea_got,
8835 .lea_actual_got,
87958836 .lea_tlv,
87968837 .lea_frame,
87978838 .reserved_frame,
......@@ -8840,6 +8881,8 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
88408881 .lea_direct,
88418882 .load_got,
88428883 .lea_got,
8884 .load_actual_got,
8885 .lea_actual_got,
88438886 .load_tlv,
88448887 .lea_tlv,
88458888 .lea_frame,
......@@ -8878,7 +8921,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
88788921 }
88798922 },
88808923 .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 => {
88828925 const tmp_reg = try self.copyToTmpRegister(dst_ty, dst_mcv);
88838926 const tmp_mcv = MCValue{ .register = tmp_reg };
88848927 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
......@@ -8971,6 +9014,7 @@ fn genVarDbgInfo(
89719014 //} },
89729015 .memory => |address| .{ .memory = address },
89739016 .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 } },
89749018 .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },
89759019 .immediate => |x| .{ .immediate = x },
89769020 .undef => .undef,
......@@ -9410,13 +9454,14 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
94109454 .indirect,
94119455 .lea_direct,
94129456 .lea_got,
9457 .lea_actual_got,
94139458 .lea_tlv,
94149459 .lea_frame,
94159460 .reserved_frame,
94169461 .air_ref,
94179462 => unreachable,
94189463 .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: {
94209465 switch (resolved_dst_mcv) {
94219466 .memory => |addr| if (math.cast(
94229467 i32,
......@@ -9425,7 +9470,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
94259470 i32,
94269471 @as(i64, @bitCast(addr)) + abi_size - 8,
94279472 ) != null) break :dst null,
9428 .load_got, .load_direct, .load_tlv => {},
9473 .load_got, .load_actual_got, .load_direct, .load_tlv => {},
94299474 else => unreachable,
94309475 }
94319476
......@@ -9468,13 +9513,14 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
94689513 .indirect,
94699514 .lea_direct,
94709515 .lea_got,
9516 .lea_actual_got,
94719517 .lea_tlv,
94729518 .lea_frame,
94739519 .reserved_frame,
94749520 .air_ref,
94759521 => unreachable,
94769522 .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: {
94789524 switch (resolved_src_mcv) {
94799525 .memory => |addr| if (math.cast(
94809526 i32,
......@@ -9483,7 +9529,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
94839529 i32,
94849530 @as(i64, @bitCast(addr)) + abi_size - 8,
94859531 ) != null) break :src null,
9486 .load_got, .load_direct, .load_tlv => {},
9532 .load_got, .load_actual_got, .load_direct, .load_tlv => {},
94879533 else => unreachable,
94889534 }
94899535
......@@ -9902,6 +9948,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
99029948 .register_overflow,
99039949 .lea_direct,
99049950 .lea_got,
9951 .lea_actual_got,
99059952 .lea_tlv,
99069953 .lea_frame,
99079954 .reserved_frame,
......@@ -9928,6 +9975,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
99289975
99299976 .memory,
99309977 .load_got,
9978 .load_actual_got,
99319979 .load_direct,
99329980 .load_tlv,
99339981 => {
......@@ -10485,7 +10533,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
1048510533 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |_|
1048610534 break :arg input_mcv,
1048710535 .indirect, .load_frame => break :arg input_mcv,
10488 .load_direct, .load_got, .load_tlv => {},
10536 .load_direct, .load_got, .load_actual_got, .load_tlv => {},
1048910537 else => {
1049010538 const temp_mcv = try self.allocTempRegOrMem(ty, false);
1049110539 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
1114611194 .register_overflow,
1114711195 .lea_direct,
1114811196 .lea_got,
11197 .lea_actual_got,
1114911198 .lea_tlv,
1115011199 .lea_frame,
1115111200 .reserved_frame,
......@@ -11197,11 +11246,11 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError
1119711246 }
1119811247 },
1119911248 .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 => {
1120111250 switch (dst_mcv) {
1120211251 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|
1120311252 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 => {},
1120511254 else => unreachable,
1120611255 }
1120711256
......@@ -11363,7 +11412,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
1136311412 else => unreachable,
1136411413 },
1136511414 )),
11366 .memory, .load_direct, .load_got, .load_tlv => {
11415 .memory, .load_direct, .load_got, .load_actual_got, .load_tlv => {
1136711416 switch (src_mcv) {
1136811417 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|
1136911418 return (try self.moveStrategy(
......@@ -11391,7 +11440,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
1139111440 },
1139211441 .Float, .Vector => {},
1139311442 },
11394 .load_got, .load_tlv => {},
11443 .load_got, .load_actual_got, .load_tlv => {},
1139511444 else => unreachable,
1139611445 }
1139711446
......@@ -11405,17 +11454,18 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
1140511454 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .{ .reg = addr_reg } }),
1140611455 );
1140711456 },
11408 .lea_direct, .lea_got => |sym_index| {
11457 .lea_direct, .lea_got, .lea_actual_got => |sym_index| {
1140911458 const atom_index = try self.owner.getSymbolIndex(self);
1141011459 _ = try self.addInst(.{
1141111460 .tag = switch (src_mcv) {
1141211461 .lea_direct => .lea,
11413 .lea_got => .mov,
11462 .lea_got, .lea_actual_got => .mov,
1141411463 else => unreachable,
1141511464 },
1141611465 .ops = switch (src_mcv) {
1141711466 .lea_direct => .direct_reloc,
1141811467 .lea_got => .got_reloc,
11468 .lea_actual_got => .actual_got_reloc,
1141911469 else => unreachable,
1142011470 },
1142111471 .data = .{ .rx = .{
......@@ -11551,6 +11601,8 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
1155111601 .lea_direct,
1155211602 .load_got,
1155311603 .lea_got,
11604 .load_actual_got,
11605 .lea_actual_got,
1155411606 .load_tlv,
1155511607 .lea_tlv,
1155611608 .load_frame,
......@@ -13556,6 +13608,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
1355613608 .memory => |addr| .{ .memory = addr },
1355713609 .load_direct => |sym_index| .{ .load_direct = sym_index },
1355813610 .load_got => |sym_index| .{ .lea_got = sym_index },
13611 .load_actual_got => |sym_index| .{ .lea_actual_got = sym_index },
1355913612 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
1356013613 },
1356113614 .fail => |msg| {
src/arch/x86_64/Emit.zig+3-1
......@@ -79,6 +79,7 @@ pub fn emitMir(emit: *Emit) Error!void {
7979 @tagName(emit.bin_file.tag),
8080 }),
8181 .linker_got,
82 .linker_actual_got,
8283 .linker_direct,
8384 .linker_direct_got,
8485 .linker_import,
......@@ -87,12 +88,13 @@ pub fn emitMir(emit: *Emit) Error!void {
8788 const r_type: u32 = switch (lowered_relocs[0].target) {
8889 .linker_direct_got => link.File.Elf.R_X86_64_ZIG_GOT32,
8990 .linker_got => link.File.Elf.R_X86_64_ZIG_GOTPCREL,
91 .linker_actual_got => std.elf.R_X86_64_GOTPCREL,
9092 .linker_direct => std.elf.R_X86_64_PC32,
9193 else => unreachable,
9294 };
9395 const r_addend: i64 = switch (lowered_relocs[0].target) {
9496 .linker_direct_got => 0,
95 .linker_got, .linker_direct => -4,
97 .linker_got, .linker_actual_got, .linker_direct => -4,
9698 else => unreachable,
9799 };
98100 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 {
5151 inst: Mir.Inst.Index,
5252 linker_extern_fn: Mir.Reloc,
5353 linker_got: Mir.Reloc,
54 linker_actual_got: Mir.Reloc,
5455 linker_direct: Mir.Reloc,
5556 linker_direct_got: Mir.Reloc,
5657 linker_import: Mir.Reloc,
......@@ -388,7 +389,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
388389 .rrmi_sib, .rrmi_rip => inst.data.rrix.fixes,
389390 .mi_sib_u, .mi_rip_u, .mi_sib_s, .mi_rip_s => inst.data.x.fixes,
390391 .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 => ._,
392393 else => return lower.fail("TODO lower .{s}", .{@tagName(inst.ops)}),
393394 };
394395 try lower.emit(switch (fixes) {
......@@ -532,11 +533,12 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
532533 else => unreachable,
533534 }
534535 },
535 .got_reloc, .direct_reloc, .import_reloc, .tlv_reloc => ops: {
536 .got_reloc, .actual_got_reloc, .direct_reloc, .import_reloc, .tlv_reloc => ops: {
536537 const reg = inst.data.rx.r1;
537538 const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;
538539 _ = lower.reloc(switch (inst.ops) {
539540 .got_reloc => .{ .linker_got = extra },
541 .actual_got_reloc => .{ .linker_actual_got = extra },
540542 .direct_reloc => .{ .linker_direct = extra },
541543 .import_reloc => .{ .linker_import = extra },
542544 .tlv_reloc => .{ .linker_tlv = extra },
src/arch/x86_64/Mir.zig+2
......@@ -783,6 +783,8 @@ pub const Inst = struct {
783783 /// Linker relocation - GOT indirection.
784784 /// Uses `rx` payload with extra data of type `Reloc`.
785785 got_reloc,
786 /// TODO
787 actual_got_reloc,
786788 /// Linker relocation - direct reference.
787789 /// Uses `rx` payload with extra data of type `Reloc`.
788790 direct_reloc,
src/codegen.zig+10
......@@ -798,6 +798,7 @@ fn lowerDeclRef(
798798pub const LinkerLoad = struct {
799799 type: enum {
800800 got,
801 actual_got,
801802 direct,
802803 import,
803804 },
......@@ -827,6 +828,8 @@ pub const GenResult = union(enum) {
827828 load_got: u32,
828829 /// Direct by-address reference to memory location.
829830 memory: u64,
831 /// TODO LOL Jakub, the king of naming...
832 load_actual_got: u32,
830833 };
831834
832835 fn mcv(val: MCValue) GenResult {
......@@ -885,8 +888,15 @@ fn genDeclRef(
885888 try mod.markDeclAlive(decl);
886889
887890 const is_threadlocal = tv.val.isPtrToThreadLocal(mod) and !bin_file.options.single_threaded;
891 const is_extern = decl.isExtern(mod);
888892
889893 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 }
890900 const sym_index = try elf_file.getOrCreateMetadataForDecl(decl_index);
891901 const sym = elf_file.symbol(sym_index);
892902 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
src/link/Dwarf.zig+1
......@@ -1389,6 +1389,7 @@ pub fn commitDeclState(
13891389 .prev_vaddr = 0,
13901390 });
13911391 },
1392 .elf => {}, // TODO
13921393 else => unreachable,
13931394 }
13941395 }
src/link/Elf.zig+9-5
......@@ -3196,12 +3196,16 @@ pub fn updateDecl(
31963196 const decl = mod.declPtr(decl_index);
31973197
31983198 if (decl.val.getExternFunc(mod)) |_| {
3199 return; // TODO Should we do more when front-end analyzed extern decl?
3199 return;
32003200 }
3201 if (decl.val.getVariable(mod)) |variable| {
3202 if (variable.is_extern) {
3203 return; // TODO Should we do more when front-end analyzed extern decl?
3204 }
3201
3202 if (decl.isExtern(mod)) {
3203 // Extern variable gets a .got entry only.
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;
32053209 }
32063210
32073211 const sym_index = try self.getOrCreateMetadataForDecl(decl_index);