aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2025-08-30 12:08:18 -0400
committerAndrew Kelley <andrew@ziglang.org>2025-09-21 14:09:14 -0700
commitf58200e3f2967a06f343c9fc9dcae9de18def92a (patch)
tree84257e40a7a0186fbc10cf7467e65f004036d3e3 /src/codegen
parent2a97e0af6d42e038d962890a320e262e676d44cb (diff)
downloadzig-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.zig55
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,