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) {
274274 stack_value: *const Loc,
275275 implicit_pointer: struct {
276276 node: MappedFile.Node.Index,
277 offset: i65,
277 offset: i65 = 0,
278278 },
279279 wasm_ext: union(enum) {
280280 local: u32,
......@@ -299,7 +299,7 @@ pub const Loc = union(enum) {
299299 };
300300 }
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 {
303303 if (std.math.cast(u5, reg)) |small_reg| {
304304 try writer.writeByte(op0 + small_reg);
305305 } else {
......@@ -308,141 +308,156 @@ pub const Loc = union(enum) {
308308 }
309309 }
310310
311 fn write(loc: Loc, adapter: anytype) link.EmitError!void {
312 const writer = adapter.writer();
311 fn write(loc: Loc, writer: union(enum) {
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 };
313319 switch (loc) {
314320 .empty => {},
315321 .addr_reloc => |si| {
316 try writer.writeByte(DW.OP.addr);
317 try adapter.addrSym(si);
322 try w.writeByte(DW.OP.addr);
323 switch (writer) {
324 .io => try dwarf.addrPlaceholder(w),
325 .mf => |nw| try dwarf.addrSym(nw, si, 0),
326 }
318327 },
319328 .deref => |addr| {
320 try addr.write(adapter);
321 try writer.writeByte(DW.OP.deref);
329 try addr.write(writer, dwarf);
330 try w.writeByte(DW.OP.deref);
322331 },
323332 .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);
325334 } else if (std.math.cast(u8, constu)) |const1u| {
326 try writer.writeAll(&.{ DW.OP.const1u, const1u });
335 try w.writeAll(&.{ DW.OP.const1u, const1u });
327336 } else if (std.math.cast(u16, constu)) |const2u| {
328 try writer.writeByte(DW.OP.const2u);
329 try writer.writeInt(u16, const2u, adapter.endian());
337 try w.writeByte(DW.OP.const2u);
338 try w.writeInt(u16, const2u, dwarf.endian);
330339 } else if (std.math.cast(u21, constu)) |const3u| {
331 try writer.writeByte(DW.OP.constu);
332 try writer.writeUleb128(const3u);
340 try w.writeByte(DW.OP.constu);
341 try w.writeUleb128(const3u);
333342 } else if (std.math.cast(u32, constu)) |const4u| {
334 try writer.writeByte(DW.OP.const4u);
335 try writer.writeInt(u32, const4u, adapter.endian());
343 try w.writeByte(DW.OP.const4u);
344 try w.writeInt(u32, const4u, dwarf.endian);
336345 } else if (std.math.cast(u49, constu)) |const7u| {
337 try writer.writeByte(DW.OP.constu);
338 try writer.writeUleb128(const7u);
346 try w.writeByte(DW.OP.constu);
347 try w.writeUleb128(const7u);
339348 } else {
340 try writer.writeByte(DW.OP.const8u);
341 try writer.writeInt(u64, constu, adapter.endian());
349 try w.writeByte(DW.OP.const8u);
350 try w.writeInt(u64, constu, dwarf.endian);
342351 },
343352 .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) });
345354 } else if (std.math.cast(i16, consts)) |const2s| {
346 try writer.writeByte(DW.OP.const2s);
347 try writer.writeInt(i16, const2s, adapter.endian());
355 try w.writeByte(DW.OP.const2s);
356 try w.writeInt(i16, const2s, dwarf.endian);
348357 } else if (std.math.cast(i21, consts)) |const3s| {
349 try writer.writeByte(DW.OP.consts);
350 try writer.writeSleb128(const3s);
358 try w.writeByte(DW.OP.consts);
359 try w.writeSleb128(const3s);
351360 } else if (std.math.cast(i32, consts)) |const4s| {
352 try writer.writeByte(DW.OP.const4s);
353 try writer.writeInt(i32, const4s, adapter.endian());
361 try w.writeByte(DW.OP.const4s);
362 try w.writeInt(i32, const4s, dwarf.endian);
354363 } else if (std.math.cast(i49, consts)) |const7s| {
355 try writer.writeByte(DW.OP.consts);
356 try writer.writeSleb128(const7s);
364 try w.writeByte(DW.OP.consts);
365 try w.writeSleb128(const7s);
357366 } else {
358 try writer.writeByte(DW.OP.const8s);
359 try writer.writeInt(i64, consts, adapter.endian());
367 try w.writeByte(DW.OP.const8s);
368 try w.writeInt(i64, consts, dwarf.endian);
360369 },
361370 .plus => |plus| done: {
362371 if (plus[0].getConst(u0)) |_| {
363 try plus[1].write(adapter);
372 try plus[1].write(writer, dwarf);
364373 break :done;
365374 }
366375 if (plus[1].getConst(u0)) |_| {
367 try plus[0].write(adapter);
376 try plus[0].write(writer, dwarf);
368377 break :done;
369378 }
370379 if (plus[0].getBaseReg()) |breg| {
371380 if (plus[1].getConst(i65)) |offset| {
372 try writeReg(breg, DW.OP.breg0, DW.OP.bregx, writer);
373 try writer.writeSleb128(offset);
381 try writeReg(breg, DW.OP.breg0, DW.OP.bregx, w);
382 try w.writeSleb128(offset);
374383 break :done;
375384 }
376385 }
377386 if (plus[1].getBaseReg()) |breg| {
378387 if (plus[0].getConst(i65)) |offset| {
379 try writeReg(breg, DW.OP.breg0, DW.OP.bregx, writer);
380 try writer.writeSleb128(offset);
388 try writeReg(breg, DW.OP.breg0, DW.OP.bregx, w);
389 try w.writeSleb128(offset);
381390 break :done;
382391 }
383392 }
384393 if (plus[0].getConst(u64)) |uconst| {
385 try plus[1].write(adapter);
386 try writer.writeByte(DW.OP.plus_uconst);
387 try writer.writeUleb128(uconst);
394 try plus[1].write(writer, dwarf);
395 try w.writeByte(DW.OP.plus_uconst);
396 try w.writeUleb128(uconst);
388397 break :done;
389398 }
390399 if (plus[1].getConst(u64)) |uconst| {
391 try plus[0].write(adapter);
392 try writer.writeByte(DW.OP.plus_uconst);
393 try writer.writeUleb128(uconst);
400 try plus[0].write(writer, dwarf);
401 try w.writeByte(DW.OP.plus_uconst);
402 try w.writeUleb128(uconst);
394403 break :done;
395404 }
396 try plus[0].write(adapter);
397 try plus[1].write(adapter);
398 try writer.writeByte(DW.OP.plus);
405 try plus[0].write(writer, dwarf);
406 try plus[1].write(writer, dwarf);
407 try w.writeByte(DW.OP.plus);
399408 },
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),
401410 .breg => |breg| {
402 try writeReg(breg, DW.OP.breg0, DW.OP.bregx, writer);
403 try writer.writeSleb128(0);
411 try writeReg(breg, DW.OP.breg0, DW.OP.bregx, w);
412 try w.writeSleb128(0);
404413 },
405 .push_object_address => try writer.writeByte(DW.OP.push_object_address),
414 .push_object_address => try w.writeByte(DW.OP.push_object_address),
406415 .call => |call| {
407 for (call.args) |arg| try arg.write(adapter);
408 try writer.writeByte(DW.OP.call_ref);
409 try adapter.infoEntry(call.node);
416 for (call.args) |arg| try arg.write(writer, dwarf);
417 try w.writeByte(DW.OP.call_ref);
418 switch (writer) {
419 .io => try dwarf.secOffsetPlaceholder(w),
420 .mf => |nw| try dwarf.secOffset(nw, call.node, 0),
421 }
410422 },
411423 .form_tls_address => |addr| {
412 try addr.write(adapter);
413 try writer.writeByte(DW.OP.form_tls_address);
424 try addr.write(writer, dwarf);
425 try w.writeByte(DW.OP.form_tls_address);
414426 },
415427 .implicit_value => |value| {
416 try writer.writeByte(DW.OP.implicit_value);
417 try writer.writeUleb128(value.len);
418 try writer.writeAll(value);
428 try w.writeByte(DW.OP.implicit_value);
429 try w.writeUleb128(value.len);
430 try w.writeAll(value);
419431 },
420432 .stack_value => |value| {
421 try value.write(adapter);
422 try writer.writeByte(DW.OP.stack_value);
433 try value.write(writer, dwarf);
434 try w.writeByte(DW.OP.stack_value);
423435 },
424436 .implicit_pointer => |implicit_pointer| {
425 try writer.writeByte(DW.OP.implicit_pointer);
426 try adapter.infoEntry(implicit_pointer.node);
427 try writer.writeSleb128(implicit_pointer.offset);
437 try w.writeByte(DW.OP.implicit_pointer);
438 switch (writer) {
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);
428443 },
429444 .wasm_ext => |wasm_ext| {
430 try writer.writeByte(DW.OP.WASM_location);
445 try w.writeByte(DW.OP.WASM_location);
431446 switch (wasm_ext) {
432447 .local => |local| {
433 try writer.writeByte(DW.OP.WASM_local);
434 try writer.writeUleb128(local);
448 try w.writeByte(DW.OP.WASM_local);
449 try w.writeUleb128(local);
435450 },
436451 .global => |global| if (std.math.cast(u21, global)) |global_u21| {
437 try writer.writeByte(DW.OP.WASM_global);
438 try writer.writeUleb128(global_u21);
452 try w.writeByte(DW.OP.WASM_global);
453 try w.writeUleb128(global_u21);
439454 } else {
440 try writer.writeByte(DW.OP.WASM_global_u32);
441 try writer.writeInt(u32, global, adapter.endian());
455 try w.writeByte(DW.OP.WASM_global_u32);
456 try w.writeInt(u32, global, dwarf.endian);
442457 },
443458 .operand_stack => |operand_stack| {
444 try writer.writeByte(DW.OP.WASM_operand_stack);
445 try writer.writeUleb128(operand_stack);
459 try w.writeByte(DW.OP.WASM_operand_stack);
460 try w.writeUleb128(operand_stack);
446461 },
447462 }
448463 },
......@@ -574,12 +589,12 @@ pub const Cfa = union(enum) {
574589 },
575590 .def_cfa_expression => |expr| {
576591 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);
578593 },
579594 .expression => |reg_expr| {
580595 try dfw.writeByte(DW.CFA.expression);
581596 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);
583598 },
584599 .val_offset => |reg_off| {
585600 const factored_off =
......@@ -597,7 +612,7 @@ pub const Cfa = union(enum) {
597612 .val_expression => |reg_expr| {
598613 try dfw.writeByte(DW.CFA.val_expression);
599614 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);
601616 },
602617 .escape => |bytes| try dfw.writeAll(bytes),
603618 }
......@@ -678,7 +693,7 @@ pub const WipNav = struct {
678693 .@"extern", .@"export" => nav.name,
679694 }.toSlice(ip));
680695 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);
682697 debug.info_func_length_offset = diw.end;
683698 try diw.writeInt(u32, undefined, dwarf.endian);
684699 try diw.writeUleb128(
......@@ -706,9 +721,9 @@ pub const WipNav = struct {
706721 const dlw = &debug.line_writer.interface;
707722 try dlw.writeByte(DW.LNS.extended_op);
708723 if (zcu.comp.config.incremental) {
709 try dlw.writeUleb128(1 + dwarf.sectionOffsetSize());
724 try dlw.writeUleb128(1 + dwarf.secOffsetSize());
710725 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
713728 try dlw.writeByte(DW.LNS.set_column);
714729 try dlw.writeUleb128(func.lbrace_column + 1);
......@@ -717,7 +732,7 @@ pub const WipNav = struct {
717732 } else {
718733 try dlw.writeUleb128(1 + @backingInt(dwarf.address_size));
719734 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
722737 const unit = dwarf.getUnit(zf.mod.?);
723738 _, const fi = try unit.get(dwarf).getFile(zcu.gpa, unit, inst_info.file);
......@@ -788,7 +803,7 @@ pub const WipNav = struct {
788803 }));
789804 if (opt_name) |name| try dwarf.strp(&dwarf.debug_str, di_nw, name);
790805 try dwarf.refConst(debug.pt, di_nw, ty.toValue());
791 try debug.infoExprLoc(loc);
806 try dwarf.exprLoc(&debug.info_writer, loc);
792807 debug.any_children = true;
793808 }
794809
......@@ -873,7 +888,7 @@ pub const WipNav = struct {
873888 delta_line: i33,
874889 delta_pc: u64,
875890 end: bool,
876 ) Writer.Error!void {
891 ) std.Io.Writer.Error!void {
877892 const dlw = &debug.line_writer.interface;
878893
879894 const header = debug.wip_nav.dwarf.debug_line.header;
......@@ -923,7 +938,7 @@ pub const WipNav = struct {
923938 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
924939 };
925940 }
926 fn setColumnInner(debug: *Debug, column: u32) Writer.Error!void {
941 fn setColumnInner(debug: *Debug, column: u32) std.Io.Writer.Error!void {
927942 const dlw = &debug.line_writer.interface;
928943 try dlw.writeByte(DW.LNS.set_column);
929944 try dlw.writeUleb128(column + 1);
......@@ -934,7 +949,7 @@ pub const WipNav = struct {
934949 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
935950 };
936951 }
937 fn negateStmtInner(debug: *Debug) Writer.Error!void {
952 fn negateStmtInner(debug: *Debug) std.Io.Writer.Error!void {
938953 try debug.line_writer.interface.writeByte(DW.LNS.negate_stmt);
939954 }
940955
......@@ -943,7 +958,7 @@ pub const WipNav = struct {
943958 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
944959 };
945960 }
946 fn setPrologueEndInner(debug: *Debug) Writer.Error!void {
961 fn setPrologueEndInner(debug: *Debug) std.Io.Writer.Error!void {
947962 try debug.line_writer.interface.writeByte(DW.LNS.set_prologue_end);
948963 }
949964
......@@ -952,7 +967,7 @@ pub const WipNav = struct {
952967 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
953968 };
954969 }
955 fn setEpilogueBeginInner(debug: *Debug) Writer.Error!void {
970 fn setEpilogueBeginInner(debug: *Debug) std.Io.Writer.Error!void {
956971 try debug.line_writer.interface.writeByte(DW.LNS.set_epilogue_begin);
957972 }
958973
......@@ -970,7 +985,7 @@ pub const WipNav = struct {
970985 block.abbrev_code = @intCast(diw.end);
971986 try diw.writeUleb128(try dwarf.refAbbrevCode(.block));
972987 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);
974989 block.high_pc = @intCast(diw.end);
975990 try diw.writeInt(u32, 0, dwarf.endian);
976991 debug.any_children = false;
......@@ -1037,7 +1052,7 @@ pub const WipNav = struct {
10371052 try diw.writeUleb128(line);
10381053 try diw.writeUleb128(column + 1);
10391054 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);
10411056 block.high_pc = @intCast(diw.end);
10421057 try diw.writeInt(u32, 0, dwarf.endian);
10431058 try debug.setInlineFunc(func);
......@@ -1094,9 +1109,9 @@ pub const WipNav = struct {
10941109 if (zcu.comp.config.incremental) {
10951110 const new_func = try dwarf.getFunc(new_owner_nav);
10961111 try dlw.writeByte(DW.LNS.extended_op);
1097 try dlw.writeUleb128(1 + dwarf.sectionOffsetSize());
1112 try dlw.writeUleb128(1 + dwarf.secOffsetSize());
10981113 try dlw.writeByte(DW.LNE.ZIG_set_decl);
1099 try dwarf.sectionOffset(
1114 try dwarf.secOffset(
11001115 &debug.line_writer,
11011116 new_func.get(dwarf).debug_info_ni.unwrap().?,
11021117 0,
......@@ -1128,38 +1143,10 @@ pub const WipNav = struct {
11281143 debug.wip_nav.func = func;
11291144 }
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
11591146 fn refFunc(debug: *Debug, func: InternPool.Index) link.EmitError!void {
11601147 const dwarf = debug.wip_nav.dwarf;
11611148 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(
11631150 &debug.info_writer,
11641151 fi.get(dwarf).debug_info_ni.unwrap().?,
11651152 0,
......@@ -1203,14 +1190,10 @@ pub const WipNav = struct {
12031190 try dfw.writeUleb128(0);
12041191 },
12051192 .debug_frame => {
1206 try dwarf.sectionOffset(
1207 &wip_nav.fde_writer,
1208 wip_nav.unit.get(dwarf).cie_ni.unwrap().?,
1209 0,
1210 );
1211 try wip_nav.frameAddrSym(wip_nav.func_si, 0);
1193 try dwarf.secOffset(&wip_nav.fde_writer, wip_nav.unit.get(dwarf).cie_ni.unwrap().?, 0);
1194 try dwarf.addrSym(&wip_nav.fde_writer, wip_nav.func_si, 0);
12121195 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);
12141197 },
12151198 }
12161199 }
......@@ -1248,78 +1231,6 @@ pub const WipNav = struct {
12481231 }
12491232 @memset(dfw.unusedCapacitySlice(), DW.CFA.nop);
12501233 }
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 }
13231234};
13241235
13251236pub fn init(lf: *link.File, format: DW.Format) Dwarf {
......@@ -1632,13 +1543,7 @@ pub fn unitLengthSize(dwarf: *Dwarf) usize {
16321543 .@"64" => 4 + 8,
16331544 };
16341545}
1635pub fn sectionOffsetSize(dwarf: *Dwarf) usize {
1636 return switch (dwarf.format) {
1637 .@"32" => 4,
1638 .@"64" => 8,
1639 };
1640}
1641pub fn genUnitLength(dwarf: *Dwarf, w: *Writer) Writer.Error!void {
1546pub fn genUnitLength(dwarf: *Dwarf, w: *std.Io.Writer) std.Io.Writer.Error!void {
16421547 switch (dwarf.format) {
16431548 .@"32" => try w.writeInt(u32, undefined, dwarf.endian),
16441549 .@"64" => {
......@@ -1654,7 +1559,7 @@ pub fn updateUnitLength(dwarf: *Dwarf, header: []u8, unit_length: u64) void {
16541559 }
16551560}
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 {
16581563 try dwarf.genUnitLength(w);
16591564 try w.writeInt(u16, 0, dwarf.endian);
16601565}
......@@ -1691,11 +1596,11 @@ pub fn genEhFrameHdr(
16911596
16921597pub fn genDebugFrameCie(
16931598 dwarf: *Dwarf,
1694 dfw: *Writer,
1599 dfw: *std.Io.Writer,
16951600 /// `null` means to generate an architecture-agnostic padding cie
16961601 arch: ?std.Target.Cpu.Arch,
16971602 format: Frame.Format,
1698) Writer.Error!void {
1603) std.Io.Writer.Error!void {
16991604 try dwarf.genUnitLength(dfw);
17001605 switch (format) {
17011606 .eh_frame => try dfw.writeInt(u32, 0, dwarf.endian),
......@@ -1768,7 +1673,7 @@ pub fn genDebugInfoHeader(
17681673 try dihw.writeInt(u16, 5, dwarf.endian);
17691674 try dihw.writeByte(DW.UT.compile);
17701675 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);
17721677 const compile_unit_offset = dihw.end;
17731678 try dihw.writeUleb128(try dwarf.refAbbrevCode(.compile_unit));
17741679 try dihw.writeByte(DW.LANG.Zig);
......@@ -1777,17 +1682,13 @@ pub fn genDebugInfoHeader(
17771682 defer comp.gpa.free(root_dir_path);
17781683 try dwarf.strp(&dwarf.debug_line_str, dih_nw, root_dir_path);
17791684 try dwarf.strp(&dwarf.debug_line_str, dih_nw, mod.root_src_path);
1780 try dwarf.sectionOffset(
1685 try dwarf.secOffset(
17811686 dih_nw,
17821687 dwarf.getUnit(zcu.root_mod).get(dwarf).debug_info_header_ni.unwrap().?,
17831688 compile_unit_offset,
17841689 );
1785 try dwarf.sectionOffset(dih_nw, unit.debug_line_header_ni.unwrap().?, 0);
1786 try dwarf.sectionOffset(
1787 dih_nw,
1788 unit.debug_rnglists_ni.unwrap().?,
1789 Rnglists.offsetsTableOffset(dwarf),
1790 );
1690 try dwarf.secOffset(dih_nw, unit.debug_line_header_ni.unwrap().?, 0);
1691 try dwarf.secOffset(dih_nw, unit.debug_rnglists_ni.unwrap().?, Rnglists.offsetsTableOffset(dwarf));
17911692 try dihw.writeUleb128(0);
17921693 const module_offset = dihw.end;
17931694 try dihw.writeUleb128(try dwarf.refAbbrevCode(.module));
......@@ -1819,10 +1720,10 @@ fn genModuleDependency(
18191720 const diw = &di_nw.interface;
18201721 try diw.writeUleb128(try dwarf.refAbbrevCode(.module_dependency));
18211722 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);
18231724}
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 {
18261727 switch (size) {
18271728 0 => {},
18281729 1 => try diw.writeUleb128(dwarf.refAbbrevCodeIfExists(.pad_1).?),
......@@ -1951,7 +1852,7 @@ pub fn genDebugLineHeader(
19511852 try genDebugLinePadding(dlhw, dlhw.unusedCapacityLen());
19521853}
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 {
19551856 switch (size) {
19561857 0 => {},
19571858 1 => try dlw.writeByte(DW.LNS.const_add_pc),
......@@ -1980,7 +1881,7 @@ pub fn genDebugRnglistsHeader(
19801881 dwarf: *Dwarf,
19811882 unit: *Unit,
19821883 drh_nw: *MappedFile.Node.Writer,
1983) Writer.Error!void {
1884) std.Io.Writer.Error!void {
19841885 const drhw = &drh_nw.interface;
19851886 try dwarf.genUnitLength(drhw);
19861887 try drhw.writeInt(u16, 5, dwarf.endian);
......@@ -2006,7 +1907,7 @@ pub fn genDebugRnglists(
20061907 const drw = &dr_nw.interface;
20071908 drw.end = unit.debug_rnglists_end;
20081909 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);
20101911 try drw.writeUleb128(func_length);
20111912 unit.debug_rnglists_end = drw.end;
20121913 try drw.writeByte(DW.RLE.end_of_list);
......@@ -2063,9 +1964,12 @@ pub fn updateComptimeNav(
20631964 const fi = try dwarf.getFunc(func.owner_nav);
20641965 const f = fi.get(dwarf);
20651966 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().?;
20661969 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);
20681971 defer di_nw.deinit();
1972 elf.resetNodeRelocs(debug_info_ni);
20691973 dwarf.genDeclFuncGeneric(
20701974 pt,
20711975 &di_nw,
......@@ -2221,17 +2125,17 @@ fn updateConstInner(
22212125 if (ptr_type.sentinel != .none) try dwarf.blockConst(pt, di_nw, .fromInterned(ptr_type.sentinel));
22222126 if (ptr_type.flags.alignment.toByteUnits()) |a| try diw.writeUleb128(a);
22232127 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(
22252129 di_nw,
22262130 di_nw.ni,
2227 diw.end + dwarf.sectionOffsetSize(),
2131 diw.end + dwarf.secOffsetSize(),
22282132 );
22292133 if (ptr_type.flags.is_const) {
22302134 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(
22322136 di_nw,
22332137 di_nw.ni,
2234 diw.end + dwarf.sectionOffsetSize(),
2138 diw.end + dwarf.secOffsetSize(),
22352139 );
22362140 }
22372141 if (ptr_type.flags.is_volatile) try diw.writeUleb128(try dwarf.refAbbrevCode(.is_volatile));
......@@ -2336,7 +2240,7 @@ fn updateConstInner(
23362240 try diw.writeUleb128(try dwarf.refAbbrevCode(
23372241 if (loaded_struct.field_types.len > 0) .decl_struct else .decl_namespace_struct,
23382242 ));
2339 try dwarf.sectionOffset(di_nw, parent_ni, 0);
2243 try dwarf.secOffset(di_nw, parent_ni, 0);
23402244 try diw.writeInt(u32, decl.src_line + 1, dwarf.endian);
23412245 try diw.writeUleb128(decl.src_column + 1);
23422246 try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
......@@ -2410,7 +2314,7 @@ fn updateConstInner(
24102314 try diw.writeUleb128(try dwarf.refAbbrevCode(
24112315 if (loaded_enum.field_names.len > 0) .decl_enum else .decl_empty_enum,
24122316 ));
2413 try dwarf.sectionOffset(di_nw, parent_ni, 0);
2317 try dwarf.secOffset(di_nw, parent_ni, 0);
24142318 try diw.writeInt(u32, decl.src_line + 1, dwarf.endian);
24152319 try diw.writeUleb128(decl.src_column + 1);
24162320 try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
......@@ -2486,7 +2390,11 @@ fn updateConstIncompleteInner(
24862390 else => break :container .{
24872391 src_inst,
24882392 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 },
24902398 loaded_struct.captures,
24912399 loaded_struct.fqn,
24922400 loaded_struct.name_nav,
......@@ -2504,7 +2412,11 @@ fn updateConstIncompleteInner(
25042412 break :container .{
25052413 src_inst,
25062414 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 },
25082420 loaded_union.captures,
25092421 loaded_union.fqn,
25102422 loaded_union.name_nav,
......@@ -2527,7 +2439,11 @@ fn updateConstIncompleteInner(
25272439 break :container .{
25282440 src_inst,
25292441 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 },
25312447 loaded_enum.captures,
25322448 loaded_enum.fqn,
25332449 loaded_enum.name_nav,
......@@ -2565,11 +2481,7 @@ fn updateConstIncompleteInner(
25652481 },
25662482 },
25672483 };
2568 const capturing = for (captures.get(ip)) |capture| switch (capture.tag) {
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;
2484 const spec_di = if (false and captures.len > 0) try dwarf.getDecl(pt, val) else undefined;
25732485 _ = spec_di;
25742486 if (maybe_name_nav.unwrap()) |name_ni| {
25752487 const name_nav = ip.getNav(name_ni);
......@@ -2579,9 +2491,9 @@ fn updateConstIncompleteInner(
25792491 name_nav.analysis.?.namespace,
25802492 ).owner_type);
25812493 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,
25832495 ));
2584 try dwarf.sectionOffset(di_nw, parent_ni, 0);
2496 try dwarf.secOffset(di_nw, parent_ni, 0);
25852497 try diw.writeInt(u32, decl.src_line + 1, dwarf.endian);
25862498 try diw.writeUleb128(decl.src_column + 1);
25872499 try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
......@@ -2594,38 +2506,53 @@ fn updateConstIncompleteInner(
25942506 ).owner_type);
25952507 _ = parent_ni;
25962508 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,
25982510 ));
25992511 try diw.writeUleb128(@backingInt(fi));
26002512 try dwarf.strp(&dwarf.debug_str, di_nw, fqn.toSlice(ip));
26012513 }
26022514 try diw.writeByte(@intFromBool(true));
2603 if (capturing) {
2604 for (capture_names, captures.get(ip)) |capture_name, capture| switch (capture.unwrap()) {
2605 .@"comptime" => |capture_val| {
2606 const ty: Type = .fromInterned(ip.typeOf(capture_val));
2607 const ty_class = ty.classify(zcu);
2608 try diw.writeUleb128(try dwarf.refAbbrevCode(switch (ty_class) {
2609 .no_possible_value => unreachable,
2610 .one_possible_value => .comptime_capture,
2611 .runtime => .comptime_capture_runtime,
2612 .partially_comptime => .comptime_capture_partially_comptime,
2613 .fully_comptime => .comptime_capture_fully_comptime,
2614 }));
2615 try dwarf.strp(&dwarf.debug_str, di_nw, zf.zir.?.nullTerminatedString(capture_name));
2616 try dwarf.refConst(pt, di_nw, ty.toValue());
2617 if (ty_class.hasRuntimeBits()) try dwarf.blockConst(pt, di_nw, .fromInterned(capture_val));
2618 if (ty_class.comptimeOnly()) try dwarf.refConst(pt, di_nw, .fromInterned(capture_val));
2619 },
2620 .runtime => |capture_ty| {
2621 try diw.writeUleb128(try dwarf.refAbbrevCode(.runtime_capture));
2622 try dwarf.strp(&dwarf.debug_str, di_nw, zf.zir.?.nullTerminatedString(capture_name));
2623 try dwarf.refConst(pt, di_nw, .fromInterned(capture_ty));
2624 },
2625 .nav_val, .nav_ref => {},
2626 };
2627 try diw.writeByte(@backingInt(AbbrevCode.null));
2628 }
2515 for (capture_names, captures.get(ip)) |capture_name, capture| switch (capture.unwrap()) {
2516 .@"comptime" => |capture_val| {
2517 const ty: Type = .fromInterned(ip.typeOf(capture_val));
2518 const ty_class = ty.classify(zcu);
2519 try diw.writeUleb128(try dwarf.refAbbrevCode(switch (ty_class) {
2520 .no_possible_value => unreachable,
2521 .one_possible_value => .comptime_capture,
2522 .runtime => .comptime_capture_runtime,
2523 .partially_comptime => .comptime_capture_partially_comptime,
2524 .fully_comptime => .comptime_capture_fully_comptime,
2525 }));
2526 try dwarf.strp(&dwarf.debug_str, di_nw, zf.zir.?.nullTerminatedString(capture_name));
2527 try dwarf.refConst(pt, di_nw, ty.toValue());
2528 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));
2530 },
2531 .runtime => |capture_ty| {
2532 try diw.writeUleb128(try dwarf.refAbbrevCode(.runtime_capture));
2533 try dwarf.strp(&dwarf.debug_str, di_nw, zf.zir.?.nullTerminatedString(capture_name));
2534 try dwarf.refConst(pt, di_nw, .fromInterned(capture_ty));
2535 },
2536 .nav_val => |capture_nav| {
2537 const gi = try dwarf.getGlobal(capture_nav);
2538 try diw.writeUleb128(try dwarf.refAbbrevCode(.nav_capture));
2539 try dwarf.strp(&dwarf.debug_str, di_nw, zf.zir.?.nullTerminatedString(capture_name));
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));
26292556 }
26302557 try dwarf.genDebugInfoPadding(diw, diw.unusedCapacityLen());
26312558}
......@@ -2657,7 +2584,7 @@ fn genDeclInner(
26572584 ip.namespacePtr(loaded_struct.namespace).parent.unwrap().?,
26582585 ).owner_type);
26592586 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);
26612588 try diw.writeInt(u32, 0, dwarf.endian);
26622589 try diw.writeUleb128(0);
26632590 try diw.writeByte(DW.ACCESS.public);
......@@ -2669,7 +2596,7 @@ fn genDeclInner(
26692596 ip.namespacePtr(loaded_enum.namespace).parent.unwrap().?,
26702597 ).owner_type);
26712598 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);
26732600 try diw.writeInt(u32, 0, dwarf.endian);
26742601 try diw.writeUleb128(0);
26752602 try diw.writeByte(DW.ACCESS.public);
......@@ -2681,7 +2608,7 @@ fn genDeclInner(
26812608 ip.namespacePtr(loaded_union.namespace).parent.unwrap().?,
26822609 ).owner_type);
26832610 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);
26852612 try diw.writeInt(u32, 0, dwarf.endian);
26862613 try diw.writeUleb128(0);
26872614 try diw.writeByte(DW.ACCESS.public);
......@@ -2698,11 +2625,16 @@ pub fn updateLineNumber(
26982625 line: u32,
26992626) void {
27002627 const di = dwarf.getDeclIfExists(inst) orelse return;
2701 const decl_ni = di.get(dwarf).debug_info_ni.unwrap() orelse return;
2702 std.mem.writeInt(u32, decl_ni.slice(mf)[AbbrevCode.decl_size..][0..4], line + 1, dwarf.endian);
2628 const decl_ni = di.get(dwarf).debug_info_ni.unwrap().?;
2629 std.mem.writeInt(
2630 u32,
2631 decl_ni.slice(mf)[AbbrevCode.decl_size..][0..4],
2632 line + 1,
2633 dwarf.endian,
2634 );
27032635}
27042636
2705pub fn lostTracking(dwarf: *Dwarf, diw: *Writer) link.EmitError!void {
2637pub fn lostTracking(dwarf: *Dwarf, diw: *std.Io.Writer) link.EmitError!void {
27062638 try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_lost));
27072639}
27082640
......@@ -2755,17 +2687,23 @@ fn genDebugAbbrev(
27552687 dwarf.debug_abbrev.end = daw.end;
27562688}
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(
27592700 dwarf: *Dwarf,
27602701 nw: *MappedFile.Node.Writer,
27612702 target_ni: MappedFile.Node.Index,
27622703 addend: usize,
27632704) link.EmitError!void {
27642705 const offset = nw.interface.end;
2765 switch (dwarf.format) {
2766 .@"32" => try nw.interface.writeInt(u32, 0, dwarf.endian),
2767 .@"64" => try nw.interface.writeInt(u64, 0, dwarf.endian),
2768 }
2706 try dwarf.secOffsetPlaceholder(&nw.interface);
27692707 const elf = dwarf.lf.cast(.elf2).?;
27702708 try elf.addNodeReloc(nw.ni, offset, target_ni, @bitCast(@as(u64, addend)), switch (dwarf.format) {
27712709 .@"32" => .abs32,
......@@ -2773,23 +2711,27 @@ fn sectionOffset(
27732711 });
27742712}
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(
27772718 dwarf: *Dwarf,
27782719 nw: *MappedFile.Node.Writer,
27792720 target_si: link.File.SymbolId,
27802721 addend: usize,
27812722) link.EmitError!void {
27822723 const offset = nw.interface.end;
2783 switch (dwarf.address_size) {
2784 else => unreachable,
2785 .@"32" => try nw.interface.writeInt(u32, 0, dwarf.endian),
2786 .@"64" => try nw.interface.writeInt(u64, 0, dwarf.endian),
2787 }
2724 try dwarf.addrPlaceholder(&nw.interface);
27882725 const elf = dwarf.lf.cast(.elf2).?;
27892726 try elf.addReloc(@bitCast(nw.ni), offset, target_si, @bitCast(@as(u64, addend)), .absAddr(elf));
27902727}
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 {
27932735 const ty = val.typeOf(pt.zcu);
27942736 const size = ty.abiSize(pt.zcu);
27952737 try nw.interface.writeUleb128(size);
......@@ -2804,11 +2746,21 @@ fn blockConst(dwarf: *Dwarf, pt: Zcu.PerThread, nw: *MappedFile.Node.Writer, val
28042746 assert(start + size == nw.interface.end);
28052747}
28062748
2807fn refConst(dwarf: *Dwarf, pt: Zcu.PerThread, nw: *MappedFile.Node.Writer, val: Value) link.EmitError!void {
2808 try dwarf.sectionOffset(nw, Const.get(try dwarf.getConst(pt, val), dwarf).debug_info_ni.unwrap().?, 0);
2749fn refConst(
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);
28092756}
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 {
28122764 const zcu = dwarf.lf.comp.zcu.?;
28132765 const signedness = switch (ty.toIntern()) {
28142766 .comptime_int_type => .signed,
......@@ -2849,7 +2801,12 @@ fn bigIntConstValue(dwarf: *Dwarf, diw: *Writer, ty: Type, big_int: std.math.big
28492801 }
28502802}
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 {
28532810 const zcu = dwarf.lf.comp.zcu.?;
28542811 var big_int_space: Value.BigIntSpace = undefined;
28552812 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
28582815 std.math.big.int.Mutable.init(&big_int_space.limbs, field_index).toConst());
28592816}
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
28612827fn strp(dwarf: *Dwarf, s: *Str, nw: *MappedFile.Node.Writer, str: []const u8) link.EmitError!void {
28622828 const comp = dwarf.lf.comp;
28632829 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) {
28652831 error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{
28662832 mf.io_err.?,
28672833 }),
......@@ -3013,6 +2979,7 @@ pub const AbbrevCode = enum {
30132979 comptime_capture_partially_comptime,
30142980 comptime_capture_fully_comptime,
30152981 runtime_capture,
2982 nav_capture,
30162983 builtin_extern_nullary_func,
30172984 builtin_extern_func,
30182985 builtin_extern_var,
......@@ -3080,6 +3047,7 @@ pub const AbbrevCode = enum {
30803047 children: bool = false,
30813048 attrs: []const Attr = &.{},
30823049 }).init(.{
3050 .null = undefined,
30833051 .pad_1 = .{
30843052 .tag = .ZIG_padding,
30853053 },
......@@ -3937,6 +3905,13 @@ pub const AbbrevCode = enum {
39373905 .{ .type, .ref_addr },
39383906 },
39393907 },
3908 .nav_capture = .{
3909 .tag = .template_value_parameter,
3910 .attrs = &.{
3911 .{ .name, .strp },
3912 .{ .location, .exprloc },
3913 },
3914 },
39403915 .builtin_extern_nullary_func = .{
39413916 .tag = .subprogram,
39423917 .attrs = &.{
......@@ -4204,20 +4179,19 @@ pub const AbbrevCode = enum {
42044179 .{ .ZIG_comptime_value, .ref_addr },
42054180 },
42064181 },
4207 .null = undefined,
42084182 });
42094183};
42104184
42114185pub fn uleb128Size(value: anytype) u32 {
4212 var buf: [64]u8 = undefined;
4213 var dw: Writer.Discarding = .init(&buf);
4186 var buf: [std.atomic.cache_line]u8 = undefined;
4187 var dw: std.Io.Writer.Discarding = .init(&buf);
42144188 dw.writer.writeUleb128(value) catch unreachable;
42154189 return @intCast(dw.fullCount());
42164190}
42174191
42184192pub fn sleb128Size(value: anytype) u32 {
4219 var buf: [64]u8 = undefined;
4220 var dw: Writer.Discarding = .init(&buf);
4193 var buf: [std.atomic.cache_line]u8 = undefined;
4194 var dw: std.Io.Writer.Discarding = .init(&buf);
42214195 dw.writer.writeSleb128(value) catch unreachable;
42224196 return @intCast(dw.fullCount());
42234197}
......@@ -4237,5 +4211,4 @@ const std = @import("std");
42374211const target_info = @import("../target.zig");
42384212const Type = @import("../Type.zig");
42394213const Value = @import("../Value.zig");
4240const Writer = std.Io.Writer;
42414214const Zcu = @import("../Zcu.zig");
src/link/Elf2.zig+1-1
......@@ -5332,7 +5332,7 @@ fn computeNodeElfOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 {
53325332///
53335333/// Asserts that `ni` must be a node which supports relocations (see `Elf.Node`). Does not support
53345334/// 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 {
53365336 const opts: struct {
53375337 first_symbol_reloc: ?*SymbolReloc.Index = null,
53385338 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"