| ... | ... | @@ -139,21 +139,10 @@ const MCValue = union(enum) { |
| 139 | 139 | /// If the type is a pointer, it means the pointer address is at |
| 140 | 140 | /// this memory location. |
| 141 | 141 | memory: u64, |
| 142 | | /// The value is in memory referenced indirectly via a GOT entry |
| 143 | | /// index. |
| 144 | | /// |
| 145 | | /// If the type is a pointer, it means the pointer is referenced |
| 146 | | /// indirectly via GOT. When lowered, linker will emit |
| 147 | | /// relocations of type ARM64_RELOC_GOT_LOAD_PAGE21 and |
| 148 | | /// ARM64_RELOC_GOT_LOAD_PAGEOFF12. |
| 149 | | got_load: u32, |
| 150 | | /// The value is in memory referenced directly via symbol index. |
| 151 | | /// |
| 152 | | /// If the type is a pointer, it means the pointer is referenced |
| 153 | | /// directly via symbol index. When lowered, linker will emit a |
| 154 | | /// relocation of type ARM64_RELOC_PAGE21 and |
| 155 | | /// ARM64_RELOC_PAGEOFF12. |
| 156 | | direct_load: u32, |
| 142 | /// The value is in memory but requires a linker relocation fixup: |
| 143 | /// * got - the value is referenced indirectly via GOT entry index (the linker emits a got-type reloc) |
| 144 | /// * direct - the value is referenced directly via symbol index index (the linker emits a displacement reloc) |
| 145 | linker_load: struct { @"type": enum { got, direct }, sym_index: u32 }, |
| 157 | 146 | /// The value is one of the stack variables. |
| 158 | 147 | /// |
| 159 | 148 | /// If the type is a pointer, it means the pointer address is in |
| ... | ... | @@ -2959,8 +2948,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 2959 | 2948 | .memory, |
| 2960 | 2949 | .stack_offset, |
| 2961 | 2950 | .stack_argument_offset, |
| 2962 | | .got_load, |
| 2963 | | .direct_load, |
| 2951 | .linker_load, |
| 2964 | 2952 | => { |
| 2965 | 2953 | const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr); |
| 2966 | 2954 | try self.load(dst_mcv, .{ .register = addr_reg }, ptr_ty); |
| ... | ... | @@ -3197,8 +3185,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 3197 | 3185 | .memory, |
| 3198 | 3186 | .stack_offset, |
| 3199 | 3187 | .stack_argument_offset, |
| 3200 | | .got_load, |
| 3201 | | .direct_load, |
| 3188 | .linker_load, |
| 3202 | 3189 | => { |
| 3203 | 3190 | const addr_reg = try self.copyToTmpRegister(ptr_ty, ptr); |
| 3204 | 3191 | try self.store(.{ .register = addr_reg }, value, ptr_ty, value_ty); |
| ... | ... | @@ -3493,7 +3480,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. |
| 3493 | 3480 | const func = func_payload.data; |
| 3494 | 3481 | const fn_owner_decl = mod.declPtr(func.owner_decl); |
| 3495 | 3482 | try self.genSetReg(Type.initTag(.u64), .x30, .{ |
| 3496 | | .got_load = fn_owner_decl.link.macho.sym_index, |
| 3483 | .linker_load = .{ |
| 3484 | .@"type" = .got, |
| 3485 | .sym_index = fn_owner_decl.link.macho.sym_index, |
| 3486 | }, |
| 3497 | 3487 | }); |
| 3498 | 3488 | // blr x30 |
| 3499 | 3489 | _ = try self.addInst(.{ |
| ... | ... | @@ -4427,8 +4417,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 4427 | 4417 | .register = cond_reg, |
| 4428 | 4418 | }); |
| 4429 | 4419 | }, |
| 4430 | | .got_load, |
| 4431 | | .direct_load, |
| 4420 | .linker_load, |
| 4432 | 4421 | .memory, |
| 4433 | 4422 | .stack_argument_offset, |
| 4434 | 4423 | .stack_offset, |
| ... | ... | @@ -4479,13 +4468,10 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 4479 | 4468 | }); |
| 4480 | 4469 | }, |
| 4481 | 4470 | .memory => |addr| try self.genSetReg(Type.usize, src_reg, .{ .immediate = addr }), |
| 4482 | | .got_load, |
| 4483 | | .direct_load, |
| 4484 | | => |sym_index| { |
| 4485 | | const tag: Mir.Inst.Tag = switch (mcv) { |
| 4486 | | .got_load => .load_memory_ptr_got, |
| 4487 | | .direct_load => .load_memory_ptr_direct, |
| 4488 | | else => unreachable, |
| 4471 | .linker_load => |load_struct| { |
| 4472 | const tag: Mir.Inst.Tag = switch (load_struct.@"type") { |
| 4473 | .got => .load_memory_ptr_got, |
| 4474 | .direct => .load_memory_ptr_direct, |
| 4489 | 4475 | }; |
| 4490 | 4476 | const mod = self.bin_file.options.module.?; |
| 4491 | 4477 | _ = try self.addInst(.{ |
| ... | ... | @@ -4494,7 +4480,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro |
| 4494 | 4480 | .payload = try self.addExtra(Mir.LoadMemoryPie{ |
| 4495 | 4481 | .register = @enumToInt(src_reg), |
| 4496 | 4482 | .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.sym_index, |
| 4497 | | .sym_index = sym_index, |
| 4483 | .sym_index = load_struct.sym_index, |
| 4498 | 4484 | }), |
| 4499 | 4485 | }, |
| 4500 | 4486 | }); |
| ... | ... | @@ -4594,13 +4580,10 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 4594 | 4580 | }); |
| 4595 | 4581 | }, |
| 4596 | 4582 | .register_with_overflow => unreachable, // doesn't fit into a register |
| 4597 | | .got_load, |
| 4598 | | .direct_load, |
| 4599 | | => |sym_index| { |
| 4600 | | const tag: Mir.Inst.Tag = switch (mcv) { |
| 4601 | | .got_load => .load_memory_got, |
| 4602 | | .direct_load => .load_memory_direct, |
| 4603 | | else => unreachable, |
| 4583 | .linker_load => |load_struct| { |
| 4584 | const tag: Mir.Inst.Tag = switch (load_struct.@"type") { |
| 4585 | .got => .load_memory_got, |
| 4586 | .direct => .load_memory_direct, |
| 4604 | 4587 | }; |
| 4605 | 4588 | const mod = self.bin_file.options.module.?; |
| 4606 | 4589 | _ = try self.addInst(.{ |
| ... | ... | @@ -4609,7 +4592,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 4609 | 4592 | .payload = try self.addExtra(Mir.LoadMemoryPie{ |
| 4610 | 4593 | .register = @enumToInt(reg), |
| 4611 | 4594 | .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.sym_index, |
| 4612 | | .sym_index = sym_index, |
| 4595 | .sym_index = load_struct.sym_index, |
| 4613 | 4596 | }), |
| 4614 | 4597 | }, |
| 4615 | 4598 | }); |
| ... | ... | @@ -4741,8 +4724,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I |
| 4741 | 4724 | .register_with_overflow => { |
| 4742 | 4725 | return self.fail("TODO implement genSetStackArgument {}", .{mcv}); |
| 4743 | 4726 | }, |
| 4744 | | .got_load, |
| 4745 | | .direct_load, |
| 4727 | .linker_load, |
| 4746 | 4728 | .memory, |
| 4747 | 4729 | .stack_argument_offset, |
| 4748 | 4730 | .stack_offset, |
| ... | ... | @@ -4785,13 +4767,10 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I |
| 4785 | 4767 | }); |
| 4786 | 4768 | }, |
| 4787 | 4769 | .memory => |addr| try self.genSetReg(ptr_ty, src_reg, .{ .immediate = @intCast(u32, addr) }), |
| 4788 | | .got_load, |
| 4789 | | .direct_load, |
| 4790 | | => |sym_index| { |
| 4791 | | const tag: Mir.Inst.Tag = switch (mcv) { |
| 4792 | | .got_load => .load_memory_ptr_got, |
| 4793 | | .direct_load => .load_memory_ptr_direct, |
| 4794 | | else => unreachable, |
| 4770 | .linker_load => |load_struct| { |
| 4771 | const tag: Mir.Inst.Tag = switch (load_struct.@"type") { |
| 4772 | .got => .load_memory_ptr_got, |
| 4773 | .direct => .load_memory_ptr_direct, |
| 4795 | 4774 | }; |
| 4796 | 4775 | const mod = self.bin_file.options.module.?; |
| 4797 | 4776 | _ = try self.addInst(.{ |
| ... | ... | @@ -4800,7 +4779,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I |
| 4800 | 4779 | .payload = try self.addExtra(Mir.LoadMemoryPie{ |
| 4801 | 4780 | .register = @enumToInt(src_reg), |
| 4802 | 4781 | .atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.sym_index, |
| 4803 | | .sym_index = sym_index, |
| 4782 | .sym_index = load_struct.sym_index, |
| 4804 | 4783 | }), |
| 4805 | 4784 | }, |
| 4806 | 4785 | }); |
| ... | ... | @@ -5107,7 +5086,10 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne |
| 5107 | 5086 | // Because MachO is PIE-always-on, we defer memory address resolution until |
| 5108 | 5087 | // the linker has enough info to perform relocations. |
| 5109 | 5088 | assert(decl.link.macho.sym_index != 0); |
| 5110 | | return MCValue{ .got_load = decl.link.macho.sym_index }; |
| 5089 | return MCValue{ .linker_load = .{ |
| 5090 | .@"type" = .got, |
| 5091 | .sym_index = decl.link.macho.sym_index, |
| 5092 | } }; |
| 5111 | 5093 | } else if (self.bin_file.cast(link.File.Coff)) |_| { |
| 5112 | 5094 | return self.fail("TODO codegen COFF const Decl pointer", .{}); |
| 5113 | 5095 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { |
| ... | ... | @@ -5129,7 +5111,10 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue { |
| 5129 | 5111 | const vaddr = elf_file.local_symbols.items[local_sym_index].st_value; |
| 5130 | 5112 | return MCValue{ .memory = vaddr }; |
| 5131 | 5113 | } else if (self.bin_file.cast(link.File.MachO)) |_| { |
| 5132 | | return MCValue{ .direct_load = local_sym_index }; |
| 5114 | return MCValue{ .linker_load = .{ |
| 5115 | .@"type" = .direct, |
| 5116 | .sym_index = local_sym_index, |
| 5117 | } }; |
| 5133 | 5118 | } else if (self.bin_file.cast(link.File.Coff)) |_| { |
| 5134 | 5119 | return self.fail("TODO lower unnamed const in COFF", .{}); |
| 5135 | 5120 | } else if (self.bin_file.cast(link.File.Plan9)) |_| { |