diff options
| author | Jacob Young <jacobly0@users.noreply.github.com> | 2025-08-30 12:08:18 -0400 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2025-09-21 14:09:14 -0700 |
| commit | f58200e3f2967a06f343c9fc9dcae9de18def92a (patch) | |
| tree | 84257e40a7a0186fbc10cf7467e65f004036d3e3 /src/codegen | |
| parent | 2a97e0af6d42e038d962890a320e262e676d44cb (diff) | |
| download | zig-f58200e3f2967a06f343c9fc9dcae9de18def92a.tar.gz zig-f58200e3f2967a06f343c9fc9dcae9de18def92a.zip | |
Elf2: create a new linker from scratch
This iteration already has significantly better incremental support.
Closes #24110
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/aarch64/Mir.zig | 55 |
1 files changed, 27 insertions, 28 deletions
diff --git a/src/codegen/aarch64/Mir.zig b/src/codegen/aarch64/Mir.zig index 318a51da95..be6478eae8 100644 --- a/src/codegen/aarch64/Mir.zig +++ b/src/codegen/aarch64/Mir.zig @@ -56,13 +56,13 @@ pub fn emit( pt: Zcu.PerThread, src_loc: Zcu.LazySrcLoc, func_index: InternPool.Index, - code: *std.ArrayListUnmanaged(u8), + atom_index: u32, + w: *std.Io.Writer, debug_output: link.File.DebugInfoOutput, ) !void { _ = debug_output; const zcu = pt.zcu; const ip = &zcu.intern_pool; - const gpa = zcu.gpa; const func = zcu.funcInfo(func_index); const nav = ip.getNav(func.owner_nav); const mod = zcu.navFileScope(func.owner_nav).mod.?; @@ -81,20 +81,19 @@ pub fn emit( @as(u5, @intCast(func_align.minStrict(.@"16").toByteUnits().?)), Instruction.size, ) - 1); - try code.ensureUnusedCapacity(gpa, Instruction.size * - (code_len + literals_align_gap + mir.literals.len)); - emitInstructionsForward(code, mir.prologue); - emitInstructionsBackward(code, mir.body); - const body_end: u32 = @intCast(code.items.len); - emitInstructionsBackward(code, mir.epilogue); - code.appendNTimesAssumeCapacity(0, Instruction.size * literals_align_gap); - code.appendSliceAssumeCapacity(@ptrCast(mir.literals)); + try w.rebase(w.end, Instruction.size * (code_len + literals_align_gap + mir.literals.len)); + emitInstructionsForward(w, mir.prologue) catch unreachable; + emitInstructionsBackward(w, mir.body) catch unreachable; + const body_end: u32 = @intCast(w.end); + emitInstructionsBackward(w, mir.epilogue) catch unreachable; + w.splatByteAll(0, Instruction.size * literals_align_gap) catch unreachable; + w.writeAll(@ptrCast(mir.literals)) catch unreachable; mir_log.debug("", .{}); for (mir.nav_relocs) |nav_reloc| try emitReloc( lf, zcu, - func.owner_nav, + atom_index, switch (try @import("../../codegen.zig").genNavRef( lf, pt, @@ -112,7 +111,7 @@ pub fn emit( for (mir.uav_relocs) |uav_reloc| try emitReloc( lf, zcu, - func.owner_nav, + atom_index, switch (try lf.lowerUav( pt, uav_reloc.uav.val, @@ -129,7 +128,7 @@ pub fn emit( for (mir.lazy_relocs) |lazy_reloc| try emitReloc( lf, zcu, - func.owner_nav, + atom_index, if (lf.cast(.elf)) |ef| ef.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(ef, pt, lazy_reloc.symbol) catch |err| return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)}) @@ -150,7 +149,7 @@ pub fn emit( for (mir.global_relocs) |global_reloc| try emitReloc( lf, zcu, - func.owner_nav, + atom_index, if (lf.cast(.elf)) |ef| try ef.getGlobalSymbol(std.mem.span(global_reloc.name), null) else if (lf.cast(.macho)) |mf| @@ -168,30 +167,30 @@ pub fn emit( var instruction = mir.body[literal_reloc.label]; instruction.load_store.register_literal.group.imm19 += literal_reloc_offset; instruction.write( - code.items[body_end - Instruction.size * (1 + literal_reloc.label) ..][0..Instruction.size], + w.buffered()[body_end - Instruction.size * (1 + literal_reloc.label) ..][0..Instruction.size], ); } } -fn emitInstructionsForward(code: *std.ArrayListUnmanaged(u8), instructions: []const Instruction) void { - for (instructions) |instruction| emitInstruction(code, instruction); +fn emitInstructionsForward(w: *std.Io.Writer, instructions: []const Instruction) !void { + for (instructions) |instruction| try emitInstruction(w, instruction); } -fn emitInstructionsBackward(code: *std.ArrayListUnmanaged(u8), instructions: []const Instruction) void { +fn emitInstructionsBackward(w: *std.Io.Writer, instructions: []const Instruction) !void { var instruction_index = instructions.len; while (instruction_index > 0) { instruction_index -= 1; - emitInstruction(code, instructions[instruction_index]); + try emitInstruction(w, instructions[instruction_index]); } } -fn emitInstruction(code: *std.ArrayListUnmanaged(u8), instruction: Instruction) void { +fn emitInstruction(w: *std.Io.Writer, instruction: Instruction) !void { mir_log.debug(" {f}", .{instruction}); - instruction.write(code.addManyAsArrayAssumeCapacity(Instruction.size)); + instruction.write(try w.writableArray(Instruction.size)); } fn emitReloc( lf: *link.File, zcu: *Zcu, - owner_nav: InternPool.Nav.Index, + atom_index: u32, sym_index: u32, instruction: Instruction, offset: u32, @@ -202,7 +201,7 @@ fn emitReloc( else => unreachable, .data_processing_immediate => |decoded| if (lf.cast(.elf)) |ef| { const zo = ef.zigObjectPtr().?; - const atom = zo.symbol(try zo.getOrCreateMetadataForNav(zcu, owner_nav)).atom(ef).?; + const atom = zo.symbol(atom_index).atom(ef).?; const r_type: std.elf.R_AARCH64 = switch (decoded.decode()) { else => unreachable, .pc_relative_addressing => |pc_relative_addressing| switch (pc_relative_addressing.group.op) { @@ -221,7 +220,7 @@ fn emitReloc( }, zo); } else if (lf.cast(.macho)) |mf| { const zo = mf.getZigObject().?; - const atom = zo.symbols.items[try zo.getOrCreateMetadataForNav(mf, owner_nav)].getAtom(mf).?; + const atom = zo.symbols.items[atom_index].getAtom(mf).?; switch (decoded.decode()) { else => unreachable, .pc_relative_addressing => |pc_relative_addressing| switch (pc_relative_addressing.group.op) { @@ -260,7 +259,7 @@ fn emitReloc( }, .branch_exception_generating_system => |decoded| if (lf.cast(.elf)) |ef| { const zo = ef.zigObjectPtr().?; - const atom = zo.symbol(try zo.getOrCreateMetadataForNav(zcu, owner_nav)).atom(ef).?; + const atom = zo.symbol(atom_index).atom(ef).?; const r_type: std.elf.R_AARCH64 = switch (decoded.decode().unconditional_branch_immediate.group.op) { .b => .JUMP26, .bl => .CALL26, @@ -272,7 +271,7 @@ fn emitReloc( }, zo); } else if (lf.cast(.macho)) |mf| { const zo = mf.getZigObject().?; - const atom = zo.symbols.items[try zo.getOrCreateMetadataForNav(mf, owner_nav)].getAtom(mf).?; + const atom = zo.symbols.items[atom_index].getAtom(mf).?; try atom.addReloc(mf, .{ .tag = .@"extern", .offset = offset, @@ -289,7 +288,7 @@ fn emitReloc( }, .load_store => |decoded| if (lf.cast(.elf)) |ef| { const zo = ef.zigObjectPtr().?; - const atom = zo.symbol(try zo.getOrCreateMetadataForNav(zcu, owner_nav)).atom(ef).?; + const atom = zo.symbol(atom_index).atom(ef).?; const r_type: std.elf.R_AARCH64 = switch (decoded.decode().register_unsigned_immediate.decode()) { .integer => |integer| switch (integer.decode()) { .unallocated, .prfm => unreachable, @@ -316,7 +315,7 @@ fn emitReloc( }, zo); } else if (lf.cast(.macho)) |mf| { const zo = mf.getZigObject().?; - const atom = zo.symbols.items[try zo.getOrCreateMetadataForNav(mf, owner_nav)].getAtom(mf).?; + const atom = zo.symbols.items[atom_index].getAtom(mf).?; try atom.addReloc(mf, .{ .tag = .@"extern", .offset = offset, |
