authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-08-20 19:49:38-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-03 12:59:38-04:00
logeecbd183ccca14f904eada0b909b70812a2c9cb8
treef2761e002e5025a7aaa02f78c83b3a657e8082d2
parent4184767f7d92e8efca05756abb12cf4d448f3f7a

Dwarf2: fix crash with reify struct updates


3 files changed, 289 insertions(+), 294 deletions(-)

src/link/Dwarf2.zig+266-293
...@@ -274,7 +274,7 @@ pub const Loc = union(enum) {...@@ -274,7 +274,7 @@ pub const Loc = union(enum) {
274 stack_value: *const Loc,274 stack_value: *const Loc,
275 implicit_pointer: struct {275 implicit_pointer: struct {
276 node: MappedFile.Node.Index,276 node: MappedFile.Node.Index,
277 offset: i65,277 offset: i65 = 0,
278 },278 },
279 wasm_ext: union(enum) {279 wasm_ext: union(enum) {
280 local: u32,280 local: u32,
...@@ -299,7 +299,7 @@ pub const Loc = union(enum) {...@@ -299,7 +299,7 @@ pub const Loc = union(enum) {
299 };299 };
300 }300 }
301301
302 fn writeReg(reg: u32, op0: u8, opx: u8, writer: *Writer) Writer.Error!void {302 fn writeReg(reg: u32, op0: u8, opx: u8, writer: *std.Io.Writer) std.Io.Writer.Error!void {
303 if (std.math.cast(u5, reg)) |small_reg| {303 if (std.math.cast(u5, reg)) |small_reg| {
304 try writer.writeByte(op0 + small_reg);304 try writer.writeByte(op0 + small_reg);
305 } else {305 } else {
...@@ -308,141 +308,156 @@ pub const Loc = union(enum) {...@@ -308,141 +308,156 @@ pub const Loc = union(enum) {
308 }308 }
309 }309 }
310310
311 fn write(loc: Loc, adapter: anytype) link.EmitError!void {311 fn write(loc: Loc, writer: union(enum) {
312 const writer = adapter.writer();312 io: *std.Io.Writer,
313 mf: *MappedFile.Node.Writer,
314 }, dwarf: *Dwarf) link.EmitError!void {
315 const w = switch (writer) {
316 .io => |w| w,
317 .mf => |nw| &nw.interface,
318 };
313 switch (loc) {319 switch (loc) {
314 .empty => {},320 .empty => {},
315 .addr_reloc => |si| {321 .addr_reloc => |si| {
316 try writer.writeByte(DW.OP.addr);322 try w.writeByte(DW.OP.addr);
317 try adapter.addrSym(si);323 switch (writer) {
324 .io => try dwarf.addrPlaceholder(w),
325 .mf => |nw| try dwarf.addrSym(nw, si, 0),
326 }
318 },327 },
319 .deref => |addr| {328 .deref => |addr| {
320 try addr.write(adapter);329 try addr.write(writer, dwarf);
321 try writer.writeByte(DW.OP.deref);330 try w.writeByte(DW.OP.deref);
322 },331 },
323 .constu => |constu| if (std.math.cast(u5, constu)) |lit| {332 .constu => |constu| if (std.math.cast(u5, constu)) |lit| {
324 try writer.writeByte(@as(u8, DW.OP.lit0) + lit);333 try w.writeByte(@as(u8, DW.OP.lit0) + lit);
325 } else if (std.math.cast(u8, constu)) |const1u| {334 } else if (std.math.cast(u8, constu)) |const1u| {
326 try writer.writeAll(&.{ DW.OP.const1u, const1u });335 try w.writeAll(&.{ DW.OP.const1u, const1u });
327 } else if (std.math.cast(u16, constu)) |const2u| {336 } else if (std.math.cast(u16, constu)) |const2u| {
328 try writer.writeByte(DW.OP.const2u);337 try w.writeByte(DW.OP.const2u);
329 try writer.writeInt(u16, const2u, adapter.endian());338 try w.writeInt(u16, const2u, dwarf.endian);
330 } else if (std.math.cast(u21, constu)) |const3u| {339 } else if (std.math.cast(u21, constu)) |const3u| {
331 try writer.writeByte(DW.OP.constu);340 try w.writeByte(DW.OP.constu);
332 try writer.writeUleb128(const3u);341 try w.writeUleb128(const3u);
333 } else if (std.math.cast(u32, constu)) |const4u| {342 } else if (std.math.cast(u32, constu)) |const4u| {
334 try writer.writeByte(DW.OP.const4u);343 try w.writeByte(DW.OP.const4u);
335 try writer.writeInt(u32, const4u, adapter.endian());344 try w.writeInt(u32, const4u, dwarf.endian);
336 } else if (std.math.cast(u49, constu)) |const7u| {345 } else if (std.math.cast(u49, constu)) |const7u| {
337 try writer.writeByte(DW.OP.constu);346 try w.writeByte(DW.OP.constu);
338 try writer.writeUleb128(const7u);347 try w.writeUleb128(const7u);
339 } else {348 } else {
340 try writer.writeByte(DW.OP.const8u);349 try w.writeByte(DW.OP.const8u);
341 try writer.writeInt(u64, constu, adapter.endian());350 try w.writeInt(u64, constu, dwarf.endian);
342 },351 },
343 .consts => |consts| if (std.math.cast(i8, consts)) |const1s| {352 .consts => |consts| if (std.math.cast(i8, consts)) |const1s| {
344 try writer.writeAll(&.{ DW.OP.const1s, @bitCast(const1s) });353 try w.writeAll(&.{ DW.OP.const1s, @bitCast(const1s) });
345 } else if (std.math.cast(i16, consts)) |const2s| {354 } else if (std.math.cast(i16, consts)) |const2s| {
346 try writer.writeByte(DW.OP.const2s);355 try w.writeByte(DW.OP.const2s);
347 try writer.writeInt(i16, const2s, adapter.endian());356 try w.writeInt(i16, const2s, dwarf.endian);
348 } else if (std.math.cast(i21, consts)) |const3s| {357 } else if (std.math.cast(i21, consts)) |const3s| {
349 try writer.writeByte(DW.OP.consts);358 try w.writeByte(DW.OP.consts);
350 try writer.writeSleb128(const3s);359 try w.writeSleb128(const3s);
351 } else if (std.math.cast(i32, consts)) |const4s| {360 } else if (std.math.cast(i32, consts)) |const4s| {
352 try writer.writeByte(DW.OP.const4s);361 try w.writeByte(DW.OP.const4s);
353 try writer.writeInt(i32, const4s, adapter.endian());362 try w.writeInt(i32, const4s, dwarf.endian);
354 } else if (std.math.cast(i49, consts)) |const7s| {363 } else if (std.math.cast(i49, consts)) |const7s| {
355 try writer.writeByte(DW.OP.consts);364 try w.writeByte(DW.OP.consts);
356 try writer.writeSleb128(const7s);365 try w.writeSleb128(const7s);
357 } else {366 } else {
358 try writer.writeByte(DW.OP.const8s);367 try w.writeByte(DW.OP.const8s);
359 try writer.writeInt(i64, consts, adapter.endian());368 try w.writeInt(i64, consts, dwarf.endian);
360 },369 },
361 .plus => |plus| done: {370 .plus => |plus| done: {
362 if (plus[0].getConst(u0)) |_| {371 if (plus[0].getConst(u0)) |_| {
363 try plus[1].write(adapter);372 try plus[1].write(writer, dwarf);
364 break :done;373 break :done;
365 }374 }
366 if (plus[1].getConst(u0)) |_| {375 if (plus[1].getConst(u0)) |_| {
367 try plus[0].write(adapter);376 try plus[0].write(writer, dwarf);
368 break :done;377 break :done;
369 }378 }
370 if (plus[0].getBaseReg()) |breg| {379 if (plus[0].getBaseReg()) |breg| {
371 if (plus[1].getConst(i65)) |offset| {380 if (plus[1].getConst(i65)) |offset| {
372 try writeReg(breg, DW.OP.breg0, DW.OP.bregx, writer);381 try writeReg(breg, DW.OP.breg0, DW.OP.bregx, w);
373 try writer.writeSleb128(offset);382 try w.writeSleb128(offset);
374 break :done;383 break :done;
375 }384 }
376 }385 }
377 if (plus[1].getBaseReg()) |breg| {386 if (plus[1].getBaseReg()) |breg| {
378 if (plus[0].getConst(i65)) |offset| {387 if (plus[0].getConst(i65)) |offset| {
379 try writeReg(breg, DW.OP.breg0, DW.OP.bregx, writer);388 try writeReg(breg, DW.OP.breg0, DW.OP.bregx, w);
380 try writer.writeSleb128(offset);389 try w.writeSleb128(offset);
381 break :done;390 break :done;
382 }391 }
383 }392 }
384 if (plus[0].getConst(u64)) |uconst| {393 if (plus[0].getConst(u64)) |uconst| {
385 try plus[1].write(adapter);394 try plus[1].write(writer, dwarf);
386 try writer.writeByte(DW.OP.plus_uconst);395 try w.writeByte(DW.OP.plus_uconst);
387 try writer.writeUleb128(uconst);396 try w.writeUleb128(uconst);
388 break :done;397 break :done;
389 }398 }
390 if (plus[1].getConst(u64)) |uconst| {399 if (plus[1].getConst(u64)) |uconst| {
391 try plus[0].write(adapter);400 try plus[0].write(writer, dwarf);
392 try writer.writeByte(DW.OP.plus_uconst);401 try w.writeByte(DW.OP.plus_uconst);
393 try writer.writeUleb128(uconst);402 try w.writeUleb128(uconst);
394 break :done;403 break :done;
395 }404 }
396 try plus[0].write(adapter);405 try plus[0].write(writer, dwarf);
397 try plus[1].write(adapter);406 try plus[1].write(writer, dwarf);
398 try writer.writeByte(DW.OP.plus);407 try w.writeByte(DW.OP.plus);
399 },408 },
400 .reg => |reg| try writeReg(reg, DW.OP.reg0, DW.OP.regx, writer),409 .reg => |reg| try writeReg(reg, DW.OP.reg0, DW.OP.regx, w),
401 .breg => |breg| {410 .breg => |breg| {
402 try writeReg(breg, DW.OP.breg0, DW.OP.bregx, writer);411 try writeReg(breg, DW.OP.breg0, DW.OP.bregx, w);
403 try writer.writeSleb128(0);412 try w.writeSleb128(0);
404 },413 },
405 .push_object_address => try writer.writeByte(DW.OP.push_object_address),414 .push_object_address => try w.writeByte(DW.OP.push_object_address),
406 .call => |call| {415 .call => |call| {
407 for (call.args) |arg| try arg.write(adapter);416 for (call.args) |arg| try arg.write(writer, dwarf);
408 try writer.writeByte(DW.OP.call_ref);417 try w.writeByte(DW.OP.call_ref);
409 try adapter.infoEntry(call.node);418 switch (writer) {
419 .io => try dwarf.secOffsetPlaceholder(w),
420 .mf => |nw| try dwarf.secOffset(nw, call.node, 0),
421 }
410 },422 },
411 .form_tls_address => |addr| {423 .form_tls_address => |addr| {
412 try addr.write(adapter);424 try addr.write(writer, dwarf);
413 try writer.writeByte(DW.OP.form_tls_address);425 try w.writeByte(DW.OP.form_tls_address);
414 },426 },
415 .implicit_value => |value| {427 .implicit_value => |value| {
416 try writer.writeByte(DW.OP.implicit_value);428 try w.writeByte(DW.OP.implicit_value);
417 try writer.writeUleb128(value.len);429 try w.writeUleb128(value.len);
418 try writer.writeAll(value);430 try w.writeAll(value);
419 },431 },
420 .stack_value => |value| {432 .stack_value => |value| {
421 try value.write(adapter);433 try value.write(writer, dwarf);
422 try writer.writeByte(DW.OP.stack_value);434 try w.writeByte(DW.OP.stack_value);
423 },435 },
424 .implicit_pointer => |implicit_pointer| {436 .implicit_pointer => |implicit_pointer| {
425 try writer.writeByte(DW.OP.implicit_pointer);437 try w.writeByte(DW.OP.implicit_pointer);
426 try adapter.infoEntry(implicit_pointer.node);438 switch (writer) {
427 try writer.writeSleb128(implicit_pointer.offset);439 .io => try dwarf.secOffsetPlaceholder(w),
440 .mf => |nw| try dwarf.secOffset(nw, implicit_pointer.node, 0),
441 }
442 try w.writeSleb128(implicit_pointer.offset);
428 },443 },
429 .wasm_ext => |wasm_ext| {444 .wasm_ext => |wasm_ext| {
430 try writer.writeByte(DW.OP.WASM_location);445 try w.writeByte(DW.OP.WASM_location);
431 switch (wasm_ext) {446 switch (wasm_ext) {
432 .local => |local| {447 .local => |local| {
433 try writer.writeByte(DW.OP.WASM_local);448 try w.writeByte(DW.OP.WASM_local);
434 try writer.writeUleb128(local);449 try w.writeUleb128(local);
435 },450 },
436 .global => |global| if (std.math.cast(u21, global)) |global_u21| {451 .global => |global| if (std.math.cast(u21, global)) |global_u21| {
437 try writer.writeByte(DW.OP.WASM_global);452 try w.writeByte(DW.OP.WASM_global);
438 try writer.writeUleb128(global_u21);453 try w.writeUleb128(global_u21);
439 } else {454 } else {
440 try writer.writeByte(DW.OP.WASM_global_u32);455 try w.writeByte(DW.OP.WASM_global_u32);
441 try writer.writeInt(u32, global, adapter.endian());456 try w.writeInt(u32, global, dwarf.endian);
442 },457 },
443 .operand_stack => |operand_stack| {458 .operand_stack => |operand_stack| {
444 try writer.writeByte(DW.OP.WASM_operand_stack);459 try w.writeByte(DW.OP.WASM_operand_stack);
445 try writer.writeUleb128(operand_stack);460 try w.writeUleb128(operand_stack);
446 },461 },
447 }462 }
448 },463 },
...@@ -574,12 +589,12 @@ pub const Cfa = union(enum) {...@@ -574,12 +589,12 @@ pub const Cfa = union(enum) {
574 },589 },
575 .def_cfa_expression => |expr| {590 .def_cfa_expression => |expr| {
576 try dfw.writeByte(DW.CFA.def_cfa_expression);591 try dfw.writeByte(DW.CFA.def_cfa_expression);
577 try wip_nav.frameExprLoc(expr);592 try wip_nav.dwarf.exprLoc(&wip_nav.fde_writer, expr);
578 },593 },
579 .expression => |reg_expr| {594 .expression => |reg_expr| {
580 try dfw.writeByte(DW.CFA.expression);595 try dfw.writeByte(DW.CFA.expression);
581 try dfw.writeUleb128(reg_expr.reg);596 try dfw.writeUleb128(reg_expr.reg);
582 try wip_nav.frameExprLoc(reg_expr.expr);597 try wip_nav.dwarf.exprLoc(&wip_nav.fde_writer, reg_expr.expr);
583 },598 },
584 .val_offset => |reg_off| {599 .val_offset => |reg_off| {
585 const factored_off =600 const factored_off =
...@@ -597,7 +612,7 @@ pub const Cfa = union(enum) {...@@ -597,7 +612,7 @@ pub const Cfa = union(enum) {
597 .val_expression => |reg_expr| {612 .val_expression => |reg_expr| {
598 try dfw.writeByte(DW.CFA.val_expression);613 try dfw.writeByte(DW.CFA.val_expression);
599 try dfw.writeUleb128(reg_expr.reg);614 try dfw.writeUleb128(reg_expr.reg);
600 try wip_nav.frameExprLoc(reg_expr.expr);615 try wip_nav.dwarf.exprLoc(&wip_nav.fde_writer, reg_expr.expr);
601 },616 },
602 .escape => |bytes| try dfw.writeAll(bytes),617 .escape => |bytes| try dfw.writeAll(bytes),
603 }618 }
...@@ -678,7 +693,7 @@ pub const WipNav = struct {...@@ -678,7 +693,7 @@ pub const WipNav = struct {
678 .@"extern", .@"export" => nav.name,693 .@"extern", .@"export" => nav.name,
679 }.toSlice(ip));694 }.toSlice(ip));
680 try dwarf.refConst(pt, di_nw, .fromInterned(func_type.return_type));695 try dwarf.refConst(pt, di_nw, .fromInterned(func_type.return_type));
681 try dwarf.symbolAddress(di_nw, debug.wip_nav.func_si, 0);696 try dwarf.addrSym(di_nw, debug.wip_nav.func_si, 0);
682 debug.info_func_length_offset = diw.end;697 debug.info_func_length_offset = diw.end;
683 try diw.writeInt(u32, undefined, dwarf.endian);698 try diw.writeInt(u32, undefined, dwarf.endian);
684 try diw.writeUleb128(699 try diw.writeUleb128(
...@@ -706,9 +721,9 @@ pub const WipNav = struct {...@@ -706,9 +721,9 @@ pub const WipNav = struct {
706 const dlw = &debug.line_writer.interface;721 const dlw = &debug.line_writer.interface;
707 try dlw.writeByte(DW.LNS.extended_op);722 try dlw.writeByte(DW.LNS.extended_op);
708 if (zcu.comp.config.incremental) {723 if (zcu.comp.config.incremental) {
709 try dlw.writeUleb128(1 + dwarf.sectionOffsetSize());724 try dlw.writeUleb128(1 + dwarf.secOffsetSize());
710 try dlw.writeByte(DW.LNE.ZIG_set_decl);725 try dlw.writeByte(DW.LNE.ZIG_set_decl);
711 try dwarf.sectionOffset(&debug.line_writer, debug.info_writer.ni, 0);726 try dwarf.secOffset(&debug.line_writer, debug.info_writer.ni, 0);
712727
713 try dlw.writeByte(DW.LNS.set_column);728 try dlw.writeByte(DW.LNS.set_column);
714 try dlw.writeUleb128(func.lbrace_column + 1);729 try dlw.writeUleb128(func.lbrace_column + 1);
...@@ -717,7 +732,7 @@ pub const WipNav = struct {...@@ -717,7 +732,7 @@ pub const WipNav = struct {
717 } else {732 } else {
718 try dlw.writeUleb128(1 + @backingInt(dwarf.address_size));733 try dlw.writeUleb128(1 + @backingInt(dwarf.address_size));
719 try dlw.writeByte(DW.LNE.set_address);734 try dlw.writeByte(DW.LNE.set_address);
720 try dwarf.symbolAddress(&debug.line_writer, debug.wip_nav.func_si, 0);735 try dwarf.addrSym(&debug.line_writer, debug.wip_nav.func_si, 0);
721736
722 const unit = dwarf.getUnit(zf.mod.?);737 const unit = dwarf.getUnit(zf.mod.?);
723 _, const fi = try unit.get(dwarf).getFile(zcu.gpa, unit, inst_info.file);738 _, const fi = try unit.get(dwarf).getFile(zcu.gpa, unit, inst_info.file);
...@@ -788,7 +803,7 @@ pub const WipNav = struct {...@@ -788,7 +803,7 @@ pub const WipNav = struct {
788 }));803 }));
789 if (opt_name) |name| try dwarf.strp(&dwarf.debug_str, di_nw, name);804 if (opt_name) |name| try dwarf.strp(&dwarf.debug_str, di_nw, name);
790 try dwarf.refConst(debug.pt, di_nw, ty.toValue());805 try dwarf.refConst(debug.pt, di_nw, ty.toValue());
791 try debug.infoExprLoc(loc);806 try dwarf.exprLoc(&debug.info_writer, loc);
792 debug.any_children = true;807 debug.any_children = true;
793 }808 }
794809
...@@ -873,7 +888,7 @@ pub const WipNav = struct {...@@ -873,7 +888,7 @@ pub const WipNav = struct {
873 delta_line: i33,888 delta_line: i33,
874 delta_pc: u64,889 delta_pc: u64,
875 end: bool,890 end: bool,
876 ) Writer.Error!void {891 ) std.Io.Writer.Error!void {
877 const dlw = &debug.line_writer.interface;892 const dlw = &debug.line_writer.interface;
878893
879 const header = debug.wip_nav.dwarf.debug_line.header;894 const header = debug.wip_nav.dwarf.debug_line.header;
...@@ -923,7 +938,7 @@ pub const WipNav = struct {...@@ -923,7 +938,7 @@ pub const WipNav = struct {
923 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),938 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
924 };939 };
925 }940 }
926 fn setColumnInner(debug: *Debug, column: u32) Writer.Error!void {941 fn setColumnInner(debug: *Debug, column: u32) std.Io.Writer.Error!void {
927 const dlw = &debug.line_writer.interface;942 const dlw = &debug.line_writer.interface;
928 try dlw.writeByte(DW.LNS.set_column);943 try dlw.writeByte(DW.LNS.set_column);
929 try dlw.writeUleb128(column + 1);944 try dlw.writeUleb128(column + 1);
...@@ -934,7 +949,7 @@ pub const WipNav = struct {...@@ -934,7 +949,7 @@ pub const WipNav = struct {
934 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),949 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
935 };950 };
936 }951 }
937 fn negateStmtInner(debug: *Debug) Writer.Error!void {952 fn negateStmtInner(debug: *Debug) std.Io.Writer.Error!void {
938 try debug.line_writer.interface.writeByte(DW.LNS.negate_stmt);953 try debug.line_writer.interface.writeByte(DW.LNS.negate_stmt);
939 }954 }
940955
...@@ -943,7 +958,7 @@ pub const WipNav = struct {...@@ -943,7 +958,7 @@ pub const WipNav = struct {
943 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),958 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
944 };959 };
945 }960 }
946 fn setPrologueEndInner(debug: *Debug) Writer.Error!void {961 fn setPrologueEndInner(debug: *Debug) std.Io.Writer.Error!void {
947 try debug.line_writer.interface.writeByte(DW.LNS.set_prologue_end);962 try debug.line_writer.interface.writeByte(DW.LNS.set_prologue_end);
948 }963 }
949964
...@@ -952,7 +967,7 @@ pub const WipNav = struct {...@@ -952,7 +967,7 @@ pub const WipNav = struct {
952 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),967 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
953 };968 };
954 }969 }
955 fn setEpilogueBeginInner(debug: *Debug) Writer.Error!void {970 fn setEpilogueBeginInner(debug: *Debug) std.Io.Writer.Error!void {
956 try debug.line_writer.interface.writeByte(DW.LNS.set_epilogue_begin);971 try debug.line_writer.interface.writeByte(DW.LNS.set_epilogue_begin);
957 }972 }
958973
...@@ -970,7 +985,7 @@ pub const WipNav = struct {...@@ -970,7 +985,7 @@ pub const WipNav = struct {
970 block.abbrev_code = @intCast(diw.end);985 block.abbrev_code = @intCast(diw.end);
971 try diw.writeUleb128(try dwarf.refAbbrevCode(.block));986 try diw.writeUleb128(try dwarf.refAbbrevCode(.block));
972 block.low_pc_off = code_off;987 block.low_pc_off = code_off;
973 try debug.infoAddrSym(debug.wip_nav.func_si, code_off);988 try dwarf.addrSym(&debug.info_writer, debug.wip_nav.func_si, code_off);
974 block.high_pc = @intCast(diw.end);989 block.high_pc = @intCast(diw.end);
975 try diw.writeInt(u32, 0, dwarf.endian);990 try diw.writeInt(u32, 0, dwarf.endian);
976 debug.any_children = false;991 debug.any_children = false;
...@@ -1037,7 +1052,7 @@ pub const WipNav = struct {...@@ -1037,7 +1052,7 @@ pub const WipNav = struct {
1037 try diw.writeUleb128(line);1052 try diw.writeUleb128(line);
1038 try diw.writeUleb128(column + 1);1053 try diw.writeUleb128(column + 1);
1039 block.low_pc_off = code_off;1054 block.low_pc_off = code_off;
1040 try debug.infoAddrSym(debug.wip_nav.func_si, code_off);1055 try dwarf.addrSym(&debug.info_writer, debug.wip_nav.func_si, code_off);
1041 block.high_pc = @intCast(diw.end);1056 block.high_pc = @intCast(diw.end);
1042 try diw.writeInt(u32, 0, dwarf.endian);1057 try diw.writeInt(u32, 0, dwarf.endian);
1043 try debug.setInlineFunc(func);1058 try debug.setInlineFunc(func);
...@@ -1094,9 +1109,9 @@ pub const WipNav = struct {...@@ -1094,9 +1109,9 @@ pub const WipNav = struct {
1094 if (zcu.comp.config.incremental) {1109 if (zcu.comp.config.incremental) {
1095 const new_func = try dwarf.getFunc(new_owner_nav);1110 const new_func = try dwarf.getFunc(new_owner_nav);
1096 try dlw.writeByte(DW.LNS.extended_op);1111 try dlw.writeByte(DW.LNS.extended_op);
1097 try dlw.writeUleb128(1 + dwarf.sectionOffsetSize());1112 try dlw.writeUleb128(1 + dwarf.secOffsetSize());
1098 try dlw.writeByte(DW.LNE.ZIG_set_decl);1113 try dlw.writeByte(DW.LNE.ZIG_set_decl);
1099 try dwarf.sectionOffset(1114 try dwarf.secOffset(
1100 &debug.line_writer,1115 &debug.line_writer,
1101 new_func.get(dwarf).debug_info_ni.unwrap().?,1116 new_func.get(dwarf).debug_info_ni.unwrap().?,
1102 0,1117 0,
...@@ -1128,38 +1143,10 @@ pub const WipNav = struct {...@@ -1128,38 +1143,10 @@ pub const WipNav = struct {
1128 debug.wip_nav.func = func;1143 debug.wip_nav.func = func;
1129 }1144 }
11301145
1131 fn infoExprLoc(debug: *Debug, loc: Loc) link.EmitError!void {
1132 var buf: [64]u8 = undefined;
1133 var counter: ExprLocCounter = .init(debug.wip_nav.dwarf, &buf);
1134 try loc.write(&counter);
1135
1136 const adapter: struct {
1137 debug: *Debug,
1138 fn writer(ctx: @This()) *Writer {
1139 return &ctx.debug.info_writer.interface;
1140 }
1141 fn endian(ctx: @This()) std.lang.Endian {
1142 return ctx.debug.wip_nav.dwarf.endian;
1143 }
1144 fn addrSym(ctx: @This(), si: link.File.SymbolId) link.EmitError!void {
1145 try ctx.debug.infoAddrSym(si, 0);
1146 }
1147 fn infoEntry(ctx: @This(), ni: MappedFile.Node.Index) link.EmitError!void {
1148 try ctx.debug.wip_nav.dwarf.sectionOffset(&ctx.debug.info_writer, ni, 0);
1149 }
1150 } = .{ .debug = debug };
1151 try adapter.writer().writeUleb128(counter.dw.fullCount());
1152 try loc.write(adapter);
1153 }
1154
1155 fn infoAddrSym(debug: *Debug, si: link.File.SymbolId, addend: usize) link.EmitError!void {
1156 try debug.wip_nav.dwarf.symbolAddress(&debug.info_writer, si, addend);
1157 }
1158
1159 fn refFunc(debug: *Debug, func: InternPool.Index) link.EmitError!void {1146 fn refFunc(debug: *Debug, func: InternPool.Index) link.EmitError!void {
1160 const dwarf = debug.wip_nav.dwarf;1147 const dwarf = debug.wip_nav.dwarf;
1161 const fi = try dwarf.getFunc(debug.pt.zcu.funcInfo(func).owner_nav);1148 const fi = try dwarf.getFunc(debug.pt.zcu.funcInfo(func).owner_nav);
1162 try debug.wip_nav.dwarf.sectionOffset(1149 try debug.wip_nav.dwarf.secOffset(
1163 &debug.info_writer,1150 &debug.info_writer,
1164 fi.get(dwarf).debug_info_ni.unwrap().?,1151 fi.get(dwarf).debug_info_ni.unwrap().?,
1165 0,1152 0,
...@@ -1203,14 +1190,10 @@ pub const WipNav = struct {...@@ -1203,14 +1190,10 @@ pub const WipNav = struct {
1203 try dfw.writeUleb128(0);1190 try dfw.writeUleb128(0);
1204 },1191 },
1205 .debug_frame => {1192 .debug_frame => {
1206 try dwarf.sectionOffset(1193 try dwarf.secOffset(&wip_nav.fde_writer, wip_nav.unit.get(dwarf).cie_ni.unwrap().?, 0);
1207 &wip_nav.fde_writer,1194 try dwarf.addrSym(&wip_nav.fde_writer, wip_nav.func_si, 0);
1208 wip_nav.unit.get(dwarf).cie_ni.unwrap().?,
1209 0,
1210 );
1211 try wip_nav.frameAddrSym(wip_nav.func_si, 0);
1212 wip_nav.frame_func_length = .{ .offset = dfw.end, .size = dwarf.address_size };1195 wip_nav.frame_func_length = .{ .offset = dfw.end, .size = dwarf.address_size };
1213 try dfw.splatByteAll(undefined, @backingInt(dwarf.address_size));1196 try dwarf.addrPlaceholder(dfw);
1214 },1197 },
1215 }1198 }
1216 }1199 }
...@@ -1248,78 +1231,6 @@ pub const WipNav = struct {...@@ -1248,78 +1231,6 @@ pub const WipNav = struct {
1248 }1231 }
1249 @memset(dfw.unusedCapacitySlice(), DW.CFA.nop);1232 @memset(dfw.unusedCapacitySlice(), DW.CFA.nop);
1250 }1233 }
1251
1252 const ExprLocCounter = struct {
1253 dw: Writer.Discarding,
1254 section_offset_size: usize,
1255 address_size: AddressSize,
1256 fn init(dwarf: *Dwarf, buf: []u8) ExprLocCounter {
1257 return .{
1258 .dw = .init(buf),
1259 .section_offset_size = dwarf.sectionOffsetSize(),
1260 .address_size = dwarf.address_size,
1261 };
1262 }
1263 fn writer(counter: *ExprLocCounter) *Writer {
1264 return &counter.dw.writer;
1265 }
1266 fn endian(_: ExprLocCounter) std.lang.Endian {
1267 return .native;
1268 }
1269 fn addrSym(counter: *ExprLocCounter, _: link.File.SymbolId) Writer.Error!void {
1270 try counter.dw.writer.splatByteAll(undefined, @backingInt(counter.address_size));
1271 }
1272 fn infoEntry(counter: *ExprLocCounter, _: MappedFile.Node.Index) Writer.Error!void {
1273 try counter.dw.writer.splatByteAll(undefined, counter.section_offset_size);
1274 }
1275 };
1276
1277 fn frameExprLoc(wip_nav: *WipNav, loc: Loc) link.EmitError!void {
1278 var buf: [64]u8 = undefined;
1279 var counter: ExprLocCounter = .init(wip_nav.dwarf, &buf);
1280 try loc.write(&counter);
1281
1282 const adapter: struct {
1283 wip_nav: *WipNav,
1284 fn writer(ctx: @This()) *Writer {
1285 return &ctx.wip_nav.fde_writer.interface;
1286 }
1287 fn endian(ctx: @This()) std.lang.Endian {
1288 return ctx.wip_nav.dwarf.endian;
1289 }
1290 fn addrSym(ctx: @This(), si: link.File.SymbolId) link.EmitError!void {
1291 try ctx.wip_nav.frameAddrSym(si, 0);
1292 }
1293 fn infoEntry(ctx: @This(), ni: MappedFile.Node.Index) link.EmitError!void {
1294 try ctx.wip_nav.dwarf.sectionOffset(&ctx.wip_nav.fde_writer, ni, 0);
1295 }
1296 } = .{ .wip_nav = wip_nav };
1297 try adapter.writer().writeUleb128(counter.dw.fullCount());
1298 try loc.write(adapter);
1299 }
1300
1301 fn frameAddrSym(
1302 wip_nav: *WipNav,
1303 si: link.File.SymbolId,
1304 sym_off: u64,
1305 ) link.EmitError!void {
1306 const dwarf = wip_nav.dwarf;
1307 const dfw = &wip_nav.fde_writer.interface;
1308 const offset = dfw.end;
1309 try dfw.splatByteAll(0, @backingInt(dwarf.address_size));
1310 const elf = dwarf.lf.cast(.elf2).?;
1311 try elf.addReloc(
1312 @bitCast(wip_nav.fde_writer.ni),
1313 offset,
1314 si,
1315 @bitCast(sym_off),
1316 switch (dwarf.address_size) {
1317 else => unreachable,
1318 .@"32" => .abs32(elf),
1319 .@"64" => .abs64(elf),
1320 },
1321 );
1322 }
1323};1234};
13241235
1325pub fn init(lf: *link.File, format: DW.Format) Dwarf {1236pub fn init(lf: *link.File, format: DW.Format) Dwarf {
...@@ -1632,13 +1543,7 @@ pub fn unitLengthSize(dwarf: *Dwarf) usize {...@@ -1632,13 +1543,7 @@ pub fn unitLengthSize(dwarf: *Dwarf) usize {
1632 .@"64" => 4 + 8,1543 .@"64" => 4 + 8,
1633 };1544 };
1634}1545}
1635pub fn sectionOffsetSize(dwarf: *Dwarf) usize {1546pub fn genUnitLength(dwarf: *Dwarf, w: *std.Io.Writer) std.Io.Writer.Error!void {
1636 return switch (dwarf.format) {
1637 .@"32" => 4,
1638 .@"64" => 8,
1639 };
1640}
1641pub fn genUnitLength(dwarf: *Dwarf, w: *Writer) Writer.Error!void {
1642 switch (dwarf.format) {1547 switch (dwarf.format) {
1643 .@"32" => try w.writeInt(u32, undefined, dwarf.endian),1548 .@"32" => try w.writeInt(u32, undefined, dwarf.endian),
1644 .@"64" => {1549 .@"64" => {
...@@ -1654,7 +1559,7 @@ pub fn updateUnitLength(dwarf: *Dwarf, header: []u8, unit_length: u64) void {...@@ -1654,7 +1559,7 @@ pub fn updateUnitLength(dwarf: *Dwarf, header: []u8, unit_length: u64) void {
1654 }1559 }
1655}1560}
16561561
1657pub fn genUnitPadding(dwarf: *Dwarf, w: *Writer) Writer.Error!void {1562pub fn genUnitPadding(dwarf: *Dwarf, w: *std.Io.Writer) std.Io.Writer.Error!void {
1658 try dwarf.genUnitLength(w);1563 try dwarf.genUnitLength(w);
1659 try w.writeInt(u16, 0, dwarf.endian);1564 try w.writeInt(u16, 0, dwarf.endian);
1660}1565}
...@@ -1691,11 +1596,11 @@ pub fn genEhFrameHdr(...@@ -1691,11 +1596,11 @@ pub fn genEhFrameHdr(
16911596
1692pub fn genDebugFrameCie(1597pub fn genDebugFrameCie(
1693 dwarf: *Dwarf,1598 dwarf: *Dwarf,
1694 dfw: *Writer,1599 dfw: *std.Io.Writer,
1695 /// `null` means to generate an architecture-agnostic padding cie1600 /// `null` means to generate an architecture-agnostic padding cie
1696 arch: ?std.Target.Cpu.Arch,1601 arch: ?std.Target.Cpu.Arch,
1697 format: Frame.Format,1602 format: Frame.Format,
1698) Writer.Error!void {1603) std.Io.Writer.Error!void {
1699 try dwarf.genUnitLength(dfw);1604 try dwarf.genUnitLength(dfw);
1700 switch (format) {1605 switch (format) {
1701 .eh_frame => try dfw.writeInt(u32, 0, dwarf.endian),1606 .eh_frame => try dfw.writeInt(u32, 0, dwarf.endian),
...@@ -1768,7 +1673,7 @@ pub fn genDebugInfoHeader(...@@ -1768,7 +1673,7 @@ pub fn genDebugInfoHeader(
1768 try dihw.writeInt(u16, 5, dwarf.endian);1673 try dihw.writeInt(u16, 5, dwarf.endian);
1769 try dihw.writeByte(DW.UT.compile);1674 try dihw.writeByte(DW.UT.compile);
1770 try dihw.writeByte(@backingInt(dwarf.address_size));1675 try dihw.writeByte(@backingInt(dwarf.address_size));
1771 try dwarf.sectionOffset(dih_nw, dwarf.debug_abbrev.ni.unwrap().?, 0);1676 try dwarf.secOffset(dih_nw, dwarf.debug_abbrev.ni.unwrap().?, 0);
1772 const compile_unit_offset = dihw.end;1677 const compile_unit_offset = dihw.end;
1773 try dihw.writeUleb128(try dwarf.refAbbrevCode(.compile_unit));1678 try dihw.writeUleb128(try dwarf.refAbbrevCode(.compile_unit));
1774 try dihw.writeByte(DW.LANG.Zig);1679 try dihw.writeByte(DW.LANG.Zig);
...@@ -1777,17 +1682,13 @@ pub fn genDebugInfoHeader(...@@ -1777,17 +1682,13 @@ pub fn genDebugInfoHeader(
1777 defer comp.gpa.free(root_dir_path);1682 defer comp.gpa.free(root_dir_path);
1778 try dwarf.strp(&dwarf.debug_line_str, dih_nw, root_dir_path);1683 try dwarf.strp(&dwarf.debug_line_str, dih_nw, root_dir_path);
1779 try dwarf.strp(&dwarf.debug_line_str, dih_nw, mod.root_src_path);1684 try dwarf.strp(&dwarf.debug_line_str, dih_nw, mod.root_src_path);
1780 try dwarf.sectionOffset(1685 try dwarf.secOffset(
1781 dih_nw,1686 dih_nw,
1782 dwarf.getUnit(zcu.root_mod).get(dwarf).debug_info_header_ni.unwrap().?,1687 dwarf.getUnit(zcu.root_mod).get(dwarf).debug_info_header_ni.unwrap().?,
1783 compile_unit_offset,1688 compile_unit_offset,
1784 );1689 );
1785 try dwarf.sectionOffset(dih_nw, unit.debug_line_header_ni.unwrap().?, 0);1690 try dwarf.secOffset(dih_nw, unit.debug_line_header_ni.unwrap().?, 0);
1786 try dwarf.sectionOffset(1691 try dwarf.secOffset(dih_nw, unit.debug_rnglists_ni.unwrap().?, Rnglists.offsetsTableOffset(dwarf));
1787 dih_nw,
1788 unit.debug_rnglists_ni.unwrap().?,
1789 Rnglists.offsetsTableOffset(dwarf),
1790 );
1791 try dihw.writeUleb128(0);1692 try dihw.writeUleb128(0);
1792 const module_offset = dihw.end;1693 const module_offset = dihw.end;
1793 try dihw.writeUleb128(try dwarf.refAbbrevCode(.module));1694 try dihw.writeUleb128(try dwarf.refAbbrevCode(.module));
...@@ -1819,10 +1720,10 @@ fn genModuleDependency(...@@ -1819,10 +1720,10 @@ fn genModuleDependency(
1819 const diw = &di_nw.interface;1720 const diw = &di_nw.interface;
1820 try diw.writeUleb128(try dwarf.refAbbrevCode(.module_dependency));1721 try diw.writeUleb128(try dwarf.refAbbrevCode(.module_dependency));
1821 try dwarf.strp(&dwarf.debug_str, di_nw, name);1722 try dwarf.strp(&dwarf.debug_str, di_nw, name);
1822 try dwarf.sectionOffset(di_nw, dep_unit.debug_info_header_ni.unwrap().?, module_offset);1723 try dwarf.secOffset(di_nw, dep_unit.debug_info_header_ni.unwrap().?, module_offset);
1823}1724}
18241725
1825pub fn genDebugInfoPadding(dwarf: *Dwarf, diw: *Writer, size: u64) Writer.Error!void {1726pub fn genDebugInfoPadding(dwarf: *Dwarf, diw: *std.Io.Writer, size: u64) std.Io.Writer.Error!void {
1826 switch (size) {1727 switch (size) {
1827 0 => {},1728 0 => {},
1828 1 => try diw.writeUleb128(dwarf.refAbbrevCodeIfExists(.pad_1).?),1729 1 => try diw.writeUleb128(dwarf.refAbbrevCodeIfExists(.pad_1).?),
...@@ -1951,7 +1852,7 @@ pub fn genDebugLineHeader(...@@ -1951,7 +1852,7 @@ pub fn genDebugLineHeader(
1951 try genDebugLinePadding(dlhw, dlhw.unusedCapacityLen());1852 try genDebugLinePadding(dlhw, dlhw.unusedCapacityLen());
1952}1853}
19531854
1954pub fn genDebugLinePadding(dlw: *Writer, size: u64) Writer.Error!void {1855pub fn genDebugLinePadding(dlw: *std.Io.Writer, size: u64) std.Io.Writer.Error!void {
1955 switch (size) {1856 switch (size) {
1956 0 => {},1857 0 => {},
1957 1 => try dlw.writeByte(DW.LNS.const_add_pc),1858 1 => try dlw.writeByte(DW.LNS.const_add_pc),
...@@ -1980,7 +1881,7 @@ pub fn genDebugRnglistsHeader(...@@ -1980,7 +1881,7 @@ pub fn genDebugRnglistsHeader(
1980 dwarf: *Dwarf,1881 dwarf: *Dwarf,
1981 unit: *Unit,1882 unit: *Unit,
1982 drh_nw: *MappedFile.Node.Writer,1883 drh_nw: *MappedFile.Node.Writer,
1983) Writer.Error!void {1884) std.Io.Writer.Error!void {
1984 const drhw = &drh_nw.interface;1885 const drhw = &drh_nw.interface;
1985 try dwarf.genUnitLength(drhw);1886 try dwarf.genUnitLength(drhw);
1986 try drhw.writeInt(u16, 5, dwarf.endian);1887 try drhw.writeInt(u16, 5, dwarf.endian);
...@@ -2006,7 +1907,7 @@ pub fn genDebugRnglists(...@@ -2006,7 +1907,7 @@ pub fn genDebugRnglists(
2006 const drw = &dr_nw.interface;1907 const drw = &dr_nw.interface;
2007 drw.end = unit.debug_rnglists_end;1908 drw.end = unit.debug_rnglists_end;
2008 try drw.writeByte(DW.RLE.start_length);1909 try drw.writeByte(DW.RLE.start_length);
2009 try dwarf.symbolAddress(dr_nw, func_si, 0);1910 try dwarf.addrSym(dr_nw, func_si, 0);
2010 try drw.writeUleb128(func_length);1911 try drw.writeUleb128(func_length);
2011 unit.debug_rnglists_end = drw.end;1912 unit.debug_rnglists_end = drw.end;
2012 try drw.writeByte(DW.RLE.end_of_list);1913 try drw.writeByte(DW.RLE.end_of_list);
...@@ -2063,9 +1964,12 @@ pub fn updateComptimeNav(...@@ -2063,9 +1964,12 @@ pub fn updateComptimeNav(
2063 const fi = try dwarf.getFunc(func.owner_nav);1964 const fi = try dwarf.getFunc(func.owner_nav);
2064 const f = fi.get(dwarf);1965 const f = fi.get(dwarf);
2065 if (f.fde_ni != .none or f.debug_line_ni != .none) return;1966 if (f.fde_ni != .none or f.debug_line_ni != .none) return;
1967 const elf = dwarf.lf.cast(.elf2).?;
1968 const debug_info_ni = f.debug_info_ni.unwrap().?;
2066 var di_nw: MappedFile.Node.Writer = undefined;1969 var di_nw: MappedFile.Node.Writer = undefined;
2067 f.debug_info_ni.unwrap().?.writer(zcu.gpa, &dwarf.lf.cast(.elf2).?.mf, &di_nw);1970 debug_info_ni.writer(zcu.gpa, &elf.mf, &di_nw);
2068 defer di_nw.deinit();1971 defer di_nw.deinit();
1972 elf.resetNodeRelocs(debug_info_ni);
2069 dwarf.genDeclFuncGeneric(1973 dwarf.genDeclFuncGeneric(
2070 pt,1974 pt,
2071 &di_nw,1975 &di_nw,
...@@ -2221,17 +2125,17 @@ fn updateConstInner(...@@ -2221,17 +2125,17 @@ fn updateConstInner(
2221 if (ptr_type.sentinel != .none) try dwarf.blockConst(pt, di_nw, .fromInterned(ptr_type.sentinel));2125 if (ptr_type.sentinel != .none) try dwarf.blockConst(pt, di_nw, .fromInterned(ptr_type.sentinel));
2222 if (ptr_type.flags.alignment.toByteUnits()) |a| try diw.writeUleb128(a);2126 if (ptr_type.flags.alignment.toByteUnits()) |a| try diw.writeUleb128(a);
2223 try diw.writeByte(@backingInt(ptr_type.flags.address_space));2127 try diw.writeByte(@backingInt(ptr_type.flags.address_space));
2224 if (ptr_type.flags.is_const or ptr_type.flags.is_volatile) try dwarf.sectionOffset(2128 if (ptr_type.flags.is_const or ptr_type.flags.is_volatile) try dwarf.secOffset(
2225 di_nw,2129 di_nw,
2226 di_nw.ni,2130 di_nw.ni,
2227 diw.end + dwarf.sectionOffsetSize(),2131 diw.end + dwarf.secOffsetSize(),
2228 );2132 );
2229 if (ptr_type.flags.is_const) {2133 if (ptr_type.flags.is_const) {
2230 try diw.writeUleb128(try dwarf.refAbbrevCode(.is_const));2134 try diw.writeUleb128(try dwarf.refAbbrevCode(.is_const));
2231 if (ptr_type.flags.is_volatile) try dwarf.sectionOffset(2135 if (ptr_type.flags.is_volatile) try dwarf.secOffset(
2232 di_nw,2136 di_nw,
2233 di_nw.ni,2137 di_nw.ni,
2234 diw.end + dwarf.sectionOffsetSize(),2138 diw.end + dwarf.secOffsetSize(),
2235 );2139 );
2236 }2140 }
2237 if (ptr_type.flags.is_volatile) try diw.writeUleb128(try dwarf.refAbbrevCode(.is_volatile));2141 if (ptr_type.flags.is_volatile) try diw.writeUleb128(try dwarf.refAbbrevCode(.is_volatile));
...@@ -2336,7 +2240,7 @@ fn updateConstInner(...@@ -2336,7 +2240,7 @@ fn updateConstInner(
2336 try diw.writeUleb128(try dwarf.refAbbrevCode(2240 try diw.writeUleb128(try dwarf.refAbbrevCode(
2337 if (loaded_struct.field_types.len > 0) .decl_struct else .decl_namespace_struct,2241 if (loaded_struct.field_types.len > 0) .decl_struct else .decl_namespace_struct,
2338 ));2242 ));
2339 try dwarf.sectionOffset(di_nw, parent_ni, 0);2243 try dwarf.secOffset(di_nw, parent_ni, 0);
2340 try diw.writeInt(u32, decl.src_line + 1, dwarf.endian);2244 try diw.writeInt(u32, decl.src_line + 1, dwarf.endian);
2341 try diw.writeUleb128(decl.src_column + 1);2245 try diw.writeUleb128(decl.src_column + 1);
2342 try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);2246 try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
...@@ -2410,7 +2314,7 @@ fn updateConstInner(...@@ -2410,7 +2314,7 @@ fn updateConstInner(
2410 try diw.writeUleb128(try dwarf.refAbbrevCode(2314 try diw.writeUleb128(try dwarf.refAbbrevCode(
2411 if (loaded_enum.field_names.len > 0) .decl_enum else .decl_empty_enum,2315 if (loaded_enum.field_names.len > 0) .decl_enum else .decl_empty_enum,
2412 ));2316 ));
2413 try dwarf.sectionOffset(di_nw, parent_ni, 0);2317 try dwarf.secOffset(di_nw, parent_ni, 0);
2414 try diw.writeInt(u32, decl.src_line + 1, dwarf.endian);2318 try diw.writeInt(u32, decl.src_line + 1, dwarf.endian);
2415 try diw.writeUleb128(decl.src_column + 1);2319 try diw.writeUleb128(decl.src_column + 1);
2416 try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);2320 try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
...@@ -2486,7 +2390,11 @@ fn updateConstIncompleteInner(...@@ -2486,7 +2390,11 @@ fn updateConstIncompleteInner(
2486 else => break :container .{2390 else => break :container .{
2487 src_inst,2391 src_inst,
2488 zf,2392 zf,
2489 zf.zir.?.getStructDecl(src_inst.inst).capture_names,2393 switch (zf.zir.?.instructions.items(.data)[@backingInt(src_inst.inst)].extended.opcode) {
2394 else => unreachable,
2395 .struct_decl => zf.zir.?.getStructDecl(src_inst.inst).capture_names,
2396 .reify_struct => &.{},
2397 },
2490 loaded_struct.captures,2398 loaded_struct.captures,
2491 loaded_struct.fqn,2399 loaded_struct.fqn,
2492 loaded_struct.name_nav,2400 loaded_struct.name_nav,
...@@ -2504,7 +2412,11 @@ fn updateConstIncompleteInner(...@@ -2504,7 +2412,11 @@ fn updateConstIncompleteInner(
2504 break :container .{2412 break :container .{
2505 src_inst,2413 src_inst,
2506 zf,2414 zf,
2507 zf.zir.?.getUnionDecl(src_inst.inst).capture_names,2415 switch (zf.zir.?.instructions.items(.data)[@backingInt(src_inst.inst)].extended.opcode) {
2416 else => unreachable,
2417 .union_decl => zf.zir.?.getUnionDecl(src_inst.inst).capture_names,
2418 .reify_union => &.{},
2419 },
2508 loaded_union.captures,2420 loaded_union.captures,
2509 loaded_union.fqn,2421 loaded_union.fqn,
2510 loaded_union.name_nav,2422 loaded_union.name_nav,
...@@ -2527,7 +2439,11 @@ fn updateConstIncompleteInner(...@@ -2527,7 +2439,11 @@ fn updateConstIncompleteInner(
2527 break :container .{2439 break :container .{
2528 src_inst,2440 src_inst,
2529 zf,2441 zf,
2530 zf.zir.?.getEnumDecl(src_inst.inst).capture_names,2442 switch (zf.zir.?.instructions.items(.data)[@backingInt(src_inst.inst)].extended.opcode) {
2443 else => unreachable,
2444 .enum_decl => zf.zir.?.getEnumDecl(src_inst.inst).capture_names,
2445 .reify_enum => &.{},
2446 },
2531 loaded_enum.captures,2447 loaded_enum.captures,
2532 loaded_enum.fqn,2448 loaded_enum.fqn,
2533 loaded_enum.name_nav,2449 loaded_enum.name_nav,
...@@ -2565,11 +2481,7 @@ fn updateConstIncompleteInner(...@@ -2565,11 +2481,7 @@ fn updateConstIncompleteInner(
2565 },2481 },
2566 },2482 },
2567 };2483 };
2568 const capturing = for (captures.get(ip)) |capture| switch (capture.tag) {2484 const spec_di = if (false and captures.len > 0) try dwarf.getDecl(pt, val) else undefined;
2569 .@"comptime", .runtime => break true,
2570 .nav_val, .nav_ref => {},
2571 } else false;
2572 const spec_di = if (false and capturing) try dwarf.getDecl(pt, val) else undefined;
2573 _ = spec_di;2485 _ = spec_di;
2574 if (maybe_name_nav.unwrap()) |name_ni| {2486 if (maybe_name_nav.unwrap()) |name_ni| {
2575 const name_nav = ip.getNav(name_ni);2487 const name_nav = ip.getNav(name_ni);
...@@ -2579,9 +2491,9 @@ fn updateConstIncompleteInner(...@@ -2579,9 +2491,9 @@ fn updateConstIncompleteInner(
2579 name_nav.analysis.?.namespace,2491 name_nav.analysis.?.namespace,
2580 ).owner_type);2492 ).owner_type);
2581 try diw.writeUleb128(try dwarf.refAbbrevCode(2493 try diw.writeUleb128(try dwarf.refAbbrevCode(
2582 if (capturing) .decl_capturing_namespace_struct else .decl_namespace_struct,2494 if (captures.len > 0) .decl_capturing_namespace_struct else .decl_namespace_struct,
2583 ));2495 ));
2584 try dwarf.sectionOffset(di_nw, parent_ni, 0);2496 try dwarf.secOffset(di_nw, parent_ni, 0);
2585 try diw.writeInt(u32, decl.src_line + 1, dwarf.endian);2497 try diw.writeInt(u32, decl.src_line + 1, dwarf.endian);
2586 try diw.writeUleb128(decl.src_column + 1);2498 try diw.writeUleb128(decl.src_column + 1);
2587 try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);2499 try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
...@@ -2594,38 +2506,53 @@ fn updateConstIncompleteInner(...@@ -2594,38 +2506,53 @@ fn updateConstIncompleteInner(
2594 ).owner_type);2506 ).owner_type);
2595 _ = parent_ni;2507 _ = parent_ni;
2596 try diw.writeUleb128(try dwarf.refAbbrevCode(2508 try diw.writeUleb128(try dwarf.refAbbrevCode(
2597 if (capturing) .capturing_empty_struct_type else .empty_struct_type,2509 if (captures.len > 0) .capturing_empty_struct_type else .empty_struct_type,
2598 ));2510 ));
2599 try diw.writeUleb128(@backingInt(fi));2511 try diw.writeUleb128(@backingInt(fi));
2600 try dwarf.strp(&dwarf.debug_str, di_nw, fqn.toSlice(ip));2512 try dwarf.strp(&dwarf.debug_str, di_nw, fqn.toSlice(ip));
2601 }2513 }
2602 try diw.writeByte(@intFromBool(true));2514 try diw.writeByte(@intFromBool(true));
2603 if (capturing) {2515 for (capture_names, captures.get(ip)) |capture_name, capture| switch (capture.unwrap()) {
2604 for (capture_names, captures.get(ip)) |capture_name, capture| switch (capture.unwrap()) {2516 .@"comptime" => |capture_val| {
2605 .@"comptime" => |capture_val| {2517 const ty: Type = .fromInterned(ip.typeOf(capture_val));
2606 const ty: Type = .fromInterned(ip.typeOf(capture_val));2518 const ty_class = ty.classify(zcu);
2607 const ty_class = ty.classify(zcu);2519 try diw.writeUleb128(try dwarf.refAbbrevCode(switch (ty_class) {
2608 try diw.writeUleb128(try dwarf.refAbbrevCode(switch (ty_class) {2520 .no_possible_value => unreachable,
2609 .no_possible_value => unreachable,2521 .one_possible_value => .comptime_capture,
2610 .one_possible_value => .comptime_capture,2522 .runtime => .comptime_capture_runtime,
2611 .runtime => .comptime_capture_runtime,2523 .partially_comptime => .comptime_capture_partially_comptime,
2612 .partially_comptime => .comptime_capture_partially_comptime,2524 .fully_comptime => .comptime_capture_fully_comptime,
2613 .fully_comptime => .comptime_capture_fully_comptime,2525 }));
2614 }));2526 try dwarf.strp(&dwarf.debug_str, di_nw, zf.zir.?.nullTerminatedString(capture_name));
2615 try dwarf.strp(&dwarf.debug_str, di_nw, zf.zir.?.nullTerminatedString(capture_name));2527 try dwarf.refConst(pt, di_nw, ty.toValue());
2616 try dwarf.refConst(pt, di_nw, ty.toValue());2528 if (ty_class.hasRuntimeBits()) try dwarf.blockConst(pt, di_nw, .fromInterned(capture_val));
2617 if (ty_class.hasRuntimeBits()) try dwarf.blockConst(pt, di_nw, .fromInterned(capture_val));2529 if (ty_class.comptimeOnly()) try dwarf.refConst(pt, di_nw, .fromInterned(capture_val));
2618 if (ty_class.comptimeOnly()) try dwarf.refConst(pt, di_nw, .fromInterned(capture_val));2530 },
2619 },2531 .runtime => |capture_ty| {
2620 .runtime => |capture_ty| {2532 try diw.writeUleb128(try dwarf.refAbbrevCode(.runtime_capture));
2621 try diw.writeUleb128(try dwarf.refAbbrevCode(.runtime_capture));2533 try dwarf.strp(&dwarf.debug_str, di_nw, zf.zir.?.nullTerminatedString(capture_name));
2622 try dwarf.strp(&dwarf.debug_str, di_nw, zf.zir.?.nullTerminatedString(capture_name));2534 try dwarf.refConst(pt, di_nw, .fromInterned(capture_ty));
2623 try dwarf.refConst(pt, di_nw, .fromInterned(capture_ty));2535 },
2624 },2536 .nav_val => |capture_nav| {
2625 .nav_val, .nav_ref => {},2537 const gi = try dwarf.getGlobal(capture_nav);
2626 };2538 try diw.writeUleb128(try dwarf.refAbbrevCode(.nav_capture));
2627 try diw.writeByte(@backingInt(AbbrevCode.null));2539 try dwarf.strp(&dwarf.debug_str, di_nw, zf.zir.?.nullTerminatedString(capture_name));
2628 }2540 try dwarf.exprLoc(di_nw, .{ .implicit_pointer = .{
2541 .node = gi.get(dwarf).debug_info_ni.unwrap().?,
2542 } });
2543 },
2544 .nav_ref => |capture_nav| {
2545 const gi = try dwarf.getGlobal(capture_nav);
2546 const capture_name_slice = try zcu.gpa.print("&{s}", .{zf.zir.?.nullTerminatedString(capture_name)});
2547 defer zcu.gpa.free(capture_name_slice);
2548 try diw.writeUleb128(try dwarf.refAbbrevCode(.nav_capture));
2549 try dwarf.strp(&dwarf.debug_str, di_nw, capture_name_slice);
2550 try dwarf.exprLoc(di_nw, .{ .stack_value = &.{ .implicit_pointer = .{
2551 .node = gi.get(dwarf).debug_info_ni.unwrap().?,
2552 } } });
2553 },
2554 };
2555 if (captures.len > 0) try diw.writeByte(@backingInt(AbbrevCode.null));
2629 }2556 }
2630 try dwarf.genDebugInfoPadding(diw, diw.unusedCapacityLen());2557 try dwarf.genDebugInfoPadding(diw, diw.unusedCapacityLen());
2631}2558}
...@@ -2657,7 +2584,7 @@ fn genDeclInner(...@@ -2657,7 +2584,7 @@ fn genDeclInner(
2657 ip.namespacePtr(loaded_struct.namespace).parent.unwrap().?,2584 ip.namespacePtr(loaded_struct.namespace).parent.unwrap().?,
2658 ).owner_type);2585 ).owner_type);
2659 try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_specification_struct));2586 try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_specification_struct));
2660 try dwarf.sectionOffset(di_nw, parent_ni, 0);2587 try dwarf.secOffset(di_nw, parent_ni, 0);
2661 try diw.writeInt(u32, 0, dwarf.endian);2588 try diw.writeInt(u32, 0, dwarf.endian);
2662 try diw.writeUleb128(0);2589 try diw.writeUleb128(0);
2663 try diw.writeByte(DW.ACCESS.public);2590 try diw.writeByte(DW.ACCESS.public);
...@@ -2669,7 +2596,7 @@ fn genDeclInner(...@@ -2669,7 +2596,7 @@ fn genDeclInner(
2669 ip.namespacePtr(loaded_enum.namespace).parent.unwrap().?,2596 ip.namespacePtr(loaded_enum.namespace).parent.unwrap().?,
2670 ).owner_type);2597 ).owner_type);
2671 try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_specification_enum));2598 try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_specification_enum));
2672 try dwarf.sectionOffset(di_nw, parent_ni, 0);2599 try dwarf.secOffset(di_nw, parent_ni, 0);
2673 try diw.writeInt(u32, 0, dwarf.endian);2600 try diw.writeInt(u32, 0, dwarf.endian);
2674 try diw.writeUleb128(0);2601 try diw.writeUleb128(0);
2675 try diw.writeByte(DW.ACCESS.public);2602 try diw.writeByte(DW.ACCESS.public);
...@@ -2681,7 +2608,7 @@ fn genDeclInner(...@@ -2681,7 +2608,7 @@ fn genDeclInner(
2681 ip.namespacePtr(loaded_union.namespace).parent.unwrap().?,2608 ip.namespacePtr(loaded_union.namespace).parent.unwrap().?,
2682 ).owner_type);2609 ).owner_type);
2683 try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_specification_union));2610 try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_specification_union));
2684 try dwarf.sectionOffset(di_nw, parent_ni, 0);2611 try dwarf.secOffset(di_nw, parent_ni, 0);
2685 try diw.writeInt(u32, 0, dwarf.endian);2612 try diw.writeInt(u32, 0, dwarf.endian);
2686 try diw.writeUleb128(0);2613 try diw.writeUleb128(0);
2687 try diw.writeByte(DW.ACCESS.public);2614 try diw.writeByte(DW.ACCESS.public);
...@@ -2698,11 +2625,16 @@ pub fn updateLineNumber(...@@ -2698,11 +2625,16 @@ pub fn updateLineNumber(
2698 line: u32,2625 line: u32,
2699) void {2626) void {
2700 const di = dwarf.getDeclIfExists(inst) orelse return;2627 const di = dwarf.getDeclIfExists(inst) orelse return;
2701 const decl_ni = di.get(dwarf).debug_info_ni.unwrap() orelse return;2628 const decl_ni = di.get(dwarf).debug_info_ni.unwrap().?;
2702 std.mem.writeInt(u32, decl_ni.slice(mf)[AbbrevCode.decl_size..][0..4], line + 1, dwarf.endian);2629 std.mem.writeInt(
2630 u32,
2631 decl_ni.slice(mf)[AbbrevCode.decl_size..][0..4],
2632 line + 1,
2633 dwarf.endian,
2634 );
2703}2635}
27042636
2705pub fn lostTracking(dwarf: *Dwarf, diw: *Writer) link.EmitError!void {2637pub fn lostTracking(dwarf: *Dwarf, diw: *std.Io.Writer) link.EmitError!void {
2706 try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_lost));2638 try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_lost));
2707}2639}
27082640
...@@ -2755,17 +2687,23 @@ fn genDebugAbbrev(...@@ -2755,17 +2687,23 @@ fn genDebugAbbrev(
2755 dwarf.debug_abbrev.end = daw.end;2687 dwarf.debug_abbrev.end = daw.end;
2756}2688}
27572689
2758fn sectionOffset(2690pub fn secOffsetSize(dwarf: *Dwarf) usize {
2691 return switch (dwarf.format) {
2692 .@"32" => 4,
2693 .@"64" => 8,
2694 };
2695}
2696fn secOffsetPlaceholder(dwarf: *Dwarf, w: *std.Io.Writer) std.Io.Writer.Error!void {
2697 @memset(try w.writableSlice(dwarf.secOffsetSize()), undefined);
2698}
2699fn secOffset(
2759 dwarf: *Dwarf,2700 dwarf: *Dwarf,
2760 nw: *MappedFile.Node.Writer,2701 nw: *MappedFile.Node.Writer,
2761 target_ni: MappedFile.Node.Index,2702 target_ni: MappedFile.Node.Index,
2762 addend: usize,2703 addend: usize,
2763) link.EmitError!void {2704) link.EmitError!void {
2764 const offset = nw.interface.end;2705 const offset = nw.interface.end;
2765 switch (dwarf.format) {2706 try dwarf.secOffsetPlaceholder(&nw.interface);
2766 .@"32" => try nw.interface.writeInt(u32, 0, dwarf.endian),
2767 .@"64" => try nw.interface.writeInt(u64, 0, dwarf.endian),
2768 }
2769 const elf = dwarf.lf.cast(.elf2).?;2707 const elf = dwarf.lf.cast(.elf2).?;
2770 try elf.addNodeReloc(nw.ni, offset, target_ni, @bitCast(@as(u64, addend)), switch (dwarf.format) {2708 try elf.addNodeReloc(nw.ni, offset, target_ni, @bitCast(@as(u64, addend)), switch (dwarf.format) {
2771 .@"32" => .abs32,2709 .@"32" => .abs32,
...@@ -2773,23 +2711,27 @@ fn sectionOffset(...@@ -2773,23 +2711,27 @@ fn sectionOffset(
2773 });2711 });
2774}2712}
27752713
2776fn symbolAddress(2714fn addrPlaceholder(dwarf: *Dwarf, w: *std.Io.Writer) std.Io.Writer.Error!void {
2715 @memset(try w.writableSlice(@backingInt(dwarf.address_size)), undefined);
2716}
2717fn addrSym(
2777 dwarf: *Dwarf,2718 dwarf: *Dwarf,
2778 nw: *MappedFile.Node.Writer,2719 nw: *MappedFile.Node.Writer,
2779 target_si: link.File.SymbolId,2720 target_si: link.File.SymbolId,
2780 addend: usize,2721 addend: usize,
2781) link.EmitError!void {2722) link.EmitError!void {
2782 const offset = nw.interface.end;2723 const offset = nw.interface.end;
2783 switch (dwarf.address_size) {2724 try dwarf.addrPlaceholder(&nw.interface);
2784 else => unreachable,
2785 .@"32" => try nw.interface.writeInt(u32, 0, dwarf.endian),
2786 .@"64" => try nw.interface.writeInt(u64, 0, dwarf.endian),
2787 }
2788 const elf = dwarf.lf.cast(.elf2).?;2725 const elf = dwarf.lf.cast(.elf2).?;
2789 try elf.addReloc(@bitCast(nw.ni), offset, target_si, @bitCast(@as(u64, addend)), .absAddr(elf));2726 try elf.addReloc(@bitCast(nw.ni), offset, target_si, @bitCast(@as(u64, addend)), .absAddr(elf));
2790}2727}
27912728
2792fn blockConst(dwarf: *Dwarf, pt: Zcu.PerThread, nw: *MappedFile.Node.Writer, val: Value) link.EmitError!void {2729fn blockConst(
2730 dwarf: *Dwarf,
2731 pt: Zcu.PerThread,
2732 nw: *MappedFile.Node.Writer,
2733 val: Value,
2734) link.EmitError!void {
2793 const ty = val.typeOf(pt.zcu);2735 const ty = val.typeOf(pt.zcu);
2794 const size = ty.abiSize(pt.zcu);2736 const size = ty.abiSize(pt.zcu);
2795 try nw.interface.writeUleb128(size);2737 try nw.interface.writeUleb128(size);
...@@ -2804,11 +2746,21 @@ fn blockConst(dwarf: *Dwarf, pt: Zcu.PerThread, nw: *MappedFile.Node.Writer, val...@@ -2804,11 +2746,21 @@ fn blockConst(dwarf: *Dwarf, pt: Zcu.PerThread, nw: *MappedFile.Node.Writer, val
2804 assert(start + size == nw.interface.end);2746 assert(start + size == nw.interface.end);
2805}2747}
28062748
2807fn refConst(dwarf: *Dwarf, pt: Zcu.PerThread, nw: *MappedFile.Node.Writer, val: Value) link.EmitError!void {2749fn refConst(
2808 try dwarf.sectionOffset(nw, Const.get(try dwarf.getConst(pt, val), dwarf).debug_info_ni.unwrap().?, 0);2750 dwarf: *Dwarf,
2751 pt: Zcu.PerThread,
2752 nw: *MappedFile.Node.Writer,
2753 val: Value,
2754) link.EmitError!void {
2755 try dwarf.secOffset(nw, Const.get(try dwarf.getConst(pt, val), dwarf).debug_info_ni.unwrap().?, 0);
2809}2756}
28102757
2811fn bigIntConstValue(dwarf: *Dwarf, diw: *Writer, ty: Type, big_int: std.math.big.int.Const) link.EmitError!void {2758fn bigIntConstValue(
2759 dwarf: *Dwarf,
2760 diw: *std.Io.Writer,
2761 ty: Type,
2762 big_int: std.math.big.int.Const,
2763) link.EmitError!void {
2812 const zcu = dwarf.lf.comp.zcu.?;2764 const zcu = dwarf.lf.comp.zcu.?;
2813 const signedness = switch (ty.toIntern()) {2765 const signedness = switch (ty.toIntern()) {
2814 .comptime_int_type => .signed,2766 .comptime_int_type => .signed,
...@@ -2849,7 +2801,12 @@ fn bigIntConstValue(dwarf: *Dwarf, diw: *Writer, ty: Type, big_int: std.math.big...@@ -2849,7 +2801,12 @@ fn bigIntConstValue(dwarf: *Dwarf, diw: *Writer, ty: Type, big_int: std.math.big
2849 }2801 }
2850}2802}
28512803
2852fn enumConstValue(dwarf: *Dwarf, diw: *Writer, loaded_enum: InternPool.LoadedEnumType, field_index: usize) link.EmitError!void {2804fn enumConstValue(
2805 dwarf: *Dwarf,
2806 diw: *std.Io.Writer,
2807 loaded_enum: InternPool.LoadedEnumType,
2808 field_index: usize,
2809) link.EmitError!void {
2853 const zcu = dwarf.lf.comp.zcu.?;2810 const zcu = dwarf.lf.comp.zcu.?;
2854 var big_int_space: Value.BigIntSpace = undefined;2811 var big_int_space: Value.BigIntSpace = undefined;
2855 try dwarf.bigIntConstValue(diw, .fromInterned(loaded_enum.int_tag_type), if (loaded_enum.field_values.len > 0)2812 try dwarf.bigIntConstValue(diw, .fromInterned(loaded_enum.int_tag_type), if (loaded_enum.field_values.len > 0)
...@@ -2858,10 +2815,19 @@ fn enumConstValue(dwarf: *Dwarf, diw: *Writer, loaded_enum: InternPool.LoadedEnu...@@ -2858,10 +2815,19 @@ fn enumConstValue(dwarf: *Dwarf, diw: *Writer, loaded_enum: InternPool.LoadedEnu
2858 std.math.big.int.Mutable.init(&big_int_space.limbs, field_index).toConst());2815 std.math.big.int.Mutable.init(&big_int_space.limbs, field_index).toConst());
2859}2816}
28602817
2818fn exprLoc(dwarf: *Dwarf, nw: *MappedFile.Node.Writer, loc: Loc) link.EmitError!void {
2819 var buf: [@max(8, std.atomic.cache_line)]u8 = undefined;
2820 var dw: std.Io.Writer.Discarding = .init(&buf);
2821 try loc.write(.{ .io = &dw.writer }, dwarf);
2822
2823 try nw.interface.writeUleb128(dw.fullCount());
2824 try loc.write(.{ .mf = nw }, dwarf);
2825}
2826
2861fn strp(dwarf: *Dwarf, s: *Str, nw: *MappedFile.Node.Writer, str: []const u8) link.EmitError!void {2827fn strp(dwarf: *Dwarf, s: *Str, nw: *MappedFile.Node.Writer, str: []const u8) link.EmitError!void {
2862 const comp = dwarf.lf.comp;2828 const comp = dwarf.lf.comp;
2863 const mf = &dwarf.lf.cast(.elf2).?.mf;2829 const mf = &dwarf.lf.cast(.elf2).?.mf;
2864 try dwarf.sectionOffset(nw, s.ni.unwrap().?, s.get(comp.gpa, mf, str) catch |err| switch (err) {2830 try dwarf.secOffset(nw, s.ni.unwrap().?, s.get(comp.gpa, mf, str) catch |err| switch (err) {
2865 error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{2831 error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{
2866 mf.io_err.?,2832 mf.io_err.?,
2867 }),2833 }),
...@@ -3013,6 +2979,7 @@ pub const AbbrevCode = enum {...@@ -3013,6 +2979,7 @@ pub const AbbrevCode = enum {
3013 comptime_capture_partially_comptime,2979 comptime_capture_partially_comptime,
3014 comptime_capture_fully_comptime,2980 comptime_capture_fully_comptime,
3015 runtime_capture,2981 runtime_capture,
2982 nav_capture,
3016 builtin_extern_nullary_func,2983 builtin_extern_nullary_func,
3017 builtin_extern_func,2984 builtin_extern_func,
3018 builtin_extern_var,2985 builtin_extern_var,
...@@ -3080,6 +3047,7 @@ pub const AbbrevCode = enum {...@@ -3080,6 +3047,7 @@ pub const AbbrevCode = enum {
3080 children: bool = false,3047 children: bool = false,
3081 attrs: []const Attr = &.{},3048 attrs: []const Attr = &.{},
3082 }).init(.{3049 }).init(.{
3050 .null = undefined,
3083 .pad_1 = .{3051 .pad_1 = .{
3084 .tag = .ZIG_padding,3052 .tag = .ZIG_padding,
3085 },3053 },
...@@ -3937,6 +3905,13 @@ pub const AbbrevCode = enum {...@@ -3937,6 +3905,13 @@ pub const AbbrevCode = enum {
3937 .{ .type, .ref_addr },3905 .{ .type, .ref_addr },
3938 },3906 },
3939 },3907 },
3908 .nav_capture = .{
3909 .tag = .template_value_parameter,
3910 .attrs = &.{
3911 .{ .name, .strp },
3912 .{ .location, .exprloc },
3913 },
3914 },
3940 .builtin_extern_nullary_func = .{3915 .builtin_extern_nullary_func = .{
3941 .tag = .subprogram,3916 .tag = .subprogram,
3942 .attrs = &.{3917 .attrs = &.{
...@@ -4204,20 +4179,19 @@ pub const AbbrevCode = enum {...@@ -4204,20 +4179,19 @@ pub const AbbrevCode = enum {
4204 .{ .ZIG_comptime_value, .ref_addr },4179 .{ .ZIG_comptime_value, .ref_addr },
4205 },4180 },
4206 },4181 },
4207 .null = undefined,
4208 });4182 });
4209};4183};
42104184
4211pub fn uleb128Size(value: anytype) u32 {4185pub fn uleb128Size(value: anytype) u32 {
4212 var buf: [64]u8 = undefined;4186 var buf: [std.atomic.cache_line]u8 = undefined;
4213 var dw: Writer.Discarding = .init(&buf);4187 var dw: std.Io.Writer.Discarding = .init(&buf);
4214 dw.writer.writeUleb128(value) catch unreachable;4188 dw.writer.writeUleb128(value) catch unreachable;
4215 return @intCast(dw.fullCount());4189 return @intCast(dw.fullCount());
4216}4190}
42174191
4218pub fn sleb128Size(value: anytype) u32 {4192pub fn sleb128Size(value: anytype) u32 {
4219 var buf: [64]u8 = undefined;4193 var buf: [std.atomic.cache_line]u8 = undefined;
4220 var dw: Writer.Discarding = .init(&buf);4194 var dw: std.Io.Writer.Discarding = .init(&buf);
4221 dw.writer.writeSleb128(value) catch unreachable;4195 dw.writer.writeSleb128(value) catch unreachable;
4222 return @intCast(dw.fullCount());4196 return @intCast(dw.fullCount());
4223}4197}
...@@ -4237,5 +4211,4 @@ const std = @import("std");...@@ -4237,5 +4211,4 @@ const std = @import("std");
4237const target_info = @import("../target.zig");4211const target_info = @import("../target.zig");
4238const Type = @import("../Type.zig");4212const Type = @import("../Type.zig");
4239const Value = @import("../Value.zig");4213const Value = @import("../Value.zig");
4240const Writer = std.Io.Writer;
4241const Zcu = @import("../Zcu.zig");4214const Zcu = @import("../Zcu.zig");
src/link/Elf2.zig+1-1
...@@ -5332,7 +5332,7 @@ fn computeNodeElfOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 {...@@ -5332,7 +5332,7 @@ fn computeNodeElfOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 {
5332///5332///
5333/// Asserts that `ni` must be a node which supports relocations (see `Elf.Node`). Does not support5333/// Asserts that `ni` must be a node which supports relocations (see `Elf.Node`). Does not support
5334/// the special-case sections '.plt', '.dynamic', and '.eh_frame_hdr'.5334/// the special-case sections '.plt', '.dynamic', and '.eh_frame_hdr'.
5335fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {5335pub fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
5336 const opts: struct {5336 const opts: struct {
5337 first_symbol_reloc: ?*SymbolReloc.Index = null,5337 first_symbol_reloc: ?*SymbolReloc.Index = null,
5338 skip_symbol_relocs: MappedFile.Node.Index.Optional = .none,5338 skip_symbol_relocs: MappedFile.Node.Index.Optional = .none,
test/incremental/change_reify_struct_field_type created+22
...@@ -0,0 +1,22 @@
1#update=initial version
2#file=main.zig
3fn getEnum(s: @Struct(.auto, null, &.{"field"}, &.{struct { tag: Enum }}, &.{.{}})) Enum {
4 return s.field.tag;
5}
6pub fn main(init: std.process.Init) !void {
7 try std.Io.File.stdout().writeStreamingAll(init.io, @tagName(getEnum(.{ .field = .{ .tag = .foo } })));
8}
9const Enum = enum { foo, bar };
10const std = @import("std");
11#expect_stdout="foo"
12#update=change field type
13#file=main.zig
14fn getEnum(s: @Struct(.auto, null, &.{"field"}, &.{Enum}, &.{.{}})) Enum {
15 return s.field;
16}
17pub fn main(init: std.process.Init) !void {
18 try std.Io.File.stdout().writeStreamingAll(init.io, @tagName(getEnum(.{ .field = .bar })));
19}
20const Enum = enum { foo, bar };
21const std = @import("std");
22#expect_stdout="bar"