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
40124012 .got => .load_memory_ptr_got,
40134013 .direct => .load_memory_ptr_direct,
40144014 .import => unreachable,
4015 .extern_got => unreachable,
40164015 };
40174016 const atom_index = switch (self.bin_file.tag) {
40184017 .macho => blk: {
......@@ -5532,7 +5531,6 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
55325531 .got => .load_memory_ptr_got,
55335532 .direct => .load_memory_ptr_direct,
55345533 .import => unreachable,
5535 .extern_got => unreachable,
55365534 };
55375535 const atom_index = switch (self.bin_file.tag) {
55385536 .macho => blk: {
......@@ -5654,7 +5652,6 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
56545652 .got => .load_memory_got,
56555653 .direct => .load_memory_direct,
56565654 .import => .load_memory_import,
5657 .extern_got => unreachable,
56585655 };
56595656 const atom_index = switch (self.bin_file.tag) {
56605657 .macho => blk: {
......@@ -5852,7 +5849,6 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
58525849 .got => .load_memory_ptr_got,
58535850 .direct => .load_memory_ptr_direct,
58545851 .import => unreachable,
5855 .extern_got => unreachable,
58565852 };
58575853 const atom_index = switch (self.bin_file.tag) {
58585854 .macho => blk: {
......@@ -6180,7 +6176,7 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
61806176 .memory => |addr| .{ .memory = addr },
61816177 .load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } },
61826178 .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },
6183 .load_extern_got, .load_tlv => unreachable, // TODO
6179 .load_memory, .lea_memory, .load_tlv => unreachable, // TODO
61846180 },
61856181 .fail => |msg| {
61866182 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_extern_got, .load_direct, .load_tlv => unreachable, // TODO
6138 .load_got, .load_memory, .lea_memory, .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_extern_got, .load_direct, .load_tlv => unreachable, // TODO
2594 .load_got, .load_memory, .lea_memory, .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_extern_got, .load_direct, .load_tlv => unreachable, // TODO
4140 .load_got, .load_memory, .lea_memory, .load_direct, .load_tlv => unreachable, // TODO
41414141 .immediate => |imm| .{ .immediate = imm },
41424142 .memory => |addr| .{ .memory = addr },
41434143 },
src/arch/x86_64/CodeGen.zig+124-97
......@@ -193,6 +193,11 @@ pub const MCValue = union(enum) {
193193 /// The value is in memory at a hard-coded address.
194194 /// If the type is a pointer, it means the pointer address is stored at this memory location.
195195 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,
196201 /// The value is in memory at a constant offset from the address in a register.
197202 indirect: RegisterOffset,
198203 /// The value is in memory.
......@@ -207,12 +212,6 @@ pub const MCValue = union(enum) {
207212 /// The value is a pointer to a value referenced indirectly via GOT.
208213 /// Payload is a symbol index.
209214 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,
216215 /// The value is a threadlocal variable.
217216 /// Payload is a symbol index.
218217 load_tlv: u32,
......@@ -299,9 +298,9 @@ pub const MCValue = union(enum) {
299298 .register_pair,
300299 .register_offset,
301300 .register_overflow,
301 .lea_memory,
302302 .lea_direct,
303303 .lea_got,
304 .lea_extern_got,
305304 .lea_tlv,
306305 .lea_frame,
307306 .reserved_frame,
......@@ -315,8 +314,8 @@ pub const MCValue = union(enum) {
315314 .load_direct => |sym_index| .{ .lea_direct = sym_index },
316315 .load_got => |sym_index| .{ .lea_got = sym_index },
317316 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
318 .load_extern_got => |sym_index| .{ .lea_extern_got = sym_index },
319317 .load_frame => |frame_addr| .{ .lea_frame = frame_addr },
318 .load_memory => |sym_index| .{ .lea_memory = sym_index },
320319 };
321320 }
322321
......@@ -333,9 +332,9 @@ pub const MCValue = union(enum) {
333332 .indirect,
334333 .load_direct,
335334 .load_got,
336 .load_extern_got,
337335 .load_tlv,
338336 .load_frame,
337 .load_memory,
339338 .reserved_frame,
340339 .air_ref,
341340 => unreachable, // not dereferenceable
......@@ -344,9 +343,9 @@ pub const MCValue = union(enum) {
344343 .register_offset => |reg_off| .{ .indirect = reg_off },
345344 .lea_direct => |sym_index| .{ .load_direct = sym_index },
346345 .lea_got => |sym_index| .{ .load_got = sym_index },
347 .lea_extern_got => |sym_index| .{ .load_extern_got = sym_index },
348346 .lea_tlv => |sym_index| .{ .load_tlv = sym_index },
349347 .lea_frame => |frame_addr| .{ .load_frame = frame_addr },
348 .lea_memory => |sym_index| .{ .load_memory = sym_index },
350349 };
351350 }
352351
......@@ -368,11 +367,11 @@ pub const MCValue = union(enum) {
368367 .lea_direct,
369368 .load_got,
370369 .lea_got,
371 .load_extern_got,
372 .lea_extern_got,
373370 .load_tlv,
374371 .lea_tlv,
375372 .load_frame,
373 .load_memory,
374 .lea_memory,
376375 => switch (off) {
377376 0 => mcv,
378377 else => unreachable, // not offsettable
......@@ -404,13 +403,13 @@ pub const MCValue = union(enum) {
404403 .lea_direct,
405404 .load_got,
406405 .lea_got,
407 .load_extern_got,
408 .lea_extern_got,
409406 .load_tlv,
410407 .lea_tlv,
411408 .lea_frame,
412409 .reserved_frame,
413410 .air_ref,
411 .load_memory,
412 .lea_memory,
414413 => unreachable,
415414 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|
416415 Memory.sib(ptr_size, .{ .base = .{ .reg = .ds }, .disp = small_addr })
......@@ -448,14 +447,14 @@ pub const MCValue = union(enum) {
448447 .lea_direct => |pl| try writer.print("direct:{d}", .{pl}),
449448 .load_got => |pl| try writer.print("[got:{d}]", .{pl}),
450449 .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}),
453450 .load_tlv => |pl| try writer.print("[tlv:{d}]", .{pl}),
454451 .lea_tlv => |pl| try writer.print("tlv:{d}", .{pl}),
455452 .load_frame => |pl| try writer.print("[{} + 0x{x}]", .{ pl.index, pl.off }),
456453 .lea_frame => |pl| try writer.print("{} + 0x{x}", .{ pl.index, pl.off }),
457454 .reserved_frame => |pl| try writer.print("(dead:{})", .{pl}),
458455 .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}),
459458 }
460459 }
461460};
......@@ -477,12 +476,12 @@ const InstTracking = struct {
477476 .lea_direct,
478477 .load_got,
479478 .lea_got,
480 .load_extern_got,
481 .lea_extern_got,
482479 .load_tlv,
483480 .lea_tlv,
484481 .load_frame,
485482 .lea_frame,
483 .load_memory,
484 .lea_memory,
486485 => result,
487486 .dead,
488487 .reserved_frame,
......@@ -538,12 +537,12 @@ const InstTracking = struct {
538537 .lea_direct,
539538 .load_got,
540539 .lea_got,
541 .load_extern_got,
542 .lea_extern_got,
543540 .load_tlv,
544541 .lea_tlv,
545542 .load_frame,
546543 .lea_frame,
544 .load_memory,
545 .lea_memory,
547546 => self.long,
548547 .dead,
549548 .eflags,
......@@ -575,11 +574,11 @@ const InstTracking = struct {
575574 .lea_direct,
576575 .load_got,
577576 .lea_got,
578 .load_extern_got,
579 .lea_extern_got,
580577 .load_tlv,
581578 .lea_tlv,
582579 .lea_frame,
580 .load_memory,
581 .lea_memory,
583582 => assert(std.meta.eql(self.long, target.long)),
584583 .load_frame,
585584 .reserved_frame,
......@@ -883,6 +882,7 @@ pub fn generate(
883882
884883 var emit = Emit{
885884 .lower = .{
885 .bin_file = bin_file,
886886 .allocator = bin_file.allocator,
887887 .mir = mir,
888888 .cc = cc,
......@@ -970,6 +970,7 @@ pub fn generateLazy(
970970
971971 var emit = Emit{
972972 .lower = .{
973 .bin_file = bin_file,
973974 .allocator = bin_file.allocator,
974975 .mir = mir,
975976 .cc = abi.resolveCallingConvention(.Unspecified, function.target.*),
......@@ -1060,6 +1061,7 @@ fn formatWipMir(
10601061 writer: anytype,
10611062) @TypeOf(writer).Error!void {
10621063 var lower = Lower{
1064 .bin_file = data.self.bin_file,
10631065 .allocator = data.self.gpa,
10641066 .mir = .{
10651067 .instructions = data.self.mir_instructions.slice(),
......@@ -4729,12 +4731,12 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
47294731 Memory.sib(.qword, .{ .base = .{ .frame = frame_addr.index }, .disp = frame_addr.off }),
47304732 ),
47314733 .memory,
4734 .load_memory,
47324735 .load_direct,
47334736 .load_got,
4734 .load_extern_got,
47354737 .load_tlv,
47364738 => try self.genSetReg(addr_reg, Type.usize, array.address()),
4737 .lea_direct, .lea_tlv => unreachable,
4739 .lea_memory, .lea_direct, .lea_tlv => unreachable,
47384740 else => return self.fail("TODO implement array_elem_val when array is {}", .{array}),
47394741 }
47404742
......@@ -6327,17 +6329,17 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro
63276329 .immediate,
63286330 .register,
63296331 .register_offset,
6332 .lea_memory,
63306333 .lea_direct,
63316334 .lea_got,
6332 .lea_extern_got,
63336335 .lea_tlv,
63346336 .lea_frame,
63356337 => try self.genCopy(dst_ty, dst_mcv, ptr_mcv.deref()),
63366338 .memory,
63376339 .indirect,
6340 .load_memory,
63386341 .load_direct,
63396342 .load_got,
6340 .load_extern_got,
63416343 .load_tlv,
63426344 .load_frame,
63436345 => {
......@@ -6476,17 +6478,17 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr
64766478 .immediate,
64776479 .register,
64786480 .register_offset,
6481 .lea_memory,
64796482 .lea_direct,
64806483 .lea_got,
6481 .lea_extern_got,
64826484 .lea_tlv,
64836485 .lea_frame,
64846486 => try self.genCopy(src_ty, ptr_mcv.deref(), src_mcv),
64856487 .memory,
64866488 .indirect,
6489 .load_memory,
64876490 .load_direct,
64886491 .load_got,
6489 .load_extern_got,
64906492 .load_tlv,
64916493 .load_frame,
64926494 => {
......@@ -6913,15 +6915,15 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MC
69136915 .register_overflow,
69146916 .lea_direct,
69156917 .lea_got,
6916 .lea_extern_got,
69176918 .lea_tlv,
69186919 .lea_frame,
69196920 .reserved_frame,
69206921 .air_ref,
6922 .lea_memory,
69216923 => unreachable, // unmodifiable destination
69226924 .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)),
69236925 .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 => {
69256927 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
69266928 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
69276929 defer self.register_manager.unlockReg(addr_reg_lock);
......@@ -7973,12 +7975,12 @@ fn genBinOp(
79737975 .immediate,
79747976 .eflags,
79757977 .register_offset,
7978 .load_memory,
7979 .lea_memory,
79767980 .load_direct,
79777981 .lea_direct,
79787982 .load_got,
79797983 .lea_got,
7980 .load_extern_got,
7981 .lea_extern_got,
79827984 .load_tlv,
79837985 .lea_tlv,
79847986 .lea_frame,
......@@ -8031,12 +8033,12 @@ fn genBinOp(
80318033 .register_pair,
80328034 .register_offset,
80338035 .register_overflow,
8036 .load_memory,
8037 .lea_memory,
80348038 .load_direct,
80358039 .lea_direct,
80368040 .load_got,
80378041 .lea_got,
8038 .load_extern_got,
8039 .lea_extern_got,
80408042 .load_tlv,
80418043 .lea_tlv,
80428044 .lea_frame,
......@@ -9164,9 +9166,9 @@ fn genBinOpMir(
91649166 .register_overflow,
91659167 .lea_direct,
91669168 .lea_got,
9167 .lea_extern_got,
91689169 .lea_tlv,
91699170 .lea_frame,
9171 .lea_memory,
91709172 .reserved_frame,
91719173 .air_ref,
91729174 => unreachable, // unmodifiable destination
......@@ -9249,12 +9251,12 @@ fn genBinOpMir(
92499251 .register_offset,
92509252 .memory,
92519253 .indirect,
9254 .load_memory,
9255 .lea_memory,
92529256 .load_direct,
92539257 .lea_direct,
92549258 .load_got,
92559259 .lea_got,
9256 .load_extern_got,
9257 .lea_extern_got,
92589260 .load_tlv,
92599261 .lea_tlv,
92609262 .load_frame,
......@@ -9285,9 +9287,9 @@ fn genBinOpMir(
92859287 switch (src_mcv) {
92869288 .eflags,
92879289 .register_offset,
9290 .lea_memory,
92889291 .lea_direct,
92899292 .lea_got,
9290 .lea_extern_got,
92919293 .lea_tlv,
92929294 .lea_frame,
92939295 => {
......@@ -9301,9 +9303,9 @@ fn genBinOpMir(
93019303 );
93029304 },
93039305 .memory,
9306 .load_memory,
93049307 .load_direct,
93059308 .load_got,
9306 .load_extern_got,
93079309 .load_tlv,
93089310 => {
93099311 const ptr_ty = try mod.singleConstPtrType(ty);
......@@ -9324,13 +9326,13 @@ fn genBinOpMir(
93249326 }
93259327 }
93269328 },
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 => {
93289330 const OpInfo = ?struct { addr_reg: Register, addr_lock: RegisterLock };
93299331 const limb_abi_size: u32 = @min(abi_size, 8);
93309332
93319333 const dst_info: OpInfo = switch (dst_mcv) {
93329334 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: {
93349336 const dst_addr_reg =
93359337 (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64();
93369338 const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg);
......@@ -9364,17 +9366,17 @@ fn genBinOpMir(
93649366 .indirect,
93659367 .lea_direct,
93669368 .lea_got,
9367 .lea_extern_got,
93689369 .lea_tlv,
93699370 .load_frame,
93709371 .lea_frame,
9372 .lea_memory,
93719373 => null,
9372 .memory, .load_got, .load_extern_got, .load_direct, .load_tlv => src: {
9374 .memory, .load_memory, .load_got, .load_direct, .load_tlv => src: {
93739375 switch (resolved_src_mcv) {
93749376 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr))) != null and
93759377 math.cast(i32, @as(i64, @bitCast(addr)) + abi_size - limb_abi_size) != null)
93769378 break :src null,
9377 .load_got, .load_extern_got, .load_direct, .load_tlv => {},
9379 .load_memory, .load_got, .load_direct, .load_tlv => {},
93789380 else => unreachable,
93799381 }
93809382
......@@ -9416,8 +9418,8 @@ fn genBinOpMir(
94169418 Memory.PtrSize.fromSize(limb_abi_size),
94179419 switch (dst_mcv) {
94189420 .memory,
9421 .load_memory,
94199422 .load_got,
9420 .load_extern_got,
94219423 .load_direct,
94229424 .load_tlv,
94239425 => .{ .base = .{ .reg = dst_info.?.addr_reg }, .disp = off },
......@@ -9498,12 +9500,12 @@ fn genBinOpMir(
94989500 .eflags,
94999501 .memory,
95009502 .indirect,
9503 .load_memory,
9504 .lea_memory,
95019505 .load_direct,
95029506 .lea_direct,
95039507 .load_got,
95049508 .lea_got,
9505 .load_extern_got,
9506 .lea_extern_got,
95079509 .load_tlv,
95089510 .lea_tlv,
95099511 .load_frame,
......@@ -9517,9 +9519,9 @@ fn genBinOpMir(
95179519 },
95189520 .eflags,
95199521 .register_offset,
9522 .lea_memory,
95209523 .lea_direct,
95219524 .lea_got,
9522 .lea_extern_got,
95239525 .lea_tlv,
95249526 .lea_frame,
95259527 => switch (limb_i) {
......@@ -9568,9 +9570,9 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
95689570 .eflags,
95699571 .register_offset,
95709572 .register_overflow,
9573 .lea_memory,
95719574 .lea_direct,
95729575 .lea_got,
9573 .lea_extern_got,
95749576 .lea_tlv,
95759577 .lea_frame,
95769578 .reserved_frame,
......@@ -9615,12 +9617,12 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
96159617 },
96169618 .register_offset,
96179619 .eflags,
9620 .load_memory,
9621 .lea_memory,
96189622 .load_direct,
96199623 .lea_direct,
96209624 .load_got,
96219625 .lea_got,
9622 .load_extern_got,
9623 .lea_extern_got,
96249626 .load_tlv,
96259627 .lea_tlv,
96269628 .lea_frame,
......@@ -9659,7 +9661,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
96599661 }
96609662 },
96619663 .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 => {
96639665 const tmp_reg = try self.copyToTmpRegister(dst_ty, dst_mcv);
96649666 const tmp_mcv = MCValue{ .register = tmp_reg };
96659667 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
......@@ -9759,8 +9761,8 @@ fn genVarDbgInfo(
97599761 // .offset = -off,
97609762 //} },
97619763 .memory => |address| .{ .memory = address },
9764 .load_memory => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } }, // TODO
97629765 .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 } },
97649766 .load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },
97659767 .immediate => |x| .{ .immediate = x },
97669768 .undef => .undef,
......@@ -10011,12 +10013,12 @@ fn genCall(self: *Self, info: union(enum) {
1001110013 const sym = elf_file.symbol(sym_index);
1001210014 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
1001310015 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 });
1001510017 try self.asmRegister(.{ ._, .call }, .rax);
1001610018 } else {
1001710019 _ = try self.addInst(.{
1001810020 .tag = .call,
10019 .ops = .direct_got_reloc,
10021 .ops = .linker_reloc,
1002010022 .data = .{ .reloc = .{
1002110023 .atom_index = try self.owner.getSymbolIndex(self),
1002210024 .sym_index = sym.esym_index,
......@@ -10241,14 +10243,14 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
1024110243 .indirect,
1024210244 .lea_direct,
1024310245 .lea_got,
10244 .lea_extern_got,
1024510246 .lea_tlv,
1024610247 .lea_frame,
10248 .lea_memory,
1024710249 .reserved_frame,
1024810250 .air_ref,
1024910251 => unreachable,
1025010252 .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: {
1025210254 switch (resolved_dst_mcv) {
1025310255 .memory => |addr| if (math.cast(
1025410256 i32,
......@@ -10257,7 +10259,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
1025710259 i32,
1025810260 @as(i64, @bitCast(addr)) + abi_size - 8,
1025910261 ) != null) break :dst null,
10260 .load_got, .load_extern_got, .load_direct, .load_tlv => {},
10262 .load_memory, .load_got, .load_direct, .load_tlv => {},
1026110263 else => unreachable,
1026210264 }
1026310265
......@@ -10298,16 +10300,16 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
1029810300 .register_offset,
1029910301 .register_overflow,
1030010302 .indirect,
10303 .lea_memory,
1030110304 .lea_direct,
1030210305 .lea_got,
10303 .lea_extern_got,
1030410306 .lea_tlv,
1030510307 .lea_frame,
1030610308 .reserved_frame,
1030710309 .air_ref,
1030810310 => unreachable,
1030910311 .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: {
1031110313 switch (resolved_src_mcv) {
1031210314 .memory => |addr| if (math.cast(
1031310315 i32,
......@@ -10316,7 +10318,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
1031610318 i32,
1031710319 @as(i64, @bitCast(addr)) + abi_size - 8,
1031810320 ) != null) break :src null,
10319 .load_got, .load_extern_got, .load_direct, .load_tlv => {},
10321 .load_memory, .load_got, .load_direct, .load_tlv => {},
1032010322 else => unreachable,
1032110323 }
1032210324
......@@ -10739,9 +10741,9 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
1073910741 .register_overflow,
1074010742 .lea_direct,
1074110743 .lea_got,
10742 .lea_extern_got,
1074310744 .lea_tlv,
1074410745 .lea_frame,
10746 .lea_memory,
1074510747 .reserved_frame,
1074610748 .air_ref,
1074710749 => unreachable,
......@@ -10765,8 +10767,8 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
1076510767 },
1076610768
1076710769 .memory,
10770 .load_memory,
1076810771 .load_got,
10769 .load_extern_got,
1077010772 .load_direct,
1077110773 .load_tlv,
1077210774 => {
......@@ -11363,7 +11365,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
1136311365 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |_|
1136411366 break :arg input_mcv,
1136511367 .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 => {},
1136711369 else => {
1136811370 const temp_mcv = try self.allocTempRegOrMem(ty, false);
1136911371 try self.genCopy(ty, temp_mcv, input_mcv);
......@@ -11625,6 +11627,10 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
1162511627 .{ .reg = try self.copyToTmpRegister(Type.usize, .{ .lea_got = sym_index }) }
1162611628 else
1162711629 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}),
1162811634 else => return self.fail("invalid constraint: '{s}'", .{op_str}),
1162911635 };
1163011636 } else if (mem.startsWith(u8, op_str, "$")) {
......@@ -12178,9 +12184,9 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError
1217812184 .register_overflow,
1217912185 .lea_direct,
1218012186 .lea_got,
12181 .lea_extern_got,
1218212187 .lea_tlv,
1218312188 .lea_frame,
12189 .lea_memory,
1218412190 .reserved_frame,
1218512191 .air_ref,
1218612192 => unreachable, // unmodifiable destination
......@@ -12236,6 +12242,12 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError
1223612242 class_ty,
1223712243 .{ .register = src_regs[dst_reg_i] },
1223812244 ),
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 },
1223912251 .memory, .indirect, .load_frame => try self.genSetReg(
1224012252 dst_reg,
1224112253 class_ty,
......@@ -12251,11 +12263,11 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError
1225112263 }
1225212264 },
1225312265 .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 => {
1225512267 switch (dst_mcv) {
1225612268 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|
1225712269 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 => {},
1225912271 else => unreachable,
1226012272 }
1226112273
......@@ -12431,7 +12443,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
1243112443 else => unreachable,
1243212444 },
1243312445 )),
12434 .memory, .load_direct, .load_got, .load_extern_got, .load_tlv => {
12446 .memory, .load_memory, .load_direct, .load_got, .load_tlv => {
1243512447 switch (src_mcv) {
1243612448 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|
1243712449 return (try self.moveStrategy(
......@@ -12461,7 +12473,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
1246112473 .segment, .mmx => unreachable,
1246212474 .x87, .sse => {},
1246312475 },
12464 .load_got, .load_extern_got, .load_tlv => {},
12476 .load_memory, .load_got, .load_tlv => {},
1246512477 else => unreachable,
1246612478 }
1246712479
......@@ -12475,28 +12487,42 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
1247512487 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .{ .reg = addr_reg } }),
1247612488 );
1247712489 },
12478 .lea_direct, .lea_got, .lea_extern_got => |sym_index| {
12490 .lea_memory, .lea_direct, .lea_got => |sym_index| {
1247912491 const atom_index = try self.owner.getSymbolIndex(self);
12480 _ = try self.addInst(.{
12481 .tag = switch (src_mcv) {
12482 .lea_direct => .lea,
12483 .lea_got, .lea_extern_got => .mov,
12484 else => unreachable,
12485 },
12486 .ops = switch (src_mcv) {
12487 .lea_direct => .direct_reloc,
12488 .lea_got => .got_reloc,
12489 .lea_extern_got => .extern_got_reloc,
12490 else => unreachable,
12491 },
12492 .data = .{ .rx = .{
12493 .r1 = dst_reg.to64(),
12494 .payload = try self.addExtra(Mir.Reloc{
12495 .atom_index = atom_index,
12496 .sym_index = sym_index,
12497 }),
12498 } },
12499 });
12492 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
12493 const sym = elf_file.symbol(elf_file.zigModulePtr().symbol(sym_index));
12494 _ = try self.addInst(.{
12495 .tag = if (sym.flags.has_zig_got) .mov else .lea,
12496 .ops = .linker_reloc,
12497 .data = .{ .rx = .{
12498 .r1 = dst_reg.to64(),
12499 .payload = try self.addExtra(Mir.Reloc{
12500 .atom_index = atom_index,
12501 .sym_index = sym_index,
12502 }),
12503 } },
12504 });
12505 } else {
12506 _ = try self.addInst(.{
12507 .tag = switch (src_mcv) {
12508 .lea_direct => .lea,
12509 .lea_got => .mov,
12510 else => unreachable,
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 }
1250012526 },
1250112527 .lea_tlv => |sym_index| {
1250212528 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
1264512671 .lea_direct,
1264612672 .load_got,
1264712673 .lea_got,
12648 .load_extern_got,
12649 .lea_extern_got,
1265012674 .load_tlv,
1265112675 .lea_tlv,
1265212676 .load_frame,
1265312677 .lea_frame,
12678 .load_memory,
12679 .lea_memory,
1265412680 => switch (abi_size) {
1265512681 0 => {},
1265612682 1, 2, 4, 8 => {
......@@ -12741,8 +12767,8 @@ fn genLazySymbolRef(
1274112767
1274212768 if (self.bin_file.options.pic) {
1274312769 switch (tag) {
12744 .lea, .call => try self.genSetReg(reg, Type.usize, .{ .lea_got = sym.esym_index }),
12745 .mov => try self.genSetReg(reg, Type.usize, .{ .load_got = sym.esym_index }),
12770 .lea, .call => try self.genSetReg(reg, Type.usize, .{ .lea_memory = sym.esym_index }),
12771 .mov => try self.genSetReg(reg, Type.usize, .{ .load_memory = sym.esym_index }),
1274612772 else => unreachable,
1274712773 }
1274812774 switch (tag) {
......@@ -12758,7 +12784,7 @@ fn genLazySymbolRef(
1275812784 switch (tag) {
1275912785 .lea, .mov => _ = try self.addInst(.{
1276012786 .tag = .mov,
12761 .ops = .direct_got_reloc,
12787 .ops = .linker_reloc,
1276212788 .data = .{ .rx = .{
1276312789 .r1 = reg.to64(),
1276412790 .payload = try self.addExtra(reloc),
......@@ -12766,7 +12792,7 @@ fn genLazySymbolRef(
1276612792 }),
1276712793 .call => _ = try self.addInst(.{
1276812794 .tag = .call,
12769 .ops = .direct_got_reloc,
12795 .ops = .linker_reloc,
1277012796 .data = .{ .reloc = reloc },
1277112797 }),
1277212798 else => unreachable,
......@@ -14716,9 +14742,10 @@ fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
1471614742 .undef => .undef,
1471714743 .immediate => |imm| .{ .immediate = imm },
1471814744 .memory => |addr| .{ .memory = addr },
14745 .load_memory => |sym_index| .{ .load_memory = sym_index },
14746 .lea_memory => |sym_index| .{ .lea_memory = sym_index },
1471914747 .load_direct => |sym_index| .{ .load_direct = sym_index },
1472014748 .load_got => |sym_index| .{ .lea_got = sym_index },
14721 .load_extern_got => |sym_index| .{ .lea_extern_got = sym_index },
1472214749 .load_tlv => |sym_index| .{ .lea_tlv = sym_index },
1472314750 },
1472414751 .fail => |msg| {
src/arch/x86_64/Emit.zig+31-21
......@@ -78,31 +78,41 @@ pub fn emitMir(emit: *Emit) Error!void {
7878 } else return emit.fail("TODO implement extern reloc for {s}", .{
7979 @tagName(emit.bin_file.tag),
8080 }),
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,
81110 .linker_got,
82 .linker_extern_got,
83111 .linker_direct,
84 .linker_direct_got,
85112 .linker_import,
86113 .linker_tlv,
87 => |symbol| if (emit.bin_file.cast(link.File.Elf)) |elf_file| {
88 const r_type: u32 = switch (lowered_relocs[0].target) {
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 });
114 => |symbol| if (emit.bin_file.cast(link.File.Elf)) |_| {
115 unreachable;
106116 } else if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
107117 const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = symbol.atom_index }).?;
108118 try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
src/arch/x86_64/Lower.zig+42-24
......@@ -1,5 +1,6 @@
11//! This file contains the functionality for lowering x86_64 MIR to Instructions
22
3bin_file: *link.File,
34allocator: Allocator,
45mir: Mir,
56cc: std.builtin.CallingConvention,
......@@ -49,11 +50,10 @@ pub const Reloc = struct {
4950
5051 const Target = union(enum) {
5152 inst: Mir.Inst.Index,
53 linker_reloc: Mir.Reloc,
5254 linker_extern_fn: Mir.Reloc,
5355 linker_got: Mir.Reloc,
54 linker_extern_got: Mir.Reloc,
5556 linker_direct: Mir.Reloc,
56 linker_direct_got: Mir.Reloc,
5757 linker_import: Mir.Reloc,
5858 linker_tlv: Mir.Reloc,
5959 };
......@@ -407,10 +407,9 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
407407 .mi_sib_u, .mi_rip_u, .mi_sib_s, .mi_rip_s => inst.data.x.fixes,
408408 .m_sib, .m_rip, .rax_moffs, .moffs_rax => inst.data.x.fixes,
409409 .extern_fn_reloc,
410 .linker_reloc,
410411 .got_reloc,
411 .extern_got_reloc,
412412 .direct_reloc,
413 .direct_got_reloc,
414413 .import_reloc,
415414 .tlv_reloc,
416415 => ._,
......@@ -545,32 +544,50 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
545544 .extern_fn_reloc => &.{
546545 .{ .imm = lower.reloc(.{ .linker_extern_fn = inst.data.reloc }) },
547546 },
548 .direct_got_reloc => ops: {
549 switch (inst.tag) {
550 .call => {
551 _ = lower.reloc(.{ .linker_direct_got = inst.data.reloc });
552 break :ops &.{
553 .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) },
554 };
555 },
556 .mov => {
557 const reg = inst.data.rx.r1;
558 const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;
559 _ = lower.reloc(.{ .linker_direct_got = extra });
560 break :ops &.{
561 .{ .reg = reg },
562 .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) },
563 };
564 },
565 else => unreachable,
547 .linker_reloc => ops: {
548 if (lower.bin_file.options.pic) {
549 const reg = inst.data.rx.r1;
550 const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;
551 _ = lower.reloc(.{ .linker_reloc = extra });
552 break :ops &.{
553 .{ .reg = reg },
554 .{ .mem = Memory.rip(Memory.PtrSize.fromBitSize(reg.bitSize()), 0) },
555 };
556 } else {
557 switch (inst.tag) {
558 .call => {
559 _ = lower.reloc(.{ .linker_reloc = inst.data.reloc });
560 break :ops &.{
561 .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .ds }, .disp = 0 }) },
562 };
563 },
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 }
566584 }
567585 },
568 .got_reloc, .extern_got_reloc, .direct_reloc, .import_reloc, .tlv_reloc => ops: {
586 .got_reloc, .direct_reloc, .import_reloc, .tlv_reloc => ops: {
569587 const reg = inst.data.rx.r1;
570588 const extra = lower.mir.extraData(Mir.Reloc, inst.data.rx.payload).data;
571589 _ = lower.reloc(switch (inst.ops) {
572590 .got_reloc => .{ .linker_got = extra },
573 .extern_got_reloc => .{ .linker_extern_got = extra },
574591 .direct_reloc => .{ .linker_direct = extra },
575592 .import_reloc => .{ .linker_import = extra },
576593 .tlv_reloc => .{ .linker_tlv = extra },
......@@ -601,6 +618,7 @@ const abi = @import("abi.zig");
601618const assert = std.debug.assert;
602619const bits = @import("bits.zig");
603620const encoder = @import("encoder.zig");
621const link = @import("../../link.zig");
604622const std = @import("std");
605623
606624const Air = @import("../../Air.zig");
src/arch/x86_64/Mir.zig+3-6
......@@ -854,9 +854,6 @@ pub const Inst = struct {
854854 /// Linker relocation - GOT indirection.
855855 /// Uses `rx` payload with extra data of type `Reloc`.
856856 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,
860857 /// Linker relocation - direct reference.
861858 /// Uses `rx` payload with extra data of type `Reloc`.
862859 direct_reloc,
......@@ -866,9 +863,9 @@ pub const Inst = struct {
866863 /// Linker relocation - threadlocal variable via GOT indirection.
867864 /// Uses `rx` payload with extra data of type `Reloc`.
868865 tlv_reloc,
869 /// Linker relocation - non-PIC direct reference to GOT cell.
870 /// Uses `reloc` payload if tag is `call`, `rx` otherwise.
871 direct_got_reloc,
866 /// Linker relocation.
867 /// Uses `rx` payload with extra data of type `Reloc`.
868 linker_reloc,
872869
873870 // Pseudo instructions:
874871
src/codegen.zig+8-15
......@@ -791,13 +791,11 @@ fn lowerDeclRef(
791791
792792/// Helper struct to denote that the value is in memory but requires a linker relocation fixup:
793793/// * 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
795794/// * direct - the value is referenced directly via symbol index index (the linker emits a displacement reloc)
796795/// * import - the value is referenced indirectly via import entry index (the linker emits an import-type reloc)
797796pub const LinkerLoad = struct {
798797 type: enum {
799798 got,
800 extern_got,
801799 direct,
802800 import,
803801 },
......@@ -827,8 +825,10 @@ pub const GenResult = union(enum) {
827825 load_got: u32,
828826 /// Direct by-address reference to memory location.
829827 memory: u64,
830 /// Pointer to extern variable via GOT.
831 load_extern_got: u32,
828 /// Reference to memory location but deferred until linker allocated the Decl in memory.
829 /// Traditionally, this corresponds to emitting a relocation in a relocatable object file.
830 load_memory: u32,
831 lea_memory: u32,
832832 };
833833
834834 fn mcv(val: MCValue) GenResult {
......@@ -903,16 +903,13 @@ fn genDeclRef(
903903 mod.intern_pool.stringToSliceUnwrap(ov.lib_name)
904904 else
905905 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 });
907908 }
908909 const sym_index = try elf_file.getOrCreateMetadataForDecl(decl_index);
909910 const sym = elf_file.symbol(sym_index);
910911 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
911 if (bin_file.options.pic) {
912 return GenResult.mcv(.{ .load_got = sym.esym_index });
913 } else {
914 return GenResult.mcv(.{ .memory = sym.zigGotAddress(elf_file) });
915 }
912 return GenResult.mcv(.{ .lea_memory = sym.esym_index });
916913 } else if (bin_file.cast(link.File.MachO)) |macho_file| {
917914 const atom_index = try macho_file.getOrCreateAtomForDecl(decl_index);
918915 const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
......@@ -948,11 +945,7 @@ fn genUnnamedConst(
948945 };
949946 if (bin_file.cast(link.File.Elf)) |elf_file| {
950947 const local = elf_file.symbol(local_sym_index);
951 if (bin_file.options.pic) {
952 return GenResult.mcv(.{ .load_direct = local.esym_index });
953 } else {
954 return GenResult.mcv(.{ .memory = local.value });
955 }
948 return GenResult.mcv(.{ .load_memory = local.esym_index });
956949 } else if (bin_file.cast(link.File.MachO)) |_| {
957950 return GenResult.mcv(.{ .load_direct = local_sym_index });
958951 } 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
59555955 return lookup_gop.value_ptr.*;
59565956}
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
59585964const GetOrCreateComdatGroupOwnerResult = struct {
59595965 found_existing: bool,
59605966 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
370370 try self.scanReloc(symbol, rel, dynAbsRelocAction(symbol, elf_file), elf_file);
371371 },
372372
373 elf.R_X86_64_GOT32,
373374 elf.R_X86_64_GOTPC32,
374375 elf.R_X86_64_GOTPC64,
375376 elf.R_X86_64_GOTPCREL,
......@@ -879,6 +880,8 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) !void {
879880 }
880881 },
881882
883 elf.R_X86_64_GOT32 => try cwriter.writeIntLittle(i32, @as(i32, @intCast(G + GOT + A))),
884
882885 // Zig custom relocations
883886 Elf.R_X86_64_ZIG_GOT32 => try cwriter.writeIntLittle(u32, @as(u32, @intCast(ZIG_GOT + A))),
884887 Elf.R_X86_64_ZIG_GOTPCREL => try cwriter.writeIntLittle(i32, @as(i32, @intCast(ZIG_GOT + A - P))),