| author | |
| committer | |
| log | 066758b1a296aa6f01d505f7b90d5aee2f387d30 |
| tree | 50c15027ca05182f8f47e55d2891d9b9d318db66 |
| parent | b9b1ab024063105a9adfe3828692867c91015dc6 |
Match changes required to `Elf` linker, which enable lowering
of const slices on `MachO` targets.
Expand `Mir` instructions requiring the knowledge of the containing
atom - pass the symbol index into the linker's table from codegen
via mir to emitter, to then utilise it in the linker.9 files changed, 130 insertions(+), 61 deletions(-)
src/arch/aarch64/CodeGen.zig+15-1| ... | ... | @@ -1617,7 +1617,12 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { |
| 1617 | 1617 | |
| 1618 | 1618 | _ = try self.addInst(.{ |
| 1619 | 1619 | .tag = .call_extern, |
| 1620 | .data = .{ .extern_fn = n_strx }, | |
| 1620 | .data = .{ | |
| 1621 | .extern_fn = .{ | |
| 1622 | .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index, | |
| 1623 | .sym_name = n_strx, | |
| 1624 | }, | |
| 1625 | }, | |
| 1621 | 1626 | }); |
| 1622 | 1627 | } else { |
| 1623 | 1628 | return self.fail("TODO implement calling bitcasted functions", .{}); |
| ... | ... | @@ -2485,9 +2490,18 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 2485 | 2490 | }); |
| 2486 | 2491 | }, |
| 2487 | 2492 | .memory => |addr| { |
| 2493 | const owner_decl = self.mod_fn.owner_decl; | |
| 2494 | // TODO when refactoring LinkBlock, make this into a generic function. | |
| 2495 | const atom_index = switch (self.bin_file.tag) { | |
| 2496 | .macho => owner_decl.link.macho.local_sym_index, | |
| 2497 | .elf => owner_decl.link.elf.local_sym_index, | |
| 2498 | .plan9 => @intCast(u32, owner_decl.link.plan9.sym_index orelse 0), | |
| 2499 | else => return self.fail("TODO handle aarch64 load memory in {}", .{self.bin_file.tag}), | |
| 2500 | }; | |
| 2488 | 2501 | _ = try self.addInst(.{ |
| 2489 | 2502 | .tag = .load_memory, |
| 2490 | 2503 | .data = .{ .payload = try self.addExtra(Mir.LoadMemory{ |
| 2504 | .atom_index = atom_index, | |
| 2491 | 2505 | .register = @enumToInt(reg), |
| 2492 | 2506 | .addr = @intCast(u32, addr), |
| 2493 | 2507 | }) }, |
src/arch/aarch64/Emit.zig+7-7| ... | ... | @@ -537,7 +537,7 @@ fn mirDebugEpilogueBegin(self: *Emit) !void { |
| 537 | 537 | |
| 538 | 538 | fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 539 | 539 | assert(emit.mir.instructions.items(.tag)[inst] == .call_extern); |
| 540 | const n_strx = emit.mir.instructions.items(.data)[inst].extern_fn; | |
| 540 | const extern_fn = emit.mir.instructions.items(.data)[inst].extern_fn; | |
| 541 | 541 | |
| 542 | 542 | if (emit.bin_file.cast(link.File.MachO)) |macho_file| { |
| 543 | 543 | const offset = blk: { |
| ... | ... | @@ -547,9 +547,10 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 547 | 547 | break :blk offset; |
| 548 | 548 | }; |
| 549 | 549 | // Add relocation to the decl. |
| 550 | try macho_file.active_decl.?.link.macho.relocs.append(emit.bin_file.allocator, .{ | |
| 550 | const atom = macho_file.atom_by_index_table.get(extern_fn.atom_index).?; | |
| 551 | try atom.relocs.append(emit.bin_file.allocator, .{ | |
| 551 | 552 | .offset = offset, |
| 552 | .target = .{ .global = n_strx }, | |
| 553 | .target = .{ .global = extern_fn.sym_name }, | |
| 553 | 554 | .addend = 0, |
| 554 | 555 | .subtractor = null, |
| 555 | 556 | .pcrel = true, |
| ... | ... | @@ -613,10 +614,9 @@ fn mirLoadMemory(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 613 | 614 | )); |
| 614 | 615 | |
| 615 | 616 | if (emit.bin_file.cast(link.File.MachO)) |macho_file| { |
| 616 | // TODO I think the reloc might be in the wrong place. | |
| 617 | const decl = macho_file.active_decl.?; | |
| 617 | const atom = macho_file.atom_by_index_table.get(load_memory.atom_index).?; | |
| 618 | 618 | // Page reloc for adrp instruction. |
| 619 | try decl.link.macho.relocs.append(emit.bin_file.allocator, .{ | |
| 619 | try atom.relocs.append(emit.bin_file.allocator, .{ | |
| 620 | 620 | .offset = offset, |
| 621 | 621 | .target = .{ .local = addr }, |
| 622 | 622 | .addend = 0, |
| ... | ... | @@ -626,7 +626,7 @@ fn mirLoadMemory(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 626 | 626 | .@"type" = @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGE21), |
| 627 | 627 | }); |
| 628 | 628 | // Pageoff reloc for adrp instruction. |
| 629 | try decl.link.macho.relocs.append(emit.bin_file.allocator, .{ | |
| 629 | try atom.relocs.append(emit.bin_file.allocator, .{ | |
| 630 | 630 | .offset = offset + 4, |
| 631 | 631 | .target = .{ .local = addr }, |
| 632 | 632 | .addend = 0, |
src/arch/aarch64/Mir.zig+7-1| ... | ... | @@ -134,7 +134,12 @@ pub const Inst = struct { |
| 134 | 134 | /// An extern function |
| 135 | 135 | /// |
| 136 | 136 | /// Used by e.g. call_extern |
| 137 | extern_fn: u32, | |
| 137 | extern_fn: struct { | |
| 138 | /// Index of the containing atom. | |
| 139 | atom_index: u32, | |
| 140 | /// Index into the linker's string table. | |
| 141 | sym_name: u32, | |
| 142 | }, | |
| 138 | 143 | /// A 16-bit immediate value. |
| 139 | 144 | /// |
| 140 | 145 | /// Used by e.g. svc |
| ... | ... | @@ -278,6 +283,7 @@ pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end |
| 278 | 283 | } |
| 279 | 284 | |
| 280 | 285 | pub const LoadMemory = struct { |
| 286 | atom_index: u32, | |
| 281 | 287 | register: u32, |
| 282 | 288 | addr: u32, |
| 283 | 289 | }; |
src/arch/x86_64/CodeGen.zig+48-4| ... | ... | @@ -1897,7 +1897,12 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 1897 | 1897 | .reg1 = addr_reg.to64(), |
| 1898 | 1898 | .flags = flags, |
| 1899 | 1899 | }).encode(), |
| 1900 | .data = .{ .linker_sym_index = sym_index }, | |
| 1900 | .data = .{ | |
| 1901 | .load_reloc = .{ | |
| 1902 | .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index, | |
| 1903 | .sym_index = sym_index, | |
| 1904 | }, | |
| 1905 | }, | |
| 1901 | 1906 | }); |
| 1902 | 1907 | break :blk addr_reg; |
| 1903 | 1908 | }, |
| ... | ... | @@ -2670,7 +2675,12 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void { |
| 2670 | 2675 | _ = try self.addInst(.{ |
| 2671 | 2676 | .tag = .call_extern, |
| 2672 | 2677 | .ops = undefined, |
| 2673 | .data = .{ .extern_fn = n_strx }, | |
| 2678 | .data = .{ | |
| 2679 | .extern_fn = .{ | |
| 2680 | .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index, | |
| 2681 | .sym_name = n_strx, | |
| 2682 | }, | |
| 2683 | }, | |
| 2674 | 2684 | }); |
| 2675 | 2685 | } else { |
| 2676 | 2686 | return self.fail("TODO implement calling bitcasted functions", .{}); |
| ... | ... | @@ -3550,7 +3560,12 @@ fn genSetStackArg(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerE |
| 3550 | 3560 | .reg1 = addr_reg.to64(), |
| 3551 | 3561 | .flags = flags, |
| 3552 | 3562 | }).encode(), |
| 3553 | .data = .{ .linker_sym_index = sym_index }, | |
| 3563 | .data = .{ | |
| 3564 | .load_reloc = .{ | |
| 3565 | .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index, | |
| 3566 | .sym_index = sym_index, | |
| 3567 | }, | |
| 3568 | }, | |
| 3554 | 3569 | }); |
| 3555 | 3570 | break :blk addr_reg; |
| 3556 | 3571 | }, |
| ... | ... | @@ -3767,6 +3782,30 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue) InnerErro |
| 3767 | 3782 | const reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = addr }); |
| 3768 | 3783 | break :blk reg; |
| 3769 | 3784 | }, |
| 3785 | .direct_load, | |
| 3786 | .got_load, | |
| 3787 | => |sym_index| { | |
| 3788 | const flags: u2 = switch (mcv) { | |
| 3789 | .got_load => 0b00, | |
| 3790 | .direct_load => 0b01, | |
| 3791 | else => unreachable, | |
| 3792 | }; | |
| 3793 | const addr_reg = try self.register_manager.allocReg(null); | |
| 3794 | _ = try self.addInst(.{ | |
| 3795 | .tag = .lea_pie, | |
| 3796 | .ops = (Mir.Ops{ | |
| 3797 | .reg1 = addr_reg.to64(), | |
| 3798 | .flags = flags, | |
| 3799 | }).encode(), | |
| 3800 | .data = .{ | |
| 3801 | .load_reloc = .{ | |
| 3802 | .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index, | |
| 3803 | .sym_index = sym_index, | |
| 3804 | }, | |
| 3805 | }, | |
| 3806 | }); | |
| 3807 | break :blk addr_reg; | |
| 3808 | }, | |
| 3770 | 3809 | else => { |
| 3771 | 3810 | return self.fail("TODO implement memcpy for setting stack from {}", .{mcv}); |
| 3772 | 3811 | }, |
| ... | ... | @@ -4202,7 +4241,12 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void |
| 4202 | 4241 | .reg1 = reg, |
| 4203 | 4242 | .flags = flags, |
| 4204 | 4243 | }).encode(), |
| 4205 | .data = .{ .linker_sym_index = sym_index }, | |
| 4244 | .data = .{ | |
| 4245 | .load_reloc = .{ | |
| 4246 | .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index, | |
| 4247 | .sym_index = sym_index, | |
| 4248 | }, | |
| 4249 | }, | |
| 4206 | 4250 | }); |
| 4207 | 4251 | // MOV reg, [reg] |
| 4208 | 4252 | _ = try self.addInst(.{ |
src/arch/x86_64/Emit.zig+12-7| ... | ... | @@ -763,6 +763,7 @@ fn mirLeaPie(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { |
| 763 | 763 | const tag = emit.mir.instructions.items(.tag)[inst]; |
| 764 | 764 | assert(tag == .lea_pie); |
| 765 | 765 | const ops = Mir.Ops.decode(emit.mir.instructions.items(.ops)[inst]); |
| 766 | const load_reloc = emit.mir.instructions.items(.data)[inst].load_reloc; | |
| 766 | 767 | |
| 767 | 768 | // lea reg1, [rip + reloc] |
| 768 | 769 | // RM |
| ... | ... | @@ -772,18 +773,19 @@ fn mirLeaPie(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { |
| 772 | 773 | RegisterOrMemory.rip(Memory.PtrSize.fromBits(ops.reg1.size()), 0), |
| 773 | 774 | emit.code, |
| 774 | 775 | ); |
| 776 | ||
| 775 | 777 | const end_offset = emit.code.items.len; |
| 776 | const sym_index = emit.mir.instructions.items(.data)[inst].linker_sym_index; | |
| 778 | ||
| 777 | 779 | if (emit.bin_file.cast(link.File.MachO)) |macho_file| { |
| 778 | 780 | const reloc_type = switch (ops.flags) { |
| 779 | 781 | 0b00 => @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_GOT), |
| 780 | 782 | 0b01 => @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_SIGNED), |
| 781 | 783 | else => return emit.fail("TODO unused LEA PIE variants 0b10 and 0b11", .{}), |
| 782 | 784 | }; |
| 783 | const decl = macho_file.active_decl.?; | |
| 784 | try decl.link.macho.relocs.append(emit.bin_file.allocator, .{ | |
| 785 | const atom = macho_file.atom_by_index_table.get(load_reloc.atom_index).?; | |
| 786 | try atom.relocs.append(emit.bin_file.allocator, .{ | |
| 785 | 787 | .offset = @intCast(u32, end_offset - 4), |
| 786 | .target = .{ .local = sym_index }, | |
| 788 | .target = .{ .local = load_reloc.sym_index }, | |
| 787 | 789 | .addend = 0, |
| 788 | 790 | .subtractor = null, |
| 789 | 791 | .pcrel = true, |
| ... | ... | @@ -801,17 +803,20 @@ fn mirLeaPie(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { |
| 801 | 803 | fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void { |
| 802 | 804 | const tag = emit.mir.instructions.items(.tag)[inst]; |
| 803 | 805 | assert(tag == .call_extern); |
| 804 | const n_strx = emit.mir.instructions.items(.data)[inst].extern_fn; | |
| 806 | const extern_fn = emit.mir.instructions.items(.data)[inst].extern_fn; | |
| 807 | ||
| 805 | 808 | const offset = blk: { |
| 806 | 809 | // callq |
| 807 | 810 | try lowerToDEnc(.call_near, 0, emit.code); |
| 808 | 811 | break :blk @intCast(u32, emit.code.items.len) - 4; |
| 809 | 812 | }; |
| 813 | ||
| 810 | 814 | if (emit.bin_file.cast(link.File.MachO)) |macho_file| { |
| 811 | 815 | // Add relocation to the decl. |
| 812 | try macho_file.active_decl.?.link.macho.relocs.append(emit.bin_file.allocator, .{ | |
| 816 | const atom = macho_file.atom_by_index_table.get(extern_fn.atom_index).?; | |
| 817 | try atom.relocs.append(emit.bin_file.allocator, .{ | |
| 813 | 818 | .offset = offset, |
| 814 | .target = .{ .global = n_strx }, | |
| 819 | .target = .{ .global = extern_fn.sym_name }, | |
| 815 | 820 | .addend = 0, |
| 816 | 821 | .subtractor = null, |
| 817 | 822 | .pcrel = true, |
src/arch/x86_64/Mir.zig+15-6| ... | ... | @@ -185,7 +185,7 @@ pub const Inst = struct { |
| 185 | 185 | /// 0b00 reg1, [rip + reloc] // via GOT emits X86_64_RELOC_GOT relocation |
| 186 | 186 | /// 0b01 reg1, [rip + reloc] // direct load emits X86_64_RELOC_SIGNED relocation |
| 187 | 187 | /// Notes: |
| 188 | /// * `Data` contains `linker_sym_index` | |
| 188 | /// * `Data` contains `load_reloc` | |
| 189 | 189 | lea_pie, |
| 190 | 190 | |
| 191 | 191 | /// ops flags: form: |
| ... | ... | @@ -350,10 +350,19 @@ pub const Inst = struct { |
| 350 | 350 | /// A 32-bit immediate value. |
| 351 | 351 | imm: u32, |
| 352 | 352 | /// An extern function. |
| 353 | /// Index into the linker's string table. | |
| 354 | extern_fn: u32, | |
| 355 | /// Entry in the linker's symbol table. | |
| 356 | linker_sym_index: u32, | |
| 353 | extern_fn: struct { | |
| 354 | /// Index of the containing atom. | |
| 355 | atom_index: u32, | |
| 356 | /// Index into the linker's string table. | |
| 357 | sym_name: u32, | |
| 358 | }, | |
| 359 | /// PIE load relocation. | |
| 360 | load_reloc: struct { | |
| 361 | /// Index of the containing atom. | |
| 362 | atom_index: u32, | |
| 363 | /// Index into the linker's symbol table. | |
| 364 | sym_index: u32, | |
| 365 | }, | |
| 357 | 366 | /// Index into `extra`. Meaning of what can be found there is context-dependent. |
| 358 | 367 | payload: u32, |
| 359 | 368 | }; |
| ... | ... | @@ -362,7 +371,7 @@ pub const Inst = struct { |
| 362 | 371 | // Note that in Debug builds, Zig is allowed to insert a secret field for safety checks. |
| 363 | 372 | comptime { |
| 364 | 373 | if (builtin.mode != .Debug) { |
| 365 | assert(@sizeOf(Inst) == 8); | |
| 374 | assert(@sizeOf(Data) == 8); | |
| 366 | 375 | } |
| 367 | 376 | } |
| 368 | 377 | }; |
src/arch/x86_64/PrintMir.zig+2-2| ... | ... | @@ -450,6 +450,7 @@ fn mirLea(print: *const Print, inst: Mir.Inst.Index, w: anytype) !void { |
| 450 | 450 | |
| 451 | 451 | fn mirLeaPie(print: *const Print, inst: Mir.Inst.Index, w: anytype) !void { |
| 452 | 452 | const ops = Mir.Ops.decode(print.mir.instructions.items(.ops)[inst]); |
| 453 | const load_reloc = print.mir.instructions.items(.data)[inst].load_reloc; | |
| 453 | 454 | try w.print("lea {s}, ", .{@tagName(ops.reg1)}); |
| 454 | 455 | switch (ops.reg1.size()) { |
| 455 | 456 | 8 => try w.print("byte ptr ", .{}), |
| ... | ... | @@ -459,9 +460,8 @@ fn mirLeaPie(print: *const Print, inst: Mir.Inst.Index, w: anytype) !void { |
| 459 | 460 | else => unreachable, |
| 460 | 461 | } |
| 461 | 462 | try w.print("[rip + 0x0] ", .{}); |
| 462 | const sym_index = print.mir.instructions.items(.data)[inst].linker_sym_index; | |
| 463 | 463 | if (print.bin_file.cast(link.File.MachO)) |macho_file| { |
| 464 | const target = macho_file.locals.items[sym_index]; | |
| 464 | const target = macho_file.locals.items[load_reloc.sym_index]; | |
| 465 | 465 | const target_name = macho_file.getString(target.n_strx); |
| 466 | 466 | try w.print("target@{s}", .{target_name}); |
| 467 | 467 | } else { |
src/link/MachO.zig+21-32| ... | ... | @@ -40,6 +40,7 @@ const StringIndexContext = std.hash_map.StringIndexContext; |
| 40 | 40 | const Trie = @import("MachO/Trie.zig"); |
| 41 | 41 | const Type = @import("../type.zig").Type; |
| 42 | 42 | const TypedValue = @import("../TypedValue.zig"); |
| 43 | const Value = @import("../value.zig").Value; | |
| 43 | 44 | |
| 44 | 45 | pub const TextBlock = Atom; |
| 45 | 46 | |
| ... | ... | @@ -220,6 +221,7 @@ atoms: std.AutoHashMapUnmanaged(MatchingSection, *Atom) = .{}, |
| 220 | 221 | /// at present owned by Module.Decl. |
| 221 | 222 | /// TODO consolidate this. |
| 222 | 223 | managed_atoms: std.ArrayListUnmanaged(*Atom) = .{}, |
| 224 | atom_by_index_table: std.AutoHashMapUnmanaged(u32, *Atom) = .{}, | |
| 223 | 225 | |
| 224 | 226 | /// Table of unnamed constants associated with a parent `Decl`. |
| 225 | 227 | /// We store them here so that we can free the constants whenever the `Decl` |
| ... | ... | @@ -248,12 +250,6 @@ unnamed_const_atoms: UnnamedConstTable = .{}, |
| 248 | 250 | /// TODO consolidate this. |
| 249 | 251 | decls: std.AutoArrayHashMapUnmanaged(*Module.Decl, ?MatchingSection) = .{}, |
| 250 | 252 | |
| 251 | /// Currently active Module.Decl. | |
| 252 | /// TODO this might not be necessary if we figure out how to pass Module.Decl instance | |
| 253 | /// to codegen.genSetReg() or alternatively move PIE displacement for MCValue{ .memory = x } | |
| 254 | /// somewhere else in the codegen. | |
| 255 | active_decl: ?*Module.Decl = null, | |
| 256 | ||
| 257 | 253 | const Entry = struct { |
| 258 | 254 | target: Atom.Relocation.Target, |
| 259 | 255 | atom: *Atom, |
| ... | ... | @@ -3441,6 +3437,8 @@ pub fn deinit(self: *MachO) void { |
| 3441 | 3437 | } |
| 3442 | 3438 | self.unnamed_const_atoms.deinit(self.base.allocator); |
| 3443 | 3439 | } |
| 3440 | ||
| 3441 | self.atom_by_index_table.deinit(self.base.allocator); | |
| 3444 | 3442 | } |
| 3445 | 3443 | |
| 3446 | 3444 | pub fn closeFiles(self: MachO) void { |
| ... | ... | @@ -3647,6 +3645,7 @@ pub fn allocateDeclIndexes(self: *MachO, decl: *Module.Decl) !void { |
| 3647 | 3645 | if (decl.link.macho.local_sym_index != 0) return; |
| 3648 | 3646 | |
| 3649 | 3647 | decl.link.macho.local_sym_index = try self.allocateLocalSymbol(); |
| 3648 | try self.atom_by_index_table.putNoClobber(self.base.allocator, decl.link.macho.local_sym_index, &decl.link.macho); | |
| 3650 | 3649 | try self.decls.putNoClobber(self.base.allocator, decl, null); |
| 3651 | 3650 | |
| 3652 | 3651 | const got_target = .{ .local = decl.link.macho.local_sym_index }; |
| ... | ... | @@ -3693,8 +3692,6 @@ pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liv |
| 3693 | 3692 | } |
| 3694 | 3693 | } |
| 3695 | 3694 | |
| 3696 | self.active_decl = decl; | |
| 3697 | ||
| 3698 | 3695 | const res = if (debug_buffers) |dbg| |
| 3699 | 3696 | try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .{ |
| 3700 | 3697 | .dwarf = .{ |
| ... | ... | @@ -3756,14 +3753,9 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl: *Module.De |
| 3756 | 3753 | log.debug("allocating symbol indexes for {s}", .{name}); |
| 3757 | 3754 | |
| 3758 | 3755 | const required_alignment = typed_value.ty.abiAlignment(self.base.options.target); |
| 3759 | const match = (try self.getMatchingSection(.{ | |
| 3760 | .segname = makeStaticString("__TEXT"), | |
| 3761 | .sectname = makeStaticString("__const"), | |
| 3762 | .size = @sizeOf(u64), | |
| 3763 | .@"align" = math.log2(required_alignment), | |
| 3764 | })).?; | |
| 3765 | 3756 | const local_sym_index = try self.allocateLocalSymbol(); |
| 3766 | 3757 | const atom = try self.createEmptyAtom(local_sym_index, @sizeOf(u64), math.log2(required_alignment)); |
| 3758 | try self.atom_by_index_table.putNoClobber(self.base.allocator, local_sym_index, atom); | |
| 3767 | 3759 | |
| 3768 | 3760 | const res = try codegen.generateSymbol(&self.base, local_sym_index, decl.srcLoc(), typed_value, &code_buffer, .{ |
| 3769 | 3761 | .none = .{}, |
| ... | ... | @@ -3780,6 +3772,8 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl: *Module.De |
| 3780 | 3772 | |
| 3781 | 3773 | atom.code.clearRetainingCapacity(); |
| 3782 | 3774 | try atom.code.appendSlice(self.base.allocator, code); |
| 3775 | ||
| 3776 | const match = try self.getMatchingSectionAtom(atom, typed_value.ty, typed_value.val); | |
| 3783 | 3777 | const addr = try self.allocateAtom(atom, code.len, required_alignment, match); |
| 3784 | 3778 | |
| 3785 | 3779 | log.debug("allocated atom for {s} at 0x{x}", .{ name, addr }); |
| ... | ... | @@ -3839,11 +3833,9 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { |
| 3839 | 3833 | } |
| 3840 | 3834 | } |
| 3841 | 3835 | |
| 3842 | self.active_decl = decl; | |
| 3843 | ||
| 3844 | 3836 | const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val; |
| 3845 | 3837 | const res = if (debug_buffers) |dbg| |
| 3846 | try codegen.generateSymbol(&self.base, decl.link.elf.local_sym_index, decl.srcLoc(), .{ | |
| 3838 | try codegen.generateSymbol(&self.base, decl.link.macho.local_sym_index, decl.srcLoc(), .{ | |
| 3847 | 3839 | .ty = decl.ty, |
| 3848 | 3840 | .val = decl_val, |
| 3849 | 3841 | }, &code_buffer, .{ |
| ... | ... | @@ -3854,7 +3846,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { |
| 3854 | 3846 | }, |
| 3855 | 3847 | }) |
| 3856 | 3848 | else |
| 3857 | try codegen.generateSymbol(&self.base, decl.link.elf.local_sym_index, decl.srcLoc(), .{ | |
| 3849 | try codegen.generateSymbol(&self.base, decl.link.macho.local_sym_index, decl.srcLoc(), .{ | |
| 3858 | 3850 | .ty = decl.ty, |
| 3859 | 3851 | .val = decl_val, |
| 3860 | 3852 | }, &code_buffer, .none); |
| ... | ... | @@ -3908,13 +3900,11 @@ fn isElemTyPointer(ty: Type) bool { |
| 3908 | 3900 | } |
| 3909 | 3901 | } |
| 3910 | 3902 | |
| 3911 | fn getMatchingSectionDecl(self: *MachO, decl: *Module.Decl) !MatchingSection { | |
| 3912 | const code = decl.link.macho.code.items; | |
| 3913 | const alignment = decl.ty.abiAlignment(self.base.options.target); | |
| 3903 | fn getMatchingSectionAtom(self: *MachO, atom: *Atom, ty: Type, val: Value) !MatchingSection { | |
| 3904 | const code = atom.code.items; | |
| 3905 | const alignment = ty.abiAlignment(self.base.options.target); | |
| 3914 | 3906 | const align_log_2 = math.log2(alignment); |
| 3915 | const ty = decl.ty; | |
| 3916 | 3907 | const zig_ty = ty.zigTypeTag(); |
| 3917 | const val = decl.val; | |
| 3918 | 3908 | const mode = self.base.options.optimize_mode; |
| 3919 | 3909 | const match: MatchingSection = blk: { |
| 3920 | 3910 | // TODO finish and audit this function |
| ... | ... | @@ -4023,9 +4013,11 @@ fn getMatchingSectionDecl(self: *MachO, decl: *Module.Decl) !MatchingSection { |
| 4023 | 4013 | }, |
| 4024 | 4014 | } |
| 4025 | 4015 | }; |
| 4016 | const local = self.locals.items[atom.local_sym_index]; | |
| 4026 | 4017 | const seg = self.load_commands.items[match.seg].segment; |
| 4027 | 4018 | const sect = seg.sections.items[match.sect]; |
| 4028 | log.debug(" allocating atom in '{s},{s}' ({d},{d})", .{ | |
| 4019 | log.debug(" allocating atom '{s}' in '{s},{s}' ({d},{d})", .{ | |
| 4020 | self.getString(local.n_strx), | |
| 4029 | 4021 | sect.segName(), |
| 4030 | 4022 | sect.sectName(), |
| 4031 | 4023 | match.seg, |
| ... | ... | @@ -4041,7 +4033,7 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64 |
| 4041 | 4033 | |
| 4042 | 4034 | const decl_ptr = self.decls.getPtr(decl).?; |
| 4043 | 4035 | if (decl_ptr.* == null) { |
| 4044 | decl_ptr.* = try self.getMatchingSectionDecl(decl); | |
| 4036 | decl_ptr.* = try self.getMatchingSectionAtom(&decl.link.macho, decl.ty, decl.val); | |
| 4045 | 4037 | } |
| 4046 | 4038 | const match = decl_ptr.*.?; |
| 4047 | 4039 | |
| ... | ... | @@ -4290,6 +4282,8 @@ fn freeUnnamedConsts(self: *MachO, decl: *Module.Decl) void { |
| 4290 | 4282 | }, true); |
| 4291 | 4283 | self.locals_free_list.append(self.base.allocator, atom.local_sym_index) catch {}; |
| 4292 | 4284 | self.locals.items[atom.local_sym_index].n_type = 0; |
| 4285 | _ = self.atom_by_index_table.remove(atom.local_sym_index); | |
| 4286 | atom.local_sym_index = 0; | |
| 4293 | 4287 | } |
| 4294 | 4288 | unnamed_consts.clearAndFree(self.base.allocator); |
| 4295 | 4289 | } |
| ... | ... | @@ -4316,6 +4310,7 @@ pub fn freeDecl(self: *MachO, decl: *Module.Decl) void { |
| 4316 | 4310 | } |
| 4317 | 4311 | |
| 4318 | 4312 | self.locals.items[decl.link.macho.local_sym_index].n_type = 0; |
| 4313 | _ = self.atom_by_index_table.remove(decl.link.macho.local_sym_index); | |
| 4319 | 4314 | decl.link.macho.local_sym_index = 0; |
| 4320 | 4315 | } |
| 4321 | 4316 | if (self.d_sym) |*ds| { |
| ... | ... | @@ -4347,13 +4342,7 @@ pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl, parent_atom_index: u |
| 4347 | 4342 | assert(self.llvm_object == null); |
| 4348 | 4343 | assert(decl.link.macho.local_sym_index != 0); |
| 4349 | 4344 | |
| 4350 | // TODO cache local_sym_index => atom!!! | |
| 4351 | const atom: *Atom = blk: for (self.managed_atoms.items) |atom| { | |
| 4352 | if (atom.local_sym_index == parent_atom_index) { | |
| 4353 | break :blk atom; | |
| 4354 | } | |
| 4355 | } else unreachable; | |
| 4356 | ||
| 4345 | const atom = self.atom_by_index_table.get(parent_atom_index).?; | |
| 4357 | 4346 | try atom.relocs.append(self.base.allocator, .{ |
| 4358 | 4347 | .offset = @intCast(u32, offset), |
| 4359 | 4348 | .target = .{ .local = decl.link.macho.local_sym_index }, |
src/link/Plan9.zig+3-1| ... | ... | @@ -302,7 +302,9 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl: *Module.Decl) !void { |
| 302 | 302 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); |
| 303 | 303 | defer code_buffer.deinit(); |
| 304 | 304 | const decl_val = if (decl.val.castTag(.variable)) |payload| payload.data.init else decl.val; |
| 305 | const res = try codegen.generateSymbol(&self.base, @intCast(u32, decl.link.plan9.sym_index.?), decl.srcLoc(), .{ | |
| 305 | // TODO we need the symbol index for symbol in the table of locals for the containing atom | |
| 306 | const sym_index = decl.link.plan9.sym_index orelse 0; | |
| 307 | const res = try codegen.generateSymbol(&self.base, @intCast(u32, sym_index), decl.srcLoc(), .{ | |
| 306 | 308 | .ty = decl.ty, |
| 307 | 309 | .val = decl_val, |
| 308 | 310 | }, &code_buffer, .{ .none = .{} }); |